@particle-academy/fancy-sheets 0.6.4 → 0.7.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/dist/index.cjs +46 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -4
- package/dist/index.d.ts +33 -4
- package/dist/index.js +46 -6
- package/dist/index.js.map +1 -1
- package/docs/Spreadsheet.md +88 -0
- package/package.json +1 -1
package/docs/Spreadsheet.md
CHANGED
|
@@ -61,6 +61,8 @@ Takes `SheetData` directly — no workbook wrapper, no tabs, no toolbar:
|
|
|
61
61
|
| rowHeight | `number` | `28` | Row height in px |
|
|
62
62
|
| readOnly | `boolean` | `false` | Disable editing |
|
|
63
63
|
| contextMenuItems | `ContextMenuItem[] \| (addr) => ContextMenuItem[]` | - | Custom right-click items |
|
|
64
|
+
| highlights | `CellHighlightMap` | - | Consumer-driven cell highlights (address → color/label) |
|
|
65
|
+
| onActiveCellChange | `(addr, cell?) => void` | - | Fires when the active cell changes |
|
|
64
66
|
| className | `string` | - | Additional CSS classes |
|
|
65
67
|
|
|
66
68
|
### Spreadsheet.Toolbar
|
|
@@ -129,6 +131,7 @@ interface CellData {
|
|
|
129
131
|
computedValue?: CellValue;
|
|
130
132
|
format?: CellFormat;
|
|
131
133
|
comment?: CellComment;
|
|
134
|
+
meta?: Record<string, unknown>; // consumer-defined metadata
|
|
132
135
|
}
|
|
133
136
|
```
|
|
134
137
|
|
|
@@ -148,6 +151,7 @@ interface CellFormat {
|
|
|
148
151
|
borderRight?: string;
|
|
149
152
|
borderBottom?: string;
|
|
150
153
|
borderLeft?: string;
|
|
154
|
+
className?: string; // custom CSS class(es) on the cell element
|
|
151
155
|
}
|
|
152
156
|
```
|
|
153
157
|
|
|
@@ -353,6 +357,90 @@ contextMenuItems={(addr) => [
|
|
|
353
357
|
|
|
354
358
|
Submenus nest arbitrarily deep — each item with `items` renders as a hover-to-open submenu with a chevron indicator.
|
|
355
359
|
|
|
360
|
+
## Cell Metadata
|
|
361
|
+
|
|
362
|
+
The `meta` field on `CellData` stores arbitrary consumer-defined data. The package preserves it through edits but never reads it — consumers use it to build domain-specific features like grouping, tagging, or variable bindings.
|
|
363
|
+
|
|
364
|
+
```tsx
|
|
365
|
+
s.cells = {
|
|
366
|
+
A1: { value: "Revenue", meta: { group: "rev", role: "label" } },
|
|
367
|
+
B1: { value: 50000, meta: { group: "rev", role: "variable" } },
|
|
368
|
+
};
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## Custom CSS Classes
|
|
372
|
+
|
|
373
|
+
The `className` field on `CellFormat` applies custom CSS classes to individual cell elements. Use it for Tailwind utilities, conditional styling, animations, or any CSS your app needs.
|
|
374
|
+
|
|
375
|
+
```tsx
|
|
376
|
+
s.cells = {
|
|
377
|
+
A1: { value: "Header", format: { className: "font-semibold tracking-wide" } },
|
|
378
|
+
B1: { value: 42, format: { className: "tabular-nums text-right" } },
|
|
379
|
+
C1: { value: "Alert", format: { className: "animate-pulse bg-red-100" } },
|
|
380
|
+
};
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
Classes are merged after the built-in cell classes via `cn()`, so Tailwind utilities work and can override defaults.
|
|
384
|
+
|
|
385
|
+
## Cell Highlights
|
|
386
|
+
|
|
387
|
+
The `highlights` prop renders visual overlays on cells independent of selection and formatting — colored outlines, background tints, and optional label badges.
|
|
388
|
+
|
|
389
|
+
```ts
|
|
390
|
+
interface CellHighlight {
|
|
391
|
+
color: string; // outline color (CSS)
|
|
392
|
+
backgroundColor?: string; // tint (auto-derived at 10% opacity from hex if omitted)
|
|
393
|
+
label?: string; // small badge in top-left corner
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
type CellHighlightMap = Record<string, CellHighlight>;
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Static highlights
|
|
400
|
+
|
|
401
|
+
```tsx
|
|
402
|
+
<Sheet
|
|
403
|
+
data={sheet}
|
|
404
|
+
onChange={setSheet}
|
|
405
|
+
highlights={{
|
|
406
|
+
A1: { color: "#8b5cf6", label: "src" },
|
|
407
|
+
B1: { color: "#8b5cf6", label: "dst" },
|
|
408
|
+
}}
|
|
409
|
+
/>
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
### Reactive highlights (grouping pattern)
|
|
413
|
+
|
|
414
|
+
Use `onActiveCellChange` + `meta` to highlight related cells when the user clicks:
|
|
415
|
+
|
|
416
|
+
```tsx
|
|
417
|
+
const [activeAddr, setActiveAddr] = useState("A1");
|
|
418
|
+
|
|
419
|
+
const highlights = useMemo<CellHighlightMap>(() => {
|
|
420
|
+
const group = (sheet.cells[activeAddr]?.meta as any)?.group;
|
|
421
|
+
if (!group) return {};
|
|
422
|
+
const map: CellHighlightMap = {};
|
|
423
|
+
for (const [addr, cell] of Object.entries(sheet.cells)) {
|
|
424
|
+
if ((cell.meta as any)?.group === group) {
|
|
425
|
+
map[addr] = {
|
|
426
|
+
color: "#8b5cf6",
|
|
427
|
+
label: (cell.meta as any)?.role,
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return map;
|
|
432
|
+
}, [activeAddr, sheet.cells]);
|
|
433
|
+
|
|
434
|
+
<Sheet
|
|
435
|
+
data={sheet}
|
|
436
|
+
onChange={setSheet}
|
|
437
|
+
highlights={highlights}
|
|
438
|
+
onActiveCellChange={(addr) => setActiveAddr(addr)}
|
|
439
|
+
/>
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
Click a cell tagged with `meta: { group: "rev" }` and all cells in that group highlight with a purple outline, tinted background, and role badges ("var", "lbl").
|
|
443
|
+
|
|
356
444
|
## Custom Formulas
|
|
357
445
|
|
|
358
446
|
Register custom functions that users can call in cell formulas with `=FUNCTION_NAME(...)`.
|