@windrun-huaiin/third-ui 29.2.0 → 30.0.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 (102) hide show
  1. package/dist/fuma/mdx/cheet-table.d.ts +13 -0
  2. package/dist/fuma/mdx/cheet-table.js +295 -0
  3. package/dist/fuma/mdx/cheet-table.mjs +293 -0
  4. package/dist/fuma/mdx/index.d.ts +1 -0
  5. package/dist/fuma/mdx/index.js +2 -0
  6. package/dist/fuma/mdx/index.mjs +1 -0
  7. package/dist/fuma/server/features/widgets.js +2 -0
  8. package/dist/fuma/server/features/widgets.mjs +2 -0
  9. package/dist/lib/fuma-schema-check-util.d.ts +1 -1
  10. package/dist/main/alert-dialog/confirm-dialog.d.ts +2 -1
  11. package/dist/main/alert-dialog/confirm-dialog.js +3 -3
  12. package/dist/main/alert-dialog/confirm-dialog.mjs +4 -4
  13. package/dist/main/alert-dialog/dialog-loading-action.d.ts +2 -1
  14. package/dist/main/alert-dialog/dialog-loading-action.js +6 -3
  15. package/dist/main/alert-dialog/dialog-loading-action.mjs +6 -3
  16. package/dist/main/alert-dialog/dialog-styles.d.ts +4 -2
  17. package/dist/main/alert-dialog/dialog-styles.js +8 -4
  18. package/dist/main/alert-dialog/dialog-styles.mjs +7 -5
  19. package/dist/main/alert-dialog/high-priority-confirm-dialog.d.ts +2 -1
  20. package/dist/main/alert-dialog/high-priority-confirm-dialog.js +7 -7
  21. package/dist/main/alert-dialog/high-priority-confirm-dialog.mjs +8 -8
  22. package/dist/main/alert-dialog/info-dialog.d.ts +2 -1
  23. package/dist/main/alert-dialog/info-dialog.js +3 -3
  24. package/dist/main/alert-dialog/info-dialog.mjs +4 -4
  25. package/dist/main/alert-dialog/undoable-confirm-dialog.d.ts +2 -1
  26. package/dist/main/alert-dialog/undoable-confirm-dialog.js +4 -4
  27. package/dist/main/alert-dialog/undoable-confirm-dialog.mjs +5 -5
  28. package/dist/main/anime/anime-beam-frame.d.ts +3 -0
  29. package/dist/main/anime/anime-beam-frame.js +63 -0
  30. package/dist/main/anime/anime-beam-frame.mjs +61 -0
  31. package/dist/main/anime/anime-spiral-loading.d.ts +10 -0
  32. package/dist/main/anime/anime-spiral-loading.js +77 -0
  33. package/dist/main/anime/anime-spiral-loading.mjs +75 -0
  34. package/dist/main/anime/index.d.ts +2 -0
  35. package/dist/main/anime/index.js +10 -0
  36. package/dist/main/anime/index.mjs +3 -0
  37. package/dist/main/beam-frame/animate.d.ts +3 -0
  38. package/dist/main/beam-frame/animate.js +63 -0
  39. package/dist/main/beam-frame/animate.mjs +61 -0
  40. package/dist/main/beam-frame/beam-frame.d.ts +4 -0
  41. package/dist/main/beam-frame/beam-frame.js +262 -0
  42. package/dist/main/beam-frame/beam-frame.mjs +258 -0
  43. package/dist/main/beam-frame/index.d.ts +4 -0
  44. package/dist/main/beam-frame/index.js +11 -0
  45. package/dist/main/beam-frame/index.mjs +3 -0
  46. package/dist/main/beam-frame/motion.d.ts +3 -0
  47. package/dist/main/beam-frame/motion.js +61 -0
  48. package/dist/main/beam-frame/motion.mjs +59 -0
  49. package/dist/main/beam-frame/share-config.d.ts +54 -0
  50. package/dist/main/beam-frame/share-config.js +161 -0
  51. package/dist/main/beam-frame/share-config.mjs +152 -0
  52. package/dist/main/beam-frame-config.d.ts +54 -0
  53. package/dist/main/beam-frame-config.js +161 -0
  54. package/dist/main/beam-frame-config.mjs +152 -0
  55. package/dist/main/calendar/random-date-range-dialog.d.ts +5 -2
  56. package/dist/main/calendar/random-date-range-dialog.js +239 -109
  57. package/dist/main/calendar/random-date-range-dialog.mjs +242 -112
  58. package/dist/main/cta.js +17 -1
  59. package/dist/main/cta.mjs +18 -2
  60. package/dist/main/delayed-img.d.ts +1 -1
  61. package/dist/main/delayed-img.js +8 -5
  62. package/dist/main/delayed-img.mjs +8 -5
  63. package/dist/main/info-tooltip.js +70 -9
  64. package/dist/main/info-tooltip.mjs +70 -9
  65. package/dist/main/loading-frame/index.d.ts +1 -0
  66. package/dist/main/loading.d.ts +2 -1
  67. package/dist/main/loading.js +64 -26
  68. package/dist/main/loading.mjs +64 -26
  69. package/dist/main/motion/index.d.ts +1 -0
  70. package/dist/main/motion/index.js +9 -0
  71. package/dist/main/motion/index.mjs +2 -0
  72. package/dist/main/motion/motion-beam-frame.d.ts +3 -0
  73. package/dist/main/motion/motion-beam-frame.js +61 -0
  74. package/dist/main/motion/motion-beam-frame.mjs +59 -0
  75. package/dist/main/snake-loading-frame.d.ts +7 -3
  76. package/dist/main/snake-loading-frame.js +44 -252
  77. package/dist/main/snake-loading-frame.mjs +46 -254
  78. package/package.json +16 -5
  79. package/src/fuma/mdx/cheet-table.tsx +650 -0
  80. package/src/fuma/mdx/index.ts +1 -0
  81. package/src/fuma/server/features/widgets.tsx +2 -0
  82. package/src/main/alert-dialog/confirm-dialog.tsx +5 -2
  83. package/src/main/alert-dialog/dialog-loading-action.tsx +22 -5
  84. package/src/main/alert-dialog/dialog-styles.ts +13 -3
  85. package/src/main/alert-dialog/high-priority-confirm-dialog.tsx +29 -24
  86. package/src/main/alert-dialog/info-dialog.tsx +5 -2
  87. package/src/main/alert-dialog/undoable-confirm-dialog.tsx +21 -18
  88. package/src/main/anime/anime-beam-frame.tsx +128 -0
  89. package/src/main/anime/anime-spiral-loading.tsx +123 -0
  90. package/src/main/anime/index.ts +9 -0
  91. package/src/main/beam-frame-config.tsx +341 -0
  92. package/src/main/calendar/random-date-range-dialog.tsx +242 -74
  93. package/src/main/cta.tsx +50 -21
  94. package/src/main/delayed-img.tsx +9 -4
  95. package/src/main/info-tooltip.tsx +116 -20
  96. package/src/main/loading-frame/index.ts +4 -0
  97. package/src/main/loading.tsx +75 -24
  98. package/src/main/motion/index.ts +8 -0
  99. package/src/main/motion/motion-beam-frame.tsx +137 -0
  100. package/src/main/snake-loading-frame.tsx +95 -496
  101. package/src/styles/cta.css +21 -4
  102. package/src/styles/third-ui.css +0 -20
@@ -1,16 +1,19 @@
1
1
  "use client";
2
- import { jsx, jsxs } from 'react/jsx-runtime';
3
- import { useState, useRef, useMemo, useEffect, useCallback } from 'react';
2
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
3
+ import { useState, useRef, useMemo, useCallback, useEffect } from 'react';
4
4
  import { createPortal } from 'react-dom';
