@iyulab/flex-table 0.40.3 → 0.41.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.
@@ -513,10 +513,19 @@ export declare class FlexTable extends LitElement {
513
513
  private _renderFrozenRows;
514
514
  private _renderFooter;
515
515
  private _renderRow;
516
+ /** Does visual row `index` continue the `mergeRepeated` run of the row above it? */
517
+ private _continuesRun;
518
+ /**
519
+ * Rows where a run starts again whatever the row above holds: the first body row below the
520
+ * frozen band, and the first body row in view — otherwise a run scrolled half out of view
521
+ * shows no value at all.
522
+ */
523
+ private _isForcedRunHead;
524
+ /** How a `mergeRepeated` cell joins its neighbours, or `null` when the column does not merge. */
525
+ private _mergeState;
516
526
  private _renderCell;
517
527
  private _renderEditor;
518
528
  /** Convert value to YYYY-MM-DD for date input (local timezone) */
519
- private _toDateInputValue;
520
529
  /** Convert value to YYYY-MM-DDTHH:mm for datetime-local input (local timezone) */
521
530
  private _toDateTimeInputValue;
522
531
  }
@@ -1,2 +1,2 @@
1
- import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "./flex-table-DvETrA1w.js";
1
+ import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "./flex-table-C6PFutM_.js";
2
2
  export { o as FlexTable, e as RowSelectionState, t as UndoStack, n as effectiveAlign, i as exportData, r as flexTableLocale, a as renderCell };
package/dist/locale.d.ts CHANGED
@@ -25,7 +25,7 @@
25
25
  * (아이콘 자리의 글리프)는 어느 로케일에서도 같은 것을 뜻하며, 번역하면 오히려 읽히지 않는다.
26
26
  * 그 판단은 «번역하지 않기로 한 것»이지 «빠뜨린 것»이 아니다.
27
27
  */
28
- export type FlexTableMessageKey = 'showHiddenColumns' | 'columnMenu' | 'cellActions' | 'noColumnsDefined' | 'addCommentPlaceholder' | 'cancel' | 'save' | 'clear' | 'blankCells' | 'emptyOnly' | 'nonEmptyOnly' | 'blankAll' | 'all' | 'contains' | 'startsWith' | 'endsWith' | 'wildcard' | 'searchPlaceholder' | 'valuePlaceholder' | 'fromPlaceholder' | 'toPlaceholder' | 'findPlaceholder' | 'findPrevious' | 'findNext' | 'matchCase' | 'wholeCell' | 'closeFind' | 'replaceWithPlaceholder' | 'replace' | 'replaceAll' | 'sortAscending' | 'sortDescending' | 'filter' | 'clearFilter' | 'hideColumn' | 'showColumn' | 'autoFitWidth' | 'wider' | 'narrower' | 'columnMenuFor' | 'columnMenuRegion' | 'copy' | 'insertRowAbove' | 'insertRowBelow' | 'deleteRow' | 'filterByThisValue' | 'addComment' | 'editComment' | 'deleteComment' | 'booleanTrue' | 'booleanFalse' | 'dropFileToImport';
28
+ export type FlexTableMessageKey = 'showHiddenColumns' | 'columnMenu' | 'cellActions' | 'noColumnsDefined' | 'addCommentPlaceholder' | 'cancel' | 'save' | 'clear' | 'blankCells' | 'emptyOnly' | 'nonEmptyOnly' | 'blankAll' | 'all' | 'contains' | 'startsWith' | 'endsWith' | 'wildcard' | 'searchPlaceholder' | 'valuePlaceholder' | 'fromPlaceholder' | 'toPlaceholder' | 'findPlaceholder' | 'findPrevious' | 'findNext' | 'matchCase' | 'wholeCell' | 'closeFind' | 'replaceWithPlaceholder' | 'replace' | 'replaceAll' | 'sortAscending' | 'sortDescending' | 'filter' | 'clearFilter' | 'hideColumn' | 'showColumn' | 'autoFitWidth' | 'wider' | 'narrower' | 'columnMenuFor' | 'columnMenuRegion' | 'copy' | 'insertRowAbove' | 'insertRowBelow' | 'deleteRow' | 'filterByThisValue' | 'addComment' | 'editComment' | 'deleteComment' | 'booleanTrue' | 'booleanFalse' | 'dropFileToImport' | 'notANumber' | 'notADate' | 'notInList';
29
29
  /** 이 패키지의 chrome 문자열 묶음. 소비자가 `register()` 로 언어를 더하거나 문구를 덮을 수 있다. */
