beez-ui 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +31 -27
  2. package/README.md +22 -2
  3. package/dist/adapters/unpic-image.js +92 -14
  4. package/dist/components/alert-dialog.js +444 -26
  5. package/dist/components/alert.js +153 -18
  6. package/dist/components/animated-theme-toggler.js +215 -76
  7. package/dist/components/avatar.js +247 -15
  8. package/dist/components/badge.js +18 -16
  9. package/dist/components/button.js +85 -28
  10. package/dist/components/calendar.js +327 -68
  11. package/dist/components/card.js +39 -9
  12. package/dist/components/carousel.js +454 -84
  13. package/dist/components/checkbox.js +50 -3
  14. package/dist/components/data-table.js +827 -583
  15. package/dist/components/dialog.js +363 -22
  16. package/dist/components/dropdown-menu.js +543 -32
  17. package/dist/components/filter-query-bar.js +809 -468
  18. package/dist/components/filter-query-grammar.js +781 -736
  19. package/dist/components/form.js +305 -43
  20. package/dist/components/highlighter.js +142 -87
  21. package/dist/components/hover-card.js +97 -7
  22. package/dist/components/input-group.js +261 -41
  23. package/dist/components/input.js +8 -2
  24. package/dist/components/label.js +38 -3
  25. package/dist/components/link.js +45 -7
  26. package/dist/components/pagination.js +332 -16
  27. package/dist/components/popover.js +222 -16
  28. package/dist/components/radio-group.js +85 -5
  29. package/dist/components/select.js +451 -22
  30. package/dist/components/separator.js +43 -3
  31. package/dist/components/sheet.js +345 -22
  32. package/dist/components/sidebar.js +1385 -193
  33. package/dist/components/skeleton.js +6 -2
  34. package/dist/components/svgs/whatsappIcon.js +11 -1
  35. package/dist/components/switch.js +55 -3
  36. package/dist/components/table.js +288 -18
  37. package/dist/components/tabs.js +161 -18
  38. package/dist/components/textarea.js +7 -2
  39. package/dist/components/themed-toaster.js +63 -20
  40. package/dist/components/tooltip.js +128 -9
  41. package/dist/components/typing-animation.js +335 -150
  42. package/dist/constants/sidebar.js +1 -4
  43. package/dist/hooks/use-mobile.js +8 -8
  44. package/dist/hooks/use-sidebar-persistence.js +27 -27
  45. package/dist/lib/image-dimensions.js +2 -2
  46. package/dist/lib/year-month-filter.js +38 -40
  47. package/dist/next.js +69 -17
  48. package/dist/providers/beez-ui-provider.js +48 -7
  49. package/dist/providers/native-provider.js +40 -6
  50. package/dist/tanstack.js +35 -23
  51. package/package.json +4 -1
@@ -1,155 +1,340 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useEffect, useMemo, useRef, useState, } from "react";
4
- import { motion, } from "motion/react";
2
+ import { c as _c } from "react/compiler-runtime";
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { motion } from "motion/react";
5
5
  import { cn } from "../lib/utils.js";
6
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
6
7
  const motionElements = {
7
- article: motion.article,
8
- div: motion.div,
9
- h1: motion.h1,
10
- h2: motion.h2,
11
- h3: motion.h3,
12
- h4: motion.h4,
13
- h5: motion.h5,
14
- h6: motion.h6,
15
- li: motion.li,
16
- p: motion.p,
17
- section: motion.section,
18
- span: motion.span,
8
+ article: motion.article,
9
+ div: motion.div,
10
+ h1: motion.h1,
11
+ h2: motion.h2,
12
+ h3: motion.h3,
13
+ h4: motion.h4,
14
+ h5: motion.h5,
15
+ h6: motion.h6,
16
+ li: motion.li,
17
+ p: motion.p,
18
+ section: motion.section,
19
+ span: motion.span
19
20
  };