5
- import { XIcon, CheckCheckIcon, ChevronsLeftIcon, ChevronLeftIcon, ChevronRightIcon, ChevronsRightIcon } from '@windrun-huaiin/base-ui/icons';
5
+ import { XIcon, ChevronsLeftIcon, ChevronLeftIcon, ChevronRightIcon, ChevronsRightIcon, CheckCheckIcon } from '@windrun-huaiin/base-ui/icons';
6
+ import { themeSvgIconColor } from '@windrun-huaiin/base-ui/lib';
6
7
  import { cn } from '@windrun-huaiin/lib/utils';
8
+ import { useDialogLoadingAction } from '../alert-dialog/dialog-loading-action.mjs';
9
+ import { XButton } from '../buttons/x-button.mjs';
7
10
  import { usePressFeedback } from '../buttons/use-press-feedback.mjs';
8
11
 
9
12
  const DEFAULT_RANGE_DAYS = 7;
10
- const MAX_RANGE_DAYS = 30;
11
- const TRACK_MIN_DAYS = 45;
12
- const TRACK_PADDING_DAYS = 20;
13
- const DIALOG_ICON_BUTTON_CLASS_NAME = 'inline-flex h-8 w-8 items-center justify-center rounded-full border border-black/10 bg-white text-slate-500 transition duration-150 hover:border-black/20 hover:bg-black/5 hover:text-slate-900 dark:border-white/10 dark:bg-slate-950 dark:text-slate-300 dark:hover:bg-white/5 dark:hover:text-white';
13
+ const MAX_RANGE_DAYS = 31;
14
+ const VISIBLE_TRACK_DAYS = 36;
15
+ const EDGE_OVERFLOW_PIXELS_PER_DAY = 24;
16
+ const DIALOG_ICON_BUTTON_CLASS_NAME = 'inline-flex h-8 w-8 items-center justify-center rounded-full bg-white text-slate-500 transition duration-150 hover:bg-black/5 hover:text-slate-900 dark:bg-slate-950 dark:text-slate-300 dark:hover:bg-white/5 dark:hover:text-white';
14
17
  const DIALOG_NAV_BUTTON_CLASS_NAME = 'inline-flex h-8 w-8 items-center justify-center rounded-full transition-[transform,background-color,color,box-shadow,border-color] duration-150 ease-out';
15
18
  const DIALOG_NAV_BUTTON_REST_CLASS_NAME = 'border border-black/10 bg-white text-slate-500 shadow-[0_1px_2px_rgba(15,23,42,0.08)] hover:border-black/15 dark:border-white/10 dark:bg-slate-950 dark:text-slate-400 dark:hover:border-white/15';
16
19
  const DIALOG_NAV_BUTTON_PRESSED_CLASS_NAME = 'translate-y-[2px] scale-[0.9] border border-black/30 bg-slate-300 text-slate-950 shadow-[inset_0_2px_4px_rgba(15,23,42,0.22)] dark:border-white/25 dark:bg-white/20 dark:text-white dark:shadow-[inset_0_2px_4px_rgba(255,255,255,0.16)]';
@@ -52,12 +55,31 @@ function clampWindowDays(days) {
52
55
  }
53
56
  function buildTrackRange(referenceDate, windowDays = DEFAULT_RANGE_DAYS) {
54
57
  const resolvedWindowDays = clampWindowDays(windowDays);
55
- const resolvedTotalDays = Math.max(TRACK_MIN_DAYS, resolvedWindowDays + TRACK_PADDING_DAYS);
56
- const daysBefore = Math.floor((resolvedTotalDays - resolvedWindowDays) / 3);
58
+ const daysBefore = Math.floor((VISIBLE_TRACK_DAYS - resolvedWindowDays) / 3);
57
59
  const startDate = addDays(referenceDate, -daysBefore);
58
- const endDate = addDays(startDate, resolvedTotalDays - 1);
60
+ const endDate = addDays(startDate, VISIBLE_TRACK_DAYS - 1);
59
61
  return { startDate, endDate };
60
62
  }
63
+ function ensureRangeVisibleOnTrack(range, bounds) {
64
+ if (!range.startDate || !range.endDate || !bounds.startDate || !bounds.endDate) {
65
+ return bounds;
66
+ }
67
+ let nextStartDate = bounds.startDate;
68
+ if (compareDateStrings(range.startDate, nextStartDate) < 0) {
69
+ nextStartDate = range.startDate;
70
+ }
71
+ const nextEndDate = addDays(nextStartDate, VISIBLE_TRACK_DAYS - 1);
72
+ if (compareDateStrings(range.endDate, nextEndDate) > 0) {
73
+ nextStartDate = addDays(range.endDate, -35);
74
+ }
75
+ if (nextStartDate === bounds.startDate && addDays(nextStartDate, VISIBLE_TRACK_DAYS - 1) === bounds.endDate) {
76
+ return bounds;
77
+ }
78
+ return {
79
+ startDate: nextStartDate,
80
+ endDate: addDays(nextStartDate, VISIBLE_TRACK_DAYS - 1),
81
+ };
82
+ }
61
83
  function clampDateToRange(date, bounds) {
62
84
  if (!bounds.startDate || !bounds.endDate) {
63
85
  return date;
@@ -80,6 +102,19 @@ function getDateByRatio(bounds, ratio) {
80
102
  return getTodayString();
81
103
  }
82
104
  const totalDays = Math.max(1, getDaysBetween(bounds.startDate, bounds.endDate));
105
+ return addDays(bounds.startDate, Math.round(totalDays * Math.max(0, Math.min(1, ratio))));
106
+ }
107
+ function getDateByOverflowRatio(bounds, ratio, trackWidth) {
108
+ if (!bounds.startDate || !bounds.endDate) {
109
+ return getTodayString();
110
+ }
111
+ const totalDays = Math.max(1, getDaysBetween(bounds.startDate, bounds.endDate));
112
+ if (ratio < 0) {
113
+ return addDays(bounds.startDate, Math.floor((ratio * trackWidth) / EDGE_OVERFLOW_PIXELS_PER_DAY));
114
+ }
115
+ if (ratio > 1) {
116
+ return addDays(bounds.endDate, Math.ceil(((ratio - 1) * trackWidth) / EDGE_OVERFLOW_PIXELS_PER_DAY));
117
+ }
83
118
  return addDays(bounds.startDate, Math.round(totalDays * ratio));
84
119
  }
85
120
  function getRatioByDate(date, bounds) {
@@ -116,8 +151,24 @@ function getMonthEnd(value) {
116
151
  const date = parseDateString(value);
117
152
  return formatDateString(new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + 1, 0)));
118
153
  }
