@helpwave/hightide 0.1.27 → 0.1.28

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 (134) hide show
  1. package/dist/coloring/index.d.mts +2 -0
  2. package/dist/coloring/index.d.ts +2 -0
  3. package/dist/coloring/index.js +85 -0
  4. package/dist/coloring/index.js.map +1 -0
  5. package/dist/coloring/index.mjs +48 -0
  6. package/dist/coloring/index.mjs.map +1 -0
  7. package/dist/components/branding/index.d.mts +3 -0
  8. package/dist/components/branding/index.d.ts +3 -0
  9. package/dist/components/branding/index.js +140 -0
  10. package/dist/components/branding/index.js.map +1 -0
  11. package/dist/components/branding/index.mjs +104 -0
  12. package/dist/components/branding/index.mjs.map +1 -0
  13. package/dist/components/date/index.d.mts +10 -0
  14. package/dist/components/date/index.d.ts +10 -0
  15. package/dist/components/date/index.js +1168 -0
  16. package/dist/components/date/index.js.map +1 -0
  17. package/dist/components/date/index.mjs +1124 -0
  18. package/dist/components/date/index.mjs.map +1 -0
  19. package/dist/components/dialog/index.js.map +1 -1
  20. package/dist/components/form/index.d.mts +5 -0
  21. package/dist/components/form/index.d.ts +5 -0
  22. package/dist/components/form/index.js +100 -0
  23. package/dist/components/form/index.js.map +1 -0
  24. package/dist/components/form/index.mjs +64 -0
  25. package/dist/components/form/index.mjs.map +1 -0
  26. package/dist/components/icons-and-geometry/index.d.mts +7 -0
  27. package/dist/components/icons-and-geometry/index.d.ts +7 -0
  28. package/dist/components/icons-and-geometry/index.js +3955 -0
  29. package/dist/components/icons-and-geometry/index.js.map +1 -0
  30. package/dist/components/icons-and-geometry/index.mjs +3939 -0
  31. package/dist/components/icons-and-geometry/index.mjs.map +1 -0
  32. package/dist/components/index.d.mts +83 -0
  33. package/dist/components/index.d.ts +83 -0
  34. package/dist/components/index.js +15471 -0
  35. package/dist/components/index.js.map +1 -0
  36. package/dist/components/index.mjs +15377 -0
  37. package/dist/components/index.mjs.map +1 -0
  38. package/dist/components/layout/index.d.mts +18 -0
  39. package/dist/components/layout/index.d.ts +18 -0
  40. package/dist/components/layout/index.js +3111 -0
  41. package/dist/components/layout/index.js.map +1 -0
  42. package/dist/components/layout/index.mjs +3064 -0
  43. package/dist/components/layout/index.mjs.map +1 -0
  44. package/dist/components/loading-states/index.d.mts +12 -0
  45. package/dist/components/loading-states/index.d.ts +12 -0
  46. package/dist/components/loading-states/index.js +614 -0
  47. package/dist/components/loading-states/index.js.map +1 -0
  48. package/dist/components/loading-states/index.mjs +573 -0
  49. package/dist/components/loading-states/index.mjs.map +1 -0
  50. package/dist/components/navigation/index.d.mts +9 -0
  51. package/dist/components/navigation/index.d.ts +9 -0
  52. package/dist/components/navigation/index.js +4660 -0
  53. package/dist/components/navigation/index.js.map +1 -0
  54. package/dist/components/navigation/index.mjs +4648 -0
  55. package/dist/components/navigation/index.mjs.map +1 -0
  56. package/dist/components/properties/index.d.mts +12 -0
  57. package/dist/components/properties/index.d.ts +12 -0
  58. package/dist/components/properties/index.js +2983 -0
  59. package/dist/components/properties/index.js.map +1 -0
  60. package/dist/components/properties/index.mjs +2951 -0
  61. package/dist/components/properties/index.mjs.map +1 -0
  62. package/dist/components/table/index.d.mts +10 -0
  63. package/dist/components/table/index.d.ts +10 -0
  64. package/dist/components/table/index.js +2329 -0
  65. package/dist/components/table/index.js.map +1 -0
  66. package/dist/components/table/index.mjs +2293 -0
  67. package/dist/components/table/index.mjs.map +1 -0
  68. package/dist/components/user-action/index.d.mts +30 -0
  69. package/dist/components/user-action/index.d.ts +30 -0
  70. package/dist/components/user-action/index.js +4257 -0
  71. package/dist/components/user-action/index.js.map +1 -0
  72. package/dist/components/user-action/index.mjs +4195 -0
  73. package/dist/components/user-action/index.mjs.map +1 -0
  74. package/dist/components/user-action/input/index.d.mts +6 -0
  75. package/dist/components/user-action/input/index.d.ts +6 -0
  76. package/dist/components/user-action/input/index.js +398 -0
  77. package/dist/components/user-action/input/index.js.map +1 -0
  78. package/dist/components/user-action/input/index.mjs +357 -0
  79. package/dist/components/user-action/input/index.mjs.map +1 -0
  80. package/dist/components/user-action/select/index.d.mts +4 -0
  81. package/dist/components/user-action/select/index.d.ts +4 -0
  82. package/dist/components/user-action/select/index.js +1369 -0
  83. package/dist/components/user-action/select/index.js.map +1 -0
  84. package/dist/components/user-action/select/index.mjs +1333 -0
  85. package/dist/components/user-action/select/index.mjs.map +1 -0
  86. package/dist/components/utils/index.d.mts +4 -0
  87. package/dist/components/utils/index.d.ts +4 -0
  88. package/dist/components/utils/index.js +302 -0
  89. package/dist/components/utils/index.js.map +1 -0
  90. package/dist/components/utils/index.mjs +275 -0
  91. package/dist/components/utils/index.mjs.map +1 -0
  92. package/dist/hooks/focus/index.d.mts +6 -0
  93. package/dist/hooks/focus/index.d.ts +6 -0
  94. package/dist/hooks/focus/index.js +379 -0
  95. package/dist/hooks/focus/index.js.map +1 -0
  96. package/dist/hooks/focus/index.mjs +339 -0
  97. package/dist/hooks/focus/index.mjs.map +1 -0
  98. package/dist/hooks/index.d.mts +16 -0
  99. package/dist/hooks/index.d.ts +16 -0
  100. package/dist/hooks/index.js +844 -0
  101. package/dist/hooks/index.js.map +1 -0
  102. package/dist/hooks/index.mjs +794 -0
  103. package/dist/hooks/index.mjs.map +1 -0
  104. package/dist/index.d.mts +110 -0
  105. package/dist/index.d.ts +110 -0
  106. package/dist/index.js +16101 -0
  107. package/dist/index.js.map +1 -0
  108. package/dist/index.mjs +15941 -0
  109. package/dist/index.mjs.map +1 -0
  110. package/dist/localization/defaults/index.d.mts +4 -0
  111. package/dist/localization/defaults/index.d.ts +4 -0
  112. package/dist/localization/defaults/index.js +223 -0
  113. package/dist/localization/defaults/index.js.map +1 -0
  114. package/dist/localization/defaults/index.mjs +195 -0
  115. package/dist/localization/defaults/index.mjs.map +1 -0
  116. package/dist/localization/index.d.mts +7 -0
  117. package/dist/localization/index.d.ts +7 -0
  118. package/dist/localization/index.js +415 -0
  119. package/dist/localization/index.js.map +1 -0
  120. package/dist/localization/index.mjs +380 -0
  121. package/dist/localization/index.mjs.map +1 -0
  122. package/dist/theming/index.d.mts +5 -0
  123. package/dist/theming/index.d.ts +5 -0
  124. package/dist/theming/index.js +174 -0
  125. package/dist/theming/index.js.map +1 -0
  126. package/dist/theming/index.mjs +145 -0
  127. package/dist/theming/index.mjs.map +1 -0
  128. package/dist/utils/index.d.mts +15 -0
  129. package/dist/utils/index.d.ts +15 -0
  130. package/dist/utils/index.js +553 -0
  131. package/dist/utils/index.js.map +1 -0
  132. package/dist/utils/index.mjs +493 -0
  133. package/dist/utils/index.mjs.map +1 -0
  134. package/package.json +25 -24
