@iyulab/flex-table 0.55.0 → 0.55.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.55.1] - 2026-10-07
4
+
5
+ ### Fixed
6
+
7
+ - **The empty-state texts follow the locale.** `emptyMessage` and `noMatchingMessage` defaulted to the English
8
+ strings themselves, so a table with no rows said "No data" in every language. They now default to empty and the
9
+ table draws the locale strings `noData` / `noMatchingData` (Korean built in); a value you set still wins.
10
+
3
11
  ## [0.55.0] - 2026-10-07
4
12
 
5
13
  ### Added
package/README.md CHANGED
@@ -111,8 +111,8 @@ guarantee about a *constrained* host. `height-model.browser.test.ts` pins both s
111
111
  | `selectionMode` | `selection-mode` | `'single' \| 'multi'` | `'multi'` | Row selection mode |
112
112
  | `dataMode` | `data-mode` | `'client' \| 'server'` | `'client'` | Client-side or server-side data processing |
113
113
  | `footerData` | `footer-data` | `Record<string, string \| TemplateResult> \| null` | `null` | Footer/summary row data (keys match column keys) |
114
- | `emptyMessage` | `empty-message` | `string` | `'No data'` | Shown when `data` is empty |
115
- | `noMatchingMessage` | `no-matching-message` | `string` | `'No matching data'` | Shown when `data` has rows but every one is hidden by an active column filter |
114
+ | `emptyMessage` | `empty-message` | `string` | `''` | Shown when `data` is empty. Empty uses the locale string `noData` ('No data') |
115
+ | `noMatchingMessage` | `no-matching-message` | `string` | `''` | Shown when `data` has rows but every one is hidden by an active column filter. Empty uses the locale string `noMatchingData` |
116
116
  | `error` | — | `{ message: string } \| null` | `null` | The last load failure. While set, `error.message` is shown as an alert where the rows or the empty state would be, so a failed query does not look like "no data". Pass a data source's `error` as is |
117
117
  | `stylesheets` | — | `CSSStyleSheet[]` | `[]` | Constructable stylesheets adopted into the shadow root alongside the grid's own styles — the escape hatch for styling content a `render` function inserts, since document CSS doesn't cross the shadow boundary. Reassigning swaps the previous set, it doesn't accumulate |
118
118
 
@@ -1,4 +1,4 @@
1
- import { n as e } from "./locale-B1SiVDS1.js";
1
+ import { n as e } from "./locale-Cfm-vJji.js";
2
2
  import { n as t, t as n } from "./sorting-CjfjRxwL.js";
3
3
  import { LitElement as r, css as i, html as a, nothing as o } from "lit";
4
4
  import { customElement as s, property as c, state as l } from "lit/decorators.js";
