ropav 0.12.3 → 0.14.0

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.
Files changed (110) hide show
  1. package/dist/components/accordion/index.d.ts +1 -0
  2. package/dist/components/autocomplete/autocomplete-filter.js +2 -1
  3. package/dist/components/autocomplete/autocomplete-root.js +3 -1
  4. package/dist/components/autocomplete/autocomplete.context.d.ts +3 -1
  5. package/dist/components/autocomplete/index.d.ts +1 -0
  6. package/dist/components/calendar/index.d.ts +1 -0
  7. package/dist/components/checkbox-group/index.d.ts +1 -0
  8. package/dist/components/color-slider/index.d.ts +1 -0
  9. package/dist/components/combo-box/combo-box-root.js +3 -5
  10. package/dist/components/combo-box/combo-box.types.d.ts +7 -4
  11. package/dist/components/combo-box/index.d.ts +2 -0
  12. package/dist/components/date-field/index.d.ts +1 -0
  13. package/dist/components/date-picker/index.d.ts +2 -0
  14. package/dist/components/date-range-picker/index.d.ts +2 -0
  15. package/dist/components/date-range-picker/use-date-range-picker.js +1 -1
  16. package/dist/components/disclosure-group/index.d.ts +1 -0
  17. package/dist/components/dropdown/dropdown-menu.js +7 -3
  18. package/dist/components/dropdown/dropdown-root.js +1 -1
  19. package/dist/components/dropdown/dropdown-submenu-trigger.js +1 -1
  20. package/dist/components/dropdown/dropdown.context.d.ts +1 -1
  21. package/dist/components/dropdown/index.d.ts +1 -0
  22. package/dist/components/field-error/field-error-root.js +1 -1
  23. package/dist/components/form/form-root.js +1 -1
  24. package/dist/components/list-box/list-box-root.js +6 -5
  25. package/dist/components/list-box/list-box.context.d.ts +8 -0
  26. package/dist/components/number-field/index.d.ts +1 -0
  27. package/dist/components/overlay/overlay-popover.js +1 -1
  28. package/dist/components/radio-group/index.d.ts +1 -0
  29. package/dist/components/range-calendar/index.d.ts +1 -0
  30. package/dist/components/segmented-control/index.d.ts +1 -0
  31. package/dist/components/segmented-control/segmented-control.types.d.ts +1 -1
  32. package/dist/components/select/index.d.ts +1 -0
  33. package/dist/components/select/select-root.js +2 -1
  34. package/dist/components/select/select.types.d.ts +4 -1
  35. package/dist/components/slider/index.d.ts +1 -0
  36. package/dist/components/table/table-drag-handle.js +1 -1
  37. package/dist/components/tabs/index.d.ts +1 -0
  38. package/dist/components/tabs/tabs-root.js +5 -0
  39. package/dist/components/tabs/tabs.types.d.ts +8 -0
  40. package/dist/components/textfield/textfield.context.d.ts +3 -2
  41. package/dist/components/textfield/textfield.types.d.ts +3 -2
  42. package/dist/components/time-field/index.d.ts +2 -0
  43. package/dist/components/toggle-button/index.d.ts +1 -0
  44. package/dist/components/toggle-button-group/index.d.ts +1 -0
  45. package/dist/components/tooltip/index.d.ts +1 -0
  46. package/dist/composables/drag-manager.js +1 -1
  47. package/dist/composables/drag-modality.js +2 -1
  48. package/dist/composables/focus-scope-registry.d.ts +19 -0
  49. package/dist/composables/focus-scope-registry.js +38 -0
  50. package/dist/composables/form-context.d.ts +25 -0
  51. package/dist/composables/form-context.js +17 -0
  52. package/dist/composables/index.d.ts +0 -24
  53. package/dist/composables/interaction-modality.d.ts +42 -0
  54. package/dist/composables/interaction-modality.js +91 -0
  55. package/dist/composables/use-calendar-cell.js +1 -1
  56. package/dist/composables/use-checkbox-group-state.js +2 -1
  57. package/dist/composables/use-combo-box-state.d.ts +2 -1
  58. package/dist/composables/use-combo-box-state.js +3 -2
  59. package/dist/composables/use-css-variable.js +1 -5
  60. package/dist/composables/use-default-locale.d.ts +9 -0
  61. package/dist/composables/use-default-locale.js +39 -0
  62. package/dist/composables/use-dismissable.js +1 -1
  63. package/dist/composables/use-display-names.js +1 -1
  64. package/dist/composables/use-drag.js +1 -1
  65. package/dist/composables/use-droppable-collection.js +1 -1
  66. package/dist/composables/use-focus-scope.d.ts +0 -12
  67. package/dist/composables/use-focus-scope.js +4 -31
  68. package/dist/composables/use-form-validation-state.d.ts +1 -60
  69. package/dist/composables/use-form-validation-state.js +3 -134
  70. package/dist/composables/use-form-validation.d.ts +2 -1
  71. package/dist/composables/use-form-validation.js +2 -2
  72. package/dist/composables/use-interaction-states.d.ts +0 -36
  73. package/dist/composables/use-interaction-states.js +8 -91
  74. package/dist/composables/use-locale.d.ts +0 -14
  75. package/dist/composables/use-locale.js +4 -37
  76. package/dist/composables/use-localized-string-dictionary.d.ts +10 -0
  77. package/dist/composables/use-localized-string-dictionary.js +26 -0
  78. package/dist/composables/use-localized-string-formatter.d.ts +0 -9
  79. package/dist/composables/use-localized-string-formatter.js +3 -24
  80. package/dist/composables/use-long-press.d.ts +0 -2
  81. package/dist/composables/use-long-press.js +2 -2
  82. package/dist/composables/use-menu-trigger-state.d.ts +64 -0
  83. package/dist/composables/use-menu-trigger-state.js +90 -0
  84. package/dist/composables/use-menu-trigger.d.ts +2 -1
  85. package/dist/composables/use-modal-overlay.d.ts +2 -1
  86. package/dist/composables/use-modal-overlay.js +3 -2
  87. package/dist/composables/use-overlay-trigger-state.d.ts +0 -62
  88. package/dist/composables/use-overlay-trigger-state.js +2 -87
  89. package/dist/composables/use-page-size.d.ts +14 -0
  90. package/dist/composables/use-page-size.js +42 -0
  91. package/dist/composables/use-press.d.ts +0 -20
  92. package/dist/composables/use-press.js +3 -26
  93. package/dist/composables/use-range-calendar.js +1 -1
  94. package/dist/composables/use-select-state.d.ts +1 -1
  95. package/dist/composables/use-select-state.js +1 -1
  96. package/dist/composables/use-slider.js +1 -1
  97. package/dist/composables/use-toast-region.js +2 -1
  98. package/dist/composables/use-tooltip-trigger-state.js +1 -15
  99. package/dist/composables/use-tooltip-trigger.js +1 -1
  100. package/dist/composables/use-viewport-size.d.ts +0 -13
  101. package/dist/composables/use-viewport-size.js +1 -38
  102. package/dist/composables/validation-result.d.ts +37 -0
  103. package/dist/composables/validation-result.js +122 -0
  104. package/dist/composables/virtual-event.d.ts +20 -0
  105. package/dist/composables/virtual-event.js +28 -0
  106. package/dist/index.js +11 -35
  107. package/dist/ropav.min.css +1 -1
  108. package/dist/utils/date-validation.js +1 -1
  109. package/dist/version.js +1 -1
  110. package/package.json +2 -2
