@windrun-huaiin/third-ui 29.2.1 → 30.1.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 (121) hide show
  1. package/dist/fuma/fuma-page-genarator.d.ts +2 -6
  2. package/dist/fuma/fuma-page-genarator.js +3 -2
  3. package/dist/fuma/fuma-page-genarator.mjs +3 -2
  4. package/dist/fuma/mdx/cheet-table.d.ts +13 -0
  5. package/dist/fuma/mdx/cheet-table.js +295 -0
  6. package/dist/fuma/mdx/cheet-table.mjs +293 -0
  7. package/dist/fuma/mdx/index.d.ts +1 -0
  8. package/dist/fuma/mdx/index.js +2 -0
  9. package/dist/fuma/mdx/index.mjs +1 -0
  10. package/dist/fuma/server/features/widgets.js +2 -0
  11. package/dist/fuma/server/features/widgets.mjs +2 -0
  12. package/dist/lib/fuma-schema-check-util.d.ts +1 -1
  13. package/dist/main/404-page.d.ts +12 -0
  14. package/dist/main/404-page.js +66 -0
  15. package/dist/main/404-page.mjs +64 -0
  16. package/dist/main/alert-dialog/confirm-dialog.js +1 -1
  17. package/dist/main/alert-dialog/confirm-dialog.mjs +2 -2
  18. package/dist/main/alert-dialog/dialog-loading-action.js +5 -2
  19. package/dist/main/alert-dialog/dialog-loading-action.mjs +5 -2
  20. package/dist/main/alert-dialog/dialog-styles.d.ts +4 -2
  21. package/dist/main/alert-dialog/dialog-styles.js +8 -4
  22. package/dist/main/alert-dialog/dialog-styles.mjs +7 -5
  23. package/dist/main/alert-dialog/high-priority-confirm-dialog.js +5 -5
  24. package/dist/main/alert-dialog/high-priority-confirm-dialog.mjs +6 -6
  25. package/dist/main/alert-dialog/info-dialog.js +1 -1
  26. package/dist/main/alert-dialog/info-dialog.mjs +2 -2
  27. package/dist/main/alert-dialog/undoable-confirm-dialog.js +2 -2
  28. package/dist/main/alert-dialog/undoable-confirm-dialog.mjs +3 -3
  29. package/dist/main/anime/anime-404-page.d.ts +14 -0
  30. package/dist/main/anime/anime-404-page.js +197 -0
  31. package/dist/main/anime/anime-404-page.mjs +195 -0
  32. package/dist/main/anime/anime-beam-frame.d.ts +3 -0
  33. package/dist/main/anime/anime-beam-frame.js +63 -0
  34. package/dist/main/anime/anime-beam-frame.mjs +61 -0
  35. package/dist/main/anime/anime-not-found-page.d.ts +7 -0
  36. package/dist/main/anime/anime-not-found-page.js +142 -0
  37. package/dist/main/anime/anime-not-found-page.mjs +140 -0
  38. package/dist/main/anime/anime-spiral-loading.d.ts +10 -0
  39. package/dist/main/anime/anime-spiral-loading.js +77 -0
  40. package/dist/main/anime/anime-spiral-loading.mjs +75 -0
  41. package/dist/main/anime/index.d.ts +3 -0
  42. package/dist/main/anime/index.js +12 -0
  43. package/dist/main/anime/index.mjs +4 -0
  44. package/dist/main/beam-frame/animate.d.ts +3 -0
  45. package/dist/main/beam-frame/animate.js +63 -0
  46. package/dist/main/beam-frame/animate.mjs +61 -0
  47. package/dist/main/beam-frame/beam-frame.d.ts +4 -0
  48. package/dist/main/beam-frame/beam-frame.js +262 -0
  49. package/dist/main/beam-frame/beam-frame.mjs +258 -0
  50. package/dist/main/beam-frame/index.d.ts +4 -0
  51. package/dist/main/beam-frame/index.js +11 -0
  52. package/dist/main/beam-frame/index.mjs +3 -0
  53. package/dist/main/beam-frame/motion.d.ts +3 -0
  54. package/dist/main/beam-frame/motion.js +61 -0
  55. package/dist/main/beam-frame/motion.mjs +59 -0
  56. package/dist/main/beam-frame/share-config.d.ts +54 -0
  57. package/dist/main/beam-frame/share-config.js +161 -0
  58. package/dist/main/beam-frame/share-config.mjs +152 -0
  59. package/dist/main/beam-frame-config.d.ts +54 -0
  60. package/dist/main/beam-frame-config.js +161 -0
  61. package/dist/main/beam-frame-config.mjs +152 -0
  62. package/dist/main/calendar/random-date-range-dialog.js +177 -51
  63. package/dist/main/calendar/random-date-range-dialog.mjs +178 -52
  64. package/dist/main/cta.js +17 -1
  65. package/dist/main/cta.mjs +18 -2
  66. package/dist/main/delayed-img.d.ts +1 -1
  67. package/dist/main/delayed-img.js +8 -5
  68. package/dist/main/delayed-img.mjs +8 -5
  69. package/dist/main/index.d.ts +1 -0
  70. package/dist/main/index.js +2 -0
  71. package/dist/main/index.mjs +1 -0
  72. package/dist/main/info-tooltip.js +70 -9
  73. package/dist/main/info-tooltip.mjs +70 -9
  74. package/dist/main/loading-frame/index.d.ts +1 -0
  75. package/dist/main/loading.d.ts +2 -1
  76. package/dist/main/loading.js +64 -26
  77. package/dist/main/loading.mjs +64 -26
  78. package/dist/main/motion/creative-left-panel.d.ts +7 -0
  79. package/dist/main/motion/creative-left-panel.js +11 -0
  80. package/dist/main/motion/creative-left-panel.mjs +9 -0
  81. package/dist/main/motion/creative-right-panel.d.ts +7 -0
  82. package/dist/main/motion/creative-right-panel.js +11 -0
  83. package/dist/main/motion/creative-right-panel.mjs +9 -0
  84. package/dist/main/motion/index.d.ts +1 -0
  85. package/dist/main/motion/index.js +9 -0
  86. package/dist/main/motion/index.mjs +2 -0
  87. package/dist/main/motion/motion-beam-frame.d.ts +3 -0
  88. package/dist/main/motion/motion-beam-frame.js +61 -0
  89. package/dist/main/motion/motion-beam-frame.mjs +59 -0
  90. package/dist/main/snake-loading-frame.d.ts +7 -3
  91. package/dist/main/snake-loading-frame.js +45 -252
  92. package/dist/main/snake-loading-frame.mjs +47 -254
  93. package/package.json +16 -5
  94. package/src/fuma/fuma-page-genarator.tsx +2 -22
  95. package/src/fuma/mdx/cheet-table.tsx +650 -0
  96. package/src/fuma/mdx/index.ts +1 -0
  97. package/src/fuma/server/features/widgets.tsx +2 -0
  98. package/src/main/404-page.tsx +162 -0
  99. package/src/main/alert-dialog/confirm-dialog.tsx +2 -1
  100. package/src/main/alert-dialog/dialog-loading-action.tsx +7 -5
  101. package/src/main/alert-dialog/dialog-styles.ts +13 -3
  102. package/src/main/alert-dialog/high-priority-confirm-dialog.tsx +26 -23
  103. package/src/main/alert-dialog/info-dialog.tsx +2 -1
  104. package/src/main/alert-dialog/undoable-confirm-dialog.tsx +18 -17
  105. package/src/main/anime/anime-404-page.tsx +344 -0
  106. package/src/main/anime/anime-beam-frame.tsx +128 -0
  107. package/src/main/anime/anime-spiral-loading.tsx +123 -0
  108. package/src/main/anime/index.ts +10 -0
  109. package/src/main/beam-frame-config.tsx +341 -0
  110. package/src/main/calendar/random-date-range-dialog.tsx +225 -69
  111. package/src/main/cta.tsx +50 -21
  112. package/src/main/delayed-img.tsx +9 -4
  113. package/src/main/index.ts +1 -0
  114. package/src/main/info-tooltip.tsx +116 -20
  115. package/src/main/loading-frame/index.ts +4 -0
  116. package/src/main/loading.tsx +75 -24
  117. package/src/main/motion/index.ts +8 -0
  118. package/src/main/motion/motion-beam-frame.tsx +137 -0
  119. package/src/main/snake-loading-frame.tsx +95 -496
  120. package/src/styles/cta.css +21 -4
  121. package/src/styles/third-ui.css +0 -20
