vanilla-vue-ui 0.0.0 â 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/basic/app-bar/WAppBar.stories.ts +41 -0
- package/basic/app-bar/WAppBar.vue +48 -0
- package/basic/banner/BannerStore.ts +54 -0
- package/basic/banner/WBanner.stories.ts +28 -0
- package/basic/banner/WBanner.vue +41 -0
- package/basic/breadcrumb/WBreadcrumb.stories.ts +25 -0
- package/basic/breadcrumb/WBreadcrumb.vue +97 -0
- package/basic/button/ButtonSize.ts +2 -0
- package/basic/button/WButton.spec.ts +17 -0
- package/basic/button/WButton.stories.ts +68 -0
- package/basic/button/WButton.vue +81 -0
- package/basic/icon/WIcon.vue +5 -0
- package/basic/range/WRange.vue +113 -17
- package/basic/text-field/TextFieldSize.ts +2 -0
- package/basic/text-field/WTextField.stories.ts +88 -0
- package/basic/text-field/WTextField.vue +188 -0
- package/basic/tooltip/WTooltip.stories.ts +87 -0
- package/basic/tooltip/WTooltip.vue +63 -0
- package/package.json +44 -30
- package/template/footer-simple/WFooterSimple.stories.ts +23 -0
- package/template/footer-simple/WFooterSimple.vue +20 -0
- package/template/navigation-drawer/NavigationDrawer.stories.ts +59 -0
- package/template/navigation-drawer/NavigationDrawer.vue +121 -0
- package/template/navigation-drawer/NavigationDrawerContent.ts +11 -0
- package/template/primary-button/WPrimaryButton.spec.ts +17 -0
- package/template/primary-button/WPrimaryButton.stories.ts +30 -0
- package/template/primary-button/WPrimaryButton.vue +9 -0
- package/template/secondary-button/WSecondaryButton.spec.ts +17 -0
- package/template/secondary-button/WSecondaryButton.stories.ts +30 -0
- package/template/secondary-button/WSecondaryButton.vue +9 -0
- package/template/tree-menu/TreeMenuContent.ts +11 -0
- package/template/tree-menu/WTreeMenu.stories.ts +55 -0
- package/template/tree-menu/WTreeMenu.vue +152 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Replace vue3 with vue if you are using Storybook for Vue 2
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/vue3';
|
|
3
|
+
import TextField from './WTextField.vue';
|
|
4
|
+
|
|
5
|
+
type TextFieldProps = InstanceType<typeof TextField>['$props']
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof TextField> = {
|
|
8
|
+
component: TextField,
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default meta;
|
|
12
|
+
type Story = StoryObj<typeof TextField>;
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
*đ Render functions are a framework specific feature to allow you control on how the component renders.
|
|
16
|
+
* See https://storybook.js.org/docs/api/csf
|
|
17
|
+
* to learn how to use render functions.
|
|
18
|
+
*/
|
|
19
|
+
export const Primary: Story = {
|
|
20
|
+
render: (args: TextFieldProps) => ({
|
|
21
|
+
setup() {
|
|
22
|
+
return {
|
|
23
|
+
...args
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
components: { TextField },
|
|
27
|
+
template: `
|
|
28
|
+
<div class="p-4">
|
|
29
|
+
<div class="mb-2"><TextField size="xs" value="John" :classes="classes"></TextField></div>
|
|
30
|
+
<div class="mb-2"><TextField size="sm" value="John" :classes="classes"></TextField></div>
|
|
31
|
+
<div class="mb-2"><TextField size="base" value="John" :classes="classes"></TextField></div>
|
|
32
|
+
<div class="mb-2"><TextField size="lg" value="John" :classes="classes"></TextField></div>
|
|
33
|
+
<div class="mb-2"><TextField size="2xl" value="John" :classes="classes"></TextField></div>
|
|
34
|
+
<div class="mb-2"><TextField size="3xl" value="John" :classes="classes"></TextField></div>
|
|
35
|
+
<div class="mb-2"><TextField size="6xl" value="John" :classes="classes"></TextField></div>
|
|
36
|
+
</div>
|
|
37
|
+
`,
|
|
38
|
+
}),
|
|
39
|
+
args: {
|
|
40
|
+
classes: {
|
|
41
|
+
content: {
|
|
42
|
+
input: {
|
|
43
|
+
color: 'text-onSurface dark:text-onSurface-dark',
|
|
44
|
+
backgroundColor: 'bg-white dark:bg-surface-dark'
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const WithLabel: Story = {
|
|
52
|
+
render: () => ({
|
|
53
|
+
components: { TextField },
|
|
54
|
+
template: `
|
|
55
|
+
<div class="mb-2"><TextField size="xs" label="Name"></TextField></div>
|
|
56
|
+
<div class="mb-2"><TextField size="sm" label="Name"></TextField></div>
|
|
57
|
+
<div class="mb-2"><TextField size="base" label="Name"></TextField></div>
|
|
58
|
+
<div class="mb-2"><TextField size="lg" label="Name"></TextField></div>
|
|
59
|
+
<div class="mb-2"><TextField size="2xl" label="Name"></TextField></div>
|
|
60
|
+
<div class="mb-2"><TextField size="3xl" label="Name"></TextField></div>
|
|
61
|
+
<div class="mb-2"><TextField size="6xl" label="Name"></TextField></div>
|
|
62
|
+
`,
|
|
63
|
+
}),
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const WithPlaceholder: Story = {
|
|
67
|
+
render: () => ({
|
|
68
|
+
components: { TextField },
|
|
69
|
+
template: '<TextField placeholder="ć
„ćăăŠăă ăă"></TextField>',
|
|
70
|
+
}),
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const WithError: Story = {
|
|
74
|
+
render: (args: TextFieldProps) => ({
|
|
75
|
+
setup() {
|
|
76
|
+
return {
|
|
77
|
+
...args,
|
|
78
|
+
};
|
|
79
|
+
},
|
|
80
|
+
components: { TextField },
|
|
81
|
+
template: '<TextField value="John Smith" :rules="rules"></TextField>',
|
|
82
|
+
}),
|
|
83
|
+
args: {
|
|
84
|
+
rules: [
|
|
85
|
+
(value: string) => value.length <= 5 || 'Max 5 characters',
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
};
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
:class="[
|
|
4
|
+
mergedClasses.outline?.base,
|
|
5
|
+
mergedClasses.outline?.backgroundColor,
|
|
6
|
+
]"
|
|
7
|
+
>
|
|
8
|
+
<label :for="name" :class="mergedClasses.label?.base">{{ label }}</label>
|
|
9
|
+
<div class="relative flex">
|
|
10
|
+
<div class="flex-1">
|
|
11
|
+
<input
|
|
12
|
+
:id="id"
|
|
13
|
+
:name="name"
|
|
14
|
+
:value="value"
|
|
15
|
+
:placeholder="placeholder"
|
|
16
|
+
:required="required"
|
|
17
|
+
:autocomplete="autocomplete"
|
|
18
|
+
:class="[
|
|
19
|
+
textSize,
|
|
20
|
+
mergedClasses.content?.input?.base,
|
|
21
|
+
mergedClasses.content?.input?.backgroundColor,
|
|
22
|
+
mergedClasses.content?.input?.color,
|
|
23
|
+
]"
|
|
24
|
+
:type="type"
|
|
25
|
+
@change="changeValue($event)"
|
|
26
|
+
@input="inputValue($event)"
|
|
27
|
+
>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<div class="flex-shrink-0">
|
|
31
|
+
<slot name="trailing" />
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
<p v-if="errorMassage.length > 0" :class="mergedClasses.errorMessage?.base">{{ errorMassage }}</p>
|
|
36
|
+
</template>
|
|
37
|
+
|
|
38
|
+
<script setup lang="ts">
|
|
39
|
+
import { ref, defineProps, type PropType, defineExpose } from 'vue'
|
|
40
|
+
import type { ClassObject } from '../../types/ClassObject';
|
|
41
|
+
import { deepMergeClassObject } from '../../util';
|
|
42
|
+
// @ts-ignore
|
|
43
|
+
import type { TextFieldSize } from './TextFieldSize'
|
|
44
|
+
|
|
45
|
+
const props = defineProps({
|
|
46
|
+
value: {
|
|
47
|
+
type: String as PropType<string>
|
|
48
|
+
},
|
|
49
|
+
label: {
|
|
50
|
+
type: String as PropType<string>
|
|
51
|
+
},
|
|
52
|
+
placeholder: {
|
|
53
|
+
type: String as PropType<string>
|
|
54
|
+
},
|
|
55
|
+
type: {
|
|
56
|
+
type: String as PropType<string>
|
|
57
|
+
},
|
|
58
|
+
autocomplete: {
|
|
59
|
+
type: String as PropType<string>
|
|
60
|
+
},
|
|
61
|
+
required: {
|
|
62
|
+
type: Boolean as PropType<boolean>
|
|
63
|
+
},
|
|
64
|
+
rules: {
|
|
65
|
+
type: Array as PropType<ValidationRule[]>
|
|
66
|
+
},
|
|
67
|
+
size: {
|
|
68
|
+
type: String as PropType<TextFieldSize>,
|
|
69
|
+
default: 'base',
|
|
70
|
+
},
|
|
71
|
+
name: {
|
|
72
|
+
type: String as PropType<string>
|
|
73
|
+
},
|
|
74
|
+
id: {
|
|
75
|
+
type: String as PropType<string>
|
|
76
|
+
},
|
|
77
|
+
classes: {
|
|
78
|
+
type: Object as PropType<ClassObject>,
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
const defaultClasses: ClassObject = {
|
|
84
|
+
content: {
|
|
85
|
+
input: {
|
|
86
|
+
base: "block w-full border-0 p-0 placeholder:text-gray-400 sm:leading-6 focus:outline-none focus:ring-0",
|
|
87
|
+
backgroundColor: 'bg-surface dark:bg-surface-dark',
|
|
88
|
+
color: 'text-onSurface dark:text-onSurface-dark'
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
outline: {
|
|
92
|
+
base: "rounded-md px-3 pb-1.5 pt-2.5 shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-primary dark:focus-within:ring-primary-dark",
|
|
93
|
+
backgroundColor: 'bg-surface dark:bg-surface-dark',
|
|
94
|
+
},
|
|
95
|
+
label: {
|
|
96
|
+
base: "block text-xs font-medium text-onSurface dark:text-onSurface-dark"
|
|
97
|
+
},
|
|
98
|
+
errorMessage: {
|
|
99
|
+
base: "mt-1 ml-1 text-sm text-red-600"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// props.classesăæžĄăăăŠăăȘăć ŽćădefaultClassesăäœżçšăă
|
|
104
|
+
const mergedClasses = props.classes ? deepMergeClassObject(defaultClasses, props.classes) : defaultClasses;
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
const textSize = ref('text-' + props.size)
|
|
108
|
+
|
|
109
|
+
// emit ăćźçŸ©
|
|
110
|
+
const emit = defineEmits<{
|
|
111
|
+
input: [value: Event],
|
|
112
|
+
change: [value: Event]
|
|
113
|
+
}>()
|
|
114
|
+
|
|
115
|
+
const errorMassage = ref("")
|
|
116
|
+
|
|
117
|
+
type ValidationRule = (value: string) => boolean | string
|
|
118
|
+
|
|
119
|
+
//
|
|
120
|
+
// Sample
|
|
121
|
+
//
|
|
122
|
+
// let rules: ValidationRule[] = [
|
|
123
|
+
// value => !!value || 'Required.', // required
|
|
124
|
+
// value => value.length <= 20 || 'Max 20 characters', // max
|
|
125
|
+
// value => {
|
|
126
|
+
// const pattern = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
|
127
|
+
// return pattern.test(value) || 'Invalid e-mail.'
|
|
128
|
+
// }, // email
|
|
129
|
+
// ]
|
|
130
|
+
|
|
131
|
+
// ććăăȘăăŒă·ă§ăł
|
|
132
|
+
// undefined ăăăȘăăŁăă
|
|
133
|
+
if (typeof props.value === "string") {
|
|
134
|
+
const setupErrorMessage = validate(props.value)
|
|
135
|
+
if (setupErrorMessage) {
|
|
136
|
+
errorMassage.value = setupErrorMessage as string
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// input ăźć€æŽăćăćă
|
|
141
|
+
function changeValue(event: Event) {
|
|
142
|
+
const target = event.target as HTMLInputElement | null
|
|
143
|
+
if (target) {
|
|
144
|
+
const validationResult = validate(target.value)
|
|
145
|
+
if (validationResult === true) {
|
|
146
|
+
// ăăȘăăŒă·ă§ăłă«éăŁăă
|
|
147
|
+
emit('change', event)
|
|
148
|
+
errorMassage.value = ""; // ăšă©ăŒăĄăă»ăŒăžăăŻăȘăą
|
|
149
|
+
} else {
|
|
150
|
+
errorMassage.value = validationResult as string; // ăšă©ăŒăĄăă»ăŒăžăèšćź
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function inputValue(event: Event) {
|
|
156
|
+
const target = event.target as HTMLInputElement | null
|
|
157
|
+
if (target) {
|
|
158
|
+
const validationResult = validate(target.value)
|
|
159
|
+
if (validationResult === true) {
|
|
160
|
+
// ăăȘăăŒă·ă§ăłă«éăŁăă
|
|
161
|
+
errorMassage.value = ""; // ăšă©ăŒăĄăă»ăŒăžăăŻăȘăą
|
|
162
|
+
} else {
|
|
163
|
+
errorMassage.value = validationResult as string; // ăšă©ăŒăĄăă»ăŒăžăèšćź
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
emit('input', event)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// ăăȘăăŒă·ă§ăł
|
|
171
|
+
function validate(value: string): boolean | string {
|
|
172
|
+
if (props.rules) {
|
|
173
|
+
for (const rule of props.rules) {
|
|
174
|
+
const result = rule(value);
|
|
175
|
+
if (result !== true) {
|
|
176
|
+
// ă«ăŒă«ăæććïŒăšă©ăŒăĄăă»ăŒăžïŒăèżăăć ŽćăăăȘăăŒă·ă§ăłć€±æ
|
|
177
|
+
return result;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return true; // ă«ăŒă«ăèšćźăăăŠăȘă or ăăčăŠăźă«ăŒă«ăæć
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// ć€éšăăăćŒăłćșăăăăă«ăă
|
|
185
|
+
defineExpose({
|
|
186
|
+
validate
|
|
187
|
+
});
|
|
188
|
+
</script>
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Replace vue3 with vue if you are using Storybook for Vue 2
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/vue3';
|
|
3
|
+
import WTooltip from './WTooltip.vue';
|
|
4
|
+
import Button from '../button/WButton.vue'
|
|
5
|
+
import { ref, watch } from 'vue';
|
|
6
|
+
|
|
7
|
+
type WTooltipProps = InstanceType<typeof WTooltip>['$props']
|
|
8
|
+
|
|
9
|
+
const meta: Meta<typeof WTooltip> = {
|
|
10
|
+
component: WTooltip,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default meta;
|
|
14
|
+
type Story = StoryObj<typeof WTooltip>;
|
|
15
|
+
|
|
16
|
+
/*
|
|
17
|
+
*đ Render functions are a framework specific feature to allow you control on how the component renders.
|
|
18
|
+
* See https://storybook.js.org/docs/api/csf
|
|
19
|
+
* to learn how to use render functions.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
export const Primary: Story = {
|
|
23
|
+
render: (args: WTooltipProps) => ({
|
|
24
|
+
setup() {
|
|
25
|
+
return {
|
|
26
|
+
...args,
|
|
27
|
+
};
|
|
28
|
+
},
|
|
29
|
+
components: { WTooltip, Button },
|
|
30
|
+
template: `
|
|
31
|
+
<w-tooltip hoverText="ăăăŒ" reactiveText="text" :isReact="isReact">
|
|
32
|
+
<Button>Text</Button>
|
|
33
|
+
</w-tooltip>
|
|
34
|
+
`,
|
|
35
|
+
}),
|
|
36
|
+
args: {
|
|
37
|
+
isReact: false
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const isReact: Story = {
|
|
42
|
+
render: (args) => ({
|
|
43
|
+
setup() {
|
|
44
|
+
// isReact ă ref ć
|
|
45
|
+
const isReact = ref(args.isReact);
|
|
46
|
+
|
|
47
|
+
watch(() => args.isReact, (val) => {
|
|
48
|
+
isReact.value = val;
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
isReact,
|
|
53
|
+
};
|
|
54
|
+
},
|
|
55
|
+
components: { WTooltip, Button },
|
|
56
|
+
template: `
|
|
57
|
+
<w-tooltip
|
|
58
|
+
reactiveText="Clicked."
|
|
59
|
+
:isReact="isReact"
|
|
60
|
+
>
|
|
61
|
+
<Button @click="isReact = true">Text</Button>
|
|
62
|
+
</w-tooltip>
|
|
63
|
+
`,
|
|
64
|
+
}),
|
|
65
|
+
args: {
|
|
66
|
+
isReact: false,
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const init: Story = {
|
|
71
|
+
render: (args: WTooltipProps) => ({
|
|
72
|
+
setup() {
|
|
73
|
+
return {
|
|
74
|
+
...args,
|
|
75
|
+
};
|
|
76
|
+
},
|
|
77
|
+
components: { WTooltip, Button },
|
|
78
|
+
template: `
|
|
79
|
+
<w-tooltip hoverText="ăăăŒ" :showHoverOnMount="true">
|
|
80
|
+
<Button>Text</Button>
|
|
81
|
+
</w-tooltip>
|
|
82
|
+
`,
|
|
83
|
+
}),
|
|
84
|
+
args: {
|
|
85
|
+
isReact: false
|
|
86
|
+
},
|
|
87
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<span class="relative group">
|
|
3
|
+
<div @mouseenter="showTooltip" @mouseleave="hideTooltip">
|
|
4
|
+
<slot />
|
|
5
|
+
</div>
|
|
6
|
+
<span v-show="isReact" class="absolute z-50 whitespace-nowrap -bottom-12 left-1/2 -translate-x-1/2 bg-gray-600 py-1 px-2 text-white rounded">{{ reactiveText }}</span>
|
|
7
|
+
<span v-show="!isReact && isShowTooltip" class="absolute z-50 whitespace-nowrap -bottom-12 left-1/2 -translate-x-1/2 bg-gray-600 py-1 px-2 text-white rounded">{{ hoverText }}</span>
|
|
8
|
+
</span>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<script setup lang="ts">
|
|
12
|
+
import { ref, defineProps, defineEmits, watch, type PropType, onMounted } from 'vue';
|
|
13
|
+
|
|
14
|
+
const isShowTooltip = ref(false)
|
|
15
|
+
|
|
16
|
+
const props = defineProps({
|
|
17
|
+
reactiveText: {
|
|
18
|
+
type: String,
|
|
19
|
+
default: ''
|
|
20
|
+
},
|
|
21
|
+
hoverText: {
|
|
22
|
+
type: String,
|
|
23
|
+
required: false,
|
|
24
|
+
default: ''
|
|
25
|
+
},
|
|
26
|
+
isReact: {
|
|
27
|
+
type: Boolean,
|
|
28
|
+
default: false
|
|
29
|
+
},
|
|
30
|
+
showHoverOnMount: {
|
|
31
|
+
type: Boolean as PropType<boolean>,
|
|
32
|
+
default: false,
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
const emit = defineEmits(['update:isReact'])
|
|
37
|
+
|
|
38
|
+
// currentStep ăźć€æŽăçŁèŠ
|
|
39
|
+
watch(
|
|
40
|
+
() => props.isReact, (newValue) => {
|
|
41
|
+
if (newValue === true) {
|
|
42
|
+
setTimeout(() => { emit('update:isReact', false) }, 1000)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
onMounted(() => {
|
|
48
|
+
if (props.showHoverOnMount) {
|
|
49
|
+
showTooltip()
|
|
50
|
+
setTimeout(() => { hideTooltip() }, 3000)
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
function showTooltip() {
|
|
55
|
+
if (props.hoverText.length) {
|
|
56
|
+
isShowTooltip.value = true
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function hideTooltip() {
|
|
61
|
+
isShowTooltip.value = false
|
|
62
|
+
}
|
|
63
|
+
</script>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vanilla-vue-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -31,39 +31,53 @@
|
|
|
31
31
|
"copy": "npm run copy-template && npm run copy-basic && npm run copy-custom && npm run copy-icon && npm run copy-types && npm run copy-util"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"vue": "^
|
|
34
|
+
"@headlessui/vue": "^1.7.17",
|
|
35
|
+
"@heroicons/vue": "^2.1.1",
|
|
36
|
+
"dayjs": "^1.11.11",
|
|
37
|
+
"japanjs": "^0.1.6",
|
|
38
|
+
"konva": "^9.3.15",
|
|
39
|
+
"pinia": "^2.1.7",
|
|
40
|
+
"vue": "^3.3.11",
|
|
41
|
+
"vue-konva": "^3.1.0",
|
|
42
|
+
"vue-router": "^4.3.2"
|
|
35
43
|
},
|
|
36
44
|
"devDependencies": {
|
|
37
|
-
"@
|
|
38
|
-
"@storybook/addon-essentials": "^
|
|
39
|
-
"@storybook/addon-interactions": "^
|
|
40
|
-
"@storybook/addon-
|
|
41
|
-
"@storybook/
|
|
42
|
-
"@storybook/
|
|
43
|
-
"@storybook/
|
|
44
|
-
"@storybook/vue3
|
|
45
|
+
"@rushstack/eslint-patch": "^1.3.3",
|
|
46
|
+
"@storybook/addon-essentials": "^7.6.10",
|
|
47
|
+
"@storybook/addon-interactions": "^7.6.10",
|
|
48
|
+
"@storybook/addon-links": "^7.6.10",
|
|
49
|
+
"@storybook/addon-themes": "^7.6.20",
|
|
50
|
+
"@storybook/blocks": "^7.6.10",
|
|
51
|
+
"@storybook/test": "^7.6.10",
|
|
52
|
+
"@storybook/vue3": "^7.6.10",
|
|
53
|
+
"@storybook/vue3-vite": "^7.6.10",
|
|
54
|
+
"@tsconfig/node18": "^18.2.2",
|
|
45
55
|
"@tsconfig/node22": "^22.0.0",
|
|
46
|
-
"@types/jsdom": "^21.1.
|
|
47
|
-
"@types/node": "^
|
|
48
|
-
"@vitejs/plugin-vue": "^5.2
|
|
49
|
-
"@
|
|
50
|
-
"@vue/eslint-config-
|
|
51
|
-
"@vue/
|
|
52
|
-
"@vue/
|
|
53
|
-
"
|
|
56
|
+
"@types/jsdom": "^21.1.6",
|
|
57
|
+
"@types/node": "^18.19.3",
|
|
58
|
+
"@vitejs/plugin-vue": "^4.5.2",
|
|
59
|
+
"@vue/eslint-config-prettier": "^8.0.0",
|
|
60
|
+
"@vue/eslint-config-typescript": "^12.0.0",
|
|
61
|
+
"@vue/test-utils": "^2.4.3",
|
|
62
|
+
"@vue/tsconfig": "^0.5.0",
|
|
63
|
+
"autoprefixer": "^10.4.17",
|
|
54
64
|
"copyfiles": "^2.4.1",
|
|
55
|
-
"eslint": "^
|
|
56
|
-
"eslint-plugin-storybook": "^0.
|
|
57
|
-
"eslint-plugin-vue": "^9.
|
|
58
|
-
"jsdom": "^
|
|
59
|
-
"npm-run-all2": "^
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
65
|
+
"eslint": "^8.57.0",
|
|
66
|
+
"eslint-plugin-storybook": "^0.6.15",
|
|
67
|
+
"eslint-plugin-vue": "^9.27.0",
|
|
68
|
+
"jsdom": "^23.0.1",
|
|
69
|
+
"npm-run-all2": "^6.1.1",
|
|
70
|
+
"postcss": "^8.4.33",
|
|
71
|
+
"prettier": "^3.0.3",
|
|
72
|
+
"react": "^18.2.0",
|
|
73
|
+
"react-dom": "^18.2.0",
|
|
74
|
+
"storybook": "^7.6.10",
|
|
75
|
+
"tailwindcss": "^3.4.1",
|
|
76
|
+
"typescript": "~5.3.0",
|
|
77
|
+
"vite": "^5.0.10",
|
|
78
|
+
"vite-plugin-vue-devtools": "^7.7.2",
|
|
79
|
+
"vitest": "^1.0.4",
|
|
80
|
+
"vue-tsc": "^1.8.25"
|
|
67
81
|
},
|
|
68
82
|
"eslintConfig": {
|
|
69
83
|
"extends": [
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Replace vue3 with vue if you are using Storybook for Vue 2
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/vue3';
|
|
3
|
+
|
|
4
|
+
import FooterSimple from './WFooterSimple.vue';
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof FooterSimple> = {
|
|
7
|
+
component: FooterSimple,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export default meta;
|
|
11
|
+
type Story = StoryObj<typeof FooterSimple>;
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
*đ Render functions are a framework specific feature to allow you control on how the component renders.
|
|
15
|
+
* See https://storybook.js.org/docs/api/csf
|
|
16
|
+
* to learn how to use render functions.
|
|
17
|
+
*/
|
|
18
|
+
export const Primary: Story = {
|
|
19
|
+
render: () => ({
|
|
20
|
+
components: { FooterSimple },
|
|
21
|
+
template: '<FooterSimple></FooterSimple>',
|
|
22
|
+
}),
|
|
23
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<footer class="fixed bottom-0">
|
|
3
|
+
<div class="mb-4 ml-4">
|
|
4
|
+
<p class="text-center text-xs leading-5 text-gray-500">{{ props.text }}</p>
|
|
5
|
+
</div>
|
|
6
|
+
</footer>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script setup lang="ts">
|
|
10
|
+
import { defineProps, type PropType } from 'vue'
|
|
11
|
+
|
|
12
|
+
const props = defineProps({
|
|
13
|
+
text: {
|
|
14
|
+
type: String as PropType<string>,
|
|
15
|
+
required: false,
|
|
16
|
+
default: `© 2020 Your Company, Inc. All rights reserved.`
|
|
17
|
+
}
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
</script>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Replace vue3 with vue if you are using Storybook for Vue 2
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/vue3';
|
|
3
|
+
import NavigationDrawer from './NavigationDrawer.vue';
|
|
4
|
+
import {
|
|
5
|
+
HomeIcon,
|
|
6
|
+
BellAlertIcon,
|
|
7
|
+
ChatBubbleBottomCenterTextIcon,
|
|
8
|
+
Cog6ToothIcon,
|
|
9
|
+
CurrencyYenIcon,
|
|
10
|
+
CubeIcon,
|
|
11
|
+
BookOpenIcon,
|
|
12
|
+
MinusIcon
|
|
13
|
+
} from '@heroicons/vue/24/outline'
|
|
14
|
+
|
|
15
|
+
type NavigationDrawerProps = InstanceType<typeof NavigationDrawer>['$props']
|
|
16
|
+
|
|
17
|
+
const meta: Meta<typeof NavigationDrawer> = {
|
|
18
|
+
component: NavigationDrawer,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default meta;
|
|
22
|
+
type Story = StoryObj<typeof NavigationDrawer>;
|
|
23
|
+
|
|
24
|
+
/*
|
|
25
|
+
*đ Render functions are a framework specific feature to allow you control on how the component renders.
|
|
26
|
+
* See https://storybook.js.org/docs/api/csf
|
|
27
|
+
* to learn how to use render functions.
|
|
28
|
+
*/
|
|
29
|
+
export const Primary: Story = {
|
|
30
|
+
render: (args: NavigationDrawerProps) => ({
|
|
31
|
+
setup() {
|
|
32
|
+
return {
|
|
33
|
+
...args
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
components: { NavigationDrawer },
|
|
37
|
+
template: '<NavigationDrawer :title="title" :navigationTop="navigationTop" :navigationBottom="navigationBottom"></NavigationDrawer>',
|
|
38
|
+
}),
|
|
39
|
+
args: {
|
|
40
|
+
title: 'ăăă·ă„ăăŒă',
|
|
41
|
+
navigationTop: [
|
|
42
|
+
{ name: 'ăĄăă„ăŒ', href: '/menu', onClick: undefined, icon: HomeIcon, current: false },
|
|
43
|
+
{ name: 'ăȘăŻăšăčă', href: '/request', icon: CubeIcon, current: false },
|
|
44
|
+
{ name: '汄æŽ', href: '/history', icon: BookOpenIcon, current: false },
|
|
45
|
+
{ name: 'æŻæă', href: '/payment', icon: CurrencyYenIcon, current: false, isOpen: true,
|
|
46
|
+
subItems: [
|
|
47
|
+
{ name: 'çŸé', href: '/payment', icon: MinusIcon, current: false },
|
|
48
|
+
{ name: 'ăŻăŹăžăă', href: '/payment', icon: MinusIcon, current: false }
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
{ name: 'ăĄăă»ăŒăž', href: '/message', icon: BellAlertIcon, current: false },
|
|
52
|
+
{ name: 'ćăćăă', href: '/contact', icon: ChatBubbleBottomCenterTextIcon, current: false },
|
|
53
|
+
{ name: 'èšćź', href: '/setting', icon: Cog6ToothIcon, current: false },
|
|
54
|
+
],
|
|
55
|
+
navigationBottom: [
|
|
56
|
+
{ name: 'ăă°ăąăŠă', href: undefined, onClick: () => console.log('click.'), icon: undefined, current: undefined },
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
};
|