edvoyui-component-library-test-flight 0.0.251 → 0.0.252
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/components/accordion/EUIAccordionMenu.d.ts +70 -0
- package/dist/components/accordion/EUIAccordionMenu.vue +160 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/tag/EUITag.vue +4 -9
- package/dist/edvoy-ui.cjs.js +12 -12
- package/dist/edvoy-ui.css +1 -1
- package/dist/edvoy-ui.es.js +5321 -5192
- package/dist/edvoy-ui.umd.js +26 -26
- package/package.json +1 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { PropType } from '../../../node_modules/vue';
|
|
2
|
+
type AccordionMenuItem = {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
};
|
|
6
|
+
type AccordionMenuSection = {
|
|
7
|
+
id: string;
|
|
8
|
+
label: string;
|
|
9
|
+
items: AccordionMenuItem[];
|
|
10
|
+
};
|
|
11
|
+
declare const _default: import('../../../node_modules/vue').DefineComponent<import('../../../node_modules/vue').ExtractPropTypes<{
|
|
12
|
+
items: {
|
|
13
|
+
type: PropType<AccordionMenuSection[]>;
|
|
14
|
+
default: () => never[];
|
|
15
|
+
};
|
|
16
|
+
modelValue: {
|
|
17
|
+
type: StringConstructor;
|
|
18
|
+
default: string;
|
|
19
|
+
};
|
|
20
|
+
defaultOpen: {
|
|
21
|
+
type: StringConstructor;
|
|
22
|
+
default: string;
|
|
23
|
+
};
|
|
24
|
+
/** Controlled expanded category; takes precedence over defaultOpen when set. */
|
|
25
|
+
openSection: {
|
|
26
|
+
type: StringConstructor;
|
|
27
|
+
default: string;
|
|
28
|
+
};
|
|
29
|
+
/** Keep the expanded category title visible while a long menu scrolls. */
|
|
30
|
+
stickySectionHeaders: {
|
|
31
|
+
type: BooleanConstructor;
|
|
32
|
+
default: boolean;
|
|
33
|
+
};
|
|
34
|
+
}>, {}, {}, {}, {}, import('../../../node_modules/vue').ComponentOptionsMixin, import('../../../node_modules/vue').ComponentOptionsMixin, {
|
|
35
|
+
"update:modelValue": (id: string) => any;
|
|
36
|
+
"update:open": (id: string | null) => any;
|
|
37
|
+
}, string, import('../../../node_modules/vue').PublicProps, Readonly<import('../../../node_modules/vue').ExtractPropTypes<{
|
|
38
|
+
items: {
|
|
39
|
+
type: PropType<AccordionMenuSection[]>;
|
|
40
|
+
default: () => never[];
|
|
41
|
+
};
|
|
42
|
+
modelValue: {
|
|
43
|
+
type: StringConstructor;
|
|
44
|
+
default: string;
|
|
45
|
+
};
|
|
46
|
+
defaultOpen: {
|
|
47
|
+
type: StringConstructor;
|
|
48
|
+
default: string;
|
|
49
|
+
};
|
|
50
|
+
/** Controlled expanded category; takes precedence over defaultOpen when set. */
|
|
51
|
+
openSection: {
|
|
52
|
+
type: StringConstructor;
|
|
53
|
+
default: string;
|
|
54
|
+
};
|
|
55
|
+
/** Keep the expanded category title visible while a long menu scrolls. */
|
|
56
|
+
stickySectionHeaders: {
|
|
57
|
+
type: BooleanConstructor;
|
|
58
|
+
default: boolean;
|
|
59
|
+
};
|
|
60
|
+
}>> & Readonly<{
|
|
61
|
+
"onUpdate:modelValue"?: ((id: string) => any) | undefined;
|
|
62
|
+
"onUpdate:open"?: ((id: string | null) => any) | undefined;
|
|
63
|
+
}>, {
|
|
64
|
+
items: AccordionMenuSection[];
|
|
65
|
+
modelValue: string;
|
|
66
|
+
defaultOpen: string;
|
|
67
|
+
openSection: string;
|
|
68
|
+
stickySectionHeaders: boolean;
|
|
69
|
+
}, {}, {}, {}, string, import('../../../node_modules/vue').ComponentProvideOptions, true, {}, HTMLElement>;
|
|
70
|
+
export default _default;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<nav class="w-full space-y-1" aria-label="Filter categories">
|
|
3
|
+
<section v-for="section in items" :key="section.id">
|
|
4
|
+
<button
|
|
5
|
+
type="button"
|
|
6
|
+
class="flex items-center w-full gap-2 py-1 pl-4 pr-2 text-sm text-left transition-[background-color,color] duration-300 ease-out rounded min-h-8"
|
|
7
|
+
:class="
|
|
8
|
+
[
|
|
9
|
+
expandedSection === section.id
|
|
10
|
+
? 'bg-gray-100 text-slate-900 font-semibold'
|
|
11
|
+
: 'bg-white text-gray-600 hover:bg-slate-50 font-medium',
|
|
12
|
+
stickySectionHeaders && expandedSection === section.id
|
|
13
|
+
? 'sticky top-0 z-50 isolate !bg-gray-100'
|
|
14
|
+
: '',
|
|
15
|
+
]
|
|
16
|
+
"
|
|
17
|
+
:aria-expanded="expandedSection === section.id"
|
|
18
|
+
@click="toggleSection(section.id)"
|
|
19
|
+
>
|
|
20
|
+
<span class="flex-1 min-w-0 truncate">{{ section.label }}</span>
|
|
21
|
+
<svg
|
|
22
|
+
class="size-5 shrink-0 transition-transform duration-350 ease-[cubic-bezier(0.15,0.3,0.25,1)]"
|
|
23
|
+
:class="expandedSection === section.id ? 'rotate-90' : ''"
|
|
24
|
+
viewBox="0 0 24 24"
|
|
25
|
+
fill="none"
|
|
26
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
27
|
+
width="24"
|
|
28
|
+
height="24"
|
|
29
|
+
>
|
|
30
|
+
<path
|
|
31
|
+
d="M10 8.13867C11.4619 9.20073 12.7713 10.4457 13.8942 11.8408C14.0353 12.016 14.0353 12.2613 13.8942 12.4365C12.7713 13.8316 11.4619 15.0766 10 16.1387"
|
|
32
|
+
stroke="currentColor"
|
|
33
|
+
stroke-opacity="0.8"
|
|
34
|
+
stroke-width="2"
|
|
35
|
+
stroke-linecap="round"
|
|
36
|
+
stroke-linejoin="round"
|
|
37
|
+
></path>
|
|
38
|
+
</svg>
|
|
39
|
+
</button>
|
|
40
|
+
|
|
41
|
+
<div
|
|
42
|
+
class="grid transition-[grid-template-rows,opacity] duration-350 ease-[cubic-bezier(0.15,0.3,0.25,1)] motion-reduce:transition-none"
|
|
43
|
+
:class="
|
|
44
|
+
expandedSection === section.id
|
|
45
|
+
? 'grid-rows-[1fr] opacity-100'
|
|
46
|
+
: 'grid-rows-[0fr] opacity-0'
|
|
47
|
+
"
|
|
48
|
+
>
|
|
49
|
+
<div class="min-h-0 overflow-hidden">
|
|
50
|
+
<div class="relative flex flex-col gap-1 pb-2 my-1 ml-4">
|
|
51
|
+
<span
|
|
52
|
+
aria-hidden="true"
|
|
53
|
+
class="absolute top-0 left-0 z-0 w-px bg-slate-200"
|
|
54
|
+
:style="treeRailStyle(section.items.length)"
|
|
55
|
+
/>
|
|
56
|
+
<span
|
|
57
|
+
aria-hidden="true"
|
|
58
|
+
class="absolute top-0 left-4 right-0 z-[1] h-8 rounded-md bg-violet-50 ring-1 ring-inset ring-violet-100 transition-[transform,opacity] duration-350 ease-[cubic-bezier(0.15,0.3,0.25,1)]"
|
|
59
|
+
:class="
|
|
60
|
+
activeItem &&
|
|
61
|
+
section.items.some((item) => item.id === activeItem)
|
|
62
|
+
? 'opacity-100'
|
|
63
|
+
: 'opacity-0'
|
|
64
|
+
"
|
|
65
|
+
:style="indicatorStyle(section)"
|
|
66
|
+
/>
|
|
67
|
+
<button
|
|
68
|
+
v-for="item in section.items"
|
|
69
|
+
:key="item.id"
|
|
70
|
+
type="button"
|
|
71
|
+
class="relative z-[2] flex items-center w-[calc(100%-1rem)] h-8 py-0 pl-4 pr-3 ml-4 text-xs text-left transition-colors duration-200 rounded-xl before:absolute before:-left-4 before:top-0 before:h-4 before:w-4 before:rounded-bl-lg before:border-b before:border-l before:border-slate-200 before:content-[''] tracking-[-0.015em]"
|
|
72
|
+
:class="
|
|
73
|
+
activeItem === item.id
|
|
74
|
+
? 'text-violet-900 font-semibold'
|
|
75
|
+
: 'text-gray-600 hover:text-gray-800 font-medium'
|
|
76
|
+
"
|
|
77
|
+
:aria-current="activeItem === item.id ? 'page' : undefined"
|
|
78
|
+
@click="selectItem(section.id, item.id)"
|
|
79
|
+
>
|
|
80
|
+
{{ item.label }}
|
|
81
|
+
</button>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
</section>
|
|
86
|
+
</nav>
|
|
87
|
+
</template>
|
|
88
|
+
|
|
89
|
+
<script setup lang="ts">
|
|
90
|
+
import { computed, ref, watch, type CSSProperties, type PropType } from "vue";
|
|
91
|
+
|
|
92
|
+
type AccordionMenuItem = { id: string; label: string };
|
|
93
|
+
type AccordionMenuSection = {
|
|
94
|
+
id: string;
|
|
95
|
+
label: string;
|
|
96
|
+
items: AccordionMenuItem[];
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const props = defineProps({
|
|
100
|
+
items: { type: Array as PropType<AccordionMenuSection[]>, default: () => [] },
|
|
101
|
+
modelValue: { type: String, default: "" },
|
|
102
|
+
defaultOpen: { type: String, default: "" },
|
|
103
|
+
/** Controlled expanded category; takes precedence over defaultOpen when set. */
|
|
104
|
+
openSection: { type: String, default: "" },
|
|
105
|
+
/** Keep the expanded category title visible while a long menu scrolls. */
|
|
106
|
+
stickySectionHeaders: { type: Boolean, default: false },
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const emit = defineEmits<{
|
|
110
|
+
"update:modelValue": [id: string];
|
|
111
|
+
"update:open": [id: string | null];
|
|
112
|
+
}>();
|
|
113
|
+
const expandedSection = ref<string | null>(
|
|
114
|
+
props.openSection || props.defaultOpen || props.items[0]?.id || null,
|
|
115
|
+
);
|
|
116
|
+
const activeItem = computed(() => props.modelValue);
|
|
117
|
+
|
|
118
|
+
watch(
|
|
119
|
+
() => props.items,
|
|
120
|
+
(items) => {
|
|
121
|
+
if (!items.some((item) => item.id === expandedSection.value))
|
|
122
|
+
expandedSection.value = items[0]?.id || null;
|
|
123
|
+
},
|
|
124
|
+
{ deep: true },
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
watch(
|
|
128
|
+
() => props.openSection,
|
|
129
|
+
(sectionId) => {
|
|
130
|
+
expandedSection.value = sectionId || null;
|
|
131
|
+
},
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
const toggleSection = (id: string) => {
|
|
135
|
+
expandedSection.value = expandedSection.value === id ? null : id;
|
|
136
|
+
emit("update:open", expandedSection.value);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const selectItem = (sectionId: string, itemId: string) => {
|
|
140
|
+
expandedSection.value = sectionId;
|
|
141
|
+
emit("update:open", sectionId);
|
|
142
|
+
emit("update:modelValue", itemId);
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const SUBMENU_ROW_STEP_REM = 2.25;
|
|
146
|
+
|
|
147
|
+
const indicatorStyle = (
|
|
148
|
+
section: AccordionMenuSection,
|
|
149
|
+
): CSSProperties => {
|
|
150
|
+
const index = section.items.findIndex((item) => item.id === activeItem.value);
|
|
151
|
+
return {
|
|
152
|
+
transform: `translateY(${Math.max(0, index) * SUBMENU_ROW_STEP_REM}rem)`,
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
/** The rail ends at the start of the final item's curved CSS connector. */
|
|
157
|
+
const treeRailStyle = (itemCount: number): CSSProperties => ({
|
|
158
|
+
height: `${Math.max(0, (itemCount - 1) * SUBMENU_ROW_STEP_REM + 0.75)}rem`,
|
|
159
|
+
});
|
|
160
|
+
</script>
|
|
@@ -14,6 +14,7 @@ export { default as EUIStepperTimeline } from './stepperTimeline/EUIStepperTimel
|
|
|
14
14
|
export { default as EUIStepperVertical } from './stepperTimeline/EUIStepperVertical';
|
|
15
15
|
export { default as EUIStepperHorizontal } from './stepperTimeline/EUIStepperHorizontal';
|
|
16
16
|
export { default as EUIAccordion } from './accordion/EUIAccordion';
|
|
17
|
+
export { default as EUIAccordionMenu } from './accordion/EUIAccordionMenu';
|
|
17
18
|
export { default as EUIPopover } from './popover/EUIPopover';
|
|
18
19
|
export { default as EUIModal } from './modal/EUIModal';
|
|
19
20
|
export { default as EUISlideover } from './slideover/EUISlideover';
|
|
@@ -10,17 +10,12 @@
|
|
|
10
10
|
<button
|
|
11
11
|
v-if="closeIcon"
|
|
12
12
|
type="button"
|
|
13
|
-
class="relative flex-shrink-0 -mr-1 rounded group hover:bg-red-
|
|
14
|
-
:class="[props.size === 'lg' ? 'size-6' : props.size === 'md'? 'size-5' : 'size-
|
|
13
|
+
class="relative inline-flex items-center justify-center flex-shrink-0 -mr-1 rounded group hover:bg-red-100 active:bg-red-200"
|
|
14
|
+
:class="[props.size === 'lg' ? 'size-6' : props.size === 'md'? 'size-5' : 'size-4']"
|
|
15
15
|
@click.stop="removeTag"
|
|
16
16
|
>
|
|
17
17
|
<span class="sr-only">Remove</span>
|
|
18
|
-
<svg
|
|
19
|
-
viewBox="0 0 14 14"
|
|
20
|
-
class="stroke-gray-400 group-hover:stroke-red-600/75 text-violet-600"
|
|
21
|
-
>
|
|
22
|
-
<path d="M4 4l6 6m0-6l-6 6" />
|
|
23
|
-
</svg>
|
|
18
|
+
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" width="24" height="24" class="text-gray-400 group-hover:text-red-600/75" :class="[props.size === 'lg' ? 'size-5' : props.size === 'md'? 'size-4' : 'size-3']"><path d="M6 18L12 12M12 12L18 6M12 12L6 6M12 12L18 18" stroke="currentColor" stroke-opacity="0.9" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg>
|
|
24
19
|
</button>
|
|
25
20
|
</div>
|
|
26
21
|
</template>
|
|
@@ -69,7 +64,7 @@ const tagClass = computed(() => {
|
|
|
69
64
|
: "bg-white hover:bg-gray-100 text-black cursor-pointer active:shadow-white/50 active:bg-transparent",
|
|
70
65
|
secondary: btnDisabled
|
|
71
66
|
? "bg-opacity-75 cursor-not-allowed text-gray-400 bg-violet-50"
|
|
72
|
-
: "bg-violet-100 hover:bg-violet-50 active:bg-violet-100 cursor-pointer text-violet-
|
|
67
|
+
: "bg-violet-100 hover:bg-violet-50 active:bg-violet-100 cursor-pointer text-violet-600 active:shadow-violet-200",
|
|
73
68
|
tertiary: btnDisabled
|
|
74
69
|
? "bg-opacity-75 cursor-not-allowed text-gray-400 bg-gray-50 ring-1 ring-gray-400/20"
|
|
75
70
|
: "bg-gray-100 hover:bg-gray-50 active:bg-gray-100 text-gray-700 cursor-pointer active:shadow-bg-gray-200/50 ring-1 ring-gray-200",
|