@@ -5,15 +5,17 @@ var jsxRuntime = require('react/jsx-runtime');
5
5
  var React = require('react');
6
6
  var reactDom = require('react-dom');
7
7
  var icons = require('@windrun-huaiin/base-ui/icons');
8
+ var lib = require('@windrun-huaiin/base-ui/lib');
8
9
  var utils = require('@windrun-huaiin/lib/utils');
9
10
  var dialogLoadingAction = require('../alert-dialog/dialog-loading-action.js');
11
+ var xButton = require('../buttons/x-button.js');
10
12
  var usePressFeedback = require('../buttons/use-press-feedback.js');
11
13
 
12
14
  const DEFAULT_RANGE_DAYS = 7;
13
- const MAX_RANGE_DAYS = 30;
14
- const TRACK_MIN_DAYS = 45;
15
- const TRACK_PADDING_DAYS = 20;
16
- 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';
15
+ const MAX_RANGE_DAYS = 31;
16
+ const VISIBLE_TRACK_DAYS = 36;
17
+ const EDGE_OVERFLOW_PIXELS_PER_DAY = 24;
18
+ 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';
17
19
  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';
18
20
  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';
19
21
  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)]';
@@ -55,12 +57,31 @@ function clampWindowDays(days) {
55
57
  }
56
58
  function buildTrackRange(referenceDate, windowDays = DEFAULT_RANGE_DAYS) {
57
59
  const resolvedWindowDays = clampWindowDays(windowDays);
58
- const resolvedTotalDays = Math.max(TRACK_MIN_DAYS, resolvedWindowDays + TRACK_PADDING_DAYS);
59
- const daysBefore = Math.floor((resolvedTotalDays - resolvedWindowDays) / 3);
60
+ const daysBefore = Math.floor((VISIBLE_TRACK_DAYS - resolvedWindowDays) / 3);
60
61
  const startDate = addDays(referenceDate, -daysBefore);
61
- const endDate = addDays(startDate, resolvedTotalDays - 1);
62
+ const endDate = addDays(startDate, VISIBLE_TRACK_DAYS - 1);
62
63
  return { startDate, endDate };
63
64
  }
