@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 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.6",
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 = createId("comboBox-control");
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, createId("listbox-option"));
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
- document.getElementById(id)?.scrollIntoView({ block: "nearest", inline: "nearest" });
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 = createId("menu-button-root");
18
- const menuId = createId("menu-button-list");
16
+ const rootId = useId();
17
+ const menuId = useId();
19
18
  const menuRef = createElRef<HTMLElement>();
20
- const buttonId = createId("menu-button-button");
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 (document.getElementById(rootId)?.contains(event.relatedTarget as HTMLElement)) {
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 = createId("nav");
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 = createId("tooltip");
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";
@@ -50,7 +50,7 @@ export type HeadlessComposable<
50
50
  * @example
51
51
  * ```ts
52
52
  * export const createTooltip = createBuilder(({ initialVisible }: CreateTooltipOptions) => {
53
- * const tooltipId = createId("tooltip");
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()}`;