@sit-onyx/headless 0.11.0 → 0.12.0-dev-20260730150439
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/LICENSE.txt +1 -1
- package/README.md +2 -2
- package/dist/composables/comboBox/createComboBox.d.ts +12 -6
- package/dist/composables/comboBox/createComboBox.testing.d.ts +2 -1
- package/dist/composables/dataGrid/createDataGrid.d.ts +8 -5
- package/dist/composables/dragAndDrop/createDragAndDrop.d.ts +44 -0
- package/dist/composables/helpers/useAllSettled.d.ts +3 -2
- package/dist/composables/helpers/useDismissible.d.ts +3 -2
- package/dist/composables/helpers/useLastSettled.d.ts +6 -4
- package/dist/composables/helpers/useTypeAhead.d.ts +7 -6
- package/dist/composables/listbox/createListbox.d.ts +4 -3
- package/dist/composables/listbox/createListbox.testing.d.ts +3 -2
- package/dist/composables/menuButton/createMenuButton.d.ts +29 -10
- package/dist/composables/menuButton/createMenuButton.testing.d.ts +3 -2
- package/dist/composables/navigationMenu/createMenu.testing.d.ts +3 -2
- package/dist/composables/slider/createSlider.d.ts +3 -2
- package/dist/composables/tabs/createTabs.testing.d.ts +4 -3
- package/dist/composables/toggleButton/createToggleButton.testing.d.ts +3 -2
- package/dist/composables/tooltip/createTooltip.d.ts +5 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +146 -85
- package/dist/playwright.js +16 -11
- package/dist/utils/builder.d.ts +42 -41
- package/dist/utils/keyboard.d.ts +10 -6
- package/dist/utils/math.d.ts +2 -2
- package/dist/utils/object.d.ts +1 -0
- package/dist/utils/types.d.ts +6 -5
- package/dist/utils/vitest.d.ts +2 -1
- package/package.json +21 -21
package/LICENSE.txt
CHANGED
|
@@ -175,7 +175,7 @@
|
|
|
175
175
|
|
|
176
176
|
END OF TERMS AND CONDITIONS
|
|
177
177
|
|
|
178
|
-
Copyright 2023 Schwarz IT KG
|
|
178
|
+
Copyright 2023 Schwarz Digits IT KG
|
|
179
179
|
|
|
180
180
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
181
181
|
you may not use this file except in compliance with the License.
|
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<div align="center" style="text-align: center">
|
|
2
|
-
|
|
2
|
+
<img alt="Onyx logo" src="https://raw.githubusercontent.com/SchwarzIT/onyx/main/packages/assets/src/onyx-brand/signet.svg" height="96px">
|
|
3
3
|
</div>
|
|
4
4
|
|
|
5
5
|
<br>
|
|
6
6
|
|
|
7
7
|
# onyx Headless
|
|
8
8
|
|
|
9
|
-
A composable headless library for Vue created by [Schwarz
|
|
9
|
+
A composable headless library for Vue created by [Schwarz Digits](https://schwarz-digits.de).
|
|
10
10
|
|
|
11
11
|
<br />
|
|
12
12
|
|
|
@@ -2,7 +2,9 @@ import { MaybeRef, Ref } from 'vue';
|
|
|
2
2
|
import { PressedKey } from '../../utils/keyboard.js';
|
|
3
3
|
import { Nullable } from '../../utils/types.js';
|
|
4
4
|
import { CreateListboxOptions, ListboxValue } from '../listbox/createListbox.js';
|
|
5
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* See https://w3c.github.io/aria/#aria-autocomplete
|
|
7
|
+
*/
|
|
6
8
|
export type ComboboxAutoComplete = "none" | "list" | "both";
|
|
7
9
|
export declare const OPENING_KEYS: PressedKey[];
|
|
8
10
|
export declare const CLOSING_KEYS: PressedKey[];
|
|
@@ -10,7 +12,8 @@ export type CreateComboboxOptions<TValue extends ListboxValue, TAutoComplete ext
|
|
|
10
12
|
autocomplete: MaybeRef<TAutoComplete>;
|
|
11
13
|
label: MaybeRef<string>;
|
|
12
14
|
/**
|
|
13
|
-
* Labels the listbox which displays the available options. E.g. the list label could be
|
|
15
|
+
* Labels the listbox which displays the available options. E.g. the list label could be
|
|
16
|
+
* "Countries" for a combobox which is labelled "Country".
|
|
14
17
|
*/
|
|
15
18
|
listLabel: MaybeRef<string>;
|
|
16
19
|
/**
|
|
@@ -18,7 +21,8 @@ export type CreateComboboxOptions<TValue extends ListboxValue, TAutoComplete ext
|
|
|
18
21
|
*/
|
|
19
22
|
listDescription?: MaybeRef<Nullable<string>>;
|
|
20
23
|
/**
|
|
21
|
-
* Controls the opened/visible state of the associated pop-up. When expanded the activeOption can
|
|
24
|
+
* Controls the opened/visible state of the associated pop-up. When expanded the activeOption can
|
|
25
|
+
* be controlled via the keyboard.
|
|
22
26
|
*/
|
|
23
27
|
isExpanded: MaybeRef<boolean>;
|
|
24
28
|
/**
|
|
@@ -32,7 +36,8 @@ export type CreateComboboxOptions<TValue extends ListboxValue, TAutoComplete ext
|
|
|
32
36
|
/**
|
|
33
37
|
* Hook when the popover should toggle.
|
|
34
38
|
*
|
|
35
|
-
* @param preventFocus If `true`, the parent combobox should not be focused (e.g. on outside
|
|
39
|
+
* @param preventFocus If `true`, the parent combobox should not be focused (e.g. on outside
|
|
40
|
+
* click).
|
|
36
41
|
*/
|
|
37
42
|
onToggle?: (preventFocus?: boolean) => void;
|
|
38
43
|
/**
|
|
@@ -279,8 +284,9 @@ export declare const createComboBox: <TValue extends ListboxValue, TAutoComplete
|
|
|
279
284
|
ref?: Ref<import('../../utils/builder.js').VueTemplateRefElement<Element>, import('../../utils/builder.js').VueTemplateRefElement<Element>> | undefined;
|
|
280
285
|
}>;
|
|
281
286
|
/**
|
|
282
|
-
* An input that controls another element, that can dynamically pop-up to help the user set
|
|
283
|
-
* The input MAY be either a single-line text field that supports
|
|
287
|
+
* An input that controls another element, that can dynamically pop-up to help the user set
|
|
288
|
+
* the value of the input. The input MAY be either a single-line text field that supports
|
|
289
|
+
* editing and typing or an element that only displays the current value of the combobox.
|
|
284
290
|
*/
|
|
285
291
|
input: import('vue').ComputedRef<{
|
|
286
292
|
"aria-autocomplete"?: TAutoComplete | undefined;
|
|
@@ -5,6 +5,7 @@ import { Locator, Page } from '@playwright/test';
|
|
|
5
5
|
export declare const comboboxTesting: (_page: Page, listbox: Locator, combobox: Locator, button: Locator, options: Locator) => Promise<void>;
|
|
6
6
|
export type CheckLocator = (option: Locator) => Promise<boolean>;
|
|
7
7
|
/**
|
|
8
|
-
* Test an implementation of the combobox based on
|
|
8
|
+
* Test an implementation of the combobox based on
|
|
9
|
+
* https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-select-only/
|
|
9
10
|
*/
|
|
10
11
|
export declare const comboboxSelectOnlyTesting: (page: Page, listbox: Locator, combobox: Locator, isActive: CheckLocator) => Promise<void>;
|
|
@@ -7,11 +7,13 @@ type CellIdentifier = {
|
|
|
7
7
|
export type LazyOptions<Lazy extends boolean> = Lazy extends true ? {
|
|
8
8
|
lazy: MaybeRefOrGetter<{
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Total number of rows that are viewable, this includes rows that are hidden because they
|
|
11
|
+
* are out of view
|
|
11
12
|
*/
|
|
12
13
|
totalRows: number | "unknown";
|
|
13
14
|
/**
|
|
14
|
-
*
|
|
15
|
+
* Total number of columns that are viewable, this includes columns that are hidden because
|
|
16
|
+
* they are out of view
|
|
15
17
|
*/
|
|
16
18
|
totalCols: number | "unknown";
|
|
17
19
|
requestLazyLoad: RequestLazyLoad;
|
|
@@ -71,9 +73,10 @@ export declare const createDataGrid: <Lazy extends boolean = false>(options: Cre
|
|
|
71
73
|
}>;
|
|
72
74
|
}, {
|
|
73
75
|
/**
|
|
74
|
-
* Indicates that the data grid expects a content change soon, e.g. because more or other
|
|
75
|
-
* If `loading` is passed in via the options, this will mirror its value.
|
|
76
|
-
* Otherwise it will be dynamically set based on the running state of the `requestLazyLoad`
|
|
76
|
+
* Indicates that the data grid expects a content change soon, e.g. because more or other
|
|
77
|
+
* data is loaded. If `loading` is passed in via the options, this will mirror its value.
|
|
78
|
+
* Otherwise it will be dynamically set based on the running state of the `requestLazyLoad`
|
|
79
|
+
* promises.
|
|
77
80
|
*/
|
|
78
81
|
busy: import('vue').ComputedRef<boolean>;
|
|
79
82
|
}, {}>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export type CreateDragAndDropOptions<TItem> = {
|
|
2
|
+
/**
|
|
3
|
+
* Emitted while actively dragging.
|
|
4
|
+
* Will be called for each animation frame.
|
|
5
|
+
*/
|
|
6
|
+
onDragover?(event: DragEvent): void;
|
|
7
|
+
/**
|
|
8
|
+
* Emitted when an active drag is dropped over a valid drop target.
|
|
9
|
+
*/
|
|
10
|
+
onDrop?: (event: DragEvent) => void;
|
|
11
|
+
/**
|
|
12
|
+
* Emitted when an item starts to be dragged.
|
|
13
|
+
*/
|
|
14
|
+
onDragstart?: (event: DragEvent, item: TItem) => void;
|
|
15
|
+
/**
|
|
16
|
+
* Emitted when the user ends stops dragging the element.
|
|
17
|
+
*/
|
|
18
|
+
onDragend?: (event: DragEvent, item: TItem) => void;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Composable for creating drag and drop functionality.
|
|
22
|
+
*/
|
|
23
|
+
export declare const createDragAndDrop: <TItem>(options: CreateDragAndDropOptions<TItem>) => {
|
|
24
|
+
elements: {
|
|
25
|
+
/**
|
|
26
|
+
* Drop target where draggable elements are allowed to be dropped.
|
|
27
|
+
* drop).
|
|
28
|
+
*/
|
|
29
|
+
target: {
|
|
30
|
+
onDragover: (event: DragEvent) => void;
|
|
31
|
+
onDrop: (event: DragEvent) => void;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Drag and drop trigger / handle (e.g. an icon) that starts the drag.
|
|
35
|
+
*/
|
|
36
|
+
trigger: ({ item }: {
|
|
37
|
+
item: TItem;
|
|
38
|
+
}) => {
|
|
39
|
+
draggable: true;
|
|
40
|
+
onDragstart: (event: DragEvent) => void | undefined;
|
|
41
|
+
onDragend: (event: DragEvent) => void | undefined;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
};
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* Execute a callback, when all added promise are settled (either resolved or rejected).
|
|
3
3
|
* It allows for more promises to be added while waiting.
|
|
4
4
|
*
|
|
5
|
-
* @param cb
|
|
6
|
-
* @returns
|
|
5
|
+
* @param cb Callback to execute when all added promise are settled.
|
|
6
|
+
* @returns An object with an add function and the active state which is true as long as any promise
|
|
7
|
+
* is running.
|
|
7
8
|
*/
|
|
8
9
|
export declare const useAllSettled: (cb?: () => void) => {
|
|
9
10
|
add: (promise: Promise<unknown>) => void;
|
|
@@ -3,8 +3,9 @@ type UseDismissibleOptions = {
|
|
|
3
3
|
isExpanded: Ref<boolean>;
|
|
4
4
|
};
|
|
5
5
|
/**
|
|
6
|
-
* Composable that sets `isExpanded` to false, when the `Escape` key is pressed.
|
|
7
|
-
*
|
|
6
|
+
* Composable that sets `isExpanded` to false, when the `Escape` key is pressed. Addresses the
|
|
7
|
+
* "dismissible" aspect of
|
|
8
|
+
* https://www.w3.org/WAI/WCAG21/Understanding/content-on-hover-or-focus.html
|
|
8
9
|
*/
|
|
9
10
|
export declare const useDismissible: ({ isExpanded }: UseDismissibleOptions) => void;
|
|
10
11
|
export {};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Execute a callback, when the latest promise is settled (either resolved or rejected).
|
|
3
|
-
*
|
|
2
|
+
* Execute a callback, when the latest promise is settled (either resolved or rejected). This
|
|
3
|
+
* ensures that out-of-order settling promises are ignored and only the latest promise is
|
|
4
|
+
* considered.
|
|
4
5
|
*
|
|
5
|
-
* @param cb
|
|
6
|
-
* @returns
|
|
6
|
+
* @param cb Callback to execute when the last promise, that was added to the queue, is settled.
|
|
7
|
+
* @returns The active state of the last settled promise and a queue function to add new promises to
|
|
8
|
+
* the queue.
|
|
7
9
|
*/
|
|
8
10
|
export declare const useLastSettled: <T>(cb: (success: boolean, resolved?: T) => void) => {
|
|
9
11
|
active: import('vue').Ref<boolean, boolean>;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Enhances typeAhead to combine multiple inputs in quick succession and filter out non-printable
|
|
2
|
+
* Enhances typeAhead to combine multiple inputs in quick succession and filter out non-printable
|
|
3
|
+
* characters.
|
|
3
4
|
*
|
|
4
5
|
* @example
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* const typeAhead = useTypeAhead((inputString) => console.log("Typed string:", inputString));
|
|
8
|
+
* // ...
|
|
9
|
+
* addEventListener("keydown", typeAhead);
|
|
10
|
+
* ```;
|
|
10
11
|
*/
|
|
11
12
|
export declare const useTypeAhead: (callback: (input: string) => void, timeout?: number) => (event: Pick<KeyboardEvent, "key">) => void;
|
|
@@ -21,7 +21,8 @@ export type CreateListboxOptions<TValue extends ListboxValue, TMultiple extends
|
|
|
21
21
|
*/
|
|
22
22
|
controlled?: boolean;
|
|
23
23
|
/**
|
|
24
|
-
* Controls the opened/visible state of the listbox. When expanded the activeOption can be
|
|
24
|
+
* Controls the opened/visible state of the listbox. When expanded the activeOption can be
|
|
25
|
+
* controlled via the keyboard.
|
|
25
26
|
*/
|
|
26
27
|
isExpanded?: MaybeRef<boolean>;
|
|
27
28
|
/**
|
|
@@ -70,8 +71,8 @@ export type CreateListboxOptions<TValue extends ListboxValue, TMultiple extends
|
|
|
70
71
|
controlled?: false;
|
|
71
72
|
});
|
|
72
73
|
/**
|
|
73
|
-
* Composable for creating a accessibility-conform listbox.
|
|
74
|
-
*
|
|
74
|
+
* Composable for creating a accessibility-conform listbox. For supported keyboard shortcuts, see:
|
|
75
|
+
* https://www.w3.org/WAI/ARIA/apg/patterns/listbox/examples/listbox-scrollable/
|
|
75
76
|
*/
|
|
76
77
|
export declare const createListbox: <TValue extends ListboxValue, TMultiple extends boolean = false>(options: CreateListboxOptions<TValue, TMultiple>) => import('../../utils/builder.js').HeadlessComposable<{
|
|
77
78
|
listbox: import('vue').ComputedRef<VBindAttributes>;
|
|
@@ -18,7 +18,8 @@ export type ListboxTestingOptions = {
|
|
|
18
18
|
isOptionActive: (locator: Locator) => Promise<boolean>;
|
|
19
19
|
};
|
|
20
20
|
/**
|
|
21
|
-
* Playwright utility for executing accessibility testing for a listbox.
|
|
22
|
-
*
|
|
21
|
+
* Playwright utility for executing accessibility testing for a listbox. Will check aria attributes
|
|
22
|
+
* and keyboard shortcuts as defined in
|
|
23
|
+
* https://www.w3.org/WAI/ARIA/apg/patterns/listbox/examples/listbox-scrollable.
|
|
23
24
|
*/
|
|
24
25
|
export declare const listboxTesting: ({ page, listbox, options, isOptionActive, }: ListboxTestingOptions) => Promise<void>;
|
|
@@ -5,7 +5,8 @@ type CreateMenuButtonOptions = {
|
|
|
5
5
|
onToggle: () => void;
|
|
6
6
|
disabled?: Readonly<Ref<boolean>>;
|
|
7
7
|
/**
|
|
8
|
-
* Whether the menu button opens to the top or bottom. Defines the keyboard navigation behavior
|
|
8
|
+
* Whether the menu button opens to the top or bottom. Defines the keyboard navigation behavior
|
|
9
|
+
* (e.g. Arrow up and down).
|
|
9
10
|
*
|
|
10
11
|
* @default "bottom"
|
|
11
12
|
*/
|
|
@@ -74,23 +75,41 @@ export declare const createMenuButton: (options: CreateMenuButtonOptions) => {
|
|
|
74
75
|
};
|
|
75
76
|
};
|
|
76
77
|
type CreateMenuItemOptions = {
|
|
77
|
-
/**
|
|
78
|
+
/**
|
|
79
|
+
* Current expanded state of the menu item (for nested children).
|
|
80
|
+
*/
|
|
78
81
|
isExpanded?: Ref<boolean>;
|
|
79
|
-
/**
|
|
82
|
+
/**
|
|
83
|
+
* Whether the menu item renders its children in an external flyout.
|
|
84
|
+
*/
|
|
80
85
|
isExternal?: MaybeRefOrGetter<boolean>;
|
|
81
|
-
/**
|
|
86
|
+
/**
|
|
87
|
+
* Whether the menu item is disabled.
|
|
88
|
+
*/
|
|
82
89
|
disabled?: MaybeRefOrGetter<boolean>;
|
|
83
|
-
/**
|
|
90
|
+
/**
|
|
91
|
+
* DOM element ref of the external children wrapper (used for focus checks).
|
|
92
|
+
*/
|
|
84
93
|
externalChildrenRef?: Readonly<Ref<HTMLElement | null>>;
|
|
85
|
-
/**
|
|
94
|
+
/**
|
|
95
|
+
* Called when the menu item should be opened (if it has nested children).
|
|
96
|
+
*/
|
|
86
97
|
onOpen?: () => void;
|
|
87
|
-
/**
|
|
98
|
+
/**
|
|
99
|
+
* Called when the menu item should be closed.
|
|
100
|
+
*/
|
|
88
101
|
onClose?: () => void;
|
|
89
|
-
/**
|
|
102
|
+
/**
|
|
103
|
+
* Called when the external children should close and focus the trigger.
|
|
104
|
+
*/
|
|
90
105
|
onFocusTrigger?: () => void;
|
|
91
|
-
/**
|
|
106
|
+
/**
|
|
107
|
+
* Called to notify a parent menu of a hover enter event.
|
|
108
|
+
*/
|
|
92
109
|
onHoverEnterParent?: () => void;
|
|
93
|
-
/**
|
|
110
|
+
/**
|
|
111
|
+
* Called to notify a parent menu of a hover leave event.
|
|
112
|
+
*/
|
|
94
113
|
onHoverLeaveParent?: () => void;
|
|
95
114
|
openingArrowDirection?: MaybeRefOrGetter<"ArrowRight" | "ArrowLeft">;
|
|
96
115
|
};
|
|
@@ -18,7 +18,8 @@ export type MenuButtonTestingOptions = {
|
|
|
18
18
|
menuItems: Locator;
|
|
19
19
|
};
|
|
20
20
|
/**
|
|
21
|
-
* Playwright utility for executing accessibility testing for a navigation menu.
|
|
22
|
-
*
|
|
21
|
+
* Playwright utility for executing accessibility testing for a navigation menu. Will check aria
|
|
22
|
+
* attributes and keyboard shortcuts as defined in
|
|
23
|
+
* https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/examples/menu-button-links.
|
|
23
24
|
*/
|
|
24
25
|
export declare const menuButtonTesting: ({ page, button, menu, menuItems, }: MenuButtonTestingOptions) => Promise<void>;
|
|
@@ -10,7 +10,8 @@ export type NavigationMenuTestingOptions = {
|
|
|
10
10
|
buttons: Locator;
|
|
11
11
|
};
|
|
12
12
|
/**
|
|
13
|
-
* Playwright utility for executing accessibility testing for a navigation menu.
|
|
14
|
-
*
|
|
13
|
+
* Playwright utility for executing accessibility testing for a navigation menu. Will check aria
|
|
14
|
+
* attributes and keyboard shortcuts as defined in
|
|
15
|
+
* https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/examples/disclosure-navigation/
|
|
15
16
|
*/
|
|
16
17
|
export declare const navigationTesting: ({ nav, buttons }: NavigationMenuTestingOptions) => Promise<void>;
|
|
@@ -25,9 +25,10 @@ export type CreateSliderOptions<TValue extends SliderValue = SliderValue> = {
|
|
|
25
25
|
*/
|
|
26
26
|
step?: MaybeRef<number>;
|
|
27
27
|
/**
|
|
28
|
-
* Step size to increase/decrease the slider value when changing the value via keyboard while
|
|
28
|
+
* Step size to increase/decrease the slider value when changing the value via keyboard while
|
|
29
|
+
* pressing the "Shift" key.
|
|
29
30
|
*
|
|
30
|
-
*
|
|
31
|
+
* Default 10% of the total range (max - min)
|
|
31
32
|
*/
|
|
32
33
|
shiftStep?: MaybeRef<number | undefined>;
|
|
33
34
|
/**
|
|
@@ -2,12 +2,13 @@ import { Locator, Page } from '@playwright/test';
|
|
|
2
2
|
export type TabsTestingOptions = {
|
|
3
3
|
page: Page;
|
|
4
4
|
/**
|
|
5
|
-
* Locator of the tabs component. Must have at least 3 tabs where the first one is initially
|
|
5
|
+
* Locator of the tabs component. Must have at least 3 tabs where the first one is initially
|
|
6
|
+
* selected.
|
|
6
7
|
*/
|
|
7
8
|
tablist: Locator;
|
|
8
9
|
};
|
|
9
10
|
/**
|
|
10
|
-
* Playwright utility for executing accessibility testing for tabs.
|
|
11
|
-
*
|
|
11
|
+
* Playwright utility for executing accessibility testing for tabs. Will check aria attributes and
|
|
12
|
+
* keyboard shortcuts as defined in https://www.w3.org/WAI/ARIA/apg/patterns/tabs/
|
|
12
13
|
*/
|
|
13
14
|
export declare const tabsTesting: (options: TabsTestingOptions) => Promise<void>;
|
|
@@ -8,7 +8,8 @@ export type ToggleButtonTestingOptions = {
|
|
|
8
8
|
initiallyPressed: boolean;
|
|
9
9
|
};
|
|
10
10
|
/**
|
|
11
|
-
* Playwright utility for executing accessibility testing for a navigation menu.
|
|
12
|
-
*
|
|
11
|
+
* Playwright utility for executing accessibility testing for a navigation menu. Will check aria
|
|
12
|
+
* attributes and keyboard shortcuts as defined in
|
|
13
|
+
* https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/examples/menu-button-links.
|
|
13
14
|
*/
|
|
14
15
|
export declare const toggleButtonTesting: ({ button, labelText, initiallyPressed, }: ToggleButtonTestingOptions) => Promise<void>;
|
|
@@ -7,10 +7,11 @@ export type CreateTooltipOptions = {
|
|
|
7
7
|
isVisible?: Ref<boolean>;
|
|
8
8
|
};
|
|
9
9
|
/**
|
|
10
|
-
* Create a tooltip as described in
|
|
11
|
-
* Its visibility
|
|
12
|
-
* A tooltip MUST be used to describe the associated trigger element.
|
|
13
|
-
* To provide contextual information use the
|
|
10
|
+
* Create a tooltip as described in
|
|
11
|
+
* https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tooltip_role Its visibility
|
|
12
|
+
* is toggled on hover or focus. A tooltip MUST be used to describe the associated trigger element.
|
|
13
|
+
* E.g. The usage with the ⓘ would be incorrect. To provide contextual information use the
|
|
14
|
+
* `createToggletip`.
|
|
14
15
|
*/
|
|
15
16
|
export declare const createTooltip: (args_0: CreateTooltipOptions) => import('../../utils/builder.js').HeadlessComposable<{
|
|
16
17
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export * from './composables/tooltip/createToggletip.js';
|
|
|
13
13
|
export * from './composables/tooltip/createTooltip.js';
|
|
14
14
|
export * from './composables/treeView/createTreeView.js';
|
|
15
15
|
export * from './composables/treeView/createTreeViewItem.js';
|
|
16
|
+
export * from './composables/dragAndDrop/createDragAndDrop.js';
|
|
16
17
|
export * from './utils/builder.js';
|
|
17
18
|
export { isPrintableCharacter, wasKeyPressed } from './utils/keyboard.js';
|
|
18
19
|
export { debounce } from './utils/timer.js';
|
package/dist/index.js
CHANGED
|
@@ -2,63 +2,65 @@ import { computed, nextTick, onBeforeMount, onBeforeUnmount, onMounted, reactive
|
|
|
2
2
|
//#region src/utils/builder.ts
|
|
3
3
|
/**
|
|
4
4
|
* We use this identity function to ensure the correct typings of the headless composables
|
|
5
|
+
*
|
|
5
6
|
* @example
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* export const createTooltip = createBuilder(({ initialVisible }: CreateTooltipOptions) => {
|
|
9
|
+
* const tooltipId = useId();
|
|
10
|
+
* const isVisible = ref(initialVisible);
|
|
10
11
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
12
|
+
* const hoverEvents = {
|
|
13
|
+
* onMouseover: () => (isVisible.value = true),
|
|
14
|
+
* onMouseout: () => (isVisible.value = false),
|
|
15
|
+
* onFocusin: () => (isVisible.value = true),
|
|
16
|
+
* onFocusout: () => (isVisible.value = false),
|
|
17
|
+
* };
|
|
17
18
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
19
|
+
* return {
|
|
20
|
+
* elements: {
|
|
21
|
+
* trigger: {
|
|
22
|
+
* "aria-describedby": tooltipId,
|
|
23
|
+
* ...hoverEvents,
|
|
24
|
+
* },
|
|
25
|
+
* tooltip: {
|
|
26
|
+
* role: "tooltip",
|
|
27
|
+
* id: tooltipId,
|
|
28
|
+
* tabindex: "-1",
|
|
29
|
+
* ...hoverEvents,
|
|
30
|
+
* },
|
|
23
31
|
* },
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* id: tooltipId,
|
|
27
|
-
* tabindex: "-1",
|
|
28
|
-
* ...hoverEvents,
|
|
32
|
+
* state: {
|
|
33
|
+
* isVisible,
|
|
29
34
|
* },
|
|
30
|
-
* }
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* },
|
|
34
|
-
* };
|
|
35
|
-
* });
|
|
36
|
-
*
|
|
37
|
-
* ```
|
|
35
|
+
* };
|
|
36
|
+
* });
|
|
37
|
+
* ```;
|
|
38
38
|
*/
|
|
39
39
|
var createBuilder = (builder) => builder;
|
|
40
40
|
/**
|
|
41
41
|
* Creates a special writeable computed that references a DOM Element.
|
|
42
42
|
* Vue Component references will be unwrapped.
|
|
43
|
+
*
|
|
43
44
|
* @example
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
45
|
+
* ```ts
|
|
46
|
+
* createBuilder() => {
|
|
47
|
+
* const buttonRef = createElRef<HtmlButtonElement>();
|
|
48
|
+
* return {
|
|
49
|
+
* elements: {
|
|
50
|
+
* button: {
|
|
51
|
+
* ref: buttonRef,
|
|
52
|
+
* },
|
|
53
|
+
* }
|
|
54
|
+
* };
|
|
55
|
+
* });
|
|
56
|
+
* ```;
|
|
56
57
|
*/
|
|
57
58
|
function createElRef() {
|
|
58
59
|
const elementRef = shallowRef(null);
|
|
59
60
|
return computed({
|
|
60
61
|
set: (ref) => {
|
|
61
|
-
|
|
62
|
+
const element = Array.isArray(ref) ? ref[0] : ref;
|
|
63
|
+
elementRef.value = getNativeElement(element);
|
|
62
64
|
},
|
|
63
65
|
get: () => elementRef.value
|
|
64
66
|
});
|
|
@@ -361,6 +363,7 @@ var createCalendar = createBuilder((options) => {
|
|
|
361
363
|
//#region src/utils/object.ts
|
|
362
364
|
/**
|
|
363
365
|
* Check if every entry of a subset exists and matches the entry of a target object.
|
|
366
|
+
*
|
|
364
367
|
* @returns `true`, if target contains the subset
|
|
365
368
|
*/
|
|
366
369
|
var isSubsetMatching = (subset, target) => Object.entries(subset).every(([key, value]) => target[key] === value);
|
|
@@ -368,10 +371,12 @@ var isSubsetMatching = (subset, target) => Object.entries(subset).every(([key, v
|
|
|
368
371
|
//#region src/utils/keyboard.ts
|
|
369
372
|
/**
|
|
370
373
|
* Check if a specified key was pressed.
|
|
374
|
+
*
|
|
371
375
|
* @param event The KeyboardEvent
|
|
372
|
-
* @param key The key, either the [key
|
|
373
|
-
*
|
|
374
|
-
*
|
|
376
|
+
* @param key The key, either the [key
|
|
377
|
+
* property](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) as a string (e.g.
|
|
378
|
+
* "m") or an object with the relevant key parameters, e.g. `{ key: "m", altKey: true }`
|
|
379
|
+
* @returns True, if the key was pressed with the specified parameters
|
|
375
380
|
*/
|
|
376
381
|
var wasKeyPressed = (event, key) => {
|
|
377
382
|
if (typeof key === "string") return event.key === key;
|
|
@@ -387,9 +392,11 @@ var GRAPHEME_SEGMENTER = new Intl.Segmenter("en-US");
|
|
|
387
392
|
/**
|
|
388
393
|
* Check if the `key` property of a KeyboardEvent is a printable character.
|
|
389
394
|
*
|
|
390
|
-
* There is no standardized or specified algorithm to check for [named
|
|
391
|
-
*
|
|
392
|
-
*
|
|
395
|
+
* There is no standardized or specified algorithm to check for [named
|
|
396
|
+
* keys](https://www.w3.org/TR/uievents-key/#named-key-attribute-values) vs printable characters.
|
|
397
|
+
* For this check we assume that any `key` value that is a single Grapheme is a printable
|
|
398
|
+
* characters. This way we can ensure that combining characters and emojis are correctly recognized
|
|
399
|
+
* without need to keep a list of all named key.
|
|
393
400
|
*/
|
|
394
401
|
var isPrintableCharacter = (key) => [...GRAPHEME_SEGMENTER.segment(key)].length === 1;
|
|
395
402
|
//#endregion
|
|
@@ -415,8 +422,8 @@ var addGlobalListener = (type, listener) => {
|
|
|
415
422
|
document.addEventListener(type, GLOBAL_HANDLER);
|
|
416
423
|
};
|
|
417
424
|
/**
|
|
418
|
-
* A single and unique function for all event types.
|
|
419
|
-
*
|
|
425
|
+
* A single and unique function for all event types. We use the fact that `addEventListener` and
|
|
426
|
+
* `removeEventListener` are idempotent when called with the same function reference.
|
|
420
427
|
*/
|
|
421
428
|
var GLOBAL_HANDLER = (event) => {
|
|
422
429
|
const type = event.type;
|
|
@@ -517,21 +524,24 @@ var debounce = (handler, timeout) => {
|
|
|
517
524
|
clearTimeout(timer);
|
|
518
525
|
timer = setTimeout(() => handler(...lastArgs), toValue(timeout));
|
|
519
526
|
};
|
|
520
|
-
/**
|
|
527
|
+
/**
|
|
528
|
+
* Abort the currently debounced action, if any.
|
|
529
|
+
*/
|
|
521
530
|
func.abort = () => clearTimeout(timer);
|
|
522
531
|
return func;
|
|
523
532
|
};
|
|
524
533
|
//#endregion
|
|
525
534
|
//#region src/composables/helpers/useTypeAhead.ts
|
|
526
535
|
/**
|
|
527
|
-
* Enhances typeAhead to combine multiple inputs in quick succession and filter out non-printable
|
|
536
|
+
* Enhances typeAhead to combine multiple inputs in quick succession and filter out non-printable
|
|
537
|
+
* characters.
|
|
528
538
|
*
|
|
529
539
|
* @example
|
|
530
|
-
*
|
|
531
|
-
*
|
|
532
|
-
*
|
|
533
|
-
*
|
|
534
|
-
*
|
|
540
|
+
* ```ts
|
|
541
|
+
* const typeAhead = useTypeAhead((inputString) => console.log("Typed string:", inputString));
|
|
542
|
+
* // ...
|
|
543
|
+
* addEventListener("keydown", typeAhead);
|
|
544
|
+
* ```;
|
|
535
545
|
*/
|
|
536
546
|
var useTypeAhead = (callback, timeout = 500) => {
|
|
537
547
|
let inputString = "";
|
|
@@ -546,8 +556,8 @@ var useTypeAhead = (callback, timeout = 500) => {
|
|
|
546
556
|
//#endregion
|
|
547
557
|
//#region src/composables/listbox/createListbox.ts
|
|
548
558
|
/**
|
|
549
|
-
* Composable for creating a accessibility-conform listbox.
|
|
550
|
-
*
|
|
559
|
+
* Composable for creating a accessibility-conform listbox. For supported keyboard shortcuts, see:
|
|
560
|
+
* https://www.w3.org/WAI/ARIA/apg/patterns/listbox/examples/listbox-scrollable/
|
|
551
561
|
*/
|
|
552
562
|
var createListbox = createBuilder((options) => {
|
|
553
563
|
const isMultiselect = computed(() => unref(options.multiple) ?? false);
|
|
@@ -682,7 +692,7 @@ var CLOSING_KEYS = [
|
|
|
682
692
|
];
|
|
683
693
|
var SELECTING_KEYS = ["Enter"];
|
|
684
694
|
/**
|
|
685
|
-
*
|
|
695
|
+
* If the a search input is included, space should not be used to select
|
|
686
696
|
* TODO: idea for the future: move this distinction to the listbox?
|
|
687
697
|
*/
|
|
688
698
|
var isSelectingKey = (event, withSpace) => {
|
|
@@ -781,8 +791,9 @@ var createComboBox = createBuilder(({ autocomplete: autocompleteRef, onAutocompl
|
|
|
781
791
|
onMousedown: (e) => e.preventDefault()
|
|
782
792
|
})),
|
|
783
793
|
/**
|
|
784
|
-
* An input that controls another element, that can dynamically pop-up to help the user set
|
|
785
|
-
* The input MAY be either a single-line text field that supports
|
|
794
|
+
* An input that controls another element, that can dynamically pop-up to help the user set
|
|
795
|
+
* the value of the input. The input MAY be either a single-line text field that supports
|
|
796
|
+
* editing and typing or an element that only displays the current value of the combobox.
|
|
786
797
|
*/
|
|
787
798
|
input: computed(() => ({
|
|
788
799
|
role: "combobox",
|
|
@@ -815,8 +826,9 @@ var createComboBox = createBuilder(({ autocomplete: autocompleteRef, onAutocompl
|
|
|
815
826
|
* Execute a callback, when all added promise are settled (either resolved or rejected).
|
|
816
827
|
* It allows for more promises to be added while waiting.
|
|
817
828
|
*
|
|
818
|
-
* @param cb
|
|
819
|
-
* @returns
|
|
829
|
+
* @param cb Callback to execute when all added promise are settled.
|
|
830
|
+
* @returns An object with an add function and the active state which is true as long as any promise
|
|
831
|
+
* is running.
|
|
820
832
|
*/
|
|
821
833
|
var useAllSettled = (cb) => {
|
|
822
834
|
const active = ref(false);
|
|
@@ -842,11 +854,13 @@ var useAllSettled = (cb) => {
|
|
|
842
854
|
//#endregion
|
|
843
855
|
//#region src/composables/helpers/useLastSettled.ts
|
|
844
856
|
/**
|
|
845
|
-
* Execute a callback, when the latest promise is settled (either resolved or rejected).
|
|
846
|
-
*
|
|
857
|
+
* Execute a callback, when the latest promise is settled (either resolved or rejected). This
|
|
858
|
+
* ensures that out-of-order settling promises are ignored and only the latest promise is
|
|
859
|
+
* considered.
|
|
847
860
|
*
|
|
848
|
-
* @param cb
|
|
849
|
-
* @returns
|
|
861
|
+
* @param cb Callback to execute when the last promise, that was added to the queue, is settled.
|
|
862
|
+
* @returns The active state of the last settled promise and a queue function to add new promises to
|
|
863
|
+
* the queue.
|
|
850
864
|
*/
|
|
851
865
|
var useLastSettled = (cb) => {
|
|
852
866
|
const active = ref(false);
|
|
@@ -914,7 +928,8 @@ var createDataGrid = createBuilder((options) => {
|
|
|
914
928
|
const selectedCell = options.selectedCell || ref();
|
|
915
929
|
const selectedCellEl = createElRef();
|
|
916
930
|
/**
|
|
917
|
-
* Tracks if the latest `resolveCell` promise is finished, if successful the focus can be moved
|
|
931
|
+
* Tracks if the latest `resolveCell` promise is finished, if successful the focus can be moved
|
|
932
|
+
* to the resolved cell.
|
|
918
933
|
*/
|
|
919
934
|
const focusQueue = useLastSettled((success, cell) => {
|
|
920
935
|
if (success) cell?.focus();
|
|
@@ -956,7 +971,7 @@ var createDataGrid = createBuilder((options) => {
|
|
|
956
971
|
mutationObserver?.disconnect();
|
|
957
972
|
});
|
|
958
973
|
/**
|
|
959
|
-
*
|
|
974
|
+
* When a cell is focused programmatically or by click, it becomes the currently selected cell.
|
|
960
975
|
*/
|
|
961
976
|
const onFocusin = (event) => {
|
|
962
977
|
setSelected(event.target);
|
|
@@ -1036,9 +1051,10 @@ var createDataGrid = createBuilder((options) => {
|
|
|
1036
1051
|
},
|
|
1037
1052
|
state: {
|
|
1038
1053
|
/**
|
|
1039
|
-
* Indicates that the data grid expects a content change soon, e.g. because more or other
|
|
1040
|
-
* If `loading` is passed in via the options, this will mirror its value.
|
|
1041
|
-
* Otherwise it will be dynamically set based on the running state of the `requestLazyLoad`
|
|
1054
|
+
* Indicates that the data grid expects a content change soon, e.g. because more or other
|
|
1055
|
+
* data is loaded. If `loading` is passed in via the options, this will mirror its value.
|
|
1056
|
+
* Otherwise it will be dynamically set based on the running state of the `requestLazyLoad`
|
|
1057
|
+
* promises.
|
|
1042
1058
|
*/
|
|
1043
1059
|
busy },
|
|
1044
1060
|
internals: {}
|
|
@@ -1297,15 +1313,15 @@ var MathUtils = {
|
|
|
1297
1313
|
clamp: (number, min, max) => Math.max(Math.min(number, max), min),
|
|
1298
1314
|
/**
|
|
1299
1315
|
* Returns the count of decimal places in a number.
|
|
1316
|
+
*
|
|
1300
1317
|
* @param number - The number to check.
|
|
1301
1318
|
* @returns The count of decimal places.
|
|
1302
|
-
*
|
|
1303
1319
|
* decimals(1.23); // 2
|
|
1304
1320
|
* decimals(10); // 0
|
|
1305
1321
|
*/
|
|
1306
1322
|
decimalsCount: (number) => String(number).split(".")[1]?.length ?? 0,
|
|
1307
1323
|
/**
|
|
1308
|
-
*
|
|
1324
|
+
* Converts a value within a range to a percentage (0-100).
|
|
1309
1325
|
*
|
|
1310
1326
|
* @param value - The value to convert.
|
|
1311
1327
|
* @param min - The minimum allowed value.
|
|
@@ -1361,7 +1377,7 @@ var createNavigationMenu = createBuilder(({ navigationName }) => {
|
|
|
1361
1377
|
var areArraysEqual = (arrayA, arrayB, comparer = (a, b) => a === b) => arrayA.length === arrayB.length && arrayA.every((value, index) => comparer(value, arrayB[index]));
|
|
1362
1378
|
//#endregion
|
|
1363
1379
|
//#region src/composables/slider/createSlider.ts
|
|
1364
|
-
var NAVIGATION_KEYS = new Set([
|
|
1380
|
+
var NAVIGATION_KEYS = /* @__PURE__ */ new Set([
|
|
1365
1381
|
"ArrowUp",
|
|
1366
1382
|
"ArrowDown",
|
|
1367
1383
|
"ArrowLeft",
|
|
@@ -1371,12 +1387,12 @@ var NAVIGATION_KEYS = new Set([
|
|
|
1371
1387
|
"Home",
|
|
1372
1388
|
"End"
|
|
1373
1389
|
]);
|
|
1374
|
-
var INCREMENT_KEYS = new Set([
|
|
1390
|
+
var INCREMENT_KEYS = /* @__PURE__ */ new Set([
|
|
1375
1391
|
"ArrowRight",
|
|
1376
1392
|
"ArrowUp",
|
|
1377
1393
|
"PageUp"
|
|
1378
1394
|
]);
|
|
1379
|
-
var DECREMENT_KEYS = new Set([
|
|
1395
|
+
var DECREMENT_KEYS = /* @__PURE__ */ new Set([
|
|
1380
1396
|
"ArrowLeft",
|
|
1381
1397
|
"ArrowDown",
|
|
1382
1398
|
"PageDown"
|
|
@@ -1695,8 +1711,9 @@ button: computed(() => ({
|
|
|
1695
1711
|
//#endregion
|
|
1696
1712
|
//#region src/composables/helpers/useDismissible.ts
|
|
1697
1713
|
/**
|
|
1698
|
-
* Composable that sets `isExpanded` to false, when the `Escape` key is pressed.
|
|
1699
|
-
*
|
|
1714
|
+
* Composable that sets `isExpanded` to false, when the `Escape` key is pressed. Addresses the
|
|
1715
|
+
* "dismissible" aspect of
|
|
1716
|
+
* https://www.w3.org/WAI/WCAG21/Understanding/content-on-hover-or-focus.html
|
|
1700
1717
|
*/
|
|
1701
1718
|
var useDismissible = ({ isExpanded }) => useGlobalEventListener({
|
|
1702
1719
|
type: "keydown",
|
|
@@ -1736,7 +1753,8 @@ var createToggletip = createBuilder(({ toggleLabel, isVisible }) => {
|
|
|
1736
1753
|
*/
|
|
1737
1754
|
tooltip: {
|
|
1738
1755
|
onToggle: (e) => {
|
|
1739
|
-
|
|
1756
|
+
const tooltip = e.target;
|
|
1757
|
+
_isVisible.value = tooltip.matches(":popover-open");
|
|
1740
1758
|
},
|
|
1741
1759
|
anchor: triggerId,
|
|
1742
1760
|
popover: "auto",
|
|
@@ -1750,10 +1768,11 @@ var createToggletip = createBuilder(({ toggleLabel, isVisible }) => {
|
|
|
1750
1768
|
//#endregion
|
|
1751
1769
|
//#region src/composables/tooltip/createTooltip.ts
|
|
1752
1770
|
/**
|
|
1753
|
-
* Create a tooltip as described in
|
|
1754
|
-
* Its visibility
|
|
1755
|
-
* A tooltip MUST be used to describe the associated trigger element.
|
|
1756
|
-
* To provide contextual information use the
|
|
1771
|
+
* Create a tooltip as described in
|
|
1772
|
+
* https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tooltip_role Its visibility
|
|
1773
|
+
* is toggled on hover or focus. A tooltip MUST be used to describe the associated trigger element.
|
|
1774
|
+
* E.g. The usage with the ⓘ would be incorrect. To provide contextual information use the
|
|
1775
|
+
* `createToggletip`.
|
|
1757
1776
|
*/
|
|
1758
1777
|
var createTooltip = createBuilder(({ debounce, isVisible }) => {
|
|
1759
1778
|
const tooltipId = useId();
|
|
@@ -1907,4 +1926,46 @@ var createTreeViewItem = createBuilder((options) => {
|
|
|
1907
1926
|
})) } };
|
|
1908
1927
|
});
|
|
1909
1928
|
//#endregion
|
|
1910
|
-
|
|
1929
|
+
//#region src/composables/dragAndDrop/createDragAndDrop.ts
|
|
1930
|
+
/**
|
|
1931
|
+
* Composable for creating drag and drop functionality.
|
|
1932
|
+
*/
|
|
1933
|
+
var createDragAndDrop = createBuilder((options) => {
|
|
1934
|
+
let isDragoverAnimationFrameTicking = false;
|
|
1935
|
+
const onDragover = (event) => {
|
|
1936
|
+
event.preventDefault();
|
|
1937
|
+
if (!isDragoverAnimationFrameTicking) {
|
|
1938
|
+
requestAnimationFrame(() => {
|
|
1939
|
+
options.onDragover?.(event);
|
|
1940
|
+
isDragoverAnimationFrameTicking = false;
|
|
1941
|
+
});
|
|
1942
|
+
isDragoverAnimationFrameTicking = true;
|
|
1943
|
+
}
|
|
1944
|
+
};
|
|
1945
|
+
const onDrop = (event) => {
|
|
1946
|
+
event.preventDefault();
|
|
1947
|
+
options.onDrop?.(event);
|
|
1948
|
+
};
|
|
1949
|
+
const onDragstart = (event, item) => options.onDragstart?.(event, item);
|
|
1950
|
+
const onDragend = (event, item) => options.onDragend?.(event, item);
|
|
1951
|
+
return { elements: {
|
|
1952
|
+
/**
|
|
1953
|
+
* Drop target where draggable elements are allowed to be dropped.
|
|
1954
|
+
* drop).
|
|
1955
|
+
*/
|
|
1956
|
+
target: {
|
|
1957
|
+
onDragover,
|
|
1958
|
+
onDrop
|
|
1959
|
+
},
|
|
1960
|
+
/**
|
|
1961
|
+
* Drag and drop trigger / handle (e.g. an icon) that starts the drag.
|
|
1962
|
+
*/
|
|
1963
|
+
trigger: ({ item }) => ({
|
|
1964
|
+
draggable: true,
|
|
1965
|
+
onDragstart: (event) => onDragstart(event, item),
|
|
1966
|
+
onDragend: (event) => onDragend(event, item)
|
|
1967
|
+
})
|
|
1968
|
+
} };
|
|
1969
|
+
});
|
|
1970
|
+
//#endregion
|
|
1971
|
+
export { CLOSING_KEYS, OPENING_KEYS, createBuilder, createCalendar, createComboBox, createDataGrid, createDragAndDrop, createElRef, createListbox, createMenuButton, createMenuItems, createNavigationMenu, createSlider, createTabs, createToggleButton, createToggletip, createTooltip, createTreeView, createTreeViewItem, debounce, getNativeElement, isPrintableCharacter, useGlobalEventListener, useOutsideClick, wasKeyPressed };
|
package/dist/playwright.js
CHANGED
|
@@ -51,7 +51,8 @@ var openCombobox = async (combobox, listbox) => {
|
|
|
51
51
|
};
|
|
52
52
|
var expectToBeSelected = async (selectedItem) => expect(selectedItem, "Option should be selected").toHaveAttribute("aria-selected", "true");
|
|
53
53
|
/**
|
|
54
|
-
* Test an implementation of the combobox based on
|
|
54
|
+
* Test an implementation of the combobox based on
|
|
55
|
+
* https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-select-only/
|
|
55
56
|
*/
|
|
56
57
|
var comboboxSelectOnlyTesting = async (page, listbox, combobox, isActive) => {
|
|
57
58
|
await expect(listbox, "Initial state of a combobox is collapsed.").toBeHidden();
|
|
@@ -87,8 +88,9 @@ var comboboxSelectOnlyTesting = async (page, listbox, combobox, isActive) => {
|
|
|
87
88
|
//#endregion
|
|
88
89
|
//#region src/composables/listbox/createListbox.testing.ts
|
|
89
90
|
/**
|
|
90
|
-
* Playwright utility for executing accessibility testing for a listbox.
|
|
91
|
-
*
|
|
91
|
+
* Playwright utility for executing accessibility testing for a listbox. Will check aria attributes
|
|
92
|
+
* and keyboard shortcuts as defined in
|
|
93
|
+
* https://www.w3.org/WAI/ARIA/apg/patterns/listbox/examples/listbox-scrollable.
|
|
92
94
|
*/
|
|
93
95
|
var listboxTesting = async ({ page, listbox, options, isOptionActive }) => {
|
|
94
96
|
const expectOptionToBeActive = async (locator, message) => {
|
|
@@ -141,8 +143,9 @@ var listboxTesting = async ({ page, listbox, options, isOptionActive }) => {
|
|
|
141
143
|
//#endregion
|
|
142
144
|
//#region src/composables/menuButton/createMenuButton.testing.ts
|
|
143
145
|
/**
|
|
144
|
-
* Playwright utility for executing accessibility testing for a navigation menu.
|
|
145
|
-
*
|
|
146
|
+
* Playwright utility for executing accessibility testing for a navigation menu. Will check aria
|
|
147
|
+
* attributes and keyboard shortcuts as defined in
|
|
148
|
+
* https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/examples/menu-button-links.
|
|
146
149
|
*/
|
|
147
150
|
var menuButtonTesting = async ({ page, button, menu, menuItems }) => {
|
|
148
151
|
await expect(button, "navigation menu should have an \"aria-haspopup\" attribute set to true").toHaveAttribute("aria-haspopup", "true");
|
|
@@ -176,8 +179,9 @@ var menuButtonTesting = async ({ page, button, menu, menuItems }) => {
|
|
|
176
179
|
//#endregion
|
|
177
180
|
//#region src/composables/navigationMenu/createMenu.testing.ts
|
|
178
181
|
/**
|
|
179
|
-
* Playwright utility for executing accessibility testing for a navigation menu.
|
|
180
|
-
*
|
|
182
|
+
* Playwright utility for executing accessibility testing for a navigation menu. Will check aria
|
|
183
|
+
* attributes and keyboard shortcuts as defined in
|
|
184
|
+
* https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/examples/disclosure-navigation/
|
|
181
185
|
*/
|
|
182
186
|
var navigationTesting = async ({ nav, buttons }) => {
|
|
183
187
|
/**
|
|
@@ -352,8 +356,8 @@ var rangeSliderTesting = async ({ page, slider, rail }) => {
|
|
|
352
356
|
//#endregion
|
|
353
357
|
//#region src/composables/tabs/createTabs.testing.ts
|
|
354
358
|
/**
|
|
355
|
-
* Playwright utility for executing accessibility testing for tabs.
|
|
356
|
-
*
|
|
359
|
+
* Playwright utility for executing accessibility testing for tabs. Will check aria attributes and
|
|
360
|
+
* keyboard shortcuts as defined in https://www.w3.org/WAI/ARIA/apg/patterns/tabs/
|
|
357
361
|
*/
|
|
358
362
|
var tabsTesting = async (options) => {
|
|
359
363
|
await expect(options.tablist, "tablist element must have role \"tablist\"").toHaveRole("tablist");
|
|
@@ -438,8 +442,9 @@ var expectPanelAttributes = async (panel, tabId) => {
|
|
|
438
442
|
//#endregion
|
|
439
443
|
//#region src/composables/toggleButton/createToggleButton.testing.ts
|
|
440
444
|
/**
|
|
441
|
-
* Playwright utility for executing accessibility testing for a navigation menu.
|
|
442
|
-
*
|
|
445
|
+
* Playwright utility for executing accessibility testing for a navigation menu. Will check aria
|
|
446
|
+
* attributes and keyboard shortcuts as defined in
|
|
447
|
+
* https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/examples/menu-button-links.
|
|
443
448
|
*/
|
|
444
449
|
var toggleButtonTesting = async ({ button, labelText, initiallyPressed }) => {
|
|
445
450
|
await expect(button, `button must have 'aria-pressed' attribute to be recognized as toggle button.`).toHaveAttribute("aria-pressed", String(initiallyPressed));
|
package/dist/utils/builder.d.ts
CHANGED
|
@@ -21,39 +21,39 @@ export type HeadlessComposable<Elements extends HeadlessElements, State extends
|
|
|
21
21
|
} & IfDefined<"internals", Internals> & IfDefined<"state", State>;
|
|
22
22
|
/**
|
|
23
23
|
* We use this identity function to ensure the correct typings of the headless composables
|
|
24
|
+
*
|
|
24
25
|
* @example
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
26
|
+
* ```ts
|
|
27
|
+
* export const createTooltip = createBuilder(({ initialVisible }: CreateTooltipOptions) => {
|
|
28
|
+
* const tooltipId = useId();
|
|
29
|
+
* const isVisible = ref(initialVisible);
|
|
29
30
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
31
|
+
* const hoverEvents = {
|
|
32
|
+
* onMouseover: () => (isVisible.value = true),
|
|
33
|
+
* onMouseout: () => (isVisible.value = false),
|
|
34
|
+
* onFocusin: () => (isVisible.value = true),
|
|
35
|
+
* onFocusout: () => (isVisible.value = false),
|
|
36
|
+
* };
|
|
36
37
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
38
|
+
* return {
|
|
39
|
+
* elements: {
|
|
40
|
+
* trigger: {
|
|
41
|
+
* "aria-describedby": tooltipId,
|
|
42
|
+
* ...hoverEvents,
|
|
43
|
+
* },
|
|
44
|
+
* tooltip: {
|
|
45
|
+
* role: "tooltip",
|
|
46
|
+
* id: tooltipId,
|
|
47
|
+
* tabindex: "-1",
|
|
48
|
+
* ...hoverEvents,
|
|
49
|
+
* },
|
|
42
50
|
* },
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* id: tooltipId,
|
|
46
|
-
* tabindex: "-1",
|
|
47
|
-
* ...hoverEvents,
|
|
51
|
+
* state: {
|
|
52
|
+
* isVisible,
|
|
48
53
|
* },
|
|
49
|
-
* }
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* },
|
|
53
|
-
* };
|
|
54
|
-
* });
|
|
55
|
-
*
|
|
56
|
-
* ```
|
|
54
|
+
* };
|
|
55
|
+
* });
|
|
56
|
+
* ```;
|
|
57
57
|
*/
|
|
58
58
|
export declare const createBuilder: <Args extends unknown[] = unknown[], Elements extends HeadlessElements = HeadlessElements, State extends HeadlessState | undefined = undefined, Internals extends object | undefined = undefined>(builder: (...args: Args) => HeadlessComposable<Elements, State, Internals>) => (...args: Args) => HeadlessComposable<Elements, State, Internals>;
|
|
59
59
|
export type VueTemplateRefElement<E extends Element> = E | {
|
|
@@ -63,7 +63,7 @@ type VueTemplateRef<E extends Element> = Ref<VueTemplateRefElement<E>>;
|
|
|
63
63
|
export declare const HeadlessElRefSymbol: unique symbol;
|
|
64
64
|
export type HeadlessElRef<E extends Element | null> = WritableComputedRef<E | null> & {
|
|
65
65
|
/**
|
|
66
|
-
*
|
|
66
|
+
* Type differentiator
|
|
67
67
|
* ensures that only `createElRef` can be used for headless element ref bindings
|
|
68
68
|
*/
|
|
69
69
|
[HeadlessElRefSymbol]: true;
|
|
@@ -71,19 +71,20 @@ export type HeadlessElRef<E extends Element | null> = WritableComputedRef<E | nu
|
|
|
71
71
|
/**
|
|
72
72
|
* Creates a special writeable computed that references a DOM Element.
|
|
73
73
|
* Vue Component references will be unwrapped.
|
|
74
|
+
*
|
|
74
75
|
* @example
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
76
|
+
* ```ts
|
|
77
|
+
* createBuilder() => {
|
|
78
|
+
* const buttonRef = createElRef<HtmlButtonElement>();
|
|
79
|
+
* return {
|
|
80
|
+
* elements: {
|
|
81
|
+
* button: {
|
|
82
|
+
* ref: buttonRef,
|
|
83
|
+
* },
|
|
84
|
+
* }
|
|
85
|
+
* };
|
|
86
|
+
* });
|
|
87
|
+
* ```;
|
|
87
88
|
*/
|
|
88
89
|
export declare function createElRef<E extends Element>(): WritableComputedRef<E | null, E | null>;
|
|
89
90
|
export declare const getNativeElement: <E extends Element>(element?: VueTemplateRefElement<E>) => E | null;
|
package/dist/utils/keyboard.d.ts
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
export type PressedKey = string | Partial<Pick<KeyboardEvent, "altKey" | "key" | "ctrlKey" | "metaKey" | "shiftKey" | "code">>;
|
|
2
2
|
/**
|
|
3
3
|
* Check if a specified key was pressed.
|
|
4
|
+
*
|
|
4
5
|
* @param event The KeyboardEvent
|
|
5
|
-
* @param key The key, either the [key
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* @param key The key, either the [key
|
|
7
|
+
* property](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) as a string (e.g.
|
|
8
|
+
* "m") or an object with the relevant key parameters, e.g. `{ key: "m", altKey: true }`
|
|
9
|
+
* @returns True, if the key was pressed with the specified parameters
|
|
8
10
|
*/
|
|
9
11
|
export declare const wasKeyPressed: (event: KeyboardEvent, key: PressedKey) => boolean;
|
|
10
12
|
/**
|
|
11
13
|
* Check if the `key` property of a KeyboardEvent is a printable character.
|
|
12
14
|
*
|
|
13
|
-
* There is no standardized or specified algorithm to check for [named
|
|
14
|
-
*
|
|
15
|
-
*
|
|
15
|
+
* There is no standardized or specified algorithm to check for [named
|
|
16
|
+
* keys](https://www.w3.org/TR/uievents-key/#named-key-attribute-values) vs printable characters.
|
|
17
|
+
* For this check we assume that any `key` value that is a single Grapheme is a printable
|
|
18
|
+
* characters. This way we can ensure that combining characters and emojis are correctly recognized
|
|
19
|
+
* without need to keep a list of all named key.
|
|
16
20
|
*/
|
|
17
21
|
export declare const isPrintableCharacter: (key: string) => boolean;
|
package/dist/utils/math.d.ts
CHANGED
|
@@ -5,15 +5,15 @@ export declare const MathUtils: {
|
|
|
5
5
|
clamp: (number: number, min: number, max: number) => number;
|
|
6
6
|
/**
|
|
7
7
|
* Returns the count of decimal places in a number.
|
|
8
|
+
*
|
|
8
9
|
* @param number - The number to check.
|
|
9
10
|
* @returns The count of decimal places.
|
|
10
|
-
*
|
|
11
11
|
* decimals(1.23); // 2
|
|
12
12
|
* decimals(10); // 0
|
|
13
13
|
*/
|
|
14
14
|
decimalsCount: (number: number) => number;
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
16
|
+
* Converts a value within a range to a percentage (0-100).
|
|
17
17
|
*
|
|
18
18
|
* @param value - The value to convert.
|
|
19
19
|
* @param min - The minimum allowed value.
|
package/dist/utils/object.d.ts
CHANGED
package/dist/utils/types.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Adds the entry with the key `Key` and the value of type `TValue` to a record when it is defined.
|
|
3
3
|
* Then the entry is either undefined or exists without being optional.
|
|
4
|
+
*
|
|
4
5
|
* @example
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* const _no_error: IfDefined<"b", number> & { a: number } = { a: 1, b: 2 };
|
|
8
|
+
* // Error: Object literal may only specify known properties, and 'b' does not exist in type '{ a: number; }'.
|
|
9
|
+
* const _error: IfDefined<"b", undefined> & { a: number } = { a: 1, b: 2 };
|
|
10
|
+
* ```;
|
|
10
11
|
*/
|
|
11
12
|
export type IfDefined<Key extends string, TValue> = TValue extends NonNullable<unknown> ? {
|
|
12
13
|
[key in Key]: TValue;
|
package/dist/utils/vitest.d.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* `onBeforeMount` and `onMounted` callbacks are executed immediately.
|
|
9
9
|
* `onBeforeUnmount` and `onUnmounted` are executed when the returned callback is run.
|
|
10
|
-
*
|
|
10
|
+
*
|
|
11
|
+
* @returns A callback to trigger the run of `onBeforeUnmount` and `onUnmounted`
|
|
11
12
|
*/
|
|
12
13
|
export declare const mockVueLifecycle: () => () => Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sit-onyx/headless",
|
|
3
|
+
"version": "0.12.0-dev-20260730150439",
|
|
3
4
|
"description": "Headless composables for Vue",
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
5
|
+
"homepage": "https://onyx.schwarz/development/packages/headless.html",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/SchwarzIT/onyx/issues"
|
|
8
|
+
},
|
|
7
9
|
"license": "Apache-2.0",
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
+
"author": "Schwarz Digits IT KG",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/SchwarzIT/onyx",
|
|
14
|
+
"directory": "packages/headless"
|
|
10
15
|
},
|
|
11
16
|
"files": [
|
|
12
17
|
"dist"
|
|
13
18
|
],
|
|
19
|
+
"type": "module",
|
|
14
20
|
"types": "./dist/index.d.ts",
|
|
15
21
|
"exports": {
|
|
16
22
|
".": {
|
|
@@ -22,27 +28,21 @@
|
|
|
22
28
|
"default": "./dist/playwright.js"
|
|
23
29
|
}
|
|
24
30
|
},
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
"bugs": {
|
|
32
|
-
"url": "https://github.com/SchwarzIT/onyx/issues"
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@vue/compiler-dom": "3.5.40",
|
|
33
|
+
"unplugin-dts": "1.0.3",
|
|
34
|
+
"vite": "8.1.5",
|
|
35
|
+
"vue": "3.5.40",
|
|
36
|
+
"@sit-onyx/shared": "^0.1.0"
|
|
33
37
|
},
|
|
34
38
|
"peerDependencies": {
|
|
35
|
-
"@playwright/experimental-ct-vue": "1.61.
|
|
36
|
-
"@playwright/test": "1.61.
|
|
39
|
+
"@playwright/experimental-ct-vue": "1.61.1",
|
|
40
|
+
"@playwright/test": "1.61.1",
|
|
37
41
|
"typescript": ">= 5",
|
|
38
42
|
"vue": ">= 3.5.0"
|
|
39
43
|
},
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"unplugin-dts": "1.0.2",
|
|
43
|
-
"vite": "8.0.16",
|
|
44
|
-
"vue": "3.5.38",
|
|
45
|
-
"@sit-onyx/shared": "^0.1.0"
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=20"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
48
|
"build": "vite build",
|