65
+ function ensureRangeVisibleOnTrack(range, bounds) {
66
+ if (!range.startDate || !range.endDate || !bounds.startDate || !bounds.endDate) {
67
+ return bounds;
68
+ }
69
+ let nextStartDate = bounds.startDate;
70
+ if (compareDateStrings(range.startDate, nextStartDate) < 0) {
71
+ nextStartDate = range.startDate;
72
+ }
73
+ const nextEndDate = addDays(nextStartDate, VISIBLE_TRACK_DAYS - 1);
74
+ if (compareDateStrings(range.endDate, nextEndDate) > 0) {
75
+ nextStartDate = addDays(range.endDate, -35);
76
+ }
77
+ if (nextStartDate === bounds.startDate && addDays(nextStartDate, VISIBLE_TRACK_DAYS - 1) === bounds.endDate) {
78
+ return bounds;
79
+ }
80
+ return {
81
+ startDate: nextStartDate,
82
+ endDate: addDays(nextStartDate, VISIBLE_TRACK_DAYS - 1),
83
+ };
84
+ }
64
85
  function clampDateToRange(date, bounds) {
65
86
  if (!bounds.startDate || !bounds.endDate) {
66
87
  return date;
@@ -83,6 +104,19 @@ function getDateByRatio(bounds, ratio) {
83
104
  return getTodayString();
84
105
  }
85
106
  const totalDays = Math.max(1, getDaysBetween(bounds.startDate, bounds.endDate));
107
+ return addDays(bounds.startDate, Math.round(totalDays * Math.max(0, Math.min(1, ratio))));
108
+ }
109
+ function getDateByOverflowRatio(bounds, ratio, trackWidth) {
110
+ if (!bounds.startDate || !bounds.endDate) {
111
+ return getTodayString();
112
+ }
113
+ const totalDays = Math.max(1, getDaysBetween(bounds.startDate, bounds.endDate));
114
+ if (ratio < 0) {
115
+ return addDays(bounds.startDate, Math.floor((ratio * trackWidth) / EDGE_OVERFLOW_PIXELS_PER_DAY));
116
+ }
117
+ if (ratio > 1) {
118
+ return addDays(bounds.endDate, Math.ceil(((ratio - 1) * trackWidth) / EDGE_OVERFLOW_PIXELS_PER_DAY));
119
+ }
86
120
  return addDays(bounds.startDate, Math.round(totalDays * ratio));
87
121
  }
88
122
  function getRatioByDate(date, bounds) {
@@ -119,8 +153,24 @@ function getMonthEnd(value) {
119
153
  const date = parseDateString(value);
120
154
  return formatDateString(new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + 1, 0)));
121
155
  }