119
- function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEFAULT_RANGE_DAYS, onOpenChange, onApply, onClear, }) {
120
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
154
+ function RollingMonthLabel({ value }) {
155
+ const [displayValue, setDisplayValue] = useState(value);
156
+ const [previousValue, setPreviousValue] = useState(null);
157
+ useEffect(() => {
158
+ if (value === displayValue) {
159
+ return undefined;
160
+ }
161
+ setPreviousValue(displayValue);
162
+ setDisplayValue(value);
163
+ const timeout = window.setTimeout(() => {
164
+ setPreviousValue(null);
165
+ }, 180);
166
+ return () => window.clearTimeout(timeout);
167
+ }, [displayValue, value]);
168
+ return (jsxs("span", { className: "relative inline-block h-5 min-w-10 overflow-hidden align-bottom", children: [previousValue ? (jsx("span", { className: "rd-date-range-month-out absolute inset-x-0 top-0 text-center", children: previousValue })) : null, jsx("span", { className: cn('absolute inset-x-0 top-0 text-center', previousValue && 'rd-date-range-month-in'), children: displayValue })] }));
169
+ }
170
+ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEFAULT_RANGE_DAYS, onOpenChange, loadingActions, loadingFullPage, onApply, onClear, }) {
171
+ var _a, _b, _c, _d, _e, _f;
121
172
  const resolvedDefaultRangeDays = clampWindowDays(defaultRangeDays);
122
173
  const [draftRange, setDraftRange] = useState(value);
123
174
  const [referenceDate, setReferenceDate] = useState(anchorDate);
@@ -135,12 +186,15 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
135
186
  const resultLabelRef = useRef(null);
136
187
  const selectionDaysRef = useRef(null);
137
188
  const dragPreviewRef = useRef(null);
189
+ const trackBoundsRef = useRef(trackBounds);
190
+ const dragStartTrackBoundsRef = useRef(null);
138
191
  const frameRef = useRef(null);
139
192
  const pendingClientXRef = useRef(null);
140
193
  const syncPreviewDomRef = useRef(() => { });
141
194
  const buildDraggedRangeRef = useRef(() => null);
142
195
  const previousBodyOverflowRef = useRef(null);
143
196
  const today = useMemo(() => getTodayString(), []);
197
+ const { dialogLoading, runDialogAction } = useDialogLoadingAction({ loadingActions, loadingFullPage, onOpenChange });
144
198
  const baseReferenceDate = anchorDate || today;
145
199
  const previousOpenRef = useRef(false);
146
200
  const startRatio = getRatioByDate((_a = draftRange.startDate) !== null && _a !== void 0 ? _a : baseReferenceDate, trackBounds);
@@ -151,22 +205,27 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
151
205
  const isSingleDay = ((_c = draftRange.startDate) !== null && _c !== void 0 ? _c : null) === ((_d = draftRange.endDate) !== null && _d !== void 0 ? _d : null);
152
206
  const startHandlePercent = isSingleDay ? Math.max(leftPercent - 0.8, 0) : leftPercent;
153
207
  const endHandlePercent = isSingleDay ? Math.min(rightPercent + 0.8, 100) : rightPercent;
154
- const trackTickCount = Math.max(getDaysBetween((_e = trackBounds.startDate) !== null && _e !== void 0 ? _e : baseReferenceDate, (_f = trackBounds.endDate) !== null && _f !== void 0 ? _f : baseReferenceDate) + 1, 2);
155
- const monthLabels = useMemo(() => {
156
- const values = [trackBounds.startDate, trackBounds.endDate]
157
- .filter((item) => Boolean(item))
158
- .map((item) => formatMonthShort(item));
159
- return [...new Set(values)];
160
- }, [trackBounds.endDate, trackBounds.startDate]);
208
+ const trackTickCount = VISIBLE_TRACK_DAYS;
209
+ const leftMonthLabel = formatMonthShort((_e = trackBounds.startDate) !== null && _e !== void 0 ? _e : baseReferenceDate);
210
+ const rightMonthLabel = formatMonthShort((_f = trackBounds.endDate) !== null && _f !== void 0 ? _f : baseReferenceDate);
211
+ const handleApply = useCallback(() => {
212
+ return onApply(draftRange);
213
+ }, [draftRange, onApply]);
214
+ function commitTrackBounds(nextTrackBounds) {
215
+ trackBoundsRef.current = nextTrackBounds;
216
+ setTrackBounds(nextTrackBounds);
217
+ }
161
218
  useEffect(() => {
162
219
  if (open && !previousOpenRef.current) {
220
+ const nextTrackBounds = buildTrackRange(baseReferenceDate, resolvedDefaultRangeDays);
163
221
  const nextRange = {
164
222
  startDate: baseReferenceDate,
165
223
  endDate: addDays(baseReferenceDate, resolvedDefaultRangeDays - 1),
166
224
  };
167
225
  setDraftRange(nextRange);
168
226
  setReferenceDate(baseReferenceDate);
169
- setTrackBounds(buildTrackRange(baseReferenceDate, resolvedDefaultRangeDays));
227
+ trackBoundsRef.current = nextTrackBounds;
228
+ setTrackBounds(nextTrackBounds);
170
229
  setWindowDays(resolvedDefaultRangeDays);
171
230
  dragStartRangeRef.current = null;
172
231
  dragModeRef.current = null;
@@ -184,16 +243,20 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
184
243
  setReferenceDate(nextReferenceDate);
185
244
  setWindowDays(clampedWindowDays);
186
245
  setDraftRange(nextRange);
187
- if (!(options === null || options === void 0 ? void 0 : options.preserveTrack)) {
188
- setTrackBounds(buildTrackRange(nextReferenceDate, clampedWindowDays));
246
+ if (options === null || options === void 0 ? void 0 : options.preserveTrack) {
247
+ commitTrackBounds(ensureRangeVisibleOnTrack(nextRange, trackBoundsRef.current));
248
+ }
249
+ else {
250
+ commitTrackBounds(buildTrackRange(nextReferenceDate, clampedWindowDays));
189
251
  }
190
252
  }
191
253
  const getPreviewPercents = useCallback((range) => {
192
254
  var _a, _b;
193
255
  const start = (_a = range.startDate) !== null && _a !== void 0 ? _a : baseReferenceDate;
194
256
  const end = (_b = range.endDate) !== null && _b !== void 0 ? _b : start;
195
- const startR = getRatioByDate(start, trackBounds);
196
- const endR = getRatioByDate(end, trackBounds);
257
+ const currentTrackBounds = trackBoundsRef.current;
258
+ const startR = getRatioByDate(start, currentTrackBounds);
259
+ const endR = getRatioByDate(end, currentTrackBounds);
197
260
  const left = Math.min(startR, endR) * 100;
198
261
  const right = Math.max(startR, endR) * 100;
199
262
  const width = Math.max(right - left, 0.5);
@@ -205,7 +268,7 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
205
268
  startHandle: single ? Math.max(left - 0.8, 0) : left,
206
269
  endHandle: single ? Math.min(right + 0.8, 100) : right,
207
270
  };
208
- }, [baseReferenceDate, trackBounds]);
271
+ }, [baseReferenceDate]);
209
272
  const syncPreviewDom = useCallback((range) => {
210
273
  const percents = getPreviewPercents(range);
211
274
  if (selectionRef.current) {
@@ -229,17 +292,20 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
229
292
  dragPreviewRef.current = draftRange;
230
293
  syncPreviewDom(draftRange);
231
294
  }, [draftRange, syncPreviewDom]);
295
+ useEffect(() => {
296
+ trackBoundsRef.current = trackBounds;
297
+ }, [trackBounds]);
232
298
  function resetReferenceFromClientX(clientX) {
233
299
  if (!trackRef.current) {
234
300
  return;
235
301
  }
236
302
  const rect = trackRef.current.getBoundingClientRect();
237
- const ratio = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
303
+ const ratio = (clientX - rect.left) / rect.width;
238
304
  const nextReferenceDate = getDateByRatio(trackBounds, ratio);
239
305
  updateRangeByReference(nextReferenceDate, resolvedDefaultRangeDays, { preserveTrack: true });
240
306
  }
241
307
  function applyQuickRange(dayCount) {
242
- updateRangeByReference(referenceDate, dayCount);
308
+ updateRangeByReference(referenceDate, dayCount, { preserveTrack: true });
243
309
  }
244
310
  function shiftReferenceDateByMonths(monthOffset) {
245
311
  updateRangeByReference(addMonthsClamped(referenceDate, monthOffset), windowDays);
@@ -253,16 +319,17 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
253
319
  pointerIdRef.current = pointerId;
254
320
  dragStartRangeRef.current = Object.assign({}, draftRange);
255
321
  dragPreviewRef.current = Object.assign({}, draftRange);
322
+ dragStartTrackBoundsRef.current = Object.assign({}, trackBoundsRef.current);
256
323
  if (mode === 'window' &&
257
324
  clientX !== undefined &&
258
325
  trackRef.current &&
259
326
  draftRange.startDate &&
260
327
  draftRange.endDate &&
261
- trackBounds.startDate &&
262
- trackBounds.endDate) {
328
+ dragStartTrackBoundsRef.current.startDate &&
329
+ dragStartTrackBoundsRef.current.endDate) {
263
330
  const rect = trackRef.current.getBoundingClientRect();
264
- const ratio = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
265
- const pointerDate = getDateByRatio(trackBounds, ratio);
331
+ const ratio = (clientX - rect.left) / rect.width;
332
+ const pointerDate = getDateByRatio(dragStartTrackBoundsRef.current, ratio);
266
333
  windowDragOffsetDaysRef.current = getDaysBetween(draftRange.startDate, pointerDate);
267
334
  }
268
335
  else {
@@ -270,36 +337,62 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
270
337
  }
271
338
  }
272
339
  const buildDraggedRange = useCallback((clientX) => {
273
- if (!dragModeRef.current || !dragStartRangeRef.current || !trackBounds.startDate || !trackBounds.endDate || !trackRef.current) {
340
+ const currentTrackBounds = trackBoundsRef.current;
341
+ const dragStartTrackBounds = dragStartTrackBoundsRef.current;
342
+ if (!dragModeRef.current ||
343
+ !dragStartRangeRef.current ||
344
+ !(dragStartTrackBounds === null || dragStartTrackBounds === void 0 ? void 0 : dragStartTrackBounds.startDate) ||
345
+ !dragStartTrackBounds.endDate ||
346
+ !currentTrackBounds.startDate ||
347
+ !currentTrackBounds.endDate ||
348
+ !trackRef.current) {
274
349
  return null;
275
350
  }
276
351
  const rect = trackRef.current.getBoundingClientRect();
277
- const ratio = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
278
- const pointerDate = getDateByRatio(trackBounds, ratio);
352
+ const ratio = (clientX - rect.left) / rect.width;
353
+ const pointerDate = getDateByOverflowRatio(dragStartTrackBounds, ratio, rect.width);
279
354
  const currentRange = dragStartRangeRef.current;
280
355
  if (!currentRange.startDate || !currentRange.endDate) {
281
356
  return null;
282
357
  }
283
358
  if (dragModeRef.current === 'start') {
284
- const earliestStart = addDays(currentRange.endDate, -29);
359
+ const earliestStart = addDays(currentRange.endDate, -30);
285
360
  const boundedPointerDate = compareDateStrings(pointerDate, earliestStart) < 0 ? earliestStart : pointerDate;
286
361
  const nextStart = compareDateStrings(boundedPointerDate, currentRange.endDate) > 0 ? currentRange.endDate : boundedPointerDate;
287
- return { startDate: nextStart, endDate: currentRange.endDate };
362
+ const nextRange = { startDate: nextStart, endDate: currentRange.endDate };
363
+ const nextTrackBounds = ensureRangeVisibleOnTrack(nextRange, currentTrackBounds);
364
+ if (nextTrackBounds !== currentTrackBounds) {
365
+ trackBoundsRef.current = nextTrackBounds;
366
+ setDraftRange(nextRange);
367
+ setTrackBounds(nextTrackBounds);
368
+ }
369
+ return nextRange;
288
370
  }
289
371
  if (dragModeRef.current === 'end') {
290
372
  const latestEnd = addDays(currentRange.startDate, MAX_RANGE_DAYS - 1);
291
373
  const boundedPointerDate = compareDateStrings(pointerDate, latestEnd) > 0 ? latestEnd : pointerDate;
292
374
  const nextEnd = compareDateStrings(boundedPointerDate, currentRange.startDate) < 0 ? currentRange.startDate : boundedPointerDate;
293
- return { startDate: currentRange.startDate, endDate: nextEnd };
375
+ const nextRange = { startDate: currentRange.startDate, endDate: nextEnd };
376
+ const nextTrackBounds = ensureRangeVisibleOnTrack(nextRange, currentTrackBounds);
377
+ if (nextTrackBounds !== currentTrackBounds) {
378
+ trackBoundsRef.current = nextTrackBounds;
379
+ setDraftRange(nextRange);
380
+ setTrackBounds(nextTrackBounds);
381
+ }
382
+ return nextRange;
294
383
  }
295
384
  const spanDays = getDaysBetween(currentRange.startDate, currentRange.endDate);
296
- const nextStart = clampDateToRange(addDays(pointerDate, -windowDragOffsetDaysRef.current), {
297
- startDate: trackBounds.startDate,
298
- endDate: addDays(trackBounds.endDate, -spanDays),
299
- });
385
+ const nextStart = addDays(pointerDate, -windowDragOffsetDaysRef.current);
300
386
  const nextEnd = addDays(nextStart, spanDays);
301
- return { startDate: nextStart, endDate: nextEnd };
302
- }, [trackBounds]);
387
+ const nextRange = { startDate: nextStart, endDate: nextEnd };
388
+ const nextTrackBounds = ensureRangeVisibleOnTrack(nextRange, currentTrackBounds);
389
+ if (nextTrackBounds !== currentTrackBounds) {
390
+ trackBoundsRef.current = nextTrackBounds;
391
+ setDraftRange(nextRange);
392
+ setTrackBounds(nextTrackBounds);
393
+ }
394
+ return nextRange;
395
+ }, []);
303
396
  useEffect(() => {
304
397
  syncPreviewDomRef.current = syncPreviewDom;
305
398
  buildDraggedRangeRef.current = buildDraggedRange;
@@ -313,6 +406,7 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
313
406
  document.body.style.userSelect = '';
314
407
  const nextRange = dragPreviewRef.current;
315
408
  dragStartRangeRef.current = null;
409
+ dragStartTrackBoundsRef.current = null;
316
410
  dragModeRef.current = null;
317
411
  pointerIdRef.current = null;
318
412
  windowDragOffsetDaysRef.current = 0;
@@ -320,6 +414,7 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
320
414
  setDraftRange(nextRange);
321
415
  setReferenceDate(nextRange.startDate);
322
416
  setWindowDays(getInclusiveDayCount(nextRange));
417
+ commitTrackBounds(ensureRangeVisibleOnTrack(nextRange, trackBoundsRef.current));
323
418
  }
324
419
  }
325
420
  useEffect(() => {
@@ -370,76 +465,111 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
370
465
  };
371
466
  }, [open]);
