bank20baht-ui 0.2.8 → 0.2.9
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 +3 -1
- package/dist/chunks/{index-BI-29Q8f.js → index-yULskrKT.js} +87 -67
- package/dist/components/baht-form.d.ts +4 -0
- package/dist/components/base.d.ts +30 -1
- package/dist/components/primitives/baht-datepicker.d.ts +14 -0
- package/dist/components/primitives/baht-modal.d.ts +2 -0
- package/dist/components/primitives/baht-repeater.d.ts +4 -2
- package/dist/components/primitives/baht-select.d.ts +41 -1
- package/dist/components/primitives/baht-table.d.ts +7 -0
- package/dist/components/primitives/baht-typeahead.d.ts +92 -0
- package/dist/components/primitives/index.d.ts +1 -0
- package/dist/core/i18n.d.ts +10 -0
- package/dist/custom-elements.json +2890 -289
- package/dist/engine.js +1 -1
- package/dist/index.js +2166 -1626
- package/dist/tokens.css +321 -27
- package/dist/vscode.html-custom-data.json +126 -22
- package/dist/web-types.json +252 -23
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -234,7 +234,9 @@ Geist / Geist Mono, borders-over-shadows, "paper" easing — plus a dark theme
|
|
|
234
234
|
`items` is one page; `baht-page-change` asks your app to fetch the next one.
|
|
235
235
|
- **Feedback** — `baht-modal` · `baht-toast` · `baht-alert` · `baht-tooltip` · `baht-progress` ·
|
|
236
236
|
`baht-spinner` · `baht-skeleton`
|
|
237
|
-
- **Inputs** — `baht-rating` · `baht-range` · `baht-otp`
|
|
237
|
+
- **Inputs** — `baht-rating` · `baht-range` · `baht-otp` · `baht-typeahead` · `baht-reference-picker` ·
|
|
238
|
+
`baht-keyvalue-editor` (+ the 11 form field primitives). Typed fields debounce keystrokes (150 ms,
|
|
239
|
+
`debounce` / `options.inputDebounce`); `dropdown` renders its own listbox, never the OS picker.
|
|
238
240
|
- **Structure & nav** — `baht-card` · `baht-fieldset` · `baht-timeline` · `baht-accordion` ·
|
|
239
241
|
`baht-link` · `baht-breadcrumbs`
|
|
240
242
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
function
|
|
1
|
+
function $(e) {
|
|
2
2
|
if (e.value !== void 0) return e.value;
|
|
3
3
|
switch (e.type) {
|
|
4
4
|
case "checkbox":
|
|
@@ -58,7 +58,17 @@ const Y = {
|
|
|
58
58
|
no: "No",
|
|
59
59
|
emptyValue: "Not provided",
|
|
60
60
|
choose: "Select",
|
|
61
|
-
rowCount: "{n} rows"
|
|
61
|
+
rowCount: "{n} rows",
|
|
62
|
+
close: "Close",
|
|
63
|
+
dismiss: "Dismiss",
|
|
64
|
+
opensInNewTab: "opens in new tab",
|
|
65
|
+
otpCharacter: "Character {i} of {n}",
|
|
66
|
+
row: "Row {n}",
|
|
67
|
+
removeRowN: "Remove row {n}",
|
|
68
|
+
stepDone: "completed",
|
|
69
|
+
stepCurrent: "current step",
|
|
70
|
+
today: "Today",
|
|
71
|
+
clear: "Clear"
|
|
62
72
|
}, J = {
|
|
63
73
|
required: "กรุณากรอกข้อมูลนี้",
|
|
64
74
|
minLength: "ต้องมีอย่างน้อย {n} ตัวอักษร",
|
|
@@ -100,20 +110,30 @@ const Y = {
|
|
|
100
110
|
no: "ไม่ใช่",
|
|
101
111
|
emptyValue: "ไม่ได้ระบุ",
|
|
102
112
|
choose: "เลือก",
|
|
103
|
-
rowCount: "{n} แถว"
|
|
113
|
+
rowCount: "{n} แถว",
|
|
114
|
+
close: "ปิด",
|
|
115
|
+
dismiss: "ปิดข้อความ",
|
|
116
|
+
opensInNewTab: "เปิดในแท็บใหม่",
|
|
117
|
+
otpCharacter: "ตัวอักษรที่ {i} จาก {n}",
|
|
118
|
+
row: "แถวที่ {n}",
|
|
119
|
+
removeRowN: "ลบแถวที่ {n}",
|
|
120
|
+
stepDone: "เสร็จแล้ว",
|
|
121
|
+
stepCurrent: "ขั้นตอนปัจจุบัน",
|
|
122
|
+
today: "วันนี้",
|
|
123
|
+
clear: "ล้างค่า"
|
|
104
124
|
}, K = { en: Y, th: J };
|
|
105
|
-
let
|
|
106
|
-
function
|
|
107
|
-
|
|
125
|
+
let D = Y;
|
|
126
|
+
function ve(e, t) {
|
|
127
|
+
D = { ...K[e], ...t };
|
|
108
128
|
}
|
|
109
|
-
function
|
|
110
|
-
return
|
|
129
|
+
function xe() {
|
|
130
|
+
return D;
|
|
111
131
|
}
|
|
112
|
-
function
|
|
113
|
-
|
|
132
|
+
function Ae(e) {
|
|
133
|
+
D = e;
|
|
114
134
|
}
|
|
115
135
|
function f(e, t) {
|
|
116
|
-
let n =
|
|
136
|
+
let n = D[e];
|
|
117
137
|
if (t)
|
|
118
138
|
for (const [s, r] of Object.entries(t))
|
|
119
139
|
n = n.replaceAll(`{${s}}`, () => String(r));
|
|
@@ -130,7 +150,7 @@ function q(e, t) {
|
|
|
130
150
|
if (n !== -1)
|
|
131
151
|
return (s = e[t.slice(0, n)]) == null ? void 0 : s[t.slice(n + 1)];
|
|
132
152
|
}
|
|
133
|
-
function
|
|
153
|
+
function E(e) {
|
|
134
154
|
return e == null ? !0 : typeof e == "string" ? e === "" : Array.isArray(e) ? e.length === 0 : !1;
|
|
135
155
|
}
|
|
136
156
|
function w(e, t) {
|
|
@@ -182,16 +202,16 @@ function X(e, t) {
|
|
|
182
202
|
case "endsWith":
|
|
183
203
|
return typeof n == "string" && n.endsWith(String(s));
|
|
184
204
|
case "isEmpty":
|
|
185
|
-
return
|
|
205
|
+
return E(n);
|
|
186
206
|
case "isNotEmpty":
|
|
187
|
-
return !
|
|
207
|
+
return !E(n);
|
|
188
208
|
}
|
|
189
209
|
}
|
|
190
|
-
function
|
|
191
|
-
return e === void 0 ? !0 : "and" in e ? e.and.every((n) =>
|
|
210
|
+
function v(e, t) {
|
|
211
|
+
return e === void 0 ? !0 : "and" in e ? e.and.every((n) => v(n, t)) : "or" in e ? e.or.some((n) => v(n, t)) : "not" in e ? !v(e.not, t) : X(e, t);
|
|
192
212
|
}
|
|
193
213
|
const H = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
194
|
-
function
|
|
214
|
+
function x(e) {
|
|
195
215
|
if (typeof e != "string") return null;
|
|
196
216
|
const t = H.exec(e);
|
|
197
217
|
if (!t) return null;
|
|
@@ -209,15 +229,15 @@ function ee(e) {
|
|
|
209
229
|
function te(e) {
|
|
210
230
|
const t = e.indexOf("/");
|
|
211
231
|
if (t === -1) {
|
|
212
|
-
const r =
|
|
232
|
+
const r = x(e);
|
|
213
233
|
return r ? [r, r] : null;
|
|
214
234
|
}
|
|
215
|
-
const n =
|
|
235
|
+
const n = x(e.slice(0, t)), s = x(e.slice(t + 1));
|
|
216
236
|
return !n || !s ? null : n <= s ? [n, s] : [s, n];
|
|
217
237
|
}
|
|
218
238
|
function ne(e, t) {
|
|
219
239
|
var s;
|
|
220
|
-
const n =
|
|
240
|
+
const n = x(t);
|
|
221
241
|
if (!n) return !1;
|
|
222
242
|
if ((s = e.disabledWeekdays) != null && s.includes(n.getDay())) return !0;
|
|
223
243
|
for (const r of e.disabledDates ?? []) {
|
|
@@ -227,7 +247,7 @@ function ne(e, t) {
|
|
|
227
247
|
return !1;
|
|
228
248
|
}
|
|
229
249
|
function re(e, t, n = 3660) {
|
|
230
|
-
const s =
|
|
250
|
+
const s = x(e), r = x(t);
|
|
231
251
|
if (!s || !r || s >= r) return [];
|
|
232
252
|
const o = [], i = new Date(s);
|
|
233
253
|
for (i.setDate(i.getDate() + 1); i < r && o.length < n; )
|
|
@@ -242,7 +262,7 @@ function oe(e) {
|
|
|
242
262
|
const t = [...e.validators ?? []], n = (s) => t.some((r) => r.type === s);
|
|
243
263
|
return e.required && !n("required") && t.push({ type: "required" }), e.maxLength !== void 0 && !n("maxLength") && t.push({ type: "maxLength", value: e.maxLength }), e.minLength !== void 0 && !n("minLength") && t.push({ type: "minLength", value: e.minLength }), e.min !== void 0 && !n("min") && t.push({ type: "min", value: e.min }), e.max !== void 0 && !n("max") && t.push({ type: "max", value: e.max }), e.type === "email" && !n("email") && t.push({ type: "email" }), t;
|
|
244
264
|
}
|
|
245
|
-
const
|
|
265
|
+
const j = (e) => Array.isArray(e) ? e : [e];
|
|
246
266
|
function ie(e, t, n, s) {
|
|
247
267
|
var r;
|
|
248
268
|
switch (e.type) {
|
|
@@ -261,12 +281,12 @@ function ie(e, t, n, s) {
|
|
|
261
281
|
), null) : typeof t == "string" && t.length > o ? e.message ?? f("maxLength", { n: e.value }) : null;
|
|
262
282
|
}
|
|
263
283
|
case "min":
|
|
264
|
-
return
|
|
284
|
+
return j(t).some((i) => {
|
|
265
285
|
const a = w(i, e.value);
|
|
266
286
|
return a !== null && a < 0;
|
|
267
287
|
}) ? e.message ?? f("min", { n: e.value }) : null;
|
|
268
288
|
case "max":
|
|
269
|
-
return
|
|
289
|
+
return j(t).some((i) => {
|
|
270
290
|
const a = w(i, e.value);
|
|
271
291
|
return a !== null && a > 0;
|
|
272
292
|
}) ? e.message ?? f("max", { n: e.value }) : null;
|
|
@@ -340,7 +360,7 @@ function me(e, t, n) {
|
|
|
340
360
|
return s.forEach((i, a) => {
|
|
341
361
|
const d = i !== null && typeof i == "object" && !Array.isArray(i) ? i : {}, p = {};
|
|
342
362
|
for (const u of o)
|
|
343
|
-
u.type === "label" || u.type === "section" || u.type === "repeater" || (p[u.key] = Object.hasOwn(d, u.key) ? d[u.key] :
|
|
363
|
+
u.type === "label" || u.type === "section" || u.type === "repeater" || (p[u.key] = Object.hasOwn(d, u.key) ? d[u.key] : $(u));
|
|
344
364
|
for (const u of o)
|
|
345
365
|
if (!(u.type === "label" || u.type === "section" || u.type === "repeater"))
|
|
346
366
|
for (const y of ae(u, p[u.key], n, p))
|
|
@@ -361,11 +381,11 @@ function S(e, t) {
|
|
|
361
381
|
function G(e, t) {
|
|
362
382
|
return e.filter((n) => S(n.flag, t)).map((n) => n.fields ? { ...n, fields: G(n.fields, t) } : n);
|
|
363
383
|
}
|
|
364
|
-
function
|
|
365
|
-
return e.some((t) => t.flag !== void 0 || (t.fields ?
|
|
384
|
+
function T(e) {
|
|
385
|
+
return e.some((t) => t.flag !== void 0 || (t.fields ? T(t.fields) : !1));
|
|
366
386
|
}
|
|
367
|
-
function
|
|
368
|
-
if (!
|
|
387
|
+
function M(e, t) {
|
|
388
|
+
if (!T(e.field_data)) return e;
|
|
369
389
|
const n = G(e.field_data, t), s = new Set(n.map((r) => r.key));
|
|
370
390
|
return {
|
|
371
391
|
...e,
|
|
@@ -373,34 +393,34 @@ function T(e, t) {
|
|
|
373
393
|
...e.views ? { views: e.views.map((r) => ({ ...r, fields: r.fields.filter((o) => s.has(o)) })) } : {}
|
|
374
394
|
};
|
|
375
395
|
}
|
|
376
|
-
function
|
|
396
|
+
function Re(e, t = {}) {
|
|
377
397
|
if ("workflowId" in e) {
|
|
378
398
|
const n = e;
|
|
379
|
-
return n.forms.some((r) => r.flag !== void 0 ||
|
|
399
|
+
return n.forms.some((r) => r.flag !== void 0 || T(r.field_data)) || n.rules.some((r) => r.flag !== void 0) || (n.transitions ?? []).some((r) => r.flag !== void 0) ? {
|
|
380
400
|
...n,
|
|
381
|
-
forms: n.forms.filter((r) => S(r.flag, t)).map((r) =>
|
|
401
|
+
forms: n.forms.filter((r) => S(r.flag, t)).map((r) => M(r, t)),
|
|
382
402
|
rules: n.rules.filter((r) => S(r.flag, t)),
|
|
383
403
|
...n.transitions ? { transitions: n.transitions.filter((r) => S(r.flag, t)) } : {}
|
|
384
404
|
} : e;
|
|
385
405
|
}
|
|
386
|
-
return
|
|
406
|
+
return M(e, t);
|
|
387
407
|
}
|
|
388
408
|
function de(e) {
|
|
389
409
|
if (e == null || e === "") return null;
|
|
390
410
|
const t = Number(e);
|
|
391
411
|
return Number.isNaN(t) ? null : t;
|
|
392
412
|
}
|
|
393
|
-
function
|
|
413
|
+
function R(e) {
|
|
394
414
|
return typeof e == "number" && Number.isNaN(e) ? null : e;
|
|
395
415
|
}
|
|
396
|
-
function
|
|
416
|
+
function L(e, t) {
|
|
397
417
|
if ("ref" in e) return q(t, e.ref);
|
|
398
418
|
if ("const" in e) return e.const;
|
|
399
419
|
if ("if" in e) {
|
|
400
420
|
const [s, r, o] = e.if;
|
|
401
|
-
return
|
|
421
|
+
return v(s, t) ? R(L(r, t)) : R(L(o, t));
|
|
402
422
|
}
|
|
403
|
-
const n = e.args.map((s) => L(
|
|
423
|
+
const n = e.args.map((s) => R(L(s, t)));
|
|
404
424
|
switch (e.op) {
|
|
405
425
|
case "concat":
|
|
406
426
|
return n.map((s) => s == null ? "" : String(s)).join("");
|
|
@@ -428,10 +448,10 @@ function $(e, t) {
|
|
|
428
448
|
}
|
|
429
449
|
}
|
|
430
450
|
function pe(e, t) {
|
|
431
|
-
return L(
|
|
451
|
+
return R(L(e, t));
|
|
432
452
|
}
|
|
433
|
-
const
|
|
434
|
-
function
|
|
453
|
+
const C = 20, I = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
454
|
+
function V(e, t) {
|
|
435
455
|
return e !== null && typeof e == "object" && Object.hasOwn(e, t) ? e[t] : void 0;
|
|
436
456
|
}
|
|
437
457
|
function O(e, t) {
|
|
@@ -454,15 +474,15 @@ function he(e, t) {
|
|
|
454
474
|
const n = [], s = /* @__PURE__ */ new Map(), r = [];
|
|
455
475
|
let o = {};
|
|
456
476
|
for (const u of e.forms) {
|
|
457
|
-
if (
|
|
477
|
+
if (I.has(u.formName)) {
|
|
458
478
|
n.push({ ref: u.formName, message: "unsafe form name", kind: "schema" });
|
|
459
479
|
continue;
|
|
460
480
|
}
|
|
461
481
|
r.push(u.formName);
|
|
462
|
-
const y = {}, N =
|
|
482
|
+
const y = {}, N = V(t, u.formName);
|
|
463
483
|
for (const m of [...u.field_data, ...B(u)]) {
|
|
464
484
|
if (m.type === "label" || m.type === "section") continue;
|
|
465
|
-
if (
|
|
485
|
+
if (I.has(m.key)) {
|
|
466
486
|
n.push({
|
|
467
487
|
ref: `${u.formName}.${m.key}`,
|
|
468
488
|
message: "unsafe field key",
|
|
@@ -471,13 +491,13 @@ function he(e, t) {
|
|
|
471
491
|
continue;
|
|
472
492
|
}
|
|
473
493
|
s.set(`${u.formName}.${m.key}`, m);
|
|
474
|
-
const c =
|
|
475
|
-
y[m.key] = c !== void 0 ? c :
|
|
494
|
+
const c = V(N, m.key);
|
|
495
|
+
y[m.key] = c !== void 0 ? c : $(m);
|
|
476
496
|
}
|
|
477
497
|
o[u.formName] = y;
|
|
478
498
|
}
|
|
479
499
|
let i = {}, a = {}, d = !1;
|
|
480
|
-
for (let u = 0; u <
|
|
500
|
+
for (let u = 0; u < C; u++) {
|
|
481
501
|
i = {}, a = {};
|
|
482
502
|
for (const c of r) a[c] = { visible: !0 };
|
|
483
503
|
for (const [c, h] of s)
|
|
@@ -490,12 +510,12 @@ function he(e, t) {
|
|
|
490
510
|
};
|
|
491
511
|
const y = /* @__PURE__ */ new Map();
|
|
492
512
|
e.rules.forEach((c, h) => {
|
|
493
|
-
const l =
|
|
513
|
+
const l = v(c.when, o) ? c.then : c.else;
|
|
494
514
|
if (!l) return;
|
|
495
515
|
const k = c.priority ?? 0;
|
|
496
516
|
for (const g of l) {
|
|
497
|
-
const b = ge(g),
|
|
498
|
-
|
|
517
|
+
const b = ge(g), A = y.get(b) ?? [];
|
|
518
|
+
A.push({ action: g, priority: k, index: h }), y.set(b, A);
|
|
499
519
|
}
|
|
500
520
|
});
|
|
501
521
|
const N = [];
|
|
@@ -507,8 +527,8 @@ function he(e, t) {
|
|
|
507
527
|
continue;
|
|
508
528
|
}
|
|
509
529
|
if (l.action === "showForm" || l.action === "hideForm" || l.action === "skipForm") {
|
|
510
|
-
const
|
|
511
|
-
if (!
|
|
530
|
+
const A = a[l.target.form];
|
|
531
|
+
if (!A) {
|
|
512
532
|
n.push({
|
|
513
533
|
ref: l.target.form,
|
|
514
534
|
message: `rule targets unknown form (${c})`,
|
|
@@ -516,7 +536,7 @@ function he(e, t) {
|
|
|
516
536
|
});
|
|
517
537
|
continue;
|
|
518
538
|
}
|
|
519
|
-
|
|
539
|
+
A.visible = l.action === "showForm";
|
|
520
540
|
continue;
|
|
521
541
|
}
|
|
522
542
|
const k = l.target, g = `${k.form}.${k.field}`, b = i[g];
|
|
@@ -551,11 +571,11 @@ function he(e, t) {
|
|
|
551
571
|
const m = {};
|
|
552
572
|
for (const c of r) m[c] = { ...o[c] };
|
|
553
573
|
for (const [c, h] of s) {
|
|
554
|
-
const [l, k] =
|
|
555
|
-
(!a[l].visible || !i[c].visible) && (m[l][k] =
|
|
574
|
+
const [l, k] = _(c);
|
|
575
|
+
(!a[l].visible || !i[c].visible) && (m[l][k] = $(h));
|
|
556
576
|
}
|
|
557
577
|
for (const { ref: c, action: h } of N) {
|
|
558
|
-
const [l, k] =
|
|
578
|
+
const [l, k] = _(c), g = i[c];
|
|
559
579
|
if (!g) {
|
|
560
580
|
n.push({ ref: c, message: "setValue targets unknown field", kind: "schema" });
|
|
561
581
|
continue;
|
|
@@ -570,7 +590,7 @@ function he(e, t) {
|
|
|
570
590
|
}
|
|
571
591
|
d || n.push({
|
|
572
592
|
ref: e.workflowId,
|
|
573
|
-
message: `rules did not converge within ${
|
|
593
|
+
message: `rules did not converge within ${C} passes (cycle?)`,
|
|
574
594
|
kind: "data"
|
|
575
595
|
});
|
|
576
596
|
const p = {};
|
|
@@ -587,7 +607,7 @@ function ge(e) {
|
|
|
587
607
|
const t = e.action === "show" || e.action === "hide" ? "visible" : e.action === "enable" || e.action === "disable" ? "enabled" : e.action === "required" || e.action === "optional" ? "required" : e.action === "showForm" || e.action === "hideForm" || e.action === "skipForm" ? "formVisible" : e.action, n = "field" in e.target ? `${e.target.form}.${e.target.field}` : e.target.form;
|
|
588
608
|
return `${t}:${n}`;
|
|
589
609
|
}
|
|
590
|
-
function
|
|
610
|
+
function _(e) {
|
|
591
611
|
const t = e.indexOf(".");
|
|
592
612
|
return [e.slice(0, t), e.slice(t + 1)];
|
|
593
613
|
}
|
|
@@ -602,7 +622,7 @@ function P(e, t) {
|
|
|
602
622
|
}
|
|
603
623
|
function W(e, t, n) {
|
|
604
624
|
for (const o of e.transitions ?? [])
|
|
605
|
-
if (o.from === t &&
|
|
625
|
+
if (o.from === t && v(o.when, n))
|
|
606
626
|
return o.to;
|
|
607
627
|
const s = [...e.forms].sort((o, i) => o.order - i.order), r = s.findIndex((o) => o.formName === t);
|
|
608
628
|
return r >= 0 && r + 1 < s.length ? s[r + 1].formName : "end";
|
|
@@ -616,7 +636,7 @@ function be(e, t, n, s) {
|
|
|
616
636
|
}
|
|
617
637
|
return i;
|
|
618
638
|
}
|
|
619
|
-
function
|
|
639
|
+
function Le(e, t) {
|
|
620
640
|
var d;
|
|
621
641
|
const n = P(e, t), r = (d = [...e.forms].sort((p, u) => p.order - u.order).find((p) => n.has(p.formName))) == null ? void 0 : d.formName;
|
|
622
642
|
if (!r) return [];
|
|
@@ -669,8 +689,8 @@ function we(e, t, n = e.options) {
|
|
|
669
689
|
}
|
|
670
690
|
export {
|
|
671
691
|
te as a,
|
|
672
|
-
|
|
673
|
-
|
|
692
|
+
$ as b,
|
|
693
|
+
Re as c,
|
|
674
694
|
Z as d,
|
|
675
695
|
we as e,
|
|
676
696
|
Q as f,
|
|
@@ -678,17 +698,17 @@ export {
|
|
|
678
698
|
be as h,
|
|
679
699
|
ee as i,
|
|
680
700
|
B as j,
|
|
681
|
-
|
|
701
|
+
v as k,
|
|
682
702
|
pe as l,
|
|
683
703
|
S as m,
|
|
684
|
-
|
|
704
|
+
xe as n,
|
|
685
705
|
ne as o,
|
|
686
|
-
|
|
706
|
+
x as p,
|
|
687
707
|
q,
|
|
688
708
|
Se as r,
|
|
689
|
-
|
|
709
|
+
Ae as s,
|
|
690
710
|
f as t,
|
|
691
|
-
|
|
711
|
+
ve as u,
|
|
692
712
|
ae as v,
|
|
693
|
-
|
|
713
|
+
Le as w
|
|
694
714
|
};
|
|
@@ -3,6 +3,8 @@ import { BahtElement } from './base.js';
|
|
|
3
3
|
import { DerivedFieldState, FeatureFlags, FormDefinition, Registry, ValidationError } from '../core/types.js';
|
|
4
4
|
export interface BahtFormOptions {
|
|
5
5
|
validateOn?: 'change' | 'blur' | 'submit';
|
|
6
|
+
/** Debounce (ms) for typed fields; unset = BahtFieldBase.defaultDebounce (150). 0 = none. */
|
|
7
|
+
inputDebounce?: number;
|
|
6
8
|
}
|
|
7
9
|
/**
|
|
8
10
|
* <baht-form> — dumb controlled form renderer (spec 01).
|
|
@@ -64,6 +66,8 @@ export declare class BahtForm extends BahtElement {
|
|
|
64
66
|
private get sortedFields();
|
|
65
67
|
private stateFor;
|
|
66
68
|
private valueFor;
|
|
69
|
+
/** Debounced keystrokes still in a control land in `edits` before anyone reads them. */
|
|
70
|
+
private flushTyped;
|
|
67
71
|
getData(): Record<string, unknown>;
|
|
68
72
|
setValue(patch: Record<string, unknown>): void;
|
|
69
73
|
validate(): {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LitElement, nothing, TemplateResult } from 'lit';
|
|
1
|
+
import { LitElement, nothing, PropertyValues, TemplateResult } from 'lit';
|
|
2
2
|
import { FieldDescriptor } from '../core/types.js';
|
|
3
3
|
/** Light-DOM Lit base: consumer CSS reaches every internal node (spec 01 §6). */
|
|
4
4
|
export declare class BahtElement extends LitElement {
|
|
@@ -22,12 +22,41 @@ export declare abstract class BahtFieldBase extends BahtElement {
|
|
|
22
22
|
* collide — worst for radios, whose shared native `name` merges groups.
|
|
23
23
|
*/
|
|
24
24
|
private readonly uid;
|
|
25
|
+
/**
|
|
26
|
+
* Default trailing debounce (ms) for TYPED edits — text, email, password,
|
|
27
|
+
* textarea, number. Every keystroke otherwise re-runs the host's rules,
|
|
28
|
+
* validation and dependent-option fetches. Per element: the `debounce`
|
|
29
|
+
* property/attribute; `<baht-form options.inputDebounce>` sets it for a whole
|
|
30
|
+
* form. 0 = emit on every keystroke. Selects, checkboxes, radios, toggles,
|
|
31
|
+
* dates and files are never debounced — a pick is one event.
|
|
32
|
+
*/
|
|
33
|
+
static defaultDebounce: number;
|
|
25
34
|
field: FieldDescriptor;
|
|
26
35
|
value: unknown;
|
|
27
36
|
disabled: boolean;
|
|
28
37
|
readonly: boolean;
|
|
29
38
|
required: boolean;
|
|
30
39
|
error: string | null;
|
|
40
|
+
/** Debounce for typed edits (ms); unset = BahtFieldBase.defaultDebounce. */
|
|
41
|
+
debounce?: number;
|
|
42
|
+
/**
|
|
43
|
+
* The keystrokes not yet (or just) handed to the host. The control keeps
|
|
44
|
+
* rendering `typed.value` until the host's `value` moves, so a re-render
|
|
45
|
+
* mid-typing (a sibling field changing) can't snap the text back.
|
|
46
|
+
*/
|
|
47
|
+
private typed;
|
|
48
|
+
private typedTimer;
|
|
49
|
+
private readonly onFocusOut;
|
|
50
|
+
connectedCallback(): void;
|
|
51
|
+
disconnectedCallback(): void;
|
|
52
|
+
protected willUpdate(changed: PropertyValues<this>): void;
|
|
53
|
+
protected get effectiveDebounce(): number;
|
|
54
|
+
/** A typed edit: emitted after `debounce` ms of quiet (or at once when 0). */
|
|
55
|
+
protected emitTyped(value: unknown): void;
|
|
56
|
+
/** Hand a pending typed edit to the host now (blur, disconnect, host reads). Idempotent. */
|
|
57
|
+
flushTyped(): void;
|
|
58
|
+
/** What a typed control shows: pending keystrokes win over a stale host value. */
|
|
59
|
+
protected get shownValue(): unknown;
|
|
31
60
|
/** Emit the user's edit upward (composed so it crosses any boundary). */
|
|
32
61
|
protected emitInput(value: unknown): void;
|
|
33
62
|
protected abstract renderControl(): TemplateResult;
|
|
@@ -13,6 +13,11 @@ import { BahtFieldBase } from '../base.js';
|
|
|
13
13
|
* The calendar renders INSIDE the element (flatpickr `static`), so it lives in
|
|
14
14
|
* light DOM like every other node and picks up a theme set on any ancestor.
|
|
15
15
|
* Give a clipping ancestor (`overflow: hidden`) room, or it hides the popup.
|
|
16
|
+
*
|
|
17
|
+
* A footer under the grid carries **Today** (picks today — greyed out when
|
|
18
|
+
* min/max/disabled rules exclude it) and **Clear** (empties the value). Both
|
|
19
|
+
* go through flatpickr, so they emit exactly like a click on a day. `disableMobile`
|
|
20
|
+
* keeps this calendar on phones too — never the OS date wheel.
|
|
16
21
|
*/
|
|
17
22
|
export declare class BahtDatepicker extends BahtFieldBase {
|
|
18
23
|
private fp;
|
|
@@ -22,6 +27,8 @@ export declare class BahtDatepicker extends BahtFieldBase {
|
|
|
22
27
|
* pick onChange already sent — compare against this until `value` catches up.
|
|
23
28
|
*/
|
|
24
29
|
private lastEmitted;
|
|
30
|
+
private todayBtn;
|
|
31
|
+
private clearBtn;
|
|
25
32
|
protected renderControl(): TemplateResult;
|
|
26
33
|
connectedCallback(): void;
|
|
27
34
|
disconnectedCallback(): void;
|
|
@@ -30,6 +37,13 @@ export declare class BahtDatepicker extends BahtFieldBase {
|
|
|
30
37
|
/** Push the host-fed `value` into the calendar without echoing an event. */
|
|
31
38
|
private syncValue;
|
|
32
39
|
private options;
|
|
40
|
+
private mountFooter;
|
|
41
|
+
/** Today greys out when the rules exclude it; Clear when there is nothing to clear.
|
|
42
|
+
* `fp` is passed explicitly from onReady — it fires inside the flatpickr()
|
|
43
|
+
* call, before `this.fp` is assigned. */
|
|
44
|
+
private refreshFooter;
|
|
45
|
+
private todayAllowed;
|
|
46
|
+
private pickToday;
|
|
33
47
|
private emitIfChanged;
|
|
34
48
|
/** Host value (any mode) -> the Date list flatpickr works with. */
|
|
35
49
|
private datesOf;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TemplateResult } from 'lit';
|
|
1
|
+
import { PropertyValues, TemplateResult } from 'lit';
|
|
2
2
|
import { BahtFieldBase } from '../base.js';
|
|
3
3
|
import { ValidationError } from '../../core/types.js';
|
|
4
4
|
/**
|
|
@@ -16,12 +16,14 @@ export declare class BahtRepeater extends BahtFieldBase {
|
|
|
16
16
|
* when the descriptor changes or row indexes shift (remove).
|
|
17
17
|
*/
|
|
18
18
|
private controls;
|
|
19
|
-
protected willUpdate(changed:
|
|
19
|
+
protected willUpdate(changed: PropertyValues<this>): void;
|
|
20
20
|
private get rows();
|
|
21
21
|
private get subFields();
|
|
22
22
|
private patchRow;
|
|
23
23
|
private addRow;
|
|
24
24
|
private removeRow;
|
|
25
|
+
/** Pending keystrokes in any row land in the array before the host reads it. */
|
|
26
|
+
flushTyped(): void;
|
|
25
27
|
private errorFor;
|
|
26
28
|
private renderSub;
|
|
27
29
|
protected renderControl(): TemplateResult;
|
|
@@ -1,5 +1,45 @@
|
|
|
1
|
-
import { TemplateResult } from 'lit';
|
|
1
|
+
import { PropertyValues, TemplateResult } from 'lit';
|
|
2
2
|
import { BahtFieldBase } from '../base.js';
|
|
3
|
+
/**
|
|
4
|
+
* Single-choice dropdown. Renders ITS OWN list (light DOM, positioned under
|
|
5
|
+
* the trigger) instead of the native `<select>` — so the picker looks the same
|
|
6
|
+
* on iOS/macOS as everywhere else (no UIKit wheel, no AppKit menu), and every
|
|
7
|
+
* option is styleable with the tokens.
|
|
8
|
+
*
|
|
9
|
+
* ARIA: APG "select-only combobox". The trigger is a `<button role="combobox">`
|
|
10
|
+
* (so `<label for>` still names it); `aria-activedescendant` tracks the
|
|
11
|
+
* highlighted option while focus stays on the trigger. Keys: Arrow Up/Down,
|
|
12
|
+
* Home/End, Enter/Space pick, Escape closes, Tab picks the highlighted option
|
|
13
|
+
* and moves on, typing jumps to the first option starting with those letters
|
|
14
|
+
* (while closed it picks it directly, like a native select).
|
|
15
|
+
*
|
|
16
|
+
* Value contract unchanged: option `key`, or `null` for the placeholder row.
|
|
17
|
+
*/
|
|
3
18
|
export declare class BahtSelect extends BahtFieldBase {
|
|
19
|
+
private open;
|
|
20
|
+
/** Index into `rows` (0 = the placeholder row) — the highlighted option. */
|
|
21
|
+
private active;
|
|
22
|
+
private typeBuffer;
|
|
23
|
+
private typeTimer;
|
|
24
|
+
private readonly onDocMousedown;
|
|
25
|
+
disconnectedCallback(): void;
|
|
26
|
+
private get listId();
|
|
27
|
+
private optionId;
|
|
28
|
+
/** Placeholder row first (picks `null`), then the field's options. */
|
|
29
|
+
private get rows();
|
|
30
|
+
private get currentKey();
|
|
31
|
+
private get selectedIndex();
|
|
32
|
+
private get interactive();
|
|
33
|
+
protected willUpdate(changed: PropertyValues<this>): void;
|
|
34
|
+
protected updated(): void;
|
|
35
|
+
private openList;
|
|
36
|
+
private close;
|
|
37
|
+
private toggle;
|
|
38
|
+
private commit;
|
|
39
|
+
private highlight;
|
|
40
|
+
private move;
|
|
41
|
+
/** Type-to-select: first option (after the highlighted one) starting with the buffer. */
|
|
42
|
+
private typeahead;
|
|
43
|
+
private onKeydown;
|
|
4
44
|
protected renderControl(): TemplateResult;
|
|
5
45
|
}
|
|
@@ -95,6 +95,8 @@ export declare class BahtTable extends BahtElement {
|
|
|
95
95
|
hasNext: boolean;
|
|
96
96
|
hasPrev: boolean;
|
|
97
97
|
private pickerOpen;
|
|
98
|
+
private static instances;
|
|
99
|
+
private readonly pickerTitleId;
|
|
98
100
|
/** User's picks once they've touched the picker; null = follow `visibleColumns`/all. */
|
|
99
101
|
private pickedColumns;
|
|
100
102
|
/** Working copy edited inside the modal; committed to `pickedColumns` on OK. */
|
|
@@ -104,7 +106,12 @@ export declare class BahtTable extends BahtElement {
|
|
|
104
106
|
private pickSel;
|
|
105
107
|
/** Reference columns unfolded in the Available tree (dot-walk). */
|
|
106
108
|
private expanded;
|
|
109
|
+
/** Element focused before the picker opened — focus returns there on close. */
|
|
110
|
+
private pickerPreviousFocus;
|
|
107
111
|
private readonly onPickerKeydown;
|
|
112
|
+
private pickerFocusables;
|
|
113
|
+
/** Keep Tab cycling inside the column-picker dialog (no escape to the page behind). */
|
|
114
|
+
private trapPickerFocus;
|
|
108
115
|
disconnectedCallback(): void;
|
|
109
116
|
protected willUpdate(changed: Map<PropertyKey, unknown>): void;
|
|
110
117
|
/** The declared map, or one derived from the first row (nested objects become reference columns). */
|