@particle-academy/react-fancy 5.56.0 → 5.58.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.
- package/CHANGELOG.md +54 -0
- package/dist/{chunk-XO4UWQCU.cjs → chunk-4DL2U23D.cjs} +233 -77
- package/dist/chunk-4DL2U23D.cjs.map +1 -0
- package/dist/{chunk-WUG646R4.cjs → chunk-IB673TEG.cjs} +39 -5
- package/dist/chunk-IB673TEG.cjs.map +1 -0
- package/dist/{chunk-SFJ5WOX5.js → chunk-MLZGGAXQ.js} +233 -77
- package/dist/chunk-MLZGGAXQ.js.map +1 -0
- package/dist/{chunk-KUJ5XRBD.js → chunk-YUNOVQQJ.js} +39 -5
- package/dist/chunk-YUNOVQQJ.js.map +1 -0
- package/dist/index.cjs +4 -4
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/inputs.cjs +2 -2
- package/dist/inputs.d.cts +1 -1
- package/dist/inputs.d.ts +1 -1
- package/dist/inputs.js +1 -1
- package/dist/multi-switch.cjs +2 -2
- package/dist/multi-switch.d.cts +15 -3
- package/dist/multi-switch.d.ts +15 -3
- package/dist/multi-switch.js +1 -1
- package/dist/time-grid.cjs +2 -2
- package/dist/time-grid.d.cts +8 -0
- package/dist/time-grid.d.ts +8 -0
- package/dist/time-grid.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-KUJ5XRBD.js.map +0 -1
- package/dist/chunk-SFJ5WOX5.js.map +0 -1
- package/dist/chunk-WUG646R4.cjs.map +0 -1
- package/dist/chunk-XO4UWQCU.cjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,60 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
11
11
|
|
|
12
12
|
## [Unreleased]
|
|
13
13
|
|
|
14
|
+
## [5.58.0] - 2026-10-22
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **`MultiSwitch` per-option colour.** An option in `list` can carry
|
|
19
|
+
`color` (any kit `Color`, including `brand`). While that option is
|
|
20
|
+
selected, the thumb and the switch's border take its colour, e.g. a green
|
|
21
|
+
"Assign" against a red "Unassign". **Nothing to do for an existing switch:**
|
|
22
|
+
without `color` the thumb is the same blue, the border the same token, and
|
|
23
|
+
the thumb's class string is byte-identical to 5.57.0.
|
|
24
|
+
- Light hues (`amber`, `yellow`, `lime`) get dark label text so the selected
|
|
25
|
+
label stays readable; the rest get white, as before.
|
|
26
|
+
- The thumb now carries `data-react-fancy-multi-switch-thumb` and, when
|
|
27
|
+
coloured, `data-color`.
|
|
28
|
+
- A caller's own border classes in `className` still win over the colour.
|
|
29
|
+
- New exported type `MultiSwitchOption` (an `InputOption` plus `color`).
|
|
30
|
+
- Verified in Chrome in light, `.dark` and `[data-theme="dark"]`.
|
|
31
|
+
|
|
32
|
+
## [5.57.0] - 2026-10-22
|
|
33
|
+
|
|
34
|
+
### Added
|
|
35
|
+
|
|
36
|
+
- **`TimeGrid` column windowing (typed grid).** `windowColumns` renders only
|
|
37
|
+
the columns in view plus overscan. It is on by default above 500 columns,
|
|
38
|
+
and `windowColumns` forces it on or off. **Nothing to do for an existing
|
|
39
|
+
grid:** at 500 columns or fewer nothing changes unless you ask, and a
|
|
40
|
+
boolean grid (no `cells`) is never windowed.
|
|
41
|
+
- Stable handles and selection still cover every cell. Ids and the cells
|
|
42
|
+
passed to `onSelectionChange` come from `cells`, not the DOM, so a
|
|
43
|
+
selection across unrendered columns reports all of them.
|
|
44
|
+
- Keyboard focus moved past the window, or a `selection` set from outside
|
|
45
|
+
(a host, an agent through a bridge) that is out of view, scrolls it into
|
|
46
|
+
view. Windowed cells carry `aria-colindex`.
|
|
47
|
+
- The column tracks stay the full grid while scrolling. A jump is rendered
|
|
48
|
+
before the next paint, so the viewport never flashes blank. On the server
|
|
49
|
+
a windowed grid renders its frame with no cells.
|
|
50
|
+
- Measured in Chrome (Playwright, CDP 4x CPU throttle, 240 columns, median
|
|
51
|
+
of 7 page loads, 2026-10-22). Mount, 5.56.0 against 5.57.0 windowed:
|
|
52
|
+
|
|
53
|
+
| container | 7 days | 14 days | 31 days |
|
|
54
|
+
|---|---|---|---|
|
|
55
|
+
| 800px | 182 → 119 ms | 329 → 209 ms | 624 → 370 ms |
|
|
56
|
+
| 1280px | 139 → 131 ms | 286 → 263 ms | 632 → 524 ms |
|
|
57
|
+
|
|
58
|
+
The gain depends on how much of the grid is off screen: at 1280px the
|
|
59
|
+
window still holds 208 of 240 columns. 14 days in 1280px still misses a
|
|
60
|
+
200 ms budget.
|
|
61
|
+
|
|
62
|
+
### Changed
|
|
63
|
+
|
|
64
|
+
- Typed `TimeGrid` cells render in memoised 16-column chunks, so a selection
|
|
65
|
+
change re-renders only the chunks it touches. Unwindowed 31 days mounts in
|
|
66
|
+
545 ms against 632 ms in 5.56.0 (1280px, same setup as above).
|
|
67
|
+
|
|
14
68
|
## [5.56.0] - 2026-10-21
|
|
15
69
|
|
|
16
70
|
### Added
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var chunkI27K6NLX_cjs = require('./chunk-I27K6NLX.cjs');
|
|
4
4
|
var chunkZU5Q77OT_cjs = require('./chunk-ZU5Q77OT.cjs');
|
|
5
5
|
var react = require('react');
|
|
6
|
+
var reactDom = require('react-dom');
|
|
6
7
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
8
|
|
|
8
9
|
// src/components/TimeGrid/TimeGrid.selection.ts
|
|
@@ -109,7 +110,7 @@ var TONE_FILL = {
|
|
|
109
110
|
zinc: "bg-zinc-500"
|
|
110
111
|
};
|
|
111
112
|
var NEUTRAL_FILL = "bg-[color:var(--fancy-surface-muted,var(--color-zinc-100))] dark:bg-[color:var(--fancy-surface-muted-dark,var(--color-zinc-800))]";
|
|
112
|
-
var CELL_BASE = "relative m-px rounded-sm";
|
|
113
|
+
var CELL_BASE = "relative m-px h-[var(--tg-cell-h)] w-[var(--tg-cell-w)] rounded-sm";
|
|
113
114
|
var CELL_ENABLED = "cursor-pointer hover:brightness-90 dark:hover:brightness-125";
|
|
114
115
|
var CELL_DISABLED = "cursor-not-allowed opacity-40";
|
|
115
116
|
var CELL_SELECTED = "after:pointer-events-none after:absolute after:inset-0 after:rounded-sm after:bg-[color:var(--fancy-focus,var(--color-blue-500))]/50 dark:after:bg-[color:var(--fancy-focus-dark,var(--color-blue-400))]/50";
|
|
@@ -127,6 +128,11 @@ function isDev() {
|
|
|
127
128
|
}
|
|
128
129
|
}
|
|
129
130
|
var EMPTY = {};
|
|
131
|
+
var WINDOW_DEFAULT_ABOVE = 500;
|
|
132
|
+
var WINDOW_MIN_OVERSCAN = 16;
|
|
133
|
+
var CHUNK = 16;
|
|
134
|
+
var WINDOW_CHUNK = CHUNK;
|
|
135
|
+
var ROW_START = { gridColumnStart: 1 };
|
|
130
136
|
var warnedStates = /* @__PURE__ */ new Set();
|
|
131
137
|
var warnedNoStates = false;
|
|
132
138
|
var cellDomId = (baseId, r, c) => `${baseId}-${r}-${c}`;
|
|
@@ -143,23 +149,71 @@ var TypedRow = react.memo(function TypedRow2({
|
|
|
143
149
|
selStart,
|
|
144
150
|
selEnd,
|
|
145
151
|
activeCol,
|
|
146
|
-
onRowHeader
|
|
152
|
+
onRowHeader,
|
|
153
|
+
colStart,
|
|
154
|
+
colEnd,
|
|
155
|
+
windowed
|
|
147
156
|
}) {
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
157
|
+
const out = [];
|
|
158
|
+
out.push(
|
|
159
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
160
|
+
"div",
|
|
161
|
+
{
|
|
162
|
+
role: "rowheader",
|
|
163
|
+
"data-react-fancy-timegrid-row": r,
|
|
164
|
+
style: windowed ? ROW_START : void 0,
|
|
165
|
+
onClick: onRowHeader ? () => onRowHeader(r) : void 0,
|
|
166
|
+
className: onRowHeader ? `${HEADER_ROW} ${HEADER_HOVER}` : HEADER_ROW,
|
|
167
|
+
children: ctx.rows[r]
|
|
168
|
+
},
|
|
169
|
+
"h"
|
|
170
|
+
)
|
|
161
171
|
);
|
|
162
|
-
|
|
172
|
+
if (colEnd >= colStart) {
|
|
173
|
+
const k0 = Math.floor(colStart / CHUNK);
|
|
174
|
+
const k1 = Math.floor(colEnd / CHUNK);
|
|
175
|
+
for (let k = k0; k <= k1; k++) {
|
|
176
|
+
const from = Math.max(k * CHUNK, colStart);
|
|
177
|
+
const to = Math.min(k * CHUNK + CHUNK - 1, colEnd);
|
|
178
|
+
const overlaps = selEnd >= from && selStart <= to;
|
|
179
|
+
out.push(
|
|
180
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
181
|
+
CellChunk,
|
|
182
|
+
{
|
|
183
|
+
ctx,
|
|
184
|
+
r,
|
|
185
|
+
rowCells,
|
|
186
|
+
from,
|
|
187
|
+
to,
|
|
188
|
+
selStart: overlaps ? Math.max(selStart, from) : -1,
|
|
189
|
+
selEnd: overlaps ? Math.min(selEnd, to) : -2,
|
|
190
|
+
activeCol: activeCol >= from && activeCol <= to ? activeCol : -1,
|
|
191
|
+
place: windowed && from === colStart,
|
|
192
|
+
windowed
|
|
193
|
+
},
|
|
194
|
+
k
|
|
195
|
+
)
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { role: "row", className: "contents", children: out });
|
|
200
|
+
});
|
|
201
|
+
var CellChunk = react.memo(function CellChunk2({
|
|
202
|
+
ctx,
|
|
203
|
+
r,
|
|
204
|
+
rowCells,
|
|
205
|
+
from,
|
|
206
|
+
to,
|
|
207
|
+
selStart,
|
|
208
|
+
selEnd,
|
|
209
|
+
activeCol,
|
|
210
|
+
place,
|
|
211
|
+
windowed
|
|
212
|
+
}) {
|
|
213
|
+
const { baseId, rows, cols, states, marks, stateClass } = ctx;
|
|
214
|
+
const { cellId, ariaCell } = ctx.fns.current;
|
|
215
|
+
const out = [];
|
|
216
|
+
for (let c = from; c <= to; c++) {
|
|
163
217
|
const cell = rowCells?.[c];
|
|
164
218
|
const state = cell?.state ?? "";
|
|
165
219
|
const selected = c >= selStart && c <= selEnd;
|
|
@@ -175,37 +229,40 @@ var TypedRow = react.memo(function TypedRow2({
|
|
|
175
229
|
let cls = stateClass(state) + " " + (cell?.disabled ? CELL_DISABLED : CELL_ENABLED);
|
|
176
230
|
if (selected) cls += " " + CELL_SELECTED;
|
|
177
231
|
if (c === activeCol) cls += " " + CELL_ACTIVE;
|
|
178
|
-
out
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
{
|
|
198
|
-
"
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
232
|
+
out.push(
|
|
233
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
234
|
+
"div",
|
|
235
|
+
{
|
|
236
|
+
id: cellDomId(baseId, r, c),
|
|
237
|
+
role: "gridcell",
|
|
238
|
+
"aria-colindex": windowed ? c + 2 : void 0,
|
|
239
|
+
style: place && c === from ? { gridColumnStart: c + 2 } : void 0,
|
|
240
|
+
"data-react-fancy-timegrid-cell": cellId ? cellId(r, c) : `${r}:${c}`,
|
|
241
|
+
"data-state": state,
|
|
242
|
+
"data-marks": markIds?.length ? markIds.join(" ") : void 0,
|
|
243
|
+
"aria-selected": selected,
|
|
244
|
+
"aria-disabled": cell?.disabled ? true : void 0,
|
|
245
|
+
"aria-label": label,
|
|
246
|
+
"aria-description": reasons,
|
|
247
|
+
title: reasons,
|
|
248
|
+
className: cls,
|
|
249
|
+
children: markIds?.length ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, className: "pointer-events-none absolute right-0 top-0 flex gap-px", children: markIds.map((m) => {
|
|
250
|
+
const def = marks[m];
|
|
251
|
+
return def?.icon ? /* @__PURE__ */ jsxRuntime.jsx("span", { "data-react-fancy-timegrid-mark": m, className: "flex h-2.5 w-2.5 items-center justify-center [&>svg]:h-full [&>svg]:w-full", children: def.icon }, m) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
252
|
+
"span",
|
|
253
|
+
{
|
|
254
|
+
"data-react-fancy-timegrid-mark": m,
|
|
255
|
+
className: `${MARK_DOT} ${def?.tone ? TONE_FILL[def.tone] : NEUTRAL_FILL}`
|
|
256
|
+
},
|
|
257
|
+
m
|
|
258
|
+
);
|
|
259
|
+
}) }) : null
|
|
260
|
+
},
|
|
261
|
+
c
|
|
262
|
+
)
|
|
206
263
|
);
|
|
207
264
|
}
|
|
208
|
-
return
|
|
265
|
+
return out;
|
|
209
266
|
});
|
|
210
267
|
var TypedTimeGrid = react.forwardRef(function TypedTimeGrid2({
|
|
211
268
|
rows,
|
|
@@ -227,6 +284,7 @@ var TypedTimeGrid = react.forwardRef(function TypedTimeGrid2({
|
|
|
227
284
|
disabledRange = "clamp",
|
|
228
285
|
onBlockedSelect,
|
|
229
286
|
onCellHover,
|
|
287
|
+
windowColumns,
|
|
230
288
|
"aria-label": ariaLabel
|
|
231
289
|
}, ref) {
|
|
232
290
|
if (!statesProp) {
|
|
@@ -254,6 +312,64 @@ var TypedTimeGrid = react.forwardRef(function TypedTimeGrid2({
|
|
|
254
312
|
const anchorRef = react.useRef(null);
|
|
255
313
|
const gestureRef = react.useRef(null);
|
|
256
314
|
const hoverRef = react.useRef("");
|
|
315
|
+
const pitchX = cellWidth + 2;
|
|
316
|
+
const windowed = windowColumns ?? nCols > WINDOW_DEFAULT_ABOVE;
|
|
317
|
+
const metrics = react.useRef({ left: 0, width: 0, headerW: 0 });
|
|
318
|
+
const [win, setWin] = react.useState(null);
|
|
319
|
+
const visibleRange = react.useCallback(() => {
|
|
320
|
+
const { left, width, headerW } = metrics.current;
|
|
321
|
+
const first = Math.max(0, Math.floor((left - headerW) / pitchX));
|
|
322
|
+
const last = Math.min(nCols - 1, Math.max(first, Math.ceil((left + width - headerW) / pitchX)));
|
|
323
|
+
return [first, last];
|
|
324
|
+
}, [pitchX, nCols]);
|
|
325
|
+
const measure = react.useCallback(() => {
|
|
326
|
+
const el = outerRef.current;
|
|
327
|
+
if (!el) return;
|
|
328
|
+
const rh = el.querySelector('[role="rowheader"]');
|
|
329
|
+
metrics.current = {
|
|
330
|
+
left: el.scrollLeft,
|
|
331
|
+
width: el.clientWidth || (typeof window !== "undefined" ? window.innerWidth : 1024),
|
|
332
|
+
headerW: rh ? rh.offsetWidth + 2 : 0
|
|
333
|
+
};
|
|
334
|
+
const [first, last] = visibleRange();
|
|
335
|
+
const over = Math.max(WINDOW_MIN_OVERSCAN, Math.ceil((last - first) / 4));
|
|
336
|
+
const start = Math.max(0, Math.floor((first - over) / WINDOW_CHUNK) * WINDOW_CHUNK);
|
|
337
|
+
const end = Math.min(nCols - 1, Math.ceil((last + over + 1) / WINDOW_CHUNK) * WINDOW_CHUNK - 1);
|
|
338
|
+
setWin((w) => w && w.start === start && w.end === end ? w : { start, end });
|
|
339
|
+
}, [visibleRange, nCols]);
|
|
340
|
+
react.useLayoutEffect(() => {
|
|
341
|
+
if (!windowed) return;
|
|
342
|
+
measure();
|
|
343
|
+
const el = outerRef.current;
|
|
344
|
+
if (!el || typeof ResizeObserver === "undefined") return;
|
|
345
|
+
const ro = new ResizeObserver(() => measure());
|
|
346
|
+
ro.observe(el);
|
|
347
|
+
return () => ro.disconnect();
|
|
348
|
+
}, [windowed, measure]);
|
|
349
|
+
const onScroll = react.useCallback(() => reactDom.flushSync(measure), [measure]);
|
|
350
|
+
let colStart = 0;
|
|
351
|
+
let colEnd = nCols - 1;
|
|
352
|
+
if (windowed) {
|
|
353
|
+
colStart = win ? win.start : 0;
|
|
354
|
+
colEnd = win ? Math.min(win.end, nCols - 1) : -1;
|
|
355
|
+
}
|
|
356
|
+
const revealCol = react.useCallback(
|
|
357
|
+
(c) => {
|
|
358
|
+
const el = outerRef.current;
|
|
359
|
+
if (!el) return;
|
|
360
|
+
const { headerW } = metrics.current;
|
|
361
|
+
const width = el.clientWidth || metrics.current.width;
|
|
362
|
+
const x = headerW + c * pitchX;
|
|
363
|
+
let left = el.scrollLeft;
|
|
364
|
+
if (x < left + headerW) left = Math.max(0, x - headerW);
|
|
365
|
+
else if (x + pitchX > left + width) left = x + pitchX - width;
|
|
366
|
+
if (left !== el.scrollLeft) {
|
|
367
|
+
el.scrollLeft = left;
|
|
368
|
+
measure();
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
[pitchX, measure]
|
|
372
|
+
);
|
|
257
373
|
const live = react.useRef({ cells, selection, selectionShape, disabledRange, onSelectionChange, onSelectionCommit, onBlockedSelect, onCellHover });
|
|
258
374
|
live.current = { cells, selection, selectionShape, disabledRange, onSelectionChange, onSelectionCommit, onBlockedSelect, onCellHover };
|
|
259
375
|
const fns = react.useRef({});
|
|
@@ -323,6 +439,23 @@ var TypedTimeGrid = react.forwardRef(function TypedTimeGrid2({
|
|
|
323
439
|
},
|
|
324
440
|
[cellsOf]
|
|
325
441
|
);
|
|
442
|
+
const clampToGrid = react.useCallback(
|
|
443
|
+
(x, y) => {
|
|
444
|
+
const first = document.getElementById(cellDomId(baseId, 0, colStart));
|
|
445
|
+
const last = document.getElementById(cellDomId(baseId, nRows - 1, colEnd));
|
|
446
|
+
if (!first || !last) return null;
|
|
447
|
+
const a = first.getBoundingClientRect();
|
|
448
|
+
const b = last.getBoundingClientRect();
|
|
449
|
+
const w = (b.right - a.left) / (colEnd - colStart + 1);
|
|
450
|
+
const h = (b.bottom - a.top) / nRows;
|
|
451
|
+
if (!(w > 0) || !(h > 0)) return null;
|
|
452
|
+
return {
|
|
453
|
+
r: Math.min(nRows - 1, Math.max(0, Math.floor((y - a.top) / h))),
|
|
454
|
+
c: Math.min(nCols - 1, Math.max(0, colStart + Math.floor((x - a.left) / w)))
|
|
455
|
+
};
|
|
456
|
+
},
|
|
457
|
+
[baseId, nRows, nCols, colStart, colEnd]
|
|
458
|
+
);
|
|
326
459
|
const coordFromEvent = react.useCallback(
|
|
327
460
|
(e) => {
|
|
328
461
|
const t = e.target;
|
|
@@ -334,23 +467,8 @@ var TypedTimeGrid = react.forwardRef(function TypedTimeGrid2({
|
|
|
334
467
|
if (!hit) hit = clampToGrid(e.clientX, e.clientY);
|
|
335
468
|
return hit;
|
|
336
469
|
},
|
|
337
|
-
|
|
338
|
-
[baseId, nRows, nCols]
|
|
470
|
+
[baseId, clampToGrid]
|
|
339
471
|
);
|
|
340
|
-
function clampToGrid(x, y) {
|
|
341
|
-
const first = document.getElementById(cellDomId(baseId, 0, 0));
|
|
342
|
-
const last = document.getElementById(cellDomId(baseId, nRows - 1, nCols - 1));
|
|
343
|
-
if (!first || !last) return null;
|
|
344
|
-
const a = first.getBoundingClientRect();
|
|
345
|
-
const b = last.getBoundingClientRect();
|
|
346
|
-
const w = (b.right - a.left) / nCols;
|
|
347
|
-
const h = (b.bottom - a.top) / nRows;
|
|
348
|
-
if (!(w > 0) || !(h > 0)) return null;
|
|
349
|
-
return {
|
|
350
|
-
r: Math.min(nRows - 1, Math.max(0, Math.floor((y - a.top) / h))),
|
|
351
|
-
c: Math.min(nCols - 1, Math.max(0, Math.floor((x - a.left) / w)))
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
472
|
const onPointerDown = (e) => {
|
|
355
473
|
if (e.button !== 0) return;
|
|
356
474
|
const at = coordFromEvent(e);
|
|
@@ -481,13 +599,33 @@ var TypedTimeGrid = react.forwardRef(function TypedTimeGrid2({
|
|
|
481
599
|
const b = el.getBoundingClientRect();
|
|
482
600
|
setTipPos({ left: b.left - o.left + outer.scrollLeft, top: b.bottom - o.top + outer.scrollTop + 4 });
|
|
483
601
|
}, [activeReasons, active.r, active.c, baseId]);
|
|
602
|
+
const reveal = react.useRef({ revealCol, windowed: windowed && !!win, visibleRange });
|
|
603
|
+
reveal.current = { revealCol, windowed: windowed && !!win, visibleRange };
|
|
484
604
|
react.useEffect(() => {
|
|
485
605
|
if (!focused) return;
|
|
606
|
+
if (reveal.current.windowed) {
|
|
607
|
+
reveal.current.revealCol(active.c);
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
486
610
|
const el = document.getElementById(cellDomId(baseId, active.r, active.c));
|
|
487
611
|
el?.scrollIntoView?.({ block: "nearest", inline: "nearest" });
|
|
488
612
|
}, [focused, active.r, active.c, baseId]);
|
|
613
|
+
react.useEffect(() => {
|
|
614
|
+
const { windowed: w, visibleRange: vr, revealCol: rc } = reveal.current;
|
|
615
|
+
if (!w || !selection || gestureRef.current) return;
|
|
616
|
+
const [f, l] = vr();
|
|
617
|
+
let s0;
|
|
618
|
+
let s1;
|
|
619
|
+
if (selection.shape === "rectangle") {
|
|
620
|
+
s0 = selection.c1;
|
|
621
|
+
s1 = selection.c2;
|
|
622
|
+
} else if (selection.from.r === selection.to.r) {
|
|
623
|
+
s0 = selection.from.c;
|
|
624
|
+
s1 = selection.to.c;
|
|
625
|
+
} else return;
|
|
626
|
+
if (s1 < f || s0 > l) rc(s0);
|
|
627
|
+
}, [selection]);
|
|
489
628
|
const colStep = Math.max(1, Math.floor(nCols / 6));
|
|
490
|
-
const pitchX = cellWidth + 2;
|
|
491
629
|
const tipId = `${baseId}-tip`;
|
|
492
630
|
const bodyRows = new Array(nRows);
|
|
493
631
|
for (let r = 0; r < nRows; r++) {
|
|
@@ -501,17 +639,41 @@ var TypedTimeGrid = react.forwardRef(function TypedTimeGrid2({
|
|
|
501
639
|
selStart: seg ? seg[0] : -1,
|
|
502
640
|
selEnd: seg ? seg[1] : -2,
|
|
503
641
|
activeCol: focused && active.r === r ? active.c : -1,
|
|
504
|
-
onRowHeader
|
|
642
|
+
onRowHeader,
|
|
643
|
+
colStart,
|
|
644
|
+
colEnd,
|
|
645
|
+
windowed
|
|
505
646
|
},
|
|
506
647
|
r
|
|
507
648
|
);
|
|
508
649
|
}
|
|
650
|
+
const gridTemplateColumns = `max-content repeat(${nCols}, ${pitchX}px)`;
|
|
651
|
+
const headerCols = [];
|
|
652
|
+
for (let c = colStart; c <= colEnd; c++) {
|
|
653
|
+
headerCols.push(
|
|
654
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
655
|
+
"div",
|
|
656
|
+
{
|
|
657
|
+
role: "columnheader",
|
|
658
|
+
"aria-colindex": windowed ? c + 2 : void 0,
|
|
659
|
+
style: windowed && c === colStart ? { gridColumnStart: c + 2 } : void 0,
|
|
660
|
+
"data-react-fancy-timegrid-col": c,
|
|
661
|
+
onClick: toggleStripsOnHeaderClick ? () => pickStrip({ r: 0, c }, { r: nRows - 1, c }) : void 0,
|
|
662
|
+
className: toggleStripsOnHeaderClick ? `${HEADER_COL} ${HEADER_HOVER}` : HEADER_COL,
|
|
663
|
+
children: sparseColLabels ? c % colStep === 0 ? cols[c] : "" : cols[c]
|
|
664
|
+
},
|
|
665
|
+
c
|
|
666
|
+
)
|
|
667
|
+
);
|
|
668
|
+
}
|
|
509
669
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
510
670
|
"div",
|
|
511
671
|
{
|
|
512
672
|
ref: setOuterRef,
|
|
513
673
|
"data-react-fancy-timegrid": "",
|
|
514
674
|
"data-typed": "",
|
|
675
|
+
"data-windowed": windowed ? "" : void 0,
|
|
676
|
+
onScroll: windowed ? onScroll : void 0,
|
|
515
677
|
className: chunkZU5Q77OT_cjs.cn("relative select-none overflow-x-auto", className),
|
|
516
678
|
children: [
|
|
517
679
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -536,21 +698,15 @@ var TypedTimeGrid = react.forwardRef(function TypedTimeGrid2({
|
|
|
536
698
|
onFocus: () => setFocused(true),
|
|
537
699
|
onBlur: () => setFocused(false),
|
|
538
700
|
className: "inline-grid touch-none items-center outline-none focus-visible:ring-2 focus-visible:ring-[color:var(--fancy-focus,var(--color-blue-500))]/40 dark:focus-visible:ring-[color:var(--fancy-focus-dark,var(--color-blue-400))]/20",
|
|
539
|
-
style: {
|
|
701
|
+
style: {
|
|
702
|
+
gridTemplateColumns,
|
|
703
|
+
"--tg-cell-w": `${cellWidth}px`,
|
|
704
|
+
"--tg-cell-h": `${cellHeight}px`
|
|
705
|
+
},
|
|
540
706
|
children: [
|
|
541
707
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { role: "row", className: "contents", children: [
|
|
542
708
|
/* @__PURE__ */ jsxRuntime.jsx("div", { role: "columnheader" }),
|
|
543
|
-
|
|
544
|
-
"div",
|
|
545
|
-
{
|
|
546
|
-
role: "columnheader",
|
|
547
|
-
"data-react-fancy-timegrid-col": c,
|
|
548
|
-
onClick: toggleStripsOnHeaderClick ? () => pickStrip({ r: 0, c }, { r: nRows - 1, c }) : void 0,
|
|
549
|
-
className: toggleStripsOnHeaderClick ? `${HEADER_COL} ${HEADER_HOVER}` : HEADER_COL,
|
|
550
|
-
children: sparseColLabels ? c % colStep === 0 ? label : "" : label
|
|
551
|
-
},
|
|
552
|
-
c
|
|
553
|
-
))
|
|
709
|
+
headerCols
|
|
554
710
|
] }),
|
|
555
711
|
bodyRows
|
|
556
712
|
]
|
|
@@ -701,5 +857,5 @@ TimeGrid.displayName = "TimeGrid";
|
|
|
701
857
|
BooleanTimeGrid.displayName = "BooleanTimeGrid";
|
|
702
858
|
|
|
703
859
|
exports.TimeGrid = TimeGrid;
|
|
704
|
-
//# sourceMappingURL=chunk-
|
|
705
|
-
//# sourceMappingURL=chunk-
|
|
860
|
+
//# sourceMappingURL=chunk-4DL2U23D.cjs.map
|
|
861
|
+
//# sourceMappingURL=chunk-4DL2U23D.cjs.map
|