372
467
  if (!open) {
373
- return null;
468
+ return jsx(Fragment, { children: dialogLoading });
374
469
  }
375
- return createPortal(jsx("div", { className: "fixed inset-0 z-120 flex select-none items-center justify-center bg-slate-950/60 px-3 py-6 backdrop-blur-sm", children: jsx("div", { className: "w-full max-w-2xl overflow-hidden rounded-3xl border border-black/10 bg-white shadow-2xl dark:border-white/10 dark:bg-slate-950", children: jsxs("div", { className: "space-y-5 p-4", children: [jsxs("div", { className: "relative flex items-center justify-center px-16 text-center", children: [jsx("div", { ref: resultLabelRef, className: "select-none text-base font-semibold text-slate-900 dark:text-white", children: getRangeLabel(draftRange) }), jsxs("div", { className: "absolute right-0 top-1/2 flex -translate-y-1/2 items-center gap-2", children: [jsx("button", { type: "button", onClick: () => onOpenChange(false), className: DIALOG_ICON_BUTTON_CLASS_NAME, "aria-label": "Cancel", children: jsx(XIcon, { className: "h-4 w-4" }) }), jsx("button", { type: "button", onClick: () => {
376
- onApply(draftRange);
377
- onOpenChange(false);
378
- }, disabled: !draftRange.startDate || !draftRange.endDate, className: cn(DIALOG_ICON_BUTTON_CLASS_NAME, 'text-slate-700 dark:text-slate-100', 'disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:border-black/10 disabled:hover:bg-white disabled:hover:text-slate-700 dark:disabled:hover:border-white/10 dark:disabled:hover:bg-slate-950 dark:disabled:hover:text-slate-100'), "aria-label": "Apply", children: jsx(CheckCheckIcon, { className: "h-4 w-4" }) })] })] }), jsxs("div", { className: "space-y-4", children: [jsxs("div", { className: "flex items-center justify-between gap-2", children: [jsxs("div", { className: "flex items-center gap-1", children: [jsx("button", Object.assign({ type: "button", onClick: () => {
379
- flashNavButtonPress('prevYear');
380
- shiftReferenceDateByYears(-1);
381
- }, className: cn(DIALOG_NAV_BUTTON_CLASS_NAME, pressedNavButton === 'prevYear'
382
- ? DIALOG_NAV_BUTTON_PRESSED_CLASS_NAME
383
- : DIALOG_NAV_BUTTON_REST_CLASS_NAME) }, getNavButtonPressProps('prevYear'), { "aria-label": "Previous year", title: "Previous year", children: jsx(ChevronsLeftIcon, { className: "h-4 w-4" }) })), jsx("button", Object.assign({ type: "button", onClick: () => {
384
- flashNavButtonPress('prevMonth');
385
- shiftReferenceDateByMonths(-1);
386
- }, className: cn(DIALOG_NAV_BUTTON_CLASS_NAME, pressedNavButton === 'prevMonth'
387
- ? DIALOG_NAV_BUTTON_PRESSED_CLASS_NAME
388
- : DIALOG_NAV_BUTTON_REST_CLASS_NAME) }, getNavButtonPressProps('prevMonth'), { "aria-label": "Previous month", title: "Previous month", children: jsx(ChevronLeftIcon, { className: "h-4 w-4" }) }))] }), jsxs("div", { className: "flex items-center gap-2", children: [jsx("button", { type: "button", onClick: () => {
389
- const nextRange = {
390
- startDate: baseReferenceDate,
391
- endDate: addDays(baseReferenceDate, resolvedDefaultRangeDays - 1),
392
- };
393
- setReferenceDate(baseReferenceDate);
394
- setTrackBounds(buildTrackRange(baseReferenceDate, resolvedDefaultRangeDays));
395
- setWindowDays(resolvedDefaultRangeDays);
396
- setDraftRange(nextRange);
397
- onClear === null || onClear === void 0 ? void 0 : onClear(nextRange);
398
- }, className: DIALOG_PILL_BUTTON_CLASS_NAME, children: "Current Day" }), jsx("button", { type: "button", onClick: () => {
399
- const nextRange = {
400
- startDate: getMonthStart(referenceDate),
401
- endDate: addDays(getMonthStart(referenceDate), MAX_RANGE_DAYS - 1),
402
- };
403
- const clampedEndDate = compareDateStrings(nextRange.endDate, getMonthEnd(referenceDate)) > 0
404
- ? getMonthEnd(referenceDate)
405
- : nextRange.endDate;
406
- const normalizedRange = {
407
- startDate: nextRange.startDate,
408
- endDate: clampedEndDate,
409
- };
410
- setDraftRange(normalizedRange);
411
- setWindowDays(getInclusiveDayCount(normalizedRange));
412
- setTrackBounds(buildTrackRange(normalizedRange.startDate, getInclusiveDayCount(normalizedRange)));
413
- }, className: DIALOG_PILL_BUTTON_CLASS_NAME, children: "This Month" })] }), jsxs("div", { className: "flex items-center gap-1", children: [jsx("button", Object.assign({ type: "button", onClick: () => {
414
- flashNavButtonPress('nextMonth');
415
- shiftReferenceDateByMonths(1);
416
- }, className: cn(DIALOG_NAV_BUTTON_CLASS_NAME, pressedNavButton === 'nextMonth'
417
- ? DIALOG_NAV_BUTTON_PRESSED_CLASS_NAME
418
- : DIALOG_NAV_BUTTON_REST_CLASS_NAME) }, getNavButtonPressProps('nextMonth'), { "aria-label": "Next month", title: "Next month", children: jsx(ChevronRightIcon, { className: "h-4 w-4" }) })), jsx("button", Object.assign({ type: "button", onClick: () => {
419
- flashNavButtonPress('nextYear');
420
- shiftReferenceDateByYears(1);
421
- }, className: cn(DIALOG_NAV_BUTTON_CLASS_NAME, pressedNavButton === 'nextYear'
422
- ? DIALOG_NAV_BUTTON_PRESSED_CLASS_NAME
423
- : DIALOG_NAV_BUTTON_REST_CLASS_NAME) }, getNavButtonPressProps('nextYear'), { "aria-label": "Next year", title: "Next year", children: jsx(ChevronsRightIcon, { className: "h-4 w-4" }) }))] })] }), jsxs("div", { className: "relative h-24", children: [jsxs("div", { className: "absolute inset-x-0 top-0 grid grid-cols-[3.5rem_minmax(0,1fr)_3.5rem] items-center gap-2 text-sm font-semibold text-slate-500 dark:text-slate-400", children: [jsxs("span", { className: "relative block select-none text-center", children: [(_g = monthLabels[0]) !== null && _g !== void 0 ? _g : formatMonthShort((_h = trackBounds.startDate) !== null && _h !== void 0 ? _h : baseReferenceDate), jsx("span", { className: "pointer-events-none absolute left-1/2 top-7 h-2.5 w-2.5 -translate-x-1/2 rounded-full bg-slate-400 dark:bg-slate-500" }), jsx("span", { className: "pointer-events-none absolute left-1/2 top-[1.95rem] h-9 w-0.5 -translate-x-1/2 bg-slate-400 dark:bg-slate-500" })] }), jsx("div", { className: "flex min-w-0 items-center justify-center gap-1", children: [
424
- { label: '+7', days: 7 },
425
- { label: '+10', days: 10 },
426
- { label: '+15', days: 15 },
427
- { label: '+30', days: 30 },
428
- ].map((item) => (jsx("button", { type: "button", onClick: () => applyQuickRange(item.days), className: DIALOG_PILL_BUTTON_COMPACT_CLASS_NAME, children: item.label }, item.label))) }), jsxs("span", { className: "relative block select-none text-center", children: [(_j = monthLabels[1]) !== null && _j !== void 0 ? _j : formatMonthShort((_k = trackBounds.endDate) !== null && _k !== void 0 ? _k : baseReferenceDate), jsx("span", { className: "pointer-events-none absolute right-1/2 top-7 h-2.5 w-2.5 translate-x-1/2 rounded-full bg-slate-400 dark:bg-slate-500" }), jsx("span", { className: "pointer-events-none absolute right-1/2 top-[1.95rem] h-9 w-0.5 translate-x-1/2 bg-slate-400 dark:bg-slate-500" })] })] }), jsx("div", { className: "absolute inset-x-0 top-[3.35rem] h-10 touch-none", onDoubleClick: (event) => {
429
- event.stopPropagation();
430
- resetReferenceFromClientX(event.clientX);
431
- }, children: jsxs("div", { ref: trackRef, className: "absolute inset-x-0 top-1/2 h-3 -translate-y-1/2 rounded-full bg-slate-400/30 dark:bg-slate-500/25", children: [jsx("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-x-0 top-1/2 grid h-8 -translate-y-1/2 items-center", style: { gridTemplateColumns: `repeat(${trackTickCount}, minmax(0, 1fr))` }, children: Array.from({ length: trackTickCount }, (_, index) => {
432
- return (jsx("span", { className: "flex justify-center", children: jsx("span", { className: cn('rounded-full bg-slate-400/55 dark:bg-slate-500/55', 'h-3 w-px') }) }, index));
433
- }) }), jsx("div", { ref: selectionRef, className: "absolute top-1/2 z-10 h-4 touch-none -translate-y-1/2 overflow-visible rounded-md border border-sky-500 bg-white dark:border-sky-300 dark:bg-slate-950", style: { left: `${leftPercent}%`, width: `${widthPercent}%` }, onPointerDown: (event) => {
434
- event.stopPropagation();
435
- beginDrag('window', event.pointerId, event.clientX);
436
- }, children: jsx("div", { ref: selectionDaysRef, className: "pointer-events-none absolute inset-0 z-30 flex select-none items-center justify-center text-xs font-semibold text-sky-700 dark:text-sky-100", children: `${getInclusiveDayCount(draftRange)}D` }) }), jsx("button", { ref: startHandleRef, type: "button", className: "absolute top-1/2 z-20 h-6 w-6 touch-none -translate-x-1/2 -translate-y-1/2 rounded-full border border-sky-500 bg-white shadow-sm dark:border-sky-300 dark:bg-slate-950", style: { left: `${startHandlePercent}%` }, onPointerDown: (event) => {
437
- event.stopPropagation();
438
- beginDrag('start', event.pointerId);
439
- }, "aria-label": "Adjust start date" }), jsx("button", { ref: endHandleRef, type: "button", className: "absolute top-1/2 z-20 h-6 w-6 touch-none -translate-x-1/2 -translate-y-1/2 rounded-full border border-sky-500 bg-white shadow-sm dark:border-sky-300 dark:bg-slate-950", style: { left: `${endHandlePercent}%` }, onPointerDown: (event) => {
440
- event.stopPropagation();
441
- beginDrag('end', event.pointerId);
442
- }, "aria-label": "Adjust end date" })] }) })] })] })] }) }) }), document.body);
470
+ return createPortal(jsxs(Fragment, { children: [jsx("div", { className: "fixed inset-0 z-120 flex select-none items-center justify-center bg-slate-950/60 px-3 py-6 backdrop-blur-sm", children: jsx("div", { className: "w-full max-w-2xl overflow-hidden rounded-3xl border border-black/10 bg-white shadow-2xl dark:border-white/10 dark:bg-slate-950", children: jsxs("div", { className: "space-y-5 p-4", children: [jsxs("div", { className: "relative flex items-center justify-center px-9 text-center sm:px-16", children: [jsx("div", { ref: resultLabelRef, className: "min-w-0 select-none truncate text-base font-semibold text-slate-900 dark:text-white", children: getRangeLabel(draftRange) }), jsx("div", { className: "absolute right-0 top-1/2 flex -translate-y-1/2 translate-x-1 items-center sm:translate-x-0", children: jsx("button", { type: "button", onClick: () => onOpenChange(false), className: DIALOG_ICON_BUTTON_CLASS_NAME, "aria-label": "Cancel", children: jsx(XIcon, { className: "h-4 w-4" }) }) })] }), jsxs("div", { className: "space-y-3", children: [jsxs("div", { className: "flex items-center justify-between gap-2", children: [jsxs("div", { className: "flex items-center gap-1", children: [jsx("button", Object.assign({ type: "button", onClick: () => {
471
+ flashNavButtonPress('prevYear');
472
+ shiftReferenceDateByYears(-1);
473
+ }, className: cn(DIALOG_NAV_BUTTON_CLASS_NAME, pressedNavButton === 'prevYear'
474
+ ? DIALOG_NAV_BUTTON_PRESSED_CLASS_NAME
475
+ : DIALOG_NAV_BUTTON_REST_CLASS_NAME) }, getNavButtonPressProps('prevYear'), { "aria-label": "Previous year", title: "Previous year", children: jsx(ChevronsLeftIcon, { className: "h-4 w-4" }) })), jsx("button", Object.assign({ type: "button", onClick: () => {
476
+ flashNavButtonPress('prevMonth');
477
+ shiftReferenceDateByMonths(-1);
478
+ }, className: cn(DIALOG_NAV_BUTTON_CLASS_NAME, pressedNavButton === 'prevMonth'
479
+ ? DIALOG_NAV_BUTTON_PRESSED_CLASS_NAME
480
+ : DIALOG_NAV_BUTTON_REST_CLASS_NAME) }, getNavButtonPressProps('prevMonth'), { "aria-label": "Previous month", title: "Previous month", children: jsx(ChevronLeftIcon, { className: "h-4 w-4" }) }))] }), jsxs("div", { className: "flex items-center gap-2", children: [jsx("button", { type: "button", onClick: () => {
481
+ const nextRange = {
482
+ startDate: baseReferenceDate,
483
+ endDate: addDays(baseReferenceDate, resolvedDefaultRangeDays - 1),
484
+ };
485
+ setReferenceDate(baseReferenceDate);
486
+ commitTrackBounds(buildTrackRange(baseReferenceDate, resolvedDefaultRangeDays));
487
+ setWindowDays(resolvedDefaultRangeDays);
488
+ setDraftRange(nextRange);
489
+ onClear === null || onClear === void 0 ? void 0 : onClear(nextRange);
490
+ }, className: DIALOG_PILL_BUTTON_CLASS_NAME, children: "Today" }), jsx("button", { type: "button", onClick: () => {
491
+ const nextRange = {
492
+ startDate: getMonthStart(referenceDate),
493
+ endDate: addDays(getMonthStart(referenceDate), MAX_RANGE_DAYS - 1),
494
+ };
495
+ const clampedEndDate = compareDateStrings(nextRange.endDate, getMonthEnd(referenceDate)) > 0
496
+ ? getMonthEnd(referenceDate)
497
+ : nextRange.endDate;
498
+ const normalizedRange = {
499
+ startDate: nextRange.startDate,
500
+ endDate: clampedEndDate,
501
+ };
502
+ setDraftRange(normalizedRange);
503
+ setWindowDays(getInclusiveDayCount(normalizedRange));
504
+ setReferenceDate(normalizedRange.startDate);
505
+ commitTrackBounds(buildTrackRange(normalizedRange.startDate, getInclusiveDayCount(normalizedRange)));
506
+ }, className: DIALOG_PILL_BUTTON_CLASS_NAME, children: "This Month" })] }), jsxs("div", { className: "flex items-center gap-1", children: [jsx("button", Object.assign({ type: "button", onClick: () => {
507
+ flashNavButtonPress('nextMonth');
508
+ shiftReferenceDateByMonths(1);
509
+ }, className: cn(DIALOG_NAV_BUTTON_CLASS_NAME, pressedNavButton === 'nextMonth'
510
+ ? DIALOG_NAV_BUTTON_PRESSED_CLASS_NAME
511
+ : DIALOG_NAV_BUTTON_REST_CLASS_NAME) }, getNavButtonPressProps('nextMonth'), { "aria-label": "Next month", title: "Next month", children: jsx(ChevronRightIcon, { className: "h-4 w-4" }) })), jsx("button", Object.assign({ type: "button", onClick: () => {
512
+ flashNavButtonPress('nextYear');
513
+ shiftReferenceDateByYears(1);
514
+ }, className: cn(DIALOG_NAV_BUTTON_CLASS_NAME, pressedNavButton === 'nextYear'
515
+ ? DIALOG_NAV_BUTTON_PRESSED_CLASS_NAME
516
+ : DIALOG_NAV_BUTTON_REST_CLASS_NAME) }, getNavButtonPressProps('nextYear'), { "aria-label": "Next year", title: "Next year", children: jsx(ChevronsRightIcon, { className: "h-4 w-4" }) }))] })] }), jsxs("div", { className: "relative h-21", children: [jsxs("div", { className: "absolute inset-x-0 top-0 grid grid-cols-[3.5rem_minmax(0,1fr)_3.5rem] items-center gap-2 text-sm font-semibold text-slate-500 dark:text-slate-400", children: [jsxs("span", { className: "relative block select-none text-center", children: [jsx(RollingMonthLabel, { value: leftMonthLabel }), jsx("span", { className: "pointer-events-none absolute left-1/2 top-7 h-2.5 w-2.5 -translate-x-1/2 rounded-full bg-slate-400 dark:bg-slate-500" }), jsx("span", { className: "pointer-events-none absolute left-1/2 top-[1.95rem] h-9 w-0.5 -translate-x-1/2 bg-slate-400 dark:bg-slate-500" })] }), jsx("div", { className: "flex min-w-0 items-center justify-center gap-1", children: [
517
+ { label: '+7', days: 7 },
518
+ { label: '+10', days: 10 },
519
+ { label: '+15', days: 15 },
520
+ { label: '+30', days: 30 },
521
+ ].map((item) => (jsx("button", { type: "button", onClick: () => applyQuickRange(item.days), className: DIALOG_PILL_BUTTON_COMPACT_CLASS_NAME, children: item.label }, item.label))) }), jsxs("span", { className: "relative block select-none text-center", children: [jsx(RollingMonthLabel, { value: rightMonthLabel }), jsx("span", { className: "pointer-events-none absolute right-1/2 top-7 h-2.5 w-2.5 translate-x-1/2 rounded-full bg-slate-400 dark:bg-slate-500" }), jsx("span", { className: "pointer-events-none absolute right-1/2 top-[1.95rem] h-9 w-0.5 translate-x-1/2 bg-slate-400 dark:bg-slate-500" })] })] }), jsx("div", { className: "absolute inset-x-0 top-[3.35rem] h-10 touch-none", onDoubleClick: (event) => {
522
+ event.stopPropagation();
523
+ resetReferenceFromClientX(event.clientX);
524
+ }, children: jsxs("div", { ref: trackRef, className: "absolute inset-x-0 top-1/2 h-3 -translate-y-1/2 rounded-full bg-slate-400/30 dark:bg-slate-500/25", children: [jsx("div", { "aria-hidden": "true", className: "pointer-events-none absolute inset-x-0 top-1/2 grid h-8 -translate-y-1/2 items-center", style: { gridTemplateColumns: `repeat(${trackTickCount}, minmax(0, 1fr))` }, children: Array.from({ length: trackTickCount }, (_, index) => {
525
+ return (jsx("span", { className: "flex justify-center", children: jsx("span", { className: cn('rounded-full bg-slate-400/55 dark:bg-slate-500/55', 'h-3 w-px') }) }, index));
526
+ }) }), jsx("div", { ref: selectionRef, className: "absolute top-1/2 z-10 h-4 touch-none -translate-y-1/2 overflow-visible rounded-md border bg-white dark:bg-slate-950", style: { left: `${leftPercent}%`, width: `${widthPercent}%`, borderColor: themeSvgIconColor }, onPointerDown: (event) => {
527
+ event.stopPropagation();
528
+ beginDrag('window', event.pointerId, event.clientX);
529
+ }, children: jsx("div", { ref: selectionDaysRef, className: "pointer-events-none absolute inset-0 z-30 flex select-none items-center justify-center text-xs font-semibold text-sky-700 dark:text-sky-100", children: `${getInclusiveDayCount(draftRange)}D` }) }), jsx("button", { ref: startHandleRef, type: "button", className: "absolute top-1/2 z-20 h-6 w-6 touch-none -translate-x-1/2 -translate-y-1/2 rounded-full border bg-white shadow-sm dark:bg-slate-950", style: { left: `${startHandlePercent}%`, borderColor: themeSvgIconColor }, onPointerDown: (event) => {
530
+ event.stopPropagation();
531
+ beginDrag('start', event.pointerId);
532
+ }, "aria-label": "Adjust start date" }), jsx("button", { ref: endHandleRef, type: "button", className: "absolute top-1/2 z-20 h-6 w-6 touch-none -translate-x-1/2 -translate-y-1/2 rounded-full border bg-white shadow-sm dark:bg-slate-950", style: { left: `${endHandlePercent}%`, borderColor: themeSvgIconColor }, onPointerDown: (event) => {
533
+ event.stopPropagation();
534
+ beginDrag('end', event.pointerId);
535
+ }, "aria-label": "Adjust end date" })] }) })] }), jsx("div", { className: "flex justify-end", children: jsx(XButton, { type: "single", variant: "soft", minWidth: "min-w-[110px]", className: "w-auto", iconClassName: "h-4 w-4", button: {
536
+ icon: jsx(CheckCheckIcon, {}),
537
+ text: 'Apply',
538
+ disabled: !draftRange.startDate || !draftRange.endDate,
539
+ onClick: () => {
540
+ void runDialogAction('confirm', handleApply);
541
+ },
542
+ } }) })] })] }) }) }), jsx("style", { children: `
543
+ @keyframes rd-date-range-month-in {
544
+ from {
545
+ opacity: 0;
546
+ transform: translateY(-0.45rem);
547
+ }
548
+ to {
549
+ opacity: 1;
550
+ transform: translateY(0);
551
+ }
552
+ }
553
+
554
+ @keyframes rd-date-range-month-out {
555
+ from {
556
+ opacity: 1;
557
+ transform: translateY(0);
558
+ }
559
+ to {
560
+ opacity: 0;
561
+ transform: translateY(0.45rem);
562
+ }
563
+ }
564
+
565
+ .rd-date-range-month-in {
566
+ animation: rd-date-range-month-in 180ms ease-out both;
567
+ }
568
+
569
+ .rd-date-range-month-out {
570
+ animation: rd-date-range-month-out 180ms ease-out both;
571
+ }
572
+ ` }), dialogLoading] }), document.body);
443
573
  }
