@ishibashi0112/spreadsheet-grid 0.28.1 → 0.29.1

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.
@@ -239,6 +239,13 @@ export type CellStyleContext<T> = {
239
239
  isEditing: boolean;
240
240
  readOnly: boolean;
241
241
  };
242
+ export type RowStyleContext<T> = {
243
+ row: T;
244
+ rowIndex: number;
245
+ sourceRowIndex: number;
246
+ rowKey: GridRowKey;
247
+ isSelected: boolean;
248
+ };
242
249
  export type CellRenderState = {
243
250
  isActive: boolean;
244
251
  isSelected: boolean;
@@ -362,7 +369,7 @@ export type GridColumn<T> = {
362
369
  valueFormatter?: CellValueFormatter<T>;
363
370
  renderHeader?: (ctx: HeaderRenderContext<T>) => ReactNode;
364
371
  filterType?: ColumnFilterTypeOption;
365
- filterOptions?: GridSelectFilterOption[];
372
+ filterOptions?: readonly GridSelectFilterOption[];
366
373
  dateFilterPresets?: false | readonly DateFilterPresetOption[];
367
374
  filterFn?: (row: T, filterValue: unknown) => boolean;
368
375
  editor?: GridColumnEditor<T>;
@@ -502,6 +509,15 @@ export type GridClassNames = {
502
509
  iconButton?: string;
503
510
  };
504
511
  export type ScrollAlign = 'auto' | 'start' | 'center' | 'end';
512
+ export type GridScrollPosition = {
513
+ top: number;
514
+ left: number;
515
+ };
516
+ export type GridScrollEventParams = {
517
+ top: number;
518
+ left: number;
519
+ source: 'user' | 'api';
520
+ };
505
521
  /**
506
522
  * エクスポートの対象範囲です(exportCsv / downloadCsv / getExportData で共通)。
507
523
  * - `'view'` : ビュー行全体(フィルター/ソート/列可視・固定順を反映)。**既定値**。スクロール位置に依存しません。
@@ -562,6 +578,13 @@ export type SpreadsheetGridHandle<T> = {
562
578
  startIndex: number;
563
579
  endIndex: number;
564
580
  } | null;
581
+ getScrollPosition: () => GridScrollPosition | null;
582
+ setScrollPosition: (position: {
583
+ top?: number;
584
+ left?: number;
585
+ }, options?: {
586
+ behavior?: 'auto' | 'smooth';
587
+ }) => void;
565
588
  getActiveCell: () => CellCoord | null;
566
589
  setActiveCell: (cell: CellCoord | null, options?: {
567
590
  scrollIntoView?: boolean;
@@ -622,12 +645,13 @@ export type ScrollHintOptions<T = unknown> = {
622
645
  export type SpreadsheetGridProps<T> = {
623
646
  ref?: Ref<SpreadsheetGridHandle<T>>;
624
647
  onStateChange?: (state: GridState) => void;
625
- rows?: T[];
648
+ onScroll?: (params: GridScrollEventParams) => void;
649
+ rows?: readonly T[];
626
650
  dataSource?: ServerSideDataSource<T>;
627
651
  serverSideRefreshToken?: number;
628
652
  onServerSideLoadError?: (error: unknown, params: ServerSideLoadErrorParams) => void;
629
653
  onServerSideWriteError?: (error: unknown, params: ServerSideWriteErrorParams<T>) => void;
630
- columns: GridColumn<T>[];
654
+ columns: readonly GridColumn<T>[];
631
655
  onRowsChange?: (nextRows: T[]) => void;
632
656
  onColumnsChange?: (nextColumns: GridColumn<T>[]) => void;
633
657
  rowKeyGetter?: (row: T, index: number) => GridRowKey;
@@ -683,7 +707,7 @@ export type SpreadsheetGridProps<T> = {
683
707
  renderBottomBar?: (context: SpreadsheetGridSlotContext<T>) => ReactNode;
684
708
  className?: string;
685
709
  classNames?: GridClassNames;
686
- getRowClassName?: (row: T, rowIndex: number) => string | undefined;
710
+ getRowClassName?: (row: T, rowIndex: number, ctx: RowStyleContext<T>) => string | undefined;
687
711
  enableContextMenu?: boolean;
688
712
  getContextMenuItems?: (params: GridContextMenuParams<T>) => GridContextMenuItem[];
689
713
  onContextMenuOpen?: (params: GridContextMenuParams<T>) => void;
@@ -0,0 +1,5 @@
1
+ export type JsdomLayoutStubOptions = {
2
+ width?: number;
3
+ height?: number;
4
+ };
5
+ export declare function installJsdomLayoutStubs(options?: JsdomLayoutStubOptions): () => void;
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e={}){let t=e.width??1200,n=e.height??600,r=Element.prototype,i=HTMLElement.prototype,a=Object.getOwnPropertyDescriptor(i,`clientHeight`),o=Object.getOwnPropertyDescriptor(i,`clientWidth`),s=r.getBoundingClientRect,c=globalThis.ResizeObserver,l=r.scrollTo;Object.defineProperty(i,"clientHeight",{configurable:!0,get:()=>n}),Object.defineProperty(i,"clientWidth",{configurable:!0,get:()=>t}),r.getBoundingClientRect=()=>({x:0,y:0,top:0,left:0,bottom:n,right:t,width:t,height:n,toJSON:()=>({})});class u{callback;constructor(e){this.callback=e}observe(e){let r={inlineSize:t,blockSize:n};this.callback([{target:e,contentRect:{width:t,height:n,top:0,left:0},borderBoxSize:[r],contentBoxSize:[r]}],this)}unobserve(){}disconnect(){}}return globalThis.ResizeObserver=u,r.scrollTo||=()=>{},()=>{a?Object.defineProperty(i,"clientHeight",a):delete i.clientHeight,o?Object.defineProperty(i,"clientWidth",o):delete i.clientWidth,r.getBoundingClientRect=s,globalThis.ResizeObserver=c,r.scrollTo=l}}exports.installJsdomLayoutStubs=e;
@@ -0,0 +1,51 @@
1
+ //#region src/components/spreadsheet-grid/testing/index.ts
2
+ function e(e = {}) {
3
+ let t = e.width ?? 1200, n = e.height ?? 600, r = Element.prototype, i = HTMLElement.prototype, a = Object.getOwnPropertyDescriptor(i, "clientHeight"), o = Object.getOwnPropertyDescriptor(i, "clientWidth"), s = r.getBoundingClientRect, c = globalThis.ResizeObserver, l = r.scrollTo;
4
+ Object.defineProperty(i, "clientHeight", {
5
+ configurable: !0,
6
+ get: () => n
7
+ }), Object.defineProperty(i, "clientWidth", {
8
+ configurable: !0,
9
+ get: () => t
10
+ }), r.getBoundingClientRect = () => ({
11
+ x: 0,
12
+ y: 0,
13
+ top: 0,
14
+ left: 0,
15
+ bottom: n,
16
+ right: t,
17
+ width: t,
18
+ height: n,
19
+ toJSON: () => ({})
20
+ });
21
+ class u {
22
+ callback;
23
+ constructor(e) {
24
+ this.callback = e;
25
+ }
26
+ observe(e) {
27
+ let r = {
28
+ inlineSize: t,
29
+ blockSize: n
30
+ };
31
+ this.callback([{
32
+ target: e,
33
+ contentRect: {
34
+ width: t,
35
+ height: n,
36
+ top: 0,
37
+ left: 0
38
+ },
39
+ borderBoxSize: [r],
40
+ contentBoxSize: [r]
41
+ }], this);
42
+ }
43
+ unobserve() {}
44
+ disconnect() {}
45
+ }
46
+ return globalThis.ResizeObserver = u, r.scrollTo ||= () => {}, () => {
47
+ a ? Object.defineProperty(i, "clientHeight", a) : delete i.clientHeight, o ? Object.defineProperty(i, "clientWidth", o) : delete i.clientWidth, r.getBoundingClientRect = s, globalThis.ResizeObserver = c, r.scrollTo = l;
48
+ };
49
+ }
50
+ //#endregion
51
+ export { e as installJsdomLayoutStubs };
@@ -1,6 +1,6 @@
1
1
  import type { CSSProperties, PointerEvent, ReactNode } from 'react';
2
2
  import type { SelectionSnapshot } from '../model/gridSelectors';
3
- import type { CellCoord, CellRenderState, GridColumn, RowModel, RowSelectionState, SpreadsheetGridProps } from '../model/gridTypes';
3
+ import type { CellCoord, CellRenderState, GridColumn, RowModel, RowSelectionState, RowStyleContext, SpreadsheetGridProps } from '../model/gridTypes';
4
4
  import type { PaneColumnEntry } from '../logic/geometry';
5
5
  import type { GridPaneKind } from './GridHeaderRow';
6
6
  type VirtualRowLike = {
@@ -40,7 +40,7 @@ type GridBodyLayerProps<T> = {
40
40
  onCellPointerEnter: (cell: CellCoord, event: PointerEvent<HTMLDivElement>) => void;
41
41
  onCellDoubleClick: (cell: CellCoord) => void;
42
42
  renderCellContent: (row: T, rowIndex: number, column: GridColumn<T>, colIndex: number, cellState: CellRenderState) => ReactNode;
43
- getRowClassName?: (row: T, rowIndex: number) => string | undefined;
43
+ getRowClassName?: (row: T, rowIndex: number, ctx: RowStyleContext<T>) => string | undefined;
44
44
  bodyCellClassName?: string;
45
45
  bodyRowClassName?: string;
46
46
  rowHeaderCellClassName?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ishibashi0112/spreadsheet-grid",
3
- "version": "0.28.1",
3
+ "version": "0.29.1",
4
4
  "description": "React 19 製のカスタム仮想化データグリッド。100 万行対応の仮想化・3 ペイン固定列・ソート/フィルター・クライアント/サーバーサイド行モデル対応。",
5
5
  "keywords": [
6
6
  "react",
@@ -40,6 +40,11 @@
40
40
  "import": "./dist/index.js",
41
41
  "require": "./dist/index.cjs"
42
42
  },
43
+ "./testing": {
44
+ "types": "./dist/testing/index.d.ts",
45
+ "import": "./dist/testing.js",
46
+ "require": "./dist/testing.cjs"
47
+ },
43
48
  "./style.css": "./dist/style.css",
44
49
  "./style.layer.css": "./dist/style.layer.css"
45
50
  },