@featherk/composables 0.17.1 → 0.18.1

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 (119) hide show
  1. package/README.md +62 -15
  2. package/dist/address.cjs +2 -0
  3. package/dist/address.cjs.map +1 -0
  4. package/dist/address.mjs +6 -0
  5. package/dist/address.mjs.map +1 -0
  6. package/dist/chunks/useActiveIdRegistry-BG8VR__Z.mjs +43 -0
  7. package/dist/chunks/useActiveIdRegistry-BG8VR__Z.mjs.map +1 -0
  8. package/dist/chunks/useActiveIdRegistry-C1b00tqW.cjs +2 -0
  9. package/dist/chunks/useActiveIdRegistry-C1b00tqW.cjs.map +1 -0
  10. package/dist/chunks/useCompositeId-DyrJ0Fqj.cjs +2 -0
  11. package/dist/chunks/useCompositeId-DyrJ0Fqj.cjs.map +1 -0
  12. package/dist/chunks/useCompositeId-xg87ehXQ.mjs +9 -0
  13. package/dist/chunks/useCompositeId-xg87ehXQ.mjs.map +1 -0
  14. package/dist/chunks/useFieldsetValidationKit-7W1XDbbr.cjs +2 -0
  15. package/dist/chunks/useFieldsetValidationKit-7W1XDbbr.cjs.map +1 -0
  16. package/dist/chunks/useFieldsetValidationKit-x0Rh48mE.mjs +64 -0
  17. package/dist/chunks/useFieldsetValidationKit-x0Rh48mE.mjs.map +1 -0
  18. package/dist/chunks/useGridRowAction-Di25yeqb.cjs +2 -0
  19. package/dist/chunks/useGridRowAction-Di25yeqb.cjs.map +1 -0
  20. package/dist/chunks/useGridRowAction-akjwkV_F.mjs +532 -0
  21. package/dist/chunks/useGridRowAction-akjwkV_F.mjs.map +1 -0
  22. package/dist/chunks/useIntersectionObserver-A4xQV_pl.mjs +23 -0
  23. package/dist/chunks/useIntersectionObserver-A4xQV_pl.mjs.map +1 -0
  24. package/dist/chunks/useIntersectionObserver-CfgNAo2N.cjs +2 -0
  25. package/dist/chunks/useIntersectionObserver-CfgNAo2N.cjs.map +1 -0
  26. package/dist/chunks/useMaskedDateInput-COOksUM_.mjs +276 -0
  27. package/dist/chunks/useMaskedDateInput-COOksUM_.mjs.map +1 -0
  28. package/dist/chunks/useMaskedDateInput-wRnYlR3L.cjs +2 -0
  29. package/dist/chunks/useMaskedDateInput-wRnYlR3L.cjs.map +1 -0
  30. package/dist/chunks/useMaskedDateRangeInput-DST5aQe0.cjs +2 -0
  31. package/dist/chunks/useMaskedDateRangeInput-DST5aQe0.cjs.map +1 -0
  32. package/dist/chunks/useMaskedDateRangeInput-owYSg36r.mjs +328 -0
  33. package/dist/chunks/useMaskedDateRangeInput-owYSg36r.mjs.map +1 -0
  34. package/dist/chunks/useMaskedTimeInput-DPd2lysd.cjs +2 -0
  35. package/dist/chunks/useMaskedTimeInput-DPd2lysd.cjs.map +1 -0
  36. package/dist/chunks/useMaskedTimeInput-DjtBdvsf.mjs +363 -0
  37. package/dist/chunks/useMaskedTimeInput-DjtBdvsf.mjs.map +1 -0
  38. package/dist/chunks/usePopupMenu-CZLtgrXk.mjs +296 -0
  39. package/dist/chunks/usePopupMenu-CZLtgrXk.mjs.map +1 -0
  40. package/dist/chunks/usePopupMenu-DeTWakUH.cjs +2 -0
  41. package/dist/chunks/usePopupMenu-DeTWakUH.cjs.map +1 -0
  42. package/dist/chunks/usePopupTrap-DQudM6YA.cjs +2 -0
  43. package/dist/chunks/usePopupTrap-DQudM6YA.cjs.map +1 -0
  44. package/dist/chunks/usePopupTrap-DeuXHLZR.mjs +105 -0
  45. package/dist/chunks/usePopupTrap-DeuXHLZR.mjs.map +1 -0
  46. package/dist/chunks/useUSAddress-BYZZfbHc.cjs +2 -0
  47. package/dist/chunks/useUSAddress-BYZZfbHc.cjs.map +1 -0
  48. package/dist/chunks/useUSAddress-CRcqdqrZ.mjs +291 -0
  49. package/dist/chunks/useUSAddress-CRcqdqrZ.mjs.map +1 -0
  50. package/dist/chunks/useWindow-C4XFBuJA.mjs +210 -0
  51. package/dist/chunks/useWindow-C4XFBuJA.mjs.map +1 -0
  52. package/dist/chunks/useWindow-Yia2I6zX.cjs +2 -0
  53. package/dist/chunks/useWindow-Yia2I6zX.cjs.map +1 -0
  54. package/dist/date/useMaskedDateInput.d.ts +4 -0
  55. package/dist/date.cjs +2 -0
  56. package/dist/date.cjs.map +1 -0
  57. package/dist/date.mjs +5 -0
  58. package/dist/date.mjs.map +1 -0
  59. package/dist/{docs-manifest.js → docs-manifest.mjs} +24 -24
  60. package/dist/form.cjs +2 -0
  61. package/dist/form.cjs.map +1 -0
  62. package/dist/form.mjs +6 -0
  63. package/dist/form.mjs.map +1 -0
  64. package/dist/geometry.cjs +2 -0
  65. package/dist/geometry.cjs.map +1 -0
  66. package/dist/geometry.mjs +60 -0
  67. package/dist/geometry.mjs.map +1 -0
  68. package/dist/grid.cjs +2 -0
  69. package/dist/grid.cjs.map +1 -0
  70. package/dist/grid.mjs +7 -0
  71. package/dist/grid.mjs.map +1 -0
  72. package/dist/id.cjs +2 -0
  73. package/dist/id.cjs.map +1 -0
  74. package/dist/id.mjs +5 -0
  75. package/dist/id.mjs.map +1 -0
  76. package/dist/index.cjs +2 -0
  77. package/dist/index.cjs.map +1 -0
  78. package/dist/index.d.ts +3 -3
  79. package/dist/index.mjs +37 -0
  80. package/dist/index.mjs.map +1 -0
  81. package/dist/menu.cjs +2 -0
  82. package/dist/menu.cjs.map +1 -0
  83. package/dist/menu.mjs +5 -0
  84. package/dist/menu.mjs.map +1 -0
  85. package/dist/observer.cjs +2 -0
  86. package/dist/observer.cjs.map +1 -0
  87. package/dist/observer.mjs +5 -0
  88. package/dist/observer.mjs.map +1 -0
  89. package/dist/range/useMaskedDateRangeInput.d.ts +4 -0
  90. package/dist/range.cjs +2 -0
  91. package/dist/range.cjs.map +1 -0
  92. package/dist/range.mjs +5 -0
  93. package/dist/range.mjs.map +1 -0
  94. package/dist/registry.cjs +2 -0
  95. package/dist/registry.cjs.map +1 -0
  96. package/dist/registry.mjs +6 -0
  97. package/dist/registry.mjs.map +1 -0
  98. package/dist/time/useMaskedTimeInput.d.ts +4 -0
  99. package/dist/time.cjs +2 -0
  100. package/dist/time.cjs.map +1 -0
  101. package/dist/time.mjs +5 -0
  102. package/dist/time.mjs.map +1 -0
  103. package/dist/trap.cjs +2 -0
  104. package/dist/trap.cjs.map +1 -0
  105. package/dist/trap.mjs +7 -0
  106. package/dist/trap.mjs.map +1 -0
  107. package/dist/window.cjs +2 -0
  108. package/dist/window.cjs.map +1 -0
  109. package/dist/window.mjs +6 -0
  110. package/dist/window.mjs.map +1 -0
  111. package/docs/date/useMaskedDateInput.md +3 -0
  112. package/docs/range/useMaskedDateRangeInput.md +6 -7
  113. package/docs/time/useMaskedTimeInput.md +3 -0
  114. package/package.json +38 -36
  115. package/dist/featherk-composables.es.js +0 -2628
  116. package/dist/featherk-composables.es.js.map +0 -1
  117. package/dist/featherk-composables.umd.js +0 -2
  118. package/dist/featherk-composables.umd.js.map +0 -1
  119. /package/dist/{docs-manifest.d.ts → docs-manifest.d.mts} +0 -0