@@ -0,0 +1,90 @@
1
+ import { useOverlayTriggerState } from "./use-overlay-trigger-state.js";
2
+ import { computed, shallowRef, toValue } from "vue";
3
+ //#region src/composables/use-menu-trigger-state.ts
4
+ /**
5
+ * Open state for a menu trigger, ported from React Stately's `useMenuTriggerState`.
6
+ *
7
+ * Adds two things to a plain overlay trigger. A focus strategy, because how a menu was opened
8
+ * decides where focus lands: ArrowUp opens it focused on the last item, a mouse click opens it
9
+ * focused on the menu itself. And the stack of open submenus, held here on the root rather
10
+ * than in each submenu, which is what makes "only one path through the menu tree is open at a
11
+ * time" true by construction — opening a submenu at level N truncates the stack to N.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * const state = useMenuTriggerState({isOpen: () => props.isOpen});
16
+ * state.open("last"); // ArrowUp on the trigger
17
+ * ```
18
+ */
19
+ var useMenuTriggerState = (options = {}) => {
20
+ const overlay = useOverlayTriggerState(options);
21
+ const focusStrategy = shallowRef(null);
22
+ const expandedKeys = shallowRef([]);
23
+ return {
24
+ close: () => {
25
+ expandedKeys.value = [];
26
+ overlay.close();
27
+ },
28
+ closeSubmenu: (triggerKey, level) => {
29
+ if (expandedKeys.value[level] === triggerKey) expandedKeys.value = expandedKeys.value.slice(0, level);
30
+ },
31
+ expandedKeysStack: computed(() => expandedKeys.value),
32
+ focusStrategy: computed(() => focusStrategy.value),
33
+ isOpen: overlay.isOpen,
34
+ open: (strategy = null) => {
35
+ focusStrategy.value = strategy;
36
+ overlay.open();
37
+ },
38
+ openSubmenu: (triggerKey, level) => {
39
+ if (level > expandedKeys.value.length) return;
40
+ expandedKeys.value = [...expandedKeys.value.slice(0, level), triggerKey];
41
+ },
42
+ setOpen: overlay.setOpen,
43
+ toggle: (strategy = null) => {
44
+ focusStrategy.value = strategy;
45
+ overlay.toggle();
46
+ }
47
+ };
48
+ };
49
+ /**
50
+ * Open state for one submenu, ported from React Stately's `useSubmenuTriggerState`.
51
+ *
52
+ * Holds no open flag of its own — it derives one by asking the root whether its own trigger
53
+ * key is the one expanded at its level. That is what makes opening a sibling submenu close
54
+ * this one with no coordination between the two.
55
+ *
56
+ * The level is captured once, when the submenu trigger is created, and deliberately not
57
+ * recomputed: it describes where this trigger sits in the tree, which does not change, whereas
58
+ * the stack it was read from changes constantly.
59
+ */
60
+ var useSubmenuTriggerState = (options, root) => {
61
+ const submenuLevel = root.expandedKeysStack.value.length;
62
+ const focusStrategy = shallowRef(null);
63
+ const triggerKey = computed(() => toValue(options.triggerKey));
64
+ const isOpen = computed(() => triggerKey.value !== null && root.expandedKeysStack.value[submenuLevel] === triggerKey.value);
65
+ const close = () => {
66
+ focusStrategy.value = null;
67
+ if (triggerKey.value === null) return;
68
+ root.closeSubmenu(triggerKey.value, submenuLevel);
69
+ };
70
+ const open = (strategy = null) => {
71
+ focusStrategy.value = strategy;
72
+ if (triggerKey.value === null) return;
73
+ root.openSubmenu(triggerKey.value, submenuLevel);
74
+ };
75
+ return {
76
+ close,
77
+ closeAll: root.close,
78
+ focusStrategy: computed(() => focusStrategy.value),
79
+ isOpen,
80
+ open,
81
+ setOpen: (next) => next ? open() : close(),
82
+ submenuLevel,
83
+ toggle: (strategy = null) => {
84
+ if (isOpen.value) close();
85
+ else open(strategy);
86
+ }
87
+ };
88
+ };
89
+ //#endregion
90
+ export { useMenuTriggerState, useSubmenuTriggerState };
@@ -1,6 +1,7 @@
1
1
  import type { PressResponder } from "./press-responder.js";
