edvoyui-component-library-test-flight 0.0.21 → 0.0.23
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/dist/EUIButton.vue.d.ts.map +1 -0
- package/dist/library-vue-ts.cjs.js +4 -3
- package/dist/library-vue-ts.es.js +3 -8
- package/dist/library-vue-ts.umd.js +4 -3
- package/dist/select/EUISelect.vue.d.ts.map +1 -0
- package/package.json +4 -2
- package/src/App.vue +16 -0
- package/src/assets/fonts/gilroy/GilroyBold/font.woff +0 -0
- package/src/assets/fonts/gilroy/GilroyBold/font.woff2 +0 -0
- package/src/assets/fonts/gilroy/GilroyBoldItalic/font.woff +0 -0
- package/src/assets/fonts/gilroy/GilroyBoldItalic/font.woff2 +0 -0
- package/src/assets/fonts/gilroy/GilroyExtraBold/font.woff +0 -0
- package/src/assets/fonts/gilroy/GilroyExtraBold/font.woff2 +0 -0
- package/src/assets/fonts/gilroy/GilroyExtraBoldItalic/font.woff +0 -0
- package/src/assets/fonts/gilroy/GilroyExtraBoldItalic/font.woff2 +0 -0
- package/src/assets/fonts/gilroy/GilroyMedium/font.woff +0 -0
- package/src/assets/fonts/gilroy/GilroyMedium/font.woff2 +0 -0
- package/src/assets/fonts/gilroy/GilroyRegular/font.woff +0 -0
- package/src/assets/fonts/gilroy/GilroyRegular/font.woff2 +0 -0
- package/src/assets/fonts/gilroy/GilroySemiBold/font.woff +0 -0
- package/src/assets/fonts/gilroy/GilroySemiBold/font.woff2 +0 -0
- package/src/assets/fonts/inter/Inter-Bold.woff +0 -0
- package/src/assets/fonts/inter/Inter-Bold.woff2 +0 -0
- package/src/assets/fonts/inter/Inter-Italic.woff +0 -0
- package/src/assets/fonts/inter/Inter-Italic.woff2 +0 -0
- package/src/assets/fonts/inter/Inter-Medium.woff +0 -0
- package/src/assets/fonts/inter/Inter-Medium.woff2 +0 -0
- package/src/assets/fonts/inter/Inter-MediumItalic.woff +0 -0
- package/src/assets/fonts/inter/Inter-MediumItalic.woff2 +0 -0
- package/src/assets/fonts/inter/Inter-Regular.woff +0 -0
- package/src/assets/fonts/inter/Inter-Regular.woff2 +0 -0
- package/src/assets/fonts/inter/Inter-SemiBold.woff +0 -0
- package/src/assets/fonts/inter/Inter-SemiBold.woff2 +0 -0
- package/src/assets/fonts/inter/Inter-SemiBoldItalic.woff +0 -0
- package/src/assets/fonts/inter/Inter-SemiBoldItalic.woff2 +0 -0
- package/src/assets/scss/body.scss +15 -0
- package/src/assets/svg/ChevronDownSolid.vue +19 -0
- package/src/assets/svg/ChevronDownStroke.vue +22 -0
- package/src/assets/svg/SortArrow.vue +24 -0
- package/src/assets/svg/Student.vue +30 -0
- package/src/assets/svg/partner.vue +33 -0
- package/src/assets/svg/people.vue +25 -0
- package/src/assets/vue.svg +1 -0
- package/src/components/HelloWorld.vue +999 -0
- package/src/components/accordion/EUIAccordion.stories.ts +157 -0
- package/src/components/accordion/EUIAccordion.vue +90 -0
- package/src/components/avatar/EUIAvatar.stories.ts +157 -0
- package/src/components/avatar/EUIAvatar.vue +96 -0
- package/src/components/button/EUIButton.stories.ts +252 -0
- package/src/components/button/EUIButton.vue +151 -0
- package/src/components/checkbox/EUICheckbox.stories.ts +58 -0
- package/src/components/checkbox/EUICheckbox.vue +103 -0
- package/src/components/datepicker/EUIDatepicker.stories.ts +236 -0
- package/src/components/datepicker/EUIDatepicker.vue +185 -0
- package/src/components/delete.vue +108 -0
- package/src/components/dropdown/EUIMultiDropdown.stories.ts +187 -0
- package/src/components/dropdown/EUIMultiDropdown.vue +129 -0
- package/src/components/errorMessage/EUIErrorMessage.scss +0 -0
- package/src/components/errorMessage/EUIErrorMessage.stories.ts +41 -0
- package/src/components/errorMessage/EUIErrorMessage.vue +25 -0
- package/src/components/index.ts +46 -0
- package/src/components/input/EUIInput.stories.ts +174 -0
- package/src/components/input/EUIInput.vue +169 -0
- package/src/components/inputNormal/EUIInputNormal.stories.ts +164 -0
- package/src/components/inputNormal/EUIInputNormal.vue +161 -0
- package/src/components/loader/EUICircleLoader.vue +31 -0
- package/src/components/loader/EUICubeLoader.vue +237 -0
- package/src/components/loader/EUILoader.stories.ts +99 -0
- package/src/components/loader/EUILoader.vue +17 -0
- package/src/components/loader/EUISquareLoader.vue +47 -0
- package/src/components/modal/EUIModal.stories.ts +372 -0
- package/src/components/modal/EUIModal.vue +163 -0
- package/src/components/pillSelect/EUIPillSelect.stories.ts +74 -0
- package/src/components/pillSelect/EUIPillSelect.vue +149 -0
- package/src/components/popover/EUIPopover.stories.ts +247 -0
- package/src/components/popover/EUIPopover.vue +159 -0
- package/src/components/radio/EUIRadio.stories.ts +54 -0
- package/src/components/radio/EUIRadio.vue +78 -0
- package/src/components/searchInput/EUISearch.stories.ts +24 -0
- package/src/components/searchInput/EUISearch.vue +215 -0
- package/src/components/select/EUISelect.scss +0 -0
- package/src/components/select/EUISelect.stories.ts +49 -0
- package/src/components/select/EUISelect.vue +682 -0
- package/src/components/selectSearch/EUISelectSearch.vue +23 -0
- package/src/components/slideover/EUISlideover.stories.ts +318 -0
- package/src/components/slideover/EUISlideover.vue +207 -0
- package/src/components/stepperTimeline/EUIStepperHorizontal.vue +112 -0
- package/src/components/stepperTimeline/EUIStepperTimeline.stories.ts +54 -0
- package/src/components/stepperTimeline/EUIStepperTimeline.vue +16 -0
- package/src/components/stepperTimeline/EUIStepperVertical.vue +112 -0
- package/src/components/table/EUIDashboardTable.vue +482 -0
- package/src/components/table/EUIPageLimit.vue +66 -0
- package/src/components/table/EUIPagination.vue +175 -0
- package/src/components/table/EUIStudentPagination.vue +172 -0
- package/src/components/table/EUITable.stories.ts +190 -0
- package/src/components/table/EUITable.vue +508 -0
- package/src/components/table/EUITableCheckbox.vue +97 -0
- package/src/components/tabs/EUITabs.vue +128 -0
- package/src/components/tabs/EUItabs.stories.ts +123 -0
- package/src/components/tag/EUITag.stories.ts +46 -0
- package/src/components/tag/EUITag.vue +46 -0
- package/src/components/telephone/EUITelephone.stories.ts +202 -0
- package/src/components/telephone/EUITelephone.vue +280 -0
- package/src/components/textArea/EUITextArea.stories.ts +82 -0
- package/src/components/textArea/EUITextArea.vue +122 -0
- package/src/components/timeLine/EUITimeLine.stories.ts +247 -0
- package/src/components/timeLine/EUITimeLine.vue +43 -0
- package/src/components/timeLine/EUITimeLineItem.vue +124 -0
- package/src/components/toggle/EUIToggle.stories.ts +63 -0
- package/src/components/toggle/EUIToggle.vue +99 -0
- package/src/components/tooltip/EUITooltip.stories.ts +53 -0
- package/src/components/tooltip/EUITooltip.vue +108 -0
- package/src/data/books.ts +163 -0
- package/src/data/tab.ts +33 -0
- package/src/data/table.ts +5392 -0
- package/src/main.ts +5 -0
- package/src/utils/lodash.ts +9 -0
- package/src/utils/types.ts +9 -0
- package/src/vite-env.d.ts +5 -0
- package/dist/EUISelect.vue.d.ts.map +0 -1
- package/dist/button/EUIButton.vue.d.ts.map +0 -1
- package/dist/library-vue-ts.css +0 -1
- package/dist/style.scss +0 -118
- /package/dist/{button/EUIButton.vue.d.ts → EUIButton.vue.d.ts} +0 -0
- /package/dist/{EUISelect.vue.d.ts → select/EUISelect.vue.d.ts} +0 -0
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/vue3";
|
|
2
|
+
import { action } from "@storybook/addon-actions";
|
|
3
|
+
import { ref } from "vue";
|
|
4
|
+
import EUISlideover from "./EUISlideover.vue";
|
|
5
|
+
import EUIButton from "../button/EUIButton.vue";
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof EUISlideover> = {
|
|
8
|
+
title: "Example/Slideover",
|
|
9
|
+
component: EUISlideover,
|
|
10
|
+
tags: ["autodocs"],
|
|
11
|
+
argTypes: {
|
|
12
|
+
...{
|
|
13
|
+
isVisible: {
|
|
14
|
+
control: "boolean",
|
|
15
|
+
description: "Controls the visibility of the EUISlideover.",
|
|
16
|
+
},
|
|
17
|
+
visibleClose: {
|
|
18
|
+
control: "boolean",
|
|
19
|
+
description: "Enables a slimmer header style for the slideover.",
|
|
20
|
+
defaultValue: true,
|
|
21
|
+
table: {
|
|
22
|
+
summary: true,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
size: {
|
|
26
|
+
control: { type: "select", options: ["xs", "sm", "md", "lg"] },
|
|
27
|
+
description: "Size of the slideover.",
|
|
28
|
+
defaultValue: "xs",
|
|
29
|
+
table: {
|
|
30
|
+
defaultValue: { summary: "xs" },
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
slidePosition: {
|
|
34
|
+
control: {
|
|
35
|
+
type: "select",
|
|
36
|
+
options: ["left", "center", "right"],
|
|
37
|
+
},
|
|
38
|
+
defaultValue: "right",
|
|
39
|
+
table: {
|
|
40
|
+
defaultValue: { summary: "right" },
|
|
41
|
+
},
|
|
42
|
+
description:
|
|
43
|
+
"Defines the position of the slideover. It can be placed at the `left` or `center` and `right` of the view.",
|
|
44
|
+
},
|
|
45
|
+
title: {
|
|
46
|
+
control: "text",
|
|
47
|
+
description: "Sets the title displayed in the slideover header.",
|
|
48
|
+
defaultValue: "Default slideover Title",
|
|
49
|
+
},
|
|
50
|
+
titleClass: {
|
|
51
|
+
control: "text",
|
|
52
|
+
description:
|
|
53
|
+
"CSS class for defining custom title decoration of the slideover.",
|
|
54
|
+
defaultValue: "",
|
|
55
|
+
},
|
|
56
|
+
"update:isVisible": {
|
|
57
|
+
action: "update:isVisible",
|
|
58
|
+
description:
|
|
59
|
+
"Triggers when the slideover's visibility is updated via the @update:isVisible event.",
|
|
60
|
+
},
|
|
61
|
+
confirm: {
|
|
62
|
+
action: "confirm",
|
|
63
|
+
description:
|
|
64
|
+
"Emits when the confirm button is clicked to your action then close the slideover.",
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export default meta;
|
|
71
|
+
type Story = StoryObj<typeof meta>;
|
|
72
|
+
|
|
73
|
+
// Default EUISlideover story with basic content
|
|
74
|
+
export const Default: Story = {
|
|
75
|
+
argTypes: {
|
|
76
|
+
slidePosition: {
|
|
77
|
+
control: "select",
|
|
78
|
+
options: ["left", "center", "right"],
|
|
79
|
+
},
|
|
80
|
+
size: {
|
|
81
|
+
control: "select",
|
|
82
|
+
options: ["xs", "sm", "md", "lg", "full"],
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
args: {
|
|
86
|
+
isVisible: false,
|
|
87
|
+
},
|
|
88
|
+
render: (args) => ({
|
|
89
|
+
components: { EUISlideover, EUIButton },
|
|
90
|
+
setup() {
|
|
91
|
+
const isslideoverVisible = ref(args.isVisible);
|
|
92
|
+
|
|
93
|
+
const openslideover = () => {
|
|
94
|
+
isslideoverVisible.value = true;
|
|
95
|
+
action("update:isVisible")(true);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const closeslideover = () => {
|
|
99
|
+
isslideoverVisible.value = false;
|
|
100
|
+
action("update:isVisible")(false);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
args,
|
|
105
|
+
isslideoverVisible,
|
|
106
|
+
openslideover,
|
|
107
|
+
closeslideover,
|
|
108
|
+
onConfirm: action("confirm"),
|
|
109
|
+
};
|
|
110
|
+
},
|
|
111
|
+
template: `
|
|
112
|
+
<EUIButton size="md" color="purple" @click="openslideover">Open slideover</EUIButton>
|
|
113
|
+
<EUISlideover v-bind="args" :isVisible="isslideoverVisible" @update:isVisible="closeslideover" @confirm="onConfirm">
|
|
114
|
+
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Minus
|
|
115
|
+
quas possimus ea culpa id voluptatum cumque, animi earum sequi,
|
|
116
|
+
aliquid eius omnis repellendus nihil soluta vitae a temporibus!
|
|
117
|
+
Perspiciatis, nihil?</p>
|
|
118
|
+
</EUISlideover>
|
|
119
|
+
`,
|
|
120
|
+
}),
|
|
121
|
+
parameters: {
|
|
122
|
+
docs: {
|
|
123
|
+
description: {
|
|
124
|
+
story:
|
|
125
|
+
"This story demonstrates a slideover component that is initially hidden. Clicking the 'Open slideover' button triggers the slideover to appear, and it can be closed through the close button inside the slideover or the cancel button. The slideover also includes a 'Confirm' button that emits a `confirm` event, which is logged in Storybook’s actions panel.",
|
|
126
|
+
},
|
|
127
|
+
source: {
|
|
128
|
+
code: `<script setup lang="ts">
|
|
129
|
+
import { ref } from "vue";
|
|
130
|
+
const isslideoverVisible = ref(false);
|
|
131
|
+
|
|
132
|
+
const openslideover = () => {
|
|
133
|
+
isslideoverVisible.value = true;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const closeslideover = () => {
|
|
137
|
+
isslideoverVisible.value = false;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const onActionslideover = () => {
|
|
141
|
+
alert("slideover Action working set validation");
|
|
142
|
+
closeslideover();
|
|
143
|
+
};
|
|
144
|
+
</script>
|
|
145
|
+
<template>
|
|
146
|
+
<EUIButton size="md" color="purple" @click="openslideover">Open slideover</EUIButton>
|
|
147
|
+
<EUISlideover
|
|
148
|
+
:isVisible="isslideoverVisible"
|
|
149
|
+
:slim-header="false"
|
|
150
|
+
@update:isVisible="isslideoverVisible = $event"
|
|
151
|
+
@confirm="onActionslideover"
|
|
152
|
+
>
|
|
153
|
+
<div>
|
|
154
|
+
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Minus quas
|
|
155
|
+
possimus ea culpa id voluptatum cumque, animi earum sequi, aliquid eius
|
|
156
|
+
omnis repellendus nihil soluta vitae a temporibus! Perspiciatis, nihil?
|
|
157
|
+
</div>
|
|
158
|
+
</EUISlideover>
|
|
159
|
+
</template>
|
|
160
|
+
`,
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
// Custom EUISlideover story with different content
|
|
167
|
+
export const slideoverCustomize: Story = {
|
|
168
|
+
args: {
|
|
169
|
+
isVisible: false, // EUISlideover is visible by default
|
|
170
|
+
size: "md",
|
|
171
|
+
slidePosition: "left",
|
|
172
|
+
},
|
|
173
|
+
render: (args) => ({
|
|
174
|
+
components: { EUISlideover, EUIButton },
|
|
175
|
+
setup() {
|
|
176
|
+
const isslideoverVisible = ref(args.isVisible);
|
|
177
|
+
|
|
178
|
+
const openslideover = () => {
|
|
179
|
+
isslideoverVisible.value = true;
|
|
180
|
+
action("update:isVisible")(true);
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const closeslideover = () => {
|
|
184
|
+
isslideoverVisible.value = false;
|
|
185
|
+
action("update:isVisible")(false);
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
const onActionslideover = () => {
|
|
189
|
+
alert("slideover Action working set validation");
|
|
190
|
+
closeslideover();
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
return {
|
|
194
|
+
args,
|
|
195
|
+
isslideoverVisible,
|
|
196
|
+
openslideover,
|
|
197
|
+
closeslideover,
|
|
198
|
+
onActionslideover,
|
|
199
|
+
onConfirm: action("confirm"),
|
|
200
|
+
};
|
|
201
|
+
},
|
|
202
|
+
template: `
|
|
203
|
+
<EUIButton size="md" color="purple" @click="openslideover">Open slideover</EUIButton>
|
|
204
|
+
<EUISlideover v-bind="args" :isVisible="isslideoverVisible" slidePosition="left"
|
|
205
|
+
size="md" @update:isVisible="closeslideover" @confirm="onConfirm">
|
|
206
|
+
<template #header>
|
|
207
|
+
<div
|
|
208
|
+
class="sticky inset-x-0 top-0 px-6 py-4 text-base font-semibold bg-white border-b"
|
|
209
|
+
>
|
|
210
|
+
Custom slideover header section
|
|
211
|
+
</div>
|
|
212
|
+
</template>
|
|
213
|
+
<template #content>
|
|
214
|
+
<div
|
|
215
|
+
class="p-4 max-h-[calc(100svh-6rem)] overflow-y-auto space-y-4"
|
|
216
|
+
>
|
|
217
|
+
<div v-for="item in 10" :key="item">
|
|
218
|
+
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Minus
|
|
219
|
+
quas possimus ea culpa id voluptatum cumque, animi earum sequi,
|
|
220
|
+
aliquid eius omnis repellendus nihil soluta vitae a temporibus!
|
|
221
|
+
Perspiciatis, nihil?
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
</template>
|
|
225
|
+
<template #footer>
|
|
226
|
+
<div
|
|
227
|
+
class="sticky inset-x-0 bottom-0 flex items-center justify-end gap-4 p-4 bg-white border-t border-gray-200"
|
|
228
|
+
>
|
|
229
|
+
<button
|
|
230
|
+
class="px-4 py-2 text-base font-semibold tracking-wide text-gray-600 transition-colors duration-75 bg-white rounded-md hover:bg-gray-100"
|
|
231
|
+
@click="closeslideover"
|
|
232
|
+
>
|
|
233
|
+
Cancel
|
|
234
|
+
</button>
|
|
235
|
+
<button
|
|
236
|
+
class="px-4 py-2 text-base font-semibold tracking-wide text-white transition-colors duration-75 bg-purple-600 rounded-md hover:bg-purple-700"
|
|
237
|
+
@click="onActionslideover"
|
|
238
|
+
>
|
|
239
|
+
Apply now
|
|
240
|
+
</button>
|
|
241
|
+
</div>
|
|
242
|
+
</template>
|
|
243
|
+
</EUISlideover>
|
|
244
|
+
`,
|
|
245
|
+
}),
|
|
246
|
+
parameters: {
|
|
247
|
+
docs: {
|
|
248
|
+
description: {
|
|
249
|
+
story:
|
|
250
|
+
"* The template method allows you to define how content is rendered in the <mark>EUISlideover</mark> component. \n\n* Named slots <mark>(#header, #content, #footer)</mark> enable you to customize slideover.",
|
|
251
|
+
},
|
|
252
|
+
source: {
|
|
253
|
+
code: `<script setup lang="ts">
|
|
254
|
+
import { ref } from "vue";
|
|
255
|
+
const isslideoverVisible = ref(false);
|
|
256
|
+
|
|
257
|
+
const openslideover = () => {
|
|
258
|
+
isslideoverVisible.value = true;
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
const closeslideover = () => {
|
|
262
|
+
isslideoverVisible.value = false;
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
const onActionslideover = () => {
|
|
266
|
+
alert("slideover Action working set validation");
|
|
267
|
+
closeslideover();
|
|
268
|
+
};
|
|
269
|
+
</script>
|
|
270
|
+
<template>
|
|
271
|
+
<EUIButton size="md" color="purple" @click="openslideover">Open slideover</EUIButton>
|
|
272
|
+
<EUISlideover
|
|
273
|
+
:isVisible="isslideoverVisible"
|
|
274
|
+
slidePosition="left"
|
|
275
|
+
size="md"
|
|
276
|
+
@update:isVisible="isslideoverVisible = $event"
|
|
277
|
+
@confirm="closeslideover"
|
|
278
|
+
>
|
|
279
|
+
<template #header>
|
|
280
|
+
<div class="sticky inset-x-0 top-0 px-6 py-4 text-base font-semibold bg-white border-b">
|
|
281
|
+
Custom Header here
|
|
282
|
+
</div>
|
|
283
|
+
</template>
|
|
284
|
+
<template #content>
|
|
285
|
+
<div class="p-4 max-h-[calc(100svh-6rem)] overflow-y-auto space-y-4">
|
|
286
|
+
<div v-for="item in 10" :key="item">
|
|
287
|
+
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Minus quas
|
|
288
|
+
possimus ea culpa id voluptatum cumque, animi earum sequi, aliquid
|
|
289
|
+
eius omnis repellendus nihil soluta vitae a temporibus! Perspiciatis,
|
|
290
|
+
nihil?
|
|
291
|
+
</div>
|
|
292
|
+
</div>
|
|
293
|
+
</template>
|
|
294
|
+
<template #footer>
|
|
295
|
+
<div
|
|
296
|
+
class="sticky inset-x-0 bottom-0 flex items-center justify-end gap-4 p-4 bg-white border-t border-gray-200"
|
|
297
|
+
>
|
|
298
|
+
<button
|
|
299
|
+
class="px-4 py-2 text-base font-semibold tracking-wide text-gray-600 transition-colors duration-75 bg-white rounded-md hover:bg-gray-100"
|
|
300
|
+
@click="closeslideover()"
|
|
301
|
+
>
|
|
302
|
+
Cancel
|
|
303
|
+
</button>
|
|
304
|
+
<button
|
|
305
|
+
class="px-4 py-2 text-base font-semibold tracking-wide text-white transition-colors duration-75 bg-purple-600 rounded-md hover:bg-purple-700"
|
|
306
|
+
@click="onActionslideover()"
|
|
307
|
+
>
|
|
308
|
+
Apply now
|
|
309
|
+
</button>
|
|
310
|
+
</div>
|
|
311
|
+
</template>
|
|
312
|
+
</EUISlideover>
|
|
313
|
+
</template>
|
|
314
|
+
`,
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
};
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Teleport defer to="body">
|
|
3
|
+
<Transition :duration="550" appear name="slideover">
|
|
4
|
+
<div
|
|
5
|
+
v-if="isVisible"
|
|
6
|
+
:class="[
|
|
7
|
+
'fixed z-50 transition-all duration-100 ease-in',
|
|
8
|
+
slideClass.modal,
|
|
9
|
+
]"
|
|
10
|
+
@click.self="closeSlideover"
|
|
11
|
+
>
|
|
12
|
+
<div
|
|
13
|
+
class="backdrop fixed inset-0 z-[-1] w-screen h-screen bg-black/20 pointer-events-none overflow-hidden"
|
|
14
|
+
></div>
|
|
15
|
+
<div
|
|
16
|
+
:class="[
|
|
17
|
+
'relative flex flex-col justify-between w-full overflow-hidden bg-white divide-gray-200 divide-y shadow-lg h-full',
|
|
18
|
+
slideClass.width,
|
|
19
|
+
]"
|
|
20
|
+
>
|
|
21
|
+
<template v-if="$slots.header">
|
|
22
|
+
<slot name="header"></slot>
|
|
23
|
+
</template>
|
|
24
|
+
<div
|
|
25
|
+
v-else
|
|
26
|
+
class="sticky top-0 flex items-center justify-between flex-initial px-4 py-3"
|
|
27
|
+
>
|
|
28
|
+
<h3 :class="['text-lg font-semibold text-gray-900', titleClass]">
|
|
29
|
+
<slot name="title">{{ title || "Slideover Title" }}</slot>
|
|
30
|
+
</h3>
|
|
31
|
+
<div v-if="visibleClose">
|
|
32
|
+
<button
|
|
33
|
+
type="button"
|
|
34
|
+
class="flex items-center justify-center text-gray-400 bg-white hover:bg-gray-50 rounded-3xl hover:text-gray-600 size-8"
|
|
35
|
+
@click="closeSlideover"
|
|
36
|
+
>
|
|
37
|
+
<span class="sr-only">Close</span>
|
|
38
|
+
<svg
|
|
39
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
40
|
+
fill="none"
|
|
41
|
+
viewBox="0 0 24 24"
|
|
42
|
+
stroke-width="2"
|
|
43
|
+
stroke="currentColor"
|
|
44
|
+
aria-hidden="true"
|
|
45
|
+
class="w-5 h-5"
|
|
46
|
+
>
|
|
47
|
+
<path
|
|
48
|
+
stroke-linecap="round"
|
|
49
|
+
stroke-linejoin="round"
|
|
50
|
+
d="M6 18L18 6M6 6l12 12"
|
|
51
|
+
></path>
|
|
52
|
+
</svg>
|
|
53
|
+
</button>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<template v-if="$slots.content">
|
|
58
|
+
<slot name="content"></slot>
|
|
59
|
+
</template>
|
|
60
|
+
<div
|
|
61
|
+
v-else
|
|
62
|
+
class="flex-1 p-4 max-h-[calc(100svh-3rem)] overflow-y-auto"
|
|
63
|
+
>
|
|
64
|
+
<slot></slot>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<template v-if="$slots.footer">
|
|
68
|
+
<slot name="footer"></slot>
|
|
69
|
+
</template>
|
|
70
|
+
<div
|
|
71
|
+
v-else
|
|
72
|
+
class="sticky bottom-0 flex items-center justify-end flex-none gap-2 px-4 py-3"
|
|
73
|
+
>
|
|
74
|
+
<EUIButton size="md" color="white" @click="closeSlideover"
|
|
75
|
+
>Cancel</EUIButton
|
|
76
|
+
>
|
|
77
|
+
<EUIButton size="md" color="purple" @click="$emit('confirm')"
|
|
78
|
+
>Slideover</EUIButton
|
|
79
|
+
>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
</Transition>
|
|
84
|
+
</Teleport>
|
|
85
|
+
</template>
|
|
86
|
+
|
|
87
|
+
<script lang="ts">
|
|
88
|
+
import { computed, defineComponent, PropType, watchEffect } from "vue";
|
|
89
|
+
import EUIButton from "../button/EUIButton.vue";
|
|
90
|
+
|
|
91
|
+
export default defineComponent({
|
|
92
|
+
name: "Slideover",
|
|
93
|
+
components: {
|
|
94
|
+
EUIButton,
|
|
95
|
+
},
|
|
96
|
+
props: {
|
|
97
|
+
isVisible: {
|
|
98
|
+
type: Boolean,
|
|
99
|
+
default: false,
|
|
100
|
+
},
|
|
101
|
+
title: {
|
|
102
|
+
type: String,
|
|
103
|
+
default: "",
|
|
104
|
+
},
|
|
105
|
+
visibleClose: {
|
|
106
|
+
type: Boolean,
|
|
107
|
+
default: true,
|
|
108
|
+
},
|
|
109
|
+
titleClass: {
|
|
110
|
+
type: String,
|
|
111
|
+
default: "",
|
|
112
|
+
},
|
|
113
|
+
slidePosition: {
|
|
114
|
+
type: String as PropType<"left" | "center" | "right">,
|
|
115
|
+
default: "right",
|
|
116
|
+
},
|
|
117
|
+
size: {
|
|
118
|
+
type: String as PropType<"xs" | "sm" | "md" | "lg" | "full">,
|
|
119
|
+
default: "xs",
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
emits: ["update:isVisible", "confirm"],
|
|
123
|
+
methods: {
|
|
124
|
+
closeSlideover() {
|
|
125
|
+
this.$emit("update:isVisible", false);
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
setup(props) {
|
|
129
|
+
const slideClass = computed(() => {
|
|
130
|
+
const sizeClass = {
|
|
131
|
+
full: "max-w-screen",
|
|
132
|
+
lg: "max-w-screen-lg min-w-[1024px]",
|
|
133
|
+
md: "max-w-2xl min-w-[42rem]",
|
|
134
|
+
sm: "max-w-xl min-w-[36rem]",
|
|
135
|
+
xs: "max-w-md min-w-[28rem]",
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const positionClasses = {
|
|
139
|
+
left:
|
|
140
|
+
props.size === "full"
|
|
141
|
+
? "inset-2 rounded-xl overflow-hidden"
|
|
142
|
+
: "top-0 left-0 h-svh",
|
|
143
|
+
center:
|
|
144
|
+
props.size === "full"
|
|
145
|
+
? "inset-2 rounded-xl overflow-hidden"
|
|
146
|
+
: "inset-0 flex flex-col items-center justify-center",
|
|
147
|
+
right:
|
|
148
|
+
props.size === "full"
|
|
149
|
+
? "inset-2 rounded-xl overflow-hidden"
|
|
150
|
+
: "top-0 right-0 h-svh",
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const addClass = positionClasses[props.slidePosition];
|
|
154
|
+
const slideWidth = sizeClass[props.size];
|
|
155
|
+
return {
|
|
156
|
+
modal: addClass,
|
|
157
|
+
width: slideWidth,
|
|
158
|
+
};
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
watchEffect(() => {
|
|
162
|
+
if (props.isVisible) {
|
|
163
|
+
document.body.style.overflow = "hidden";
|
|
164
|
+
} else {
|
|
165
|
+
document.body.style.overflow = "";
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
return {
|
|
169
|
+
slideClass,
|
|
170
|
+
};
|
|
171
|
+
},
|
|
172
|
+
beforeUnmount() {
|
|
173
|
+
document.body.style.overflow = "";
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
</script>
|
|
177
|
+
|
|
178
|
+
<style lang="scss" scoped>
|
|
179
|
+
.slideover-enter-active,
|
|
180
|
+
.slideover-leave-active {
|
|
181
|
+
transition: transform 0.5s ease, opacity 0.5s ease;
|
|
182
|
+
}
|
|
183
|
+
.slideover-enter-from,
|
|
184
|
+
.slideover-leave-to {
|
|
185
|
+
transform: translateX(100%);
|
|
186
|
+
opacity: 0;
|
|
187
|
+
}
|
|
188
|
+
.slideover-enter-to,
|
|
189
|
+
.slideover-leave-from {
|
|
190
|
+
transform: translateX(0);
|
|
191
|
+
opacity: 1;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.backdrop {
|
|
195
|
+
transition: opacity 0.8s ease;
|
|
196
|
+
}
|
|
197
|
+
.slideover-enter-from .backdrop,
|
|
198
|
+
.slideover-leave-to .backdrop {
|
|
199
|
+
transform: translateX(100%);
|
|
200
|
+
opacity: 0;
|
|
201
|
+
}
|
|
202
|
+
.slideover-enter-to .backdrop,
|
|
203
|
+
.slideover-leave-from .backdrop {
|
|
204
|
+
transform: translateX(0);
|
|
205
|
+
opacity: 0.3;
|
|
206
|
+
}
|
|
207
|
+
</style>
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<nav aria-label="Progress" class="relative z-10">
|
|
3
|
+
<ol role="list" class="flex flex-row items-start justify-center w-full py-4 ps-4 pe-2">
|
|
4
|
+
<li
|
|
5
|
+
v-for="(step, stepIdx) in lifeCycleEntries"
|
|
6
|
+
:key="step.value"
|
|
7
|
+
:class="[
|
|
8
|
+
stepIdx !== lifeCycleEntries.length - 1 ? 'pe-8' : '',
|
|
9
|
+
'relative flex items-center w-full pt-6 group',
|
|
10
|
+
getStatus(step.key, stepIdx) === 'upcoming'
|
|
11
|
+
? 'pointer-events-none'
|
|
12
|
+
: '',
|
|
13
|
+
]"
|
|
14
|
+
>
|
|
15
|
+
<template v-if="getStatus(step.key, stepIdx) === 'complete'">
|
|
16
|
+
<div
|
|
17
|
+
v-if="stepIdx !== lifeCycleEntries.length - 1"
|
|
18
|
+
class="absolute bg-green-500 w-full start-0 top-2.5 h-[0.0875rem] z-0"
|
|
19
|
+
/>
|
|
20
|
+
<div class="absolute top-0 start-0 flex items-center size-5 bg-green-500 rounded-full border-[1.5px] border-green-500" >
|
|
21
|
+
<svg fill="currentColor" width="16" height="16" viewBox="0 0 24 24" class="text-white size-4"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"><title>Check icon</title></path></svg>
|
|
22
|
+
</div>
|
|
23
|
+
<div class="flex flex-col items-start justify-between max-w-full w-full py-0.5">
|
|
24
|
+
<span class="text-xs font-semibold text-gray-900">{{ startCase(step.value) }}</span>
|
|
25
|
+
<span class="text-xs font-medium text-gray-500">{{'26-05-2024 18:47'}}</span>
|
|
26
|
+
</div>
|
|
27
|
+
</template>
|
|
28
|
+
<template v-else-if="getStatus(step.key, stepIdx) === 'current'">
|
|
29
|
+
<div
|
|
30
|
+
class="absolute bg-orange-500 w-full start-0 top-2.5 h-[0.0875rem] z-0"
|
|
31
|
+
/>
|
|
32
|
+
<div class="absolute start-0 top-0 flex items-center justify-center size-5 rounded-full bg-white border-[1.5px] border-orange-500">
|
|
33
|
+
<div class="size-2.5 bg-orange-400 rounded-full" />
|
|
34
|
+
</div>
|
|
35
|
+
<div class="flex flex-col items-start justify-between max-w-full w-full py-0.5">
|
|
36
|
+
<span class="text-xs font-semibold text-gray-900">{{ startCase(step.value) }}</span>
|
|
37
|
+
<span class="text-xs font-medium text-gray-500">{{'26-05-2024 18:47'}}</span>
|
|
38
|
+
</div>
|
|
39
|
+
</template>
|
|
40
|
+
<template v-else-if="getStatus(step.key, stepIdx) === 'upcoming'">
|
|
41
|
+
<div
|
|
42
|
+
v-if="stepIdx !== lifeCycleEntries.length - 1"
|
|
43
|
+
class="absolute bg-gray-300 w-full start-0 top-2.5 h-[0.0875rem] z-0"
|
|
44
|
+
/>
|
|
45
|
+
<div class="absolute top-0 start-0 flex items-center justify-center size-5 rounded-full bg-gray-100 border-gray-300 border-[1.5px]">
|
|
46
|
+
<div class="bg-gray-200 rounded-full size-3" />
|
|
47
|
+
</div>
|
|
48
|
+
<div class="flex flex-col items-start justify-between max-w-full w-full py-0.5">
|
|
49
|
+
<span class="text-xs font-semibold text-gray-900">{{ startCase(step.value) }}</span>
|
|
50
|
+
<span class="text-xs font-medium text-gray-500">{{'26-05-2024 18:47'}}</span>
|
|
51
|
+
</div>
|
|
52
|
+
</template>
|
|
53
|
+
</li>
|
|
54
|
+
</ol>
|
|
55
|
+
</nav>
|
|
56
|
+
</template>
|
|
57
|
+
<script setup lang="ts">
|
|
58
|
+
import { startCase } from 'lodash';
|
|
59
|
+
import { computed, PropType } from 'vue';
|
|
60
|
+
|
|
61
|
+
const props = defineProps({
|
|
62
|
+
stepStatus: {
|
|
63
|
+
type: String as PropType<"contact" | "MQL" | 'SQL' | 'opportunity' | 'Prospect' | 'Prospect Paid' | 'Prospect Enrolled' | 'Customer'>,
|
|
64
|
+
default: 'contact'
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
const stepStatusEnum = ["contact" , "MQL" , 'SQL' , 'opportunity' , 'Prospect' , 'Prospect Paid' , 'Prospect Enrolled' , 'Customer']
|
|
69
|
+
|
|
70
|
+
const lifeCycleEntries = computed(() => {
|
|
71
|
+
return Object.entries(stepStatusEnum).map((x) => {
|
|
72
|
+
return { key: x[0], value: x[1] }
|
|
73
|
+
})
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
const lifeCycleState = computed(() => {
|
|
77
|
+
return currentStatus.value
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
const currentStatus = computed(() => props.stepStatus)
|
|
81
|
+
|
|
82
|
+
const status = computed(() => lifeCycleState.value)
|
|
83
|
+
|
|
84
|
+
const lifeCycle = computed(() => {
|
|
85
|
+
return lifeCycleEntries.value.findIndex((e) => e.value === status.value)
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
const getStatus = computed(() => {
|
|
89
|
+
return (status: string, index: number) => {
|
|
90
|
+
if (
|
|
91
|
+
index &&
|
|
92
|
+
lifeCycle.value === lifeCycleEntries.value.length - 1
|
|
93
|
+
) {
|
|
94
|
+
return 'complete'
|
|
95
|
+
}
|
|
96
|
+
if (index === lifeCycle.value) {
|
|
97
|
+
return 'current'
|
|
98
|
+
}
|
|
99
|
+
if (index < lifeCycle.value) {
|
|
100
|
+
return 'complete'
|
|
101
|
+
}
|
|
102
|
+
if (index > lifeCycle.value) {
|
|
103
|
+
return 'upcoming'
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
status,
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
})
|
|
110
|
+
</script>
|
|
111
|
+
<style lang="scss">
|
|
112
|
+
</style>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/vue3";
|
|
2
|
+
import EUIStepperHorizontal from "./EUIStepperHorizontal.vue";
|
|
3
|
+
import EUIStepperVertical from "./EUIStepperVertical.vue";
|
|
4
|
+
|
|
5
|
+
const meta = {
|
|
6
|
+
title: "Example/Stepper Timeline",
|
|
7
|
+
component: EUIStepperVertical,
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
argTypes: {
|
|
10
|
+
stepStatus: {
|
|
11
|
+
control: "select",
|
|
12
|
+
options: [
|
|
13
|
+
"Contact",
|
|
14
|
+
"MQL",
|
|
15
|
+
"SQL",
|
|
16
|
+
"opportunity",
|
|
17
|
+
"Prospect",
|
|
18
|
+
"Prospect Paid",
|
|
19
|
+
"Prospect Enrolled",
|
|
20
|
+
"Customer",
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
} satisfies Meta<typeof EUIStepperVertical>;
|
|
25
|
+
|
|
26
|
+
export default meta;
|
|
27
|
+
type Story = StoryObj<typeof meta>;
|
|
28
|
+
|
|
29
|
+
export const StepperVertical: Story = {
|
|
30
|
+
args: {
|
|
31
|
+
stepStatus: "opportunity",
|
|
32
|
+
},
|
|
33
|
+
render: (args) => ({
|
|
34
|
+
components: { EUIStepperVertical },
|
|
35
|
+
setup() {
|
|
36
|
+
return { args };
|
|
37
|
+
},
|
|
38
|
+
template: `<EUIStepperVertical v-bind="args" />`,
|
|
39
|
+
}),
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const StepperHorizontal: Story = {
|
|
43
|
+
argTypes: {},
|
|
44
|
+
args: {
|
|
45
|
+
stepStatus: "Prospect",
|
|
46
|
+
},
|
|
47
|
+
render: (args) => ({
|
|
48
|
+
components: { EUIStepperHorizontal },
|
|
49
|
+
setup() {
|
|
50
|
+
return { args };
|
|
51
|
+
},
|
|
52
|
+
template: `<EUIStepperHorizontal v-bind="args" />`,
|
|
53
|
+
}),
|
|
54
|
+
};
|