edvoyui-component-library-test-flight 0.0.249 → 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/searchTagSelect/EUISearchTagSelect.d.ts +2 -2
- package/dist/components/searchTagSelect/EUISearchTagSelect.vue +73 -89
- package/dist/components/table/UTable.vue +1 -1
- package/dist/components/tag/EUITag.vue +4 -9
- package/dist/edvoy-ui.cjs.js +22 -109
- package/dist/edvoy-ui.css +1 -1
- package/dist/edvoy-ui.es.js +11180 -12294
- package/dist/edvoy-ui.umd.js +34 -121
- 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';
|
|
@@ -61,6 +61,7 @@ declare function __VLS_template(): {
|
|
|
61
61
|
};
|
|
62
62
|
refs: {
|
|
63
63
|
componentRef: HTMLDivElement;
|
|
64
|
+
triggerRef: HTMLDivElement;
|
|
64
65
|
searchInputRef: import('../../../node_modules/vue').CreateComponentPublicInstanceWithMixins<Readonly<import('../../../node_modules/vue').ExtractPropTypes<{
|
|
65
66
|
modelValue: {
|
|
66
67
|
type: (StringConstructor | NumberConstructor)[];
|
|
@@ -196,7 +197,6 @@ declare function __VLS_template(): {
|
|
|
196
197
|
activeOptionId: string;
|
|
197
198
|
expanded: boolean;
|
|
198
199
|
}> | null;
|
|
199
|
-
triggerButtonRef: HTMLButtonElement;
|
|
200
200
|
dropdownContentRef: HTMLDivElement;
|
|
201
201
|
options: HTMLUListElement;
|
|
202
202
|
};
|
|
@@ -257,6 +257,7 @@ declare const __VLS_component: import('../../../node_modules/vue').DefineCompone
|
|
|
257
257
|
dropdownWidth: string;
|
|
258
258
|
}, {}, {}, {}, string, import('../../../node_modules/vue').ComponentProvideOptions, false, {
|
|
259
259
|
componentRef: HTMLDivElement;
|
|
260
|
+
triggerRef: HTMLDivElement;
|
|
260
261
|
searchInputRef: import('../../../node_modules/vue').CreateComponentPublicInstanceWithMixins<Readonly<import('../../../node_modules/vue').ExtractPropTypes<{
|
|
261
262
|
modelValue: {
|
|
262
263
|
type: (StringConstructor | NumberConstructor)[];
|
|
@@ -392,7 +393,6 @@ declare const __VLS_component: import('../../../node_modules/vue').DefineCompone
|
|
|
392
393
|
activeOptionId: string;
|
|
393
394
|
expanded: boolean;
|
|
394
395
|
}> | null;
|
|
395
|
-
triggerButtonRef: HTMLButtonElement;
|
|
396
396
|
dropdownContentRef: HTMLDivElement;
|
|
397
397
|
options: HTMLUListElement;
|
|
398
398
|
}, HTMLDivElement>;
|
|
@@ -9,23 +9,7 @@
|
|
|
9
9
|
{{ label }} <span v-if="required" class="text-red-500">*</span>
|
|
10
10
|
</label>
|
|
11
11
|
</slot>
|
|
12
|
-
<
|
|
13
|
-
:class="[
|
|
14
|
-
`popper-defaultstyle w-full ${popperClasses}`,
|
|
15
|
-
{ 'search-tag-select--teleported': teleported },
|
|
16
|
-
]"
|
|
17
|
-
v-bind="$attrs"
|
|
18
|
-
:show="showDropDown"
|
|
19
|
-
:arrow="!teleported"
|
|
20
|
-
closeDelay="100"
|
|
21
|
-
:offsetSkid="offsetSkid"
|
|
22
|
-
:offsetDistance="offsetDistance"
|
|
23
|
-
:placement="placement"
|
|
24
|
-
:interactive="true"
|
|
25
|
-
:auto-hide="!teleported"
|
|
26
|
-
@open:popper="handleOpen"
|
|
27
|
-
@close:popper="handleClose"
|
|
28
|
-
>
|
|
12
|
+
<div ref="triggerRef" class="w-full" v-bind="$attrs">
|
|
29
13
|
<SearchInput
|
|
30
14
|
v-if="showDropDown || selectedValues.length === 0"
|
|
31
15
|
ref="searchInputRef"
|
|
@@ -44,7 +28,6 @@
|
|
|
44
28
|
/>
|
|
45
29
|
<button
|
|
46
30
|
v-else-if="!showDropDown && selectedValues.length > 0"
|
|
47
|
-
ref="triggerButtonRef"
|
|
48
31
|
type="button"
|
|
49
32
|
:disabled="disabled"
|
|
50
33
|
class="flex items-center justify-between w-full h-10 gap-2 px-4 py-2 text-left bg-white border border-gray-200 border-solid cursor-pointer search-textstyle rounded-3xl focus-within:outline-violet-200"
|
|
@@ -93,13 +76,19 @@
|
|
|
93
76
|
/>
|
|
94
77
|
</div>
|
|
95
78
|
</button>
|
|
96
|
-
|
|
97
|
-
|
|
79
|
+
</div>
|
|
80
|
+
<Teleport to="body" :disabled="!teleported">
|
|
98
81
|
<div
|
|
99
82
|
v-if="showDropDown"
|
|
100
83
|
ref="dropdownContentRef"
|
|
101
|
-
:class="[
|
|
102
|
-
|
|
84
|
+
:class="[
|
|
85
|
+
'p-3 text-sm bg-white border-2 border-gray-100 border-solid shadow-lg rounded-3xl min-w-28',
|
|
86
|
+
confirmSelection && selectType === 'multiple' ? '' : 'overflow-y-auto max-h-72 scrollbar--hide',
|
|
87
|
+
dropdownWidth,
|
|
88
|
+
teleported ? 'z-[60]' : 'z-50',
|
|
89
|
+
'transition-opacity duration-150 ease-out',
|
|
90
|
+
dropdownReady ? 'opacity-100' : 'opacity-0 pointer-events-none',
|
|
91
|
+
]"
|
|
103
92
|
>
|
|
104
93
|
<div class="flex items-center justify-between p-2 pb-0 mb-1 -mx-px -mt-3">
|
|
105
94
|
<h3
|
|
@@ -276,9 +265,7 @@
|
|
|
276
265
|
</EUIButton>
|
|
277
266
|
</div>
|
|
278
267
|
</div>
|
|
279
|
-
|
|
280
|
-
</template>
|
|
281
|
-
</Popper>
|
|
268
|
+
</Teleport>
|
|
282
269
|
<template v-if="errors && errors.length && !showDropDown">
|
|
283
270
|
<EUIErrorMessage :errors="errors" :name="name" class="mt-2" />
|
|
284
271
|
</template>
|
|
@@ -358,8 +345,7 @@ import ChevronDownStroke from "../../assets/svg/ChevronDownStroke.vue";
|
|
|
358
345
|
import EUICheckbox from "../checkbox/EUICheckbox.vue";
|
|
359
346
|
import EUITag from "../tag/EUITag.vue";
|
|
360
347
|
import EUIButton from "../button/EUIButton.vue";
|
|
361
|
-
import
|
|
362
|
-
import { createPopper, type Instance } from "@popperjs/core";
|
|
348
|
+
import { createPopper, type Instance, type Placement } from "@popperjs/core";
|
|
363
349
|
import CheckTick from "../../assets/svg/CheckTick.vue";
|
|
364
350
|
import { XMarkIcon } from "@heroicons/vue/20/solid";
|
|
365
351
|
import EUIErrorMessage from "../errorMessage/EUIErrorMessage.vue";
|
|
@@ -476,9 +462,10 @@ const draftValues = ref<any[]>([]);
|
|
|
476
462
|
const options = ref<HTMLElement>();
|
|
477
463
|
const searchInputRef = ref<any>();
|
|
478
464
|
const componentRef = ref<HTMLElement>();
|
|
479
|
-
const
|
|
465
|
+
const triggerRef = ref<HTMLElement>();
|
|
480
466
|
const dropdownContentRef = ref<HTMLElement>();
|
|
481
|
-
|
|
467
|
+
const dropdownReady = ref(false);
|
|
468
|
+
let popperInstance: Instance | null = null;
|
|
482
469
|
const tagsExpanded = ref(false);
|
|
483
470
|
const highlightedIndex = ref(-1);
|
|
484
471
|
const listboxId = `search-tag-listbox-${getCurrentInstance()?.uid ?? 0}`;
|
|
@@ -843,44 +830,58 @@ const handleSearchKeydown = (event: KeyboardEvent) => {
|
|
|
843
830
|
else handleSelect(item);
|
|
844
831
|
};
|
|
845
832
|
|
|
846
|
-
const
|
|
847
|
-
|
|
848
|
-
|
|
833
|
+
const destroyPopper = () => {
|
|
834
|
+
popperInstance?.destroy();
|
|
835
|
+
popperInstance = null;
|
|
849
836
|
};
|
|
850
837
|
|
|
851
|
-
const
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
(searchInputRef.value?.$el as HTMLElement | undefined) ||
|
|
856
|
-
triggerButtonRef.value;
|
|
857
|
-
if (!trigger) return;
|
|
838
|
+
const createDropdownPopper = async () => {
|
|
839
|
+
await nextTick();
|
|
840
|
+
if (!showDropDown.value || !triggerRef.value || !dropdownContentRef.value)
|
|
841
|
+
return;
|
|
858
842
|
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
placement: props.placement,
|
|
862
|
-
strategy: "fixed",
|
|
843
|
+
destroyPopper();
|
|
844
|
+
popperInstance = createPopper(triggerRef.value, dropdownContentRef.value, {
|
|
845
|
+
placement: props.placement as Placement,
|
|
846
|
+
strategy: props.teleported ? "fixed" : "absolute",
|
|
863
847
|
modifiers: [
|
|
864
848
|
{
|
|
865
849
|
name: "offset",
|
|
866
850
|
options: { offset: [Number(props.offsetSkid), Number(props.offsetDistance)] },
|
|
867
851
|
},
|
|
868
|
-
{
|
|
869
|
-
|
|
852
|
+
{
|
|
853
|
+
name: "flip",
|
|
854
|
+
options: {
|
|
855
|
+
padding: 8,
|
|
856
|
+
fallbackPlacements: ["bottom-start", "top-start", "bottom-end", "top-end"],
|
|
857
|
+
},
|
|
858
|
+
},
|
|
859
|
+
{
|
|
860
|
+
name: "preventOverflow",
|
|
861
|
+
options: {
|
|
862
|
+
boundary: "viewport",
|
|
863
|
+
rootBoundary: "viewport",
|
|
864
|
+
padding: 8,
|
|
865
|
+
altAxis: true,
|
|
866
|
+
tether: true,
|
|
867
|
+
},
|
|
868
|
+
},
|
|
870
869
|
{
|
|
871
870
|
name: "sameWidth",
|
|
872
|
-
enabled:
|
|
871
|
+
enabled: !props.dropdownWidth,
|
|
873
872
|
phase: "beforeWrite",
|
|
874
873
|
requires: ["computeStyles"],
|
|
875
874
|
fn: ({ state }) => {
|
|
876
875
|
state.styles.popper.width = `${state.rects.reference.width}px`;
|
|
877
876
|
},
|
|
878
877
|
},
|
|
878
|
+
{ name: "eventListeners", options: { scroll: true, resize: true } },
|
|
879
879
|
],
|
|
880
880
|
});
|
|
881
|
+
await popperInstance.update();
|
|
881
882
|
};
|
|
882
883
|
|
|
883
|
-
const handleOpen = () => {
|
|
884
|
+
const handleOpen = async () => {
|
|
884
885
|
if (props.disabled || showDropDown.value) return;
|
|
885
886
|
|
|
886
887
|
highlightedIndex.value = -1;
|
|
@@ -893,13 +894,15 @@ const handleOpen = () => {
|
|
|
893
894
|
if (props.selectType === "single") {
|
|
894
895
|
internalSearch.value = "";
|
|
895
896
|
}
|
|
897
|
+
dropdownReady.value = false;
|
|
896
898
|
showDropDown.value = true;
|
|
897
|
-
|
|
899
|
+
await createDropdownPopper();
|
|
900
|
+
if (!showDropDown.value) return;
|
|
901
|
+
dropdownReady.value = true;
|
|
898
902
|
emit("open");
|
|
899
903
|
|
|
900
904
|
nextTick(() => {
|
|
901
905
|
if (!showDropDown.value) return;
|
|
902
|
-
createTeleportedPopper();
|
|
903
906
|
focusTimer = setTimeout(() => {
|
|
904
907
|
focusTimer = undefined;
|
|
905
908
|
if (!showDropDown.value) return;
|
|
@@ -930,8 +933,8 @@ const handleApply = () => {
|
|
|
930
933
|
|
|
931
934
|
const handleClose = () => {
|
|
932
935
|
highlightedIndex.value = -1;
|
|
933
|
-
|
|
934
|
-
|
|
936
|
+
destroyPopper();
|
|
937
|
+
dropdownReady.value = false;
|
|
935
938
|
if (focusTimer) {
|
|
936
939
|
clearTimeout(focusTimer);
|
|
937
940
|
focusTimer = undefined;
|
|
@@ -962,40 +965,25 @@ const handleSearchFocus = () => {
|
|
|
962
965
|
};
|
|
963
966
|
|
|
964
967
|
// Document click handler for outside clicks
|
|
965
|
-
const
|
|
966
|
-
|
|
967
|
-
|
|
968
|
+
const handleDocumentPointerDown = (event: PointerEvent) => {
|
|
969
|
+
if (!showDropDown.value) return;
|
|
970
|
+
const target = event.target as Node;
|
|
968
971
|
if (
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
!event.composedPath().includes(dropdownContentRef.value as EventTarget)
|
|
973
|
-
) {
|
|
974
|
-
handleDismiss();
|
|
975
|
-
}
|
|
976
|
-
};
|
|
972
|
+
componentRef.value?.contains(target) ||
|
|
973
|
+
dropdownContentRef.value?.contains(target)
|
|
974
|
+
) return;
|
|
977
975
|
|
|
978
|
-
const handleScroll = (event: Event) => {
|
|
979
|
-
if (!showDropDown.value) return;
|
|
980
|
-
if (props.teleported) {
|
|
981
|
-
teleportedPopper?.update();
|
|
982
|
-
return;
|
|
983
|
-
}
|
|
984
|
-
const target = event.target;
|
|
985
|
-
// Keep the options usable; scrolling any ancestor or the page closes them.
|
|
986
|
-
if (target instanceof Node && componentRef.value?.contains(target)) return;
|
|
987
976
|
handleDismiss();
|
|
988
977
|
};
|
|
989
978
|
|
|
990
979
|
// Lifecycle hooks
|
|
991
980
|
onMounted(() => {
|
|
992
|
-
document.addEventListener("
|
|
981
|
+
document.addEventListener("pointerdown", handleDocumentPointerDown);
|
|
993
982
|
});
|
|
994
983
|
|
|
995
984
|
onUnmounted(() => {
|
|
996
|
-
document.removeEventListener("
|
|
997
|
-
|
|
998
|
-
destroyTeleportedPopper();
|
|
985
|
+
document.removeEventListener("pointerdown", handleDocumentPointerDown);
|
|
986
|
+
destroyPopper();
|
|
999
987
|
if (focusTimer) clearTimeout(focusTimer);
|
|
1000
988
|
});
|
|
1001
989
|
|
|
@@ -1004,23 +992,19 @@ watch(internalSearch, (value: string) => {
|
|
|
1004
992
|
emit("search", value);
|
|
1005
993
|
});
|
|
1006
994
|
|
|
995
|
+
watch(
|
|
996
|
+
() => [props.placement, props.offsetDistance, props.offsetSkid, props.teleported],
|
|
997
|
+
async () => {
|
|
998
|
+
if (!showDropDown.value) return;
|
|
999
|
+
dropdownReady.value = false;
|
|
1000
|
+
await createDropdownPopper();
|
|
1001
|
+
if (showDropDown.value) dropdownReady.value = true;
|
|
1002
|
+
},
|
|
1003
|
+
);
|
|
1004
|
+
|
|
1007
1005
|
</script>
|
|
1008
1006
|
|
|
1009
1007
|
<style lang="scss">
|
|
1010
|
-
.popper-defaultstyle {
|
|
1011
|
-
border: 0px solid transparent !important;
|
|
1012
|
-
margin: 0px !important;
|
|
1013
|
-
@apply w-full;
|
|
1014
|
-
|
|
1015
|
-
& > div.popper {
|
|
1016
|
-
width: 100% !important;
|
|
1017
|
-
}
|
|
1018
|
-
|
|
1019
|
-
&.search-tag-select--teleported > div.popper {
|
|
1020
|
-
display: none !important;
|
|
1021
|
-
}
|
|
1022
|
-
}
|
|
1023
|
-
|
|
1024
1008
|
.show-count {
|
|
1025
1009
|
@apply min-w-5 h-5 inline-flex items-center justify-center text-xss font-semibold bg-white rounded-xl;
|
|
1026
1010
|
}
|
|
@@ -470,7 +470,7 @@ const headerStyle = (header: Header) => ({
|
|
|
470
470
|
});
|
|
471
471
|
|
|
472
472
|
const bodyStyle = (header: Header) => ({
|
|
473
|
-
|
|
473
|
+
minWidth: `${header.width || 300}px`,
|
|
474
474
|
maxWidth: `${header.width || 300}px`,
|
|
475
475
|
// flex: `${header.width || 300} 0 auto`,
|
|
476
476
|
});
|
|
@@ -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",
|