Skip to content

Commit f7cb732

Browse files
committed
refactor: support storybook screens
1 parent 6dce309 commit f7cb732

File tree

10 files changed

+162
-39
lines changed

10 files changed

+162
-39
lines changed

packages/components-vue/.storybook/main.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ function getAbsolutePath(value) {
1010
}
1111

1212
const config: StorybookConfig = {
13-
stories: ["../src/**/*.mdx", "../src/components/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
13+
stories: [
14+
"../src/**/*.mdx",
15+
"../src/screens/*.stories.@(js|jsx|mjs|ts|tsx)",
16+
"../src/components/**/*.stories.@(js|jsx|mjs|ts|tsx)",
17+
],
1418
addons: [
1519
getAbsolutePath("@storybook/addon-links"),
1620
getAbsolutePath("@storybook/addon-essentials"),

packages/components-vue/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,6 @@
5959
"@fortawesome/fontawesome-common-types": "^6.4.0",
6060
"@open-xamu-co/ui-common-enums": "link:../common-enums",
6161
"@open-xamu-co/ui-common-helpers": "link:../common-helpers",
62-
"@open-xamu-co/ui-common-types": "link:../common-types",
63-
"@types/lodash": "^4.14.192",
64-
"@types/validator": "^13.11.1",
6562
"js-md5": "^0.8.3",
6663
"lodash": "^4.17.21",
6764
"nanoid": "^4.0.2",
@@ -70,6 +67,7 @@
7067
},
7168
"devDependencies": {
7269
"@chromatic-com/storybook": "1.4.0",
70+
"@open-xamu-co/ui-common-types": "link:../common-types",
7371
"@open-xamu-co/ui-styles": "link:../styles",
7472
"@storybook/addon-essentials": "^8.1.1",
7573
"@storybook/addon-interactions": "^8.1.1",
@@ -78,7 +76,9 @@
7876
"@storybook/test": "^8.1.1",
7977
"@storybook/vue3": "^8.1.1",
8078
"@storybook/vue3-vite": "^8.1.1",
79+
"@types/lodash": "^4.14.192",
8180
"@types/node": "^18.17.17",
81+
"@types/validator": "^13.11.1",
8282
"@vitejs/plugin-vue": "^4.2.1",
8383
"storybook": "^8.1.1",
8484
"vite": "^5.0.10",

packages/components-vue/src/components/form/Input.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
readonly || (!input.multiple && modelValue.includes(option.value))
2626
"
2727
:round="!!option.pattern"
28-
:tooltip="!!option.pattern ? option.alias || String(option.value) : ''"
28+
:tooltip="{
29+
[option.alias || option.value]: !!(option.pattern || option.icon),
30+
}"
2931
tooltip-as-text
3032
tooltip-position="bottom"
3133
@click="choose(option.value)"

packages/components-vue/src/components/form/Simple.stories.ts

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,11 @@ const inputs: FormInput[] = [
1515
icon: "user",
1616
}),
1717
new FormInput({
18-
values: [""],
19-
name: "lastName",
20-
required: true,
21-
title: "Last Name",
22-
placeholder: "What is your last name?",
23-
autocomplete: "family-name",
24-
icon: "user-group",
18+
placeholder: "E.g. Blue",
19+
title: "Possible Value",
20+
icon: ["industry", {}],
21+
name: "offerFieldValues",
22+
multiple: true,
2523
}),
2624
new FormInput({
2725
required: true,
@@ -35,19 +33,24 @@ const inputs: FormInput[] = [
3533
title: "Choose one or several payment methods",
3634
}),
3735
new FormInput({
38-
values: [["", "", ""]],
39-
name: "location",
40-
type: eFormType.LOCATION,
41-
required: true,
36+
options: [
37+
{ value: "Happy", icon: "face-smile" },
38+
{ value: "Tired", icon: "face-tired" },
39+
{ value: "Sad", icon: "face-sad-tear" },
40+
{ value: "indiferent", icon: "face-meh" },
41+
{ value: "In love", icon: "face-grin-hearts" },
42+
],
43+
type: eFormType.CHOICE,
44+
values: [""],
45+
name: "feeling",
46+
title: "How you feeling today?",
4247
}),
4348
new FormInput({
44-
values: [["CO+57", ""]],
45-
name: "cellphone",
46-
required: true,
47-
type: eFormType.CELLPHONE,
49+
type: eFormType.BOOLEAN,
50+
placeholder: "Users can skip this field when creating an offer",
51+
name: "nullable",
52+
title: "Is this field optional in the offer?",
4853
}),
49-
50-
// new FormInput({ value:"",name: "identification", type: eFormTypeSimple.ID }),
5154
];
5255

5356
const meta = {
@@ -62,4 +65,30 @@ export const Sample: Story = {
6265
args: { modelValue: inputs },
6366
};
6467

68+
export const WithLocation: Story = {
69+
args: {
70+
modelValue: [
71+
new FormInput({
72+
values: [["", "", ""]],
73+
name: "location",
74+
type: eFormType.LOCATION,
75+
required: true,
76+
}),
77+
],
78+
},
79+
};
80+
81+
export const WithPhone: Story = {
82+
args: {
83+
modelValue: [
84+
new FormInput({
85+
values: [["CO+57", ""]],
86+
name: "cellphone",
87+
required: true,
88+
type: eFormType.CELLPHONE,
89+
}),
90+
],
91+
},
92+
};
93+
6594
export default meta;

packages/components-vue/src/components/form/Stages.stories.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import type { Meta, StoryObj } from "@storybook/vue3";
22

3-
import Stages from "./Stages.vue";
43
import { type iForm, FormInput, useForm } from "@open-xamu-co/ui-common-helpers";
54
import { eFormType } from "@open-xamu-co/ui-common-enums";
65
import type { iInvalidInput } from "@open-xamu-co/ui-common-types";
76

8-
const stages: iForm[][] = [
7+
import Stages from "./Stages.vue";
8+
9+
export const stages: iForm[][] = [
910
[
1011
{
1112
title: "Offer field",

packages/components-vue/src/components/form/Stages.vue

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,20 @@
99
class="flx --flxColumn --flx-start-stretch --gap-30 --maxWidth-full"
1010
>
1111
<div
12-
v-for="(stage, stageIndex) in localStages.filter((stage) => stage.length)"
12+
v-for="(_stage, stageIndex) in localStages"
1313
v-show="activeStage == stageIndex"
1414
:key="`stage-${stageIndex}`"
1515
:class="stagesClasses ?? 'flx --flxColumn --flx-start-stretch --gap-30'"
1616
>
1717
<FormSimple
18-
v-for="(form, formIndex) in stage"
18+
v-for="(_form, formIndex) in localStages[stageIndex]"
1919
:key="`form-${stageIndex}-${formIndex}`"
2020
:model-value="localStages[stageIndex][formIndex].inputs"
2121
:theme="theme"
2222
:invalid="invalid"
2323
no-form
24-
:title="form.title"
25-
:readonly="form.readonly"
24+
:title="localStages[stageIndex][formIndex].title"
25+
:readonly="localStages[stageIndex][formIndex].readonly"
2626
@update:model-value="updateForm(stageIndex, formIndex, $event)"
2727
@update:invalid="invalid = $event"
2828
/>
@@ -166,7 +166,7 @@
166166
const canSubmit = ref(props.optional);
167167
const activeStage = ref(0);
168168
const invalid = ref<iInvalidInput[]>([]);
169-
const localStages = ref(markRaw(props.stages));
169+
const localStages = ref(markRaw(props.stages.filter((stage) => stage.length)));
170170
/**
171171
* Submit process is loading/running
172172
*/
@@ -176,11 +176,7 @@
176176
submitting.value = true;
177177
178178
// get inputs
179-
const inputs = (props.stages || [])
180-
.map((stage) => {
181-
return stage.map(({ inputs }) => inputs);
182-
})
183-
.flat(2);
179+
const inputs = localStages.value.map((stage) => stage.map(({ inputs }) => inputs)).flat(2);
184180
const successOrInvalid = await props.submitFn?.(inputs);
185181
186182
submitting.value = false;
@@ -189,7 +185,7 @@
189185
if (Array.isArray(successOrInvalid)) invalid.value = successOrInvalid;
190186
else {
191187
emit("submited", successOrInvalid);
192-
localStages.value = props.stages; // reset form
188+
localStages.value = props.stages.filter((stage) => stage.length); // reset form
193189
}
194190
});
195191

packages/components-vue/src/components/input/Toggle.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
>
2020
<span v-if="label">{{ label }}</span>
2121
<span v-else-if="showPlaceholder">
22-
{{ t(modelValue ? "yes" : "no") }}
22+
{{ modelValue ? t("yes") : t("no") }}
2323
</span>
2424
<slot></slot>
2525
</div>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import type { Meta, StoryObj } from "@storybook/vue3";
2+
3+
import ModalWithFormStages from "./ModalWithFormStages.vue";
4+
5+
const meta = {
6+
title: "Screens/Modal with Form Stages",
7+
component: ModalWithFormStages as Record<keyof typeof ModalWithFormStages, unknown>,
8+
args: {},
9+
tags: ["!autodocs"],
10+
} satisfies Meta<typeof ModalWithFormStages>;
11+
12+
type Story = StoryObj<typeof ModalWithFormStages>;
13+
14+
export const Sample: Story = {
15+
args: {},
16+
};
17+
18+
export default meta;
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<template>
2+
<Modal
3+
v-bind="{
4+
title: 'Create offer field',
5+
subtitle: 'Complete the following data',
6+
}"
7+
class="--txtColor"
8+
hide-footer
9+
invert-theme
10+
>
11+
<template #toggle="{ toggleModal }">
12+
<BoxAction icon="align-left" label="Offer field" @click="toggleModal" />
13+
</template>
14+
<template #default="{ toggleModal }">
15+
<FormStages
16+
v-bind="{
17+
stages,
18+
submitFn,
19+
submitLabel: 'Create offer field',
20+
}"
21+
class="--pTop --pBottom --width-440:md"
22+
v-on="{
23+
submited: toggleModal,
24+
inputValues: updateUiComponentId,
25+
}"
26+
>
27+
<template #secondary-actions>
28+
<ActionButtonToggle
29+
aria-label="Cancel"
30+
round=":sm-inv"
31+
@click.prevent="toggleModal()"
32+
>
33+
<IconFa name="xmark" hidden="-full:sm" />
34+
<IconFa name="xmark" regular hidden="-full:sm" />
35+
<span class="--hidden-full:sm-inv">Cancel</span>
36+
</ActionButtonToggle>
37+
</template>
38+
</FormStages>
39+
</template>
40+
</Modal>
41+
</template>
42+
43+
<script setup lang="ts">
44+
import { computed } from "vue";
45+
import type { iInvalidInput } from "@open-xamu-co/ui-common-types";
46+
import { FormInput, useForm, type iForm } from "@open-xamu-co/ui-common-helpers";
47+
48+
import IconFa from "../components/icon/Fa.vue";
49+
import ActionButtonToggle from "../components/action/ButtonToggle.vue";
50+
import BoxAction from "../components/box/Action.vue";
51+
import FormStages from "../components/form/Stages.vue";
52+
import Modal from "../components/modal/Simple.vue";
53+
54+
import { stages as formStages } from "../components/form/Stages.stories";
55+
56+
/**
57+
* Modal with form stages
58+
*/
59+
60+
const stages = computed<iForm[][]>(() => {
61+
return formStages;
62+
});
63+
64+
function updateUiComponentId({ uiComponent }: Record<string, any[]>) {
65+
if (uiComponent) console.log(uiComponent);
66+
}
67+
68+
async function submitFn(inputs: FormInput[]): Promise<boolean | iInvalidInput[]> {
69+
const { utils } = useForm();
70+
71+
console.log(utils.getFormValues(inputs));
72+
73+
return true;
74+
}
75+
</script>

yarn.lock

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3731,9 +3731,6 @@
37313731
"@fortawesome/fontawesome-common-types" "^6.4.0"
37323732
"@open-xamu-co/ui-common-enums" "link:packages/common-enums"
37333733
"@open-xamu-co/ui-common-helpers" "link:packages/common-helpers"
3734-
"@open-xamu-co/ui-common-types" "link:packages/common-types"
3735-
"@types/lodash" "^4.14.192"
3736-
"@types/validator" "^13.11.1"
37373734
js-md5 "^0.8.3"
37383735
lodash "^4.17.21"
37393736
nanoid "^4.0.2"
@@ -15276,6 +15273,7 @@ prepend-http@^2.0.0:
1527615273
integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==
1527715274

1527815275
"prettier-fallback@npm:prettier@^3", prettier@^3.1.1:
15276+
name prettier-fallback
1527915277
version "3.2.5"
1528015278
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368"
1528115279
integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==

0 commit comments

Comments
 (0)