@@ -0,0 +1,210 @@
1
+ import { isRef as P, ref as v, shallowRef as Z, computed as M, watch as J, onScopeDispose as C, toValue as Q, nextTick as tt } from "vue";
2
+ const U = {
3
+ title: "My Window",
4
+ draggable: !0,
5
+ resizable: !0,
6
+ closable: !0,
7
+ fixed: !0,
8
+ minimizeButton: !0,
9
+ maximizeButton: !0,
10
+ initialLeft: void 0,
11
+ initialTop: void 0,
12
+ initialWidth: 500,
13
+ initialHeight: 500,
14
+ width: 500,
15
+ height: 500,
16
+ left: void 0,
17
+ top: void 0
18
+ }, et = (n) => n === "DEFAULT" || n === "MINIMIZED" || n === "FULLSCREEN", it = 120, nt = 100, ot = ["n", "e", "s", "w", "ne", "nw", "se", "sw"], m = (n, e, u) => Math.min(Math.max(n, e), u), _ = (n) => typeof n == "object" && n !== null && "drag" in n && "left" in n && "top" in n && "width" in n && "height" in n && typeof n.left == "number" && typeof n.top == "number" && typeof n.width == "number" && typeof n.height == "number", lt = (n, e, u) => Math.max(n - e - u, 0);
19
+ function rt(n = {}) {
20
+ P(n.settings) && (n.settings.value = {
21
+ ...U,
22
+ ...n.settings.value
23
+ });
24
+ const e = P(n.settings) ? n.settings : v({ ...U, ...n.settings }), u = Z(null), p = v(!1), f = v(n.initialStage ?? "DEFAULT"), b = v(!1), E = v(!1), T = v(0), D = v(0), L = M(() => e.value.minWidth ?? it), x = M(
25
+ () => e.value.minHeight ?? nt
26
+ );
27
+ let d = null, z = null;
28
+ const S = () => {
29
+ const i = e.value.fixed ? 0 : window.scrollX, t = e.value.fixed ? 0 : window.scrollY;
30
+ return {
31
+ left: i,
32
+ top: t,
33
+ right: i + document.documentElement.clientWidth,
34
+ bottom: t + document.documentElement.clientHeight
35
+ };
36
+ }, H = () => ({
37
+ left: e.value.left ?? T.value,
38
+ top: e.value.top ?? D.value,
39
+ width: e.value.width ?? e.value.initialWidth,
40
+ height: e.value.height ?? e.value.initialHeight
41
+ }), A = async (i) => {
42
+ z = null;
43
+ const t = e.value.left !== void 0 && e.value.top !== void 0;
44
+ if (i?.resetPosition || !t) {
45
+ const o = Number.parseFloat(
46
+ window.getComputedStyle(document.documentElement).fontSize
47
+ ), l = Number.isFinite(o) ? o : 16, s = e.value.fixed ? 0 : window.scrollX, r = e.value.fixed ? 0 : window.scrollY;
48
+ e.value.left = void 0, e.value.top = void 0, e.value.width = void 0, e.value.height = void 0, T.value = e.value.initialLeft ?? s + lt(
49
+ window.innerWidth,
50
+ e.value.initialWidth,
51
+ l
52
+ ), D.value = e.value.initialTop ?? r + l, p.value = !0, await tt(), e.value.width = e.value.initialWidth, e.value.height = e.value.initialHeight;
53
+ } else
54
+ p.value = !0;
55
+ n.onOpen?.();
56
+ }, y = () => {
57
+ f.value = "DEFAULT", p.value = !1, n.onClose?.();
58
+ }, B = (...i) => {
59
+ const t = i[2];
60
+ if (typeof t != "object" || t === null || !("state" in t) || !et(t.state))
61
+ return;
62
+ const o = t.state;
63
+ o !== f.value && (z = null, f.value = o, n.onStageChange?.(o));
64
+ }, j = (...i) => {
65
+ const t = i[0];
66
+ if (_(t)) {
67
+ const o = u.value?.$el, s = (o instanceof Element ? o.querySelector(".k-window-titlebar") : null)?.getBoundingClientRect(), r = s?.width ?? t.width, w = s?.height ?? t.height, a = S(), c = Math.max(
68
+ a.right - r,
69
+ a.left
70
+ ), h = Math.max(
71
+ a.bottom - w,
72
+ a.top
73
+ );
74
+ e.value.left = m(t.left, a.left, c), e.value.top = m(t.top, a.top, h), b.value = t.drag && !t.end, n.onMove?.(t);
75
+ }
76
+ }, G = (i) => {
77
+ const { direction: t, start: o } = i, l = S(), s = i.pointerX - i.startX, r = i.pointerY - i.startY;
78
+ let w = o.left, a = o.top, c = o.left + o.width, h = o.top + o.height;
79
+ return t.includes("n") && (a = m(
80
+ o.top + r,
81
+ Math.min(l.top, o.top),
82
+ h - x.value
83
+ )), t.includes("s") && (h = m(
84
+ h + r,
85
+ a + x.value,
86
+ Math.max(l.bottom, h)
87
+ )), t.includes("w") && (w = m(
88
+ o.left + s,
89
+ Math.min(l.left, o.left),
90
+ c - L.value
91
+ )), t.includes("e") && (c = m(
92
+ c + s,
93
+ w + L.value,
94
+ Math.max(l.right, c)
95
+ )), { left: w, top: a, width: c - w, height: h - a };
96
+ }, O = (i) => {
97
+ const t = H(), o = z ?? t, l = S(), s = Math.max(l.right, t.left + t.width) - t.left, r = Math.max(l.bottom, t.top + t.height) - t.top;
98
+ return {
99
+ left: t.left,
100
+ top: t.top,
101
+ width: Math.max(
102
+ Math.min(t.width + i.width - o.width, s),
103
+ L.value
104
+ ),
105
+ height: Math.max(
106
+ Math.min(
107
+ t.height + i.height - o.height,
108
+ r
109
+ ),
110
+ x.value
111
+ )
112
+ };
113
+ }, F = (i) => {
114
+ d && (d.pointerX = i.clientX, d.pointerY = i.clientY);
115
+ }, g = () => {
116
+ d = null, window.removeEventListener("pointermove", F, !0), window.removeEventListener("pointerup", W, !0), window.removeEventListener("pointercancel", W, !0);
117
+ };
118
+ function W() {
119
+ window.setTimeout(g, 0);
120
+ }
121
+ const $ = (i, t) => {
122
+ const o = ot.find(
123
+ (l) => t.classList.contains(`k-resize-${l}`)
124
+ );
125
+ g(), o && (d = {
126
+ direction: o,
127
+ start: H(),
128
+ startX: i.clientX,
129
+ startY: i.clientY,
130
+ pointerX: i.clientX,
131
+ pointerY: i.clientY
132
+ }, window.addEventListener("pointermove", F, !0), window.addEventListener("pointerup", W, !0), window.addEventListener("pointercancel", W, !0));
133
+ }, q = (...i) => {
134
+ const t = i[0];
135
+ if (_(t)) {
136
+ const o = d ? G(d) : O(t);
137
+ z = { width: t.width, height: t.height }, e.value.left = o.left, e.value.top = o.top, e.value.width = o.width, e.value.height = o.height, E.value = t.drag && !t.end, t.end && g(), n.onResize?.({ ...t, ...o });
138
+ }
139
+ }, I = (i) => {
140
+ const t = i.target instanceof Element ? i.target.closest(".k-resize-handle") : null;
141
+ t && (i.preventDefault(), $(i, t));
142
+ }, N = (i) => {
143
+ Q(n.titlebarDoubleClick) === !1 && i.target instanceof Element && i.target.closest(".k-window-titlebar") && (i.preventDefault(), i.stopPropagation());
144
+ };
145
+ let k, R;
146
+ const X = () => {
147
+ k?.(), k = void 0;
148
+ }, Y = () => {
149
+ R?.(), R = void 0;
150
+ };
151
+ J(
152
+ u,
153
+ (i) => {
154
+ X(), Y(), g(), E.value = !1, b.value = !1;
155
+ const t = i?.$el;
156
+ t instanceof HTMLElement && (t.addEventListener("pointerdown", I, {
157
+ capture: !0
158
+ }), k = () => t.removeEventListener("pointerdown", I, {
159
+ capture: !0
160
+ }), t.addEventListener("dblclick", N, {
161
+ capture: !0
162
+ }), R = () => t.removeEventListener("dblclick", N, {
163
+ capture: !0
164
+ }));
165
+ },
166
+ { flush: "post" }
167
+ ), C(X), C(Y), C(g);
168
+ const K = M(() => {
169
+ const i = ["fk-window"];
170
+ return e.value.draggable && f.value !== "FULLSCREEN" && i.push("fk-window-can-drag"), b.value && i.push("fk-window-is-dragging"), E.value && i.push("fk-window-is-resizing"), e.value.fixed && i.push("fk-window-fixed"), e.value.minimizeButton || i.push("fk-window-hide-minimize"), e.value.maximizeButton || i.push("fk-window-hide-maximize"), e.value.closable || i.push("fk-window-hide-close"), i.join(" ");
171
+ }), V = M(() => ({
172
+ title: e.value.title,
173
+ draggable: e.value.draggable,
174
+ resizable: e.value.resizable,
175
+ left: e.value.left,
176
+ top: e.value.top,
177
+ initialLeft: T.value,
178
+ initialTop: D.value,
179
+ initialWidth: e.value.initialWidth,
180
+ initialHeight: e.value.initialHeight,
181
+ width: e.value.width,
182
+ height: e.value.height,
183
+ minWidth: L.value,
184
+ minHeight: x.value,
185
+ stage: f.value,
186
+ windowClass: K.value
187
+ }));
188
+ return {
189
+ windowRef: u,
190
+ settings: e,
191
+ visible: p,
192
+ stage: f,
193
+ isDragging: b,
194
+ isResizing: E,
195
+ props: V,
196
+ events: {
197
+ move: j,
198
+ resize: q,
199
+ stagechange: B,
200
+ close: y
201
+ },
202
+ open: A,
203
+ close: y
204
+ };
205
+ }
206
+ export {
207
+ U as W,
208
+ rt as u
209
+ };
210
+ //# sourceMappingURL=useWindow-C4XFBuJA.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useWindow-C4XFBuJA.mjs","sources":["../../src/window/useWindow.ts"],"sourcesContent":["import {\n computed,\n isRef,\n nextTick,\n onScopeDispose,\n ref,\n shallowRef,\n toValue,\n watch,\n type ComponentPublicInstance,\n type ComputedRef,\n type MaybeRefOrGetter,\n type Ref,\n} from \"vue\";\n\n/** Kendo Window's stage values. Distinct from browser fullscreen APIs. */\nexport type WindowStage = \"DEFAULT\" | \"MINIMIZED\" | \"FULLSCREEN\";\n\nexport interface WindowMoveEventPayload {\n drag: boolean;\n end: boolean;\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\nexport type WindowResizeEventPayload = WindowMoveEventPayload;\n\nexport interface WindowSettings {\n title: string;\n draggable: boolean;\n resizable: boolean;\n /** Hidden via `windowClass`, not a real Kendo prop - see docs \"Inert Props\". */\n closable: boolean;\n fixed: boolean;\n /** Hidden via `windowClass`, not a real Kendo prop - see docs \"Inert Props\". */\n minimizeButton: boolean;\n /** Hidden via `windowClass`, not a real Kendo prop - see docs \"Inert Props\". */\n maximizeButton: boolean;\n initialLeft?: number;\n initialTop?: number;\n initialWidth: number;\n initialHeight: number;\n width?: number;\n height?: number;\n left?: number;\n top?: number;\n /** Minimum resize width in px. Unset/`null` falls back to Kendo's default (120). */\n minWidth?: number | null;\n /** Minimum resize height in px. Unset/`null` falls back to Kendo's default (100). */\n minHeight?: number | null;\n}\n\nexport const WINDOW_SETTINGS_DEFAULTS: WindowSettings = {\n title: \"My Window\",\n draggable: true,\n resizable: true,\n closable: true,\n fixed: true,\n minimizeButton: true,\n maximizeButton: true,\n initialLeft: undefined,\n initialTop: undefined,\n initialWidth: 500,\n initialHeight: 500,\n width: 500,\n height: 500,\n left: undefined,\n top: undefined,\n};\n\nexport interface UseWindowOptions {\n /**\n * Overrides for one or more settings; any field you omit falls back to\n * `WINDOW_SETTINGS_DEFAULTS`, merged internally - you never need to spread\n * the defaults yourself. Pass a `Ref` (e.g. one already wired to your own\n * persistence layer) to have `useWindow` read and mutate it directly\n * instead of creating its own internal ref; missing fields on that ref are\n * filled in from the defaults once, in place, at setup time.\n */\n settings?: Partial<WindowSettings> | Ref<Partial<WindowSettings>>;\n initialStage?: WindowStage;\n /** Enables the native titlebar double-click stage toggle. Defaults to true. */\n titlebarDoubleClick?: MaybeRefOrGetter<boolean>;\n onMove?: (payload: WindowMoveEventPayload) => void;\n onResize?: (payload: WindowResizeEventPayload) => void;\n onStageChange?: (stage: WindowStage) => void;\n onOpen?: () => void;\n onClose?: () => void;\n}\n\n/** The subset of Kendo `Window` props useWindow keeps functional - see docs \"Inert Props\". */\nexport interface WindowBindableProps {\n title: string;\n draggable: boolean;\n resizable: boolean;\n left?: number;\n top?: number;\n initialLeft: number;\n initialTop: number;\n initialWidth: number;\n initialHeight: number;\n width?: number;\n height?: number;\n minWidth: number;\n minHeight: number;\n stage: WindowStage;\n windowClass: string;\n}\n\nexport interface WindowEvents {\n move: (...args: unknown[]) => void;\n resize: (...args: unknown[]) => void;\n stagechange: (...args: unknown[]) => void;\n close: (...args: unknown[]) => void;\n}\n\nexport interface UseWindowOpenOptions {\n /**\n * Discards any existing left/top/width/height (including one restored from\n * an externally-persisted `settings` ref) and recomputes the initial inset\n * position and `initialWidth`/`initialHeight` size. Defaults to `false`, so\n * a previously dragged/resized/persisted position survives close + reopen.\n */\n resetPosition?: boolean;\n}\n\nexport interface UseWindowReturn {\n windowRef: Ref<ComponentPublicInstance | null>;\n settings: Ref<WindowSettings>;\n visible: Ref<boolean>;\n stage: Ref<WindowStage>;\n isDragging: Ref<boolean>;\n isResizing: Ref<boolean>;\n /** Spread via `v-bind` onto `<Window>`. */\n props: ComputedRef<WindowBindableProps>;\n /** Spread via `v-on` onto `<Window>`. */\n events: WindowEvents;\n open: (openOptions?: UseWindowOpenOptions) => Promise<void>;\n close: () => void;\n}\n\nconst isWindowStage = (value: unknown): value is WindowStage =>\n value === \"DEFAULT\" || value === \"MINIMIZED\" || value === \"FULLSCREEN\";\n\n// Mirror Kendo Window's own minWidth/minHeight defaults.\nconst DEFAULT_MIN_WIDTH = 120;\nconst DEFAULT_MIN_HEIGHT = 100;\n\nconst RESIZE_DIRECTIONS = [\"n\", \"e\", \"s\", \"w\", \"ne\", \"nw\", \"se\", \"sw\"];\n\ninterface WindowRect {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\ninterface ResizeSession {\n direction: string;\n start: WindowRect;\n startX: number;\n startY: number;\n pointerX: number;\n pointerY: number;\n}\n\nconst clamp = (value: number, min: number, max: number) =>\n Math.min(Math.max(value, min), max);\n\nconst isWindowGeometryEvent = (\n event: unknown,\n): event is WindowMoveEventPayload =>\n typeof event === \"object\" &&\n event !== null &&\n \"drag\" in event &&\n \"left\" in event &&\n \"top\" in event &&\n \"width\" in event &&\n \"height\" in event &&\n typeof event.left === \"number\" &&\n typeof event.top === \"number\" &&\n typeof event.width === \"number\" &&\n typeof event.height === \"number\";\n\n/**\n * Converts a desired right-edge inset into Kendo Window's `initialLeft`\n * coordinate. Kendo exposes no `initialRight` prop, so positioning from the\n * right must be expressed as a left offset. Clamps to zero when the Window is\n * wider than the available viewport.\n */\nconst calculateInitialLeft = (\n viewportWidth: number,\n windowWidth: number,\n rightInset: number,\n) => Math.max(viewportWidth - windowWidth - rightInset, 0);\n\n/**\n * Wraps Kendo UI for Vue's `Window` component (not the browser `window`\n * object) with zero-config defaults, viewport-clamped dragging, and the\n * pointerdown-capture resize/text-selection workaround from\n * docs/design/composable-native-event-listener-tactic.md.\n */\nexport function useWindow(options: UseWindowOptions = {}): UseWindowReturn {\n // Merge WINDOW_SETTINGS_DEFAULTS into whatever the consumer provided.\n // A Ref is filled in place (preserving its identity, e.g. for persistence);\n // a plain partial object seeds a new internal ref.\n if (isRef(options.settings)) {\n options.settings.value = {\n ...WINDOW_SETTINGS_DEFAULTS,\n ...options.settings.value,\n };\n }\n\n const settings: Ref<WindowSettings> = isRef(options.settings)\n ? (options.settings as Ref<WindowSettings>)\n : ref<WindowSettings>({ ...WINDOW_SETTINGS_DEFAULTS, ...options.settings });\n\n const windowRef = shallowRef<ComponentPublicInstance | null>(null);\n const visible = ref(false);\n const stage = ref<WindowStage>(options.initialStage ?? \"DEFAULT\");\n const isDragging = ref(false);\n const isResizing = ref(false);\n const initialLeft = ref(0);\n const initialTop = ref(0);\n const minWidth = computed(() => settings.value.minWidth ?? DEFAULT_MIN_WIDTH);\n const minHeight = computed(\n () => settings.value.minHeight ?? DEFAULT_MIN_HEIGHT,\n );\n\n let resizeSession: ResizeSession | null = null;\n // Kendo's internal size, which drifts from the clamped settings; keyboard resizes are applied as deltas of it.\n let lastKendoSize: { width: number; height: number } | null = null;\n\n const getViewportBounds = () => {\n const left = settings.value.fixed ? 0 : window.scrollX;\n const top = settings.value.fixed ? 0 : window.scrollY;\n\n return {\n left,\n top,\n right: left + document.documentElement.clientWidth,\n bottom: top + document.documentElement.clientHeight,\n };\n };\n\n const getCurrentRect = (): WindowRect => ({\n left: settings.value.left ?? initialLeft.value,\n top: settings.value.top ?? initialTop.value,\n width: settings.value.width ?? settings.value.initialWidth,\n height: settings.value.height ?? settings.value.initialHeight,\n });\n\n const open = async (openOptions?: UseWindowOpenOptions) => {\n lastKendoSize = null;\n\n // No stored left/top means this is the first-ever open - always compute\n // the initial layout then, regardless of resetPosition.\n const hasStoredPosition =\n settings.value.left !== undefined && settings.value.top !== undefined;\n\n if (openOptions?.resetPosition || !hasStoredPosition) {\n const rootFontSize = Number.parseFloat(\n window.getComputedStyle(document.documentElement).fontSize,\n );\n const padding = Number.isFinite(rootFontSize) ? rootFontSize : 16;\n // Non-fixed Windows position in document coordinates (matching\n // handleMove's viewportLeft/viewportTop), so the inset must account for\n // scroll offset or a scrolled page opens the Window off-screen.\n const viewportLeft = settings.value.fixed ? 0 : window.scrollX;\n const viewportTop = settings.value.fixed ? 0 : window.scrollY;\n\n settings.value.left = undefined;\n settings.value.top = undefined;\n settings.value.width = undefined;\n settings.value.height = undefined;\n initialLeft.value =\n settings.value.initialLeft ??\n viewportLeft +\n calculateInitialLeft(\n window.innerWidth,\n settings.value.initialWidth,\n padding,\n );\n initialTop.value = settings.value.initialTop ?? viewportTop + padding;\n visible.value = true;\n\n await nextTick();\n settings.value.width = settings.value.initialWidth;\n settings.value.height = settings.value.initialHeight;\n } else {\n // Persisted/dragged left, top, width, and height are left untouched -\n // Kendo applies them directly via the controlled left/top/width/height props.\n visible.value = true;\n }\n\n options.onOpen?.();\n };\n\n const closeWindow = () => {\n stage.value = \"DEFAULT\";\n visible.value = false;\n options.onClose?.();\n };\n\n const handleStageChange = (...args: unknown[]) => {\n // Kendo emits (nativeEvent, windowInstance, { state }) at runtime despite\n // its .d.ts typing onStagechange as a single-argument callback.\n const payload = args[2];\n\n if (\n typeof payload !== \"object\" ||\n payload === null ||\n !(\"state\" in payload) ||\n !isWindowStage(payload.state)\n ) {\n return;\n }\n\n const requestedStage = payload.state;\n\n if (requestedStage === stage.value) {\n return;\n }\n\n // Kendo resyncs its internal size to our props on stage transitions.\n lastKendoSize = null;\n stage.value = requestedStage;\n options.onStageChange?.(requestedStage);\n };\n\n const handleMove = (...args: unknown[]) => {\n const payload = args[0];\n\n if (isWindowGeometryEvent(payload)) {\n const windowRoot = windowRef.value?.$el;\n const titlebar =\n windowRoot instanceof Element\n ? windowRoot.querySelector<HTMLElement>(\".k-window-titlebar\")\n : null;\n const titlebarRect = titlebar?.getBoundingClientRect();\n const titlebarWidth = titlebarRect?.width ?? payload.width;\n const titlebarHeight = titlebarRect?.height ?? payload.height;\n const viewport = getViewportBounds();\n const maximumLeft = Math.max(\n viewport.right - titlebarWidth,\n viewport.left,\n );\n const maximumTop = Math.max(\n viewport.bottom - titlebarHeight,\n viewport.top,\n );\n\n settings.value.left = clamp(payload.left, viewport.left, maximumLeft);\n settings.value.top = clamp(payload.top, viewport.top, maximumTop);\n isDragging.value = payload.drag && !payload.end;\n options.onMove?.(payload);\n }\n };\n\n // Kendo snaps edges to the absolute pointer with no viewport bounds, so a\n // pointer resize is derived from our own pointer delta instead.\n const resizeFromPointer = (session: ResizeSession): WindowRect => {\n const { direction, start } = session;\n const viewport = getViewportBounds();\n const dx = session.pointerX - session.startX;\n const dy = session.pointerY - session.startY;\n let left = start.left;\n let top = start.top;\n let right = start.left + start.width;\n let bottom = start.top + start.height;\n\n // Bounds use min/max with the start edge so an already-offscreen edge never snaps back.\n if (direction.includes(\"n\")) {\n top = clamp(\n start.top + dy,\n Math.min(viewport.top, start.top),\n bottom - minHeight.value,\n );\n }\n if (direction.includes(\"s\")) {\n bottom = clamp(\n bottom + dy,\n top + minHeight.value,\n Math.max(viewport.bottom, bottom),\n );\n }\n if (direction.includes(\"w\")) {\n left = clamp(\n start.left + dx,\n Math.min(viewport.left, start.left),\n right - minWidth.value,\n );\n }\n if (direction.includes(\"e\")) {\n right = clamp(\n right + dx,\n left + minWidth.value,\n Math.max(viewport.right, right),\n );\n }\n\n return { left, top, width: right - left, height: bottom - top };\n };\n\n // Keyboard (Ctrl+Arrow) resizes only change size, never left/top.\n const resizeFromKendoDelta = (\n payload: WindowResizeEventPayload,\n ): WindowRect => {\n const current = getCurrentRect();\n const previous = lastKendoSize ?? current;\n const viewport = getViewportBounds();\n const maximumWidth =\n Math.max(viewport.right, current.left + current.width) - current.left;\n const maximumHeight =\n Math.max(viewport.bottom, current.top + current.height) - current.top;\n\n return {\n left: current.left,\n top: current.top,\n width: Math.max(\n Math.min(current.width + payload.width - previous.width, maximumWidth),\n minWidth.value,\n ),\n height: Math.max(\n Math.min(\n current.height + payload.height - previous.height,\n maximumHeight,\n ),\n minHeight.value,\n ),\n };\n };\n\n const trackResizePointer = (event: PointerEvent) => {\n if (resizeSession) {\n resizeSession.pointerX = event.clientX;\n resizeSession.pointerY = event.clientY;\n }\n };\n\n const endResizeSession = () => {\n resizeSession = null;\n window.removeEventListener(\"pointermove\", trackResizePointer, true);\n window.removeEventListener(\"pointerup\", releaseResizePointer, true);\n window.removeEventListener(\"pointercancel\", releaseResizePointer, true);\n };\n\n // Deferred so Kendo's own release (the final `end` resize event) still sees the session.\n function releaseResizePointer() {\n window.setTimeout(endResizeSession, 0);\n }\n\n const startResizeSession = (event: PointerEvent, handle: Element) => {\n const direction = RESIZE_DIRECTIONS.find((candidate) =>\n handle.classList.contains(`k-resize-${candidate}`),\n );\n\n endResizeSession();\n\n if (!direction) {\n return;\n }\n\n resizeSession = {\n direction,\n start: getCurrentRect(),\n startX: event.clientX,\n startY: event.clientY,\n pointerX: event.clientX,\n pointerY: event.clientY,\n };\n // Window capture runs before Kendo's draggable listeners, so the pointer is current when Kendo emits resize.\n window.addEventListener(\"pointermove\", trackResizePointer, true);\n window.addEventListener(\"pointerup\", releaseResizePointer, true);\n window.addEventListener(\"pointercancel\", releaseResizePointer, true);\n };\n\n const handleResize = (...args: unknown[]) => {\n const payload = args[0];\n\n if (isWindowGeometryEvent(payload)) {\n const rect = resizeSession\n ? resizeFromPointer(resizeSession)\n : resizeFromKendoDelta(payload);\n\n lastKendoSize = { width: payload.width, height: payload.height };\n settings.value.left = rect.left;\n settings.value.top = rect.top;\n settings.value.width = rect.width;\n settings.value.height = rect.height;\n isResizing.value = payload.drag && !payload.end;\n\n if (payload.end) {\n endResizeSession();\n }\n\n options.onResize?.({ ...payload, ...rect });\n }\n };\n\n // Kendo Window's resize-handle drag competes with native text-selection\n // dragging unless the handle's pointerdown default is prevented in the\n // capture phase, before Kendo's own listeners and the browser's default\n // selection-drag both react. See docs/design/composable-native-event-listener-tactic.md.\n const handlePointerDown = (event: PointerEvent) => {\n const handle =\n event.target instanceof Element\n ? event.target.closest(\".k-resize-handle\")\n : null;\n\n if (handle) {\n event.preventDefault();\n startResizeSession(event, handle);\n }\n };\n\n const handleTitlebarDoubleClick = (event: MouseEvent) => {\n if (toValue(options.titlebarDoubleClick) !== false) {\n return;\n }\n\n if (\n event.target instanceof Element &&\n event.target.closest(\".k-window-titlebar\")\n ) {\n event.preventDefault();\n event.stopPropagation();\n }\n };\n\n let removePointerDownListener: (() => void) | undefined;\n let removeTitlebarDoubleClickListener: (() => void) | undefined;\n\n const removePointerDownWatcher = () => {\n removePointerDownListener?.();\n removePointerDownListener = undefined;\n };\n\n const removeTitlebarDoubleClickWatcher = () => {\n removeTitlebarDoubleClickListener?.();\n removeTitlebarDoubleClickListener = undefined;\n };\n\n watch(\n windowRef,\n (instance) => {\n removePointerDownWatcher();\n removeTitlebarDoubleClickWatcher();\n // Kendo never emits the final `end` event for a Window unmounted mid-drag/resize.\n endResizeSession();\n isResizing.value = false;\n isDragging.value = false;\n\n const root = instance?.$el;\n\n if (!(root instanceof HTMLElement)) {\n return;\n }\n\n root.addEventListener(\"pointerdown\", handlePointerDown, {\n capture: true,\n });\n removePointerDownListener = () =>\n root.removeEventListener(\"pointerdown\", handlePointerDown, {\n capture: true,\n });\n\n root.addEventListener(\"dblclick\", handleTitlebarDoubleClick, {\n capture: true,\n });\n removeTitlebarDoubleClickListener = () =>\n root.removeEventListener(\"dblclick\", handleTitlebarDoubleClick, {\n capture: true,\n });\n },\n { flush: \"post\" },\n );\n\n onScopeDispose(removePointerDownWatcher);\n onScopeDispose(removeTitlebarDoubleClickWatcher);\n onScopeDispose(endResizeSession);\n\n const windowClass = computed(() => {\n const classes: string[] = [\"fk-window\"];\n\n if (settings.value.draggable && stage.value !== \"FULLSCREEN\") {\n classes.push(\"fk-window-can-drag\");\n }\n if (isDragging.value) {\n classes.push(\"fk-window-is-dragging\");\n }\n if (isResizing.value) {\n classes.push(\"fk-window-is-resizing\");\n }\n if (settings.value.fixed) {\n classes.push(\"fk-window-fixed\");\n }\n // Kendo's Window titlebar buttons render unconditionally; hidden via CSS\n // since minimizeButton/maximizeButton/closable only accept a\n // String|Function template in Kendo's own (buggy) prop types.\n if (!settings.value.minimizeButton) {\n classes.push(\"fk-window-hide-minimize\");\n }\n if (!settings.value.maximizeButton) {\n classes.push(\"fk-window-hide-maximize\");\n }\n if (!settings.value.closable) {\n classes.push(\"fk-window-hide-close\");\n }\n\n return classes.join(\" \");\n });\n\n const props = computed<WindowBindableProps>(() => ({\n title: settings.value.title,\n draggable: settings.value.draggable,\n resizable: settings.value.resizable,\n left: settings.value.left,\n top: settings.value.top,\n initialLeft: initialLeft.value,\n initialTop: initialTop.value,\n initialWidth: settings.value.initialWidth,\n initialHeight: settings.value.initialHeight,\n width: settings.value.width,\n height: settings.value.height,\n minWidth: minWidth.value,\n minHeight: minHeight.value,\n stage: stage.value,\n windowClass: windowClass.value,\n }));\n\n const events: WindowEvents = {\n move: handleMove,\n resize: handleResize,\n stagechange: handleStageChange,\n close: closeWindow,\n };\n\n return {\n windowRef,\n settings,\n visible,\n stage,\n isDragging,\n isResizing,\n props,\n events,\n open,\n close: closeWindow,\n };\n}\n"],"names":["WINDOW_SETTINGS_DEFAULTS","isWindowStage","value","DEFAULT_MIN_WIDTH","DEFAULT_MIN_HEIGHT","RESIZE_DIRECTIONS","clamp","min","max","isWindowGeometryEvent","event","calculateInitialLeft","viewportWidth","windowWidth","rightInset","useWindow","options","isRef","settings","ref","windowRef","shallowRef","visible","stage","isDragging","isResizing","initialLeft","initialTop","minWidth","computed","minHeight","resizeSession","lastKendoSize","getViewportBounds","left","top","getCurrentRect","open","openOptions","hasStoredPosition","rootFontSize","padding","viewportLeft","viewportTop","nextTick","closeWindow","handleStageChange","args","payload","requestedStage","handleMove","windowRoot","titlebarRect","titlebarWidth","titlebarHeight","viewport","maximumLeft","maximumTop","resizeFromPointer","session","direction","start","dx","dy","right","bottom","resizeFromKendoDelta","current","previous","maximumWidth","maximumHeight","trackResizePointer","endResizeSession","releaseResizePointer","startResizeSession","handle","candidate","handleResize","rect","handlePointerDown","handleTitlebarDoubleClick","toValue","removePointerDownListener","removeTitlebarDoubleClickListener","removePointerDownWatcher","removeTitlebarDoubleClickWatcher","watch","instance","root","onScopeDispose","windowClass","classes","props"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";const l=require("vue"),R={title:"My Window",draggable:!0,resizable:!0,closable:!0,fixed:!0,minimizeButton:!0,maximizeButton:!0,initialLeft:void 0,initialTop:void 0,initialWidth:500,initialHeight:500,width:500,height:500,left:void 0,top:void 0},$=n=>n==="DEFAULT"||n==="MINIMIZED"||n==="FULLSCREEN",K=120,V=100,Z=["n","e","s","w","ne","nw","se","sw"],m=(n,t,c)=>Math.min(Math.max(n,t),c),Y=n=>typeof n=="object"&&n!==null&&"drag"in n&&"left"in n&&"top"in n&&"width"in n&&"height"in n&&typeof n.left=="number"&&typeof n.top=="number"&&typeof n.width=="number"&&typeof n.height=="number",J=(n,t,c)=>Math.max(n-t-c,0);function Q(n={}){l.isRef(n.settings)&&(n.settings.value={...R,...n.settings.value});const t=l.isRef(n.settings)?n.settings:l.ref({...R,...n.settings}),c=l.shallowRef(null),p=l.ref(!1),v=l.ref(n.initialStage??"DEFAULT"),b=l.ref(!1),E=l.ref(!1),D=l.ref(0),T=l.ref(0),L=l.computed(()=>t.value.minWidth??K),S=l.computed(()=>t.value.minHeight??V);let d=null,x=null;const W=()=>{const i=t.value.fixed?0:window.scrollX,e=t.value.fixed?0:window.scrollY;return{left:i,top:e,right:i+document.documentElement.clientWidth,bottom:e+document.documentElement.clientHeight}},C=()=>({left:t.value.left??D.value,top:t.value.top??T.value,width:t.value.width??t.value.initialWidth,height:t.value.height??t.value.initialHeight}),P=async i=>{x=null;const e=t.value.left!==void 0&&t.value.top!==void 0;if(i?.resetPosition||!e){const o=Number.parseFloat(window.getComputedStyle(document.documentElement).fontSize),a=Number.isFinite(o)?o:16,r=t.value.fixed?0:window.scrollX,u=t.value.fixed?0:window.scrollY;t.value.left=void 0,t.value.top=void 0,t.value.width=void 0,t.value.height=void 0,D.value=t.value.initialLeft??r+J(window.innerWidth,t.value.initialWidth,a),T.value=t.value.initialTop??u+a,p.value=!0,await l.nextTick(),t.value.width=t.value.initialWidth,t.value.height=t.value.initialHeight}else p.value=!0;n.onOpen?.()},H=()=>{v.value="DEFAULT",p.value=!1,n.onClose?.()},U=(...i)=>{const e=i[2];if(typeof e!="object"||e===null||!("state"in e)||!$(e.state))return;const o=e.state;o!==v.value&&(x=null,v.value=o,n.onStageChange?.(o))},_=(...i)=>{const e=i[0];if(Y(e)){const o=c.value?.$el,r=(o instanceof Element?o.querySelector(".k-window-titlebar"):null)?.getBoundingClientRect(),u=r?.width??e.width,w=r?.height??e.height,s=W(),h=Math.max(s.right-u,s.left),f=Math.max(s.bottom-w,s.top);t.value.left=m(e.left,s.left,h),t.value.top=m(e.top,s.top,f),b.value=e.drag&&!e.end,n.onMove?.(e)}},A=i=>{const{direction:e,start:o}=i,a=W(),r=i.pointerX-i.startX,u=i.pointerY-i.startY;let w=o.left,s=o.top,h=o.left+o.width,f=o.top+o.height;return e.includes("n")&&(s=m(o.top+u,Math.min(a.top,o.top),f-S.value)),e.includes("s")&&(f=m(f+u,s+S.value,Math.max(a.bottom,f))),e.includes("w")&&(w=m(o.left+r,Math.min(a.left,o.left),h-L.value)),e.includes("e")&&(h=m(h+r,w+L.value,Math.max(a.right,h))),{left:w,top:s,width:h-w,height:f-s}},B=i=>{const e=C(),o=x??e,a=W(),r=Math.max(a.right,e.left+e.width)-e.left,u=Math.max(a.bottom,e.top+e.height)-e.top;return{left:e.left,top:e.top,width:Math.max(Math.min(e.width+i.width-o.width,r),L.value),height:Math.max(Math.min(e.height+i.height-o.height,u),S.value)}},I=i=>{d&&(d.pointerX=i.clientX,d.pointerY=i.clientY)},g=()=>{d=null,window.removeEventListener("pointermove",I,!0),window.removeEventListener("pointerup",z,!0),window.removeEventListener("pointercancel",z,!0)};function z(){window.setTimeout(g,0)}const G=(i,e)=>{const o=Z.find(a=>e.classList.contains(`k-resize-${a}`));g(),o&&(d={direction:o,start:C(),startX:i.clientX,startY:i.clientY,pointerX:i.clientX,pointerY:i.clientY},window.addEventListener("pointermove",I,!0),window.addEventListener("pointerup",z,!0),window.addEventListener("pointercancel",z,!0))},O=(...i)=>{const e=i[0];if(Y(e)){const o=d?A(d):B(e);x={width:e.width,height:e.height},t.value.left=o.left,t.value.top=o.top,t.value.width=o.width,t.value.height=o.height,E.value=e.drag&&!e.end,e.end&&g(),n.onResize?.({...e,...o})}},y=i=>{const e=i.target instanceof Element?i.target.closest(".k-resize-handle"):null;e&&(i.preventDefault(),G(i,e))},F=i=>{l.toValue(n.titlebarDoubleClick)===!1&&i.target instanceof Element&&i.target.closest(".k-window-titlebar")&&(i.preventDefault(),i.stopPropagation())};let M,k;const N=()=>{M?.(),M=void 0},X=()=>{k?.(),k=void 0};l.watch(c,i=>{N(),X(),g(),E.value=!1,b.value=!1;const e=i?.$el;e instanceof HTMLElement&&(e.addEventListener("pointerdown",y,{capture:!0}),M=()=>e.removeEventListener("pointerdown",y,{capture:!0}),e.addEventListener("dblclick",F,{capture:!0}),k=()=>e.removeEventListener("dblclick",F,{capture:!0}))},{flush:"post"}),l.onScopeDispose(N),l.onScopeDispose(X),l.onScopeDispose(g);const j=l.computed(()=>{const i=["fk-window"];return t.value.draggable&&v.value!=="FULLSCREEN"&&i.push("fk-window-can-drag"),b.value&&i.push("fk-window-is-dragging"),E.value&&i.push("fk-window-is-resizing"),t.value.fixed&&i.push("fk-window-fixed"),t.value.minimizeButton||i.push("fk-window-hide-minimize"),t.value.maximizeButton||i.push("fk-window-hide-maximize"),t.value.closable||i.push("fk-window-hide-close"),i.join(" ")}),q=l.computed(()=>({title:t.value.title,draggable:t.value.draggable,resizable:t.value.resizable,left:t.value.left,top:t.value.top,initialLeft:D.value,initialTop:T.value,initialWidth:t.value.initialWidth,initialHeight:t.value.initialHeight,width:t.value.width,height:t.value.height,minWidth:L.value,minHeight:S.value,stage:v.value,windowClass:j.value}));return{windowRef:c,settings:t,visible:p,stage:v,isDragging:b,isResizing:E,props:q,events:{move:_,resize:O,stagechange:U,close:H},open:P,close:H}}exports.WINDOW_SETTINGS_DEFAULTS=R;exports.useWindow=Q;
2
+ //# sourceMappingURL=useWindow-Yia2I6zX.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useWindow-Yia2I6zX.cjs","sources":["../../src/window/useWindow.ts"],"sourcesContent":["import {\n computed,\n isRef,\n nextTick,\n onScopeDispose,\n ref,\n shallowRef,\n toValue,\n watch,\n type ComponentPublicInstance,\n type ComputedRef,\n type MaybeRefOrGetter,\n type Ref,\n} from \"vue\";\n\n/** Kendo Window's stage values. Distinct from browser fullscreen APIs. */\nexport type WindowStage = \"DEFAULT\" | \"MINIMIZED\" | \"FULLSCREEN\";\n\nexport interface WindowMoveEventPayload {\n drag: boolean;\n end: boolean;\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\nexport type WindowResizeEventPayload = WindowMoveEventPayload;\n\nexport interface WindowSettings {\n title: string;\n draggable: boolean;\n resizable: boolean;\n /** Hidden via `windowClass`, not a real Kendo prop - see docs \"Inert Props\". */\n closable: boolean;\n fixed: boolean;\n /** Hidden via `windowClass`, not a real Kendo prop - see docs \"Inert Props\". */\n minimizeButton: boolean;\n /** Hidden via `windowClass`, not a real Kendo prop - see docs \"Inert Props\". */\n maximizeButton: boolean;\n initialLeft?: number;\n initialTop?: number;\n initialWidth: number;\n initialHeight: number;\n width?: number;\n height?: number;\n left?: number;\n top?: number;\n /** Minimum resize width in px. Unset/`null` falls back to Kendo's default (120). */\n minWidth?: number | null;\n /** Minimum resize height in px. Unset/`null` falls back to Kendo's default (100). */\n minHeight?: number | null;\n}\n\nexport const WINDOW_SETTINGS_DEFAULTS: WindowSettings = {\n title: \"My Window\",\n draggable: true,\n resizable: true,\n closable: true,\n fixed: true,\n minimizeButton: true,\n maximizeButton: true,\n initialLeft: undefined,\n initialTop: undefined,\n initialWidth: 500,\n initialHeight: 500,\n width: 500,\n height: 500,\n left: undefined,\n top: undefined,\n};\n\nexport interface UseWindowOptions {\n /**\n * Overrides for one or more settings; any field you omit falls back to\n * `WINDOW_SETTINGS_DEFAULTS`, merged internally - you never need to spread\n * the defaults yourself. Pass a `Ref` (e.g. one already wired to your own\n * persistence layer) to have `useWindow` read and mutate it directly\n * instead of creating its own internal ref; missing fields on that ref are\n * filled in from the defaults once, in place, at setup time.\n */\n settings?: Partial<WindowSettings> | Ref<Partial<WindowSettings>>;\n initialStage?: WindowStage;\n /** Enables the native titlebar double-click stage toggle. Defaults to true. */\n titlebarDoubleClick?: MaybeRefOrGetter<boolean>;\n onMove?: (payload: WindowMoveEventPayload) => void;\n onResize?: (payload: WindowResizeEventPayload) => void;\n onStageChange?: (stage: WindowStage) => void;\n onOpen?: () => void;\n onClose?: () => void;\n}\n\n/** The subset of Kendo `Window` props useWindow keeps functional - see docs \"Inert Props\". */\nexport interface WindowBindableProps {\n title: string;\n draggable: boolean;\n resizable: boolean;\n left?: number;\n top?: number;\n initialLeft: number;\n initialTop: number;\n initialWidth: number;\n initialHeight: number;\n width?: number;\n height?: number;\n minWidth: number;\n minHeight: number;\n stage: WindowStage;\n windowClass: string;\n}\n\nexport interface WindowEvents {\n move: (...args: unknown[]) => void;\n resize: (...args: unknown[]) => void;\n stagechange: (...args: unknown[]) => void;\n close: (...args: unknown[]) => void;\n}\n\nexport interface UseWindowOpenOptions {\n /**\n * Discards any existing left/top/width/height (including one restored from\n * an externally-persisted `settings` ref) and recomputes the initial inset\n * position and `initialWidth`/`initialHeight` size. Defaults to `false`, so\n * a previously dragged/resized/persisted position survives close + reopen.\n */\n resetPosition?: boolean;\n}\n\nexport interface UseWindowReturn {\n windowRef: Ref<ComponentPublicInstance | null>;\n settings: Ref<WindowSettings>;\n visible: Ref<boolean>;\n stage: Ref<WindowStage>;\n isDragging: Ref<boolean>;\n isResizing: Ref<boolean>;\n /** Spread via `v-bind` onto `<Window>`. */\n props: ComputedRef<WindowBindableProps>;\n /** Spread via `v-on` onto `<Window>`. */\n events: WindowEvents;\n open: (openOptions?: UseWindowOpenOptions) => Promise<void>;\n close: () => void;\n}\n\nconst isWindowStage = (value: unknown): value is WindowStage =>\n value === \"DEFAULT\" || value === \"MINIMIZED\" || value === \"FULLSCREEN\";\n\n// Mirror Kendo Window's own minWidth/minHeight defaults.\nconst DEFAULT_MIN_WIDTH = 120;\nconst DEFAULT_MIN_HEIGHT = 100;\n\nconst RESIZE_DIRECTIONS = [\"n\", \"e\", \"s\", \"w\", \"ne\", \"nw\", \"se\", \"sw\"];\n\ninterface WindowRect {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\ninterface ResizeSession {\n direction: string;\n start: WindowRect;\n startX: number;\n startY: number;\n pointerX: number;\n pointerY: number;\n}\n\nconst clamp = (value: number, min: number, max: number) =>\n Math.min(Math.max(value, min), max);\n\nconst isWindowGeometryEvent = (\n event: unknown,\n): event is WindowMoveEventPayload =>\n typeof event === \"object\" &&\n event !== null &&\n \"drag\" in event &&\n \"left\" in event &&\n \"top\" in event &&\n \"width\" in event &&\n \"height\" in event &&\n typeof event.left === \"number\" &&\n typeof event.top === \"number\" &&\n typeof event.width === \"number\" &&\n typeof event.height === \"number\";\n\n/**\n * Converts a desired right-edge inset into Kendo Window's `initialLeft`\n * coordinate. Kendo exposes no `initialRight` prop, so positioning from the\n * right must be expressed as a left offset. Clamps to zero when the Window is\n * wider than the available viewport.\n */\nconst calculateInitialLeft = (\n viewportWidth: number,\n windowWidth: number,\n rightInset: number,\n) => Math.max(viewportWidth - windowWidth - rightInset, 0);\n\n/**\n * Wraps Kendo UI for Vue's `Window` component (not the browser `window`\n * object) with zero-config defaults, viewport-clamped dragging, and the\n * pointerdown-capture resize/text-selection workaround from\n * docs/design/composable-native-event-listener-tactic.md.\n */\nexport function useWindow(options: UseWindowOptions = {}): UseWindowReturn {\n // Merge WINDOW_SETTINGS_DEFAULTS into whatever the consumer provided.\n // A Ref is filled in place (preserving its identity, e.g. for persistence);\n // a plain partial object seeds a new internal ref.\n if (isRef(options.settings)) {\n options.settings.value = {\n ...WINDOW_SETTINGS_DEFAULTS,\n ...options.settings.value,\n };\n }\n\n const settings: Ref<WindowSettings> = isRef(options.settings)\n ? (options.settings as Ref<WindowSettings>)\n : ref<WindowSettings>({ ...WINDOW_SETTINGS_DEFAULTS, ...options.settings });\n\n const windowRef = shallowRef<ComponentPublicInstance | null>(null);\n const visible = ref(false);\n const stage = ref<WindowStage>(options.initialStage ?? \"DEFAULT\");\n const isDragging = ref(false);\n const isResizing = ref(false);\n const initialLeft = ref(0);\n const initialTop = ref(0);\n const minWidth = computed(() => settings.value.minWidth ?? DEFAULT_MIN_WIDTH);\n const minHeight = computed(\n () => settings.value.minHeight ?? DEFAULT_MIN_HEIGHT,\n );\n\n let resizeSession: ResizeSession | null = null;\n // Kendo's internal size, which drifts from the clamped settings; keyboard resizes are applied as deltas of it.\n let lastKendoSize: { width: number; height: number } | null = null;\n\n const getViewportBounds = () => {\n const left = settings.value.fixed ? 0 : window.scrollX;\n const top = settings.value.fixed ? 0 : window.scrollY;\n\n return {\n left,\n top,\n right: left + document.documentElement.clientWidth,\n bottom: top + document.documentElement.clientHeight,\n };\n };\n\n const getCurrentRect = (): WindowRect => ({\n left: settings.value.left ?? initialLeft.value,\n top: settings.value.top ?? initialTop.value,\n width: settings.value.width ?? settings.value.initialWidth,\n height: settings.value.height ?? settings.value.initialHeight,\n });\n\n const open = async (openOptions?: UseWindowOpenOptions) => {\n lastKendoSize = null;\n\n // No stored left/top means this is the first-ever open - always compute\n // the initial layout then, regardless of resetPosition.\n const hasStoredPosition =\n settings.value.left !== undefined && settings.value.top !== undefined;\n\n if (openOptions?.resetPosition || !hasStoredPosition) {\n const rootFontSize = Number.parseFloat(\n window.getComputedStyle(document.documentElement).fontSize,\n );\n const padding = Number.isFinite(rootFontSize) ? rootFontSize : 16;\n // Non-fixed Windows position in document coordinates (matching\n // handleMove's viewportLeft/viewportTop), so the inset must account for\n // scroll offset or a scrolled page opens the Window off-screen.\n const viewportLeft = settings.value.fixed ? 0 : window.scrollX;\n const viewportTop = settings.value.fixed ? 0 : window.scrollY;\n\n settings.value.left = undefined;\n settings.value.top = undefined;\n settings.value.width = undefined;\n settings.value.height = undefined;\n initialLeft.value =\n settings.value.initialLeft ??\n viewportLeft +\n calculateInitialLeft(\n window.innerWidth,\n settings.value.initialWidth,\n padding,\n );\n initialTop.value = settings.value.initialTop ?? viewportTop + padding;\n visible.value = true;\n\n await nextTick();\n settings.value.width = settings.value.initialWidth;\n settings.value.height = settings.value.initialHeight;\n } else {\n // Persisted/dragged left, top, width, and height are left untouched -\n // Kendo applies them directly via the controlled left/top/width/height props.\n visible.value = true;\n }\n\n options.onOpen?.();\n };\n\n const closeWindow = () => {\n stage.value = \"DEFAULT\";\n visible.value = false;\n options.onClose?.();\n };\n\n const handleStageChange = (...args: unknown[]) => {\n // Kendo emits (nativeEvent, windowInstance, { state }) at runtime despite\n // its .d.ts typing onStagechange as a single-argument callback.\n const payload = args[2];\n\n if (\n typeof payload !== \"object\" ||\n payload === null ||\n !(\"state\" in payload) ||\n !isWindowStage(payload.state)\n ) {\n return;\n }\n\n const requestedStage = payload.state;\n\n if (requestedStage === stage.value) {\n return;\n }\n\n // Kendo resyncs its internal size to our props on stage transitions.\n lastKendoSize = null;\n stage.value = requestedStage;\n options.onStageChange?.(requestedStage);\n };\n\n const handleMove = (...args: unknown[]) => {\n const payload = args[0];\n\n if (isWindowGeometryEvent(payload)) {\n const windowRoot = windowRef.value?.$el;\n const titlebar =\n windowRoot instanceof Element\n ? windowRoot.querySelector<HTMLElement>(\".k-window-titlebar\")\n : null;\n const titlebarRect = titlebar?.getBoundingClientRect();\n const titlebarWidth = titlebarRect?.width ?? payload.width;\n const titlebarHeight = titlebarRect?.height ?? payload.height;\n const viewport = getViewportBounds();\n const maximumLeft = Math.max(\n viewport.right - titlebarWidth,\n viewport.left,\n );\n const maximumTop = Math.max(\n viewport.bottom - titlebarHeight,\n viewport.top,\n );\n\n settings.value.left = clamp(payload.left, viewport.left, maximumLeft);\n settings.value.top = clamp(payload.top, viewport.top, maximumTop);\n isDragging.value = payload.drag && !payload.end;\n options.onMove?.(payload);\n }\n };\n\n // Kendo snaps edges to the absolute pointer with no viewport bounds, so a\n // pointer resize is derived from our own pointer delta instead.\n const resizeFromPointer = (session: ResizeSession): WindowRect => {\n const { direction, start } = session;\n const viewport = getViewportBounds();\n const dx = session.pointerX - session.startX;\n const dy = session.pointerY - session.startY;\n let left = start.left;\n let top = start.top;\n let right = start.left + start.width;\n let bottom = start.top + start.height;\n\n // Bounds use min/max with the start edge so an already-offscreen edge never snaps back.\n if (direction.includes(\"n\")) {\n top = clamp(\n start.top + dy,\n Math.min(viewport.top, start.top),\n bottom - minHeight.value,\n );\n }\n if (direction.includes(\"s\")) {\n bottom = clamp(\n bottom + dy,\n top + minHeight.value,\n Math.max(viewport.bottom, bottom),\n );\n }\n if (direction.includes(\"w\")) {\n left = clamp(\n start.left + dx,\n Math.min(viewport.left, start.left),\n right - minWidth.value,\n );\n }\n if (direction.includes(\"e\")) {\n right = clamp(\n right + dx,\n left + minWidth.value,\n Math.max(viewport.right, right),\n );\n }\n\n return { left, top, width: right - left, height: bottom - top };\n };\n\n // Keyboard (Ctrl+Arrow) resizes only change size, never left/top.\n const resizeFromKendoDelta = (\n payload: WindowResizeEventPayload,\n ): WindowRect => {\n const current = getCurrentRect();\n const previous = lastKendoSize ?? current;\n const viewport = getViewportBounds();\n const maximumWidth =\n Math.max(viewport.right, current.left + current.width) - current.left;\n const maximumHeight =\n Math.max(viewport.bottom, current.top + current.height) - current.top;\n\n return {\n left: current.left,\n top: current.top,\n width: Math.max(\n Math.min(current.width + payload.width - previous.width, maximumWidth),\n minWidth.value,\n ),\n height: Math.max(\n Math.min(\n current.height + payload.height - previous.height,\n maximumHeight,\n ),\n minHeight.value,\n ),\n };\n };\n\n const trackResizePointer = (event: PointerEvent) => {\n if (resizeSession) {\n resizeSession.pointerX = event.clientX;\n resizeSession.pointerY = event.clientY;\n }\n };\n\n const endResizeSession = () => {\n resizeSession = null;\n window.removeEventListener(\"pointermove\", trackResizePointer, true);\n window.removeEventListener(\"pointerup\", releaseResizePointer, true);\n window.removeEventListener(\"pointercancel\", releaseResizePointer, true);\n };\n\n // Deferred so Kendo's own release (the final `end` resize event) still sees the session.\n function releaseResizePointer() {\n window.setTimeout(endResizeSession, 0);\n }\n\n const startResizeSession = (event: PointerEvent, handle: Element) => {\n const direction = RESIZE_DIRECTIONS.find((candidate) =>\n handle.classList.contains(`k-resize-${candidate}`),\n );\n\n endResizeSession();\n\n if (!direction) {\n return;\n }\n\n resizeSession = {\n direction,\n start: getCurrentRect(),\n startX: event.clientX,\n startY: event.clientY,\n pointerX: event.clientX,\n pointerY: event.clientY,\n };\n // Window capture runs before Kendo's draggable listeners, so the pointer is current when Kendo emits resize.\n window.addEventListener(\"pointermove\", trackResizePointer, true);\n window.addEventListener(\"pointerup\", releaseResizePointer, true);\n window.addEventListener(\"pointercancel\", releaseResizePointer, true);\n };\n\n const handleResize = (...args: unknown[]) => {\n const payload = args[0];\n\n if (isWindowGeometryEvent(payload)) {\n const rect = resizeSession\n ? resizeFromPointer(resizeSession)\n : resizeFromKendoDelta(payload);\n\n lastKendoSize = { width: payload.width, height: payload.height };\n settings.value.left = rect.left;\n settings.value.top = rect.top;\n settings.value.width = rect.width;\n settings.value.height = rect.height;\n isResizing.value = payload.drag && !payload.end;\n\n if (payload.end) {\n endResizeSession();\n }\n\n options.onResize?.({ ...payload, ...rect });\n }\n };\n\n // Kendo Window's resize-handle drag competes with native text-selection\n // dragging unless the handle's pointerdown default is prevented in the\n // capture phase, before Kendo's own listeners and the browser's default\n // selection-drag both react. See docs/design/composable-native-event-listener-tactic.md.\n const handlePointerDown = (event: PointerEvent) => {\n const handle =\n event.target instanceof Element\n ? event.target.closest(\".k-resize-handle\")\n : null;\n\n if (handle) {\n event.preventDefault();\n startResizeSession(event, handle);\n }\n };\n\n const handleTitlebarDoubleClick = (event: MouseEvent) => {\n if (toValue(options.titlebarDoubleClick) !== false) {\n return;\n }\n\n if (\n event.target instanceof Element &&\n event.target.closest(\".k-window-titlebar\")\n ) {\n event.preventDefault();\n event.stopPropagation();\n }\n };\n\n let removePointerDownListener: (() => void) | undefined;\n let removeTitlebarDoubleClickListener: (() => void) | undefined;\n\n const removePointerDownWatcher = () => {\n removePointerDownListener?.();\n removePointerDownListener = undefined;\n };\n\n const removeTitlebarDoubleClickWatcher = () => {\n removeTitlebarDoubleClickListener?.();\n removeTitlebarDoubleClickListener = undefined;\n };\n\n watch(\n windowRef,\n (instance) => {\n removePointerDownWatcher();\n removeTitlebarDoubleClickWatcher();\n // Kendo never emits the final `end` event for a Window unmounted mid-drag/resize.\n endResizeSession();\n isResizing.value = false;\n isDragging.value = false;\n\n const root = instance?.$el;\n\n if (!(root instanceof HTMLElement)) {\n return;\n }\n\n root.addEventListener(\"pointerdown\", handlePointerDown, {\n capture: true,\n });\n removePointerDownListener = () =>\n root.removeEventListener(\"pointerdown\", handlePointerDown, {\n capture: true,\n });\n\n root.addEventListener(\"dblclick\", handleTitlebarDoubleClick, {\n capture: true,\n });\n removeTitlebarDoubleClickListener = () =>\n root.removeEventListener(\"dblclick\", handleTitlebarDoubleClick, {\n capture: true,\n });\n },\n { flush: \"post\" },\n );\n\n onScopeDispose(removePointerDownWatcher);\n onScopeDispose(removeTitlebarDoubleClickWatcher);\n onScopeDispose(endResizeSession);\n\n const windowClass = computed(() => {\n const classes: string[] = [\"fk-window\"];\n\n if (settings.value.draggable && stage.value !== \"FULLSCREEN\") {\n classes.push(\"fk-window-can-drag\");\n }\n if (isDragging.value) {\n classes.push(\"fk-window-is-dragging\");\n }\n if (isResizing.value) {\n classes.push(\"fk-window-is-resizing\");\n }\n if (settings.value.fixed) {\n classes.push(\"fk-window-fixed\");\n }\n // Kendo's Window titlebar buttons render unconditionally; hidden via CSS\n // since minimizeButton/maximizeButton/closable only accept a\n // String|Function template in Kendo's own (buggy) prop types.\n if (!settings.value.minimizeButton) {\n classes.push(\"fk-window-hide-minimize\");\n }\n if (!settings.value.maximizeButton) {\n classes.push(\"fk-window-hide-maximize\");\n }\n if (!settings.value.closable) {\n classes.push(\"fk-window-hide-close\");\n }\n\n return classes.join(\" \");\n });\n\n const props = computed<WindowBindableProps>(() => ({\n title: settings.value.title,\n draggable: settings.value.draggable,\n resizable: settings.value.resizable,\n left: settings.value.left,\n top: settings.value.top,\n initialLeft: initialLeft.value,\n initialTop: initialTop.value,\n initialWidth: settings.value.initialWidth,\n initialHeight: settings.value.initialHeight,\n width: settings.value.width,\n height: settings.value.height,\n minWidth: minWidth.value,\n minHeight: minHeight.value,\n stage: stage.value,\n windowClass: windowClass.value,\n }));\n\n const events: WindowEvents = {\n move: handleMove,\n resize: handleResize,\n stagechange: handleStageChange,\n close: closeWindow,\n };\n\n return {\n windowRef,\n settings,\n visible,\n stage,\n isDragging,\n isResizing,\n props,\n events,\n open,\n close: closeWindow,\n };\n}\n"],"names":["WINDOW_SETTINGS_DEFAULTS","isWindowStage","value","DEFAULT_MIN_WIDTH","DEFAULT_MIN_HEIGHT","RESIZE_DIRECTIONS","clamp","min","max","isWindowGeometryEvent","event","calculateInitialLeft","viewportWidth","windowWidth","rightInset","useWindow","options","isRef","settings","ref","windowRef","shallowRef","visible","stage","isDragging","isResizing","initialLeft","initialTop","minWidth","computed","minHeight","resizeSession","lastKendoSize","getViewportBounds","left","top","getCurrentRect","open","openOptions","hasStoredPosition","rootFontSize","padding","viewportLeft","viewportTop","nextTick","closeWindow","handleStageChange","args","payload","requestedStage","handleMove","windowRoot","titlebarRect","titlebarWidth","titlebarHeight","viewport","maximumLeft","maximumTop","resizeFromPointer","session","direction","start","dx","dy","right","bottom","resizeFromKendoDelta","current","previous","maximumWidth","maximumHeight","trackResizePointer","endResizeSession","releaseResizePointer","startResizeSession","handle","candidate","handleResize","rect","handlePointerDown","handleTitlebarDoubleClick","toValue","removePointerDownListener","removeTitlebarDoubleClickListener","removePointerDownWatcher","removeTitlebarDoubleClickWatcher","watch","instance","root","onScopeDispose","windowClass","classes","props"],"mappings":"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"}
@@ -17,6 +17,9 @@ export declare function useMaskedDateInput(args: {
17
17
  dateFormat?: string;
18
18
  debug?: boolean;
19
19
  }): {
20
+ id: string;
21
+ min: Date;
22
+ max: Date;
20
23
  raw: Ref<string, string>;
21
24
  cursorPos: Ref<number, number>;
22
25
  debugEnabled: Ref<boolean, boolean>;
@@ -38,3 +41,4 @@ export declare function useMaskedDateInput(args: {
38
41
  handleBlur: (event: FocusEvent) => void;
39
42
  initStyling: () => void;
40
43
  };
44
+ export type UseMaskedDateInputReturn = ReturnType<typeof useMaskedDateInput>;
package/dist/date.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./chunks/useMaskedDateInput-wRnYlR3L.cjs");exports.useMaskedDateInput=e.useMaskedDateInput;
2
+ //# sourceMappingURL=date.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
package/dist/date.mjs ADDED
@@ -0,0 +1,5 @@
1
+ import { u as s } from "./chunks/useMaskedDateInput-COOksUM_.mjs";
2
+ export {
3
+ s as useMaskedDateInput
4
+ };
5
+ //# sourceMappingURL=date.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -1,7 +1,7 @@
1
1
  // Generated by scripts/generate-docs-manifest.mjs. Do not edit.
2
2
  export const packageName = "@featherk/composables";
3
3
 
4
- export const version = "0.17.1";
4
+ export const version = "0.18.1";
5
5
 
6
6
  export const paths = {
7
7
  useActiveIdRegistry: "registry/useActiveIdRegistry.md",
@@ -30,29 +30,29 @@ export const paths = {
30
30
  };
31
31
 
32
32
  export const docs = {
33
- useActiveIdRegistry: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/registry/useActiveIdRegistry.md",
34
- useCompositeId: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/id/useCompositeId.md",
35
- useExclusiveGroup: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/registry/useExclusiveGroup.md",
36
- useFieldsetTouchTracker: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/form/useFieldsetTouchTracker.md",
37
- useFieldsetValidationKit: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/form/useFieldsetValidationKit.md",
38
- useGridA11y: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/grid/useGridA11y.md",
39
- useGridActiveFilter: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/grid/useGridActiveFilter.md",
40
- useGridRowAction: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/grid/useGridRowAction.md",
41
- useIntersectionObserver: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/observer/useIntersectionObserver.md",
42
- useMaskedDateInput: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/date/useMaskedDateInput.md",
43
- useMaskedDateRangeInput: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/range/useMaskedDateRangeInput.md",
44
- useMaskedTimeInput: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/time/useMaskedTimeInput.md",
45
- usePopupMenu: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/menu/usePopupMenu.md",
46
- usePopupMenuActivationAnchor: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/menu/usePopupMenuActivationAnchor.md",
47
- usePopupMenuAndActiveIdRegistry: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/menu/usePopupMenuAndActiveIdRegistry.md",
48
- usePopupMenuFocusAndExclusivity: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/menu/usePopupMenuFocusAndExclusivity.md",
49
- usePopupMenuGridOrchestration: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/menu/usePopupMenuGridOrchestration.md",
50
- usePopupMenuSharedInstance: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/menu/usePopupMenuSharedInstance.md",
51
- usePopupMenuUpgrade0130: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/menu/usePopupMenuUpgrade0130.md",
52
- usePopupTrap: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/trap/usePopupTrap.md",
53
- useUSAddress: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/address/useUSAddress.md",
54
- useWindow: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/window/useWindow.md",
55
- useZipTextBox: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.17.1/docs/address/useZipTextBox.md",
33
+ useActiveIdRegistry: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/registry/useActiveIdRegistry.md",
34
+ useCompositeId: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/id/useCompositeId.md",
35
+ useExclusiveGroup: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/registry/useExclusiveGroup.md",
36
+ useFieldsetTouchTracker: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/form/useFieldsetTouchTracker.md",
37
+ useFieldsetValidationKit: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/form/useFieldsetValidationKit.md",
38
+ useGridA11y: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/grid/useGridA11y.md",
39
+ useGridActiveFilter: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/grid/useGridActiveFilter.md",
40
+ useGridRowAction: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/grid/useGridRowAction.md",
41
+ useIntersectionObserver: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/observer/useIntersectionObserver.md",
42
+ useMaskedDateInput: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/date/useMaskedDateInput.md",
43
+ useMaskedDateRangeInput: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/range/useMaskedDateRangeInput.md",
44
+ useMaskedTimeInput: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/time/useMaskedTimeInput.md",
45
+ usePopupMenu: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/menu/usePopupMenu.md",
46
+ usePopupMenuActivationAnchor: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/menu/usePopupMenuActivationAnchor.md",
47
+ usePopupMenuAndActiveIdRegistry: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/menu/usePopupMenuAndActiveIdRegistry.md",
48
+ usePopupMenuFocusAndExclusivity: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/menu/usePopupMenuFocusAndExclusivity.md",
49
+ usePopupMenuGridOrchestration: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/menu/usePopupMenuGridOrchestration.md",
50
+ usePopupMenuSharedInstance: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/menu/usePopupMenuSharedInstance.md",
51
+ usePopupMenuUpgrade0130: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/menu/usePopupMenuUpgrade0130.md",
52
+ usePopupTrap: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/trap/usePopupTrap.md",
53
+ useUSAddress: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/address/useUSAddress.md",
54
+ useWindow: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/window/useWindow.md",
55
+ useZipTextBox: "https://cdn.jsdelivr.net/npm/@featherk/composables@0.18.1/docs/address/useZipTextBox.md",
56
56
  };
57
57
 
58
58
  export const docUrl = (name, host = "https://cdn.jsdelivr.net/npm") =>
package/dist/form.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./chunks/useFieldsetValidationKit-7W1XDbbr.cjs");exports.useFieldsetTouchTracker=e.useFieldsetTouchTracker;exports.useFieldsetValidationKit=e.useFieldsetValidationKit;
2
+ //# sourceMappingURL=form.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
package/dist/form.mjs ADDED
@@ -0,0 +1,6 @@
1
+ import { u as s, a as i } from "./chunks/useFieldsetValidationKit-x0Rh48mE.mjs";
2
+ export {
3
+ s as useFieldsetTouchTracker,
4
+ i as useFieldsetValidationKit
5
+ };
6
+ //# sourceMappingURL=form.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=e=>e==="left"?"right":e==="right"?"left":"center",z=e=>e==="top"?"bottom":e==="bottom"?"top":"center",w=(e,t,i,o)=>{const r=e.left+(i.horizontal==="right"?e.width:i.horizontal==="center"?e.width/2:0),v=e.top+(i.vertical==="bottom"?e.height:i.vertical==="center"?e.height/2:0),m=t?o.horizontal==="right"?t.width:o.horizontal==="center"?t.width/2:0:0,f=t?o.vertical==="bottom"?t.height:o.vertical==="center"?t.height/2:0:0;return{left:r-m,top:v-f}},M=(e,t,i,o)=>t>=o-i?i:Math.min(Math.max(e,i),o-t),x=({anchor:e,popup:t,anchorAlign:i,popupAlign:o,bounds:r,collision:v})=>{const m=w(e,t,i,o);if(!t)return m;let{left:f,top:h}=m;if(v.horizontal==="fit")f=M(f,t.width,r.left,r.right);else{const a=f+t.width-r.right,c=r.left-f;if(a>0||c>0){const l=w(e,t,{horizontal:n(i.horizontal),vertical:i.vertical},{horizontal:n(o.horizontal),vertical:o.vertical}),s=Math.max(a,0)+Math.max(c,0);Math.max(l.left+t.width-r.right,0)+Math.max(r.left-l.left,0)<s&&(f=l.left)}}if(v.vertical==="fit")h=M(h,t.height,r.top,r.bottom);else{const a=h+t.height-r.bottom,c=r.top-h;if(a>0||c>0){const l=w(e,t,{horizontal:i.horizontal,vertical:z(i.vertical)},{horizontal:o.horizontal,vertical:z(o.vertical)}),s=Math.max(a,0)+Math.max(c,0);Math.max(l.top+t.height-r.bottom,0)+Math.max(r.top-l.top,0)<s&&(h=l.top)}}return{left:f,top:h}};exports.computeCollisionOffset=x;
2
+ //# sourceMappingURL=geometry.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geometry.cjs","sources":["../src/geometry/computeCollisionOffset.ts"],"sourcesContent":["/** A corner/center alignment pair, independent of any specific composable. */\nexport type GeometryAlign = {\n horizontal: \"left\" | \"center\" | \"right\";\n vertical: \"top\" | \"center\" | \"bottom\";\n};\n\n/** A rectangular clipping region (viewport or a scrollable container's rect). */\nexport type GeometryBounds = {\n left: number;\n top: number;\n right: number;\n bottom: number;\n};\n\nexport type GeometryCollisionType = \"fit\" | \"flip\";\n\nexport type GeometryCollision = {\n horizontal: GeometryCollisionType;\n vertical: GeometryCollisionType;\n};\n\nexport type ComputeCollisionOffsetInput = {\n /** The anchor rect (or a zero-size point rect for a click/keyboard activation). */\n anchor: DOMRect;\n /** The popup's own measured size, or `null` before it has been measured. */\n popup: DOMRect | null;\n /** Point on the anchor that the popup is positioned from. */\n anchorAlign: GeometryAlign;\n /** Point on the popup that is placed at the computed anchor point. */\n popupAlign: GeometryAlign;\n /** Clipping bounds checked for overflow; same coordinate space as `anchor`. */\n bounds: GeometryBounds;\n /** Per-axis collision behavior applied when the preferred corner overflows. */\n collision: GeometryCollision;\n};\n\nconst flipHorizontal = (\n horizontal: GeometryAlign[\"horizontal\"],\n): GeometryAlign[\"horizontal\"] =>\n horizontal === \"left\" ? \"right\" : horizontal === \"right\" ? \"left\" : \"center\";\n\nconst flipVertical = (\n vertical: GeometryAlign[\"vertical\"],\n): GeometryAlign[\"vertical\"] =>\n vertical === \"top\" ? \"bottom\" : vertical === \"bottom\" ? \"top\" : \"center\";\n\nconst computeCorner = (\n anchor: DOMRect,\n popup: DOMRect | null,\n anchorAlign: GeometryAlign,\n popupAlign: GeometryAlign,\n) => {\n const anchorX =\n anchor.left +\n (anchorAlign.horizontal === \"right\"\n ? anchor.width\n : anchorAlign.horizontal === \"center\"\n ? anchor.width / 2\n : 0);\n const anchorY =\n anchor.top +\n (anchorAlign.vertical === \"bottom\"\n ? anchor.height\n : anchorAlign.vertical === \"center\"\n ? anchor.height / 2\n : 0);\n\n const popupOffsetX = popup\n ? popupAlign.horizontal === \"right\"\n ? popup.width\n : popupAlign.horizontal === \"center\"\n ? popup.width / 2\n : 0\n : 0;\n const popupOffsetY = popup\n ? popupAlign.vertical === \"bottom\"\n ? popup.height\n : popupAlign.vertical === \"center\"\n ? popup.height / 2\n : 0\n : 0;\n\n return { left: anchorX - popupOffsetX, top: anchorY - popupOffsetY };\n};\n\nconst fitAxis = (\n position: number,\n size: number,\n start: number,\n end: number,\n) => {\n if (size >= end - start) return start;\n return Math.min(Math.max(position, start), end - size);\n};\n\n/**\n * Computes a popup's top-left corner from an anchor rect and alignment pair,\n * then applies Kendo-style `fit` or `flip` collision behavior independently\n * on each axis. Fit shifts the popup within bounds without changing sides;\n * flip moves it to the anchor's opposite side only when that reduces overflow.\n *\n * Returns the preferred position when `popup` is `null`, since collision\n * behavior cannot be calculated before the popup has been measured.\n */\nexport const computeCollisionOffset = ({\n anchor,\n popup,\n anchorAlign,\n popupAlign,\n bounds,\n collision,\n}: ComputeCollisionOffsetInput): { left: number; top: number } => {\n const preferred = computeCorner(anchor, popup, anchorAlign, popupAlign);\n if (!popup) return preferred;\n\n let { left, top } = preferred;\n\n if (collision.horizontal === \"fit\") {\n left = fitAxis(left, popup.width, bounds.left, bounds.right);\n } else {\n const overflowsRight = left + popup.width - bounds.right;\n const overflowsLeft = bounds.left - left;\n if (overflowsRight > 0 || overflowsLeft > 0) {\n const flipped = computeCorner(\n anchor,\n popup,\n {\n horizontal: flipHorizontal(anchorAlign.horizontal),\n vertical: anchorAlign.vertical,\n },\n {\n horizontal: flipHorizontal(popupAlign.horizontal),\n vertical: popupAlign.vertical,\n },\n );\n const currentOverflow =\n Math.max(overflowsRight, 0) + Math.max(overflowsLeft, 0);\n const flippedOverflow =\n Math.max(flipped.left + popup.width - bounds.right, 0) +\n Math.max(bounds.left - flipped.left, 0);\n if (flippedOverflow < currentOverflow) left = flipped.left;\n }\n }\n\n if (collision.vertical === \"fit\") {\n top = fitAxis(top, popup.height, bounds.top, bounds.bottom);\n } else {\n const overflowsBottom = top + popup.height - bounds.bottom;\n const overflowsTop = bounds.top - top;\n if (overflowsBottom > 0 || overflowsTop > 0) {\n const flipped = computeCorner(\n anchor,\n popup,\n {\n horizontal: anchorAlign.horizontal,\n vertical: flipVertical(anchorAlign.vertical),\n },\n {\n horizontal: popupAlign.horizontal,\n vertical: flipVertical(popupAlign.vertical),\n },\n );\n const currentOverflow =\n Math.max(overflowsBottom, 0) + Math.max(overflowsTop, 0);\n const flippedOverflow =\n Math.max(flipped.top + popup.height - bounds.bottom, 0) +\n Math.max(bounds.top - flipped.top, 0);\n if (flippedOverflow < currentOverflow) top = flipped.top;\n }\n }\n\n return { left, top };\n};\n"],"names":["flipHorizontal","horizontal","flipVertical","vertical","computeCorner","anchor","popup","anchorAlign","popupAlign","anchorX","anchorY","popupOffsetX","popupOffsetY","fitAxis","position","size","start","end","computeCollisionOffset","bounds","collision","preferred","left","top","overflowsRight","overflowsLeft","flipped","currentOverflow","overflowsBottom","overflowsTop"],"mappings":"gFAoCA,MAAMA,EACJC,GAEAA,IAAe,OAAS,QAAUA,IAAe,QAAU,OAAS,SAEhEC,EACJC,GAEAA,IAAa,MAAQ,SAAWA,IAAa,SAAW,MAAQ,SAE5DC,EAAgB,CACpBC,EACAC,EACAC,EACAC,IACG,CACH,MAAMC,EACJJ,EAAO,MACNE,EAAY,aAAe,QACxBF,EAAO,MACPE,EAAY,aAAe,SACzBF,EAAO,MAAQ,EACf,GACFK,EACJL,EAAO,KACNE,EAAY,WAAa,SACtBF,EAAO,OACPE,EAAY,WAAa,SACvBF,EAAO,OAAS,EAChB,GAEFM,EAAeL,EACjBE,EAAW,aAAe,QACxBF,EAAM,MACNE,EAAW,aAAe,SACxBF,EAAM,MAAQ,EACd,EACJ,EACEM,EAAeN,EACjBE,EAAW,WAAa,SACtBF,EAAM,OACNE,EAAW,WAAa,SACtBF,EAAM,OAAS,EACf,EACJ,EAEJ,MAAO,CAAE,KAAMG,EAAUE,EAAc,IAAKD,EAAUE,CAAA,CACxD,EAEMC,EAAU,CACdC,EACAC,EACAC,EACAC,IAEIF,GAAQE,EAAMD,EAAcA,EACzB,KAAK,IAAI,KAAK,IAAIF,EAAUE,CAAK,EAAGC,EAAMF,CAAI,EAY1CG,EAAyB,CAAC,CACrC,OAAAb,EACA,MAAAC,EACA,YAAAC,EACA,WAAAC,EACA,OAAAW,EACA,UAAAC,CACF,IAAkE,CAChE,MAAMC,EAAYjB,EAAcC,EAAQC,EAAOC,EAAaC,CAAU,EACtE,GAAI,CAACF,EAAO,OAAOe,EAEnB,GAAI,CAAE,KAAAC,EAAM,IAAAC,CAAA,EAAQF,EAEpB,GAAID,EAAU,aAAe,MAC3BE,EAAOT,EAAQS,EAAMhB,EAAM,MAAOa,EAAO,KAAMA,EAAO,KAAK,MACtD,CACL,MAAMK,EAAiBF,EAAOhB,EAAM,MAAQa,EAAO,MAC7CM,EAAgBN,EAAO,KAAOG,EACpC,GAAIE,EAAiB,GAAKC,EAAgB,EAAG,CAC3C,MAAMC,EAAUtB,EACdC,EACAC,EACA,CACE,WAAYN,EAAeO,EAAY,UAAU,EACjD,SAAUA,EAAY,QAAA,EAExB,CACE,WAAYP,EAAeQ,EAAW,UAAU,EAChD,SAAUA,EAAW,QAAA,CACvB,EAEImB,EACJ,KAAK,IAAIH,EAAgB,CAAC,EAAI,KAAK,IAAIC,EAAe,CAAC,EAEvD,KAAK,IAAIC,EAAQ,KAAOpB,EAAM,MAAQa,EAAO,MAAO,CAAC,EACrD,KAAK,IAAIA,EAAO,KAAOO,EAAQ,KAAM,CAAC,EAClBC,IAAiBL,EAAOI,EAAQ,KACxD,CACF,CAEA,GAAIN,EAAU,WAAa,MACzBG,EAAMV,EAAQU,EAAKjB,EAAM,OAAQa,EAAO,IAAKA,EAAO,MAAM,MACrD,CACL,MAAMS,EAAkBL,EAAMjB,EAAM,OAASa,EAAO,OAC9CU,EAAeV,EAAO,IAAMI,EAClC,GAAIK,EAAkB,GAAKC,EAAe,EAAG,CAC3C,MAAMH,EAAUtB,EACdC,EACAC,EACA,CACE,WAAYC,EAAY,WACxB,SAAUL,EAAaK,EAAY,QAAQ,CAAA,EAE7C,CACE,WAAYC,EAAW,WACvB,SAAUN,EAAaM,EAAW,QAAQ,CAAA,CAC5C,EAEImB,EACJ,KAAK,IAAIC,EAAiB,CAAC,EAAI,KAAK,IAAIC,EAAc,CAAC,EAEvD,KAAK,IAAIH,EAAQ,IAAMpB,EAAM,OAASa,EAAO,OAAQ,CAAC,EACtD,KAAK,IAAIA,EAAO,IAAMO,EAAQ,IAAK,CAAC,EAChBC,IAAiBJ,EAAMG,EAAQ,IACvD,CACF,CAEA,MAAO,CAAE,KAAAJ,EAAM,IAAAC,CAAA,CACjB"}
@@ -0,0 +1,60 @@
1
+ const z = (e) => e === "left" ? "right" : e === "right" ? "left" : "center", x = (e) => e === "top" ? "bottom" : e === "bottom" ? "top" : "center", s = (e, t, r, o) => {
2
+ const i = e.left + (r.horizontal === "right" ? e.width : r.horizontal === "center" ? e.width / 2 : 0), v = e.top + (r.vertical === "bottom" ? e.height : r.vertical === "center" ? e.height / 2 : 0), m = t ? o.horizontal === "right" ? t.width : o.horizontal === "center" ? t.width / 2 : 0 : 0, f = t ? o.vertical === "bottom" ? t.height : o.vertical === "center" ? t.height / 2 : 0 : 0;
3
+ return { left: i - m, top: v - f };
4
+ }, n = (e, t, r, o) => t >= o - r ? r : Math.min(Math.max(e, r), o - t), O = ({
5
+ anchor: e,
6
+ popup: t,
7
+ anchorAlign: r,
8
+ popupAlign: o,
9
+ bounds: i,
10
+ collision: v
11
+ }) => {
12
+ const m = s(e, t, r, o);
13
+ if (!t) return m;
14
+ let { left: f, top: h } = m;
15
+ if (v.horizontal === "fit")
16
+ f = n(f, t.width, i.left, i.right);
17
+ else {
18
+ const a = f + t.width - i.right, c = i.left - f;
19
+ if (a > 0 || c > 0) {
20
+ const l = s(
21
+ e,
22
+ t,
23
+ {
24
+ horizontal: z(r.horizontal),
25
+ vertical: r.vertical
26
+ },
27
+ {
28
+ horizontal: z(o.horizontal),
29
+ vertical: o.vertical
30
+ }
31
+ ), w = Math.max(a, 0) + Math.max(c, 0);
32
+ Math.max(l.left + t.width - i.right, 0) + Math.max(i.left - l.left, 0) < w && (f = l.left);
33
+ }
34
+ }
35
+ if (v.vertical === "fit")
36
+ h = n(h, t.height, i.top, i.bottom);
37
+ else {
38
+ const a = h + t.height - i.bottom, c = i.top - h;
39
+ if (a > 0 || c > 0) {
40
+ const l = s(
41
+ e,
42
+ t,
43
+ {
44
+ horizontal: r.horizontal,
45
+ vertical: x(r.vertical)
46
+ },
47
+ {
48
+ horizontal: o.horizontal,
49
+ vertical: x(o.vertical)
50
+ }
51
+ ), w = Math.max(a, 0) + Math.max(c, 0);
52
+ Math.max(l.top + t.height - i.bottom, 0) + Math.max(i.top - l.top, 0) < w && (h = l.top);
53
+ }
54
+ }
55
+ return { left: f, top: h };
56
+ };
57
+ export {
58
+ O as computeCollisionOffset
59
+ };
60
+ //# sourceMappingURL=geometry.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geometry.mjs","sources":["../src/geometry/computeCollisionOffset.ts"],"sourcesContent":["/** A corner/center alignment pair, independent of any specific composable. */\nexport type GeometryAlign = {\n horizontal: \"left\" | \"center\" | \"right\";\n vertical: \"top\" | \"center\" | \"bottom\";\n};\n\n/** A rectangular clipping region (viewport or a scrollable container's rect). */\nexport type GeometryBounds = {\n left: number;\n top: number;\n right: number;\n bottom: number;\n};\n\nexport type GeometryCollisionType = \"fit\" | \"flip\";\n\nexport type GeometryCollision = {\n horizontal: GeometryCollisionType;\n vertical: GeometryCollisionType;\n};\n\nexport type ComputeCollisionOffsetInput = {\n /** The anchor rect (or a zero-size point rect for a click/keyboard activation). */\n anchor: DOMRect;\n /** The popup's own measured size, or `null` before it has been measured. */\n popup: DOMRect | null;\n /** Point on the anchor that the popup is positioned from. */\n anchorAlign: GeometryAlign;\n /** Point on the popup that is placed at the computed anchor point. */\n popupAlign: GeometryAlign;\n /** Clipping bounds checked for overflow; same coordinate space as `anchor`. */\n bounds: GeometryBounds;\n /** Per-axis collision behavior applied when the preferred corner overflows. */\n collision: GeometryCollision;\n};\n\nconst flipHorizontal = (\n horizontal: GeometryAlign[\"horizontal\"],\n): GeometryAlign[\"horizontal\"] =>\n horizontal === \"left\" ? \"right\" : horizontal === \"right\" ? \"left\" : \"center\";\n\nconst flipVertical = (\n vertical: GeometryAlign[\"vertical\"],\n): GeometryAlign[\"vertical\"] =>\n vertical === \"top\" ? \"bottom\" : vertical === \"bottom\" ? \"top\" : \"center\";\n\nconst computeCorner = (\n anchor: DOMRect,\n popup: DOMRect | null,\n anchorAlign: GeometryAlign,\n popupAlign: GeometryAlign,\n) => {\n const anchorX =\n anchor.left +\n (anchorAlign.horizontal === \"right\"\n ? anchor.width\n : anchorAlign.horizontal === \"center\"\n ? anchor.width / 2\n : 0);\n const anchorY =\n anchor.top +\n (anchorAlign.vertical === \"bottom\"\n ? anchor.height\n : anchorAlign.vertical === \"center\"\n ? anchor.height / 2\n : 0);\n\n const popupOffsetX = popup\n ? popupAlign.horizontal === \"right\"\n ? popup.width\n : popupAlign.horizontal === \"center\"\n ? popup.width / 2\n : 0\n : 0;\n const popupOffsetY = popup\n ? popupAlign.vertical === \"bottom\"\n ? popup.height\n : popupAlign.vertical === \"center\"\n ? popup.height / 2\n : 0\n : 0;\n\n return { left: anchorX - popupOffsetX, top: anchorY - popupOffsetY };\n};\n\nconst fitAxis = (\n position: number,\n size: number,\n start: number,\n end: number,\n) => {\n if (size >= end - start) return start;\n return Math.min(Math.max(position, start), end - size);\n};\n\n/**\n * Computes a popup's top-left corner from an anchor rect and alignment pair,\n * then applies Kendo-style `fit` or `flip` collision behavior independently\n * on each axis. Fit shifts the popup within bounds without changing sides;\n * flip moves it to the anchor's opposite side only when that reduces overflow.\n *\n * Returns the preferred position when `popup` is `null`, since collision\n * behavior cannot be calculated before the popup has been measured.\n */\nexport const computeCollisionOffset = ({\n anchor,\n popup,\n anchorAlign,\n popupAlign,\n bounds,\n collision,\n}: ComputeCollisionOffsetInput): { left: number; top: number } => {\n const preferred = computeCorner(anchor, popup, anchorAlign, popupAlign);\n if (!popup) return preferred;\n\n let { left, top } = preferred;\n\n if (collision.horizontal === \"fit\") {\n left = fitAxis(left, popup.width, bounds.left, bounds.right);\n } else {\n const overflowsRight = left + popup.width - bounds.right;\n const overflowsLeft = bounds.left - left;\n if (overflowsRight > 0 || overflowsLeft > 0) {\n const flipped = computeCorner(\n anchor,\n popup,\n {\n horizontal: flipHorizontal(anchorAlign.horizontal),\n vertical: anchorAlign.vertical,\n },\n {\n horizontal: flipHorizontal(popupAlign.horizontal),\n vertical: popupAlign.vertical,\n },\n );\n const currentOverflow =\n Math.max(overflowsRight, 0) + Math.max(overflowsLeft, 0);\n const flippedOverflow =\n Math.max(flipped.left + popup.width - bounds.right, 0) +\n Math.max(bounds.left - flipped.left, 0);\n if (flippedOverflow < currentOverflow) left = flipped.left;\n }\n }\n\n if (collision.vertical === \"fit\") {\n top = fitAxis(top, popup.height, bounds.top, bounds.bottom);\n } else {\n const overflowsBottom = top + popup.height - bounds.bottom;\n const overflowsTop = bounds.top - top;\n if (overflowsBottom > 0 || overflowsTop > 0) {\n const flipped = computeCorner(\n anchor,\n popup,\n {\n horizontal: anchorAlign.horizontal,\n vertical: flipVertical(anchorAlign.vertical),\n },\n {\n horizontal: popupAlign.horizontal,\n vertical: flipVertical(popupAlign.vertical),\n },\n );\n const currentOverflow =\n Math.max(overflowsBottom, 0) + Math.max(overflowsTop, 0);\n const flippedOverflow =\n Math.max(flipped.top + popup.height - bounds.bottom, 0) +\n Math.max(bounds.top - flipped.top, 0);\n if (flippedOverflow < currentOverflow) top = flipped.top;\n }\n }\n\n return { left, top };\n};\n"],"names":["flipHorizontal","horizontal","flipVertical","vertical","computeCorner","anchor","popup","anchorAlign","popupAlign","anchorX","anchorY","popupOffsetX","popupOffsetY","fitAxis","position","size","start","end","computeCollisionOffset","bounds","collision","preferred","left","top","overflowsRight","overflowsLeft","flipped","currentOverflow","overflowsBottom","overflowsTop"],"mappings":"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"}
package/dist/grid.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./chunks/useGridRowAction-Di25yeqb.cjs");exports.useGridA11y=e.useGridA11y;exports.useGridActiveFilter=e.useGridActiveFilter;exports.useGridRowAction=e.useGridRowAction;
2
+ //# sourceMappingURL=grid.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grid.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}