2
+ import type { MenuTriggerState } from "./use-menu-trigger-state.js";
2
3
  import type { OverlayType } from "./use-overlay-trigger.js";
3
- import type { FocusStrategy, MenuTriggerState } from "./use-overlay-trigger-state.js";
4
+ import type { FocusStrategy } from "./use-overlay-trigger-state.js";
4
5
  import type { ComputedRef, MaybeRefOrGetter } from "vue";
5
6
  /** How the menu is opened. */
6
7
  export type MenuTriggerType = "press" | "longPress";
@@ -1,4 +1,5 @@
1
- import type { PageSize, ViewportSize } from "./use-viewport-size.js";
1
+ import type { PageSize } from "./use-page-size.js";
2
+ import type { ViewportSize } from "./use-viewport-size.js";
2
3
  import type { ComputedRef, MaybeRefOrGetter } from "vue";
3
4
  export interface UseModalOverlayOptions {
4
5
  /**
@@ -1,8 +1,9 @@
1
1
  import { ariaHideOutside } from "../utils/aria-hide-outside.js";
2
- import { useFocusScope } from "./use-focus-scope.js";
3
2
  import { useDismissable } from "./use-dismissable.js";
3
+ import { useFocusScope } from "./use-focus-scope.js";
4
+ import { usePageSize } from "./use-page-size.js";
4
5
  import { usePreventScroll } from "./use-prevent-scroll.js";
5
- import { usePageSize, useViewportSize } from "./use-viewport-size.js";
6
+ import { useViewportSize } from "./use-viewport-size.js";
6
7
  import { computed, toValue, watch } from "vue";
7
8
  //#region src/composables/use-modal-overlay.ts
8
9
  /**
@@ -1,4 +1,3 @@
1
- import type { CollectionKey } from "./use-collection.js";
2
1
  import type { ComputedRef, MaybeRefOrGetter } from "vue";
3
2
  /** Which end of a collection receives focus when an overlay opens. */
4
3
  export type FocusStrategy = "first" | "last";
@@ -26,64 +25,3 @@ export interface OverlayTriggerState {
26
25
  * ```
27
26
  */
28
27
  export declare const useOverlayTriggerState: (options?: UseOverlayTriggerStateOptions) => OverlayTriggerState;
29
- export interface MenuTriggerState extends OverlayTriggerState {
30
- /** Which item the menu focuses when it opens, or `null` to focus the menu itself. */
31
- focusStrategy: ComputedRef<FocusStrategy | null>;
32
- open: (focusStrategy?: FocusStrategy | null) => void;
33
- toggle: (focusStrategy?: FocusStrategy | null) => void;
34
- }
35
- export interface RootMenuTriggerState extends MenuTriggerState {
36
- /**
37
- * The open submenu trigger keys, one per level: index 0 is the submenu opened from the root
38
- * menu, index 1 the submenu opened from that one, and so on.
39
- */
40
- expandedKeysStack: ComputedRef<CollectionKey[]>;
41
- openSubmenu: (triggerKey: CollectionKey, level: number) => void;
42
- closeSubmenu: (triggerKey: CollectionKey, level: number) => void;
43
- }
44
- /**
45
- * Open state for a menu trigger, ported from React Stately's `useMenuTriggerState`.
46
- *
47
- * Adds two things to a plain overlay trigger. A focus strategy, because how a menu was opened
48
- * decides where focus lands: ArrowUp opens it focused on the last item, a mouse click opens it
49
- * focused on the menu itself. And the stack of open submenus, held here on the root rather
50
- * than in each submenu, which is what makes "only one path through the menu tree is open at a
51
- * time" true by construction — opening a submenu at level N truncates the stack to N.
52
- *
53
- * @example
54
- * ```ts
55
- * const state = useMenuTriggerState({isOpen: () => props.isOpen});
56
- * state.open("last"); // ArrowUp on the trigger
57
- * ```
58
- */
59
- export declare const useMenuTriggerState: (options?: UseOverlayTriggerStateOptions) => RootMenuTriggerState;
60
- export interface SubmenuTriggerState extends OverlayTriggerState {
61
- focusStrategy: ComputedRef<FocusStrategy | null>;
62
- open: (focusStrategy?: FocusStrategy | null) => void;
63
- toggle: (focusStrategy?: FocusStrategy | null) => void;
64
- /** Closes every menu in the tree, which is what selecting an item does. */
65
- closeAll: () => void;
66
- /** How deep this submenu sits, counting the root menu as level 0. */
67
- submenuLevel: number;
68
- }
69
- export interface UseSubmenuTriggerStateOptions {
70
- /**
71
- * The key of the item that opens this submenu.
72
- *
73
- * Read reactively, because the item is declared beside the submenu rather than around it: the
74
- * submenu exists before it has been told which item it belongs to, and is closed until it has.
75
- */
76
- triggerKey: MaybeRefOrGetter<CollectionKey | null>;
77
- }
78
- /**
79
- * Open state for one submenu, ported from React Stately's `useSubmenuTriggerState`.
80
- *
81
- * Holds no open flag of its own — it derives one by asking the root whether its own trigger
82
- * key is the one expanded at its level. That is what makes opening a sibling submenu close
83
- * this one with no coordination between the two.
84
- *
85
- * The level is captured once, when the submenu trigger is created, and deliberately not
86
- * recomputed: it describes where this trigger sits in the tree, which does not change, whereas
87
- * the stack it was read from changes constantly.
88
- */
89
- export declare const useSubmenuTriggerState: (options: UseSubmenuTriggerStateOptions, root: RootMenuTriggerState) => SubmenuTriggerState;
@@ -1,5 +1,5 @@
1
1
  import { useControllableState } from "./use-controllable-state.js";
2
- import { computed, shallowRef, toValue } from "vue";
2
+ import { computed } from "vue";
3
3
  //#region src/composables/use-overlay-trigger-state.ts
4
4
  /**
5
5
  * Open state for an overlay trigger, ported from React Stately's `useOverlayTriggerState`.
@@ -26,90 +26,5 @@ var useOverlayTriggerState = (options = {}) => {
26
26
  toggle: () => setState(!state.value)
27
27
  };
28
28
  };
29
- /**
30
- * Open state for a menu trigger, ported from React Stately's `useMenuTriggerState`.
31
- *
32
- * Adds two things to a plain overlay trigger. A focus strategy, because how a menu was opened
33
- * decides where focus lands: ArrowUp opens it focused on the last item, a mouse click opens it
34
- * focused on the menu itself. And the stack of open submenus, held here on the root rather
35
- * than in each submenu, which is what makes "only one path through the menu tree is open at a
36
- * time" true by construction — opening a submenu at level N truncates the stack to N.
37
- *
38
- * @example
39
- * ```ts
40
- * const state = useMenuTriggerState({isOpen: () => props.isOpen});
41
- * state.open("last"); // ArrowUp on the trigger
42
- * ```
43
- */
44
- var useMenuTriggerState = (options = {}) => {
45
- const overlay = useOverlayTriggerState(options);
46
- const focusStrategy = shallowRef(null);
47
- const expandedKeys = shallowRef([]);
48
- return {
49
- close: () => {
50
- expandedKeys.value = [];
51
- overlay.close();
52
- },
53
- closeSubmenu: (triggerKey, level) => {
54
- if (expandedKeys.value[level] === triggerKey) expandedKeys.value = expandedKeys.value.slice(0, level);
55
- },
56
- expandedKeysStack: computed(() => expandedKeys.value),
57
- focusStrategy: computed(() => focusStrategy.value),
58
- isOpen: overlay.isOpen,
59
- open: (strategy = null) => {
60
- focusStrategy.value = strategy;
61
- overlay.open();
62
- },
63
- openSubmenu: (triggerKey, level) => {
64
- if (level > expandedKeys.value.length) return;
65
- expandedKeys.value = [...expandedKeys.value.slice(0, level), triggerKey];
66
- },
67
- setOpen: overlay.setOpen,
68
- toggle: (strategy = null) => {
69
- focusStrategy.value = strategy;
70
- overlay.toggle();
71
- }
72
- };
73
- };
74
- /**
75
- * Open state for one submenu, ported from React Stately's `useSubmenuTriggerState`.
76
- *
77
- * Holds no open flag of its own — it derives one by asking the root whether its own trigger
78
- * key is the one expanded at its level. That is what makes opening a sibling submenu close
79
- * this one with no coordination between the two.
80
- *
81
- * The level is captured once, when the submenu trigger is created, and deliberately not
82
- * recomputed: it describes where this trigger sits in the tree, which does not change, whereas
83
- * the stack it was read from changes constantly.
84
- */
85
- var useSubmenuTriggerState = (options, root) => {
86
- const submenuLevel = root.expandedKeysStack.value.length;
87
- const focusStrategy = shallowRef(null);
88
- const triggerKey = computed(() => toValue(options.triggerKey));
89
- const isOpen = computed(() => triggerKey.value !== null && root.expandedKeysStack.value[submenuLevel] === triggerKey.value);
90
- const close = () => {
91
- focusStrategy.value = null;
92
- if (triggerKey.value === null) return;
93
- root.closeSubmenu(triggerKey.value, submenuLevel);
94
- };
95
- const open = (strategy = null) => {
96
- focusStrategy.value = strategy;
97
- if (triggerKey.value === null) return;
98
- root.openSubmenu(triggerKey.value, submenuLevel);
99
- };
100
- return {
101
- close,
102
- closeAll: root.close,
103
- focusStrategy: computed(() => focusStrategy.value),
104
- isOpen,
105
- open,
106
- setOpen: (next) => next ? open() : close(),
107
- submenuLevel,
108
- toggle: (strategy = null) => {
109
- if (isOpen.value) close();
110
- else open(strategy);
111
- }
112
- };
113
- };
114
29
  //#endregion
115
- export { useMenuTriggerState, useOverlayTriggerState, useSubmenuTriggerState };
30
+ export { useOverlayTriggerState };
@@ -0,0 +1,14 @@
1
+ import type { ShallowRef } from "vue";
2
+ export interface PageSize {
3
+ /** Absent on the server, and while there is no document to measure. */
4
+ width: number | undefined;
5
+ height: number | undefined;
6
+ }
7
+ /**
8
+ * Track the size of the whole scrollable page.
9
+ *
10
+ * Ported from the block React Aria computes inline in `ModalOverlayInner`. Published as
11
+ * `--page-width` / `--page-height` for a backdrop that has to cover a page taller than the
12
+ * viewport rather than only the part currently on screen.
13
+ */
14
+ export declare const usePageSize: () => ShallowRef<PageSize>;
@@ -0,0 +1,42 @@
1
+ import { isScrollable } from "../utils/focus.js";
2
+ import { onScopeDispose, shallowRef } from "vue";
3
+ //#region src/composables/use-page-size.ts
4
+ var getVisualViewport = () => typeof document === "undefined" ? null : window.visualViewport ?? null;
5
+ var measurePage = () => {
6
+ if (typeof document === "undefined") return {
7
+ height: void 0,
8
+ width: void 0
9
+ };
10
+ const scrolling = isScrollable(document.body) ? document.body : document.scrollingElement ?? document.documentElement;
11
+ const rect = scrolling.getBoundingClientRect();
12
+ return {
13
+ height: scrolling.scrollHeight - rect.height % 1,
14
+ width: scrolling.scrollWidth - rect.width % 1
15
+ };
16
+ };
17
+ /**
18
+ * Track the size of the whole scrollable page.
19
+ *
20
+ * Ported from the block React Aria computes inline in `ModalOverlayInner`. Published as
21
+ * `--page-width` / `--page-height` for a backdrop that has to cover a page taller than the
22
+ * viewport rather than only the part currently on screen.
23
+ */
24
+ var usePageSize = () => {
25
+ const size = shallowRef(measurePage());
26
+ if (typeof document === "undefined") return size;
27
+ const onResize = () => {
28
+ const next = measurePage();
29
+ if (next.width === size.value.width && next.height === size.value.height) return;
30
+ size.value = next;
31
+ };
32
+ const viewport = getVisualViewport();
33
+ window.addEventListener("resize", onResize);
34
+ viewport?.addEventListener("resize", onResize);
35
+ onScopeDispose(() => {
36
+ window.removeEventListener("resize", onResize);
37
+ viewport?.removeEventListener("resize", onResize);
38
+ }, true);
39
+ return size;
40
+ };
41
+ //#endregion
42
+ export { usePageSize };
@@ -64,26 +64,6 @@ export interface UsePressReturn {
64
64
  */
65
65
  handlers: UsePressHandlers;
66
66
  }
67
- /**
68
- * Whether a click came from something other than a pointer.
69
- *
70
- * Ported from React Aria's `isVirtualClick`. A screen reader and `element.click()` both
71
- * produce a click with no pointer data behind it, which is the only way to tell them apart
72
- * from a real one.
73
- */
74
- export declare const isVirtualClick: (event: MouseEvent) => boolean;
75
- /**
76
- * Whether a pointer event was synthesised by assistive technology.
77
- *
78
- * A screen reader activating an element reports a zero-sized pointer. Safari on iOS gives
79
- * such events the wrong coordinates and target, so they have to be left to the click handler.
80
- *
81
- * Android needs a shape of its own, and the zero-size test is turned off there rather than left
82
- * to miss: TalkBack's double tap reports a one-by-one pointer claiming to be a mouse. Every part
83
- * of that is load-bearing — pressure alone would catch real presses in Safari, which reports zero
84
- * for those too, and the mouse claim is what separates the double tap from a touch screen press.
85
- */
86
- export declare const isVirtualPointerEvent: (event: PointerEvent) => boolean;
87
67
  /**
88
68
  * Press interactions across mouse, touch, keyboard and assistive technology, ported from
89
69
  * React Aria's `usePress`.
@@ -1,31 +1,8 @@
1
- import { isAndroid, isMac } from "../utils/platform.js";
1
+ import { isMac } from "../utils/platform.js";
2
+ import { isVirtualClick, isVirtualPointerEvent } from "./virtual-event.js";
2
3
  import { computed, onScopeDispose, shallowRef, toValue, watch } from "vue";
3
4
  //#region src/composables/use-press.ts
4
5
  /**
5
- * Whether a click came from something other than a pointer.
6
- *
7
- * Ported from React Aria's `isVirtualClick`. A screen reader and `element.click()` both
8
- * produce a click with no pointer data behind it, which is the only way to tell them apart
9
- * from a real one.
10
- */
11
- var isVirtualClick = (event) => {
12
- if (event.pointerType === "" && event.isTrusted) return true;
13
- if (isAndroid() && event.pointerType) return event.type === "click" && event.buttons === 1;
14
- return event.detail === 0 && !event.pointerType;
15
- };
16
- /**
17
- * Whether a pointer event was synthesised by assistive technology.
18
- *
19
- * A screen reader activating an element reports a zero-sized pointer. Safari on iOS gives
20
- * such events the wrong coordinates and target, so they have to be left to the click handler.
21
- *
22
- * Android needs a shape of its own, and the zero-size test is turned off there rather than left
23
- * to miss: TalkBack's double tap reports a one-by-one pointer claiming to be a mouse. Every part
24
- * of that is load-bearing — pressure alone would catch real presses in Safari, which reports zero
25
- * for those too, and the mouse claim is what separates the double tap from a touch screen press.
26
- */
27
- var isVirtualPointerEvent = (event) => !isAndroid() && event.width === 0 && event.height === 0 || isAndroid() && event.width === 1 && event.height === 1 && event.pressure === 0 && event.detail === 0 && event.pointerType === "mouse";
28
- /**
29
6
  * Whether an enter or a leave came from a pointer with no hover to report.
30
7
  *
31
8
  * A touch pointer is created where the finger lands and destroyed where it lifts, and the browser
@@ -385,4 +362,4 @@ var usePress = (options = {}) => {
385
362
  };
386
363
  };
387
364
  //#endregion
388
- export { isVirtualClick, isVirtualPointerEvent, usePress };
365
+ export { usePress };
@@ -1,4 +1,4 @@
1
- import { isVirtualPointerEvent } from "./use-press.js";
1
+ import { isVirtualPointerEvent } from "./virtual-event.js";
2
2
  import { useCalendar } from "./use-calendar.js";
3
3
  import { onScopeDispose, toValue, watch } from "vue";
4
4
  //#region src/composables/use-range-calendar.ts
@@ -1,6 +1,6 @@
1
1
  import type { CollectionKey, UseCollectionReturn } from "./use-collection.js";
2
2
  import type { FormValidationState, ValidationBehavior, ValidationFunction } from "./use-form-validation-state.js";
3
- import type { MenuTriggerState } from "./use-overlay-trigger-state.js";
3
+ import type { MenuTriggerState } from "./use-menu-trigger-state.js";
4
4
  import type { DisabledBehavior, UseSelectionManagerReturn } from "./use-selection-manager.js";
5
5
  import type { ComputedRef, MaybeRefOrGetter } from "vue";
6
6
  /** Whether one or several options can be chosen. */
@@ -1,8 +1,8 @@
1
1
  import { useControllableState } from "./use-controllable-state.js";
2
- import { useMenuTriggerState } from "./use-overlay-trigger-state.js";
3
2
  import { useCollection } from "./use-collection.js";
4
3
  import { createListCollection } from "../utils/virtualizer-collection.js";
5
4
  import { useFormValidationState } from "./use-form-validation-state.js";
5
+ import { useMenuTriggerState } from "./use-menu-trigger-state.js";
6
6
  import { useSelectionManager } from "./use-selection-manager.js";
7
7
  import { computed, shallowRef, toValue } from "vue";
8
8
  //#region src/composables/use-select-state.ts
@@ -1,4 +1,4 @@
1
- import { setInteractionModality } from "./use-interaction-states.js";
1
+ import { setInteractionModality } from "./interaction-modality.js";
2
2
  import { useMove } from "./use-move.js";
3
3
  import { clamp } from "../utils/number.js";
4
4
  import { computed, onScopeDispose, toValue } from "vue";
@@ -1,4 +1,5 @@
1
- import { getInteractionModality, retainInteractionModality, useInteractionStates } from "./use-interaction-states.js";
1
+ import { getInteractionModality, retainInteractionModality } from "./interaction-modality.js";
2
+ import { useInteractionStates } from "./use-interaction-states.js";
2
3
  import { TOP_LAYER_ATTRIBUTE } from "../utils/top-layer.js";
3
4
  import { willOpenKeyboard } from "../utils/platform.js";
4
5
  import { useLocalizedStringFormatter } from "./use-localized-string-formatter.js";
@@ -27,20 +27,6 @@ var clearCooldownTimeout = () => {
27
27
  globalCooldownTimeout = null;
28
28
  };
29
29
  /**
30
- * Forget the shared warmup state.
31
- *
32
- * For a test: the registry and both timers outlive any one component, so a case that leaves a
33
- * tooltip warm would make the next one open with no delay and read as a bug in that test instead.
34
- */
35
- var resetTooltipWarmup = () => {
36
- tooltips.clear();
37
- clearWarmUpTimeout();
38
- clearCooldownTimeout();
39
- globalWarmedUp = false;
40
- };
41
- /** How many tooltips are registered. For a test proving a disposed trigger left nothing behind. */
42
- var getRegisteredTooltipCount = () => tooltips.size;
43
- /**
44
30
  * Open state for a tooltip trigger, ported from React Stately's `useTooltipTriggerState`.
45
31
  *
46
32
  * Two things beyond a plain overlay trigger, and both are about time rather than state. A tooltip
@@ -138,4 +124,4 @@ var useTooltipTriggerState = (options = {}) => {
138
124
  };
139
125
  };
140
126
  //#endregion
141
- export { getRegisteredTooltipCount, resetTooltipWarmup, useTooltipTriggerState };
127
+ export { useTooltipTriggerState };
@@ -1,5 +1,5 @@
1
1
  import { useId as useId$1 } from "./use-id.js";
2
- import { getInteractionModality, isFocusVisible, retainInteractionModality } from "./use-interaction-states.js";
2
+ import { getInteractionModality, isFocusVisible, retainInteractionModality } from "./interaction-modality.js";
3
3
  import { computed, onScopeDispose, shallowRef, toValue, watch } from "vue";
4
4
  //#region src/composables/use-tooltip-trigger.ts
5
5
  /**
@@ -3,11 +3,6 @@ export interface ViewportSize {
3
3
  width: number;
4
4
  height: number;
5
5
  }
6
- export interface PageSize {
7
- /** Absent on the server, and while there is no document to measure. */
8
- width: number | undefined;
9
- height: number | undefined;
10
- }
11
6
  /**
12
7
  * Track the visual viewport, ported from React Aria's `useViewportSize`.
13
8
  *
@@ -21,11 +16,3 @@ export interface PageSize {
21
16
  * ```
22
17
  */
23
18
  export declare const useViewportSize: () => ShallowRef<ViewportSize>;
24
- /**
25
- * Track the size of the whole scrollable page.
26
- *
27
- * Ported from the block React Aria computes inline in `ModalOverlayInner`. Published as
28
- * `--page-width` / `--page-height` for a backdrop that has to cover a page taller than the
29
- * viewport rather than only the part currently on screen.
30
- */
31
- export declare const usePageSize: () => ShallowRef<PageSize>;
@@ -1,4 +1,3 @@
1
- import { isScrollable } from "../utils/focus.js";
2
1
  import { isIOS, isWebKit, willOpenKeyboard } from "../utils/platform.js";
3
2
  import { onScopeDispose, shallowRef } from "vue";
4
3
  //#region src/composables/use-viewport-size.ts
@@ -81,41 +80,5 @@ var useViewportSize = () => {
81
80
  }, true);
82
81
  return size;
83
82
  };
