bank20baht-ui 0.1.5 → 0.1.6

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.
@@ -20,6 +20,13 @@ export type CellRenderer = (value: unknown, row: Record<string, unknown>) => unk
20
20
  *
21
21
  * t.cursorMode = true; t.hasNext = true; t.hasPrev = false;
22
22
  * t.addEventListener('baht-cursor-change', (e) => fetchPage(e.detail.direction));
23
+ *
24
+ * `visibleColumns` picks + orders a subset of `columns` client-side (no
25
+ * refetch) — pair it with <baht-multiselect> as the chooser UI:
26
+ *
27
+ * picker.field = { key: 'cols', options: Object.entries(t.columns).map(([key, label]) => ({ key, label })) };
28
+ * picker.value = t.visibleColumns; // omit/empty = show all columns
29
+ * picker.addEventListener('baht-input', (e) => t.visibleColumns = e.detail.value);
23
30
  */
24
31
  export declare class BahtTable extends BahtElement {
25
32
  /** Rows of the CURRENT page. */
@@ -40,6 +47,8 @@ export declare class BahtTable extends BahtElement {
40
47
  clickable: boolean;
41
48
  /** Custom cell renderers by column key (functions — a property, never JSON). */
42
49
  renderers: Record<string, CellRenderer>;
50
+ /** Subset + order of `columns` to render; empty/omitted = show all. */
51
+ visibleColumns: string[];
43
52
  page: number;
44
53
  totalPages: number;
45
54
  /** Switch the footer to Prev/Next (cursor-based API, no total count). */
@@ -8348,7 +8348,7 @@
8348
8348
  "declarations": [
8349
8349
  {
8350
8350
  "kind": "class",
8351
- "description": "Server-side data table. `items` is ONE page of rows — the component never\nslices or fetches; on `baht-page-change` the host fetches the next page and\nre-feeds `items`/`page`. While that fetch runs, set `loading` to show\nskeleton rows.\n\n const t = document.querySelector('baht-table');\n t.columns = { name: 'Name', created_at: 'Created' };\n t.items = pageRows; // current page only\n t.loading = false; t.page = 1; t.totalPages = 12;\n t.addEventListener('baht-page-change', (e) => fetchPage(e.detail.page));\n t.addEventListener('baht-row-click', (e) => open(e.detail.id));\n\nSet `cursor-mode` for cursor-based APIs (no total count) — the footer\nbecomes a Prev/Next pair gated by `has-next`/`has-prev`, and the host\nlistens for `baht-cursor-change` instead of `baht-page-change`:\n\n t.cursorMode = true; t.hasNext = true; t.hasPrev = false;\n t.addEventListener('baht-cursor-change', (e) => fetchPage(e.detail.direction));",
8351
+ "description": "Server-side data table. `items` is ONE page of rows — the component never\nslices or fetches; on `baht-page-change` the host fetches the next page and\nre-feeds `items`/`page`. While that fetch runs, set `loading` to show\nskeleton rows.\n\n const t = document.querySelector('baht-table');\n t.columns = { name: 'Name', created_at: 'Created' };\n t.items = pageRows; // current page only\n t.loading = false; t.page = 1; t.totalPages = 12;\n t.addEventListener('baht-page-change', (e) => fetchPage(e.detail.page));\n t.addEventListener('baht-row-click', (e) => open(e.detail.id));\n\nSet `cursor-mode` for cursor-based APIs (no total count) — the footer\nbecomes a Prev/Next pair gated by `has-next`/`has-prev`, and the host\nlistens for `baht-cursor-change` instead of `baht-page-change`:\n\n t.cursorMode = true; t.hasNext = true; t.hasPrev = false;\n t.addEventListener('baht-cursor-change', (e) => fetchPage(e.detail.direction));\n\n`visibleColumns` picks + orders a subset of `columns` client-side (no\nrefetch) — pair it with <baht-multiselect> as the chooser UI:\n\n picker.field = { key: 'cols', options: Object.entries(t.columns).map(([key, label]) => ({ key, label })) };\n picker.value = t.visibleColumns; // omit/empty = show all columns\n picker.addEventListener('baht-input', (e) => t.visibleColumns = e.detail.value);",
8352
8352
  "name": "BahtTable",
8353
8353
  "members": [
8354
8354
  {
@@ -8462,6 +8462,15 @@
8462
8462
  "default": "{}",
8463
8463
  "description": "Custom cell renderers by column key (functions — a property, never JSON)."
8464
8464
  },
8465
+ {
8466
+ "kind": "field",
8467
+ "name": "visibleColumns",
8468
+ "type": {
8469
+ "text": "string[]"
8470
+ },
8471
+ "default": "[]",
8472
+ "description": "Subset + order of `columns` to render; empty/omitted = show all."
8473
+ },
8465
8474
  {
8466
8475
  "kind": "field",
8467
8476
  "name": "page",
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { t as v, defaultValue as _t, applyFlags as ee, resolveViewFields as Ut, validateField as zt, evaluate as pe, resolveNext as ce } from "./engine.js";
1
+ import { t as f, defaultValue as _t, applyFlags as ee, resolveViewFields as Ut, validateField as Kt, evaluate as pe, resolveNext as ce } from "./engine.js";
2
2
  import { approvalFields as dr, evalCondition as ur, evalValueExpr as br, flagEnabled as vr, getCatalog as fr, readRef as mr, setCatalog as yr, setLocale as $r, walkPath as gr } from "./engine.js";
3
3
  import { LitElement as de, nothing as h, html as n, svg as E } from "lit";
4
- import { property as l, query as tt, customElement as p, state as b } from "lit/decorators.js";
4
+ import { property as l, query as tt, customElement as p, state as v } from "lit/decorators.js";
5
5
  import { live as B } from "lit/directives/live.js";
6
6
  import { ifDefined as O } from "lit/directives/if-defined.js";
7
7
  var ue = Object.defineProperty, et = (t, e, r, a) => {
@@ -226,7 +226,7 @@ Rt([
226
226
  xt = Rt([
227
227
  p("baht-code")
228
228
  ], xt);
229
- var _e = Object.defineProperty, xe = Object.getOwnPropertyDescriptor, z = (t, e, r, a) => {
229
+ var _e = Object.defineProperty, xe = Object.getOwnPropertyDescriptor, K = (t, e, r, a) => {
230
230
  for (var s = a > 1 ? void 0 : a ? xe(e, r) : e, i = t.length - 1, o; i >= 0; i--)
231
231
  (o = t[i]) && (s = (a ? o(e, r, s) : o(s)) || s);
232
232
  return a && s && _e(e, r, s), s;
@@ -285,39 +285,39 @@ let I = class extends c {
285
285
  </nav>`;
286
286
  }
287
287
  };
288
- z([
288
+ K([
289
289
  l({ type: Number })
290
290
  ], I.prototype, "page", 2);
291
- z([
291
+ K([
292
292
  l({ type: Number, attribute: "total-pages" })
293
293
  ], I.prototype, "totalPages", 2);
294
- z([
294
+ K([
295
295
  l()
296
296
  ], I.prototype, "variant", 2);
297
- z([
297
+ K([
298
298
  l({ type: Number })
299
299
  ], I.prototype, "siblings", 2);
300
- z([
300
+ K([
301
301
  l({ type: Boolean, attribute: "has-next" })
302
302
  ], I.prototype, "hasNext", 2);
303
- z([
303
+ K([
304
304
  l({ type: Boolean, attribute: "has-prev" })
305
305
  ], I.prototype, "hasPrev", 2);
306
- I = z([
306
+ I = K([
307
307
  p("baht-pagination")
308
308
  ], I);
309
- var Oe = Object.defineProperty, Pe = Object.getOwnPropertyDescriptor, y = (t, e, r, a) => {
309
+ var Oe = Object.defineProperty, Pe = Object.getOwnPropertyDescriptor, m = (t, e, r, a) => {
310
310
  for (var s = a > 1 ? void 0 : a ? Pe(e, r) : e, i = t.length - 1, o; i >= 0; i--)
311
311
  (o = t[i]) && (s = (a ? o(e, r, s) : o(s)) || s);
312
312
  return a && s && Oe(e, r, s), s;
313
313
  };
314
- let f = class extends c {
314
+ let b = class extends c {
315
315
  constructor() {
316
- super(...arguments), this.items = [], this.columns = {}, this.loading = !1, this.error = !1, this.errorMessage = "Couldn't load data. Try again.", this.emptyMessage = "No records yet.", this.showIndex = !0, this.indexOffset = 0, this.skeletonRows = 10, this.rowKey = "", this.clickable = !0, this.renderers = {}, this.page = 1, this.totalPages = 1, this.cursorMode = !1, this.hasNext = !1, this.hasPrev = !1;
316
+ super(...arguments), this.items = [], this.columns = {}, this.loading = !1, this.error = !1, this.errorMessage = "Couldn't load data. Try again.", this.emptyMessage = "No records yet.", this.showIndex = !0, this.indexOffset = 0, this.skeletonRows = 10, this.rowKey = "", this.clickable = !0, this.renderers = {}, this.visibleColumns = [], this.page = 1, this.totalPages = 1, this.cursorMode = !1, this.hasNext = !1, this.hasPrev = !1;
317
317
  }
318
318
  get columnKeys() {
319
- const t = Object.keys(this.columns);
320
- return t.length > 0 ? t : this.items.length > 0 ? Object.keys(this.items[0]) : [];
319
+ const t = Object.keys(this.columns), e = t.length > 0 ? t : this.items.length > 0 ? Object.keys(this.items[0]) : [];
320
+ return this.visibleColumns.length === 0 ? e : this.visibleColumns.filter((r) => e.includes(r));
321
321
  }
322
322
  labelFor(t) {
323
323
  return this.columns[t] ?? t.replace(/_/g, " ").replace(/\b\w/g, (e) => e.toUpperCase());
@@ -388,60 +388,63 @@ let f = class extends c {
388
388
  </div>`;
389
389
  }
390
390
  };
391
- y([
391
+ m([
392
392
  l({ attribute: !1 })
393
- ], f.prototype, "items", 2);
394
- y([
393
+ ], b.prototype, "items", 2);
394
+ m([
395
395
  l({ attribute: !1 })
396
- ], f.prototype, "columns", 2);
397
- y([
396
+ ], b.prototype, "columns", 2);
397
+ m([
398
398
  l({ type: Boolean })
399
- ], f.prototype, "loading", 2);
400
- y([
399
+ ], b.prototype, "loading", 2);
400
+ m([
401
401
  l({ type: Boolean })
402
- ], f.prototype, "error", 2);
403
- y([
402
+ ], b.prototype, "error", 2);
403
+ m([
404
404
  l({ attribute: "error-message" })
405
- ], f.prototype, "errorMessage", 2);
406
- y([
405
+ ], b.prototype, "errorMessage", 2);
406
+ m([
407
407
  l({ attribute: "empty-message" })
408
- ], f.prototype, "emptyMessage", 2);
409
- y([
408
+ ], b.prototype, "emptyMessage", 2);
409
+ m([
410
410
  l({ type: Boolean, attribute: "show-index" })
411
- ], f.prototype, "showIndex", 2);
412
- y([
411
+ ], b.prototype, "showIndex", 2);
412
+ m([
413
413
  l({ type: Number, attribute: "index-offset" })
414
- ], f.prototype, "indexOffset", 2);
415
- y([
414
+ ], b.prototype, "indexOffset", 2);
415
+ m([
416
416
  l({ type: Number, attribute: "skeleton-rows" })
417
- ], f.prototype, "skeletonRows", 2);
418
- y([
417
+ ], b.prototype, "skeletonRows", 2);
418
+ m([
419
419
  l({ attribute: "row-key" })
420
- ], f.prototype, "rowKey", 2);
421
- y([
420
+ ], b.prototype, "rowKey", 2);
421
+ m([
422
422
  l({ type: Boolean })
423
- ], f.prototype, "clickable", 2);
424
- y([
423
+ ], b.prototype, "clickable", 2);
424
+ m([
425
+ l({ attribute: !1 })
426
+ ], b.prototype, "renderers", 2);
427
+ m([
425
428
  l({ attribute: !1 })
426
- ], f.prototype, "renderers", 2);
427
- y([
429
+ ], b.prototype, "visibleColumns", 2);
430
+ m([
428
431
  l({ type: Number })
429
- ], f.prototype, "page", 2);
430
- y([
432
+ ], b.prototype, "page", 2);
433
+ m([
431
434
  l({ type: Number, attribute: "total-pages" })
432
- ], f.prototype, "totalPages", 2);
433
- y([
435
+ ], b.prototype, "totalPages", 2);
436
+ m([
434
437
  l({ type: Boolean, attribute: "cursor-mode" })
435
- ], f.prototype, "cursorMode", 2);
436
- y([
438
+ ], b.prototype, "cursorMode", 2);
439
+ m([
437
440
  l({ type: Boolean, attribute: "has-next" })
438
- ], f.prototype, "hasNext", 2);
439
- y([
441
+ ], b.prototype, "hasNext", 2);
442
+ m([
440
443
  l({ type: Boolean, attribute: "has-prev" })
441
- ], f.prototype, "hasPrev", 2);
442
- f = y([
444
+ ], b.prototype, "hasPrev", 2);
445
+ b = m([
443
446
  p("baht-table")
444
- ], f);
447
+ ], b);
445
448
  var Ce = Object.defineProperty, De = Object.getOwnPropertyDescriptor, R = (t, e, r, a) => {
446
449
  for (var s = a > 1 ? void 0 : a ? De(e, r) : e, i = t.length - 1, o; i >= 0; i--)
447
450
  (o = t[i]) && (s = (a ? o(e, r, s) : o(s)) || s);
@@ -660,7 +663,7 @@ Lt([
660
663
  l({ type: Number })
661
664
  ], W.prototype, "duration", 2);
662
665
  Lt([
663
- b()
666
+ v()
664
667
  ], W.prototype, "entries", 2);
665
668
  W = Lt([
666
669
  p("baht-toast")
@@ -720,7 +723,7 @@ ft([
720
723
  tt(".baht-tooltip-anchor")
721
724
  ], S.prototype, "anchorEl", 2);
722
725
  ft([
723
- b()
726
+ v()
724
727
  ], S.prototype, "dismissed", 2);
725
728
  S = ft([
726
729
  p("baht-tooltip")
@@ -763,7 +766,7 @@ at([
763
766
  l({ type: Boolean })
764
767
  ], A.prototype, "dismissible", 2);
765
768
  at([
766
- b()
769
+ v()
767
770
  ], A.prototype, "dismissed", 2);
768
771
  A = at([
769
772
  p("baht-alert")
@@ -839,7 +842,7 @@ it([
839
842
  l()
840
843
  ], T.prototype, "label", 2);
841
844
  it([
842
- b()
845
+ v()
843
846
  ], T.prototype, "hover", 2);
844
847
  T = it([
845
848
  p("baht-rating")
@@ -1061,10 +1064,10 @@ lt([
1061
1064
  U = lt([
1062
1065
  p("baht-filter")
1063
1066
  ], U);
1064
- var ze = Object.defineProperty, Ke = Object.getOwnPropertyDescriptor, Dt = (t, e, r, a) => {
1065
- for (var s = a > 1 ? void 0 : a ? Ke(e, r) : e, i = t.length - 1, o; i >= 0; i--)
1067
+ var Ke = Object.defineProperty, ze = Object.getOwnPropertyDescriptor, Dt = (t, e, r, a) => {
1068
+ for (var s = a > 1 ? void 0 : a ? ze(e, r) : e, i = t.length - 1, o; i >= 0; i--)
1066
1069
  (o = t[i]) && (s = (a ? o(e, r, s) : o(s)) || s);
1067
- return a && s && ze(e, r, s), s;
1070
+ return a && s && Ke(e, r, s), s;
1068
1071
  };
1069
1072
  let pt = class extends c {
1070
1073
  constructor() {
@@ -1310,7 +1313,7 @@ kt([
1310
1313
  l({ type: Boolean })
1311
1314
  ], q.prototype, "multiple", 2);
1312
1315
  kt([
1313
- b()
1316
+ v()
1314
1317
  ], q.prototype, "openSet", 2);
1315
1318
  q = kt([
1316
1319
  p("baht-accordion")
@@ -1392,7 +1395,7 @@ var ns = Object.getOwnPropertyDescriptor, hs = (t, e, r, a) => {
1392
1395
  (o = t[i]) && (s = o(s) || s);
1393
1396
  return s;
1394
1397
  };
1395
- let Kt = class extends g {
1398
+ let zt = class extends g {
1396
1399
  renderControl() {
1397
1400
  return n`<input
1398
1401
  class="baht-control baht-control--text"
@@ -1411,9 +1414,9 @@ let Kt = class extends g {
1411
1414
  />`;
1412
1415
  }
1413
1416
  };
1414
- Kt = hs([
1417
+ zt = hs([
1415
1418
  p("baht-input")
1416
- ], Kt);
1419
+ ], zt);
1417
1420
  var ps = Object.getOwnPropertyDescriptor, cs = (t, e, r, a) => {
1418
1421
  for (var s = a > 1 ? void 0 : a ? ps(e, r) : e, i = t.length - 1, o; i >= 0; i--)
1419
1422
  (o = t[i]) && (s = o(s) || s);
@@ -1697,7 +1700,7 @@ let X = class extends g {
1697
1700
  try {
1698
1701
  e.push(await this.uploader(r));
1699
1702
  } catch {
1700
- this.uploadError = v("uploadFailed");
1703
+ this.uploadError = f("uploadFailed");
1701
1704
  } finally {
1702
1705
  this.uploadingCount -= 1;
1703
1706
  }
@@ -1724,10 +1727,10 @@ let X = class extends g {
1724
1727
  aria-describedby=${this.describedBy}
1725
1728
  @change=${(t) => this.onPick(t)}
1726
1729
  />
1727
- ${this.uploadingCount > 0 ? n`<p class="baht-file-status" role="status">${v("uploading")}</p>` : h}
1730
+ ${this.uploadingCount > 0 ? n`<p class="baht-file-status" role="status">${f("uploading")}</p>` : h}
1728
1731
  ${this.uploadError ? n`<p class="baht-error" role="alert">${this.uploadError}</p>` : h}
1729
1732
  ${this.rejectedNames.length > 0 ? n`<p class="baht-error baht-file-rejected" role="alert">
1730
- ${v("fileRejectedTooLarge", { names: this.rejectedNames.join(", ") })}
1733
+ ${f("fileRejectedTooLarge", { names: this.rejectedNames.join(", ") })}
1731
1734
  </p>` : h}
1732
1735
  ${this.refs.map(
1733
1736
  (t) => n`<span class="baht-file-chip">
@@ -1736,8 +1739,8 @@ let X = class extends g {
1736
1739
  ${this.disabled || this.readonly ? h : n`<button
1737
1740
  type="button"
1738
1741
  class="baht-file-remove"
1739
- aria-label=${v("removeFile")}
1740
- title=${v("removeFile")}
1742
+ aria-label=${f("removeFile")}
1743
+ title=${f("removeFile")}
1741
1744
  @click=${() => this.emitRefs(this.refs.filter((e) => e !== t))}
1742
1745
  >
1743
1746
  ✕
@@ -1750,13 +1753,13 @@ gt([
1750
1753
  l({ attribute: !1 })
1751
1754
  ], X.prototype, "uploader", 2);
1752
1755
  gt([
1753
- b()
1756
+ v()
1754
1757
  ], X.prototype, "uploadingCount", 2);
1755
1758
  gt([
1756
- b()
1759
+ v()
1757
1760
  ], X.prototype, "uploadError", 2);
1758
1761
  gt([
1759
- b()
1762
+ v()
1760
1763
  ], X.prototype, "rejectedNames", 2);
1761
1764
  X = gt([
1762
1765
  p("baht-file")
@@ -2004,10 +2007,10 @@ wt([
2004
2007
  Z = wt([
2005
2008
  p("baht-error-state")
2006
2009
  ], Z);
2007
- var zs = Object.defineProperty, Ks = Object.getOwnPropertyDescriptor, K = (t, e, r, a) => {
2008
- for (var s = a > 1 ? void 0 : a ? Ks(e, r) : e, i = t.length - 1, o; i >= 0; i--)
2010
+ var Ks = Object.defineProperty, zs = Object.getOwnPropertyDescriptor, z = (t, e, r, a) => {
2011
+ for (var s = a > 1 ? void 0 : a ? zs(e, r) : e, i = t.length - 1, o; i >= 0; i--)
2009
2012
  (o = t[i]) && (s = (a ? o(e, r, s) : o(s)) || s);
2010
- return a && s && zs(e, r, s), s;
2013
+ return a && s && Ks(e, r, s), s;
2011
2014
  };
2012
2015
  let M = class extends c {
2013
2016
  constructor() {
@@ -2076,25 +2079,25 @@ let M = class extends c {
2076
2079
  </div>`;
2077
2080
  }
2078
2081
  };
2079
- K([
2082
+ z([
2080
2083
  l({ attribute: !1 })
2081
2084
  ], M.prototype, "value", 2);
2082
- K([
2085
+ z([
2083
2086
  l({ attribute: "key-placeholder" })
2084
2087
  ], M.prototype, "keyPlaceholder", 2);
2085
- K([
2088
+ z([
2086
2089
  l({ attribute: "value-placeholder" })
2087
2090
  ], M.prototype, "valuePlaceholder", 2);
2088
- K([
2091
+ z([
2089
2092
  l({ attribute: "add-label" })
2090
2093
  ], M.prototype, "addLabel", 2);
2091
- K([
2094
+ z([
2092
2095
  l({ type: Boolean })
2093
2096
  ], M.prototype, "disabled", 2);
2094
- K([
2095
- b()
2097
+ z([
2098
+ v()
2096
2099
  ], M.prototype, "rows", 2);
2097
- M = K([
2100
+ M = z([
2098
2101
  p("baht-keyvalue-editor")
2099
2102
  ], M);
2100
2103
  var Hs = Object.defineProperty, Js = Object.getOwnPropertyDescriptor, w = (t, e, r, a) => {
@@ -2102,7 +2105,7 @@ var Hs = Object.defineProperty, Js = Object.getOwnPropertyDescriptor, w = (t, e,
2102
2105
  (o = t[i]) && (s = (a ? o(e, r, s) : o(s)) || s);
2103
2106
  return a && s && Hs(e, r, s), s;
2104
2107
  };
2105
- let Ws = 0, m = class extends c {
2108
+ let Ws = 0, y = class extends c {
2106
2109
  constructor() {
2107
2110
  super(...arguments), this.label = "Reference", this.value = "", this.display = "", this.placeholder = "", this.disabled = !1, this.invalid = !1, this.href = "", this.lookupLabel = "Look up records", this.debounce = 200, this.fetcher = null, this.open = !1, this.term = "", this.options = [], this.loading = !1, this.activeIndex = -1, this.listboxId = `baht-refpicker-list-${++Ws}`, this.fetchSeq = 0, this.onDocMousedown = (t) => {
2108
2111
  this.contains(t.target) || this.close();
@@ -2236,55 +2239,55 @@ let Ws = 0, m = class extends c {
2236
2239
  };
2237
2240
  w([
2238
2241
  l()
2239
- ], m.prototype, "label", 2);
2242
+ ], y.prototype, "label", 2);
2240
2243
  w([
2241
2244
  l()
2242
- ], m.prototype, "value", 2);
2245
+ ], y.prototype, "value", 2);
2243
2246
  w([
2244
2247
  l()
2245
- ], m.prototype, "display", 2);
2248
+ ], y.prototype, "display", 2);
2246
2249
  w([
2247
2250
  l()
2248
- ], m.prototype, "placeholder", 2);
2251
+ ], y.prototype, "placeholder", 2);
2249
2252
  w([
2250
2253
  l({ type: Boolean })
2251
- ], m.prototype, "disabled", 2);
2254
+ ], y.prototype, "disabled", 2);
2252
2255
  w([
2253
2256
  l({ type: Boolean })
2254
- ], m.prototype, "invalid", 2);
2257
+ ], y.prototype, "invalid", 2);
2255
2258
  w([
2256
2259
  l()
2257
- ], m.prototype, "href", 2);
2260
+ ], y.prototype, "href", 2);
2258
2261
  w([
2259
2262
  l({ attribute: "lookup-label" })
2260
- ], m.prototype, "lookupLabel", 2);
2263
+ ], y.prototype, "lookupLabel", 2);
2261
2264
  w([
2262
2265
  l({ type: Number })
2263
- ], m.prototype, "debounce", 2);
2266
+ ], y.prototype, "debounce", 2);
2264
2267
  w([
2265
2268
  l({ attribute: !1 })
2266
- ], m.prototype, "fetcher", 2);
2269
+ ], y.prototype, "fetcher", 2);
2267
2270
  w([
2268
- b()
2269
- ], m.prototype, "open", 2);
2271
+ v()
2272
+ ], y.prototype, "open", 2);
2270
2273
  w([
2271
- b()
2272
- ], m.prototype, "term", 2);
2274
+ v()
2275
+ ], y.prototype, "term", 2);
2273
2276
  w([
2274
- b()
2275
- ], m.prototype, "options", 2);
2277
+ v()
2278
+ ], y.prototype, "options", 2);
2276
2279
  w([
2277
- b()
2278
- ], m.prototype, "loading", 2);
2280
+ v()
2281
+ ], y.prototype, "loading", 2);
2279
2282
  w([
2280
- b()
2281
- ], m.prototype, "activeIndex", 2);
2283
+ v()
2284
+ ], y.prototype, "activeIndex", 2);
2282
2285
  w([
2283
2286
  tt("input")
2284
- ], m.prototype, "inputEl", 2);
2285
- m = w([
2287
+ ], y.prototype, "inputEl", 2);
2288
+ y = w([
2286
2289
  p("baht-reference-picker")
2287
- ], m);
2290
+ ], y);
2288
2291
  const le = {
2289
2292
  text: "baht-input",
2290
2293
  email: "baht-input",
@@ -2376,8 +2379,8 @@ let Mt = class extends g {
2376
2379
  ${e ? n`<button
2377
2380
  type="button"
2378
2381
  class="baht-repeater-remove"
2379
- aria-label=${v("removeRow")}
2380
- title=${v("removeRow")}
2382
+ aria-label=${f("removeRow")}
2383
+ title=${f("removeRow")}
2381
2384
  @click=${() => this.removeRow(s)}
2382
2385
  >
2383
2386
  ✕
@@ -2390,7 +2393,7 @@ let Mt = class extends g {
2390
2393
  ?disabled=${this.disabled || r}
2391
2394
  @click=${() => this.addRow()}
2392
2395
  >
2393
- + ${this.field.addLabel ?? v("addRow")}
2396
+ + ${this.field.addLabel ?? f("addRow")}
2394
2397
  </button>`}
2395
2398
  </div>`;
2396
2399
  }
@@ -2414,7 +2417,7 @@ let vt = class extends c {
2414
2417
  const t = this.variant === "sidebar";
2415
2418
  return n`<ol
2416
2419
  class="baht-steps ${t ? "baht-steps--sidebar" : ""}"
2417
- aria-label=${v("step", { current: this.current + 1, total: this.steps.length })}
2420
+ aria-label=${f("step", { current: this.current + 1, total: this.steps.length })}
2418
2421
  >
2419
2422
  ${this.steps.map((e, r) => {
2420
2423
  const a = r < this.current ? "done" : r === this.current ? "current" : "todo";
@@ -2543,7 +2546,7 @@ let P = class extends c {
2543
2546
  const s = this.stateFor(a);
2544
2547
  if (!s.visible) continue;
2545
2548
  const i = s.required === !!a.required ? a : { ...a, required: s.required };
2546
- t.push(...zt(i, this.valueFor(a), this.registry, e));
2549
+ t.push(...Kt(i, this.valueFor(a), this.registry, e));
2547
2550
  }
2548
2551
  this.errors = t;
2549
2552
  const r = { valid: t.length === 0, errors: t };
@@ -2573,7 +2576,7 @@ let P = class extends c {
2573
2576
  const e = this.stateFor(t);
2574
2577
  if (!e.visible) return [];
2575
2578
  const r = this.getData(), a = e.required === !!t.required ? t : { ...t, required: e.required };
2576
- return zt(a, this.valueFor(t), this.registry, r);
2579
+ return Kt(a, this.valueFor(t), this.registry, r);
2577
2580
  }
2578
2581
  /** `validateOn: 'blur'` — validate just the field the user left, same as
2579
2582
  * how errors are shown elsewhere (merged into `this.errors`, painted by
@@ -2638,10 +2641,10 @@ D([
2638
2641
  l({ type: Boolean })
2639
2642
  ], P.prototype, "readonly", 2);
2640
2643
  D([
2641
- b()
2644
+ v()
2642
2645
  ], P.prototype, "edits", 2);
2643
2646
  D([
2644
- b()
2647
+ v()
2645
2648
  ], P.prototype, "errors", 2);
2646
2649
  P = D([
2647
2650
  p("baht-form")
@@ -2772,7 +2775,7 @@ let $ = class extends c {
2772
2775
  if (!e || e.kind !== "approval") return;
2773
2776
  const r = e.approval ?? {}, a = String(((u = this.data[e.formName]) == null ? void 0 : u.comment) ?? ""), s = r.comment ?? "optional";
2774
2777
  if ((s === "required" || s === "requireOnReject" && t === "rejected") && a.trim() === "") {
2775
- this.approvalError = v("commentRequired");
2778
+ this.approvalError = f("commentRequired");
2776
2779
  return;
2777
2780
  }
2778
2781
  this.approvalError = null, this.data = {
@@ -2835,7 +2838,7 @@ let $ = class extends c {
2835
2838
  const e = ((a = t.approval) == null ? void 0 : a.comment) ?? "optional", r = this.summaryForms(t);
2836
2839
  return n`<div class="baht-approval">
2837
2840
  <div class="baht-approval-summary">
2838
- ${r.length === 0 ? n`<p class="baht-approval-empty">${v("nothingToReview")}</p>` : r.map(
2841
+ ${r.length === 0 ? n`<p class="baht-approval-empty">${f("nothingToReview")}</p>` : r.map(
2839
2842
  (i) => n`<section class="baht-approval-group">
2840
2843
  <h4 class="baht-approval-group-title">${i.formName}</h4>
2841
2844
  <baht-form
@@ -2849,7 +2852,7 @@ let $ = class extends c {
2849
2852
  </div>
2850
2853
  ${e !== "hidden" ? n`<label class="baht-approval-comment">
2851
2854
  <span class="baht-approval-comment-label">
2852
- ${v("comment")}${e === "required" ? v("commentRequiredSuffix") : ""}
2855
+ ${f("comment")}${e === "required" ? f("commentRequiredSuffix") : ""}
2853
2856
  </span>
2854
2857
  <textarea
2855
2858
  rows="3"
@@ -2869,7 +2872,7 @@ let $ = class extends c {
2869
2872
  const e = t.kind === "approval", r = this.visibleForms, a = r.findIndex((o) => o.formName === t.formName);
2870
2873
  return n`<div class="baht-workflow" data-step=${t.formName}>
2871
2874
  <div class="baht-visually-hidden" role="status">
2872
- ${v("step", { current: a + 1, total: r.length })}
2875
+ ${f("step", { current: a + 1, total: r.length })}
2873
2876
  </div>
2874
2877
  ${this.showSteps ? n`<baht-steps
2875
2878
  .steps=${r.map((o) => o.formName)}
@@ -2886,23 +2889,23 @@ let $ = class extends c {
2886
2889
  ></baht-form>`}
2887
2890
  <div class="baht-workflow-nav">
2888
2891
  ${this.showBack && this.history.length > 0 ? n`<button type="button" class="baht-button baht-button--back" @click=${() => this.back()}>
2889
- ${this.backLabel ?? v("back")}
2892
+ ${this.backLabel ?? f("back")}
2890
2893
  </button>` : h}
2891
2894
  ${e ? n`<button
2892
2895
  type="button"
2893
2896
  class="baht-button baht-button--reject"
2894
2897
  @click=${() => this.decide("rejected")}
2895
2898
  >
2896
- ${((s = t.approval) == null ? void 0 : s.rejectLabel) ?? v("reject")}
2899
+ ${((s = t.approval) == null ? void 0 : s.rejectLabel) ?? f("reject")}
2897
2900
  </button>
2898
2901
  <button
2899
2902
  type="button"
2900
2903
  class="baht-button baht-button--next baht-button--approve"
2901
2904
  @click=${() => this.decide("approved")}
2902
2905
  >
2903
- ${((i = t.approval) == null ? void 0 : i.approveLabel) ?? v("approve")}
2906
+ ${((i = t.approval) == null ? void 0 : i.approveLabel) ?? f("approve")}
2904
2907
  </button>` : n`<button type="button" class="baht-button baht-button--next" @click=${() => this.next()}>
2905
- ${this.isLast ? this.submitLabel ?? v("submit") : this.nextLabel ?? v("next")}
2908
+ ${this.isLast ? this.submitLabel ?? f("submit") : this.nextLabel ?? f("next")}
2906
2909
  </button>`}
2907
2910
  </div>
2908
2911
  </div>`;
@@ -2942,16 +2945,16 @@ _([
2942
2945
  l({ attribute: "steps-variant" })
2943
2946
  ], $.prototype, "stepsVariant", 2);
2944
2947
  _([
2945
- b()
2948
+ v()
2946
2949
  ], $.prototype, "data", 2);
2947
2950
  _([
2948
- b()
2951
+ v()
2949
2952
  ], $.prototype, "derived", 2);
2950
2953
  _([
2951
- b()
2954
+ v()
2952
2955
  ], $.prototype, "current", 2);
2953
2956
  _([
2954
- b()
2957
+ v()
2955
2958
  ], $.prototype, "approvalError", 2);
2956
2959
  $ = _([
2957
2960
  p("baht-workflow")
@@ -2976,7 +2979,7 @@ export {
2976
2979
  X as BahtFile,
2977
2980
  U as BahtFilter,
2978
2981
  P as BahtForm,
2979
- Kt as BahtInput,
2982
+ zt as BahtInput,
2980
2983
  M as BahtKeyvalueEditor,
2981
2984
  Q as BahtLink,
2982
2985
  j as BahtList,
@@ -2989,7 +2992,7 @@ export {
2989
2992
  Qt as BahtRadio,
2990
2993
  C as BahtRange,
2991
2994
  T as BahtRating,
2992
- m as BahtReferencePicker,
2995
+ y as BahtReferencePicker,
2993
2996
  Mt as BahtRepeater,
2994
2997
  qt as BahtSection,
2995
2998
  Wt as BahtSelect,
@@ -2997,7 +3000,7 @@ export {
2997
3000
  Ot as BahtSpinner,
2998
3001
  dt as BahtStatChart,
2999
3002
  vt as BahtSteps,
3000
- f as BahtTable,
3003
+ b as BahtTable,
3001
3004
  St as BahtText,
3002
3005
  Ht as BahtTextarea,
3003
3006
  It as BahtTimeline,
@@ -3023,7 +3026,7 @@ export {
3023
3026
  Ut as resolveViewFields,
3024
3027
  yr as setCatalog,
3025
3028
  $r as setLocale,
3026
- v as t,
3027
- zt as validateField,
3029
+ f as t,
3030
+ Kt as validateField,
3028
3031
  gr as walkPath
3029
3032
  };
package/dist/react.d.ts CHANGED
@@ -111,6 +111,7 @@ declare module 'react' {
111
111
  items?: Record<string, unknown>[];
112
112
  columns?: Record<string, string>;
113
113
  renderers?: Record<string, CellRenderer>;
114
+ visibleColumns?: string[];
114
115
  loading?: boolean;
115
116
  error?: boolean;
116
117
  'error-message'?: string;
@@ -583,7 +583,7 @@
583
583
  },
584
584
  {
585
585
  "name": "baht-table",
586
- "description": "Server-side data table. `items` is ONE page of rows — the component never\nslices or fetches; on `baht-page-change` the host fetches the next page and\nre-feeds `items`/`page`. While that fetch runs, set `loading` to show\nskeleton rows.\n\n const t = document.querySelector('baht-table');\n t.columns = { name: 'Name', created_at: 'Created' };\n t.items = pageRows; // current page only\n t.loading = false; t.page = 1; t.totalPages = 12;\n t.addEventListener('baht-page-change', (e) => fetchPage(e.detail.page));\n t.addEventListener('baht-row-click', (e) => open(e.detail.id));\n\nSet `cursor-mode` for cursor-based APIs (no total count) — the footer\nbecomes a Prev/Next pair gated by `has-next`/`has-prev`, and the host\nlistens for `baht-cursor-change` instead of `baht-page-change`:\n\n t.cursorMode = true; t.hasNext = true; t.hasPrev = false;\n t.addEventListener('baht-cursor-change', (e) => fetchPage(e.detail.direction));\n---\n\n\n### **Events:**\n - **baht-row-click**",
586
+ "description": "Server-side data table. `items` is ONE page of rows — the component never\nslices or fetches; on `baht-page-change` the host fetches the next page and\nre-feeds `items`/`page`. While that fetch runs, set `loading` to show\nskeleton rows.\n\n const t = document.querySelector('baht-table');\n t.columns = { name: 'Name', created_at: 'Created' };\n t.items = pageRows; // current page only\n t.loading = false; t.page = 1; t.totalPages = 12;\n t.addEventListener('baht-page-change', (e) => fetchPage(e.detail.page));\n t.addEventListener('baht-row-click', (e) => open(e.detail.id));\n\nSet `cursor-mode` for cursor-based APIs (no total count) — the footer\nbecomes a Prev/Next pair gated by `has-next`/`has-prev`, and the host\nlistens for `baht-cursor-change` instead of `baht-page-change`:\n\n t.cursorMode = true; t.hasNext = true; t.hasPrev = false;\n t.addEventListener('baht-cursor-change', (e) => fetchPage(e.detail.direction));\n\n`visibleColumns` picks + orders a subset of `columns` client-side (no\nrefetch) — pair it with <baht-multiselect> as the chooser UI:\n\n picker.field = { key: 'cols', options: Object.entries(t.columns).map(([key, label]) => ({ key, label })) };\n picker.value = t.visibleColumns; // omit/empty = show all columns\n picker.addEventListener('baht-input', (e) => t.visibleColumns = e.detail.value);\n---\n\n\n### **Events:**\n - **baht-row-click**",
587
587
  "attributes": [
588
588
  { "name": "loading", "values": [] },
589
589
  { "name": "error", "values": [] },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://raw.githubusercontent.com/JetBrains/web-types/master/schema/web-types.json",
3
3
  "name": "bank20baht-ui",
4
- "version": "0.1.5",
4
+ "version": "0.1.6",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
@@ -1452,7 +1452,7 @@
1452
1452
  },
1453
1453
  {
1454
1454
  "name": "baht-table",
1455
- "description": "Server-side data table. `items` is ONE page of rows — the component never\nslices or fetches; on `baht-page-change` the host fetches the next page and\nre-feeds `items`/`page`. While that fetch runs, set `loading` to show\nskeleton rows.\n\n const t = document.querySelector('baht-table');\n t.columns = { name: 'Name', created_at: 'Created' };\n t.items = pageRows; // current page only\n t.loading = false; t.page = 1; t.totalPages = 12;\n t.addEventListener('baht-page-change', (e) => fetchPage(e.detail.page));\n t.addEventListener('baht-row-click', (e) => open(e.detail.id));\n\nSet `cursor-mode` for cursor-based APIs (no total count) — the footer\nbecomes a Prev/Next pair gated by `has-next`/`has-prev`, and the host\nlistens for `baht-cursor-change` instead of `baht-page-change`:\n\n t.cursorMode = true; t.hasNext = true; t.hasPrev = false;\n t.addEventListener('baht-cursor-change', (e) => fetchPage(e.detail.direction));\n---\n\n\n### **Events:**\n - **baht-row-click**",
1455
+ "description": "Server-side data table. `items` is ONE page of rows — the component never\nslices or fetches; on `baht-page-change` the host fetches the next page and\nre-feeds `items`/`page`. While that fetch runs, set `loading` to show\nskeleton rows.\n\n const t = document.querySelector('baht-table');\n t.columns = { name: 'Name', created_at: 'Created' };\n t.items = pageRows; // current page only\n t.loading = false; t.page = 1; t.totalPages = 12;\n t.addEventListener('baht-page-change', (e) => fetchPage(e.detail.page));\n t.addEventListener('baht-row-click', (e) => open(e.detail.id));\n\nSet `cursor-mode` for cursor-based APIs (no total count) — the footer\nbecomes a Prev/Next pair gated by `has-next`/`has-prev`, and the host\nlistens for `baht-cursor-change` instead of `baht-page-change`:\n\n t.cursorMode = true; t.hasNext = true; t.hasPrev = false;\n t.addEventListener('baht-cursor-change', (e) => fetchPage(e.detail.direction));\n\n`visibleColumns` picks + orders a subset of `columns` client-side (no\nrefetch) — pair it with <baht-multiselect> as the chooser UI:\n\n picker.field = { key: 'cols', options: Object.entries(t.columns).map(([key, label]) => ({ key, label })) };\n picker.value = t.visibleColumns; // omit/empty = show all columns\n picker.addEventListener('baht-input', (e) => t.visibleColumns = e.detail.value);\n---\n\n\n### **Events:**\n - **baht-row-click**",
1456
1456
  "doc-url": "",
1457
1457
  "attributes": [
1458
1458
  {
@@ -1555,6 +1555,11 @@
1555
1555
  "description": "Custom cell renderers by column key (functions — a property, never JSON).",
1556
1556
  "type": "Record<string, CellRenderer>"
1557
1557
  },
1558
+ {
1559
+ "name": "visibleColumns",
1560
+ "description": "Subset + order of `columns` to render; empty/omitted = show all.",
1561
+ "type": "string[]"
1562
+ },
1558
1563
  { "name": "page", "type": "number" },
1559
1564
  { "name": "totalPages", "type": "number" },
1560
1565
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bank20baht-ui",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "type": "module",
5
5
  "description": "JSON-driven form + workflow engine. Send JSON in, get an interactive form out.",
6
6
  "license": "MIT",