156
+ function RollingMonthLabel({ value }) {
157
+ const [displayValue, setDisplayValue] = React.useState(value);
158
+ const [previousValue, setPreviousValue] = React.useState(null);
159
+ React.useEffect(() => {
160
+ if (value === displayValue) {
161
+ return undefined;
162
+ }
163
+ setPreviousValue(displayValue);
164
+ setDisplayValue(value);
165
+ const timeout = window.setTimeout(() => {
166
+ setPreviousValue(null);
167
+ }, 180);
168
+ return () => window.clearTimeout(timeout);
169
+ }, [displayValue, value]);
170
+ return (jsxRuntime.jsxs("span", { className: "relative inline-block h-5 min-w-10 overflow-hidden align-bottom", children: [previousValue ? (jsxRuntime.jsx("span", { className: "rd-date-range-month-out absolute inset-x-0 top-0 text-center", children: previousValue })) : null, jsxRuntime.jsx("span", { className: utils.cn('absolute inset-x-0 top-0 text-center', previousValue && 'rd-date-range-month-in'), children: displayValue })] }));
171
+ }
122
172
  function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEFAULT_RANGE_DAYS, onOpenChange, loadingActions, loadingFullPage, onApply, onClear, }) {
123
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
173
+ var _a, _b, _c, _d, _e, _f;
124
174
  const resolvedDefaultRangeDays = clampWindowDays(defaultRangeDays);
125
175
  const [draftRange, setDraftRange] = React.useState(value);
126
176
  const [referenceDate, setReferenceDate] = React.useState(anchorDate);
@@ -138,6 +188,8 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
138
188
  const resultLabelRef = React.useRef(null);
139
189
  const selectionDaysRef = React.useRef(null);
140
190
  const dragPreviewRef = React.useRef(null);
191
+ const trackBoundsRef = React.useRef(trackBounds);
192
+ const dragStartTrackBoundsRef = React.useRef(null);
141
193
  const frameRef = React.useRef(null);
142
194
  const pendingClientXRef = React.useRef(null);
143
195
  const syncPreviewDomRef = React.useRef(() => { });
@@ -155,25 +207,27 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
155
207
  const isSingleDay = ((_c = draftRange.startDate) !== null && _c !== void 0 ? _c : null) === ((_d = draftRange.endDate) !== null && _d !== void 0 ? _d : null);
156
208
  const startHandlePercent = isSingleDay ? Math.max(leftPercent - 0.8, 0) : leftPercent;
157
209
  const endHandlePercent = isSingleDay ? Math.min(rightPercent + 0.8, 100) : rightPercent;
158
- 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);
159
- const monthLabels = React.useMemo(() => {
160
- const values = [trackBounds.startDate, trackBounds.endDate]
161
- .filter((item) => Boolean(item))
162
- .map((item) => formatMonthShort(item));
163
- return [...new Set(values)];
164
- }, [trackBounds.endDate, trackBounds.startDate]);
210
+ const trackTickCount = VISIBLE_TRACK_DAYS;
211
+ const leftMonthLabel = formatMonthShort((_e = trackBounds.startDate) !== null && _e !== void 0 ? _e : baseReferenceDate);
212
+ const rightMonthLabel = formatMonthShort((_f = trackBounds.endDate) !== null && _f !== void 0 ? _f : baseReferenceDate);
165
213
  const handleApply = React.useCallback(() => {
166
214
  return onApply(draftRange);
167
215
  }, [draftRange, onApply]);
