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,149 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<p v-if="label" class="mb-3 text-sm font-medium text-gray-500 font-inter">
|
|
4
|
+
{{ label }}<span v-if="required" class="text-red-500">*</span>
|
|
5
|
+
</p>
|
|
6
|
+
<div class="flex flex-row flex-wrap gap-3">
|
|
7
|
+
<EUIButton
|
|
8
|
+
v-for="(item, idx) in items"
|
|
9
|
+
:key="`${name}-${idx}`"
|
|
10
|
+
type="button"
|
|
11
|
+
size="md"
|
|
12
|
+
color="white"
|
|
13
|
+
:class="[
|
|
14
|
+
isSelected(item)
|
|
15
|
+
? '!bg-purple-100 !text-purple-600 !font-medium shadow-sm'
|
|
16
|
+
: '!bg-gray-100 !text-gray-600 !font-medium hover:text-gray-800',
|
|
17
|
+
'px-4 py-2 text-sm leading-6 focus:outline-none rounded-3xl transition-colors duration-100 ease-in-out',
|
|
18
|
+
]"
|
|
19
|
+
rounded
|
|
20
|
+
@click="handleSelect(item)"
|
|
21
|
+
:disabled="disabled"
|
|
22
|
+
>
|
|
23
|
+
{{
|
|
24
|
+
ignoreStartCase
|
|
25
|
+
? item[labelKey] || ""
|
|
26
|
+
: startCase(item[labelKey] || "")
|
|
27
|
+
}}
|
|
28
|
+
</EUIButton>
|
|
29
|
+
</div>
|
|
30
|
+
<div class="ml-2 mt-1">
|
|
31
|
+
<EUIErrorMessage :name="name" :errors="errors" />
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
</template>
|
|
35
|
+
|
|
36
|
+
<script setup lang="ts">
|
|
37
|
+
import { startCase } from "lodash";
|
|
38
|
+
import EUIButton from "../button/EUIButton.vue";
|
|
39
|
+
import EUIErrorMessage from "../errorMessage/EUIErrorMessage.vue";
|
|
40
|
+
import { PropType, computed, toRefs, watch } from "vue";
|
|
41
|
+
import { ErrorObject, ValidationErrors } from "../../utils/types";
|
|
42
|
+
const props = defineProps({
|
|
43
|
+
label: {
|
|
44
|
+
type: String,
|
|
45
|
+
default: "",
|
|
46
|
+
},
|
|
47
|
+
modelValue: {
|
|
48
|
+
type: Object as PropType<any | null>,
|
|
49
|
+
default: null,
|
|
50
|
+
},
|
|
51
|
+
labelKey: {
|
|
52
|
+
type: String,
|
|
53
|
+
default: "label",
|
|
54
|
+
},
|
|
55
|
+
valueKey: {
|
|
56
|
+
type: String,
|
|
57
|
+
default: "value",
|
|
58
|
+
},
|
|
59
|
+
items: {
|
|
60
|
+
type: Array<any>,
|
|
61
|
+
default: [],
|
|
62
|
+
},
|
|
63
|
+
multiple: {
|
|
64
|
+
type: Boolean,
|
|
65
|
+
default: false,
|
|
66
|
+
},
|
|
67
|
+
name: {
|
|
68
|
+
type: String,
|
|
69
|
+
default: "",
|
|
70
|
+
},
|
|
71
|
+
disabled: {
|
|
72
|
+
type: Boolean,
|
|
73
|
+
deault: false,
|
|
74
|
+
},
|
|
75
|
+
required: {
|
|
76
|
+
type: Boolean,
|
|
77
|
+
deault: false,
|
|
78
|
+
},
|
|
79
|
+
errors: {
|
|
80
|
+
type: Object as PropType<ValidationErrors | ErrorObject[]>,
|
|
81
|
+
default: [],
|
|
82
|
+
},
|
|
83
|
+
ignoreStartCase: {
|
|
84
|
+
type: Boolean,
|
|
85
|
+
deault: false,
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
const { multiple, valueKey, labelKey, errors, ignoreStartCase } = toRefs(props);
|
|
89
|
+
const emit = defineEmits(["update:model-value","on-change"]);
|
|
90
|
+
const activeItem = computed({
|
|
91
|
+
set: (value) => {
|
|
92
|
+
emit("update:model-value", value);
|
|
93
|
+
},
|
|
94
|
+
get: () => props.modelValue,
|
|
95
|
+
});
|
|
96
|
+
const handleMultiSelect = (item: any) => {
|
|
97
|
+
if (Array.isArray(activeItem.value)) {
|
|
98
|
+
const index = activeItem.value?.findIndex(
|
|
99
|
+
(x) => x?.[valueKey.value] === item?.[valueKey.value]
|
|
100
|
+
);
|
|
101
|
+
if (index != -1) {
|
|
102
|
+
activeItem.value.splice(index, 1);
|
|
103
|
+
} else {
|
|
104
|
+
activeItem.value.push(item);
|
|
105
|
+
}
|
|
106
|
+
emit('on-change',activeItem.value)
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
const handleSingleSelect = (item: any) => {
|
|
110
|
+
if (!Array.isArray(activeItem.value)) {
|
|
111
|
+
if (activeItem.value?.[valueKey.value] === item?.[valueKey.value]) {
|
|
112
|
+
activeItem.value = null;
|
|
113
|
+
} else {
|
|
114
|
+
activeItem.value = item;
|
|
115
|
+
}
|
|
116
|
+
emit('on-change',activeItem.value)
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
const handleSelect = (item: any) => {
|
|
120
|
+
if (multiple.value) {
|
|
121
|
+
handleMultiSelect(item);
|
|
122
|
+
} else {
|
|
123
|
+
handleSingleSelect(item);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const isSelected = (item: any) => {
|
|
128
|
+
if (Array.isArray(activeItem.value)) {
|
|
129
|
+
const values = activeItem.value
|
|
130
|
+
.map((x) => x[valueKey.value])
|
|
131
|
+
.filter((x) => x);
|
|
132
|
+
return values.includes(item?.[valueKey.value]);
|
|
133
|
+
}
|
|
134
|
+
return activeItem.value?.[valueKey.value] === item?.[valueKey.value];
|
|
135
|
+
};
|
|
136
|
+
watch(
|
|
137
|
+
multiple,
|
|
138
|
+
() => {
|
|
139
|
+
if (multiple.value) {
|
|
140
|
+
if (!Array.isArray(activeItem.value)) {
|
|
141
|
+
activeItem.value = [activeItem.value];
|
|
142
|
+
}
|
|
143
|
+
} else {
|
|
144
|
+
activeItem.value = activeItem.value ? activeItem.value : null;
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
{ immediate: true }
|
|
148
|
+
);
|
|
149
|
+
</script>
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/vue3";
|
|
2
|
+
import EUIPopover from "./EUIPopover.vue";
|
|
3
|
+
import { InformationCircleIcon } from "@heroicons/vue/24/outline";
|
|
4
|
+
import { ref } from "vue";
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof EUIPopover> = {
|
|
7
|
+
title: "Example/Popover",
|
|
8
|
+
component: EUIPopover,
|
|
9
|
+
tags: ["autodocs"],
|
|
10
|
+
argTypes: {
|
|
11
|
+
title: {
|
|
12
|
+
control: "text",
|
|
13
|
+
description: "Sets the title for the popper content.",
|
|
14
|
+
},
|
|
15
|
+
trigger: {
|
|
16
|
+
control: { type: "select" },
|
|
17
|
+
options: ["click", "hover"],
|
|
18
|
+
description:
|
|
19
|
+
"Specifies the trigger for displaying the popper. Default is 'click'.",
|
|
20
|
+
defaultValue: "click",
|
|
21
|
+
table: {
|
|
22
|
+
defaultValue: { summary: "click" },
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
placement: {
|
|
26
|
+
control: { type: "select" },
|
|
27
|
+
options: ["top", "left", "bottom", "right", "bottom-start", "bottom-end"],
|
|
28
|
+
description:
|
|
29
|
+
"Defines the position of the popper relative to the reference element. Default is 'bottom'.",
|
|
30
|
+
defaultValue: "bottom",
|
|
31
|
+
table: {
|
|
32
|
+
defaultValue: { summary: "bottom" },
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
className: {
|
|
36
|
+
control: "text",
|
|
37
|
+
description:
|
|
38
|
+
"Additional CSS classes for styling the popper content container.",
|
|
39
|
+
},
|
|
40
|
+
customButton: {
|
|
41
|
+
control: "text",
|
|
42
|
+
description:
|
|
43
|
+
"CSS classes for styling the button that triggers the popper.",
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
} satisfies Meta<typeof EUIPopover>;
|
|
47
|
+
|
|
48
|
+
export default meta;
|
|
49
|
+
type Story = StoryObj<typeof meta>;
|
|
50
|
+
|
|
51
|
+
export const Default: Story = {
|
|
52
|
+
args: {
|
|
53
|
+
className: "max-w-64 min-w-64",
|
|
54
|
+
title: "Popper click to show",
|
|
55
|
+
customButton: "border border-gray-600 px-4 py-2 rounded-lg",
|
|
56
|
+
trigger: "click",
|
|
57
|
+
placement: "bottom",
|
|
58
|
+
},
|
|
59
|
+
render: (args) => ({
|
|
60
|
+
components: { EUIPopover },
|
|
61
|
+
setup() {
|
|
62
|
+
return { args };
|
|
63
|
+
},
|
|
64
|
+
template: `<div class="min-h-72 mx-auto max-w-xl p-6">
|
|
65
|
+
<EUIPopover v-bind="args">
|
|
66
|
+
<template #referenceButton>
|
|
67
|
+
Information
|
|
68
|
+
</template>
|
|
69
|
+
<div class="relative z-10 px-4 pb-4 pt-0 text-gray-900 bg-white rounded-lg shadow-lg text-start">
|
|
70
|
+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Minima, hic a quidem non delectus, est, ad voluptatum nostrum minus consequatur aut excepturi iste autem distinctio neque porro. Ipsa, quasi enim!
|
|
71
|
+
</div>
|
|
72
|
+
</EUIPopover>
|
|
73
|
+
</div>`,
|
|
74
|
+
}),
|
|
75
|
+
parameters: {
|
|
76
|
+
docs: {
|
|
77
|
+
description: {
|
|
78
|
+
story:
|
|
79
|
+
"This is the default configuration for the `EUIPopover` component, triggered by clicking the button.",
|
|
80
|
+
},
|
|
81
|
+
source: {
|
|
82
|
+
code: `<template>
|
|
83
|
+
<EUIPopover
|
|
84
|
+
trigger="click"
|
|
85
|
+
placement="bottom"
|
|
86
|
+
className="max-w-64 min-w-64"
|
|
87
|
+
title="Popper click to show"
|
|
88
|
+
customButton="border border-gray-600 px-4 py-2 rounded-lg"
|
|
89
|
+
>
|
|
90
|
+
<template #referenceButton>
|
|
91
|
+
Information
|
|
92
|
+
</template>
|
|
93
|
+
<!-- Popper Content Here... -->
|
|
94
|
+
<div
|
|
95
|
+
class="relative z-10 px-4 pt-0 pb-4 text-gray-900 bg-white rounded-lg shadow-lg text-start"
|
|
96
|
+
>
|
|
97
|
+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Minima, hic a
|
|
98
|
+
quidem non delectus, est, ad voluptatum nostrum minus consequatur aut
|
|
99
|
+
excepturi iste autem distinctio neque porro. Ipsa, quasi enim!
|
|
100
|
+
</div>
|
|
101
|
+
</EUIPopover>
|
|
102
|
+
</template>`,
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export const PopoverHover: Story = {
|
|
109
|
+
args: {
|
|
110
|
+
title: "Popover hover to Shows",
|
|
111
|
+
className: "max-w-64 min-w-64",
|
|
112
|
+
customButton: "border border-gray-600 px-4 py-2 rounded-lg",
|
|
113
|
+
trigger: "hover",
|
|
114
|
+
placement: "bottom-start",
|
|
115
|
+
},
|
|
116
|
+
render: (args) => ({
|
|
117
|
+
components: { EUIPopover, InformationCircleIcon },
|
|
118
|
+
setup() {
|
|
119
|
+
return { args };
|
|
120
|
+
},
|
|
121
|
+
template: `<div class="min-h-72">
|
|
122
|
+
<EUIPopover v-bind="args" trigger="hover">
|
|
123
|
+
<template #referenceButton>
|
|
124
|
+
Information <InformationCircleIcon class="text-gray-900 cursor-pointer size-6" />
|
|
125
|
+
</template>
|
|
126
|
+
<div class="relative z-10 px-4 pb-4 pt-0 text-gray-900 bg-white rounded-lg shadow-lg">
|
|
127
|
+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Minima, hic a quidem non delectus, est, ad voluptatum nostrum minus consequatur aut excepturi iste autem distinctio neque porro. Ipsa, quasi enim!
|
|
128
|
+
</div>
|
|
129
|
+
</EUIPopover>
|
|
130
|
+
</div>`,
|
|
131
|
+
}),
|
|
132
|
+
parameters: {
|
|
133
|
+
docs: {
|
|
134
|
+
description: {
|
|
135
|
+
story:
|
|
136
|
+
"The `PopoverHover` story showcases the `EUIPopover` component triggered on hover.",
|
|
137
|
+
},
|
|
138
|
+
source: {
|
|
139
|
+
code: `<template>
|
|
140
|
+
<EUIPopover
|
|
141
|
+
trigger="hover"
|
|
142
|
+
placement="bottom-start"
|
|
143
|
+
className="max-w-64 min-w-64"
|
|
144
|
+
title="Popper hover to Shows"
|
|
145
|
+
customButton="border border-gray-600 px-4 py-2 rounded-lg"
|
|
146
|
+
>
|
|
147
|
+
<template #referenceButton>
|
|
148
|
+
<InformationCircleIcon class="text-gray-900 cursor-pointer size-6" />
|
|
149
|
+
</template>
|
|
150
|
+
<!-- Popper Content Here... -->
|
|
151
|
+
<div
|
|
152
|
+
class="relative z-10 px-4 pt-0 pb-4 text-gray-900 bg-white rounded-lg shadow-lg text-start"
|
|
153
|
+
>
|
|
154
|
+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Minima, hic a
|
|
155
|
+
quidem non delectus, est, ad voluptatum nostrum minus consequatur aut
|
|
156
|
+
excepturi iste autem distinctio neque porro. Ipsa, quasi enim!
|
|
157
|
+
</div>
|
|
158
|
+
</EUIPopover>
|
|
159
|
+
</template>`,
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
export const PopoverEmitAccess: Story = {
|
|
166
|
+
args: {
|
|
167
|
+
title: "Popover click to Show",
|
|
168
|
+
className: "max-w-64 min-w-64",
|
|
169
|
+
customButton: "border border-gray-600 px-4 py-2 rounded-lg",
|
|
170
|
+
trigger: "click",
|
|
171
|
+
placement: "bottom-start",
|
|
172
|
+
},
|
|
173
|
+
render: (args) => ({
|
|
174
|
+
components: { EUIPopover, InformationCircleIcon },
|
|
175
|
+
setup() {
|
|
176
|
+
const popoverVisible = ref(false);
|
|
177
|
+
|
|
178
|
+
const onPopoverShow = () => {
|
|
179
|
+
popoverVisible.value = true;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
const onPopoverHide = () => {
|
|
183
|
+
popoverVisible.value = false;
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
return { args, onPopoverShow, onPopoverHide };
|
|
187
|
+
},
|
|
188
|
+
template: `<div class="min-h-72">
|
|
189
|
+
<EUIPopover v-bind="args" trigger="click" @showPopover="onPopoverShow"
|
|
190
|
+
@hidePopover="onPopoverHide">
|
|
191
|
+
<template #referenceButton>
|
|
192
|
+
Information <InformationCircleIcon class="text-gray-900 cursor-pointer size-6" />
|
|
193
|
+
</template>
|
|
194
|
+
<div class="relative z-10 px-4 pb-4 pt-0 text-gray-900 bg-white rounded-lg shadow-lg">
|
|
195
|
+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Minima, hic a quidem non delectus, est, ad voluptatum nostrum minus consequatur aut excepturi iste autem distinctio neque porro. Ipsa, quasi enim!
|
|
196
|
+
</div>
|
|
197
|
+
</EUIPopover>
|
|
198
|
+
</div>`,
|
|
199
|
+
}),
|
|
200
|
+
parameters: {
|
|
201
|
+
docs: {
|
|
202
|
+
description: {
|
|
203
|
+
story:
|
|
204
|
+
"The `PopoverClick` story showcases the `EUIPopover` component triggered on Emit.",
|
|
205
|
+
},
|
|
206
|
+
source: {
|
|
207
|
+
code: `<script lang="ts" setup>
|
|
208
|
+
const popoverVisible = ref(false);
|
|
209
|
+
|
|
210
|
+
const onPopoverShow = () => {
|
|
211
|
+
popoverVisible.value = true;
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
const onPopoverHide = () => {
|
|
215
|
+
popoverVisible.value = false;
|
|
216
|
+
};
|
|
217
|
+
</script>
|
|
218
|
+
<template>
|
|
219
|
+
<div>
|
|
220
|
+
Popover is {{ popoverVisible ? "visible" : "hidden" }}
|
|
221
|
+
</div>
|
|
222
|
+
<EUIPopover
|
|
223
|
+
@showPopover="onPopoverShow"
|
|
224
|
+
@hidePopover="onPopoverHide"
|
|
225
|
+
trigger="hover"
|
|
226
|
+
placement="bottom-start"
|
|
227
|
+
className="max-w-64 min-w-64"
|
|
228
|
+
title="Popover hover to Shows"
|
|
229
|
+
customButton="border border-gray-600 px-4 py-2 rounded-lg"
|
|
230
|
+
>
|
|
231
|
+
<template #referenceButton>
|
|
232
|
+
<InformationCircleIcon class="text-gray-900 cursor-pointer size-6" />
|
|
233
|
+
</template>
|
|
234
|
+
<!-- Popover Content Here... -->
|
|
235
|
+
<div
|
|
236
|
+
class="relative z-10 px-4 pt-0 pb-4 text-gray-900 bg-white rounded-lg shadow-lg text-start"
|
|
237
|
+
>
|
|
238
|
+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Minima, hic a
|
|
239
|
+
quidem non delectus, est, ad voluptatum nostrum minus consequatur aut
|
|
240
|
+
excepturi iste autem distinctio neque porro. Ipsa, quasi enim!
|
|
241
|
+
</div>
|
|
242
|
+
</EUIPopover>
|
|
243
|
+
</template>`,
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
};
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<div
|
|
4
|
+
ref="popperButton"
|
|
5
|
+
:class="['inline-flex items-center text-sm font-semibold gap-x-2', customButton]"
|
|
6
|
+
>
|
|
7
|
+
<slot name="referenceButton" :open="isOpen"/>
|
|
8
|
+
</div>
|
|
9
|
+
<div
|
|
10
|
+
ref="tooltip"
|
|
11
|
+
:class="['poppertooltip h-auto text-sm font-normal bg-white', className]"
|
|
12
|
+
>
|
|
13
|
+
<div class="arrow" data-popper-arrow />
|
|
14
|
+
<div
|
|
15
|
+
v-if="title"
|
|
16
|
+
class="text-base font-semibold text-current leading-[normal] px-4 py-2"
|
|
17
|
+
v-text="title"
|
|
18
|
+
/>
|
|
19
|
+
<slot />
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
23
|
+
|
|
24
|
+
<script setup lang="ts">
|
|
25
|
+
import { PropType } from "vue";
|
|
26
|
+
import { createPopper, Instance } from "@popperjs/core";
|
|
27
|
+
import { onClickOutside, useEventListener } from "@vueuse/core";
|
|
28
|
+
import { onMounted, ref } from "vue";
|
|
29
|
+
const props = defineProps({
|
|
30
|
+
title: {
|
|
31
|
+
type: String,
|
|
32
|
+
default: "",
|
|
33
|
+
},
|
|
34
|
+
trigger: {
|
|
35
|
+
type: String as PropType<"click" | "hover">,
|
|
36
|
+
default: "click",
|
|
37
|
+
validator: (value: string) => ["click", "hover"].includes(value),
|
|
38
|
+
},
|
|
39
|
+
className: {
|
|
40
|
+
type: String,
|
|
41
|
+
required: false,
|
|
42
|
+
default: "bg-white text-gray-900",
|
|
43
|
+
},
|
|
44
|
+
placement: {
|
|
45
|
+
type: String as PropType<"top" | "left" | "bottom" | "right" | "bottom-start" | "bottom-end">,
|
|
46
|
+
default: "bottom",
|
|
47
|
+
},
|
|
48
|
+
customButton: {
|
|
49
|
+
type: String,
|
|
50
|
+
required: false,
|
|
51
|
+
default: ''
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const popperInstance = ref<Instance | null>(null);
|
|
56
|
+
const popperButton = ref<HTMLElement | null>(null);
|
|
57
|
+
const tooltip = ref<HTMLElement | null>(null);
|
|
58
|
+
const isOpen = ref(false);
|
|
59
|
+
|
|
60
|
+
const emit = defineEmits(['showPopover', 'hidePopover']);
|
|
61
|
+
|
|
62
|
+
onMounted(() => {
|
|
63
|
+
if (props.trigger === "click") {
|
|
64
|
+
useEventListener(popperButton.value, "click", show);
|
|
65
|
+
onClickOutside(popperButton.value, hide);
|
|
66
|
+
} else if (props.trigger === "hover") {
|
|
67
|
+
const showEvents = ["mouseenter", "focus"];
|
|
68
|
+
const hideEvents = ["mouseleave", "blur"];
|
|
69
|
+
|
|
70
|
+
showEvents.forEach((event) => {
|
|
71
|
+
popperButton.value?.addEventListener(event, show);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
hideEvents.forEach((event) => {
|
|
75
|
+
popperButton.value?.addEventListener(event, hide);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (popperButton.value && tooltip.value) {
|
|
80
|
+
popperInstance.value = createPopper(popperButton.value, tooltip.value, {
|
|
81
|
+
placement: props.placement,
|
|
82
|
+
modifiers: [
|
|
83
|
+
{
|
|
84
|
+
name: "offset",
|
|
85
|
+
options: {
|
|
86
|
+
offset: [0, 8],
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
function show() {
|
|
95
|
+
tooltip.value?.setAttribute("data-show", "");
|
|
96
|
+
isOpen.value = true;
|
|
97
|
+
emit("showPopover");
|
|
98
|
+
popperInstance.value?.update();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function hide() {
|
|
102
|
+
tooltip.value?.removeAttribute("data-show");
|
|
103
|
+
isOpen.value = false;
|
|
104
|
+
emit("hidePopover");
|
|
105
|
+
}
|
|
106
|
+
</script>
|
|
107
|
+
|
|
108
|
+
<style lang="scss" scoped>
|
|
109
|
+
.poppertooltip {
|
|
110
|
+
@apply hidden;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.poppertooltip[data-show] {
|
|
114
|
+
z-index: calc(infinity);
|
|
115
|
+
@apply block rounded-lg;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.arrow,
|
|
119
|
+
.arrow::before {
|
|
120
|
+
background: inherit;
|
|
121
|
+
@apply size-3 absolute border-[0.4rem] border-gray-200 rounded-tl-sm -z-[1];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.arrow {
|
|
125
|
+
@apply invisible;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.arrow::before {
|
|
129
|
+
content: "";
|
|
130
|
+
@apply visible transform rotate-45 mx-1;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.poppertooltip{
|
|
134
|
+
&[data-popper-placement^="top"] > .arrow {
|
|
135
|
+
@apply bottom-0 -ml-2.5;
|
|
136
|
+
&::before {
|
|
137
|
+
@apply border-t-transparent border-l-transparent;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
&[data-popper-placement^="bottom"] > .arrow {
|
|
141
|
+
@apply -top-3 -ml-2.5;
|
|
142
|
+
&::before {
|
|
143
|
+
@apply border-b-transparent border-r-transparent;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
&[data-popper-placement^="left"] > .arrow {
|
|
147
|
+
@apply right-1 -mt-1.5;
|
|
148
|
+
&::before {
|
|
149
|
+
@apply border-l-transparent border-b-transparent;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
&[data-popper-placement^="right"] > .arrow {
|
|
153
|
+
@apply -left-4 -mt-1.5;
|
|
154
|
+
&::before {
|
|
155
|
+
@apply border-r-transparent border-t-transparent;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
</style>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/vue3";
|
|
2
|
+
import EUIRadio from "./EUIRadio.vue";
|
|
3
|
+
|
|
4
|
+
// Meta configuration for the component's stories
|
|
5
|
+
const meta = {
|
|
6
|
+
title: "Forms/Radio",
|
|
7
|
+
component: EUIRadio,
|
|
8
|
+
tags: ["autodocs"],
|
|
9
|
+
argTypes: {
|
|
10
|
+
label: {
|
|
11
|
+
description: "The label displayed next to the raidobox",
|
|
12
|
+
control: "text",
|
|
13
|
+
},
|
|
14
|
+
disabled: {
|
|
15
|
+
description: "Disables the raidobox when set to true",
|
|
16
|
+
control: "boolean",
|
|
17
|
+
},
|
|
18
|
+
modelValue: {
|
|
19
|
+
description: "Controls the checked state of the raidobox",
|
|
20
|
+
control: "boolean",
|
|
21
|
+
},
|
|
22
|
+
errors: {
|
|
23
|
+
description:
|
|
24
|
+
"An object that contains error messages or validation information",
|
|
25
|
+
control: "object",
|
|
26
|
+
},
|
|
27
|
+
name: {
|
|
28
|
+
description:
|
|
29
|
+
"The name attribute for the raidobox input, useful for forms",
|
|
30
|
+
control: "text",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
} satisfies Meta<typeof EUIRadio>;
|
|
34
|
+
|
|
35
|
+
export default meta;
|
|
36
|
+
type Story = StoryObj<typeof meta>;
|
|
37
|
+
|
|
38
|
+
// Default story with minimum props
|
|
39
|
+
export const Default: Story = {
|
|
40
|
+
args: {
|
|
41
|
+
label: "Accept Terms & Conditions",
|
|
42
|
+
modelValue: false,
|
|
43
|
+
disabled: false,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// Disabled state story
|
|
48
|
+
export const Disabled: Story = {
|
|
49
|
+
args: {
|
|
50
|
+
label: "Disabled Radio",
|
|
51
|
+
modelValue: false,
|
|
52
|
+
disabled: true,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
<label class="inline-flex items-center cursor-pointer eui-radio">
|
|
4
|
+
<input
|
|
5
|
+
v-model="modelValue"
|
|
6
|
+
type="radio"
|
|
7
|
+
class="sr-only peer eui-radio_input"
|
|
8
|
+
:disabled="disabled"
|
|
9
|
+
@change="toggle()"
|
|
10
|
+
/>
|
|
11
|
+
<div
|
|
12
|
+
class="eui-radio_circle relative size-6 bg-gray-200 peer-focus:outline-none rounded-full after:content-[''] after:absolute after:top-0.5 after:start-0.5 after:bg-gray-500/20 after:border-gray-300/10 after:border after:rounded-full after:size-5 peer-checked:after:bg-purple-700"
|
|
13
|
+
>
|
|
14
|
+
<span class="eui-radio_icons"></span>
|
|
15
|
+
</div>
|
|
16
|
+
<span v-if="label" class="text-sm font-medium text-gray-900 ms-3 first-letter:capitalize">
|
|
17
|
+
{{ label }}
|
|
18
|
+
</span>
|
|
19
|
+
</label>
|
|
20
|
+
<EUIErrorMessage :errors="errors" :name="name" />
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
23
|
+
|
|
24
|
+
<script setup lang="ts">
|
|
25
|
+
import { PropType, toRefs } from "vue";
|
|
26
|
+
import EUIErrorMessage from "../errorMessage/EUIErrorMessage.vue";
|
|
27
|
+
|
|
28
|
+
// Props declaration
|
|
29
|
+
const props = defineProps({
|
|
30
|
+
errors: { type: Object, required: false, default: () => {} },
|
|
31
|
+
modelValue: {
|
|
32
|
+
type: Boolean as PropType<boolean>,
|
|
33
|
+
required: true,
|
|
34
|
+
default: false,
|
|
35
|
+
},
|
|
36
|
+
name: {
|
|
37
|
+
type: String,
|
|
38
|
+
required: false,
|
|
39
|
+
default: "",
|
|
40
|
+
},
|
|
41
|
+
label: { type: String as PropType<string>, required: true, default: "" },
|
|
42
|
+
disabled: {
|
|
43
|
+
type: Boolean,
|
|
44
|
+
default: false,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
const {modelValue} = toRefs(props)
|
|
48
|
+
|
|
49
|
+
const emit = defineEmits(["update:modelValue", "toggle"]);
|
|
50
|
+
const toggle = () => {
|
|
51
|
+
emit("toggle", props.modelValue);
|
|
52
|
+
emit("update:modelValue", props.modelValue);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
</script>
|
|
56
|
+
|
|
57
|
+
<style lang="scss" scoped>
|
|
58
|
+
.eui-radio_icons {
|
|
59
|
+
@apply size-5 absolute z-10 top-0.5 left-0.5 rounded-full;
|
|
60
|
+
&::after {
|
|
61
|
+
content: '';
|
|
62
|
+
@apply absolute border-solid border-transparent transform scale-0 opacity-0 transition-all duration-200 delay-75 ease-in;
|
|
63
|
+
}
|
|
64
|
+
&::after {
|
|
65
|
+
@apply rotate-45 top-2;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.eui-radio_input:checked + .eui-radio_circle {
|
|
70
|
+
.eui-radio_icons {
|
|
71
|
+
&::after {
|
|
72
|
+
width: 5.3px;
|
|
73
|
+
border-width: 0 2.4px 2.4px 0;
|
|
74
|
+
@apply border-white top-1 left-2 h-2.5 opacity-100 scale-100;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
</style>
|