30
30
  export declare const flexTableLocale: import("@iyulab/components/dist/utilities/Locale.js").LocaleNamespace<FlexTableMessageKey>;
31
31
  /** 짧은 조회 별칭 — 렌더 코드가 읽히게 유지한다. */
@@ -104,6 +104,17 @@ export interface ColumnDefinition<T = DataRow> {
104
104
  format?: string | ((value: unknown, row: T, col: ColumnDefinition<T>) => string);
105
105
  /** Per-column conditional formatting rules applied during cell rendering */
106
106
  conditionalRules?: ConditionalRule<T>[];
107
+ /**
108
+ * Draws a run of repeated values in this column as one merged cell — the value shows once, in
109
+ * the first row of the run, and the lines between the run's rows are dropped. Every row keeps its
110
+ * own value: sorting, filtering, copying, export and screen readers see each row as before.
111
+ * - `true`: a row continues the run when its value equals the previous row's (empty values never merge).
112
+ * - Function: `(row, previousRow, col) => boolean` — e.g. merge customer cells only within one
113
+ * order: `(row, prev) => row.orderId === prev.orderId`.
114
+ * Rows are compared in display order (after sorting and filtering). The value is drawn again at
115
+ * the top of the scrolled view and below frozen rows, so it never scrolls out of sight.
116
+ */
117
+ mergeRepeated?: boolean | ((row: T, previousRow: T, col: ColumnDefinition<T>) => boolean);
107
118
  }
108
119
  /** Style applied to a cell by a conditional formatting rule */
109
120
  export interface CellStyle {
package/dist/react.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as e } from "./flex-table-DvETrA1w.js";
1
+ import { t as e } from "./flex-table-C6PFutM_.js";
2
2
  import { i as t, t as n } from "./query-Dw4iO0ir.js";
3
3
  import { t as r } from "./view-DiLr-TdY.js";
4
4
  import i, { useCallback as a, useEffect as o, useMemo as s, useRef as c, useState as l } from "react";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iyulab/flex-table",
3
- "version": "0.40.3",
3
+ "version": "0.41.1",
4
4
  "description": "A minimalist, input-centric data grid web component",
5
5
  "type": "module",
6
6
  "main": "./dist/flex-table.js",
@@ -72,8 +72,8 @@
72
72
  "odata-query": "^8.1.0"
73
73
  },
74
74
  "peerDependencies": {
75
- "@iyulab/components": ">=1.52.0",
76
- "@lit/react": "^1.0.0",
75
+ "@iyulab/components": ">=1.55.0",
76
+ "@lit/react": "^1.0.8",
77
77
  "react": "^18.0.0 || ^19.0.0"
78
78
  },
79
79
  "peerDependenciesMeta": {
@@ -66,6 +66,8 @@ as `text`). See `references/api.md` for every field.
66
66
  - `render` replaces the cell content (`(value, row, col) => TemplateResult | string`) and wins over `format`.
67
67
  - `editor` returns a Lit template containing an element with class `ft-editor`; its `.value` is committed.
68
68
  - `validator` returns `null` when valid, or an error message (the edit is rejected and `validation-error` fires).
69
+ - `number` cells, the number filter and paste read numbers in the active `Locale` (`1,5` is 1.5 on a comma-decimal page); an edit that is not a number is rejected with `validation-error`.
70
+ - `date` cells edit as a `YYYY-MM-DD` text box in every browser language (also `20261002`, `2026/10/2`, `10-02`); pasted dates are normalized to ISO.
69
71
  - `conditionalRules` applies `{ when, style }` rules in order; later matches override earlier ones.
70
72
  - `pinned: 'left' | 'right'` freezes a column during horizontal scroll.
71
73
 
@@ -65,6 +65,7 @@ Replacing `data` with the same array reference does not trigger the clear-on-cha
65
65
  | `editor` | `CellEditor<T>` | `(value, row, col) => TemplateResult` with an `.ft-editor` element |
66
66
  | `validator` | `CellValidator<T>` | `(value, row, col) => string \| null \| undefined` |
67
67
  | `conditionalRules` | `ConditionalRule<T>[]` | `{ when(value, row, col): boolean, style: CellStyle }` |
68
+ | `mergeRepeated` | `boolean \| (row, previousRow, col) => boolean` | Draw a run of repeated values as one merged cell; values, sort, filter and export are unchanged |
68
69
 
69
70
  `CellStyle` = `{ background?, color?, fontWeight?: 'bold' | 'normal', fontStyle?: 'italic' | 'normal' }`.
70
71