bank20baht-ui 0.4.3 → 0.5.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/README.md CHANGED
@@ -224,6 +224,35 @@ el.registry = {
224
224
  // JSON side: { formatter: 'uppercase', validators: [{ type: 'custom', fn: 'idCardTH' }] }
225
225
  ```
226
226
 
227
+ ### Client scripts — ServiceNow-style `load` / `change` / `submit`
228
+
229
+ When rules JSON isn't enough, register imperative hooks the same way — by name:
230
+
231
+ ```js
232
+ // JSON side
233
+ form.scripts = [
234
+ { on: 'change', field: 'type', handler: 'typeChanged' },
235
+ { on: 'submit', handler: 'checkQuota' },
236
+ ];
237
+ // host side — `g` is the g_form equivalent, scoped to this form
238
+ el.registry.scripts = {
239
+ typeChanged: (g, { newValue, isLoading }) => {
240
+ if (isLoading) return;
241
+ g.setRequired('doc', newValue === 'sick');
242
+ g.showFieldMsg('doc', 'แนบใบรับรองแพทย์', 'info');
243
+ },
244
+ checkQuota: (g) => {
245
+ if (g.getValue('days') > 10) { g.addErrorMessage('เกินโควตา'); return false; } // blocks submit
246
+ },
247
+ };
248
+ ```
249
+
250
+ `g` reads (`getValue`, `getData`), writes (`setValue` — cascades to that field's `change`
251
+ script, depth-guarded), overrides UI state (`setVisible` / `setReadOnly` / `setRequired` /
252
+ `setDisabled`, on top of rule-derived states) and shows messages. `bank20baht-validator`
253
+ re-runs `submit` scripts on the server; `load`/`change` are UI-only. See
254
+ `docs/components/baht-form.md` and spec 01 §14.
255
+
227
256
  ## Design system — 20baht
228
257
 
229
258
  Ships themed as the **20baht design system**: olive intaglio (`#5C7A33`), rose
@@ -1,19 +1,27 @@
1
- import { svg as c, html as p, nothing as d } from "lit";
2
- import { property as r, query as $, customElement as f, state as w } from "lit/decorators.js";
3
- import { B as v, b as C, h as g } from "./base-CajA2aCO.js";
4
- import { t as E } from "./i18n-BcPL9_Jh.js";
5
- const O = {
6
- copy: c`<rect x="6" y="6" width="8" height="8" rx="1.5"/><path d="M10 6V4.5A1.5 1.5 0 0 0 8.5 3H4.5A1.5 1.5 0 0 0 3 4.5v4A1.5 1.5 0 0 0 4.5 10H6"/>`,
7
- check: c`<path d="M3.5 8.5 6.5 11.5 12.5 4.5"/>`,
8
- download: c`<path d="M8 3v7m0 0 3-3m-3 3L5 7"/><path d="M3 12h10"/>`,
9
- upload: c`<path d="M8 12V5m0 0 3 3M8 5 5 8"/><path d="M3 4h10"/>`,
10
- plus: c`<path d="M8 3.5v9M3.5 8h9"/>`,
11
- external: c`<path d="M6 3H3.5v9.5h9.5V10"/><path d="M9 3h4v4"/><path d="M13 3 7.5 8.5"/>`,
12
- close: c`<path d="M4 4l8 8M12 4l-8 8"/>`,
13
- play: c`<path d="M5 3.5v9l7-4.5z"/>`,
14
- search: c`<circle cx="7" cy="7" r="4"/><path d="m13 13-3.2-3.2"/>`
1
+ import { svg as r, html as p, nothing as d } from "lit";
2
+ import { property as l, query as $, customElement as f, state as w } from "lit/decorators.js";
3
+ import { B as v, b as C, h as g } from "./base-CGS8ov6z.js";
4
+ import { t as O } from "./i18n-Cnr3OLiz.js";
5
+ const M = {
6
+ copy: r`<rect x="6" y="6" width="8" height="8" rx="1.5"/><path d="M10 6V4.5A1.5 1.5 0 0 0 8.5 3H4.5A1.5 1.5 0 0 0 3 4.5v4A1.5 1.5 0 0 0 4.5 10H6"/>`,
7
+ check: r`<path d="M3.5 8.5 6.5 11.5 12.5 4.5"/>`,
8
+ download: r`<path d="M8 3v7m0 0 3-3m-3 3L5 7"/><path d="M3 12h10"/>`,
9
+ upload: r`<path d="M8 12V5m0 0 3 3M8 5 5 8"/><path d="M3 4h10"/>`,
10
+ plus: r`<path d="M8 3.5v9M3.5 8h9"/>`,
11
+ external: r`<path d="M6 3H3.5v9.5h9.5V10"/><path d="M9 3h4v4"/><path d="M13 3 7.5 8.5"/>`,
12
+ close: r`<path d="M4 4l8 8M12 4l-8 8"/>`,
13
+ play: r`<path d="M5 3.5v9l7-4.5z"/>`,
14
+ search: r`<circle cx="7" cy="7" r="4"/><path d="m13 13-3.2-3.2"/>`,
15
+ // table headers: unsorted (both chevrons), ascending, descending
16
+ sort: r`<path d="m5 6.5 3-3 3 3"/><path d="m5 9.5 3 3 3-3"/>`,
17
+ "chevron-up": r`<path d="m4.5 10 3.5-3.5L11.5 10"/>`,
18
+ "chevron-down": r`<path d="m4.5 6 3.5 3.5L11.5 6"/>`,
19
+ // row actions trigger
20
+ more: r`<circle cx="3.5" cy="8" r="1" fill="currentColor"/><circle cx="8" cy="8" r="1" fill="currentColor"/><circle cx="12.5" cy="8" r="1" fill="currentColor"/>`,
21
+ // column picker trigger (sliders)
22
+ columns: r`<path d="M3 5h10M3 11h10"/><circle cx="6" cy="5" r="1.5" fill="var(--baht-color-surface, #fff)"/><circle cx="10" cy="11" r="1.5" fill="var(--baht-color-surface, #fff)"/>`
15
23
  };
16
- function S(t) {
24
+ function x(t) {
17
25
  return p`<svg
18
26
  class="baht-icon"
19
27
  width="16"
@@ -25,15 +33,15 @@ function S(t) {
25
33
  stroke-linecap="round"
26
34
  stroke-linejoin="round"
27
35
  aria-hidden="true"
28
- >${O[t]}</svg>`;
36
+ >${M[t]}</svg>`;
29
37
  }
30
- function M(t) {
31
- return t in O;
38
+ function S(t) {
39
+ return t in M;
32
40
  }
33
- var k = Object.defineProperty, x = Object.getOwnPropertyDescriptor, u = (t, s, o, i) => {
34
- for (var e = i > 1 ? void 0 : i ? x(s, o) : s, a = t.length - 1, l; a >= 0; a--)
35
- (l = t[a]) && (e = (i ? l(s, o, e) : l(e)) || e);
36
- return i && e && k(s, o, e), e;
41
+ var E = Object.defineProperty, k = Object.getOwnPropertyDescriptor, u = (t, s, o, i) => {
42
+ for (var e = i > 1 ? void 0 : i ? k(s, o) : s, a = t.length - 1, c; a >= 0; a--)
43
+ (c = t[a]) && (e = (i ? c(s, o, e) : c(e)) || e);
44
+ return i && e && E(s, o, e), e;
37
45
  };
38
46
  let h = class extends v {
39
47
  constructor() {
@@ -43,7 +51,7 @@ let h = class extends v {
43
51
  this.iconOnly || C(this, this.buttonEl);
44
52
  }
45
53
  render() {
46
- const t = this.variant === "primary" ? "" : ` baht-button--${this.variant}`, s = this.size === "md" ? "" : ` baht-button--${this.size}`, o = this.iconOnly ? " baht-button--icon" : "", i = this.icon && M(this.icon) ? S(this.icon) : d;
54
+ const t = this.variant === "primary" ? "" : ` baht-button--${this.variant}`, s = this.size === "md" ? "" : ` baht-button--${this.size}`, o = this.iconOnly ? " baht-button--icon" : "", i = this.icon && S(this.icon) ? x(this.icon) : d;
47
55
  return p`<button
48
56
  class="baht-button${t}${s}${o}"
49
57
  type=${this.type}
@@ -53,25 +61,25 @@ let h = class extends v {
53
61
  }
54
62
  };
55
63
  u([
56
- r()
64
+ l()
57
65
  ], h.prototype, "variant", 2);
58
66
  u([
59
- r()
67
+ l()
60
68
  ], h.prototype, "size", 2);
61
69
  u([
62
- r({ type: Boolean })
70
+ l({ type: Boolean })
63
71
  ], h.prototype, "disabled", 2);
64
72
  u([
65
- r()
73
+ l()
66
74
  ], h.prototype, "type", 2);
67
75
  u([
68
- r()
76
+ l()
69
77
  ], h.prototype, "label", 2);
70
78
  u([
71
- r()
79
+ l()
72
80
  ], h.prototype, "icon", 2);
73
81
  u([
74
- r({ type: Boolean, attribute: "icon-only" })
82
+ l({ type: Boolean, attribute: "icon-only" })
75
83
  ], h.prototype, "iconOnly", 2);
76
84
  u([
77
85
  $("button")
@@ -93,9 +101,9 @@ function _(t, s) {
93
101
  Promise.all(o.map((a) => a.finished.catch(() => {
94
102
  }))).then(e, e), setTimeout(e, P);
95
103
  }
96
- var B = Object.defineProperty, T = Object.getOwnPropertyDescriptor, b = (t, s, o, i) => {
97
- for (var e = i > 1 ? void 0 : i ? T(s, o) : s, a = t.length - 1, l; a >= 0; a--)
98
- (l = t[a]) && (e = (i ? l(s, o, e) : l(e)) || e);
104
+ var B = Object.defineProperty, T = Object.getOwnPropertyDescriptor, m = (t, s, o, i) => {
105
+ for (var e = i > 1 ? void 0 : i ? T(s, o) : s, a = t.length - 1, c; a >= 0; a--)
106
+ (c = t[a]) && (e = (i ? c(s, o, e) : c(e)) || e);
99
107
  return i && e && B(s, o, e), e;
100
108
  };
101
109
  let n = class extends v {
@@ -156,9 +164,7 @@ let n = class extends v {
156
164
  }
157
165
  /** Ask the host to close (the host owns `open`). */
158
166
  requestClose(t = "button") {
159
- this.dispatchEvent(
160
- new CustomEvent("baht-close", { detail: { reason: t }, bubbles: !0, composed: !0 })
161
- );
167
+ this.emit("baht-close", { reason: t });
162
168
  }
163
169
  render() {
164
170
  return p`<div
@@ -176,7 +182,7 @@ let n = class extends v {
176
182
  >
177
183
  ${this.heading || this.showClose ? p`<header class="baht-modal-header">
178
184
  <div class="baht-modal-title" id=${this.titleId}>${this.heading}</div>
179
- ${this.showClose ? p`<button type="button" class="baht-modal-close" aria-label=${E("close")} @click=${() => this.requestClose("button")}>×</button>` : d}
185
+ ${this.showClose ? p`<button type="button" class="baht-modal-close" aria-label=${O("close")} @click=${() => this.requestClose("button")}>×</button>` : d}
180
186
  </header>` : d}
181
187
  <div class="baht-modal-body"></div>
182
188
  </div>
@@ -184,39 +190,39 @@ let n = class extends v {
184
190
  }
185
191
  };
186
192
  n.openStack = [];
187
- b([
188
- r({ type: Boolean, reflect: !0 })
193
+ m([
194
+ l({ type: Boolean, reflect: !0 })
189
195
  ], n.prototype, "open", 2);
190
- b([
191
- r()
196
+ m([
197
+ l()
192
198
  ], n.prototype, "heading", 2);
193
- b([
194
- r({ type: Boolean, attribute: "show-close" })
199
+ m([
200
+ l({ type: Boolean, attribute: "show-close" })
195
201
  ], n.prototype, "showClose", 2);
196
- b([
197
- r({ type: Boolean, attribute: "close-on-scrim" })
202
+ m([
203
+ l({ type: Boolean, attribute: "close-on-scrim" })
198
204
  ], n.prototype, "closeOnScrim", 2);
199
- b([
205
+ m([
200
206
  $(".baht-modal-body")
201
207
  ], n.prototype, "bodyEl", 2);
202
- b([
208
+ m([
203
209
  w()
204
210
  ], n.prototype, "closing", 2);
205
- n = b([
211
+ n = m([
206
212
  f("baht-modal")
207
213
  ], n);
208
214
  var D = Object.defineProperty, q = Object.getOwnPropertyDescriptor, y = (t, s, o, i) => {
209
- for (var e = i > 1 ? void 0 : i ? q(s, o) : s, a = t.length - 1, l; a >= 0; a--)
210
- (l = t[a]) && (e = (i ? l(s, o, e) : l(e)) || e);
215
+ for (var e = i > 1 ? void 0 : i ? q(s, o) : s, a = t.length - 1, c; a >= 0; a--)
216
+ (c = t[a]) && (e = (i ? c(s, o, e) : c(e)) || e);
211
217
  return i && e && D(s, o, e), e;
212
218
  };
213
- let m = class extends v {
219
+ let b = class extends v {
214
220
  constructor() {
215
221
  super(...arguments), this.duration = 4e3, this.entries = [], this.timers = /* @__PURE__ */ new Map();
216
222
  }
217
223
  show(t) {
218
224
  const s = {
219
- id: ++m.counter,
225
+ id: ++b.counter,
220
226
  message: t.message,
221
227
  tone: t.tone ?? "neutral",
222
228
  duration: t.duration ?? this.duration
@@ -229,13 +235,7 @@ let m = class extends v {
229
235
  dismiss(t) {
230
236
  const s = this.entries.find((e) => e.id === t);
231
237
  if (!s || s.leaving) return;
232
- clearTimeout(this.timers.get(t)), this.timers.delete(t), this.entries = this.entries.map((e) => e.id === t ? { ...e, leaving: !0 } : e), this.dispatchEvent(
233
- new CustomEvent("baht-dismiss", {
234
- detail: { id: t, message: s.message },
235
- bubbles: !0,
236
- composed: !0
237
- })
238
- );
238
+ clearTimeout(this.timers.get(t)), this.timers.delete(t), this.entries = this.entries.map((e) => e.id === t ? { ...e, leaving: !0 } : e), this.emit("baht-dismiss", { id: t, message: s.message });
239
239
  const o = () => {
240
240
  this.entries = this.entries.filter((e) => e.id !== t);
241
241
  }, i = this.querySelector(`.baht-toast[data-toast="${t}"]`);
@@ -258,27 +258,27 @@ let m = class extends v {
258
258
  role=${t.tone === "danger" || t.tone === "warning" ? "alert" : d}
259
259
  >
260
260
  <span class="baht-toast-message">${t.message}</span>
261
- <button type="button" class="baht-toast-dismiss" aria-label=${E("dismiss")} @click=${() => this.dismiss(t.id)}>×</button>
261
+ <button type="button" class="baht-toast-dismiss" aria-label=${O("dismiss")} @click=${() => this.dismiss(t.id)}>×</button>
262
262
  </div>`
263
263
  )}
264
264
  </div>`;
265
265
  }
266
266
  };
267
- m.counter = 0;
267
+ b.counter = 0;
268
268
  y([
269
- r({ type: Number })
270
- ], m.prototype, "duration", 2);
269
+ l({ type: Number })
270
+ ], b.prototype, "duration", 2);
271
271
  y([
272
272
  w()
273
- ], m.prototype, "entries", 2);
274
- m = y([
273
+ ], b.prototype, "entries", 2);
274
+ b = y([
275
275
  f("baht-toast")
276
- ], m);
276
+ ], b);
277
277
  export {
278
278
  h as B,
279
279
  n as a,
280
- m as b,
280
+ b,
281
281
  _ as c,
282
- M as i,
283
- S as r
282
+ S as i,
283
+ x as r
284
284
  };