@@ -1756,7 +1756,7 @@ var K = {
1756
1756
  lte: "≤"
1757
1757
  }, q = 120, J = 40, Y = 20, X = 32, Z = 5, Xe = 200, Q = class extends r {
1758
1758
  constructor(...e) {
1759
- super(...e), this.columns = [], this._data = [], this._inUndoRedo = !1, this.clearUndoOnDataChange = !1, this.clearSelectionOnDataChange = !1, this._rowHeightFromCss = X, this._targetFloor = 0, this.showRowNumbers = !1, this.theme = void 0, this.maxRows = 0, this.editable = !0, this.showFilters = !1, this.showContextMenu = !1, this.frozenRows = 0, this.emptyMessage = "No data", this.noMatchingMessage = "No matching data", this.error = null, this.loading = !1, this.importEnabled = !1, this.selectable = !1, this.dataMode = "client", this.footerData = null, this.stylesheets = [], this._scrollTop = 0, this._scrollLeft = 0, this._viewportHeight = 0, this._viewportWidth = 0, this._colLeftOffsets = [], this._totalRowWidth = 0, this._baseStyleSheets = [], this._activeCell = null, this._headerCol = null, this._focusedCellEl = null, this._editingCell = null, this._sortCriteria = [], this._selection = new oe(), this._editing = new se(), this._rowSelection = new k(), this._undo = new A(), this._filters = [], this._filteredIndices = [], this._sortedIndices = [], this._openFilterKey = null, this._rowSelectionVersion = 0, this._lastCheckboxRowIndex = null, this._checkboxShiftPending = !1, this._autocompleteState = null, this._headerMenu = null, this._bodyContextMenu = null, this._commentPopup = null, this._viewDirty = !0, this._isDragging = !1, this._wasDrag = !1, this._resizing = null, this._resizeCleanup = null, this._wasHeaderDrag = !1, this._wasRowDrag = !1, this._colDrag = null, this._colDragIndicatorLeft = null, this._fillDrag = null, this._rowDrag = null, this._rowDragIndicatorY = null, this._findState = null, this._columnWidths = /* @__PURE__ */ new Map(), this._hostResizeObserver = null, this._comments = /* @__PURE__ */ new Map(), this._isDragOver = !1, this._warnedUnconstrained = !1, this._onHostFocus = (e) => {
1759
+ super(...e), this.columns = [], this._data = [], this._inUndoRedo = !1, this.clearUndoOnDataChange = !1, this.clearSelectionOnDataChange = !1, this._rowHeightFromCss = X, this._targetFloor = 0, this.showRowNumbers = !1, this.theme = void 0, this.maxRows = 0, this.editable = !0, this.showFilters = !1, this.showContextMenu = !1, this.frozenRows = 0, this.emptyMessage = "", this.noMatchingMessage = "", this.error = null, this.loading = !1, this.importEnabled = !1, this.selectable = !1, this.dataMode = "client", this.footerData = null, this.stylesheets = [], this._scrollTop = 0, this._scrollLeft = 0, this._viewportHeight = 0, this._viewportWidth = 0, this._colLeftOffsets = [], this._totalRowWidth = 0, this._baseStyleSheets = [], this._activeCell = null, this._headerCol = null, this._focusedCellEl = null, this._editingCell = null, this._sortCriteria = [], this._selection = new oe(), this._editing = new se(), this._rowSelection = new k(), this._undo = new A(), this._filters = [], this._filteredIndices = [], this._sortedIndices = [], this._openFilterKey = null, this._rowSelectionVersion = 0, this._lastCheckboxRowIndex = null, this._checkboxShiftPending = !1, this._autocompleteState = null, this._headerMenu = null, this._bodyContextMenu = null, this._commentPopup = null, this._viewDirty = !0, this._isDragging = !1, this._wasDrag = !1, this._resizing = null, this._resizeCleanup = null, this._wasHeaderDrag = !1, this._wasRowDrag = !1, this._colDrag = null, this._colDragIndicatorLeft = null, this._fillDrag = null, this._rowDrag = null, this._rowDragIndicatorY = null, this._findState = null, this._columnWidths = /* @__PURE__ */ new Map(), this._hostResizeObserver = null, this._comments = /* @__PURE__ */ new Map(), this._isDragOver = !1, this._warnedUnconstrained = !1, this._onHostFocus = (e) => {
1760
1760
  e.composedPath()[0] !== this || this._activeCell || this._headerCol !== null || this.visibleColumns.length !== 0 && this.matches(":focus-visible") && (this._visibleRowCount > 0 ? (this._selection.setActive(0, 0), this._syncActiveCell()) : this._headerCol = 0);
1761
1761
  }, this._onFocusIn = (e) => {
1762
1762
  let t = e.composedPath()[0];
@@ -4158,7 +4158,7 @@ var K = {
4158
4158
  for (let e = c; e < l; e++) h.push(this._renderHeaderCell(t[e], e));
4159
4159
  let g = this._colDragIndicatorLeft == null ? "" : a`<div class="ft-drop-indicator" style="left:${this._colDragIndicatorLeft}px"></div>`;
4160
4160
  if (this.error || this.data.length === 0 || this._visibleRowCount === 0) {
4161
- let e = this.error ? a`<div class="ft-empty ft-error" role="alert">${this.error.message}</div>` : a`<div class="ft-empty">${this.data.length === 0 ? this.emptyMessage : this.noMatchingMessage}</div>`;
4161
+ let t = this.error ? a`<div class="ft-empty ft-error" role="alert">${this.error.message}</div>` : a`<div class="ft-empty">${this.data.length === 0 ? this.emptyMessage || e("noData") : this.noMatchingMessage || e("noMatchingData")}</div>`;
4162
4162
  return a`
4163
4163
  ${r}
4164
4164
  <div class="ft-header" role="row" aria-rowindex="1" style="width: ${s}px; height: ${i}px;">
@@ -4166,7 +4166,7 @@ var K = {
4166
4166
  ${h}
4167
4167
  ${g}
4168
4168
  </div>
4169
- ${e}
4169
+ ${t}
4170
4170
  `;
4171
4171
  }
4172
4172
  let { start: _, end: v } = this.visibleRange, y = this._frozenRowCount, b = [];
@@ -65,11 +65,12 @@ export declare class FlexTable extends LitElement {
65
65
  showContextMenu: boolean;
66
66
  /** Number of rows to freeze at the top (always visible during vertical scroll). */
67
67
  frozenRows: number;
68
- /** Message shown when `data` is empty (no rows at all). Default: 'No data'. */
68
+ /** Message shown when `data` is empty (no rows at all). Empty (the default) uses the locale string (`noData` — 'No data'). */
69
69
  emptyMessage: string;
70
70
  /**
71
71
  * Message shown when `data` has rows but every one is hidden by the active
72
- * column filters (0 visible rows, non-empty `data`). Default: 'No matching data'.
72
+ * column filters (0 visible rows, non-empty `data`). Empty (the default) uses the locale string (`noMatchingData` —
73
+ * 'No matching data').
73
74
  */
74
75
  noMatchingMessage: string;
75
76
  /**
@@ -1,3 +1,3 @@
1
- import { a as e, i as t, n, o as r, r as i, t as a } from "./flex-table-DlvIBu4z.js";
2
- import { t as o } from "./locale-B1SiVDS1.js";
1
+ import { a as e, i as t, n, o as r, r as i, t as a } from "./flex-table-D3E9npd9.js";
2
+ import { t as o } from "./locale-Cfm-vJji.js";
3
3
  export { a as FlexTable, e as RowSelectionState, t as UndoStack, n as effectiveAlign, i as exportData, o as flexTableLocale, r as renderCell };
@@ -9,6 +9,8 @@ t.register("en", {
9
9
  addCommentPlaceholder: "Add a comment… (Ctrl+Enter to save)",
10
10
  cancel: "Cancel",
11
11
  save: "Save",
12
+ noData: "No data",
13
+ noMatchingData: "No matching data",
12
14
  clear: "Clear",
13
15
  blankCells: "Blank cells",
14
16
  emptyOnly: "Empty only",
@@ -79,6 +81,8 @@ t.register("en", {
79
81
  addCommentPlaceholder: "메모 입력… (Ctrl+Enter 로 저장)",
80
82
  cancel: "취소",
81
83
  save: "저장",
84
+ noData: "데이터 없음",
85
+ noMatchingData: "일치하는 데이터 없음",
82
86
  clear: "지우기",
83
87
  blankCells: "빈 셀",
84
88
  emptyOnly: "빈 값만",
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' | 'findNoResults' | 'replaceWithPlaceholder' | 'replace' | 'replaceAll' | 'findInput' | 'replaceInput' | 'filterFor' | 'filterMatchMode' | 'filterText' | 'conditionOperator' | 'conditionValue' | 'conditionJoin' | 'sortAscending' | 'sortDescending' | 'filter' | 'clearFilter' | 'hideColumn' | 'showColumn' | 'autoFitWidth' | 'wider' | 'narrower' | 'columnMenuFor' | 'columnMenuRegion' | 'copy' | 'insertRowAbove' | 'insertRowBelow' | 'deleteRow' | 'selectRow' | 'selectAllRows' | 'filterByThisValue' | 'addComment' | 'editComment' | 'deleteComment' | 'booleanTrue' | 'booleanFalse' | 'dropFileToImport' | 'notANumber' | 'notADate' | 'notADateTime' | 'notInList' | 'requestFailed' | 'networkFailed';
28
+ export type FlexTableMessageKey = 'showHiddenColumns' | 'columnMenu' | 'cellActions' | 'noColumnsDefined' | 'addCommentPlaceholder' | 'cancel' | 'save' | 'noData' | 'noMatchingData' | 'clear' | 'blankCells' | 'emptyOnly' | 'nonEmptyOnly' | 'blankAll' | 'all' | 'contains' | 'startsWith' | 'endsWith' | 'wildcard' | 'searchPlaceholder' | 'valuePlaceholder' | 'fromPlaceholder' | 'toPlaceholder' | 'findPlaceholder' | 'findPrevious' | 'findNext' | 'matchCase' | 'wholeCell' | 'closeFind' | 'findNoResults' | 'replaceWithPlaceholder' | 'replace' | 'replaceAll' | 'findInput' | 'replaceInput' | 'filterFor' | 'filterMatchMode' | 'filterText' | 'conditionOperator' | 'conditionValue' | 'conditionJoin' | 'sortAscending' | 'sortDescending' | 'filter' | 'clearFilter' | 'hideColumn' | 'showColumn' | 'autoFitWidth' | 'wider' | 'narrower' | 'columnMenuFor' | 'columnMenuRegion' | 'copy' | 'insertRowAbove' | 'insertRowBelow' | 'deleteRow' | 'selectRow' | 'selectAllRows' | 'filterByThisValue' | 'addComment' | 'editComment' | 'deleteComment' | 'booleanTrue' | 'booleanFalse' | 'dropFileToImport' | 'notANumber' | 'notADate' | 'notADateTime' | 'notInList' | 'requestFailed' | 'networkFailed';
29
29
  /** 이 패키지의 chrome 문자열 묶음. 소비자가 `register()` 로 언어를 더하거나 문구를 덮을 수 있다. */
30
30
  export declare const flexTableLocale: import("@iyulab/components/dist/utilities/Locale.js").LocaleNamespace<FlexTableMessageKey>;
31
31
  /** 짧은 조회 별칭 — 렌더 코드가 읽히게 유지한다. */
@@ -1,5 +1,5 @@
1
1
  import { n as e, r as t, t as n } from "../query-Dw4iO0ir.js";
2
- import { t as r } from "../source-r2Pv6Pvo.js";
2
+ import { t as r } from "../source--q5s2Oti.js";
3
3
  //#region src/odata/controller.ts
4
4
  var i = class {
5
5
  constructor(e, t, n = {}) {
package/dist/react.js CHANGED
@@ -1,6 +1,6 @@
1
- import { t as e } from "./flex-table-DlvIBu4z.js";
1
+ import { t as e } from "./flex-table-D3E9npd9.js";
2
2
  import { i as t } from "./query-Dw4iO0ir.js";
3
- import { t as n } from "./source-r2Pv6Pvo.js";
3
+ import { t as n } from "./source--q5s2Oti.js";
4
4
  import { t as r } from "./view-DiLr-TdY.js";
5
5
  import i, { useCallback as a, useEffect as o, useMemo as s, useState as c, useSyncExternalStore as l } from "react";
6
6
  import { createComponent as u } from "@lit/react";
@@ -1,4 +1,4 @@
1
- import { n as e } from "./locale-B1SiVDS1.js";
1
+ import { n as e } from "./locale-Cfm-vJji.js";
2
2
  import { i as t, t as n } from "./query-Dw4iO0ir.js";
3
3
  //#region src/core/source-error.ts
4
4
  async function r(t) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iyulab/flex-table",
3
- "version": "0.55.0",
3
+ "version": "0.55.1",
4
4
  "description": "A minimalist, input-centric data grid web component",
5
5
  "type": "module",
6
6
  "main": "./dist/flex-table.js",
@@ -21,8 +21,8 @@ All names below are members of the `FlexTable` class (`<flex-table>`).
21
21
  | `selectionMode` | `selection-mode` | `'single' \| 'multi'` | `'multi'` | |
22
22
  | `dataMode` | `data-mode` | `'client' \| 'server'` | `'client'` | Server mode only emits sort/filter events |
23
23
  | `footerData` | `footer-data` | `Record<string, string \| TemplateResult> \| null` | `null` | Summary row keyed by column key |
24
- | `emptyMessage` | `empty-message` | `string` | `'No data'` | |
25
- | `noMatchingMessage` | `no-matching-message` | `string` | `'No matching data'` | All rows hidden by filters |
24
+ | `emptyMessage` | `empty-message` | `string` | `''` | Empty: locale `noData` |
25
+ | `noMatchingMessage` | `no-matching-message` | `string` | `''` | All rows hidden by filters. Empty: locale `noMatchingData` |
26
26
  | `error` | — | `{ message: string } \| null` | `null` | Load failure shown as an alert instead of rows / empty state (a source's `error` as is) |
27
27
  | `loading` | `loading` | `boolean` | `false` | Loading overlay + `aria-busy` |
28
28
  | `importEnabled` | `import-enabled` | `boolean` | `false` | Drag-and-drop `.xlsx` / `.csv` import |