216
+ function commitTrackBounds(nextTrackBounds) {
217
+ trackBoundsRef.current = nextTrackBounds;
218
+ setTrackBounds(nextTrackBounds);
219
+ }
168
220
  React.useEffect(() => {
169
221
  if (open && !previousOpenRef.current) {
222
+ const nextTrackBounds = buildTrackRange(baseReferenceDate, resolvedDefaultRangeDays);
170
223
  const nextRange = {
171
224
  startDate: baseReferenceDate,
172
225
  endDate: addDays(baseReferenceDate, resolvedDefaultRangeDays - 1),
173
226
  };
174
227
  setDraftRange(nextRange);
175
228
  setReferenceDate(baseReferenceDate);
176
- setTrackBounds(buildTrackRange(baseReferenceDate, resolvedDefaultRangeDays));
229
+ trackBoundsRef.current = nextTrackBounds;
230
+ setTrackBounds(nextTrackBounds);
177
231
  setWindowDays(resolvedDefaultRangeDays);
178
232
  dragStartRangeRef.current = null;
179
233
  dragModeRef.current = null;
@@ -191,16 +245,20 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
191
245
  setReferenceDate(nextReferenceDate);
192
246
  setWindowDays(clampedWindowDays);
193
247
  setDraftRange(nextRange);
194
- if (!(options === null || options === void 0 ? void 0 : options.preserveTrack)) {
195
- setTrackBounds(buildTrackRange(nextReferenceDate, clampedWindowDays));
248
+ if (options === null || options === void 0 ? void 0 : options.preserveTrack) {
249
+ commitTrackBounds(ensureRangeVisibleOnTrack(nextRange, trackBoundsRef.current));
250
+ }
251
+ else {
252
+ commitTrackBounds(buildTrackRange(nextReferenceDate, clampedWindowDays));
196
253
  }
197
254
  }
198
255
  const getPreviewPercents = React.useCallback((range) => {
199
256
  var _a, _b;
200
257
  const start = (_a = range.startDate) !== null && _a !== void 0 ? _a : baseReferenceDate;
201
258
  const end = (_b = range.endDate) !== null && _b !== void 0 ? _b : start;
202
- const startR = getRatioByDate(start, trackBounds);
203
- const endR = getRatioByDate(end, trackBounds);
259
+ const currentTrackBounds = trackBoundsRef.current;
260
+ const startR = getRatioByDate(start, currentTrackBounds);
261
+ const endR = getRatioByDate(end, currentTrackBounds);
204
262
  const left = Math.min(startR, endR) * 100;
205
263
  const right = Math.max(startR, endR) * 100;
206
264
  const width = Math.max(right - left, 0.5);
@@ -212,7 +270,7 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
212
270
  startHandle: single ? Math.max(left - 0.8, 0) : left,
213
271
  endHandle: single ? Math.min(right + 0.8, 100) : right,
214
272
  };
215
- }, [baseReferenceDate, trackBounds]);
273
+ }, [baseReferenceDate]);
216
274
  const syncPreviewDom = React.useCallback((range) => {
217
275
  const percents = getPreviewPercents(range);
218
276
  if (selectionRef.current) {
@@ -236,17 +294,20 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
236
294
  dragPreviewRef.current = draftRange;
237
295
  syncPreviewDom(draftRange);
238
296
  }, [draftRange, syncPreviewDom]);
297
+ React.useEffect(() => {
298
+ trackBoundsRef.current = trackBounds;
299
+ }, [trackBounds]);
239
300
  function resetReferenceFromClientX(clientX) {
240
301
  if (!trackRef.current) {
241
302
  return;
242
303
  }
243
304
  const rect = trackRef.current.getBoundingClientRect();
244
- const ratio = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
305
+ const ratio = (clientX - rect.left) / rect.width;
245
306
  const nextReferenceDate = getDateByRatio(trackBounds, ratio);
246
307
  updateRangeByReference(nextReferenceDate, resolvedDefaultRangeDays, { preserveTrack: true });
247
308
  }
248
309
  function applyQuickRange(dayCount) {
249
- updateRangeByReference(referenceDate, dayCount);
310
+ updateRangeByReference(referenceDate, dayCount, { preserveTrack: true });
250
311
  }
251
312
  function shiftReferenceDateByMonths(monthOffset) {
252
313
  updateRangeByReference(addMonthsClamped(referenceDate, monthOffset), windowDays);
@@ -260,16 +321,17 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
260
321
  pointerIdRef.current = pointerId;
261
322
  dragStartRangeRef.current = Object.assign({}, draftRange);
262
323
  dragPreviewRef.current = Object.assign({}, draftRange);
324
+ dragStartTrackBoundsRef.current = Object.assign({}, trackBoundsRef.current);
263
325
  if (mode === 'window' &&
264
326
  clientX !== undefined &&
265
327
  trackRef.current &&
266
328
  draftRange.startDate &&
267
329
  draftRange.endDate &&
268
- trackBounds.startDate &&
269
- trackBounds.endDate) {
330
+ dragStartTrackBoundsRef.current.startDate &&
331
+ dragStartTrackBoundsRef.current.endDate) {
270
332
  const rect = trackRef.current.getBoundingClientRect();
271
- const ratio = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
272
- const pointerDate = getDateByRatio(trackBounds, ratio);
333
+ const ratio = (clientX - rect.left) / rect.width;
334
+ const pointerDate = getDateByRatio(dragStartTrackBoundsRef.current, ratio);
273
335
  windowDragOffsetDaysRef.current = getDaysBetween(draftRange.startDate, pointerDate);
274
336
  }
275
337
  else {
@@ -277,36 +339,62 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
277
339
  }
278
340
  }
279
341
  const buildDraggedRange = React.useCallback((clientX) => {
280
- if (!dragModeRef.current || !dragStartRangeRef.current || !trackBounds.startDate || !trackBounds.endDate || !trackRef.current) {
342
+ const currentTrackBounds = trackBoundsRef.current;
343
+ const dragStartTrackBounds = dragStartTrackBoundsRef.current;
344
+ if (!dragModeRef.current ||
345
+ !dragStartRangeRef.current ||
346
+ !(dragStartTrackBounds === null || dragStartTrackBounds === void 0 ? void 0 : dragStartTrackBounds.startDate) ||
347
+ !dragStartTrackBounds.endDate ||
348
+ !currentTrackBounds.startDate ||
349
+ !currentTrackBounds.endDate ||
350
+ !trackRef.current) {
281
351
  return null;
282
352
  }
283
353
  const rect = trackRef.current.getBoundingClientRect();
284
- const ratio = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
285
- const pointerDate = getDateByRatio(trackBounds, ratio);
354
+ const ratio = (clientX - rect.left) / rect.width;
355
+ const pointerDate = getDateByOverflowRatio(dragStartTrackBounds, ratio, rect.width);
286
356
  const currentRange = dragStartRangeRef.current;
287
357
  if (!currentRange.startDate || !currentRange.endDate) {
288
358
  return null;
289
359
  }
290
360
  if (dragModeRef.current === 'start') {
291
- const earliestStart = addDays(currentRange.endDate, -29);
361
+ const earliestStart = addDays(currentRange.endDate, -30);
292
362
  const boundedPointerDate = compareDateStrings(pointerDate, earliestStart) < 0 ? earliestStart : pointerDate;
293
363
  const nextStart = compareDateStrings(boundedPointerDate, currentRange.endDate) > 0 ? currentRange.endDate : boundedPointerDate;
294
- return { startDate: nextStart, endDate: currentRange.endDate };
364
+ const nextRange = { startDate: nextStart, endDate: currentRange.endDate };
365
+ const nextTrackBounds = ensureRangeVisibleOnTrack(nextRange, currentTrackBounds);
366
+ if (nextTrackBounds !== currentTrackBounds) {
367
+ trackBoundsRef.current = nextTrackBounds;
368
+ setDraftRange(nextRange);
369
+ setTrackBounds(nextTrackBounds);
370
+ }
371
+ return nextRange;
295
372
  }
296
373
  if (dragModeRef.current === 'end') {
297
374
  const latestEnd = addDays(currentRange.startDate, MAX_RANGE_DAYS - 1);
298
375
  const boundedPointerDate = compareDateStrings(pointerDate, latestEnd) > 0 ? latestEnd : pointerDate;
299
376
  const nextEnd = compareDateStrings(boundedPointerDate, currentRange.startDate) < 0 ? currentRange.startDate : boundedPointerDate;
300
- return { startDate: currentRange.startDate, endDate: nextEnd };
377
+ const nextRange = { startDate: currentRange.startDate, endDate: nextEnd };
378
+ const nextTrackBounds = ensureRangeVisibleOnTrack(nextRange, currentTrackBounds);
379
+ if (nextTrackBounds !== currentTrackBounds) {
380
+ trackBoundsRef.current = nextTrackBounds;
381
+ setDraftRange(nextRange);
382
+ setTrackBounds(nextTrackBounds);
383
+ }
384
+ return nextRange;
301
385
  }
302
386
  const spanDays = getDaysBetween(currentRange.startDate, currentRange.endDate);
303
- const nextStart = clampDateToRange(addDays(pointerDate, -windowDragOffsetDaysRef.current), {
304
- startDate: trackBounds.startDate,
305
- endDate: addDays(trackBounds.endDate, -spanDays),
306
- });
387
+ const nextStart = addDays(pointerDate, -windowDragOffsetDaysRef.current);
307
388
  const nextEnd = addDays(nextStart, spanDays);
308
- return { startDate: nextStart, endDate: nextEnd };
309
- }, [trackBounds]);
389
+ const nextRange = { startDate: nextStart, endDate: nextEnd };
390
+ const nextTrackBounds = ensureRangeVisibleOnTrack(nextRange, currentTrackBounds);
391
+ if (nextTrackBounds !== currentTrackBounds) {
392
+ trackBoundsRef.current = nextTrackBounds;
393
+ setDraftRange(nextRange);
394
+ setTrackBounds(nextTrackBounds);
395
+ }
396
+ return nextRange;
397
+ }, []);
310
398
  React.useEffect(() => {
311
399
  syncPreviewDomRef.current = syncPreviewDom;
312
400
  buildDraggedRangeRef.current = buildDraggedRange;
@@ -320,6 +408,7 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
320
408
  document.body.style.userSelect = '';
321
409
  const nextRange = dragPreviewRef.current;
322
410
  dragStartRangeRef.current = null;
411
+ dragStartTrackBoundsRef.current = null;
323
412
  dragModeRef.current = null;
324
413
  pointerIdRef.current = null;
325
414
  windowDragOffsetDaysRef.current = 0;
@@ -327,6 +416,7 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
327
416
  setDraftRange(nextRange);
328
417
  setReferenceDate(nextRange.startDate);
329
418
  setWindowDays(getInclusiveDayCount(nextRange));
419
+ commitTrackBounds(ensureRangeVisibleOnTrack(nextRange, trackBoundsRef.current));
330
420
  }
331
421
  }