444
574
 
445
575
  export { RandomDateRangeDialog };
package/dist/main/cta.js CHANGED
@@ -11,6 +11,22 @@ var utils = require('@windrun-huaiin/lib/utils');
11
11
  var richTextExpert = require('./rich-text-expert.js');
12
12
  var sectionLayout = require('./section-layout.js');
13
13
 
14
+ const CTA_THEME_PALETTES = {
15
+ purple: { b: '#EC4899', c: '#6366F1' },
16
+ orange: { b: '#F59E0B', c: '#EF4444' },
17
+ indigo: { b: '#3B82F6', c: '#06B6D4' },
18
+ emerald: { b: '#14B8A6', c: '#22C55E' },
19
+ rose: { b: '#EC4899', c: '#FB7185' },
20
+ };
21
+ function createCTAStyle() {
22
+ var _a;
23
+ const palette = (_a = CTA_THEME_PALETTES[lib.themeName]) !== null && _a !== void 0 ? _a : CTA_THEME_PALETTES.purple;
24
+ return {
25
+ '--cta-color-a': lib.themeSvgIconColor,
26
+ '--cta-color-b': palette.b,
27
+ '--cta-color-c': palette.c,
28
+ };
29
+ }
14
30
  function CTA(_a) {
15
31
  return tslib.__awaiter(this, arguments, void 0, function* ({ locale, sectionClassName }) {
16
32
  const t = yield server.getTranslations({ locale, namespace: 'cta' });
@@ -22,7 +38,7 @@ function CTA(_a) {
22
38
  button: t('button'),
23
39
  url: t('url')
24
40
  };
25
- return (jsxRuntime.jsx("section", { id: "cta", className: utils.cn(sectionLayout.responsiveSection, sectionClassName), children: jsxRuntime.jsxs("div", { className: "\n py-3 sm:py-6 md:8\n bg-linear-to-r from-[#f7f8fa] via-[#e0c3fc] to-[#b2fefa]\n dark:bg-linear-to-r dark:from-[#2d0b4e] dark:via-[#6a3fa0] dark:to-[#3a185a]\n rounded-2xl text-center\n bg-size[200%_auto] animate-cta-gradient-wave\n ", children: [jsxRuntime.jsxs("h2", { className: "text-3xl md:text-4xl font-bold mb-6", children: [data.title, " ", jsxRuntime.jsx("span", { className: lib.themeIconColor, children: data.eyesOn }), "?"] }), jsxRuntime.jsxs("p", { className: "text-base sm:text-xl mx-auto mb-8 max-w-3xl", children: [data.description1, jsxRuntime.jsx("br", {}), jsxRuntime.jsx("span", { className: utils.cn(lib.themeIconColor, "text-xl sm:text-2xl"), children: data.description2 })] }), jsxRuntime.jsx(gradientButton.GradientButton, { title: data.button, href: data.url, align: "center" })] }) }));
41
+ return (jsxRuntime.jsx("section", { id: "cta", className: utils.cn(sectionLayout.responsiveSection, sectionClassName), children: jsxRuntime.jsx("div", { className: "\n third-ui-cta-surface\n relative overflow-hidden rounded-2xl border border-black/5 py-3 text-center shadow-sm\n animate-cta-gradient-wave\n sm:py-6 md:py-8\n dark:border-white/10 dark:shadow-none\n ", style: createCTAStyle(), children: jsxRuntime.jsxs("div", { className: "relative z-10 px-4 sm:px-6", children: [jsxRuntime.jsxs("h2", { className: "mb-6 text-3xl font-bold text-neutral-950 md:text-4xl dark:text-neutral-50", children: [data.title, " ", jsxRuntime.jsx("span", { className: lib.themeIconColor, children: data.eyesOn }), "?"] }), jsxRuntime.jsxs("p", { className: "mx-auto mb-8 max-w-3xl text-base text-neutral-700 sm:text-xl dark:text-neutral-300", children: [data.description1, jsxRuntime.jsx("br", {}), jsxRuntime.jsx("span", { className: utils.cn(lib.themeIconColor, "text-xl sm:text-2xl"), children: data.description2 })] }), jsxRuntime.jsx(gradientButton.GradientButton, { title: data.button, href: data.url, align: "center" })] }) }) }));
26
42
  });
27
43
  }
