@box-kite/react 2.2.0 → 2.2.2
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/.claude/rules/box-kite-rules.md +1 -1
- package/.claude/skills/box-kite/SKILL.md +1 -1
- package/.claude/skills/box-kite/references/components.md +3 -3
- package/.claude/skills/box-kite/references/styling.md +2 -1
- package/.cursor/rules/box-kite.mdc +1 -1
- package/AGENTS.md +1 -1
- package/BOX_AI_CONTEXT.md +95 -77
- package/BOX_KITE_AI_CONTEXT.md +95 -77
- package/README.md +1 -1
- package/client.cjs +1 -1
- package/client.mjs +61 -51
- package/components/dataGrid/components/dataGridBottomBarSelection.d.ts +7 -0
- package/components/dataGrid/components/dataGridColumnsPanel.d.ts +10 -0
- package/components/dataGrid/components/dataGridDetailRow.d.ts +3 -3
- package/components/dataGrid/components/dataGridGroupRow.d.ts +3 -3
- package/components/dataGrid/components/dataGridHeader.d.ts +6 -2
- package/components/dataGrid/components/dataGridRow.d.ts +3 -3
- package/components/dataGrid/contracts/dataGridContract.d.ts +13 -0
- package/components/dataGrid/gridNavigationContext.d.ts +7 -2
- package/components/dataGrid/models/columnModel.d.ts +2 -0
- package/components/dataGrid/models/columnVisibilityModel.d.ts +16 -2
- package/components/dataGrid/models/editModel.d.ts +6 -4
- package/components/dataGrid/models/exportModel.d.ts +1 -1
- package/components/dataGrid/models/gridModel.d.ts +60 -2
- package/components/dataGrid/models/groupRowModel.d.ts +2 -2
- package/components/dataGrid/models/headerCellModel.d.ts +10 -0
- package/components/dataGrid/models/localeText.d.ts +108 -0
- package/components/dataGrid/models/rangeModel.d.ts +2 -0
- package/components/dataGrid/models/rowModel.d.ts +1 -1
- package/components/dataGrid/useFilterDraft.d.ts +9 -0
- package/components/dataGrid.cjs +3 -3
- package/components/dataGrid.d.ts +1 -0
- package/components/dataGrid.mjs +1631 -1120
- package/components/semantics.d.ts +29 -29
- package/docs/components.md +1 -1
- package/docs/props.md +1 -1
- package/layer.cjs +1 -1
- package/layer.mjs +4 -1
- package/package.json +76 -46
- package/react/theme/theme.d.ts +5 -3
- package/utils/dataGrid/activeCellStore.d.ts +14 -0
- package/utils/dataGrid/filterDraftUtils.d.ts +19 -0
- package/utils/dataGrid/headerCellUtils.d.ts +50 -0
- package/components/dataGrid/components/dataGridTopBarContextMenu.d.ts +0 -6
package/BOX_KITE_AI_CONTEXT.md
CHANGED
|
@@ -726,7 +726,7 @@ so a change that was a jump becomes a transition with nothing animated by hand.
|
|
|
726
726
|
| `viewTransitionName` | Names this element, so it animates _from where it was to where it is_ instead of being cross-faded with the page. A `<custom-ident>`, **not** dashed |
|
|
727
727
|
| `viewTransitionClass` | A name shared by several elements, so `::view-transition-group(.card)` styles them together. Space-separated for more than one |
|
|
728
728
|
| `Box.viewTransition(update, options)` | Runs `update` inside `document.startViewTransition` where the browser has one, and plainly where it has not |
|
|
729
|
-
| `<Box.Theme viewTransition>` | That call around a theme change, `flushSync` included
|
|
729
|
+
| `<Box.Theme viewTransition>` | That call around a theme change, `flushSync` included. `viewTransition="reveal"` grows the new theme out of the pressed control as a circle |
|
|
730
730
|
|
|
731
731
|
```tsx
|
|
732
732
|
const handle = Box.viewTransition(() => flushSync(() => setTab(next)), { types: ['forward'] });
|
|
@@ -756,7 +756,9 @@ interface ViewTransitionHandle {
|
|
|
756
756
|
- **In React the update has to be flushed.** The browser takes its second screenshot the moment the
|
|
757
757
|
callback returns, and a `setState` has not rendered by then — so a hand-rolled version captures the old
|
|
758
758
|
state twice and nothing appears to move. `flushSync` inside the callback is the fix, and
|
|
759
|
-
`<Box.Theme viewTransition>` is it already done for the one change every app has.
|
|
759
|
+
`<Box.Theme viewTransition>` is it already done for the one change every app has. A theme change also
|
|
760
|
+
pauses every CSS transition until the new theme has painted (and the view transition has finished) — `color` is inherited and every Box transitions
|
|
761
|
+
`all`, so each element would start one of its own — which leaves the view transition as the only animation.
|
|
760
762
|
- **A name has to be unique in the document while the transition runs.** Two elements sharing one is how a
|
|
761
763
|
transition silently does nothing. The prop is for the handful of names a layout has (`header`, `main`);
|
|
762
764
|
a name **per list item** is a rule per item that is never freed, so that one goes in
|
|
@@ -2365,34 +2367,36 @@ named ones carry the reason.
|
|
|
2365
2367
|
|
|
2366
2368
|
### GridDefinition
|
|
2367
2369
|
|
|
2368
|
-
| Prop | Type | Default | Description
|
|
2369
|
-
| ------------------------- | ------------------------------------- | ----------- |
|
|
2370
|
-
| `columns` | `ColumnType[]` | required | Column definitions
|
|
2371
|
-
| `rowKey` | `keyof TRow \| (row) => Key` | auto | Unique row identifier
|
|
2372
|
-
| `rowHeight` | `number` | `48` | Row height in px
|
|
2373
|
-
| `visibleRowsCount` | `number \| 'all'` | `10` | Visible rows. `'all'` disables virtualization
|
|
2374
|
-
| `showRowNumber` | `boolean \| { pinned?, width? }` | `false` | Row number column
|
|
2375
|
-
| `rowSelection` | `boolean \| { pinned? }` | `false` | Checkbox selection column
|
|
2376
|
-
| `rowDetail` | `RowDetailConfig` | — | Expandable detail panel (see below)
|
|
2377
|
-
| `treeData` | `TreeDataConfig` | — | Rows that hold rows: a `treegrid` with a chevron column (see below)
|
|
2378
|
-
| `groupBy` | `Key[]` | — | The columns the grid starts grouped by, outermost first. The column menu takes it from there
|
|
2379
|
-
| `groupDefaultExpanded` | `boolean \| number` | `false` | Which group rows start open: `true` for all, a number for how many levels down
|
|
2380
|
-
| `editable` | `boolean` | `false` | Whether every column can be edited. A column’s own `editable` takes priority
|
|
2381
|
-
| `onCellEdit` | `(edit) => void \| boolean \| string` | — | Judges an edit and is told about it: nothing accepts, a string refuses. May be async
|
|
2382
|
-
| `dataSource` | `DataSource` | — | The grid fetches its own rows a block at a time; `data` is not read at all
|
|
2383
|
-
| `pagination` | `{ totalCount, pageSize? }` | — | Server-side pagination. Bypasses client-side filtering
|
|
2384
|
-
| `topBar` / `bottomBar` | `boolean` | `false` | Show top/bottom bars
|
|
2385
|
-
| `title` / `topBarContent` | `ReactNode` | — | Top bar content
|
|
2386
|
-
| `globalFilter` | `boolean` | `false` | Enable global fuzzy search
|
|
2387
|
-
| `globalFilterKeys` | `(keyof TRow)[]` | all | Limit global filter columns
|
|
2388
|
-
| `sortable` / `resizable` | `boolean` | `true` | Enable sorting/resizing for all columns
|
|
2389
|
-
| `contextMenu` | `boolean \| ContextMenuConfig` | `true` | Control column header context menu. `false` hides it. Object: `{ sort?, pin?, group? }`
|
|
2390
|
-
| `resizerStyle` | `'visible' \| 'hover' \| 'hidden'` | `'visible'` | Resizer handle visibility. `'hover'`: shows on header cell hover. `'hidden'`: invisible but resize still works
|
|
2391
|
-
| `
|
|
2392
|
-
| `
|
|
2393
|
-
| `
|
|
2394
|
-
| `
|
|
2395
|
-
| `
|
|
2370
|
+
| Prop | Type | Default | Description |
|
|
2371
|
+
| ------------------------- | ------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
2372
|
+
| `columns` | `ColumnType[]` | required | Column definitions |
|
|
2373
|
+
| `rowKey` | `keyof TRow \| (row) => Key` | auto | Unique row identifier |
|
|
2374
|
+
| `rowHeight` | `number` | `48` | Row height in px |
|
|
2375
|
+
| `visibleRowsCount` | `number \| 'all'` | `10` | Visible rows. `'all'` disables virtualization |
|
|
2376
|
+
| `showRowNumber` | `boolean \| { pinned?, width? }` | `false` | Row number column |
|
|
2377
|
+
| `rowSelection` | `boolean \| { pinned? }` | `false` | Checkbox selection column. The header checkbox acts on the rows the filters leave on screen; a filter never drops a selection, and the bottom bar counts what it hides, with **Show selected** and **Clear selection** |
|
|
2378
|
+
| `rowDetail` | `RowDetailConfig` | — | Expandable detail panel (see below) |
|
|
2379
|
+
| `treeData` | `TreeDataConfig` | — | Rows that hold rows: a `treegrid` with a chevron column (see below) |
|
|
2380
|
+
| `groupBy` | `Key[]` | — | The columns the grid starts grouped by, outermost first. The column menu takes it from there |
|
|
2381
|
+
| `groupDefaultExpanded` | `boolean \| number` | `false` | Which group rows start open: `true` for all, a number for how many levels down |
|
|
2382
|
+
| `editable` | `boolean` | `false` | Whether every column can be edited. A column’s own `editable` takes priority |
|
|
2383
|
+
| `onCellEdit` | `(edit) => void \| boolean \| string` | — | Judges an edit and is told about it: nothing accepts, a string refuses. May be async |
|
|
2384
|
+
| `dataSource` | `DataSource` | — | The grid fetches its own rows a block at a time; `data` is not read at all |
|
|
2385
|
+
| `pagination` | `{ totalCount, pageSize? }` | — | Server-side pagination. Bypasses client-side filtering |
|
|
2386
|
+
| `topBar` / `bottomBar` | `boolean` | `false` | Show top/bottom bars |
|
|
2387
|
+
| `title` / `topBarContent` | `ReactNode` | — | Top bar content |
|
|
2388
|
+
| `globalFilter` | `boolean` | `false` | Enable global fuzzy search |
|
|
2389
|
+
| `globalFilterKeys` | `(keyof TRow)[]` | all | Limit global filter columns |
|
|
2390
|
+
| `sortable` / `resizable` | `boolean` | `true` | Enable sorting/resizing for all columns |
|
|
2391
|
+
| `contextMenu` | `boolean \| ContextMenuConfig` | `true` | Control column header context menu. `false` hides it. Object: `{ sort?, pin?, group? }` |
|
|
2392
|
+
| `resizerStyle` | `'visible' \| 'hover' \| 'hidden'` | `'visible'` | Resizer handle visibility. `'hover'`: shows on header cell hover. `'hidden'`: invisible but resize still works |
|
|
2393
|
+
| `headerHover` | `'static' \| 'sliding'` | `'static'` | Header hover: an inset pill per sortable cell, or one pill that flows from cell to cell. Whole cell sorts on press |
|
|
2394
|
+
| `localeText` | `Partial<DataGridLocaleText>` | English | Every word the grid writes — labels, accessible names, announcements, messages. Values with a number or a name in them are functions; spread `DATA_GRID_LOCALE_TEXT` to start a translation |
|
|
2395
|
+
| `noDataComponent` | `ReactNode` | `'empty'` | Custom empty state |
|
|
2396
|
+
| `footer` | `boolean \| { label? }` | `false` | A pinned row of grand totals over every column with an `aggregate`. `label` replaces the default `Total` |
|
|
2397
|
+
| `export` | `boolean \| ExportConfig` | `false` | Export buttons in the top bar: `{ csv?, xlsx?, fileName? }`. The writers load on the first press |
|
|
2398
|
+
| `tabNavigation` | `'none' \| 'cells'` | `'none'` | What Tab does. `'none'` is APG's single tab stop; `'cells'` is the spreadsheet reading |
|
|
2399
|
+
| `rangeSelection` | `boolean` | `false` | A drag or Shift+arrow marks a block of cells, and `Ctrl+C`/`Ctrl+V` copy and paste it as TSV (see below) |
|
|
2396
2400
|
|
|
2397
2401
|
### ColumnType
|
|
2398
2402
|
|
|
@@ -2404,7 +2408,7 @@ named ones carry the reason.
|
|
|
2404
2408
|
| `align` | `'start' \| 'end' \| 'center' \| 'left' \| 'right'` | `'left'` | Cell alignment. `start`/`end` follow the reading order; `left`/`right` stay on the screen side they name |
|
|
2405
2409
|
| `pin` | `'START' \| 'END'` (also `'LEFT'`/`'RIGHT'`) | — | Pin to an edge of the **inline axis** (sticky on scroll), so it holds under either `dir`. `LEFT`/`RIGHT` are the older spelling of the same two |
|
|
2406
2410
|
| `columns` | `ColumnType[]` | — | Nested columns (grouped header) |
|
|
2407
|
-
| `Cell` | `({ cell }) => ReactNode` | — | Custom renderer. `cell`: `{ value, row, column, grid }
|
|
2411
|
+
| `Cell` | `({ cell }) => ReactNode` | — | Custom renderer. `cell`: `{ value, row, column, grid }`. It redraws when its row changes or the grid does — not when another row is selected |
|
|
2408
2412
|
| `sortable` / `resizable` | `boolean` | inherits | Override grid-level setting |
|
|
2409
2413
|
| `flexible` | `boolean` | `true` | Participate in flex width distribution |
|
|
2410
2414
|
| `filterable` | `boolean \| FilterConfig` | — | `true` (text), `{ type: 'number', min?, max? }`, `{ type: 'multiselect', options? }` |
|
|
@@ -2787,52 +2791,66 @@ stops, as they were before A7.
|
|
|
2787
2791
|
|
|
2788
2792
|
### Component Style Tree
|
|
2789
2793
|
|
|
2790
|
-
| Component Name | Description
|
|
2791
|
-
| --------------------------------------------------------- |
|
|
2792
|
-
| `datagrid` | Root container
|
|
2793
|
-
| `datagrid.content` | Scroll container for header + body
|
|
2794
|
-
| `datagrid.topBar` | Top bar (title, filters, column groups)
|
|
2795
|
-
| `datagrid.topBar.globalFilter` | Global search wrapper
|
|
2796
|
-
| `datagrid.topBar.globalFilter.stats` | Filtered rows count badge
|
|
2797
|
-
| `datagrid.topBar.columnGroups` | Column group chips container
|
|
2798
|
-
| `datagrid.topBar.columnGroups.icon` | Column group icon
|
|
2799
|
-
| `datagrid.topBar.columnGroups.separator` | Separator between groups
|
|
2800
|
-
| `datagrid.topBar.columnGroups.item` | Column group chip
|
|
2801
|
-
| `datagrid.topBar.columnGroups.item.icon` | Remove icon on chip
|
|
2802
|
-
| `datagrid.topBar.columnVisibility` |
|
|
2803
|
-
| `datagrid.topBar.columnVisibility.badge` |
|
|
2804
|
-
| `datagrid.
|
|
2805
|
-
| `datagrid.
|
|
2806
|
-
| `datagrid.
|
|
2807
|
-
| `datagrid.
|
|
2808
|
-
| `datagrid.
|
|
2809
|
-
| `datagrid.
|
|
2810
|
-
| `datagrid.
|
|
2811
|
-
| `datagrid.
|
|
2812
|
-
| `datagrid.
|
|
2813
|
-
| `datagrid.
|
|
2814
|
-
| `datagrid.
|
|
2815
|
-
| `datagrid.
|
|
2816
|
-
| `datagrid.
|
|
2817
|
-
| `datagrid.
|
|
2818
|
-
| `datagrid.
|
|
2819
|
-
| `datagrid.
|
|
2820
|
-
| `datagrid.
|
|
2821
|
-
| `datagrid.
|
|
2822
|
-
| `datagrid.
|
|
2823
|
-
| `datagrid.
|
|
2824
|
-
| `datagrid.
|
|
2825
|
-
| `datagrid.
|
|
2826
|
-
| `datagrid.
|
|
2827
|
-
| `datagrid.body
|
|
2828
|
-
| `datagrid.body.
|
|
2829
|
-
| `datagrid.
|
|
2830
|
-
| `datagrid.
|
|
2831
|
-
| `datagrid.
|
|
2832
|
-
| `datagrid.
|
|
2833
|
-
| `datagrid.
|
|
2834
|
-
| `datagrid.
|
|
2835
|
-
| `datagrid.
|
|
2794
|
+
| Component Name | Description | Variants |
|
|
2795
|
+
| --------------------------------------------------------- | --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
2796
|
+
| `datagrid` | Root container | — |
|
|
2797
|
+
| `datagrid.content` | Scroll container for header + body | — |
|
|
2798
|
+
| `datagrid.topBar` | Top bar (title, filters, column groups) | — |
|
|
2799
|
+
| `datagrid.topBar.globalFilter` | Global search wrapper | — |
|
|
2800
|
+
| `datagrid.topBar.globalFilter.stats` | Filtered rows count badge (only without a bottom bar) | — |
|
|
2801
|
+
| `datagrid.topBar.columnGroups` | Column group chips container | — |
|
|
2802
|
+
| `datagrid.topBar.columnGroups.icon` | Column group icon | — |
|
|
2803
|
+
| `datagrid.topBar.columnGroups.separator` | Separator between groups | — |
|
|
2804
|
+
| `datagrid.topBar.columnGroups.item` | Column group chip | — |
|
|
2805
|
+
| `datagrid.topBar.columnGroups.item.icon` | Remove icon on chip | — |
|
|
2806
|
+
| `datagrid.topBar.columnVisibility` | Columns button (opens the columns panel) | — |
|
|
2807
|
+
| `datagrid.topBar.columnVisibility.badge` | Shown/total count, only while columns are hidden | `empty` |
|
|
2808
|
+
| `datagrid.topBar.columnVisibility.panel` | Columns panel body | — |
|
|
2809
|
+
| `datagrid.topBar.columnVisibility.search` | Search row (past six columns) | — |
|
|
2810
|
+
| `datagrid.topBar.columnVisibility.searchIcon` | Magnifier inside the search field | — |
|
|
2811
|
+
| `datagrid.topBar.columnVisibility.searchInput` | Search field | — |
|
|
2812
|
+
| `datagrid.topBar.columnVisibility.toolbar` | Count + Show all / Hide all row | — |
|
|
2813
|
+
| `datagrid.topBar.columnVisibility.count` | "6 of 8 shown" | — |
|
|
2814
|
+
| `datagrid.topBar.columnVisibility.action` | Show all / Hide all buttons | — |
|
|
2815
|
+
| `datagrid.topBar.columnVisibility.list` | Scrolling list of switches | — |
|
|
2816
|
+
| `datagrid.topBar.columnVisibility.section` | A run of columns under one header group | `divided` |
|
|
2817
|
+
| `datagrid.topBar.columnVisibility.group` | Header group name above its columns | — |
|
|
2818
|
+
| `datagrid.topBar.columnVisibility.item` | One column: label + switch (the `<label>`) | — |
|
|
2819
|
+
| `datagrid.topBar.columnVisibility.empty` | No-match message | — |
|
|
2820
|
+
| `datagrid.filter.cell` | Filter row cell | `isPinned`, `isFirstLeftPinned`, `isLastLeftPinned`, `isFirstRightPinned`, `isLastRightPinned` |
|
|
2821
|
+
| `datagrid.filter.cell.input` | Filter input container (text/number/multiselect) | — |
|
|
2822
|
+
| `datagrid.header` | Header grid container (sticky) | — |
|
|
2823
|
+
| `datagrid.header.cell` | Header cell | `isPinned`, `isFirstLeftPinned`, `isLastLeftPinned`, `isFirstRightPinned`, `isLastRightPinned`, `isSortable`, `isRowSelection`, `isRowNumber`, `isFirstLeaf`, `isLastLeaf`, `isEmptyCell` |
|
|
2824
|
+
| `datagrid.header.cell.contextMenu` | Column context menu button | — |
|
|
2825
|
+
| `datagrid.header.cell.contextMenu.icon` | Context menu icon | — |
|
|
2826
|
+
| `datagrid.header.cell.contextMenu.tooltip` | Context menu popup | — |
|
|
2827
|
+
| `datagrid.header.cell.contextMenu.tooltip.item` | Context menu action | — |
|
|
2828
|
+
| `datagrid.header.cell.contextMenu.tooltip.item.icon` | Action icon | — |
|
|
2829
|
+
| `datagrid.header.cell.contextMenu.tooltip.item.separator` | Menu separator line | — |
|
|
2830
|
+
| `datagrid.header.cell.resizer` | Column resize handle | — |
|
|
2831
|
+
| `datagrid.body` | Body grid container (virtualized rows) | — |
|
|
2832
|
+
| `datagrid.body.cell` | Body cell | `isPinned`, `isFirstLeftPinned`, `isLastLeftPinned`, `isFirstRightPinned`, `isLastRightPinned`, `isRowNumber`, `isRowSelection`, `isRowSelected`, `isFirstLeaf`, `isLastLeaf`, `isEmptyCell`, `isEditing`, `isInvalid` |
|
|
2833
|
+
| `datagrid.body.cell.text` | Default cell text renderer | — |
|
|
2834
|
+
| `datagrid.body.cell.editor` | The open cell editor | `isPending` |
|
|
2835
|
+
| `datagrid.body.cell.error` | What a refused value says, in the top layer | — |
|
|
2836
|
+
| `datagrid.body.cell.rowDetail` | Row detail expand/collapse button | — |
|
|
2837
|
+
| `datagrid.body.cell.tree` | Tree cell: the indent, the chevron and the value | — |
|
|
2838
|
+
| `datagrid.body.cell.tree.toggle` | Tree expand/collapse chevron | `isExpanded` |
|
|
2839
|
+
| `datagrid.body.cell.tree.spacer` | What a leaf puts where its chevron would be | — |
|
|
2840
|
+
| `datagrid.body.row` | Data row (display: contents) | — |
|
|
2841
|
+
| `datagrid.body.groupRow` | Group row (display: contents) | — |
|
|
2842
|
+
| `datagrid.body.groupRow.expandButton` | Group expand/collapse button | — |
|
|
2843
|
+
| `datagrid.body.detailRow` | Expanded detail row | — |
|
|
2844
|
+
| `datagrid.body.empty` | Empty state container | — |
|
|
2845
|
+
| `datagrid.emptyColumns` | No columns selected placeholder | — |
|
|
2846
|
+
| `datagrid.bottomBar` | Bottom bar (row count, pagination) | — |
|
|
2847
|
+
| `datagrid.bottomBar.info` | Status text ("Rows: ...", "Selected: ...") | — |
|
|
2848
|
+
| `datagrid.bottomBar.clearFilters` | "Clear filters" button | — |
|
|
2849
|
+
| `datagrid.bottomBar.selection` | The selection count and its buttons, at the bar's far end | — |
|
|
2850
|
+
| `datagrid.bottomBar.action` | "Show selected" and "Clear selection" | `pressed` (Show selected while it is on) |
|
|
2851
|
+
| `datagrid.bottomBar.pagination` | Pagination controls wrapper | — |
|
|
2852
|
+
| `datagrid.bottomBar.pagination.button` | Pagination nav button | — |
|
|
2853
|
+
| `datagrid.bottomBar.pagination.info` | Page info text ("1 of 5") | — |
|
|
2836
2854
|
|
|
2837
2855
|
---
|
|
2838
2856
|
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ pass at runtime and caches every rule by its content, so the same value anywhere
|
|
|
10
10
|
one class — a project styles itself in TypeScript, with no CSS files to write and no class-name
|
|
11
11
|
convention to remember.
|
|
12
12
|
|
|
13
|
-
[Docs and live demos](https://www.box-kite.dev) · [Contributing](CONTRIBUTING.md) ·
|
|
13
|
+
[Docs and live demos](https://www.box-kite.dev) · [Blog](https://www.box-kite.dev/blog/) · [Contributing](CONTRIBUTING.md) ·
|
|
14
14
|
[Support](SUPPORT.md) · [Security](SECURITY.md) ·
|
|
15
15
|
[Releases](https://github.com/box-kite/box-kite/releases)
|
|
16
16
|
|
package/client.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=require("./rolldown-runtime.cjs"),t=require("./react-shared.cjs"),n=require("./platform.cjs"),r=require("./effects.cjs"),i=require("./box.cjs");let a=require("react");a=e.t(a,1);let o=require("@box-kite/core"),s=require("react-dom"),c=require("react/jsx-runtime");function l(e){let{node:t=null,event:r=`click`,hideOnScroll:i=!1,hideOnResize:o=!1,hideOnEscape:s=!0}=e??{},[c,l]=(0,a.useState)(!1),u=(0,a.useRef)(null);return(0,a.useEffect)(()=>{function e(e){let r=t??u.current;r&&!n.l(e,[r])&&l(!1)}function a(){l(!1)}function d(e){e.key===`Escape`&&l(!1)}let f=new AbortController;return c&&(window.addEventListener(r,e,f),s&&window.addEventListener(`keydown`,d,f),o&&window.addEventListener(`resize`,a,f),i&&window.addEventListener(`scroll`,e,{signal:f.signal,capture:!0})),()=>{f.abort()}},[t,c,r,s,o,i]),[c,l,u]}var u=r.t;function d(e,n){let{classNames:r,signature:i,styleElements:a}=t.l(e,n);return u(()=>{(0,o.getDefaultEngine)().flushSync()},[i??e]),{classNames:r,styleElements:a}}function f(e,n){let r=e?(0,o.getDefaultEngine)().addGlobalStyles(e,n):void 0;return u(()=>{(0,o.getDefaultEngine)().flushSync()},[e,n]),t.u(r)}var p;(function(e){function t(){(0,o.getDefaultEngine)().flushSync()}e.flushSync=t;function n(){(0,o.getDefaultEngine)().clear()}e.clear=n;function r(){return(0,o.getDefaultEngine)().getStyles()}e.getStyles=r;function i(){return(0,o.getDefaultEngine)().getStyleTag()}e.getStyleTag=i;function a(){return(0,o.getDefaultEngine)().styleElementId}e.styleElementId=a;function s(e){(0,o.getDefaultEngine)().configure(e)}e.configure=s})(p||={});var m=`[box-kite] The client build was loaded into a React Server Component graph, where React has no createContext. Import '@box-kite/react' by its package name — the react-server condition resolves it to a Box that renders on the server — and import the components that hold state (Dropdown, Tooltip, DataGrid, Checkbox, Select, Form) from a 'use client' module. See https://github.com/box-kite/box-kite#react-server-components-react-19`;function h(e){if(typeof e.createContext!=`function`)throw Error(m)}h(a.default);var g=a.default.createContext({theme:``,setTheme:()=>{}});function _(e){let{children:t,theme:n,use:
|
|
1
|
+
const e=require("./rolldown-runtime.cjs"),t=require("./react-shared.cjs"),n=require("./platform.cjs"),r=require("./effects.cjs"),i=require("./box.cjs");let a=require("react");a=e.t(a,1);let o=require("@box-kite/core"),s=require("react-dom"),c=require("react/jsx-runtime");function l(e){let{node:t=null,event:r=`click`,hideOnScroll:i=!1,hideOnResize:o=!1,hideOnEscape:s=!0}=e??{},[c,l]=(0,a.useState)(!1),u=(0,a.useRef)(null);return(0,a.useEffect)(()=>{function e(e){let r=t??u.current;r&&!n.l(e,[r])&&l(!1)}function a(){l(!1)}function d(e){e.key===`Escape`&&l(!1)}let f=new AbortController;return c&&(window.addEventListener(r,e,f),s&&window.addEventListener(`keydown`,d,f),o&&window.addEventListener(`resize`,a,f),i&&window.addEventListener(`scroll`,e,{signal:f.signal,capture:!0})),()=>{f.abort()}},[t,c,r,s,o,i]),[c,l,u]}var u=r.t;function d(e,n){let{classNames:r,signature:i,styleElements:a}=t.l(e,n);return u(()=>{(0,o.getDefaultEngine)().flushSync()},[i??e]),{classNames:r,styleElements:a}}function f(e,n){let r=e?(0,o.getDefaultEngine)().addGlobalStyles(e,n):void 0;return u(()=>{(0,o.getDefaultEngine)().flushSync()},[e,n]),t.u(r)}var p;(function(e){function t(){(0,o.getDefaultEngine)().flushSync()}e.flushSync=t;function n(){(0,o.getDefaultEngine)().clear()}e.clear=n;function r(){return(0,o.getDefaultEngine)().getStyles()}e.getStyles=r;function i(){return(0,o.getDefaultEngine)().getStyleTag()}e.getStyleTag=i;function a(){return(0,o.getDefaultEngine)().styleElementId}e.styleElementId=a;function s(e){(0,o.getDefaultEngine)().configure(e)}e.configure=s})(p||={});var m=`[box-kite] The client build was loaded into a React Server Component graph, where React has no createContext. Import '@box-kite/react' by its package name — the react-server condition resolves it to a Box that renders on the server — and import the components that hold state (Dropdown, Tooltip, DataGrid, Checkbox, Select, Form) from a 'use client' module. See https://github.com/box-kite/box-kite#react-server-components-react-19`;function h(e){if(typeof e.createContext!=`function`)throw Error(m)}h(a.default);var g=a.default.createContext({theme:``,setTheme:()=>{}});function _(e){let{children:t,theme:n,use:l=`local`,storageKey:u,globalStyles:d,viewTransition:p}=e,m=f(l===`global`?d:void 0,`html`),[h,_]=(0,a.useState)(n??o.defaultThemeName),[v,y]=(0,a.useState)(n!==void 0),b=(0,a.useRef)(null),x=(0,a.useRef)(h),S=(0,a.useRef)(null),C=(0,a.useRef)(void 0),w=(0,a.useCallback)(e=>{let t=()=>{e===null?(u&&(0,o.clearStoredTheme)(u),y(!1)):(u&&(0,o.writeStoredTheme)(u,e),_(e),y(!0))};if(p){let e=(0,o.transitionTheme)(()=>(0,s.flushSync)(t),p===`reveal`?`reveal`:`fade`);C.current=e.finished,e.finished.then(()=>C.current=void 0,()=>C.current=void 0)}else t()},[u,p]),T=p===`reveal`;(0,a.useEffect)(()=>T?(0,o.prepareReveal)():void 0,[T]);let[E,D]=(0,a.useState)(n);return n!==E&&(D(n),n===void 0?y(!1):(_(n),y(!0))),(0,a.useLayoutEffect)(()=>{if(v)return;let e=u?(0,o.readStoredTheme)(u):null,t=e??(0,o.getSystemTheme)();if(t!==x.current&&(b.current=t),_(t),e){y(!0);return}return(0,o.watchSystemTheme)(_)},[v,u]),r.t(()=>{h!==x.current&&(S.current??=(0,o.pauseTransitions)())},[h]),(0,a.useLayoutEffect)(()=>{if(x.current=h,b.current!==null&&b.current!==h)return;b.current=null;let e=S.current;S.current=null;let t=l===`global`?(0,o.documentRoot)():null,n=t?(0,o.applyThemeToElement)(t,h):void 0;return e?.(C.current),n},[h,l]),l===`local`?(0,c.jsxs)(g.Provider,{value:{theme:h,setTheme:w},children:[m,(0,c.jsx)(i.default,{className:h,props:{"data-theme":h},children:t})]}):(0,c.jsxs)(g.Provider,{value:{theme:h,setTheme:w},children:[m,t]})}(function(e){function t(){let{theme:e,setTheme:t}=(0,a.useContext)(g);return[e,t]}e.useTheme=t})(_||={});var v=_,y=new WeakMap;function b(e){let t=y.get(e);return t||(t=new Map,y.set(e,t)),t}function x(e=!0){let[t]=v.useTheme(),r=(0,a.useMemo)(()=>{if(!e)return null;let t=n.t();if(!t)return null;let r=`box-kite-portal`,i=t.getElementById(r);return i||(i=document.createElement(`div`),i.id=r,document.body.appendChild(i)),i},[e]);return(0,a.useLayoutEffect)(()=>{if(!t||!r)return;let e=b(r),n=e.get(t)??0;return e.set(t,n+1),n===0&&r.classList.add(t),()=>{let n=(e.get(t)??1)-1;n<=0?(e.delete(t),r.classList.remove(t)):e.set(t,n)}},[r,t]),r}Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return x}});
|
package/client.mjs
CHANGED
|
@@ -3,11 +3,11 @@ import { l as n, t as r } from "./platform.mjs";
|
|
|
3
3
|
import { t as i } from "./effects.mjs";
|
|
4
4
|
import a from "./box.mjs";
|
|
5
5
|
import o, { useCallback as s, useContext as c, useEffect as l, useLayoutEffect as u, useMemo as d, useRef as f, useState as p } from "react";
|
|
6
|
-
import { applyThemeToElement as m, clearStoredTheme as h, defaultThemeName as g, documentRoot as _, getDefaultEngine as v, getSystemTheme as y,
|
|
7
|
-
import { flushSync as
|
|
8
|
-
import { jsx as
|
|
6
|
+
import { applyThemeToElement as m, clearStoredTheme as h, defaultThemeName as g, documentRoot as _, getDefaultEngine as v, getSystemTheme as y, pauseTransitions as b, prepareReveal as x, readStoredTheme as S, transitionTheme as C, watchSystemTheme as w, writeStoredTheme as T } from "@box-kite/core";
|
|
7
|
+
import { flushSync as E } from "react-dom";
|
|
8
|
+
import { jsx as D, jsxs as O } from "react/jsx-runtime";
|
|
9
9
|
//#region src/react/hooks/useVisibility.ts
|
|
10
|
-
function
|
|
10
|
+
function k(e) {
|
|
11
11
|
let { node: t = null, event: r = "click", hideOnScroll: i = !1, hideOnResize: a = !1, hideOnEscape: o = !0 } = e ?? {}, [s, c] = p(!1), u = f(null);
|
|
12
12
|
return l(() => {
|
|
13
13
|
function e(e) {
|
|
@@ -42,23 +42,23 @@ function D(e) {
|
|
|
42
42
|
}
|
|
43
43
|
//#endregion
|
|
44
44
|
//#region src/react/useStyles.ts
|
|
45
|
-
var
|
|
46
|
-
function
|
|
45
|
+
var A = i;
|
|
46
|
+
function j(t, n) {
|
|
47
47
|
let { classNames: r, signature: i, styleElements: a } = e(t, n);
|
|
48
|
-
return
|
|
48
|
+
return A(() => {
|
|
49
49
|
v().flushSync();
|
|
50
50
|
}, [i ?? t]), {
|
|
51
51
|
classNames: r,
|
|
52
52
|
styleElements: a
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
|
-
function
|
|
55
|
+
function M(e, n) {
|
|
56
56
|
let r = e ? v().addGlobalStyles(e, n) : void 0;
|
|
57
|
-
return
|
|
57
|
+
return A(() => {
|
|
58
58
|
v().flushSync();
|
|
59
59
|
}, [e, n]), t(r);
|
|
60
60
|
}
|
|
61
|
-
var
|
|
61
|
+
var N;
|
|
62
62
|
(function(e) {
|
|
63
63
|
function t() {
|
|
64
64
|
v().flushSync();
|
|
@@ -84,73 +84,83 @@ var j;
|
|
|
84
84
|
v().configure(e);
|
|
85
85
|
}
|
|
86
86
|
e.configure = o;
|
|
87
|
-
})(
|
|
87
|
+
})(N ||= {});
|
|
88
88
|
//#endregion
|
|
89
89
|
//#region src/react/clientRuntime.ts
|
|
90
|
-
var
|
|
91
|
-
function
|
|
92
|
-
if (typeof e.createContext != "function") throw Error(
|
|
90
|
+
var P = "[box-kite] The client build was loaded into a React Server Component graph, where React has no createContext. Import '@box-kite/react' by its package name — the react-server condition resolves it to a Box that renders on the server — and import the components that hold state (Dropdown, Tooltip, DataGrid, Checkbox, Select, Form) from a 'use client' module. See https://github.com/box-kite/box-kite#react-server-components-react-19";
|
|
91
|
+
function F(e) {
|
|
92
|
+
if (typeof e.createContext != "function") throw Error(P);
|
|
93
93
|
}
|
|
94
94
|
//#endregion
|
|
95
95
|
//#region src/react/theme/themeContext.ts
|
|
96
|
-
|
|
97
|
-
var
|
|
96
|
+
F(o);
|
|
97
|
+
var I = o.createContext({
|
|
98
98
|
theme: "",
|
|
99
99
|
setTheme: () => {}
|
|
100
100
|
});
|
|
101
101
|
//#endregion
|
|
102
102
|
//#region src/react/theme/theme.tsx
|
|
103
|
-
function
|
|
104
|
-
let { children: t, theme: n, use: r = "local", storageKey:
|
|
103
|
+
function L(e) {
|
|
104
|
+
let { children: t, theme: n, use: r = "local", storageKey: o, globalStyles: c, viewTransition: d } = e, v = M(r === "global" ? c : void 0, "html"), [k, A] = p(n ?? g), [j, N] = p(n !== void 0), P = f(null), F = f(k), L = f(null), R = f(void 0), z = s((e) => {
|
|
105
105
|
let t = () => {
|
|
106
|
-
e === null ? (
|
|
106
|
+
e === null ? (o && h(o), N(!1)) : (o && T(o, e), A(e), N(!0));
|
|
107
107
|
};
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
108
|
+
if (d) {
|
|
109
|
+
let e = C(() => E(t), d === "reveal" ? "reveal" : "fade");
|
|
110
|
+
R.current = e.finished, e.finished.then(() => R.current = void 0, () => R.current = void 0);
|
|
111
|
+
} else t();
|
|
112
|
+
}, [o, d]), B = d === "reveal";
|
|
113
|
+
l(() => B ? x() : void 0, [B]);
|
|
114
|
+
let [V, H] = p(n);
|
|
115
|
+
return n !== V && (H(n), n === void 0 ? N(!1) : (A(n), N(!0))), u(() => {
|
|
116
|
+
if (j) return;
|
|
117
|
+
let e = o ? S(o) : null, t = e ?? y();
|
|
118
|
+
if (t !== F.current && (P.current = t), A(t), e) {
|
|
119
|
+
N(!0);
|
|
115
120
|
return;
|
|
116
121
|
}
|
|
117
|
-
return
|
|
118
|
-
}, [
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if (
|
|
122
|
-
|
|
122
|
+
return w(A);
|
|
123
|
+
}, [j, o]), i(() => {
|
|
124
|
+
k !== F.current && (L.current ??= b());
|
|
125
|
+
}, [k]), u(() => {
|
|
126
|
+
if (F.current = k, P.current !== null && P.current !== k) return;
|
|
127
|
+
P.current = null;
|
|
128
|
+
let e = L.current;
|
|
129
|
+
L.current = null;
|
|
130
|
+
let t = r === "global" ? _() : null, n = t ? m(t, k) : void 0;
|
|
131
|
+
return e?.(R.current), n;
|
|
132
|
+
}, [k, r]), r === "local" ? /* @__PURE__ */ O(I.Provider, {
|
|
123
133
|
value: {
|
|
124
|
-
theme:
|
|
125
|
-
setTheme:
|
|
134
|
+
theme: k,
|
|
135
|
+
setTheme: z
|
|
126
136
|
},
|
|
127
|
-
children: [
|
|
128
|
-
className:
|
|
129
|
-
props: { "data-theme":
|
|
137
|
+
children: [v, /* @__PURE__ */ D(a, {
|
|
138
|
+
className: k,
|
|
139
|
+
props: { "data-theme": k },
|
|
130
140
|
children: t
|
|
131
141
|
})]
|
|
132
|
-
}) : /* @__PURE__ */
|
|
142
|
+
}) : /* @__PURE__ */ O(I.Provider, {
|
|
133
143
|
value: {
|
|
134
|
-
theme:
|
|
135
|
-
setTheme:
|
|
144
|
+
theme: k,
|
|
145
|
+
setTheme: z
|
|
136
146
|
},
|
|
137
|
-
children: [
|
|
147
|
+
children: [v, t]
|
|
138
148
|
});
|
|
139
149
|
}
|
|
140
150
|
(function(e) {
|
|
141
151
|
function t() {
|
|
142
|
-
let { theme: e, setTheme: t } = c(
|
|
152
|
+
let { theme: e, setTheme: t } = c(I);
|
|
143
153
|
return [e, t];
|
|
144
154
|
}
|
|
145
155
|
e.useTheme = t;
|
|
146
|
-
})(
|
|
147
|
-
var
|
|
148
|
-
function
|
|
149
|
-
let t =
|
|
150
|
-
return t || (t = /* @__PURE__ */ new Map(),
|
|
156
|
+
})(L ||= {});
|
|
157
|
+
var R = L, z = /* @__PURE__ */ new WeakMap();
|
|
158
|
+
function B(e) {
|
|
159
|
+
let t = z.get(e);
|
|
160
|
+
return t || (t = /* @__PURE__ */ new Map(), z.set(e, t)), t;
|
|
151
161
|
}
|
|
152
|
-
function
|
|
153
|
-
let [t] =
|
|
162
|
+
function V(e = !0) {
|
|
163
|
+
let [t] = R.useTheme(), n = d(() => {
|
|
154
164
|
if (!e) return null;
|
|
155
165
|
let t = r();
|
|
156
166
|
if (!t) return null;
|
|
@@ -159,7 +169,7 @@ function z(e = !0) {
|
|
|
159
169
|
}, [e]);
|
|
160
170
|
return u(() => {
|
|
161
171
|
if (!t || !n) return;
|
|
162
|
-
let e =
|
|
172
|
+
let e = B(n), r = e.get(t) ?? 0;
|
|
163
173
|
return e.set(t, r + 1), r === 0 && n.classList.add(t), () => {
|
|
164
174
|
let r = (e.get(t) ?? 1) - 1;
|
|
165
175
|
r <= 0 ? (e.delete(t), n.classList.remove(t)) : e.set(t, r);
|
|
@@ -167,4 +177,4 @@ function z(e = !0) {
|
|
|
167
177
|
}, [n, t]), n;
|
|
168
178
|
}
|
|
169
179
|
//#endregion
|
|
170
|
-
export {
|
|
180
|
+
export { k as a, j as i, R as n, N as r, V as t };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { default as GridModel } from '../models/gridModel';
|
|
2
|
+
interface Props<TRow> {
|
|
3
|
+
grid: GridModel<TRow>;
|
|
4
|
+
}
|
|
5
|
+
/** The selection's half of the bottom bar: the count, how much of it the filters hide, and the two ways out. */
|
|
6
|
+
export default function DataGridBottomBarSelection<TRow>(props: Props<TRow>): import("react").JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { default as GridModel } from '../models/gridModel';
|
|
2
|
+
interface Props<TRow> {
|
|
3
|
+
grid: GridModel<TRow>;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* The columns button and its panel: a non-modal dialog with a search field, the count and the two bulk
|
|
7
|
+
* actions, and one switch per column under its header group's name.
|
|
8
|
+
*/
|
|
9
|
+
export default function DataGridColumnsPanel<TRow>(props: Props<TRow>): import("react").JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -4,10 +4,10 @@ interface Props<TRow> {
|
|
|
4
4
|
/** Position in the whole row list, not in the rendered window. */
|
|
5
5
|
index: number;
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
* from the model has moved, since every other prop it takes holds still while the window slides.
|
|
7
|
+
* This row's version (`GridModel.rowVersion`). Not read: it is what tells the memo below that something
|
|
8
|
+
* the row draws from the model has moved, since every other prop it takes holds still while the window slides.
|
|
9
9
|
*/
|
|
10
|
-
version:
|
|
10
|
+
version: string;
|
|
11
11
|
}
|
|
12
12
|
declare function DataGridDetailRowImpl<TRow>(props: Props<TRow>): import("react").JSX.Element;
|
|
13
13
|
/**
|
|
@@ -4,10 +4,10 @@ interface Props<TRow> {
|
|
|
4
4
|
/** Position in the whole row list, not in the rendered window. */
|
|
5
5
|
index: number;
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
* from the model has moved, since every other prop it takes holds still while the window slides.
|
|
7
|
+
* This row's version (`GridModel.rowVersion`). Not read: it is what tells the memo below that something
|
|
8
|
+
* the row draws from the model has moved, since every other prop it takes holds still while the window slides.
|
|
9
9
|
*/
|
|
10
|
-
version:
|
|
10
|
+
version: string;
|
|
11
11
|
}
|
|
12
12
|
declare function DataGridGroupRowImpl<TRow>(props: Props<TRow>): import("react").JSX.Element;
|
|
13
13
|
/**
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { default as GridModel } from '../models/gridModel';
|
|
2
2
|
interface Props<TRow> {
|
|
3
3
|
grid: GridModel<TRow>;
|
|
4
|
+
/** `GridModel.headerVersion`. Not read: it is what tells the memo below the header has something new to draw. */
|
|
5
|
+
version: string;
|
|
4
6
|
}
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
declare function DataGridHeaderImpl<TRow>(props: Props<TRow>): import("react").JSX.Element;
|
|
8
|
+
/** Memoized, so a press that only moves the tab stop does not redraw the header and the filters under it. */
|
|
9
|
+
declare const DataGridHeader: typeof DataGridHeaderImpl;
|
|
10
|
+
export default DataGridHeader;
|
|
@@ -4,10 +4,10 @@ interface Props<TRow> {
|
|
|
4
4
|
/** Position in the whole row list, not in the rendered window. */
|
|
5
5
|
index: number;
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
* from the model has moved, since every other prop it takes holds still while the window slides.
|
|
7
|
+
* This row's version (`GridModel.rowVersion`). Not read: it is what tells the memo below that something
|
|
8
|
+
* the row draws from the model has moved, since every other prop it takes holds still while the window slides.
|
|
9
9
|
*/
|
|
10
|
-
version:
|
|
10
|
+
version: string;
|
|
11
11
|
}
|
|
12
12
|
declare function DataGridRowImpl<TRow>(props: Props<TRow>): import("react").JSX.Element;
|
|
13
13
|
/**
|