332
422
  React.useEffect(() => {
@@ -379,9 +469,7 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
379
469
  if (!open) {
380
470
  return jsxRuntime.jsx(jsxRuntime.Fragment, { children: dialogLoading });
381
471
  }
382
- return reactDom.createPortal(jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.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: jsxRuntime.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: jsxRuntime.jsxs("div", { className: "space-y-5 p-4", children: [jsxRuntime.jsxs("div", { className: "relative flex items-center justify-center px-16 text-center", children: [jsxRuntime.jsx("div", { ref: resultLabelRef, className: "select-none text-base font-semibold text-slate-900 dark:text-white", children: getRangeLabel(draftRange) }), jsxRuntime.jsxs("div", { className: "absolute right-0 top-1/2 flex -translate-y-1/2 items-center gap-2", children: [jsxRuntime.jsx("button", { type: "button", onClick: () => onOpenChange(false), className: DIALOG_ICON_BUTTON_CLASS_NAME, "aria-label": "Cancel", children: jsxRuntime.jsx(icons.XIcon, { className: "h-4 w-4" }) }), jsxRuntime.jsx("button", { type: "button", onClick: () => {
383
- void runDialogAction('confirm', handleApply);
384
- }, disabled: !draftRange.startDate || !draftRange.endDate, className: utils.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: jsxRuntime.jsx(icons.CheckCheckIcon, { className: "h-4 w-4" }) })] })] }), jsxRuntime.jsxs("div", { className: "space-y-4", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [jsxRuntime.jsx("button", Object.assign({ type: "button", onClick: () => {
472
+ return reactDom.createPortal(jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.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: jsxRuntime.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: jsxRuntime.jsxs("div", { className: "space-y-5 p-4", children: [jsxRuntime.jsxs("div", { className: "relative flex items-center justify-center px-9 text-center sm:px-16", children: [jsxRuntime.jsx("div", { ref: resultLabelRef, className: "min-w-0 select-none truncate text-base font-semibold text-slate-900 dark:text-white", children: getRangeLabel(draftRange) }), jsxRuntime.jsx("div", { className: "absolute right-0 top-1/2 flex -translate-y-1/2 translate-x-1 items-center sm:translate-x-0", children: jsxRuntime.jsx("button", { type: "button", onClick: () => onOpenChange(false), className: DIALOG_ICON_BUTTON_CLASS_NAME, "aria-label": "Cancel", children: jsxRuntime.jsx(icons.XIcon, { className: "h-4 w-4" }) }) })] }), jsxRuntime.jsxs("div", { className: "space-y-3", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [jsxRuntime.jsx("button", Object.assign({ type: "button", onClick: () => {
385
473
  flashNavButtonPress('prevYear');
386
474
  shiftReferenceDateByYears(-1);
387
475
  }, className: utils.cn(DIALOG_NAV_BUTTON_CLASS_NAME, pressedNavButton === 'prevYear'
@@ -397,11 +485,11 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
397
485
  endDate: addDays(baseReferenceDate, resolvedDefaultRangeDays - 1),
398
486
  };
399
487
  setReferenceDate(baseReferenceDate);
400
- setTrackBounds(buildTrackRange(baseReferenceDate, resolvedDefaultRangeDays));
488
+ commitTrackBounds(buildTrackRange(baseReferenceDate, resolvedDefaultRangeDays));
401
489
  setWindowDays(resolvedDefaultRangeDays);
402
490
  setDraftRange(nextRange);
403
491
  onClear === null || onClear === void 0 ? void 0 : onClear(nextRange);
404
- }, className: DIALOG_PILL_BUTTON_CLASS_NAME, children: "Current Day" }), jsxRuntime.jsx("button", { type: "button", onClick: () => {
492
+ }, className: DIALOG_PILL_BUTTON_CLASS_NAME, children: "Today" }), jsxRuntime.jsx("button", { type: "button", onClick: () => {
405
493
  const nextRange = {
406
494
  startDate: getMonthStart(referenceDate),
407
495
  endDate: addDays(getMonthStart(referenceDate), MAX_RANGE_DAYS - 1),
@@ -415,7 +503,8 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
415
503
  };
416
504
  setDraftRange(normalizedRange);
417
505
  setWindowDays(getInclusiveDayCount(normalizedRange));
418
- setTrackBounds(buildTrackRange(normalizedRange.startDate, getInclusiveDayCount(normalizedRange)));
506
+ setReferenceDate(normalizedRange.startDate);
507
+ commitTrackBounds(buildTrackRange(normalizedRange.startDate, getInclusiveDayCount(normalizedRange)));
419
508
  }, className: DIALOG_PILL_BUTTON_CLASS_NAME, children: "This Month" })] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [jsxRuntime.jsx("button", Object.assign({ type: "button", onClick: () => {
420
509
  flashNavButtonPress('nextMonth');
421
510
  shiftReferenceDateByMonths(1);
@@ -426,26 +515,63 @@ function RandomDateRangeDialog({ open, value, anchorDate, defaultRangeDays = DEF
426
515
  shiftReferenceDateByYears(1);
427
516
  }, className: utils.cn(DIALOG_NAV_BUTTON_CLASS_NAME, pressedNavButton === 'nextYear'
428
517
  ? DIALOG_NAV_BUTTON_PRESSED_CLASS_NAME
429
- : DIALOG_NAV_BUTTON_REST_CLASS_NAME) }, getNavButtonPressProps('nextYear'), { "aria-label": "Next year", title: "Next year", children: jsxRuntime.jsx(icons.ChevronsRightIcon, { className: "h-4 w-4" }) }))] })] }), jsxRuntime.jsxs("div", { className: "relative h-24", children: [jsxRuntime.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: [jsxRuntime.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), jsxRuntime.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" }), jsxRuntime.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" })] }), jsxRuntime.jsx("div", { className: "flex min-w-0 items-center justify-center gap-1", children: [
518
+ : DIALOG_NAV_BUTTON_REST_CLASS_NAME) }, getNavButtonPressProps('nextYear'), { "aria-label": "Next year", title: "Next year", children: jsxRuntime.jsx(icons.ChevronsRightIcon, { className: "h-4 w-4" }) }))] })] }), jsxRuntime.jsxs("div", { className: "relative h-21", children: [jsxRuntime.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: [jsxRuntime.jsxs("span", { className: "relative block select-none text-center", children: [jsxRuntime.jsx(RollingMonthLabel, { value: leftMonthLabel }), jsxRuntime.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" }), jsxRuntime.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" })] }), jsxRuntime.jsx("div", { className: "flex min-w-0 items-center justify-center gap-1", children: [
430
519
  { label: '+7', days: 7 },
431
520
  { label: '+10', days: 10 },
432
521
  { label: '+15', days: 15 },
433
522
  { label: '+30', days: 30 },
434
- ].map((item) => (jsxRuntime.jsx("button", { type: "button", onClick: () => applyQuickRange(item.days), className: DIALOG_PILL_BUTTON_COMPACT_CLASS_NAME, children: item.label }, item.label))) }), jsxRuntime.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), jsxRuntime.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" }), jsxRuntime.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" })] })] }), jsxRuntime.jsx("div", { className: "absolute inset-x-0 top-[3.35rem] h-10 touch-none", onDoubleClick: (event) => {
523
+ ].map((item) => (jsxRuntime.jsx("button", { type: "button", onClick: () => applyQuickRange(item.days), className: DIALOG_PILL_BUTTON_COMPACT_CLASS_NAME, children: item.label }, item.label))) }), jsxRuntime.jsxs("span", { className: "relative block select-none text-center", children: [jsxRuntime.jsx(RollingMonthLabel, { value: rightMonthLabel }), jsxRuntime.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" }), jsxRuntime.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" })] })] }), jsxRuntime.jsx("div", { className: "absolute inset-x-0 top-[3.35rem] h-10 touch-none", onDoubleClick: (event) => {
435
524
  event.stopPropagation();
436
525
  resetReferenceFromClientX(event.clientX);
437
526
  }, children: jsxRuntime.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: [jsxRuntime.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) => {
438
527
  return (jsxRuntime.jsx("span", { className: "flex justify-center", children: jsxRuntime.jsx("span", { className: utils.cn('rounded-full bg-slate-400/55 dark:bg-slate-500/55', 'h-3 w-px') }) }, index));
439
- }) }), jsxRuntime.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) => {
528
+ }) }), jsxRuntime.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: lib.themeSvgIconColor }, onPointerDown: (event) => {
440
529
  event.stopPropagation();
441
530
  beginDrag('window', event.pointerId, event.clientX);
442
- }, children: jsxRuntime.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` }) }), jsxRuntime.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) => {
531
+ }, children: jsxRuntime.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` }) }), jsxRuntime.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: lib.themeSvgIconColor }, onPointerDown: (event) => {
443
532
  event.stopPropagation();
444
533
  beginDrag('start', event.pointerId);
445
- }, "aria-label": "Adjust start date" }), jsxRuntime.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) => {
534
+ }, "aria-label": "Adjust start date" }), jsxRuntime.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: lib.themeSvgIconColor }, onPointerDown: (event) => {
446
535
  event.stopPropagation();
447
536
  beginDrag('end', event.pointerId);
448
- }, "aria-label": "Adjust end date" })] }) })] })] })] }) }) }), dialogLoading] }), document.body);
537
+ }, "aria-label": "Adjust end date" })] }) })] }), jsxRuntime.jsx("div", { className: "flex justify-end", children: jsxRuntime.jsx(xButton.XButton, { type: "single", variant: "soft", minWidth: "min-w-[110px]", className: "w-auto", iconClassName: "h-4 w-4", button: {
538
+ icon: jsxRuntime.jsx(icons.CheckCheckIcon, {}),
539
+ text: 'Apply',
540
+ disabled: !draftRange.startDate || !draftRange.endDate,
541
+ onClick: () => {
542
+ void runDialogAction('confirm', handleApply);
543
+ },
544
+ } }) })] })] }) }) }), jsxRuntime.jsx("style", { children: `
545
+ @keyframes rd-date-range-month-in {
546
+ from {
547
+ opacity: 0;
548
+ transform: translateY(-0.45rem);
549
+ }
550
+ to {
551
+ opacity: 1;
552
+ transform: translateY(0);
553
+ }
554
+ }
555
+
556
+ @keyframes rd-date-range-month-out {
557
+ from {
558
+ opacity: 1;
559
+ transform: translateY(0);
560
+ }
561
+ to {
562
+ opacity: 0;
563
+ transform: translateY(0.45rem);
564
+ }
565
+ }
566
+
567
+ .rd-date-range-month-in {
568
+ animation: rd-date-range-month-in 180ms ease-out both;
569
+ }
570
+
571
+ .rd-date-range-month-out {
572
+ animation: rd-date-range-month-out 180ms ease-out both;
573
+ }
574
+ ` }), dialogLoading] }), document.body);
449
575
  }
450
576
 
451
577
  exports.RandomDateRangeDialog = RandomDateRangeDialog;