28
44
 
package/dist/main/cta.mjs CHANGED
@@ -4,11 +4,27 @@ import { getTranslations } from 'next-intl/server';
4
4
  import { GradientButton } from './buttons/gradient-button.mjs';
5
5
  import 'react';
6
6
  import '@windrun-huaiin/base-ui/icons';
7
- import { themeIconColor } from '@windrun-huaiin/base-ui/lib';
7
+ import { themeIconColor, themeSvgIconColor, themeName } from '@windrun-huaiin/base-ui/lib';
8
8
  import { cn } from '@windrun-huaiin/lib/utils';
9
9
  import { richText } from './rich-text-expert.mjs';
10
10
  import { responsiveSection } from './section-layout.mjs';
11
11
 
12
+ const CTA_THEME_PALETTES = {
13
+ purple: { b: '#EC4899', c: '#6366F1' },
14
+ orange: { b: '#F59E0B', c: '#EF4444' },
15
+ indigo: { b: '#3B82F6', c: '#06B6D4' },
16
+ emerald: { b: '#14B8A6', c: '#22C55E' },
17
+ rose: { b: '#EC4899', c: '#FB7185' },
18
+ };
19
+ function createCTAStyle() {
20
+ var _a;
21
+ const palette = (_a = CTA_THEME_PALETTES[themeName]) !== null && _a !== void 0 ? _a : CTA_THEME_PALETTES.purple;
22
+ return {
23
+ '--cta-color-a': themeSvgIconColor,
24
+ '--cta-color-b': palette.b,
25
+ '--cta-color-c': palette.c,
26
+ };
27
+ }
12
28
  function CTA(_a) {
13
29
  return __awaiter(this, arguments, void 0, function* ({ locale, sectionClassName }) {
14
30
  const t = yield getTranslations({ locale, namespace: 'cta' });
@@ -20,7 +36,7 @@ function CTA(_a) {
20
36
  button: t('button'),
21
37
  url: t('url')
22
38
  };
23
- return (jsx("section", { id: "cta", className: cn(responsiveSection, sectionClassName), children: jsxs("div", { className: "\n py-3 sm:py-6 md:8\n bg-linear-to-r from-[#f7f8fa] via-[#e0c3fc] to-[#b2fefa]\n dark:bg-linear-to-r dark:from-[#2d0b4e] dark:via-[#6a3fa0] dark:to-[#3a185a]\n rounded-2xl text-center\n bg-size[200%_auto] animate-cta-gradient-wave\n ", children: [jsxs("h2", { className: "text-3xl md:text-4xl font-bold mb-6", children: [data.title, " ", jsx("span", { className: themeIconColor, children: data.eyesOn }), "?"] }), jsxs("p", { className: "text-base sm:text-xl mx-auto mb-8 max-w-3xl", children: [data.description1, jsx("br", {}), jsx("span", { className: cn(themeIconColor, "text-xl sm:text-2xl"), children: data.description2 })] }), jsx(GradientButton, { title: data.button, href: data.url, align: "center" })] }) }));
39
+ return (jsx("section", { id: "cta", className: cn(responsiveSection, sectionClassName), children: jsx("div", { className: "\n third-ui-cta-surface\n relative overflow-hidden rounded-2xl border border-black/5 py-3 text-center shadow-sm\n animate-cta-gradient-wave\n sm:py-6 md:py-8\n dark:border-white/10 dark:shadow-none\n ", style: createCTAStyle(), children: jsxs("div", { className: "relative z-10 px-4 sm:px-6", children: [jsxs("h2", { className: "mb-6 text-3xl font-bold text-neutral-950 md:text-4xl dark:text-neutral-50", children: [data.title, " ", jsx("span", { className: themeIconColor, children: data.eyesOn }), "?"] }), jsxs("p", { className: "mx-auto mb-8 max-w-3xl text-base text-neutral-700 sm:text-xl dark:text-neutral-300", children: [data.description1, jsx("br", {}), jsx("span", { className: cn(themeIconColor, "text-xl sm:text-2xl"), children: data.description2 })] }), jsx(GradientButton, { title: data.button, href: data.url, align: "center" })] }) }) }));
24
40
  });
25
41
  }
26
42