84
- var measurePage = () => {
85
- if (typeof document === "undefined") return {
86
- height: void 0,
87
- width: void 0
88
- };
89
- const scrolling = isScrollable(document.body) ? document.body : document.scrollingElement ?? document.documentElement;
90
- const rect = scrolling.getBoundingClientRect();
91
- return {
92
- height: scrolling.scrollHeight - rect.height % 1,
93
- width: scrolling.scrollWidth - rect.width % 1
94
- };
95
- };
96
- /**
97
- * Track the size of the whole scrollable page.
98
- *
99
- * Ported from the block React Aria computes inline in `ModalOverlayInner`. Published as
100
- * `--page-width` / `--page-height` for a backdrop that has to cover a page taller than the
101
- * viewport rather than only the part currently on screen.
102
- */
103
- var usePageSize = () => {
104
- const size = shallowRef(measurePage());
105
- if (typeof document === "undefined") return size;
106
- const onResize = () => {
107
- const next = measurePage();
108
- if (next.width === size.value.width && next.height === size.value.height) return;
109
- size.value = next;
110
- };
111
- const viewport = getVisualViewport();
112
- window.addEventListener("resize", onResize);
113
- viewport?.addEventListener("resize", onResize);
114
- onScopeDispose(() => {
115
- window.removeEventListener("resize", onResize);
116
- viewport?.removeEventListener("resize", onResize);
117
- }, true);
118
- return size;
119
- };
120
83
  //#endregion
