@ishibashi0112/spreadsheet-grid 0.17.0 → 0.18.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/README.md +12 -4
- package/dist/SpreadsheetGrid.d.ts +1 -1
- package/dist/hooks/useGridClipboardController.d.ts +3 -1
- package/dist/hooks/useGridEditController.d.ts +3 -1
- package/dist/hooks/useServerSideRowModel.d.ts +9 -1
- package/dist/index.cjs +8 -8
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1969 -1748
- package/dist/logic/clearCells.d.ts +9 -0
- package/dist/logic/serverSideCache.d.ts +1 -0
- package/dist/logic/serverSideEdits.d.ts +16 -0
- package/dist/model/gridTypes.d.ts +23 -0
- package/dist/style.css +1 -1
- package/dist/utils/clipboard.d.ts +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ A high-performance, virtualized spreadsheet / data grid for **React 19**, writte
|
|
|
25
25
|
- Full-text tooltip on truncated cells — `showCellOverflowTooltip` shows the full value on hover, but only when the cell is actually clipped (…).
|
|
26
26
|
- Japanese-aware line wrapping — per-column `wordBreak` / `lineBreak`, including `wordBreak: 'auto-phrase'` for phrase-based breaks on Chromium (BudouX). Cross-browser BudouX recipe in the API reference.
|
|
27
27
|
- External height control via `height` / `maxHeight` (e.g. `height="100%"` to follow the parent's height).
|
|
28
|
-
- Both **client-side** (`rows`) and **server-side** (`dataSource`, SSRM) row models.
|
|
28
|
+
- Both **client-side** (`rows`) and **server-side** (`dataSource`, SSRM) row models — server-side includes query forwarding (filter / sort / global filter), soft refresh (`refreshServerSide()`), load-error retry UI, and cell-edit write-back via `dataSource.updateRows` with optimistic updates and automatic rollback on failure.
|
|
29
29
|
- Themeable with CSS custom properties (`--ssg-*`, defined at zero specificity so your overrides always win). Base styles are plain unlayered CSS with single-class specificity, so they survive CSS resets such as Tailwind Preflight; a cascade-layers variant (`style.layer.css`) is also shipped. `className` / `classNames` slots are provided.
|
|
30
30
|
- Styled tooltips out of the box — action hints and truncated-text previews use a custom dark-chip tooltip (no browser-default `title` look). Add `data-ssg-tooltip="text"` to your own elements (custom cells, headers) to get the same tooltip; colors are themeable via `--ssg-tooltip-*` tokens.
|
|
31
31
|
- Built-in dark theme — `theme="light" | "dark" | "auto"` switches the grid, every popover / panel / menu, the drag ghost and tooltips through a single token preset. `"auto"` follows `prefers-color-scheme`; with class-based dark frameworks (Mantine / HeroUI / Tailwind) pass your resolved color scheme instead.
|
|
@@ -222,11 +222,15 @@ Pass a `dataSource` instead of `rows` to switch to server-side mode. The grid ke
|
|
|
222
222
|
const { rows, totalRowCount } = await fetchPage({ startIndex, endIndex, query, signal })
|
|
223
223
|
return { rows, totalRowCount }
|
|
224
224
|
},
|
|
225
|
+
// Optional: enables cell editing in server-side mode (optimistic update + rollback on failure).
|
|
226
|
+
async updateRows({ updates }) {
|
|
227
|
+
await patchRows(updates) // updates: [{ rowKey, rowIndex, row, previousRow, changes }]
|
|
228
|
+
},
|
|
225
229
|
}}
|
|
226
230
|
/>
|
|
227
231
|
```
|
|
228
232
|
|
|
229
|
-
Sorting, column filters, and the global filter stay enabled and are forwarded to the server through `query`. See the [API reference](./src/components/spreadsheet-grid/API_REFERENCE.md) for the full `getRows`
|
|
233
|
+
Sorting, column filters, and the global filter stay enabled and are forwarded to the server through `query`. Cell edits (editor commit / paste / Delete-clear / checkbox) are written back through `updateRows` with optimistic updates — the grid rolls the cells back and shows a dismissible error bar if the write fails (`onServerSideWriteError` fires for toasts/logging). Without `updateRows`, server-side cells are read-only. Row add/remove has no write-back API; apply it on the server and call `refreshServerSide()`. See the [API reference](./src/components/spreadsheet-grid/API_REFERENCE.md) for the full `getRows` / `updateRows` contracts, the filter wire format, and `serverSideRefreshToken`.
|
|
230
234
|
|
|
231
235
|
## Styling & theming
|
|
232
236
|
|
|
@@ -308,7 +312,7 @@ The full prop and type reference lives in [`src/components/spreadsheet-grid/API_
|
|
|
308
312
|
- 省略(…)セルの全文ツールチップ — `showCellOverflowTooltip` でホバー時に全文表示(実際にクリップされているセルのみ)。
|
|
309
313
|
- 日本語対応の折り返し — 列ごとの `wordBreak` / `lineBreak`。`wordBreak: 'auto-phrase'` で Chromium(Chrome / Edge)の文節折り返し(BudouX)。クロスブラウザの BudouX レシピは API リファレンス参照。
|
|
310
314
|
- `height` / `maxHeight` によるスクロールコンテナ高さの外部制御(`height="100%"` で親要素の高さに追従)。
|
|
311
|
-
- **クライアントサイド**(`rows`)と**サーバーサイド**(`dataSource`、SSRM
|
|
315
|
+
- **クライアントサイド**(`rows`)と**サーバーサイド**(`dataSource`、SSRM)の両行モデル — サーバーサイドはクエリ送出(フィルター / ソート / グローバルフィルター)、ソフトリフレッシュ(`refreshServerSide()`)、取得失敗の再試行 UI に加え、`dataSource.updateRows` によるセル編集の書き戻し(楽観更新 + 失敗時の自動ロールバック)まで対応。
|
|
312
316
|
- CSS カスタムプロパティ(`--ssg-*`。特異度 0 で定義され、利用側の上書きが常に勝ちます)によるテーマ設定。基底スタイルは未レイヤーの単一クラス特異度で、Tailwind Preflight などの CSS リセットに壊されません。カスケードレイヤー版(`style.layer.css`)も同梱。`className` / `classNames` スロットも用意。
|
|
313
317
|
- スタイル付きツールチップを標準装備 — 操作ヒントや切り詰めテキストの全文表示は、ブラウザ標準の `title` ではなくダークチップのカスタムツールチップで表示。利用側の要素(カスタムセルやヘッダー)にも `data-ssg-tooltip="文言"` を付けるだけで同じ見た目になります。配色は `--ssg-tooltip-*` トークンで調整可。
|
|
314
318
|
- ダークテーマを標準装備 — `theme="light" | "dark" | "auto"` で、グリッド本体・全ポップオーバー / パネル / メニュー・ドラッグゴースト・ツールチップをトークンプリセット 1 つで一括切替。`"auto"` は `prefers-color-scheme` に追従(Mantine / HeroUI / Tailwind のクラスベース dark 運用では、解決済みのカラースキームを渡す使い方を推奨)。
|
|
@@ -505,11 +509,15 @@ const invalid = gridRef.current?.getInvalidCells()
|
|
|
505
509
|
const { rows, totalRowCount } = await fetchPage({ startIndex, endIndex, query, signal })
|
|
506
510
|
return { rows, totalRowCount }
|
|
507
511
|
},
|
|
512
|
+
// 任意: serverSide のセル編集を有効化(楽観更新 + 失敗時ロールバック)。
|
|
513
|
+
async updateRows({ updates }) {
|
|
514
|
+
await patchRows(updates) // updates: [{ rowKey, rowIndex, row, previousRow, changes }]
|
|
515
|
+
},
|
|
508
516
|
}}
|
|
509
517
|
/>
|
|
510
518
|
```
|
|
511
519
|
|
|
512
|
-
ソート・列フィルター・グローバルフィルターは有効なまま `query`
|
|
520
|
+
ソート・列フィルター・グローバルフィルターは有効なまま `query` 経由でサーバへ送られます。セル編集(エディタ確定 / ペースト / Delete クリア / checkbox)は `updateRows` で楽観更新つきの書き戻しになり、保存失敗時はセルが自動で元に戻って保存失敗バーが表示されます(`onServerSideWriteError` でトースト / ログ通知も可)。`updateRows` 未指定の serverSide セルは読み取り専用です。行の追加削除は書き戻し API を持たないため、サーバへ反映後に `refreshServerSide()` を呼ぶ運用にしてください。`getRows` / `updateRows` の契約、フィルターの wire format、`serverSideRefreshToken` の詳細は [API リファレンス](./src/components/spreadsheet-grid/API_REFERENCE.md) を参照してください。
|
|
513
521
|
|
|
514
522
|
### スタイリング / テーマ
|
|
515
523
|
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import './styles.css';
|
|
2
2
|
import type { SpreadsheetGridProps } from './model/gridTypes';
|
|
3
|
-
export declare function SpreadsheetGrid<T extends object>({ rows, dataSource, serverSideRefreshToken, onServerSideLoadError, columns, onRowsChange, onColumnsChange, rowKeyGetter, createRow, createOverflowColumn, rowHeight: rowHeightProp, autoHeight, estimateRowHeight, headerHeight: headerHeightProp, density, theme, rowHeaderWidth, height, maxHeight, readOnly, dimReadOnlyCells, canEditCell, enableUndoRedo, undoHistoryLimit, onUndoRedoStateChange, enableRangeSelection, enableRowSelection, rowSelectionMode, enableSelectAllRows: enableSelectAllRowsProp, rowSelection: rowSelectionProp, selectedRowKeys: selectedRowKeysProp, onRowSelectionChange, enableGlobalFilter, enableColumnFilter, enableSorting, enableColumnResize, autoSizeColumns, showCellOverflowTooltip, showValidationMarks, enableRowHover, enableColumnHeaderHover, enableColumnMenu, noMatchingRowsText, noRowsText, showTopBar, showBottomBar, showTopBarSummary, showTopBarFilter, globalFilterPlaceholder, globalFilterIcon, showTopBarCounts, showBottomBarCounts, showFilterChipBar, renderTopBar, renderBottomBar, className, classNames, getRowClassName, enableContextMenu, getContextMenuItems, onContextMenuOpen, ref, onStateChange, }: SpreadsheetGridProps<T>): import("react").JSX.Element;
|
|
3
|
+
export declare function SpreadsheetGrid<T extends object>({ rows, dataSource, serverSideRefreshToken, onServerSideLoadError, onServerSideWriteError, columns, onRowsChange, onColumnsChange, rowKeyGetter, createRow, createOverflowColumn, rowHeight: rowHeightProp, autoHeight, estimateRowHeight, headerHeight: headerHeightProp, density, theme, rowHeaderWidth, height, maxHeight, readOnly, dimReadOnlyCells, canEditCell: canEditCellProp, enableUndoRedo, undoHistoryLimit, onUndoRedoStateChange, enableRangeSelection, enableRowSelection, rowSelectionMode, enableSelectAllRows: enableSelectAllRowsProp, rowSelection: rowSelectionProp, selectedRowKeys: selectedRowKeysProp, onRowSelectionChange, enableGlobalFilter, enableColumnFilter, enableSorting, enableColumnResize, autoSizeColumns, showCellOverflowTooltip, showValidationMarks, enableRowHover, enableColumnHeaderHover, enableColumnMenu, noMatchingRowsText, noRowsText, showTopBar, showBottomBar, showTopBarSummary, showTopBarFilter, globalFilterPlaceholder, globalFilterIcon, showTopBarCounts, showBottomBarCounts, showFilterChipBar, renderTopBar, renderBottomBar, className, classNames, getRowClassName, enableContextMenu, getContextMenuItems, onContextMenuOpen, ref, onStateChange, }: SpreadsheetGridProps<T>): import("react").JSX.Element;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type Dispatch } from 'react';
|
|
2
2
|
import { type GridUiAction } from '../model/gridActions';
|
|
3
3
|
import type { GridColumn, SpreadsheetGridProps, GridUiState, RowModel } from '../model/gridTypes';
|
|
4
|
+
import type { ServerSideCellEditInput } from '../logic/serverSideEdits';
|
|
4
5
|
type UseGridClipboardControllerArgs<T extends object> = {
|
|
5
6
|
rows: T[];
|
|
6
7
|
rowModel: RowModel<T>;
|
|
@@ -12,9 +13,10 @@ type UseGridClipboardControllerArgs<T extends object> = {
|
|
|
12
13
|
createOverflowColumn?: (columnIndex: number) => GridColumn<T>;
|
|
13
14
|
onRowsChange?: (nextRows: T[]) => void;
|
|
14
15
|
onColumnsChange?: (nextColumns: GridColumn<T>[]) => void;
|
|
16
|
+
applyServerSideCellEdits?: (edits: ServerSideCellEditInput<T>[]) => number;
|
|
15
17
|
dispatch: Dispatch<GridUiAction>;
|
|
16
18
|
};
|
|
17
|
-
export declare const useGridClipboardController: <T extends object>({ rows, rowModel, visibleColumns, uiState, readOnly, canEditCell, createRow, createOverflowColumn, onRowsChange, onColumnsChange, dispatch, }: UseGridClipboardControllerArgs<T>) => {
|
|
19
|
+
export declare const useGridClipboardController: <T extends object>({ rows, rowModel, visibleColumns, uiState, readOnly, canEditCell, createRow, createOverflowColumn, onRowsChange, onColumnsChange, applyServerSideCellEdits, dispatch, }: UseGridClipboardControllerArgs<T>) => {
|
|
18
20
|
isWholeGridSelected: boolean;
|
|
19
21
|
handleCopy: () => Promise<void>;
|
|
20
22
|
handlePaste: (event: React.ClipboardEvent<HTMLDivElement>) => void;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type Dispatch, type RefObject } from 'react';
|
|
2
2
|
import { type GridUiAction } from '../model/gridActions';
|
|
3
3
|
import type { CellCoord, EditorCommitDirection, EditorCommitResult, GridColumn, GridUiState, RowModel } from '../model/gridTypes';
|
|
4
|
+
import type { ServerSideCellEditInput } from '../logic/serverSideEdits';
|
|
4
5
|
type UseGridEditControllerArgs<T extends object> = {
|
|
5
6
|
uiState: GridUiState;
|
|
6
7
|
rows: T[];
|
|
@@ -8,12 +9,13 @@ type UseGridEditControllerArgs<T extends object> = {
|
|
|
8
9
|
rowModel: RowModel<T>;
|
|
9
10
|
setEditorInitialValue: (value: string) => void;
|
|
10
11
|
onRowsChange?: (nextRows: T[]) => void;
|
|
12
|
+
applyServerSideCellEdits?: (edits: ServerSideCellEditInput<T>[]) => number;
|
|
11
13
|
dispatch: Dispatch<GridUiAction>;
|
|
12
14
|
getMovedCell: (baseCell: CellCoord, deltaRow: number, deltaCol: number) => CellCoord;
|
|
13
15
|
gridRootRef: RefObject<HTMLDivElement | null>;
|
|
14
16
|
editorActionGuardRef: RefObject<boolean>;
|
|
15
17
|
};
|
|
16
|
-
export declare const useGridEditController: <T extends object>({ uiState, rows, visibleColumns, rowModel, setEditorInitialValue, onRowsChange, dispatch, getMovedCell, gridRootRef, editorActionGuardRef, }: UseGridEditControllerArgs<T>) => {
|
|
18
|
+
export declare const useGridEditController: <T extends object>({ uiState, rows, visibleColumns, rowModel, setEditorInitialValue, onRowsChange, applyServerSideCellEdits, dispatch, getMovedCell, gridRootRef, editorActionGuardRef, }: UseGridEditControllerArgs<T>) => {
|
|
17
19
|
activateSingleCell: (cell: CellCoord) => void;
|
|
18
20
|
startEditWithValue: (cell: CellCoord, initialValue: string) => void;
|
|
19
21
|
commitEdit: (committedValue: unknown, direction?: EditorCommitDirection) => EditorCommitResult;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { GridRowKey, RowModel, ServerSideDataSource, ServerSideLoadErrorParams, ServerSideQuery } from '../model/gridTypes';
|
|
1
|
+
import type { GridRowKey, RowModel, ServerSideDataSource, ServerSideLoadErrorParams, ServerSideQuery, ServerSideWriteErrorParams } from '../model/gridTypes';
|
|
2
|
+
import { type ServerSideCellEditInput } from '../logic/serverSideEdits';
|
|
2
3
|
export type UseServerSideRowModelParams<T> = {
|
|
3
4
|
dataSource?: ServerSideDataSource<T>;
|
|
4
5
|
rowKeyGetter: (row: T, index: number) => GridRowKey;
|
|
@@ -6,11 +7,15 @@ export type UseServerSideRowModelParams<T> = {
|
|
|
6
7
|
queryKey: string;
|
|
7
8
|
refreshToken?: number;
|
|
8
9
|
onLoadError?: (error: unknown, params: ServerSideLoadErrorParams) => void;
|
|
10
|
+
onWriteError?: (error: unknown, params: ServerSideWriteErrorParams<T>) => void;
|
|
9
11
|
debounceMs?: number;
|
|
10
12
|
};
|
|
11
13
|
export type ServerSideLoadErrorState = {
|
|
12
14
|
failedBlockCount: number;
|
|
13
15
|
};
|
|
16
|
+
export type ServerSideWriteErrorState = {
|
|
17
|
+
failedRowCount: number;
|
|
18
|
+
};
|
|
14
19
|
export type UseServerSideRowModelResult<T> = {
|
|
15
20
|
rowModel: RowModel<T>;
|
|
16
21
|
rowCount: number;
|
|
@@ -19,5 +24,8 @@ export type UseServerSideRowModelResult<T> = {
|
|
|
19
24
|
refresh: () => void;
|
|
20
25
|
loadError: ServerSideLoadErrorState | null;
|
|
21
26
|
retryFailedBlocks: () => void;
|
|
27
|
+
canUpdateRows: boolean;
|
|
28
|
+
applyCellEdits: (edits: ServerSideCellEditInput<T>[]) => number;
|
|
29
|
+
writeError: ServerSideWriteErrorState | null;
|
|
22
30
|
};
|
|
23
31
|
export declare function useServerSideRowModel<T>(params: UseServerSideRowModelParams<T>): UseServerSideRowModelResult<T>;
|