@freegridjs/core 0.7.1 → 0.8.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.
@@ -1,4 +1,4 @@
1
- import { L as LocalePack } from '../types-CusLVNhk.js';
1
+ import { L as LocalePack } from '../types-e45suTSB.js';
2
2
 
3
3
  declare const de: LocalePack;
4
4
 
@@ -32,6 +32,7 @@ var de = {
32
32
  pasteHint: "Der Browser hat die Zwischenablage blockiert. Dr\xFCcken Sie Ctrl+V zum Einf\xFCgen.",
33
33
  required: "Dieses Feld ist erforderlich",
34
34
  invalidValue: "Ung\xFCltiger Wert",
35
+ duplicate: "Dieser Wert wird bereits verwendet",
35
36
  undo: "R\xFCckg\xE4ngig",
36
37
  redo: "Wiederholen",
37
38
  deleteRows: "Ausgew\xE4hlte Zeilen l\xF6schen",
@@ -1,4 +1,4 @@
1
- import { L as LocalePack } from '../types-CusLVNhk.js';
1
+ import { L as LocalePack } from '../types-e45suTSB.js';
2
2
 
3
3
  declare const en: LocalePack;
4
4
 
@@ -32,6 +32,7 @@ var en = {
32
32
  pasteHint: "Clipboard access was blocked. Press Ctrl+V to paste.",
33
33
  required: "This field is required",
34
34
  invalidValue: "Invalid value",
35
+ duplicate: "This value is already used",
35
36
  undo: "Undo",
36
37
  redo: "Redo",
37
38
  deleteRows: "Delete selected rows",
@@ -1,4 +1,4 @@
1
- import { L as LocalePack } from '../types-CusLVNhk.js';
1
+ import { L as LocalePack } from '../types-e45suTSB.js';
2
2
 
3
3
  declare const es: LocalePack;
4
4
 
@@ -32,6 +32,7 @@ var es = {
32
32
  pasteHint: "El navegador bloque\xF3 el portapapeles. Pulsa Ctrl+V para pegar.",
33
33
  required: "Este campo es obligatorio",
34
34
  invalidValue: "Valor no v\xE1lido",
35
+ duplicate: "Este valor ya est\xE1 en uso",
35
36
  undo: "Deshacer",
36
37
  redo: "Rehacer",
37
38
  deleteRows: "Eliminar filas seleccionadas",
@@ -1,4 +1,4 @@
1
- import { L as LocalePack } from '../types-CusLVNhk.js';
1
+ import { L as LocalePack } from '../types-e45suTSB.js';
2
2
 
3
3
  declare const fr: LocalePack;
4
4
 
@@ -32,6 +32,7 @@ var fr = {
32
32
  pasteHint: "Le navigateur a bloqu\xE9 le presse-papiers. Appuyez sur Ctrl+V pour coller.",
33
33
  required: "Ce champ est obligatoire",
34
34
  invalidValue: "Valeur non valide",
35
+ duplicate: "Cette valeur est d\xE9j\xE0 utilis\xE9e",
35
36
  undo: "Annuler",
36
37
  redo: "R\xE9tablir",
37
38
  deleteRows: "Supprimer les lignes s\xE9lectionn\xE9es",
@@ -1,4 +1,4 @@
1
- import { L as LocalePack } from '../types-CusLVNhk.js';
1
+ import { L as LocalePack } from '../types-e45suTSB.js';
2
2
 
3
3
  declare const ja: LocalePack;
4
4
 
@@ -32,6 +32,7 @@ var ja = {
32
32
  pasteHint: "\u30D6\u30E9\u30A6\u30B6\u30FC\u304C\u30AF\u30EA\u30C3\u30D7\u30DC\u30FC\u30C9\u3078\u306E\u30A2\u30AF\u30BB\u30B9\u3092\u30D6\u30ED\u30C3\u30AF\u3057\u307E\u3057\u305F\u3002Ctrl+V \u3067\u8CBC\u308A\u4ED8\u3051\u3066\u304F\u3060\u3055\u3044\u3002",
33
33
  required: "\u3053\u306E\u9805\u76EE\u306F\u5FC5\u9808\u3067\u3059",
34
34
  invalidValue: "\u7121\u52B9\u306A\u5024\u3067\u3059",
35
+ duplicate: "\u3053\u306E\u5024\u306F\u3059\u3067\u306B\u4F7F\u308F\u308C\u3066\u3044\u307E\u3059",
35
36
  undo: "\u5143\u306B\u623B\u3059",
36
37
  redo: "\u3084\u308A\u76F4\u3057",
37
38
  deleteRows: "\u9078\u629E\u3057\u305F\u884C\u3092\u524A\u9664",
@@ -1,4 +1,4 @@
1
- import { L as LocalePack } from '../types-CusLVNhk.js';
1
+ import { L as LocalePack } from '../types-e45suTSB.js';
2
2
 
3
3
  declare const ko: LocalePack;
4
4
 
@@ -32,6 +32,7 @@ var ko = {
32
32
  pasteHint: "\uBE0C\uB77C\uC6B0\uC800\uAC00 \uD074\uB9BD\uBCF4\uB4DC \uC811\uADFC\uC744 \uB9C9\uC558\uC2B5\uB2C8\uB2E4. Ctrl+V\uB85C \uBD99\uC5EC\uB123\uC73C\uC138\uC694.",
33
33
  required: "\uD544\uC218 \uC785\uB825 \uD56D\uBAA9\uC785\uB2C8\uB2E4",
34
34
  invalidValue: "\uC62C\uBC14\uB978 \uAC12\uC774 \uC544\uB2D9\uB2C8\uB2E4",
35
+ duplicate: "\uC774\uBBF8 \uC0AC\uC6A9 \uC911\uC778 \uAC12\uC785\uB2C8\uB2E4",
35
36
  undo: "\uC2E4\uD589 \uCDE8\uC18C",
36
37
  redo: "\uB2E4\uC2DC \uC2E4\uD589",
37
38
  deleteRows: "\uC120\uD0DD\uD55C \uD589 \uC0AD\uC81C",
@@ -1,4 +1,4 @@
1
- import { L as LocalePack } from '../types-CusLVNhk.js';
1
+ import { L as LocalePack } from '../types-e45suTSB.js';
2
2
 
3
3
  declare const zhCN: LocalePack;
4
4
 
@@ -32,6 +32,7 @@ var zhCN = {
32
32
  pasteHint: "\u6D4F\u89C8\u5668\u963B\u6B62\u4E86\u526A\u8D34\u677F\u8BBF\u95EE\u3002\u8BF7\u6309 Ctrl+V \u7C98\u8D34\u3002",
33
33
  required: "\u6B64\u9879\u4E3A\u5FC5\u586B\u9879",
34
34
  invalidValue: "\u503C\u65E0\u6548",
35
+ duplicate: "\u8BE5\u503C\u5DF2\u88AB\u4F7F\u7528",
35
36
  undo: "\u64A4\u9500",
36
37
  redo: "\u91CD\u505A",
37
38
  deleteRows: "\u5220\u9664\u6240\u9009\u884C",
package/dist/styles.css CHANGED
@@ -6,7 +6,7 @@
6
6
  --fg-shadow: 0 12px 32px rgba(15, 23, 42, .16), 0 2px 6px rgba(15, 23, 42, .08);
7
7
  }
8
8
  .fg-theme-light {
9
- --fg-bg: #ffffff; --fg-fg: #1f2430; --fg-muted: #6b7385;
9
+ --fg-bg: #ffffff; --fg-fg: #1f2430; --fg-muted: #636b7c;
10
10
  --fg-header-bg: #f6f7f9; --fg-header-fg: #39404f; --fg-border: #e3e6eb; --fg-row-border: #eef0f3;
11
11
  --fg-row-odd: #fbfbfc; --fg-row-hover: #f2f6ff; --fg-row-selected: #e3edff;
12
12
  --fg-accent: #2563eb; --fg-accent-fg: #ffffff; --fg-focus: #2563eb; --fg-popup-bg: #ffffff; --fg-input-bg: #ffffff;
@@ -29,6 +29,7 @@
29
29
  }
30
30
  .fg-root *, .fg-menu * { box-sizing: border-box; }
31
31
  .fg-main { position: relative; display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; overflow: hidden; }
32
+ .fg-grid { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; outline: none; }
32
33
  .fg-root [hidden], .fg-menu [hidden] { display: none !important; }
33
34
  .fg-header { display: flex; flex: none; background: var(--fg-header-bg); color: var(--fg-header-fg); border-bottom: var(--fg-header-border, 1px solid var(--fg-border)); }
34
35
  .fg-header-pane { position: relative; overflow: hidden; flex: none; }
@@ -291,7 +292,11 @@ textarea.fg-editor-control { padding-top: 8px; resize: none; }
291
292
  .fg-drag-handle.fg-drag-disabled { opacity: .35; cursor: not-allowed; }
292
293
  .fg-row-dragging, .fg-row-dragging * { cursor: grabbing !important; }
293
294
  .fg-row-drop-marker { position: absolute; left: 0; right: 0; height: 2px; background: var(--fg-accent); z-index: 6; pointer-events: none; }
295
+ .fg-row-drop-marker.fg-row-drop-inside { background: color-mix(in srgb, var(--fg-accent) 8%, transparent); box-shadow: inset 0 0 0 2px var(--fg-accent); }
294
296
  @media (prefers-reduced-motion: reduce) { .fg-group-toggle svg, .fg-tree-toggle svg, .fg-detail-toggle svg { transition: none; } }
297
+ .fg-tree-loading svg { animation: fg-spin .8s linear infinite; opacity: .6; }
298
+ @keyframes fg-spin { to { transform: rotate(360deg); } }
299
+ @media (prefers-reduced-motion: reduce) { .fg-tree-loading svg { animation: none; } }
295
300
 
296
301
  /* pagination and server rows */
297
302
  .fg-pager {
@@ -375,3 +380,42 @@ textarea.fg-editor-control { padding-top: 8px; resize: none; }
375
380
  }
376
381
  .fg-free-badge:hover { opacity: 1; }
377
382
  .fg-free-badge svg { flex: none; }
383
+
384
+ /* column spans */
385
+ .fg-cell-span-hidden { visibility: hidden; }
386
+ .fg-cell-colspan { z-index: 1; background: inherit; }
387
+
388
+ /* per-cell locks */
389
+ .fg-cell-readonly { color: var(--fg-muted); background-image: linear-gradient(rgba(14, 23, 38, .025), rgba(14, 23, 38, .025)); }
390
+ .fg-cell-select-locked .fg-checkbox { cursor: not-allowed; opacity: .45; }
391
+
392
+ /* wrapped cells (autoRowHeight grows the row to fit) */
393
+ .fg-cell-wrap { white-space: normal; overflow-wrap: anywhere; text-overflow: clip; line-height: 1.45; padding-top: 6px; padding-bottom: 6px; }
394
+
395
+ /* right-to-left: mirror the grid area, then turn every cell back so text reads normally */
396
+ /* the root keeps dir=rtl (side bar on the left); the grid inside is laid out ltr and mirrored */
397
+ .fg-rtl .fg-main { transform: scaleX(-1); direction: ltr; }
398
+ .fg-rtl .fg-cell, .fg-rtl .fg-header-cell, .fg-rtl .fg-statusbar, .fg-rtl .fg-pager, .fg-rtl .fg-group-panel,
399
+ .fg-rtl .fg-overlay, .fg-rtl .fg-find, .fg-rtl .fg-chart-panel, .fg-rtl .fg-row-detail .fg-detail { transform: scaleX(-1); direction: rtl; }
400
+ .fg-rtl .fg-sidebar { direction: rtl; border-left: 0; border-right: 1px solid var(--fg-border); }
401
+
402
+ /* touch */
403
+ .fg-body { touch-action: pan-x pan-y; }
404
+ @media (pointer: coarse) {
405
+ .fg-editor input, .fg-editor select, .fg-editor textarea { font-size: 16px; } /* no zoom-in on focus in mobile Safari */
406
+ }
407
+
408
+ /* card view for narrow screens */
409
+ .fg-card-mode .fg-header, .fg-card-mode .fg-body, .fg-card-mode .fg-grid, .fg-card-mode .fg-summary, .fg-card-mode .fg-pinned-rows { display: none; }
410
+ .fg-cards { flex: 1; min-height: 0; overflow: auto; padding: 10px; -webkit-overflow-scrolling: touch; }
411
+ .fg-cards-canvas { position: relative; }
412
+ .fg-card {
413
+ position: absolute; left: 0; right: 0; top: 0; box-sizing: border-box; padding: 10px 14px; overflow: hidden;
414
+ border: 1px solid var(--fg-border); border-radius: 10px; background: var(--fg-bg); box-shadow: 0 1px 2px rgba(14, 23, 38, .06);
415
+ }
416
+ .fg-card-selected { border-color: var(--fg-accent); background: var(--fg-row-selected); }
417
+ .fg-card-other { background: var(--fg-header-bg); font-weight: 600; display: flex; align-items: center; }
418
+ .fg-card-head { display: flex; align-items: center; gap: 8px; height: var(--fg-card-line, 27px); color: var(--fg-muted); font-size: .92em; }
419
+ .fg-card-line { display: grid; grid-template-columns: minmax(80px, 38%) 1fr; gap: 10px; align-items: center; height: var(--fg-card-line, 27px); }
420
+ .fg-card-label { color: var(--fg-muted); font-size: .92em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
421
+ .fg-card-value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@@ -42,6 +42,11 @@ interface CellParams {
42
42
  rowIndex: number;
43
43
  column: ColumnDef;
44
44
  }
45
+ interface SpanParams {
46
+ value: unknown;
47
+ row: Row;
48
+ rowIndex: number;
49
+ }
45
50
  interface ColumnDef {
46
51
  /** Column id; defaults to `field`. Required when `field` is absent. */
47
52
  id?: string;
@@ -71,24 +76,77 @@ interface ColumnDef {
71
76
  chooser?: boolean;
72
77
  /** Users cannot hide this column from the UI (API still can). */
73
78
  lockVisible?: boolean;
74
- /** Allow editing and pasting into this column (requires `field`). */
75
- editable?: boolean;
79
+ /** Allow editing and pasting into this column (requires `field`); a function decides per cell. */
80
+ editable?: boolean | ((params: SpanParams & {
81
+ column: ColumnDef;
82
+ }) => boolean);
76
83
  /** Editor for editable columns; defaults by type (text, number, date, boolean toggle). */
77
84
  editor?: EditorSpec;
78
85
  /** Reject blank values on edit. */
79
86
  required?: boolean;
87
+ /** Cells may hold formulas like `=qty*price` (same-row fields); the result is shown, sorted and exported. */
88
+ formulas?: boolean;
89
+ /** Reject a value another row already has in this column (blank values are allowed). */
90
+ unique?: boolean;
91
+ /** Set false (or return false) to keep values out of copies: blocked cells copy as empty text. */
92
+ copyable?: boolean | ((params: {
93
+ value: unknown;
94
+ row: Row;
95
+ column: ColumnDef;
96
+ }) => boolean);
80
97
  /** Return true to accept, or a message to reject the edited value. */
81
98
  validate?: (value: unknown, row: Row) => true | string;
82
99
  /** Merge consecutive rows with the same value into one tall cell (or decide with a function). */
83
100
  merge?: boolean | ((a: unknown, b: unknown, rowA: Row, rowB: Row) => boolean);
84
101
  /** Let a long header label wrap onto more lines. */
85
102
  wrapHeaderText?: boolean;
103
+ /** Rows this cell covers downwards (1 = itself). Takes precedence over `merge`. */
104
+ rowSpan?: (params: SpanParams) => number;
105
+ /** Columns this cell covers to the right within its pinned area (1 = itself). */
106
+ colSpan?: (params: SpanParams) => number;
107
+ /** Wrap long text onto more lines (with `autoRowHeight` the row grows to fit). */
108
+ wrapText?: boolean;
109
+ /** Header content instead of the plain text (icons, buttons, links). Sorting and the menu button stay. */
110
+ headerRenderer?: (params: {
111
+ header: string;
112
+ column: ColumnDef;
113
+ }) => string | HTMLElement;
114
+ /** Extra class names on the header cell (also for column groups). */
115
+ headerClass?: string | ((column: ColumnDef) => string | undefined);
86
116
  /** Aggregate shown in group rows: 'sum' | 'avg' | 'min' | 'max' | 'count' | (values, rows) => value. */
87
117
  aggFunc?: Aggregator;
88
118
  }
119
+ interface InvalidCell {
120
+ row: Row;
121
+ /** Displayed row index; -1 when the row is filtered out or in a collapsed group. */
122
+ rowIndex: number;
123
+ colId: string;
124
+ message: string;
125
+ }
126
+ interface ScrollPosition {
127
+ top: number;
128
+ left: number;
129
+ }
130
+ type RowDropPosition = 'before' | 'after' | 'inside';
131
+ interface RowDropParams {
132
+ row: Row;
133
+ /** Row under the pointer; null = below the last row. */
134
+ target: Row | null;
135
+ /** 'inside' makes the row a child of the target (tree data only). */
136
+ position: RowDropPosition;
137
+ /** True when the row comes from another grid. */
138
+ fromOtherGrid: boolean;
139
+ }
140
+ interface RowDragOptions {
141
+ /** Grids with the same group accept rows dragged between them. */
142
+ group?: string;
143
+ /** Return false to refuse a drop target. */
144
+ canDrop?: (params: RowDropParams) => boolean;
145
+ }
89
146
  type SelectOption = unknown | {
90
147
  value: unknown;
91
148
  label?: string;
149
+ disabled?: boolean;
92
150
  };
93
151
  interface EditorParams {
94
152
  value: unknown;
@@ -108,6 +166,14 @@ type EditorSpec = {
108
166
  options: SelectOption[] | ((row: Row) => SelectOption[]);
109
167
  } | {
110
168
  type: 'textarea';
169
+ }
170
+ /** Time of day as 'HH:mm'. */
171
+ | {
172
+ type: 'time';
173
+ }
174
+ /** Date and time; Date values stay Dates, otherwise 'YYYY-MM-DDTHH:mm'. Default for date columns with format 'datetime'. */
175
+ | {
176
+ type: 'datetime';
111
177
  } | ((params: EditorParams) => CustomEditor);
112
178
  type KeyAction = 'edit' | 'clear' | 'undo' | 'redo' | 'copy' | 'paste' | 'selectAll' | 'find' | 'none';
113
179
  interface ColumnState {
@@ -148,6 +214,7 @@ interface Messages {
148
214
  pasteHint: string;
149
215
  required: string;
150
216
  invalidValue: string;
217
+ duplicate: string;
151
218
  undo: string;
152
219
  redo: string;
153
220
  deleteRows: string;
@@ -274,6 +341,8 @@ interface ExportOptions {
274
341
  sheetName?: string;
275
342
  /** CSV separator, default ','. */
276
343
  separator?: string;
344
+ /** xlsx: carry column align and the text color, background and bold of `cellClass` into the file. Default true. */
345
+ styles?: boolean;
277
346
  }
278
347
  interface PivotConfig {
279
348
  /** Row fields; every field but the last becomes a group level. */
@@ -348,6 +417,12 @@ interface GridOptions {
348
417
  /** Nest rows under their parent. Needs `getRowId`; `getParentId` returns the parent's id or null. */
349
418
  treeData?: {
350
419
  getParentId: (row: Row) => unknown;
420
+ /** Store a new parent id on the row (null = top level). Needed to drag rows to another parent. */
421
+ setParentId?: (row: Row, parentId: unknown, parent: Row | null) => void;
422
+ /** Rows whose children are not loaded yet but exist (e.g. folders on a server). */
423
+ hasChildren?: (row: Row) => boolean;
424
+ /** Fetch the children of a row on its first expand; they must carry the row's id as parent id. */
425
+ loadChildren?: (row: Row) => Promise<Row[]> | Row[];
351
426
  };
352
427
  /** Content of the expandable panel under a master row. */
353
428
  detailRenderer?: (params: {
@@ -358,8 +433,18 @@ interface GridOptions {
358
433
  detailHeight?: number;
359
434
  /** Which rows can expand a detail panel (default: all rows). */
360
435
  isRowMaster?: (row: Row) => boolean;
361
- /** Add a handle column for dragging rows into a new order. */
362
- rowDrag?: boolean;
436
+ /** Add a handle column for dragging rows into a new order (and between grids with the same `group`). */
437
+ rowDrag?: boolean | RowDragOptions;
438
+ /** Show rows as cards (header: value lines) when the grid is narrower than this many px; true = 640. */
439
+ cardView?: boolean | number;
440
+ /** 'rtl' lays the grid out right to left (Arabic, Hebrew…): first column on the right. */
441
+ direction?: 'ltr' | 'rtl';
442
+ /** Grow each row to fit its wrapped cells (`wrapText` columns); `rowHeight` is the minimum. */
443
+ autoRowHeight?: boolean;
444
+ /** Rows that may be checked; others show a disabled checkbox and are skipped by select-all. */
445
+ isRowSelectable?: (row: Row) => boolean;
446
+ /** Show the select-all checkbox in the header (default true). */
447
+ headerCheckbox?: boolean;
363
448
  /** Show rows one page at a time with a pager under the grid. */
364
449
  pagination?: boolean | {
365
450
  pageSize?: number;
@@ -464,6 +549,12 @@ interface GridEvents {
464
549
  fromIndex: number;
465
550
  toIndex: number;
466
551
  };
552
+ /** The rows area scrolled (also from setScrollPosition). */
553
+ scroll: ScrollPosition;
554
+ /** A row was dropped on this grid (also from another grid of the same drag group). */
555
+ rowDrop: RowDropParams & {
556
+ fromGrid: GridApi | null;
557
+ };
467
558
  pageChange: {
468
559
  page: number;
469
560
  pageSize: number;
@@ -479,12 +570,53 @@ interface GridEvents {
479
570
  end: number;
480
571
  error: unknown;
481
572
  };
573
+ /** treeData.loadChildren finished for a row. */
574
+ childrenLoaded: {
575
+ row: Row;
576
+ rows: Row[];
577
+ };
578
+ childrenLoadFailed: {
579
+ row: Row;
580
+ error: unknown;
581
+ };
482
582
  pivotChange: {
483
583
  pivot: PivotConfig | null;
484
584
  };
585
+ /** Fired before the change; call cancel() to stop it (e.g. to sort or filter on a server instead). */
586
+ beforeSort: {
587
+ sort: SortItem[];
588
+ cancel(): void;
589
+ };
590
+ beforeFilter: {
591
+ colId: string;
592
+ model: FilterModel | null;
593
+ cancel(): void;
594
+ };
595
+ beforePageChange: {
596
+ page: number;
597
+ pageSize: number;
598
+ cancel(): void;
599
+ };
600
+ beforeEdit: {
601
+ row: Row;
602
+ rowIndex: number;
603
+ colId: string;
604
+ cancel(): void;
605
+ };
606
+ beforeCellChange: {
607
+ row: Row;
608
+ rowIndex: number;
609
+ colId: string;
610
+ oldValue: unknown;
611
+ newValue: unknown;
612
+ cancel(): void;
613
+ };
485
614
  }
486
615
  interface GridApi {
487
- setData(rows: Row[]): void;
616
+ /** Replace all rows. The scroll position stays unless `scrollToTop` is set. */
617
+ setData(rows: Row[], options?: {
618
+ scrollToTop?: boolean;
619
+ }): void;
488
620
  getData(): Row[];
489
621
  setColumns(columns: ColumnDef[]): void;
490
622
  getColumnState(): ColumnState[];
@@ -499,6 +631,14 @@ interface GridApi {
499
631
  deselectAll(): void;
500
632
  getDisplayedRowCount(): number;
501
633
  scrollToRow(index: number): void;
634
+ /** Check every editable cell against required, unique and validate. Empty when all rows are valid. */
635
+ validate(): InvalidCell[];
636
+ /** Scroll offsets of the rows area in px. */
637
+ getScrollPosition(): ScrollPosition;
638
+ /** Scroll the rows area; omitted axes stay where they are. */
639
+ setScrollPosition(position: Partial<ScrollPosition>): void;
640
+ /** Keep this grid and `other` scrolled together; returns a function that unlinks them. */
641
+ syncScroll(other: GridApi, axis?: 'both' | 'vertical' | 'horizontal'): () => void;
502
642
  setTheme(theme: string): void;
503
643
  setLocale(locale: string | Partial<LocalePack>): void;
504
644
  setFont(font: {
@@ -516,6 +656,9 @@ interface GridApi {
516
656
  getSummaryValues(): Record<string, unknown>[];
517
657
  getRange(): GridRange | null;
518
658
  setRange(range: GridRange | null): void;
659
+ /** Every selected range (Ctrl+click adds one); the last is the active range. */
660
+ getRanges(): GridRange[];
661
+ setRanges(ranges: GridRange[]): void;
519
662
  /** Copy the range (or checked rows, or the focused cell) as Excel TSV; also writes the clipboard when allowed. */
520
663
  copySelection(options?: {
521
664
  headers?: boolean;
@@ -570,6 +713,8 @@ interface GridApi {
570
713
  isDetailExpanded(row: Row): boolean;
571
714
  /** Move a row to a new index in the source data. False while sorting, filtering or grouping is active. */
572
715
  moveRow(row: Row, toIndex: number): boolean;
716
+ /** Move a row before, after or (tree data) inside another row; null target = to the end. False when refused. */
717
+ dropRow(row: Row, target: Row | null, position?: RowDropPosition): boolean;
573
718
  /** 0-based page; clamped to the available pages. */
574
719
  setPage(page: number): void;
575
720
  getPage(): number;
@@ -601,4 +746,4 @@ interface GridApi {
601
746
  destroy(): void;
602
747
  }
603
748
 
604
- export type { Aggregator as A, SummaryRowDef as B, CellEvent as C, Datasource as D, EditorParams as E, FilterModel as F, GridOptions as G, TextOp as H, KeyAction as K, LocalePack as L, Messages as M, NumberFilterModel as N, PivotConfig as P, Region as R, SelectOption as S, TextFilterModel as T, GridApi as a, CellParams as b, ChartHandle as c, ChartOptions as d, ColumnDef as e, ColumnState as f, ColumnType as g, ContextMenuItem as h, ContextMenuParams as i, CustomEditor as j, DateFilterModel as k, DateOp as l, EditorSpec as m, ExportOptions as n, FilterOp as o, FilterType as p, GridEvents as q, GridRange as r, NumberOp as s, Row as t, ServerParams as u, SetFilterModel as v, SortDir as w, SortItem as x, SummaryCell as y, SummaryOptions as z };
749
+ export type { Aggregator as A, SortDir as B, CellEvent as C, Datasource as D, EditorParams as E, FilterModel as F, GridOptions as G, SortItem as H, InvalidCell as I, SpanParams as J, KeyAction as K, LocalePack as L, Messages as M, NumberFilterModel as N, SummaryCell as O, PivotConfig as P, SummaryOptions as Q, Region as R, ScrollPosition as S, SummaryRowDef as T, TextFilterModel as U, TextOp as V, GridApi as a, CellParams as b, ChartHandle as c, ChartOptions as d, ColumnDef as e, ColumnState as f, ColumnType as g, ContextMenuItem as h, ContextMenuParams as i, CustomEditor as j, DateFilterModel as k, DateOp as l, EditorSpec as m, ExportOptions as n, FilterOp as o, FilterType as p, GridEvents as q, GridRange as r, NumberOp as s, Row as t, RowDragOptions as u, RowDropParams as v, RowDropPosition as w, SelectOption as x, ServerParams as y, SetFilterModel as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@freegridjs/core",
3
- "version": "0.7.1",
3
+ "version": "0.8.1",
4
4
  "description": "FreeGrid — a fast data grid for the web (free for personal use): virtual scrolling, grouping, pivot, charts, Excel export, 7 languages.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",