121
- export { usePageSize, useViewportSize };
84
+ export { useViewportSize };
@@ -0,0 +1,37 @@
1
+ import type { ValidationDetails, ValidationResult, RequiredControl } from "./use-form-validation-state.js";
2
+ export declare const VALID_VALIDITY_STATE: ValidationDetails;
3
+ /** Failure that came from a prop, a `validate` function or the server rather than the browser. */
4
+ export declare const CUSTOM_VALIDITY_STATE: ValidationDetails;
5
+ /** A required field with nothing in it. What the browser reports under `"native"`. */
6
+ export declare const MISSING_VALIDITY_STATE: ValidationDetails;
7
+ export declare const DEFAULT_VALIDATION_RESULT: ValidationResult;
8
+ /**
9
+ * One verdict out of several, for a control whose value has more than one part.
10
+ *
11
+ * Invalid if any part is, with the messages collected in order and deduplicated — two ends of a
12
+ * range that are both out of bounds say the same thing, and saying it twice is not more helpful.
13
+ */
14
+ export declare const mergeValidation: (...results: ValidationResult[]) => ValidationResult;
15
+ /** Form controls that take part in constraint validation. */
16
+ export type ValidatableElement = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
17
+ /** Freeze an element's live validity into a result the state layer can hold. */
18
+ export declare const getNativeValidation: (element: ValidatableElement) => ValidationResult;
19
+ /**
20
+ * What the browser would say about an empty control of this kind.
21
+ *
22
+ * Read off a detached probe rather than translated here. The platform already holds the sentence,
23
+ * in the *browser's* locale — which is the locale a validation message belongs in, since it sits
24
+ * beside the browser's own — and it is the one the same field would report under `"native"`.
25
+ *
26
+ * Empty on a server, where the field cannot have been revealed yet and so has nothing to say.
27
+ */
28
+ export declare const missingValueMessage: (kind: RequiredControl) => string;
29
+ /** Whether a value counts as nothing. Covers every shape a field holds when it is empty. */
30
+ export declare const isValueMissing: (value: unknown) => boolean;
31
+ /**
32
+ * Whether two results say the same thing.
33
+ *
34
+ * Not an optimisation: the results live in `shallowRef`s, and assigning an equal-but-new
35
+ * object still retriggers every computed reading them.
36
+ */
37
+ export declare const isEqualValidation: (a: ValidationResult | null, b: ValidationResult | null) => boolean;