20
- export function TypingAnimation({ children, words, className, duration = 80, typeSpeed, deleteSpeed, delay = 0, pauseDelay = 1000, loop = false, as: Component = "span", startOnView = true, showCursor = true, blinkCursor = true, cursorStyle = "line", ...props }) {
21
- const MotionComponent = motionElements[Component];
22
- const [displayedText, setDisplayedText] = useState("");
23
- const [currentWordIndex, setCurrentWordIndex] = useState(0);
24
- const [currentCharIndex, setCurrentCharIndex] = useState(0);
25
- const [phase, setPhase] = useState("typing");
26
- const elementRef = useRef(null);
27
- const [isInView, setIsInView] = useState(() => !startOnView || typeof IntersectionObserver === "undefined");
28
- const wordsToAnimate = useMemo(() => words ?? (children ? [children] : []), [words, children]);
29
- const hasMultipleWords = wordsToAnimate.length > 1;
30
- const typingSpeed = typeSpeed ?? duration;
31
- const deletingSpeed = deleteSpeed ?? typingSpeed / 2;
32
- const shouldStart = startOnView ? isInView : true;
33
- const animationSourceKey = useMemo(() => (words ? words.join("\u0000") : (children ?? "")), [words, children]);
34
- const lastResetSourceKeyRef = useRef(animationSourceKey);
35
- useEffect(() => {
36
- if (!startOnView || isInView) {
37
- return;
38
- }
39
- const element = elementRef.current;
40
- if (!element || typeof IntersectionObserver === "undefined") {
41
- return;
42
- }
43
- const observer = new IntersectionObserver(([entry]) => {
44
- if (entry.isIntersecting) {
45
- setIsInView(true);
46
- observer.disconnect();
47
- }
48
- }, {
49
- threshold: 0.3,
50
- });
51
- observer.observe(element);
52
- return () => {
53
- observer.disconnect();
54
- };
55
- }, [isInView, startOnView]);
56
- useEffect(() => {
57
- if (lastResetSourceKeyRef.current === animationSourceKey) {
58
- return;
59
- }
60
- lastResetSourceKeyRef.current = animationSourceKey;
61
- const resetTimeout = setTimeout(() => {
62
- setDisplayedText("");
63
- setCurrentWordIndex(0);
64
- setCurrentCharIndex(0);
65
- setPhase("typing");
66
- }, 0);
67
- return () => {
68
- clearTimeout(resetTimeout);
69
- };
70
- }, [animationSourceKey]);
71
- useEffect(() => {
72
- let timeout = null;
73
- if (shouldStart && wordsToAnimate.length > 0) {
74
- const timeoutDelay = delay > 0 && displayedText === ""
75
- ? delay
76
- : phase === "typing"
77
- ? typingSpeed
78
- : phase === "deleting"
79
- ? deletingSpeed
80
- : pauseDelay;
81
- timeout = setTimeout(() => {
82
- const currentWord = wordsToAnimate[currentWordIndex] || "";
83
- const graphemes = Array.from(currentWord);
84
- switch (phase) {
85
- case "typing":
86
- if (currentCharIndex < graphemes.length) {
87
- setDisplayedText(graphemes.slice(0, currentCharIndex + 1).join(""));
88
- setCurrentCharIndex(currentCharIndex + 1);
89
- }
90
- else {
91
- if (hasMultipleWords || loop) {
92
- const isLastWord = currentWordIndex === wordsToAnimate.length - 1;
93
- if (!isLastWord || loop) {
94
- setPhase("pause");
95
- }
96
- }
97
- }
98
- break;
99
- case "pause":
100
- setPhase("deleting");
101
- break;
102
- case "deleting":
103
- if (currentCharIndex > 0) {
104
- setDisplayedText(graphemes.slice(0, currentCharIndex - 1).join(""));
105
- setCurrentCharIndex(currentCharIndex - 1);
106
- }
107
- else {
108
- const nextIndex = (currentWordIndex + 1) % wordsToAnimate.length;
109
- setCurrentWordIndex(nextIndex);
110
- setPhase("typing");
111
- }
112
- break;
113
- }
114
- }, timeoutDelay);
115
- }
116
- return () => {
117
- if (timeout !== null) {
118
- clearTimeout(timeout);
119
- }
120
- };
121
- }, [
122
- shouldStart,
123
- phase,
124
- currentCharIndex,
125
- currentWordIndex,
126
- displayedText,
127
- wordsToAnimate,
128
- hasMultipleWords,
129
- loop,
130
- typingSpeed,
131
- deletingSpeed,
132
- pauseDelay,
133
- delay,
134
- ]);
135
- const currentWordGraphemes = Array.from(wordsToAnimate[currentWordIndex] || "");
136
- const isComplete = !loop &&
137
- currentWordIndex === wordsToAnimate.length - 1 &&
138
- currentCharIndex >= currentWordGraphemes.length &&
139
- phase !== "deleting";
140
- const shouldShowCursor = showCursor &&
141
- !isComplete &&
142
- (hasMultipleWords || loop || currentCharIndex < currentWordGraphemes.length);
143
- const getCursorChar = () => {
144
- switch (cursorStyle) {
145
- case "block":
146
- return "▌";
147
- case "underscore":
148
- return "_";
149
- case "line":
150
- default:
151
- return "|";
152
- }
153
- };
154
- return (_jsxs(MotionComponent, { ref: elementRef, className: cn("tracking-[-0.02em]", Component === "h1" && "text-3xl font-bold leading-tight md:text-4xl", Component === "span" && "inline-block", className), ...props, children: [displayedText, shouldShowCursor && (_jsx("span", { className: cn("inline-block", blinkCursor && "animate-blink-cursor"), children: getCursorChar() }))] }));
21
+ export function TypingAnimation(t0) {
22
+ const $ = _c(64);
23
+ let children;
24
+ let className;
25
+ let deleteSpeed;
26
+ let props;
27
+ let t1;
28
+ let t2;
29
+ let t3;
30
+ let t4;
31
+ let t5;
32
+ let t6;
33
+ let t7;
34
+ let t8;
35
+ let t9;
36
+ let typeSpeed;
37
+ let words;
38
+ if ($[0] !== t0) {
39
+ ({children, words, className, duration: t1, typeSpeed, deleteSpeed, delay: t2, pauseDelay: t3, loop: t4, as: t5, startOnView: t6, showCursor: t7, blinkCursor: t8, cursorStyle: t9, ...props} = t0);
40
+ $[0] = t0;
41
+ $[1] = children;
42
+ $[2] = className;
43
+ $[3] = deleteSpeed;
44
+ $[4] = props;
45
+ $[5] = t1;
46
+ $[6] = t2;
47
+ $[7] = t3;
48
+ $[8] = t4;
49
+ $[9] = t5;
50
+ $[10] = t6;
51
+ $[11] = t7;
52
+ $[12] = t8;
53
+ $[13] = t9;
54
+ $[14] = typeSpeed;
55
+ $[15] = words;
56
+ } else {
57
+ children = $[1];
58
+ className = $[2];
59
+ deleteSpeed = $[3];
60
+ props = $[4];
61
+ t1 = $[5];
62
+ t2 = $[6];
63
+ t3 = $[7];
64
+ t4 = $[8];
65
+ t5 = $[9];
66
+ t6 = $[10];
67
+ t7 = $[11];
68
+ t8 = $[12];
69
+ t9 = $[13];
70
+ typeSpeed = $[14];
71
+ words = $[15];
72
+ }
73
+ const duration = t1 === undefined ? 80 : t1;
74
+ const delay = t2 === undefined ? 0 : t2;
75
+ const pauseDelay = t3 === undefined ? 1e3 : t3;
76
+ const loop = t4 === undefined ? false : t4;
77
+ const Component = t5 === undefined ? "span" : t5;
78
+ const startOnView = t6 === undefined ? true : t6;
79
+ const showCursor = t7 === undefined ? true : t7;
80
+ const blinkCursor = t8 === undefined ? true : t8;
81
+ const cursorStyle = t9 === undefined ? "line" : t9;
82
+ const MotionComponent = motionElements[Component];
83
+ const [displayedText, setDisplayedText] = useState("");
84
+ const [currentWordIndex, setCurrentWordIndex] = useState(0);
85
+ const [currentCharIndex, setCurrentCharIndex] = useState(0);
86
+ const [phase, setPhase] = useState("typing");
87
+ const elementRef = useRef(null);
88
+ let t10;
89
+ if ($[16] !== startOnView) {
90
+ t10 = () => !startOnView || typeof IntersectionObserver === "undefined";
91
+ $[16] = startOnView;
92
+ $[17] = t10;
93
+ } else {
94
+ t10 = $[17];
95
+ }
96
+ const [isInView, setIsInView] = useState(t10);
97
+ let t11;
98
+ if ($[18] !== children || $[19] !== words) {
99
+ t11 = words ?? (children ? [children] : []);
100
+ $[18] = children;
101
+ $[19] = words;
102
+ $[20] = t11;
103
+ } else {
104
+ t11 = $[20];
105
+ }
106
+ const wordsToAnimate = t11;
107
+ const hasMultipleWords = wordsToAnimate.length > 1;
108
+ const typingSpeed = typeSpeed ?? duration;
109
+ const deletingSpeed = deleteSpeed ?? typingSpeed / 2;
110
+ const shouldStart = startOnView ? isInView : true;
111
+ let t12;
112
+ if ($[21] !== children || $[22] !== words) {
113
+ t12 = words ? words.join("\0") : children ?? "";
114
+ $[21] = children;
115
+ $[22] = words;
116
+ $[23] = t12;
117
+ } else {
118
+ t12 = $[23];
119
+ }
120
+ const animationSourceKey = t12;
121
+ const lastResetSourceKeyRef = useRef(animationSourceKey);
122
+ let t13;
123
+ let t14;
124
+ if ($[24] !== isInView || $[25] !== startOnView) {
125
+ t13 = () => {
126
+ if (!startOnView || isInView) {
127
+ return;
128
+ }
129
+ const element = elementRef.current;
130
+ if (!element || typeof IntersectionObserver === "undefined") {
131
+ return;
132
+ }
133
+ const observer = new IntersectionObserver((t15) => {
134
+ const [entry] = t15;
135
+ if (entry.isIntersecting) {
136
+ setIsInView(true);
137
+ observer.disconnect();
138
+ }
139
+ }, { threshold: .3 });
140
+ observer.observe(element);
141
+ return () => {
142
+ observer.disconnect();
143
+ };
144
+ };
145
+ t14 = [isInView, startOnView];
146
+ $[24] = isInView;
147
+ $[25] = startOnView;
148
+ $[26] = t13;
149
+ $[27] = t14;
150
+ } else {
151
+ t13 = $[26];
152
+ t14 = $[27];
153
+ }
154
+ useEffect(t13, t14);
155
+ let t15;
156
+ let t16;
157
+ if ($[28] !== animationSourceKey) {
158
+ t15 = () => {
159
+ if (lastResetSourceKeyRef.current === animationSourceKey) {
160
+ return;
161
+ }
162
+ lastResetSourceKeyRef.current = animationSourceKey;
163
+ const resetTimeout = setTimeout(() => {
164
+ setDisplayedText("");
165
+ setCurrentWordIndex(0);
166
+ setCurrentCharIndex(0);
167
+ setPhase("typing");
168
+ }, 0);
169
+ return () => {
170
+ clearTimeout(resetTimeout);
171
+ };
172
+ };
173
+ t16 = [animationSourceKey];
174
+ $[28] = animationSourceKey;
175
+ $[29] = t15;
176
+ $[30] = t16;
177
+ } else {
178
+ t15 = $[29];
179
+ t16 = $[30];
180
+ }
181
+ useEffect(t15, t16);
182
+ let t17;
183
+ let t18;
184
+ if ($[31] !== currentCharIndex || $[32] !== currentWordIndex || $[33] !== delay || $[34] !== deletingSpeed || $[35] !== displayedText || $[36] !== hasMultipleWords || $[37] !== loop || $[38] !== pauseDelay || $[39] !== phase || $[40] !== shouldStart || $[41] !== typingSpeed || $[42] !== wordsToAnimate) {
185
+ t17 = () => {
186
+ let timeout = null;
187
+ if (shouldStart && wordsToAnimate.length > 0) {
188
+ const timeoutDelay = delay > 0 && displayedText === "" ? delay : phase === "typing" ? typingSpeed : phase === "deleting" ? deletingSpeed : pauseDelay;
189
+ timeout = setTimeout(() => {
190
+ const currentWord = wordsToAnimate[currentWordIndex] || "";
191
+ const graphemes = Array.from(currentWord);
192
+ bb126: switch (phase) {
193
+ case "typing": {
194
+ if (currentCharIndex < graphemes.length) {
195
+ setDisplayedText(graphemes.slice(0, currentCharIndex + 1).join(""));
196
+ setCurrentCharIndex(currentCharIndex + 1);
197
+ } else {
198
+ if (hasMultipleWords || loop) {
199
+ const isLastWord = currentWordIndex === wordsToAnimate.length - 1;
200
+ if (!isLastWord || loop) {
201
+ setPhase("pause");
202
+ }
203
+ }
204
+ }
205
+ break bb126;
206
+ }
207
+ case "pause": {
208
+ setPhase("deleting");
209
+ break bb126;
210
+ }
211
+ case "deleting": {
212
+ if (currentCharIndex > 0) {
213
+ setDisplayedText(graphemes.slice(0, currentCharIndex - 1).join(""));
214
+ setCurrentCharIndex(currentCharIndex - 1);
215
+ } else {
216
+ const nextIndex = (currentWordIndex + 1) % wordsToAnimate.length;
217
+ setCurrentWordIndex(nextIndex);
218
+ setPhase("typing");
219
+ }
220
+ }
221
+ }
222
+ }, timeoutDelay);
223
+ }
224
+ return () => {
225
+ if (timeout !== null) {
226
+ clearTimeout(timeout);
227
+ }
228
+ };
229
+ };
230
+ t18 = [
231
+ shouldStart,
232
+ phase,
233
+ currentCharIndex,
234
+ currentWordIndex,
235
+ displayedText,
236
+ wordsToAnimate,
237
+ hasMultipleWords,
238
+ loop,
239
+ typingSpeed,
240
+ deletingSpeed,
241
+ pauseDelay,
242
+ delay
243
+ ];
244
+ $[31] = currentCharIndex;
245
+ $[32] = currentWordIndex;
246
+ $[33] = delay;
247
+ $[34] = deletingSpeed;
248
+ $[35] = displayedText;
249
+ $[36] = hasMultipleWords;
250
+ $[37] = loop;
251
+ $[38] = pauseDelay;
252
+ $[39] = phase;
253
+ $[40] = shouldStart;
254
+ $[41] = typingSpeed;
255
+ $[42] = wordsToAnimate;
256
+ $[43] = t17;
257
+ $[44] = t18;
258
+ } else {
259
+ t17 = $[43];
260
+ t18 = $[44];
261
+ }
262
+ useEffect(t17, t18);
263
+ let t19;
264
+ if ($[45] !== currentWordIndex || $[46] !== wordsToAnimate) {
265
+ t19 = Array.from(wordsToAnimate[currentWordIndex] || "");
266
+ $[45] = currentWordIndex;
267
+ $[46] = wordsToAnimate;
268
+ $[47] = t19;
269
+ } else {
270
+ t19 = $[47];
271
+ }
272
+ const currentWordGraphemes = t19;
273
+ const isComplete = !loop && currentWordIndex === wordsToAnimate.length - 1 && currentCharIndex >= currentWordGraphemes.length && phase !== "deleting";
274
+ const shouldShowCursor = showCursor && !isComplete && (hasMultipleWords || loop || currentCharIndex < currentWordGraphemes.length);
275
+ let t20;
276
+ if ($[48] !== cursorStyle) {
277
+ t20 = () => {
278
+ switch (cursorStyle) {
279
+ case "block": {
280
+ return "▌";
281
+ }
282
+ case "underscore": {
283
+ return "_";
284
+ }
285
+ case "line":
286
+ default: {
287
+ return "|";
288
+ }
289
+ }
290
+ };
291
+ $[48] = cursorStyle;
292
+ $[49] = t20;
293
+ } else {
294
+ t20 = $[49];
295
+ }
296
+ const getCursorChar = t20;
297
+ const t21 = Component === "h1" && "text-3xl font-bold leading-tight md:text-4xl";
298
+ const t22 = Component === "span" && "inline-block";
299
+ let t23;
300
+ if ($[50] !== className || $[51] !== t21 || $[52] !== t22) {
301
+ t23 = cn("tracking-[-0.02em]", t21, t22, className);
302
+ $[50] = className;
303
+ $[51] = t21;
304
+ $[52] = t22;
305
+ $[53] = t23;
306
+ } else {
307
+ t23 = $[53];
308
+ }
309
+ let t24;
310
+ if ($[54] !== blinkCursor || $[55] !== getCursorChar || $[56] !== shouldShowCursor) {
311
+ t24 = shouldShowCursor && /* @__PURE__ */ _jsx("span", {
312
+ className: cn("inline-block", blinkCursor && "animate-blink-cursor"),
313
+ children: getCursorChar()
314
+ });
315
+ $[54] = blinkCursor;
316
+ $[55] = getCursorChar;
317
+ $[56] = shouldShowCursor;
318
+ $[57] = t24;
319
+ } else {
320
+ t24 = $[57];
321
+ }
322
+ let t25;
323
+ if ($[58] !== MotionComponent || $[59] !== displayedText || $[60] !== props || $[61] !== t23 || $[62] !== t24) {
324
+ t25 = /* @__PURE__ */ _jsxs(MotionComponent, {
325
+ ref: elementRef,
326
+ className: t23,
327
+ ...props,
328
+ children: [displayedText, t24]
329
+ });
330
+ $[58] = MotionComponent;
331
+ $[59] = displayedText;
332
+ $[60] = props;
333
+ $[61] = t23;
334
+ $[62] = t24;
335
+ $[63] = t25;
336
+ } else {
337
+ t25 = $[63];
338
+ }
339
+ return t25;
155
340
  }
@@ -14,7 +14,4 @@ export const SIDEBAR_COOKIE_OPEN_VALUE = "true";
14
14
  /** Serialized value representing collapsed navigation. */
15
15
  export const SIDEBAR_COOKIE_COLLAPSED_VALUE = "false";
16
16
  /** Preference lifetime in seconds, as required by the cookie max-age field. */
17
- export const SIDEBAR_COOKIE_MAX_AGE = SIDEBAR_COOKIE_MAX_AGE_SECONDS_PER_MINUTE *
18
- SIDEBAR_COOKIE_MAX_AGE_MINUTES_PER_HOUR *
19
- SIDEBAR_COOKIE_MAX_AGE_HOURS_PER_DAY *
20
- SIDEBAR_COOKIE_MAX_AGE_DAYS;
17
+ export const SIDEBAR_COOKIE_MAX_AGE = SIDEBAR_COOKIE_MAX_AGE_SECONDS_PER_MINUTE * SIDEBAR_COOKIE_MAX_AGE_MINUTES_PER_HOUR * SIDEBAR_COOKIE_MAX_AGE_HOURS_PER_DAY * SIDEBAR_COOKIE_MAX_AGE_DAYS;
@@ -2,18 +2,18 @@ import * as React from "react";
2
2
  /** Viewport width in CSS pixels at which desktop navigation begins. */
3
3
  const MOBILE_BREAKPOINT = 768;
4
4
  function subscribeToMobileBreakpoint(onStoreChange) {
5
- const mediaQueryList = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
6
- mediaQueryList.addEventListener("change", onStoreChange);
7
- return () => {
8
- mediaQueryList.removeEventListener("change", onStoreChange);
9
- };
5
+ const mediaQueryList = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
6
+ mediaQueryList.addEventListener("change", onStoreChange);
7
+ return () => {
8
+ mediaQueryList.removeEventListener("change", onStoreChange);
9
+ };
10
10
  }
11
11
  function getMobileSnapshot() {
12
- return window.innerWidth < MOBILE_BREAKPOINT;
12
+ return window.innerWidth < MOBILE_BREAKPOINT;
13
13
  }
14
14
  function getServerMobileSnapshot() {
15
- return false;
15
+ return false;
16
16
  }
17
17
  export function useIsMobile() {
18
- return React.useSyncExternalStore(subscribeToMobileBreakpoint, getMobileSnapshot, getServerMobileSnapshot);
18
+ return React.useSyncExternalStore(subscribeToMobileBreakpoint, getMobileSnapshot, getServerMobileSnapshot);
19
19
  }
@@ -1,45 +1,45 @@
1
1
  "use client";
2
+ import { c as _c } from "react/compiler-runtime";
2
3
  /** Keeps optional browser persistence separate from the sidebar rendering contract. */
3
- import { useCallback, useSyncExternalStore } from "react";
4
+ import { useSyncExternalStore } from "react";
4
5
  import { SIDEBAR_COOKIE_COLLAPSED_VALUE, SIDEBAR_COOKIE_OPEN_VALUE } from "../constants/sidebar.js";
5
6
  /** Reads a preference without making unavailable browser storage a render failure. */
6
7
  function readSidebarPreference(storageKey) {
7
- if (!storageKey || typeof window === "undefined")
8
- return null;
9
- try {
10
- const value = window.localStorage.getItem(storageKey);
11
- if (value === SIDEBAR_COOKIE_OPEN_VALUE)
12
- return true;
13
- if (value === SIDEBAR_COOKIE_COLLAPSED_VALUE)
14
- return false;
15
- }
16
- catch {
17
- // Persisted preferences are optional; blocked storage retains the server default.
18
- }
19
- return null;
8
+ if (!storageKey || typeof window === "undefined") return null;
9
+ try {
10
+ const value = window.localStorage.getItem(storageKey);
11
+ if (value === SIDEBAR_COOKIE_OPEN_VALUE) return true;
12
+ if (value === SIDEBAR_COOKIE_COLLAPSED_VALUE) return false;
13
+ } catch {}
14
+ return null;
20
15
  }
21
16
  /** Subscribes to browser storage updates and releases the listener on unmount. */
22
17
  function subscribeToStorage(onChange) {
23
- window.addEventListener("storage", onChange);
24
- return () => window.removeEventListener("storage", onChange);
18
+ window.addEventListener("storage", onChange);
19
+ return () => window.removeEventListener("storage", onChange);
25
20
  }
26
21
  /** Keeps the first hydrated render identical to the server-provided preference. */
27
22
  function getServerPreference() {
28
- return null;
23
+ return null;
29
24
  }
30
25
  /** Resolves opt-in persistence after hydration, without changing controlled state. */
31
26
  export function useSidebarPersistence(storageKey) {
32
- const getSnapshot = useCallback(() => readSidebarPreference(storageKey), [storageKey]);
33
- return useSyncExternalStore(subscribeToStorage, getSnapshot, getServerPreference);
27
+ const $ = _c(2);
28
+ let t0;
29
+ if ($[0] !== storageKey) {
30
+ t0 = () => readSidebarPreference(storageKey);
31
+ $[0] = storageKey;
32
+ $[1] = t0;
33
+ } else {
34
+ t0 = $[1];
35
+ }
36
+ const getSnapshot = t0;
37
+ return useSyncExternalStore(subscribeToStorage, getSnapshot, getServerPreference);
34
38
  }
35
39
  /** Stores an optional preference while retaining usable navigation in private mode. */
36
40
  export function saveSidebarPreference(storageKey, open) {
37
- if (!storageKey)
38
- return;
39
- try {
40
- window.localStorage.setItem(storageKey, open ? SIDEBAR_COOKIE_OPEN_VALUE : SIDEBAR_COOKIE_COLLAPSED_VALUE);
41
- }
42
- catch {
43
- // The current in-memory state remains authoritative if storage is blocked.
44
- }
41
+ if (!storageKey) return;
42
+ try {
43
+ window.localStorage.setItem(storageKey, open ? SIDEBAR_COOKIE_OPEN_VALUE : SIDEBAR_COOKIE_COLLAPSED_VALUE);
44
+ } catch {}
45
45
  }
@@ -2,6 +2,6 @@
2
2
  const DEFAULT_IMAGE_DIMENSION_PX = 40;
3
3
  /** Converts native image dimensions into a positive numeric value. */
4
4
  export function imageDimension(value) {
5
- const parsed = Number(value);
6
- return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_IMAGE_DIMENSION_PX;
5
+ const parsed = Number(value);
6
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_IMAGE_DIMENSION_PX;
7
7
  }