@sit-onyx/headless 0.9.0 → 0.10.0-dev-20260505160733
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/composables/comboBox/SelectOnlyCombobox.d.vue.ts +2 -1
- package/dist/composables/comboBox/TestCombobox.d.vue.ts +2 -1
- package/dist/composables/comboBox/createComboBox.d.ts +3 -2
- package/dist/composables/listbox/createListbox.d.ts +3 -2
- package/dist/composables/menuButton/createMenuButton.d.ts +73 -18
- package/dist/index.js +117 -20
- package/package.json +1 -1
|
@@ -12,7 +12,7 @@ declare const _default: import('@vue/runtime-core').DefineComponent<{}, {
|
|
|
12
12
|
readonly "aria-disabled": boolean | undefined;
|
|
13
13
|
readonly "aria-checked": boolean | undefined;
|
|
14
14
|
readonly "aria-selected": boolean | undefined;
|
|
15
|
-
readonly onClick: () => false | void | undefined;
|
|
15
|
+
readonly onClick: (event: PointerEvent) => false | void | undefined;
|
|
16
16
|
}>;
|
|
17
17
|
group: import('@vue/reactivity').ComputedRef<(options: {
|
|
18
18
|
label: string;
|
|
@@ -228,6 +228,7 @@ declare const _default: import('@vue/runtime-core').DefineComponent<{}, {
|
|
|
228
228
|
}, undefined, {
|
|
229
229
|
getOptionId: (value: string) => string;
|
|
230
230
|
getOptionValueById: (id: string) => string | undefined;
|
|
231
|
+
getOption: (value: string) => HTMLElement | null;
|
|
231
232
|
}>;
|
|
232
233
|
}, {}, {}, {}, import('@vue/runtime-core').ComponentOptionsMixin, import('@vue/runtime-core').ComponentOptionsMixin, {}, string, import('@vue/runtime-core').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('@vue/runtime-core').ComponentProvideOptions, true, {
|
|
233
234
|
combobox: HTMLDivElement;
|
|
@@ -12,7 +12,7 @@ declare const _default: import('@vue/runtime-core').DefineComponent<{}, {
|
|
|
12
12
|
readonly "aria-disabled": boolean | undefined;
|
|
13
13
|
readonly "aria-checked": boolean | undefined;
|
|
14
14
|
readonly "aria-selected": boolean | undefined;
|
|
15
|
-
readonly onClick: () => false | void | undefined;
|
|
15
|
+
readonly onClick: (event: PointerEvent) => false | void | undefined;
|
|
16
16
|
}>;
|
|
17
17
|
group: import('@vue/reactivity').ComputedRef<(options: {
|
|
18
18
|
label: string;
|
|
@@ -228,6 +228,7 @@ declare const _default: import('@vue/runtime-core').DefineComponent<{}, {
|
|
|
228
228
|
}, undefined, {
|
|
229
229
|
getOptionId: (value: string) => string;
|
|
230
230
|
getOptionValueById: (id: string) => string | undefined;
|
|
231
|
+
getOption: (value: string) => HTMLElement | null;
|
|
231
232
|
}>;
|
|
232
233
|
}, {}, {}, {}, import('@vue/runtime-core').ComponentOptionsMixin, import('@vue/runtime-core').ComponentOptionsMixin, {}, string, import('@vue/runtime-core').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('@vue/runtime-core').ComponentProvideOptions, true, {
|
|
233
234
|
combobox: HTMLDivElement;
|
|
@@ -38,7 +38,7 @@ export type CreateComboboxOptions<TValue extends ListboxValue, TAutoComplete ext
|
|
|
38
38
|
/**
|
|
39
39
|
* Hook when an option is (un-)selected.
|
|
40
40
|
*/
|
|
41
|
-
onSelect?: (value: TValue) => void;
|
|
41
|
+
onSelect?: (value: TValue, event?: Event) => void;
|
|
42
42
|
/**
|
|
43
43
|
* Hook when the first option should be activated.
|
|
44
44
|
*/
|
|
@@ -77,7 +77,7 @@ export declare const createComboBox: <TValue extends ListboxValue, TAutoComplete
|
|
|
77
77
|
readonly "aria-disabled": boolean | undefined;
|
|
78
78
|
readonly "aria-checked": boolean | undefined;
|
|
79
79
|
readonly "aria-selected": boolean | undefined;
|
|
80
|
-
readonly onClick: () => false | void | undefined;
|
|
80
|
+
readonly onClick: (event: PointerEvent) => false | void | undefined;
|
|
81
81
|
}>;
|
|
82
82
|
group: import('vue').ComputedRef<(options: {
|
|
83
83
|
label: string;
|
|
@@ -303,4 +303,5 @@ export declare const createComboBox: <TValue extends ListboxValue, TAutoComplete
|
|
|
303
303
|
}, undefined, {
|
|
304
304
|
getOptionId: (value: TValue) => string;
|
|
305
305
|
getOptionValueById: (id: string) => TValue | undefined;
|
|
306
|
+
getOption: (value: TValue) => HTMLElement | null;
|
|
306
307
|
}>;
|
|
@@ -31,7 +31,7 @@ export type CreateListboxOptions<TValue extends ListboxValue, TMultiple extends
|
|
|
31
31
|
/**
|
|
32
32
|
* Hook when an option is selected.
|
|
33
33
|
*/
|
|
34
|
-
onSelect?: (value: TValue) => void;
|
|
34
|
+
onSelect?: (value: TValue, event?: Event) => void;
|
|
35
35
|
/**
|
|
36
36
|
* Hook when the first option should be activated.
|
|
37
37
|
*/
|
|
@@ -93,11 +93,12 @@ export declare const createListbox: <TValue extends ListboxValue, TMultiple exte
|
|
|
93
93
|
readonly "aria-disabled": boolean | undefined;
|
|
94
94
|
readonly "aria-checked": boolean | undefined;
|
|
95
95
|
readonly "aria-selected": boolean | undefined;
|
|
96
|
-
readonly onClick: () => false | void | undefined;
|
|
96
|
+
readonly onClick: (event: PointerEvent) => false | void | undefined;
|
|
97
97
|
}>;
|
|
98
98
|
}, {
|
|
99
99
|
isFocused: Ref<boolean, boolean>;
|
|
100
100
|
}, {
|
|
101
101
|
getOptionId: (value: TValue) => string;
|
|
102
102
|
getOptionValueById: (id: string) => TValue | undefined;
|
|
103
|
+
getOption: (value: TValue) => HTMLElement | null;
|
|
103
104
|
}>;
|
|
@@ -18,6 +18,10 @@ export declare const createMenuButton: (options: CreateMenuButtonOptions) => {
|
|
|
18
18
|
elements: {
|
|
19
19
|
listItem: {
|
|
20
20
|
role: string;
|
|
21
|
+
onMouseenter: (event?: Event) => void;
|
|
22
|
+
onMouseleave: () => void;
|
|
23
|
+
onFocusin: (event?: Event) => void;
|
|
24
|
+
onFocusout: () => void;
|
|
21
25
|
};
|
|
22
26
|
menuItem: (data: {
|
|
23
27
|
active?: boolean;
|
|
@@ -28,6 +32,22 @@ export declare const createMenuButton: (options: CreateMenuButtonOptions) => {
|
|
|
28
32
|
role: string;
|
|
29
33
|
onKeydown: (event: KeyboardEvent) => void;
|
|
30
34
|
};
|
|
35
|
+
internalChildren: {
|
|
36
|
+
role: string;
|
|
37
|
+
};
|
|
38
|
+
backButton: {
|
|
39
|
+
onKeydown: (event: KeyboardEvent) => void;
|
|
40
|
+
onClick: (event: Event) => void;
|
|
41
|
+
};
|
|
42
|
+
externalChildren: {
|
|
43
|
+
role: string;
|
|
44
|
+
tabindex: number;
|
|
45
|
+
onKeydown: (event: KeyboardEvent) => void;
|
|
46
|
+
onMouseenter: (event?: Event) => void;
|
|
47
|
+
onMouseleave: () => void;
|
|
48
|
+
onFocusin: (event?: Event) => void;
|
|
49
|
+
onFocusout: () => void;
|
|
50
|
+
};
|
|
31
51
|
root: import('vue').ComputedRef<{
|
|
32
52
|
onMouseenter?: (() => void) | undefined;
|
|
33
53
|
onMouseleave?: (() => void) | undefined;
|
|
@@ -54,26 +74,61 @@ export declare const createMenuButton: (options: CreateMenuButtonOptions) => {
|
|
|
54
74
|
};
|
|
55
75
|
};
|
|
56
76
|
type CreateMenuItemOptions = {
|
|
57
|
-
/**
|
|
58
|
-
|
|
59
|
-
|
|
77
|
+
/** Current expanded state of the menu item (for nested children). */
|
|
78
|
+
isExpanded?: Ref<boolean>;
|
|
79
|
+
/** Whether the menu item renders its children in an external flyout. */
|
|
80
|
+
isExternal?: MaybeRefOrGetter<boolean>;
|
|
81
|
+
/** Whether the menu item is disabled. */
|
|
82
|
+
disabled?: MaybeRefOrGetter<boolean>;
|
|
83
|
+
/** DOM element ref of the external children wrapper (used for focus checks). */
|
|
84
|
+
externalChildrenRef?: Readonly<Ref<HTMLElement | null>>;
|
|
85
|
+
/** Called when the menu item should be opened (if it has nested children). */
|
|
60
86
|
onOpen?: () => void;
|
|
87
|
+
/** Called when the menu item should be closed.*/
|
|
88
|
+
onClose?: () => void;
|
|
89
|
+
/** Called when the external children should close and focus the trigger. */
|
|
90
|
+
onFocusTrigger?: () => void;
|
|
91
|
+
/** Called to notify a parent menu of a hover enter event. */
|
|
92
|
+
onHoverEnterParent?: () => void;
|
|
93
|
+
/** Called to notify a parent menu of a hover leave event. */
|
|
94
|
+
onHoverLeaveParent?: () => void;
|
|
61
95
|
openingArrowDirection?: MaybeRefOrGetter<"ArrowRight" | "ArrowLeft">;
|
|
62
96
|
};
|
|
63
|
-
export declare const createMenuItems: (options?: CreateMenuItemOptions | undefined) => {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
disabled?: boolean;
|
|
71
|
-
}) => {
|
|
72
|
-
"aria-current": "page" | undefined;
|
|
73
|
-
"aria-disabled": boolean | undefined;
|
|
74
|
-
role: string;
|
|
75
|
-
onKeydown: (event: KeyboardEvent) => void;
|
|
76
|
-
};
|
|
97
|
+
export declare const createMenuItems: (options?: CreateMenuItemOptions | undefined) => import('../../utils/builder.js').HeadlessComposable<{
|
|
98
|
+
listItem: {
|
|
99
|
+
role: string;
|
|
100
|
+
onMouseenter: (event?: Event) => void;
|
|
101
|
+
onMouseleave: () => void;
|
|
102
|
+
onFocusin: (event?: Event) => void;
|
|
103
|
+
onFocusout: () => void;
|
|
77
104
|
};
|
|
78
|
-
|
|
105
|
+
menuItem: (data: {
|
|
106
|
+
active?: boolean;
|
|
107
|
+
disabled?: boolean;
|
|
108
|
+
}) => {
|
|
109
|
+
"aria-current": "page" | undefined;
|
|
110
|
+
"aria-disabled": boolean | undefined;
|
|
111
|
+
role: string;
|
|
112
|
+
onKeydown: (event: KeyboardEvent) => void;
|
|
113
|
+
};
|
|
114
|
+
internalChildren: {
|
|
115
|
+
role: string;
|
|
116
|
+
};
|
|
117
|
+
backButton: {
|
|
118
|
+
onKeydown: (event: KeyboardEvent) => void;
|
|
119
|
+
onClick: (event: Event) => void;
|
|
120
|
+
};
|
|
121
|
+
externalChildren: {
|
|
122
|
+
role: string;
|
|
123
|
+
tabindex: number;
|
|
124
|
+
onKeydown: (event: KeyboardEvent) => void;
|
|
125
|
+
onMouseenter: (event?: Event) => void;
|
|
126
|
+
onMouseleave: () => void;
|
|
127
|
+
onFocusin: (event?: Event) => void;
|
|
128
|
+
onFocusout: () => void;
|
|
129
|
+
};
|
|
130
|
+
}, undefined, {
|
|
131
|
+
handlePopoverMouseEnter: (event?: Event) => void;
|
|
132
|
+
handlePopoverMouseLeave: () => void;
|
|
133
|
+
}>;
|
|
79
134
|
export {};
|
package/dist/index.js
CHANGED
|
@@ -564,15 +564,18 @@ var createListbox = createBuilder((options) => {
|
|
|
564
564
|
const getOptionValueById = (id) => {
|
|
565
565
|
return Array.from(descendantKeyIdMap.entries()).find(([_value, key]) => key === id)?.[0];
|
|
566
566
|
};
|
|
567
|
+
const getOption = (value) => {
|
|
568
|
+
const id = getOptionId(value);
|
|
569
|
+
return document.getElementById(id);
|
|
570
|
+
};
|
|
567
571
|
/**
|
|
568
572
|
* Whether the listbox element is focused.
|
|
569
573
|
*/
|
|
570
574
|
const isFocused = ref(false);
|
|
571
575
|
watchEffect(async () => {
|
|
572
576
|
if (!isExpanded.value || options.activeOption.value == void 0 || !isFocused.value && !options.controlled) return;
|
|
573
|
-
const id = getOptionId(options.activeOption.value);
|
|
574
577
|
await nextTick();
|
|
575
|
-
|
|
578
|
+
getOption(options.activeOption.value)?.scrollIntoView({
|
|
576
579
|
block: "nearest",
|
|
577
580
|
inline: "nearest"
|
|
578
581
|
});
|
|
@@ -582,7 +585,7 @@ var createListbox = createBuilder((options) => {
|
|
|
582
585
|
switch (event.key) {
|
|
583
586
|
case " ":
|
|
584
587
|
event.preventDefault();
|
|
585
|
-
if (options.activeOption.value != void 0) options.onSelect?.(options.activeOption.value);
|
|
588
|
+
if (options.activeOption.value != void 0) options.onSelect?.(options.activeOption.value, event);
|
|
586
589
|
break;
|
|
587
590
|
case "ArrowUp":
|
|
588
591
|
event.preventDefault();
|
|
@@ -646,7 +649,7 @@ var createListbox = createBuilder((options) => {
|
|
|
646
649
|
"aria-disabled": data.disabled,
|
|
647
650
|
"aria-checked": isMultiselect.value ? selected : void 0,
|
|
648
651
|
"aria-selected": !isMultiselect.value ? selected : void 0,
|
|
649
|
-
onClick: () => !data.disabled && options.onSelect?.(data.value)
|
|
652
|
+
onClick: (event) => !data.disabled && options.onSelect?.(data.value, event)
|
|
650
653
|
};
|
|
651
654
|
};
|
|
652
655
|
})
|
|
@@ -654,7 +657,8 @@ var createListbox = createBuilder((options) => {
|
|
|
654
657
|
state: { isFocused },
|
|
655
658
|
internals: {
|
|
656
659
|
getOptionId,
|
|
657
|
-
getOptionValueById
|
|
660
|
+
getOptionValueById,
|
|
661
|
+
getOption
|
|
658
662
|
}
|
|
659
663
|
};
|
|
660
664
|
});
|
|
@@ -696,9 +700,9 @@ var createComboBox = createBuilder(({ autocomplete: autocompleteRef, onAutocompl
|
|
|
696
700
|
if (autocomplete.value !== "none") onAutocomplete?.(inputElement.value);
|
|
697
701
|
};
|
|
698
702
|
const typeAhead = useTypeAhead((inputString) => onTypeAhead?.(inputString));
|
|
699
|
-
const handleSelect = (value) => {
|
|
700
|
-
onSelect?.(value);
|
|
701
|
-
if (!
|
|
703
|
+
const handleSelect = (value, event) => {
|
|
704
|
+
onSelect?.(value, event);
|
|
705
|
+
if (!toValue(multiple)) onToggle?.();
|
|
702
706
|
};
|
|
703
707
|
const handleNavigation = (event) => {
|
|
704
708
|
switch (event.key) {
|
|
@@ -749,7 +753,7 @@ var createComboBox = createBuilder(({ autocomplete: autocompleteRef, onAutocompl
|
|
|
749
753
|
type: "text"
|
|
750
754
|
};
|
|
751
755
|
});
|
|
752
|
-
const { elements: { option, group, listbox }, internals: { getOptionId, getOptionValueById } } = createListbox({
|
|
756
|
+
const { elements: { option, group, listbox }, internals: { getOptionId, getOptionValueById, getOption } } = createListbox({
|
|
753
757
|
label: listLabel,
|
|
754
758
|
description: listDescription,
|
|
755
759
|
multiple,
|
|
@@ -791,7 +795,8 @@ var createComboBox = createBuilder(({ autocomplete: autocompleteRef, onAutocompl
|
|
|
791
795
|
},
|
|
792
796
|
internals: {
|
|
793
797
|
getOptionId,
|
|
794
|
-
getOptionValueById
|
|
798
|
+
getOptionValueById,
|
|
799
|
+
getOption
|
|
795
800
|
}
|
|
796
801
|
};
|
|
797
802
|
});
|
|
@@ -1154,7 +1159,48 @@ var createMenuButton = createBuilder((options) => {
|
|
|
1154
1159
|
} };
|
|
1155
1160
|
});
|
|
1156
1161
|
var createMenuItems = createBuilder((options) => {
|
|
1157
|
-
const { onOpen, openingArrowDirection = "ArrowRight" } = options || {};
|
|
1162
|
+
const { isExpanded, isExternal, disabled, externalChildrenRef, onOpen, onClose, onFocusTrigger, onHoverEnterParent, onHoverLeaveParent, openingArrowDirection = "ArrowRight" } = options || {};
|
|
1163
|
+
const debouncedClose = debounce(() => {
|
|
1164
|
+
if (isExpanded) isExpanded.value = false;
|
|
1165
|
+
}, 300);
|
|
1166
|
+
onBeforeUnmount(() => {
|
|
1167
|
+
debouncedClose.abort();
|
|
1168
|
+
});
|
|
1169
|
+
const handleClose = () => {
|
|
1170
|
+
debouncedClose.abort();
|
|
1171
|
+
if (isExpanded) isExpanded.value = false;
|
|
1172
|
+
onClose?.();
|
|
1173
|
+
};
|
|
1174
|
+
const handleTriggerMouseEnter = (event) => {
|
|
1175
|
+
if (toValue(isExternal) && !toValue(disabled)) {
|
|
1176
|
+
if (event?.type === "focusin") {
|
|
1177
|
+
const focusEvent = event;
|
|
1178
|
+
const relatedTarget = focusEvent.relatedTarget;
|
|
1179
|
+
const target = focusEvent.target;
|
|
1180
|
+
const externalNode = toValue(externalChildrenRef);
|
|
1181
|
+
if (!externalNode?.contains(target) && relatedTarget && externalNode?.contains(relatedTarget)) {
|
|
1182
|
+
debouncedClose.abort();
|
|
1183
|
+
return;
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
debouncedClose.abort();
|
|
1187
|
+
if (isExpanded) isExpanded.value = true;
|
|
1188
|
+
}
|
|
1189
|
+
};
|
|
1190
|
+
const handleTriggerMouseLeave = () => {
|
|
1191
|
+
if (toValue(isExternal)) {
|
|
1192
|
+
debouncedClose.abort();
|
|
1193
|
+
debouncedClose();
|
|
1194
|
+
}
|
|
1195
|
+
};
|
|
1196
|
+
const handlePopoverMouseEnter = (event) => {
|
|
1197
|
+
handleTriggerMouseEnter(event);
|
|
1198
|
+
onHoverEnterParent?.();
|
|
1199
|
+
};
|
|
1200
|
+
const handlePopoverMouseLeave = () => {
|
|
1201
|
+
handleTriggerMouseLeave();
|
|
1202
|
+
onHoverLeaveParent?.();
|
|
1203
|
+
};
|
|
1158
1204
|
const onKeydown = (event) => {
|
|
1159
1205
|
const resolvedKey = toValue(openingArrowDirection);
|
|
1160
1206
|
switch (event.key) {
|
|
@@ -1166,15 +1212,66 @@ var createMenuItems = createBuilder((options) => {
|
|
|
1166
1212
|
break;
|
|
1167
1213
|
}
|
|
1168
1214
|
};
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1215
|
+
const getClosingArrowDirection = () => {
|
|
1216
|
+
return toValue(openingArrowDirection) === "ArrowRight" ? "ArrowLeft" : "ArrowRight";
|
|
1217
|
+
};
|
|
1218
|
+
const onBackButtonKeydown = (event) => {
|
|
1219
|
+
if ([
|
|
1220
|
+
getClosingArrowDirection(),
|
|
1221
|
+
" ",
|
|
1222
|
+
"Enter"
|
|
1223
|
+
].includes(event.key)) {
|
|
1224
|
+
event.preventDefault();
|
|
1225
|
+
event.stopPropagation();
|
|
1226
|
+
handleClose();
|
|
1227
|
+
}
|
|
1228
|
+
};
|
|
1229
|
+
const onExternalChildrenKeydown = (event) => {
|
|
1230
|
+
const closeKey = getClosingArrowDirection();
|
|
1231
|
+
if (event.key === closeKey) {
|
|
1232
|
+
event.preventDefault();
|
|
1233
|
+
event.stopPropagation();
|
|
1234
|
+
onFocusTrigger?.();
|
|
1235
|
+
}
|
|
1236
|
+
};
|
|
1237
|
+
return {
|
|
1238
|
+
elements: {
|
|
1239
|
+
listItem: {
|
|
1240
|
+
role: "none",
|
|
1241
|
+
onMouseenter: handleTriggerMouseEnter,
|
|
1242
|
+
onMouseleave: handleTriggerMouseLeave,
|
|
1243
|
+
onFocusin: handleTriggerMouseEnter,
|
|
1244
|
+
onFocusout: handleTriggerMouseLeave
|
|
1245
|
+
},
|
|
1246
|
+
menuItem: (data) => ({
|
|
1247
|
+
"aria-current": data.active ? "page" : void 0,
|
|
1248
|
+
"aria-disabled": data.disabled,
|
|
1249
|
+
role: "menuitem",
|
|
1250
|
+
onKeydown
|
|
1251
|
+
}),
|
|
1252
|
+
internalChildren: { role: "menu" },
|
|
1253
|
+
backButton: {
|
|
1254
|
+
onKeydown: onBackButtonKeydown,
|
|
1255
|
+
onClick: (event) => {
|
|
1256
|
+
event.stopPropagation();
|
|
1257
|
+
handleClose();
|
|
1258
|
+
}
|
|
1259
|
+
},
|
|
1260
|
+
externalChildren: {
|
|
1261
|
+
role: "presentation",
|
|
1262
|
+
tabindex: -1,
|
|
1263
|
+
onKeydown: onExternalChildrenKeydown,
|
|
1264
|
+
onMouseenter: handlePopoverMouseEnter,
|
|
1265
|
+
onMouseleave: handlePopoverMouseLeave,
|
|
1266
|
+
onFocusin: handlePopoverMouseEnter,
|
|
1267
|
+
onFocusout: handlePopoverMouseLeave
|
|
1268
|
+
}
|
|
1269
|
+
},
|
|
1270
|
+
internals: {
|
|
1271
|
+
handlePopoverMouseEnter,
|
|
1272
|
+
handlePopoverMouseLeave
|
|
1273
|
+
}
|
|
1274
|
+
};
|
|
1178
1275
|
});
|
|
1179
1276
|
//#endregion
|
|
1180
1277
|
//#region src/utils/math.ts
|