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.
Files changed (125) hide show
  1. package/dist/EUIButton.vue.d.ts.map +1 -0
  2. package/dist/library-vue-ts.cjs.js +4 -3
  3. package/dist/library-vue-ts.es.js +3 -8
  4. package/dist/library-vue-ts.umd.js +4 -3
  5. package/dist/select/EUISelect.vue.d.ts.map +1 -0
  6. package/package.json +4 -2
  7. package/src/App.vue +16 -0
  8. package/src/assets/fonts/gilroy/GilroyBold/font.woff +0 -0
  9. package/src/assets/fonts/gilroy/GilroyBold/font.woff2 +0 -0
  10. package/src/assets/fonts/gilroy/GilroyBoldItalic/font.woff +0 -0
  11. package/src/assets/fonts/gilroy/GilroyBoldItalic/font.woff2 +0 -0
  12. package/src/assets/fonts/gilroy/GilroyExtraBold/font.woff +0 -0
  13. package/src/assets/fonts/gilroy/GilroyExtraBold/font.woff2 +0 -0
  14. package/src/assets/fonts/gilroy/GilroyExtraBoldItalic/font.woff +0 -0
  15. package/src/assets/fonts/gilroy/GilroyExtraBoldItalic/font.woff2 +0 -0
  16. package/src/assets/fonts/gilroy/GilroyMedium/font.woff +0 -0
  17. package/src/assets/fonts/gilroy/GilroyMedium/font.woff2 +0 -0
  18. package/src/assets/fonts/gilroy/GilroyRegular/font.woff +0 -0
  19. package/src/assets/fonts/gilroy/GilroyRegular/font.woff2 +0 -0
  20. package/src/assets/fonts/gilroy/GilroySemiBold/font.woff +0 -0
  21. package/src/assets/fonts/gilroy/GilroySemiBold/font.woff2 +0 -0
  22. package/src/assets/fonts/inter/Inter-Bold.woff +0 -0
  23. package/src/assets/fonts/inter/Inter-Bold.woff2 +0 -0
  24. package/src/assets/fonts/inter/Inter-Italic.woff +0 -0
  25. package/src/assets/fonts/inter/Inter-Italic.woff2 +0 -0
  26. package/src/assets/fonts/inter/Inter-Medium.woff +0 -0
  27. package/src/assets/fonts/inter/Inter-Medium.woff2 +0 -0
  28. package/src/assets/fonts/inter/Inter-MediumItalic.woff +0 -0
  29. package/src/assets/fonts/inter/Inter-MediumItalic.woff2 +0 -0
  30. package/src/assets/fonts/inter/Inter-Regular.woff +0 -0
  31. package/src/assets/fonts/inter/Inter-Regular.woff2 +0 -0
  32. package/src/assets/fonts/inter/Inter-SemiBold.woff +0 -0
  33. package/src/assets/fonts/inter/Inter-SemiBold.woff2 +0 -0
  34. package/src/assets/fonts/inter/Inter-SemiBoldItalic.woff +0 -0
  35. package/src/assets/fonts/inter/Inter-SemiBoldItalic.woff2 +0 -0
  36. package/src/assets/scss/body.scss +15 -0
  37. package/src/assets/svg/ChevronDownSolid.vue +19 -0
  38. package/src/assets/svg/ChevronDownStroke.vue +22 -0
  39. package/src/assets/svg/SortArrow.vue +24 -0
  40. package/src/assets/svg/Student.vue +30 -0
  41. package/src/assets/svg/partner.vue +33 -0
  42. package/src/assets/svg/people.vue +25 -0
  43. package/src/assets/vue.svg +1 -0
  44. package/src/components/HelloWorld.vue +999 -0
  45. package/src/components/accordion/EUIAccordion.stories.ts +157 -0
  46. package/src/components/accordion/EUIAccordion.vue +90 -0
  47. package/src/components/avatar/EUIAvatar.stories.ts +157 -0
  48. package/src/components/avatar/EUIAvatar.vue +96 -0
  49. package/src/components/button/EUIButton.stories.ts +252 -0
  50. package/src/components/button/EUIButton.vue +151 -0
  51. package/src/components/checkbox/EUICheckbox.stories.ts +58 -0
  52. package/src/components/checkbox/EUICheckbox.vue +103 -0
  53. package/src/components/datepicker/EUIDatepicker.stories.ts +236 -0
  54. package/src/components/datepicker/EUIDatepicker.vue +185 -0
  55. package/src/components/delete.vue +108 -0
  56. package/src/components/dropdown/EUIMultiDropdown.stories.ts +187 -0
  57. package/src/components/dropdown/EUIMultiDropdown.vue +129 -0
  58. package/src/components/errorMessage/EUIErrorMessage.scss +0 -0
  59. package/src/components/errorMessage/EUIErrorMessage.stories.ts +41 -0
  60. package/src/components/errorMessage/EUIErrorMessage.vue +25 -0
  61. package/src/components/index.ts +46 -0
  62. package/src/components/input/EUIInput.stories.ts +174 -0
  63. package/src/components/input/EUIInput.vue +169 -0
  64. package/src/components/inputNormal/EUIInputNormal.stories.ts +164 -0
  65. package/src/components/inputNormal/EUIInputNormal.vue +161 -0
  66. package/src/components/loader/EUICircleLoader.vue +31 -0
  67. package/src/components/loader/EUICubeLoader.vue +237 -0
  68. package/src/components/loader/EUILoader.stories.ts +99 -0
  69. package/src/components/loader/EUILoader.vue +17 -0
  70. package/src/components/loader/EUISquareLoader.vue +47 -0
  71. package/src/components/modal/EUIModal.stories.ts +372 -0
  72. package/src/components/modal/EUIModal.vue +163 -0
  73. package/src/components/pillSelect/EUIPillSelect.stories.ts +74 -0
  74. package/src/components/pillSelect/EUIPillSelect.vue +149 -0
  75. package/src/components/popover/EUIPopover.stories.ts +247 -0
  76. package/src/components/popover/EUIPopover.vue +159 -0
  77. package/src/components/radio/EUIRadio.stories.ts +54 -0
  78. package/src/components/radio/EUIRadio.vue +78 -0
  79. package/src/components/searchInput/EUISearch.stories.ts +24 -0
  80. package/src/components/searchInput/EUISearch.vue +215 -0
  81. package/src/components/select/EUISelect.scss +0 -0
  82. package/src/components/select/EUISelect.stories.ts +49 -0
  83. package/src/components/select/EUISelect.vue +682 -0
  84. package/src/components/selectSearch/EUISelectSearch.vue +23 -0
  85. package/src/components/slideover/EUISlideover.stories.ts +318 -0
  86. package/src/components/slideover/EUISlideover.vue +207 -0
  87. package/src/components/stepperTimeline/EUIStepperHorizontal.vue +112 -0
  88. package/src/components/stepperTimeline/EUIStepperTimeline.stories.ts +54 -0
  89. package/src/components/stepperTimeline/EUIStepperTimeline.vue +16 -0
  90. package/src/components/stepperTimeline/EUIStepperVertical.vue +112 -0
  91. package/src/components/table/EUIDashboardTable.vue +482 -0
  92. package/src/components/table/EUIPageLimit.vue +66 -0
  93. package/src/components/table/EUIPagination.vue +175 -0
  94. package/src/components/table/EUIStudentPagination.vue +172 -0
  95. package/src/components/table/EUITable.stories.ts +190 -0
  96. package/src/components/table/EUITable.vue +508 -0
  97. package/src/components/table/EUITableCheckbox.vue +97 -0
  98. package/src/components/tabs/EUITabs.vue +128 -0
  99. package/src/components/tabs/EUItabs.stories.ts +123 -0
  100. package/src/components/tag/EUITag.stories.ts +46 -0
  101. package/src/components/tag/EUITag.vue +46 -0
  102. package/src/components/telephone/EUITelephone.stories.ts +202 -0
  103. package/src/components/telephone/EUITelephone.vue +280 -0
  104. package/src/components/textArea/EUITextArea.stories.ts +82 -0
  105. package/src/components/textArea/EUITextArea.vue +122 -0
  106. package/src/components/timeLine/EUITimeLine.stories.ts +247 -0
  107. package/src/components/timeLine/EUITimeLine.vue +43 -0
  108. package/src/components/timeLine/EUITimeLineItem.vue +124 -0
  109. package/src/components/toggle/EUIToggle.stories.ts +63 -0
  110. package/src/components/toggle/EUIToggle.vue +99 -0
  111. package/src/components/tooltip/EUITooltip.stories.ts +53 -0
  112. package/src/components/tooltip/EUITooltip.vue +108 -0
  113. package/src/data/books.ts +163 -0
  114. package/src/data/tab.ts +33 -0
  115. package/src/data/table.ts +5392 -0
  116. package/src/main.ts +5 -0
  117. package/src/utils/lodash.ts +9 -0
  118. package/src/utils/types.ts +9 -0
  119. package/src/vite-env.d.ts +5 -0
  120. package/dist/EUISelect.vue.d.ts.map +0 -1
  121. package/dist/button/EUIButton.vue.d.ts.map +0 -1
  122. package/dist/library-vue-ts.css +0 -1
  123. package/dist/style.scss +0 -118
  124. /package/dist/{button/EUIButton.vue.d.ts → EUIButton.vue.d.ts} +0 -0
  125. /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
+ };