@@ -0,0 +1,794 @@
1
+ // src/hooks/focus/useFocusGuards.ts
2
+ import { useEffect } from "react";
3
+ var selectorName = "data-hw-focus-guard";
4
+ function FocusGuard() {
5
+ const element = document.createElement("div");
6
+ element.setAttribute(selectorName, "");
7
+ element.tabIndex = 0;
8
+ element.style.border = "none";
9
+ element.style.outline = "none";
10
+ element.style.boxShadow = "none";
11
+ element.style.opacity = "0";
12
+ element.style.position = "fixed";
13
+ element.style.pointerEvents = "none";
14
+ return element;
15
+ }
16
+ var FocusGuardsService = class _FocusGuardsService {
17
+ constructor() {
18
+ this.count = 0;
19
+ }
20
+ static getInstance() {
21
+ if (!_FocusGuardsService.instance) {
22
+ _FocusGuardsService.instance = new _FocusGuardsService();
23
+ }
24
+ return _FocusGuardsService.instance;
25
+ }
26
+ add() {
27
+ const edgeGuards = document.querySelectorAll(`[${selectorName}]`);
28
+ document.body.insertAdjacentElement("afterbegin", edgeGuards[0] ?? FocusGuard());
29
+ document.body.insertAdjacentElement("beforeend", edgeGuards[1] ?? FocusGuard());
30
+ this.count++;
31
+ }
32
+ remove() {
33
+ if (this.count === 1) {
34
+ document.querySelectorAll(`[${selectorName}]`).forEach((node) => node.remove());
35
+ }
36
+ this.count--;
37
+ }
38
+ };
39
+ var useFocusGuards = () => {
40
+ useEffect(() => {
41
+ FocusGuardsService.getInstance().add();
42
+ return () => {
43
+ FocusGuardsService.getInstance().remove();
44
+ };
45
+ }, []);
46
+ };
47
+
48
+ // src/hooks/focus/useFocusManagement.ts
49
+ import { useCallback } from "react";
50
+ function useFocusManagement() {
51
+ const getFocusableElements = useCallback(() => {
52
+ return Array.from(
53
+ document.querySelectorAll(
54
+ 'input, button, select, textarea, a[href], [tabindex]:not([tabindex="-1"])'
55
+ )
56
+ ).filter(
57
+ (el) => el instanceof HTMLElement && !el.hasAttribute("disabled") && !el.hasAttribute("hidden") && el.tabIndex !== -1
58
+ );
59
+ }, []);
60
+ const getNextFocusElement = useCallback(() => {
61
+ const elements = getFocusableElements();
62
+ if (elements.length === 0) {
63
+ return void 0;
64
+ }
65
+ let nextElement = elements[0];
66
+ if (document.activeElement instanceof HTMLElement) {
67
+ const currentIndex = elements.indexOf(document.activeElement);
68
+ nextElement = elements[(currentIndex + 1) % elements.length];
69
+ }
70
+ return nextElement;
71
+ }, [getFocusableElements]);
72
+ const focusNext = useCallback(() => {
73
+ const nextElement = getNextFocusElement();
74
+ nextElement?.focus();
75
+ }, [getNextFocusElement]);
76
+ const getPreviousFocusElement = useCallback(() => {
77
+ const elements = getFocusableElements();
78
+ if (elements.length === 0) {
79
+ return void 0;
80
+ }
81
+ let previousElement = elements[0];
82
+ if (document.activeElement instanceof HTMLElement) {
83
+ const currentIndex = elements.indexOf(document.activeElement);
84
+ if (currentIndex === 0) {
85
+ previousElement = elements[elements.length - 1];
86
+ } else {
87
+ previousElement = elements[currentIndex - 1];
88
+ }
89
+ }
90
+ return previousElement;
91
+ }, [getFocusableElements]);
92
+ const focusPrevious = useCallback(() => {
93
+ const previousElement = getPreviousFocusElement();
94
+ if (previousElement) previousElement.focus();
95
+ }, [getPreviousFocusElement]);
96
+ return {
97
+ getFocusableElements,
98
+ getNextFocusElement,
99
+ getPreviousFocusElement,
100
+ focusNext,
101
+ focusPrevious
102
+ };
103
+ }
104
+
105
+ // src/hooks/focus/useFocusOnceVisible.ts
106
+ import React, { useEffect as useEffect2 } from "react";
107
+ var useFocusOnceVisible = (ref, disable = false) => {
108
+ const [hasUsedFocus, setHasUsedFocus] = React.useState(false);
109
+ useEffect2(() => {
110
+ if (disable || hasUsedFocus) {
111
+ return;
112
+ }
113
+ const observer = new IntersectionObserver(([entry]) => {
114
+ if (entry.isIntersecting && !hasUsedFocus) {
115
+ ref.current?.focus();
116
+ setHasUsedFocus(hasUsedFocus);
117
+ }
118
+ }, {
119
+ threshold: 0.1
120
+ });
121
+ if (ref.current) {
122
+ observer.observe(ref.current);
123
+ }
124
+ return () => observer.disconnect();
125
+ }, [disable, hasUsedFocus, ref]);
126
+ };
127
+
128
+ // src/hooks/focus/useFocusTrap.ts
129
+ import { useCallback as useCallback2, useEffect as useEffect4, useId, useRef, useState as useState2 } from "react";
130
+
131
+ // src/hooks/focus/useIsMounted.ts
132
+ import { useEffect as useEffect3, useLayoutEffect, useState } from "react";
133
+ var isClient = typeof window !== "undefined" && typeof document !== "undefined";
134
+ var useIsomorphicEffect = isClient ? useLayoutEffect : useEffect3;
135
+ var useIsMounted = () => {
136
+ const [isMounted, setIsMounted] = useState(false);
137
+ useIsomorphicEffect(() => {
138
+ setIsMounted(true);
139
+ return () => {
140
+ setIsMounted(false);
141
+ };
142
+ }, []);
143
+ return isMounted;
144
+ };
145
+
146
+ // src/hooks/focus/useFocusTrap.ts
147
+ var createFocusGuard = () => {
148
+ const div = document.createElement("div");
149
+ Object.assign(div.style, {
150
+ opacity: "0",
151
+ outline: "none",
152
+ boxShadow: "none",
153
+ position: "fixed",
154
+ pointerEvents: "none",
155
+ touchAction: "none"
156
+ });
157
+ div.tabIndex = 0;
158
+ div.setAttribute("data-hw-focus-guard", "");
159
+ document.body.appendChild(div);
160
+ return div;
161
+ };
162
+ function getContainedFocusableElements(element) {
163
+ return element?.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
164
+ }
165
+ var FocusTrapService = class {
166
+ constructor() {
167
+ // The last entry is always the active one
168
+ this.listeners = [];
169
+ this.onFocusIn = (event) => {
170
+ const active = this.getActive();
171
+ if (!active || !active.container.current) return;
172
+ const { container } = active;
173
+ if (!container.current.contains(event.target)) {
174
+ this.focusElement();
175
+ }
176
+ };
177
+ }
178
+ getActive() {
179
+ if (this.listeners.length === 0) return void 0;
180
+ return this.listeners[this.listeners.length - 1];
181
+ }
182
+ focusElement() {
183
+ const active = this.getActive();
184
+ if (!active) return;
185
+ const { container, initialFocusElement } = active;
186
+ const containerElement = container.current;
187
+ if (initialFocusElement?.current) {
188
+ initialFocusElement.current.focus();
189
+ } else {
190
+ const elements = getContainedFocusableElements(containerElement);
191
+ if (elements && elements.length > 0) {
192
+ const first = elements.item(0);
193
+ first.focus();
194
+ } else {
195
+ containerElement.focus();
196
+ }
197
+ }
198
+ }
199
+ removeGuards() {
200
+ document.querySelectorAll("[data-hw-focus-guard]").forEach((node) => node.remove());
201
+ }
202
+ addGuards() {
203
+ document.body.insertAdjacentElement("afterbegin", createFocusGuard());
204
+ document.body.insertAdjacentElement("beforeend", createFocusGuard());
205
+ }
206
+ activate() {
207
+ document.addEventListener("focusin", this.onFocusIn);
208
+ this.addGuards();
209
+ }
210
+ deactivate() {
211
+ document.removeEventListener("focusin", this.onFocusIn);
212
+ this.removeGuards();
213
+ }
214
+ register(listener) {
215
+ this.listeners.push(listener);
216
+ if (this.listeners.length === 1) {
217
+ this.activate();
218
+ }
219
+ const active = listener;
220
+ this.listeners.forEach((listener2) => {
221
+ const { focus, pause } = listener2;
222
+ if (listener2 === active) {
223
+ focus();
224
+ } else {
225
+ pause();
226
+ }
227
+ });
228
+ }
229
+ unregister(id) {
230
+ const index = this.listeners.findIndex((trap) => trap.id === id);
231
+ if (index !== -1) {
232
+ const isActive = index === this.listeners.length - 1;
233
+ const listener = this.listeners[index];
234
+ this.listeners = this.listeners.filter((listener2) => listener2.id !== id);
235
+ if (isActive) {
236
+ this.deactivate();
237
+ listener.focusLast();
238
+ const active = this.getActive();
239
+ this.listeners.forEach((listener2) => {
240
+ const { pause, unpause } = listener2;
241
+ if (listener2 === active) {
242
+ unpause();
243
+ } else {
244
+ pause();
245
+ }
246
+ });
247
+ if (this.listeners.length > 0) {
248
+ this.activate();
249
+ }
250
+ }
251
+ } else {
252
+ console.warn(`Unable to unregister id ${id}: not found`);
253
+ }
254
+ }
255
+ };
256
+ var service = new FocusTrapService();
257
+ var useFocusTrap = ({
258
+ container,
259
+ active = true,
260
+ initialFocus,
261
+ focusFirst = true
262
+ }) => {
263
+ const lastFocusRef = useRef(null);
264
+ const [paused, setPaused] = useState2(false);
265
+ const isMounted = useIsMounted();
266
+ const id = useId();
267
+ const focusElement = useCallback2(() => {
268
+ const containerElement = container.current;
269
+ if (initialFocus?.current) {
270
+ initialFocus.current.focus();
271
+ } else {
272
+ const elements = getContainedFocusableElements(containerElement);
273
+ if (elements && elements.length > 0) {
274
+ const first = elements.item(0);
275
+ first.focus();
276
+ } else {
277
+ containerElement.focus();
278
+ }
279
+ }
280
+ }, [container, initialFocus]);
281
+ useEffect4(() => {
282
+ if (active && isMounted) {
283
+ let pause = function() {
284
+ setPaused(true);
285
+ }, unpause = function() {
286
+ setPaused(false);
287
+ if (!container.current.contains(document.activeElement)) {
288
+ focusElement();
289
+ }
290
+ }, focus = function() {
291
+ focusElement();
292
+ setPaused(false);
293
+ }, focusLast = function() {
294
+ lastFocusRef.current?.focus();
295
+ };
296
+ if (!lastFocusRef.current) {
297
+ lastFocusRef.current = document.activeElement;
298
+ }
299
+ service.register({ id, pause, focus, focusLast, unpause, container, initialFocusElement: initialFocus });
300
+ return () => {
301
+ service.unregister(id);
302
+ lastFocusRef.current = void 0;
303
+ };
304
+ }
305
+ }, [active, container, focusElement, id, initialFocus, isMounted]);
306
+ useEffect4(() => {
307
+ if (active && !paused && isMounted) {
308
+ let onKeyDown = function(event) {
309
+ const key = event.key;
310
+ const elements = getContainedFocusableElements(containerElement);
311
+ const active2 = document.activeElement;
312
+ const index = [...elements].findIndex((value) => value === active2);
313
+ if (index === -1 || event.altKey || event.ctrlKey || event.metaKey) {
314
+ return;
315
+ }
316
+ if (key === "Tab") {
317
+ const next = event.shiftKey ? -1 : 1;
318
+ const nextIndex = (index + next + elements.length) % elements.length;
319
+ const nextElement = elements[nextIndex];
320
+ nextElement.focus();
321
+ event.preventDefault();
322
+ }
323
+ };
324
+ const containerElement = container.current;
325
+ containerElement.addEventListener("keydown", onKeyDown);
326
+ return () => {
327
+ containerElement.removeEventListener("keydown", onKeyDown);
328
+ };
329
+ }
330
+ }, [active, paused, isMounted, container, initialFocus, focusFirst, focusElement]);
331
+ };
332
+
333
+ // src/hooks/useDelay.ts
334
+ import { useEffect as useEffect5, useState as useState3 } from "react";
335
+ var defaultOptions = {
336
+ delay: 3e3,
337
+ disabled: false
338
+ };
339
+ function useDelay(options) {
340
+ const [timer, setTimer] = useState3(void 0);
341
+ const { delay, disabled } = {
342
+ ...defaultOptions,
343
+ ...options
344
+ };
345
+ const clearTimer = () => {
346
+ clearTimeout(timer);
347
+ setTimer(void 0);
348
+ };
349
+ const restartTimer = (onDelayFinish) => {
350
+ if (disabled) {
351
+ return;
352
+ }
353
+ clearTimeout(timer);
354
+ setTimer(setTimeout(() => {
355
+ onDelayFinish();
356
+ setTimer(void 0);
357
+ }, delay));
358
+ };
359
+ useEffect5(() => {
360
+ return () => {
361
+ clearTimeout(timer);
362
+ };
363
+ }, [timer]);
364
+ useEffect5(() => {
365
+ if (disabled) {
366
+ clearTimeout(timer);
367
+ setTimer(void 0);
368
+ }
369
+ }, [disabled, timer]);
370
+ return { restartTimer, clearTimer, hasActiveTimer: !!timer };
371
+ }
372
+
373
+ // src/hooks/useFloatingElement.ts
374
+ import { useCallback as useCallback3, useEffect as useEffect6, useState as useState4 } from "react";
375
+
376
+ // src/utils/math.ts
377
+ var clamp = (value, range = [0, 1]) => {
378
+ const [min, max] = range;
379
+ return Math.min(Math.max(value, min), max);
380
+ };
381
+
382
+ // src/hooks/useFloatingElement.ts
383
+ function calculatePosition({
384
+ windowRect,
385
+ containerRect,
386
+ anchorRect,
387
+ options
388
+ }) {
389
+ const { verticalAlignment, horizontalAlignment, gap, screenPadding } = options;
390
+ const windowWidth = windowRect.width;
391
+ const windowHeight = windowRect.height;
392
+ const maxWidth = windowWidth - 2 * screenPadding;
393
+ const maxHeight = windowHeight - 2 * screenPadding;
394
+ const width = Math.min(containerRect.width, maxWidth);
395
+ const height = Math.min(containerRect.height, maxHeight);
396
+ const leftSuggestion = {
397
+ beforeStart: anchorRect.left - width - gap,
398
+ afterStart: anchorRect.left,
399
+ center: anchorRect.left + anchorRect.width / 2 - width / 2,
400
+ beforeEnd: anchorRect.right - width,
401
+ afterEnd: anchorRect.right + gap
402
+ }[horizontalAlignment];
403
+ const topSuggestion = {
404
+ beforeStart: anchorRect.top - height - gap,
405
+ afterStart: anchorRect.top,
406
+ center: anchorRect.top + anchorRect.height / 2 - height / 2,
407
+ beforeEnd: anchorRect.bottom - height,
408
+ afterEnd: anchorRect.bottom + gap
409
+ }[verticalAlignment];
410
+ const left = clamp(leftSuggestion, [
411
+ screenPadding,
412
+ windowWidth - screenPadding - width
413
+ ]);
414
+ const top = clamp(topSuggestion, [
415
+ screenPadding,
416
+ windowHeight - screenPadding - height
417
+ ]);
418
+ return {
419
+ left,
420
+ top,
421
+ maxWidth,
422
+ maxHeight
423
+ };
424
+ }
425
+ function useFloatingElement({
426
+ active = true,
427
+ windowRef,
428
+ anchorRef,
429
+ containerRef,
430
+ isPolling = false,
431
+ pollingInterval = 100,
432
+ verticalAlignment = "afterEnd",
433
+ horizontalAlignment = "afterStart",
434
+ screenPadding = 16,
435
+ gap = 4
436
+ }) {
437
+ const [style, setStyle] = useState4();
438
+ const isMounted = useIsMounted();
439
+ const calculate = useCallback3(() => {
440
+ const containerRect = containerRef.current.getBoundingClientRect();
441
+ const windowRect = windowRef?.current.getBoundingClientRect() ?? {
442
+ top: 0,
443
+ bottom: window.innerHeight,
444
+ left: 0,
445
+ right: window.innerWidth,
446
+ width: window.innerWidth,
447
+ height: window.innerHeight
448
+ };
449
+ const anchorElement = anchorRef?.current;
450
+ if (anchorRef && !anchorElement) {
451
+ console.warn("FloatingContainer anchor provided, but its value is undefined");
452
+ }
453
+ const anchorRect = anchorElement?.getBoundingClientRect() ?? windowRect;
454
+ const calculateProps = {
455
+ windowRect,
456
+ anchorRect,
457
+ containerRect,
458
+ options: {
459
+ horizontalAlignment,
460
+ verticalAlignment,
461
+ screenPadding,
462
+ gap
463
+ }
464
+ };
465
+ setStyle(calculatePosition(calculateProps));
466
+ }, [anchorRef, containerRef, gap, horizontalAlignment, screenPadding, verticalAlignment, windowRef]);
467
+ const height = containerRef.current?.getBoundingClientRect().height;
468
+ const width = containerRef.current?.getBoundingClientRect().width;
469
+ useEffect6(() => {
470
+ if (active && isMounted) {
471
+ calculate();
472
+ } else {
473
+ setStyle(void 0);
474
+ }
475
+ }, [calculate, active, isMounted, height, width]);
476
+ useEffect6(() => {
477
+ window.addEventListener("resize", calculate);
478
+ let timeout;
479
+ if (isPolling) {
480
+ timeout = setInterval(calculate, pollingInterval);
481
+ }
482
+ return () => {
483
+ window.removeEventListener("resize", calculate);
484
+ if (timeout) {
485
+ clearInterval(timeout);
486
+ }
487
+ };
488
+ }, [calculate, isPolling, pollingInterval]);
489
+ return style;
490
+ }
491
+
492
+ // src/hooks/useHoverState.ts
493
+ import { useEffect as useEffect7, useState as useState5 } from "react";
494
+ var defaultUseHoverStateProps = {
495
+ closingDelay: 200,
496
+ isDisabled: false
497
+ };
498
+ var useHoverState = (props = void 0) => {
499
+ const { closingDelay, isDisabled } = { ...defaultUseHoverStateProps, ...props };
500
+ const [isHovered, setIsHovered] = useState5(false);
501
+ const [timer, setTimer] = useState5();
502
+ const onMouseEnter = () => {
503
+ if (isDisabled) {
504
+ return;
505
+ }
506
+ clearTimeout(timer);
507
+ setIsHovered(true);
508
+ };
509
+ const onMouseLeave = () => {
510
+ if (isDisabled) {
511
+ return;
512
+ }
513
+ setTimer(setTimeout(() => {
514
+ setIsHovered(false);
515
+ }, closingDelay));
516
+ };
517
+ useEffect7(() => {
518
+ if (timer) {
519
+ return () => {
520
+ clearTimeout(timer);
521
+ };
522
+ }
523
+ });
524
+ useEffect7(() => {
525
+ if (timer) {
526
+ clearTimeout(timer);
527
+ }
528
+ }, [isDisabled]);
529
+ return {
530
+ isHovered,
531
+ setIsHovered,
532
+ handlers: { onMouseEnter, onMouseLeave }
533
+ };
534
+ };
535
+
536
+ // src/hooks/useLocalStorage.ts
537
+ import { useCallback as useCallback4, useState as useState6 } from "react";
538
+
539
+ // src/utils/storage.ts
540
+ var StorageService = class {
541
+ // this seems to be a bug in eslint as 'paramter-properties' is a special syntax of typescript
542
+ constructor(storage) {
543
+ this.storage = storage;
544
+ }
545
+ get(key) {
546
+ const value = this.storage.getItem(key);
547
+ if (value === null) {
548
+ return null;
549
+ }
550
+ return JSON.parse(value);
551
+ }
552
+ set(key, value) {
553
+ this.storage.setItem(key, JSON.stringify(value));
554
+ }
555
+ delete(key) {
556
+ this.storage.removeItem(key);
557
+ }
558
+ deleteAll() {
559
+ this.storage.clear();
560
+ }
561
+ };
562
+ var LocalStorageService = class extends StorageService {
563
+ constructor() {
564
+ super(window.localStorage);
565
+ }
566
+ };
567
+
568
+ // src/utils/resolveSetState.ts
569
+ function resolveSetState(action, prev) {
570
+ return typeof action === "function" ? action(prev) : action;
571
+ }
572
+
573
+ // src/hooks/useLocalStorage.ts
574
+ var useLocalStorage = (key, initValue) => {
575
+ const get = useCallback4(() => {
576
+ if (typeof window === "undefined") {
577
+ return initValue;
578
+ }
579
+ const storageService = new LocalStorageService();
580
+ const value = storageService.get(key);
581
+ return value || initValue;
582
+ }, [initValue, key]);
583
+ const [storedValue, setStoredValue] = useState6(get);
584
+ const setValue = useCallback4((action) => {
585
+ const newValue = resolveSetState(action, storedValue);
586
+ const storageService = new LocalStorageService();
587
+ storageService.set(key, newValue);
588
+ setStoredValue(newValue);
589
+ }, [storedValue, setStoredValue, key]);
590
+ return [storedValue, setValue];
591
+ };
592
+
593
+ // src/hooks/useLogOnce.ts
594
+ import { useEffect as useEffect8, useState as useState7 } from "react";
595
+ var defaultOptions2 = {
596
+ type: "warning"
597
+ };
598
+ var useLogOnce = (message, condition, options) => {
599
+ const [hasLogged, setHasLogged] = useState7(false);
600
+ const { type } = { ...defaultOptions2, ...options };
601
+ useEffect8(() => {
602
+ if (!hasLogged && condition) {
603
+ switch (type) {
604
+ case "info":
605
+ console.info(message);
606
+ break;
607
+ case "error":
608
+ console.error(message);
609
+ break;
610
+ case "warning":
611
+ console.warn(message);
612
+ break;
613
+ }
614
+ setHasLogged(true);
615
+ }
616
+ }, [condition]);
617
+ };
618
+
619
+ // src/hooks/useOutsideClick.ts
620
+ import { useEffect as useEffect9 } from "react";
621
+ var useOutsideClick = (refs, handler) => {
622
+ useEffect9(() => {
623
+ const listener = (event) => {
624
+ if (event.target === null) return;
625
+ if (refs.some((ref) => !ref.current || ref.current.contains(event.target))) {
626
+ return;
627
+ }
628
+ handler();
629
+ };
630
+ document.addEventListener("mousedown", listener);
631
+ document.addEventListener("touchstart", listener);
632
+ return () => {
633
+ document.removeEventListener("mousedown", listener);
634
+ document.removeEventListener("touchstart", listener);
635
+ };
636
+ }, [refs, handler]);
637
+ };
638
+
639
+ // src/hooks/usePopoverPosition.ts
640
+ var defaultPopoverPositionOptions = {
641
+ edgePadding: 16,
642
+ outerGap: 4,
643
+ horizontalAlignment: "leftInside",
644
+ verticalAlignment: "bottomOutside",
645
+ disabled: false
646
+ };
647
+ var usePopoverPosition = (trigger, options) => {
648
+ const {
649
+ edgePadding,
650
+ outerGap,
651
+ verticalAlignment,
652
+ horizontalAlignment,
653
+ disabled
654
+ } = { ...defaultPopoverPositionOptions, ...options };
655
+ if (disabled || !trigger) {
656
+ return {};
657
+ }
658
+ const left = {
659
+ leftOutside: trigger.left - outerGap,
660
+ leftInside: trigger.left,
661
+ rightOutside: trigger.right + outerGap,
662
+ rightInside: trigger.right,
663
+ center: trigger.left + trigger.width / 2
664
+ }[horizontalAlignment];
665
+ const top = {
666
+ topOutside: trigger.top - outerGap,
667
+ topInside: trigger.top,
668
+ bottomOutside: trigger.bottom + outerGap,
669
+ bottomInside: trigger.bottom,
670
+ center: trigger.top + trigger.height / 2
671
+ }[verticalAlignment];
672
+ const translateX = {
673
+ leftOutside: "-100%",
674
+ leftInside: void 0,
675
+ rightOutside: void 0,
676
+ rightInside: "-100%",
677
+ center: "-50%"
678
+ }[horizontalAlignment];
679
+ const translateY = {
680
+ topOutside: "-100%",
681
+ topInside: void 0,
682
+ bottomOutside: void 0,
683
+ bottomInside: "-100%",
684
+ center: "-50%"
685
+ }[verticalAlignment];
686
+ return {
687
+ left: Math.max(left, edgePadding),
688
+ top: Math.max(top, edgePadding),
689
+ translate: [translateX ?? "0", translateY ?? "0"].join(" ")
690
+ };
691
+ };
692
+
693
+ // src/hooks/useRerender.ts
694
+ import { useReducer } from "react";
695
+ var useRerender = () => {
696
+ return useReducer(() => ({}), {})[1];
697
+ };
698
+
699
+ // src/hooks/useResizeCallbackWrapper.ts
700
+ import { useEffect as useEffect10 } from "react";
701
+ var useResizeCallbackWrapper = (callback) => {
702
+ useEffect10(() => {
703
+ window.addEventListener("resize", callback);
704
+ return () => {
705
+ window.removeEventListener("resize", callback);
706
+ };
707
+ }, [callback]);
708
+ };
709
+
710
+ // src/hooks/useSearch.ts
711
+ import { useCallback as useCallback5, useEffect as useEffect11, useMemo, useState as useState8 } from "react";
712
+
713
+ // src/utils/simpleSearch.ts
714
+ var MultiSubjectSearchWithMapping = (search, objects, mapping) => {
715
+ return objects.filter((object) => {
716
+ const mappedSearchKeywords = mapping(object)?.map((value) => value.toLowerCase().trim());
717
+ if (!mappedSearchKeywords) {
718
+ return true;
719
+ }
720
+ return search.every((searchValue) => !!mappedSearchKeywords.find((value) => !!value && value.includes(searchValue.toLowerCase().trim())));
721
+ });
722
+ };
723
+
724
+ // src/hooks/useSearch.ts
725
+ var useSearch = ({
726
+ list,
727
+ initialSearch,
728
+ searchMapping,
729
+ additionalSearchTags,
730
+ isSearchInstant = true,
731
+ sortingFunction,
732
+ filter,
733
+ disabled = false
734
+ }) => {
735
+ const [search, setSearch] = useState8(initialSearch ?? "");
736
+ const [result, setResult] = useState8(list);
737
+ const searchTags = useMemo(() => additionalSearchTags ?? [], [additionalSearchTags]);
738
+ const updateSearch = useCallback5((newSearch) => {
739
+ const usedSearch = newSearch ?? search;
740
+ if (newSearch) {
741
+ setSearch(search);
742
+ }
743
+ setResult(MultiSubjectSearchWithMapping([usedSearch, ...searchTags], list, searchMapping));
744
+ }, [searchTags, list, search, searchMapping]);
745
+ useEffect11(() => {
746
+ if (isSearchInstant) {
747
+ setResult(MultiSubjectSearchWithMapping([search, ...searchTags], list, searchMapping));
748
+ }
749
+ }, [searchTags, isSearchInstant, list, search, searchMapping, additionalSearchTags]);
750
+ const filteredResult = useMemo(() => {
751
+ if (!filter) {
752
+ return result;
753
+ }
754
+ return result.filter(filter);
755
+ }, [result, filter]);
756
+ const sortedAndFilteredResult = useMemo(() => {
757
+ if (!sortingFunction) {
758
+ return filteredResult;
759
+ }
760
+ return filteredResult.sort(sortingFunction);
761
+ }, [filteredResult, sortingFunction]);
762
+ const usedResult = useMemo(() => {
763
+ if (!disabled) {
764
+ return sortedAndFilteredResult;
765
+ }
766
+ return list;
767
+ }, [disabled, list, sortedAndFilteredResult]);
768
+ return {
769
+ result: usedResult,
770
+ hasResult: usedResult.length > 0,
771
+ allItems: list,
772
+ updateSearch,
773
+ search,
774
+ setSearch
775
+ };
776
+ };
777
+ export {
778
+ useDelay,
779
+ useFloatingElement,
780
+ useFocusGuards,
781
+ useFocusManagement,
782
+ useFocusOnceVisible,
783
+ useFocusTrap,
784
+ useHoverState,
785
+ useIsMounted,
786
+ useLocalStorage,
787
+ useLogOnce,
788
+ useOutsideClick,
789
+ usePopoverPosition,
790
+ useRerender,
791
+ useResizeCallbackWrapper,
792
+ useSearch
793
+ };
794
+ //# sourceMappingURL=index.mjs.map