@sit-onyx/headless 1.0.0-beta.6 → 1.0.0-beta.8
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/package.json +6 -2
- package/src/composables/comboBox/createComboBox.ts +2 -3
- package/src/composables/listbox/createListbox.ts +7 -5
- package/src/composables/menuButton/createMenuButton.ts +8 -6
- package/src/composables/navigationMenu/createMenu.ts +3 -4
- package/src/composables/tooltip/createTooltip.ts +2 -3
- package/src/index.ts +0 -1
- package/src/utils/builder.ts +1 -1
- package/src/utils/id.ts +0 -14
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sit-onyx/headless",
|
|
3
3
|
"description": "Headless composables for Vue",
|
|
4
|
-
"version": "1.0.0-beta.
|
|
4
|
+
"version": "1.0.0-beta.8",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Schwarz IT KG",
|
|
7
7
|
"license": "Apache-2.0",
|
|
@@ -24,7 +24,11 @@
|
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"typescript": ">= 5",
|
|
27
|
-
"vue": ">= 3"
|
|
27
|
+
"vue": ">= 3.5.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@vue/compiler-dom": "^3.5.0",
|
|
31
|
+
"vue": "^3.5.0"
|
|
28
32
|
},
|
|
29
33
|
"scripts": {
|
|
30
34
|
"build": "vue-tsc --build --force",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { computed, unref, type MaybeRef, type Ref } from "vue";
|
|
1
|
+
import { computed, unref, useId, type MaybeRef, type Ref } from "vue";
|
|
2
2
|
import { createBuilder } from "../../utils/builder";
|
|
3
|
-
import { createId } from "../../utils/id";
|
|
4
3
|
import { isPrintableCharacter, wasKeyPressed, type PressedKey } from "../../utils/keyboard";
|
|
5
4
|
import { useOutsideClick } from "../helpers/useOutsideClick";
|
|
6
5
|
import { useTypeAhead } from "../helpers/useTypeAhead";
|
|
@@ -127,7 +126,7 @@ export const createComboBox = createBuilder(
|
|
|
127
126
|
onActivatePrevious,
|
|
128
127
|
templateRef,
|
|
129
128
|
}: CreateComboboxOptions<TValue, TAutoComplete, TMultiple>) => {
|
|
130
|
-
const controlsId =
|
|
129
|
+
const controlsId = useId();
|
|
131
130
|
|
|
132
131
|
const autocomplete = computed(() => unref(autocompleteRef));
|
|
133
132
|
const isExpanded = computed(() => unref(isExpandedRef));
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { computed, ref, unref, watchEffect, type MaybeRef, type Ref } from "vue";
|
|
2
|
-
import { createId } from "../..";
|
|
1
|
+
import { computed, nextTick, ref, unref, useId, watchEffect, type MaybeRef, type Ref } from "vue";
|
|
3
2
|
import { createBuilder, type VBindAttributes } from "../../utils/builder";
|
|
4
3
|
import { useTypeAhead } from "../helpers/useTypeAhead";
|
|
5
4
|
|
|
@@ -94,7 +93,7 @@ export const createListbox = createBuilder(
|
|
|
94
93
|
|
|
95
94
|
const getOptionId = (value: TValue) => {
|
|
96
95
|
if (!descendantKeyIdMap.has(value)) {
|
|
97
|
-
descendantKeyIdMap.set(value,
|
|
96
|
+
descendantKeyIdMap.set(value, useId() ?? value.toString());
|
|
98
97
|
}
|
|
99
98
|
return descendantKeyIdMap.get(value)!;
|
|
100
99
|
};
|
|
@@ -105,7 +104,7 @@ export const createListbox = createBuilder(
|
|
|
105
104
|
const isFocused = ref(false);
|
|
106
105
|
|
|
107
106
|
// scroll currently active option into view if needed
|
|
108
|
-
watchEffect(() => {
|
|
107
|
+
watchEffect(async () => {
|
|
109
108
|
if (
|
|
110
109
|
!isExpanded.value ||
|
|
111
110
|
options.activeOption.value == undefined ||
|
|
@@ -113,7 +112,10 @@ export const createListbox = createBuilder(
|
|
|
113
112
|
)
|
|
114
113
|
return;
|
|
115
114
|
const id = getOptionId(options.activeOption.value);
|
|
116
|
-
|
|
115
|
+
|
|
116
|
+
await nextTick(() => {
|
|
117
|
+
document.getElementById(id)?.scrollIntoView({ block: "end", inline: "nearest" });
|
|
118
|
+
});
|
|
117
119
|
});
|
|
118
120
|
|
|
119
121
|
const typeAhead = useTypeAhead((inputString) => options.onTypeAhead?.(inputString));
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { computed, type Ref } from "vue";
|
|
1
|
+
import { computed, useId, type Ref } from "vue";
|
|
2
2
|
import { createBuilder, createElRef } from "../../utils/builder";
|
|
3
|
-
import { createId } from "../../utils/id";
|
|
4
3
|
import { debounce } from "../../utils/timer";
|
|
5
4
|
import { useGlobalEventListener } from "../helpers/useGlobalListener";
|
|
6
5
|
|
|
@@ -14,10 +13,10 @@ type CreateMenuButtonOptions = {
|
|
|
14
13
|
*/
|
|
15
14
|
export const createMenuButton = createBuilder(
|
|
16
15
|
({ isExpanded, onToggle }: CreateMenuButtonOptions) => {
|
|
17
|
-
const rootId =
|
|
18
|
-
const menuId =
|
|
16
|
+
const rootId = useId();
|
|
17
|
+
const menuId = useId();
|
|
19
18
|
const menuRef = createElRef<HTMLElement>();
|
|
20
|
-
const buttonId =
|
|
19
|
+
const buttonId = useId();
|
|
21
20
|
|
|
22
21
|
useGlobalEventListener({
|
|
23
22
|
type: "keydown",
|
|
@@ -106,7 +105,10 @@ export const createMenuButton = createBuilder(
|
|
|
106
105
|
onMouseout: () => updateDebouncedExpanded(false),
|
|
107
106
|
onFocusout: (event) => {
|
|
108
107
|
// if focus receiving element is not part of the menu button, then close
|
|
109
|
-
if (
|
|
108
|
+
if (
|
|
109
|
+
rootId &&
|
|
110
|
+
document.getElementById(rootId)?.contains(event.relatedTarget as HTMLElement)
|
|
111
|
+
) {
|
|
110
112
|
return;
|
|
111
113
|
}
|
|
112
114
|
isExpanded.value && onToggle();
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { unref, type MaybeRef } from "vue";
|
|
2
|
-
import { createId } from "../..";
|
|
1
|
+
import { unref, useId, type MaybeRef } from "vue";
|
|
3
2
|
import { createBuilder } from "../../utils/builder";
|
|
4
3
|
import { MathUtils } from "../../utils/math";
|
|
5
4
|
|
|
@@ -15,10 +14,10 @@ type CreateNavigationMenu = {
|
|
|
15
14
|
* Based on https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/examples/disclosure-navigation/
|
|
16
15
|
*/
|
|
17
16
|
export const createNavigationMenu = createBuilder(({ navigationName }: CreateNavigationMenu) => {
|
|
18
|
-
const navId =
|
|
17
|
+
const navId = useId();
|
|
19
18
|
|
|
20
19
|
const getMenuButtons = () => {
|
|
21
|
-
const nav = document.getElementById(navId);
|
|
20
|
+
const nav = navId ? document.getElementById(navId) : undefined;
|
|
22
21
|
if (!nav) return [];
|
|
23
22
|
return [...nav.querySelectorAll<HTMLElement>("button[aria-expanded][aria-controls]")];
|
|
24
23
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { computed, toRef, toValue, type MaybeRefOrGetter, type Ref } from "vue";
|
|
2
|
-
import { createId } from "../..";
|
|
1
|
+
import { computed, toRef, toValue, useId, type MaybeRefOrGetter, type Ref } from "vue";
|
|
3
2
|
import { createBuilder } from "../../utils/builder";
|
|
4
3
|
import { useDismissible } from "../helpers/useDismissible";
|
|
5
4
|
|
|
@@ -18,7 +17,7 @@ export type CreateTooltipOptions = {
|
|
|
18
17
|
* To provide contextual information use the `createToggletip`.
|
|
19
18
|
*/
|
|
20
19
|
export const createTooltip = createBuilder(({ debounce, isVisible }: CreateTooltipOptions) => {
|
|
21
|
-
const tooltipId =
|
|
20
|
+
const tooltipId = useId();
|
|
22
21
|
const _isVisible = toRef(isVisible ?? false);
|
|
23
22
|
let timeout: ReturnType<typeof setTimeout> | undefined;
|
|
24
23
|
|
package/src/index.ts
CHANGED
|
@@ -5,6 +5,5 @@ export * from "./composables/navigationMenu/createMenu";
|
|
|
5
5
|
export * from "./composables/tooltip/createToggletip";
|
|
6
6
|
export * from "./composables/tooltip/createTooltip";
|
|
7
7
|
export * from "./utils/builder";
|
|
8
|
-
export { createId } from "./utils/id";
|
|
9
8
|
export { isPrintableCharacter, wasKeyPressed } from "./utils/keyboard";
|
|
10
9
|
export { debounce } from "./utils/timer";
|
package/src/utils/builder.ts
CHANGED
|
@@ -50,7 +50,7 @@ export type HeadlessComposable<
|
|
|
50
50
|
* @example
|
|
51
51
|
* ```ts
|
|
52
52
|
* export const createTooltip = createBuilder(({ initialVisible }: CreateTooltipOptions) => {
|
|
53
|
-
* const tooltipId =
|
|
53
|
+
* const tooltipId = useId();
|
|
54
54
|
* const isVisible = ref(initialVisible);
|
|
55
55
|
*
|
|
56
56
|
* const hoverEvents = {
|
package/src/utils/id.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Returns a unique global id string
|
|
3
|
-
*/
|
|
4
|
-
// ⚠️ we make use of an IIFE to encapsulate the globalCounter so it can never accidentally be used somewhere else.
|
|
5
|
-
const nextId = (() => {
|
|
6
|
-
let globalCounter = 1;
|
|
7
|
-
return () => globalCounter++;
|
|
8
|
-
})();
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Creates a globally unique string using a counter.
|
|
12
|
-
* The given name is the prefix.
|
|
13
|
-
*/
|
|
14
|
-
export const createId = (name: string) => `${name}-${nextId()}`;
|