bank20baht-ui 0.8.2 → 0.10.0
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/dist/components/primitives/baht-bar-chart.js +1 -1
- package/dist/components/primitives/baht-line-chart.d.ts +12 -0
- package/dist/components/primitives/baht-line-chart.js +112 -87
- package/dist/components/primitives/baht-modal.d.ts +4 -0
- package/dist/components/primitives/baht-modal.js +25 -21
- package/dist/core/i18n.d.ts +4 -0
- package/dist/core/i18n.js +4 -0
- package/dist/core/validators.js +39 -32
- package/dist/css/components.css +18 -7
- package/dist/custom-elements.json +33 -2
- package/dist/overlay.d.ts +1 -1
- package/dist/overlay.js +20 -20
- package/dist/tokens.css +18 -7
- package/dist/vscode.html-custom-data.json +5 -1
- package/dist/web-types.json +8 -3
- package/package.json +1 -1
|
@@ -167,7 +167,7 @@ let p = class extends E {
|
|
|
167
167
|
return o`<div class="baht-bar-chart-row">
|
|
168
168
|
<span class="baht-bar-chart-label" title=${y}>${y}</span>
|
|
169
169
|
<div
|
|
170
|
-
class="baht-bar-chart-track${this.stacked ? " baht-bar-chart-track--stacked" : ""}"
|
|
170
|
+
class="baht-bar-chart-track${this.stacked ? " baht-bar-chart-track--stacked" : ""}${this.categoryMarkers(y).length > 0 ? " baht-bar-chart-track--marked" : ""}"
|
|
171
171
|
tabindex="0"
|
|
172
172
|
role="button"
|
|
173
173
|
aria-label=${u}
|
|
@@ -25,6 +25,18 @@ export declare class BahtLineChart extends BahtChartBase {
|
|
|
25
25
|
labelValues: 'ends' | 'none';
|
|
26
26
|
/** Accessible summary; falls back to a generated sentence. */
|
|
27
27
|
label: string;
|
|
28
|
+
/**
|
|
29
|
+
* Drawing width in SVG units. It follows the host up to `W`, so on a phone
|
|
30
|
+
* one unit is one CSS pixel and tick text keeps its real size instead of
|
|
31
|
+
* shrinking with a 640-wide drawing scaled into a 360px card.
|
|
32
|
+
*/
|
|
33
|
+
private width;
|
|
34
|
+
private resizeObserver;
|
|
35
|
+
connectedCallback(): void;
|
|
36
|
+
disconnectedCallback(): void;
|
|
37
|
+
protected firstUpdated(): void;
|
|
38
|
+
/** Host width → drawing width. Never runs on the server (`hasDom` guard). */
|
|
39
|
+
private measure;
|
|
28
40
|
private get plot();
|
|
29
41
|
protected render(): TemplateResult;
|
|
30
42
|
private crosshairAt;
|
|
@@ -1,151 +1,176 @@
|
|
|
1
|
-
import { html as
|
|
2
|
-
import { property as
|
|
3
|
-
import { arr as
|
|
4
|
-
import { BahtChartBase as
|
|
5
|
-
var U = Object.defineProperty,
|
|
6
|
-
for (var
|
|
7
|
-
(
|
|
8
|
-
return
|
|
1
|
+
import { html as _, nothing as y, svg as l } from "lit";
|
|
2
|
+
import { property as x, state as H, customElement as N } from "lit/decorators.js";
|
|
3
|
+
import { hasDom as k, arr as L } from "../base.js";
|
|
4
|
+
import { BahtChartBase as W, niceTicks as q, linearScale as O, chartColor as g, renderTableTwin as R } from "./charts.js";
|
|
5
|
+
var U = Object.defineProperty, V = Object.getOwnPropertyDescriptor, c = (o, s, $, r) => {
|
|
6
|
+
for (var d = r > 1 ? void 0 : r ? V(s, $) : s, f = o.length - 1, b; f >= 0; f--)
|
|
7
|
+
(b = o[f]) && (d = (r ? b(s, $, d) : b(d)) || d);
|
|
8
|
+
return r && d && U(s, $, d), d;
|
|
9
9
|
};
|
|
10
|
-
const
|
|
11
|
-
let h = class extends
|
|
10
|
+
const T = 640, X = 280, A = 260, I = 56, a = { top: 14, right: 72, bottom: 30, left: 60 };
|
|
11
|
+
let h = class extends W {
|
|
12
12
|
constructor() {
|
|
13
|
-
super(...arguments), this.series = [], this.categories = [], this.area = !1, this.markers = [], this.forecast = 0, this.baseline = null, this.labelValues = "ends", this.label = "", this.crosshairAt = null;
|
|
13
|
+
super(...arguments), this.series = [], this.categories = [], this.area = !1, this.markers = [], this.forecast = 0, this.baseline = null, this.labelValues = "ends", this.label = "", this.width = T, this.crosshairAt = null;
|
|
14
|
+
}
|
|
15
|
+
connectedCallback() {
|
|
16
|
+
super.connectedCallback(), !(!k() || typeof ResizeObserver > "u") && (this.resizeObserver = new ResizeObserver(() => {
|
|
17
|
+
this.measure();
|
|
18
|
+
}), this.resizeObserver.observe(this));
|
|
19
|
+
}
|
|
20
|
+
disconnectedCallback() {
|
|
21
|
+
var o;
|
|
22
|
+
(o = this.resizeObserver) == null || o.disconnect(), this.resizeObserver = void 0, super.disconnectedCallback();
|
|
23
|
+
}
|
|
24
|
+
firstUpdated() {
|
|
25
|
+
k() && queueMicrotask(() => {
|
|
26
|
+
this.measure();
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/** Host width → drawing width. Never runs on the server (`hasDom` guard). */
|
|
30
|
+
measure() {
|
|
31
|
+
if (!k() || !this.isConnected) return;
|
|
32
|
+
const o = this.clientWidth;
|
|
33
|
+
if (o <= 0) return;
|
|
34
|
+
const s = Math.min(T, Math.max(X, Math.round(o)));
|
|
35
|
+
s !== this.width && (this.width = s);
|
|
14
36
|
}
|
|
15
37
|
get plot() {
|
|
16
|
-
return { w:
|
|
38
|
+
return { w: this.width - a.left - a.right, h: A - a.top - a.bottom };
|
|
17
39
|
}
|
|
18
40
|
render() {
|
|
19
|
-
const
|
|
20
|
-
series:
|
|
21
|
-
categories:
|
|
22
|
-
}), { series:
|
|
23
|
-
if (
|
|
24
|
-
return
|
|
25
|
-
const
|
|
41
|
+
const o = this.hold({
|
|
42
|
+
series: L(this.series).filter((t) => t.values.length > 0),
|
|
43
|
+
categories: L(this.categories)
|
|
44
|
+
}), { series: s, categories: $ } = o;
|
|
45
|
+
if (s.length === 0)
|
|
46
|
+
return _`<div class=${this.rootClass("baht-line-chart")}>${this.renderEmpty()}</div>`;
|
|
47
|
+
const r = Math.max(...s.map((t) => t.values.length)), d = s.flatMap((t) => t.values).filter((t) => Number.isFinite(t)), f = Math.max(0, ...d, ...this.markers.map((t) => t.value)), b = q(f, 4), z = b[b.length - 1] ?? 1, { w: v, h: F } = this.plot, p = O([0, Math.max(1, r - 1)], [a.left, a.left + v]), i = O([0, z], [a.top + F, a.top]), M = Math.max(0, r - 1 - Math.max(0, this.forecast)), w = (t, e, n) => t.slice(e, n + 1).map((u, m) => `${m === 0 ? "M" : "L"}${p(e + m).toFixed(2)},${i(u).toFixed(2)}`).join(" "), P = s.map((t, e) => ({
|
|
26
48
|
i: e,
|
|
27
49
|
name: t.name,
|
|
28
50
|
value: t.values[t.values.length - 1] ?? 0,
|
|
29
|
-
yPos:
|
|
51
|
+
yPos: i(t.values[t.values.length - 1] ?? 0),
|
|
30
52
|
color: g(e, t.color)
|
|
31
|
-
})),
|
|
32
|
-
return
|
|
53
|
+
})), C = [...P].sort((t, e) => t.yPos - e.yPos), B = C.some((t, e) => e > 0 && t.yPos - C[e - 1].yPos < 15), j = this.labelValues === "ends" && !B, D = Math.max(1, Math.ceil(r / Math.max(2, Math.min(8, Math.floor(v / I))))), E = this.label || `Line chart, ${s.length} series over ${r} points. ${s.map((t, e) => `${t.name}: ${this.fmt(P[e].value)} at the end`).join(". ")}`;
|
|
54
|
+
return _`<div class=${this.rootClass("baht-line-chart")}>
|
|
33
55
|
<svg
|
|
34
56
|
class="baht-chart-svg"
|
|
35
|
-
viewBox="0 0 ${
|
|
57
|
+
viewBox="0 0 ${this.width} ${A}"
|
|
36
58
|
preserveAspectRatio="xMidYMid meet"
|
|
37
59
|
role="img"
|
|
38
|
-
aria-label=${
|
|
60
|
+
aria-label=${E}
|
|
39
61
|
>
|
|
40
|
-
${
|
|
62
|
+
${b.map(
|
|
41
63
|
(t) => l`
|
|
42
|
-
<line class="baht-chart-grid-line" x1=${
|
|
43
|
-
y1=${
|
|
44
|
-
<text class="baht-chart-tick" x=${
|
|
64
|
+
<line class="baht-chart-grid-line" x1=${a.left} x2=${a.left + v}
|
|
65
|
+
y1=${i(t).toFixed(2)} y2=${i(t).toFixed(2)}/>
|
|
66
|
+
<text class="baht-chart-tick" x=${a.left - 8} y=${(i(t) + 4).toFixed(2)}
|
|
45
67
|
text-anchor="end">${this.fmt(t)}</text>`
|
|
46
68
|
)}
|
|
47
69
|
${this.baseline != null ? [
|
|
48
|
-
l`<line class="baht-chart-baseline" x1=${
|
|
49
|
-
y1=${
|
|
70
|
+
l`<line class="baht-chart-baseline" x1=${a.left} x2=${a.left + v}
|
|
71
|
+
y1=${i(this.baseline).toFixed(2)} y2=${i(this.baseline).toFixed(2)}/>`
|
|
50
72
|
] : []}
|
|
51
|
-
${
|
|
73
|
+
${L(this.markers).map(
|
|
52
74
|
(t) => l`
|
|
53
|
-
<line class="baht-chart-marker-line" x1=${
|
|
54
|
-
y1=${
|
|
55
|
-
<text class="baht-chart-marker-label" x=${
|
|
75
|
+
<line class="baht-chart-marker-line" x1=${a.left} x2=${a.left + v}
|
|
76
|
+
y1=${i(t.value).toFixed(2)} y2=${i(t.value).toFixed(2)}/>
|
|
77
|
+
<text class="baht-chart-marker-label" x=${a.left + v} y=${(i(t.value) - 5).toFixed(2)}
|
|
56
78
|
text-anchor="end">${t.label ?? this.fmt(t.value)}</text>`
|
|
57
79
|
)}
|
|
58
|
-
${this.area &&
|
|
59
|
-
d=${`${
|
|
60
|
-
${
|
|
61
|
-
const
|
|
62
|
-
l`<path class="baht-chart-line" d=${
|
|
80
|
+
${this.area && s.length === 1 ? l`<path class="baht-chart-area" fill=${g(0, s[0].color)}
|
|
81
|
+
d=${`${w(s[0].values, 0, r - 1)} L${p(r - 1).toFixed(2)},${i(0).toFixed(2)} L${p(0).toFixed(2)},${i(0).toFixed(2)} Z`}/>` : y}
|
|
82
|
+
${s.map((t, e) => {
|
|
83
|
+
const n = g(e, t.color), u = [
|
|
84
|
+
l`<path class="baht-chart-line" d=${w(t.values, 0, M)} stroke=${n} fill="none"/>`
|
|
63
85
|
];
|
|
64
|
-
return M <
|
|
65
|
-
l`<path class="baht-chart-line baht-chart-line--forecast" d=${
|
|
66
|
-
stroke=${
|
|
67
|
-
),
|
|
68
|
-
l`<circle class="baht-chart-end-dot" cx=${
|
|
69
|
-
cy=${
|
|
70
|
-
),
|
|
86
|
+
return M < r - 1 && u.push(
|
|
87
|
+
l`<path class="baht-chart-line baht-chart-line--forecast" d=${w(t.values, M, r - 1)}
|
|
88
|
+
stroke=${n} fill="none"/>`
|
|
89
|
+
), u.push(
|
|
90
|
+
l`<circle class="baht-chart-end-dot" cx=${p(r - 1).toFixed(2)}
|
|
91
|
+
cy=${i(t.values[t.values.length - 1] ?? 0).toFixed(2)} r="4" fill=${n}/>`
|
|
92
|
+
), u;
|
|
71
93
|
})}
|
|
72
|
-
${
|
|
94
|
+
${j ? P.map(
|
|
73
95
|
(t) => l`
|
|
74
|
-
<text class="baht-chart-end-label" x=${
|
|
96
|
+
<text class="baht-chart-end-label" x=${p(r - 1) + 10} y=${(t.yPos + 4).toFixed(2)}
|
|
75
97
|
text-anchor="start">${this.fmt(t.value)}</text>`
|
|
76
98
|
) : y}
|
|
77
|
-
${
|
|
78
|
-
(t, e) => e %
|
|
99
|
+
${$.map(
|
|
100
|
+
(t, e) => e % D === 0 ? l`<text class="baht-chart-tick" x=${p(e).toFixed(2)} y=${A - 10} text-anchor="middle">${t}</text>` : y
|
|
79
101
|
)}
|
|
80
|
-
${Array.from({ length:
|
|
81
|
-
const
|
|
82
|
-
return l`<rect class="baht-chart-hit" x=${(
|
|
83
|
-
width=${Math.max(24,
|
|
84
|
-
aria-label=${
|
|
85
|
-
@pointermove=${(
|
|
86
|
-
this.onHover(
|
|
102
|
+
${Array.from({ length: r }, (t, e) => {
|
|
103
|
+
const n = v / Math.max(1, r - 1), u = `${$[e] ?? `Point ${e + 1}`}: ${s.map((m) => `${m.name} ${this.fmt(m.values[e] ?? 0)}`).join(", ")}`;
|
|
104
|
+
return l`<rect class="baht-chart-hit" x=${(p(e) - n / 2).toFixed(2)} y=${a.top}
|
|
105
|
+
width=${Math.max(24, n).toFixed(2)} height=${F} tabindex="0" role="button"
|
|
106
|
+
aria-label=${u}
|
|
107
|
+
@pointermove=${(m) => {
|
|
108
|
+
this.onHover(m, e, u);
|
|
87
109
|
}}
|
|
88
110
|
@pointerleave=${() => {
|
|
89
111
|
this.onLeave();
|
|
90
112
|
}}
|
|
91
|
-
@focus=${(
|
|
92
|
-
this.onHover(
|
|
113
|
+
@focus=${(m) => {
|
|
114
|
+
this.onHover(m, e, u);
|
|
93
115
|
}}
|
|
94
116
|
@blur=${() => {
|
|
95
117
|
this.onLeave();
|
|
96
118
|
}}/>`;
|
|
97
119
|
})}
|
|
98
|
-
${this.crosshairAt != null ? l`<line class="baht-chart-crosshair" x1=${
|
|
99
|
-
x2=${
|
|
120
|
+
${this.crosshairAt != null ? l`<line class="baht-chart-crosshair" x1=${p(this.crosshairAt).toFixed(2)}
|
|
121
|
+
x2=${p(this.crosshairAt).toFixed(2)} y1=${a.top} y2=${a.top + F}/>` : y}
|
|
100
122
|
</svg>
|
|
101
123
|
${this.renderTooltip()}
|
|
102
124
|
${this.renderLegend(
|
|
103
|
-
|
|
125
|
+
s.map((t, e) => ({ label: t.name, color: g(e, t.color) })),
|
|
104
126
|
"line"
|
|
105
127
|
)}
|
|
106
|
-
${this.showTable ?
|
|
128
|
+
${this.showTable ? R(
|
|
107
129
|
this.label || "Line chart data",
|
|
108
|
-
["Point", ...
|
|
109
|
-
Array.from({ length:
|
|
110
|
-
|
|
111
|
-
...
|
|
130
|
+
["Point", ...s.map((t) => t.name)],
|
|
131
|
+
Array.from({ length: r }, (t, e) => [
|
|
132
|
+
$[e] ?? `Point ${e + 1}`,
|
|
133
|
+
...s.map((n) => this.fmt(n.values[e] ?? 0))
|
|
112
134
|
])
|
|
113
135
|
) : y}
|
|
114
136
|
</div>`;
|
|
115
137
|
}
|
|
116
|
-
onHover(
|
|
117
|
-
this.crosshairAt =
|
|
138
|
+
onHover(o, s, $) {
|
|
139
|
+
this.crosshairAt = s, this.requestUpdate(), this.showTip(o, $);
|
|
118
140
|
}
|
|
119
141
|
onLeave() {
|
|
120
142
|
this.crosshairAt = null, this.requestUpdate(), this.hideTip();
|
|
121
143
|
}
|
|
122
144
|
};
|
|
123
|
-
|
|
124
|
-
|
|
145
|
+
c([
|
|
146
|
+
x({ attribute: !1 })
|
|
125
147
|
], h.prototype, "series", 2);
|
|
126
|
-
|
|
127
|
-
|
|
148
|
+
c([
|
|
149
|
+
x({ attribute: !1 })
|
|
128
150
|
], h.prototype, "categories", 2);
|
|
129
|
-
|
|
130
|
-
|
|
151
|
+
c([
|
|
152
|
+
x({ type: Boolean })
|
|
131
153
|
], h.prototype, "area", 2);
|
|
132
|
-
|
|
133
|
-
|
|
154
|
+
c([
|
|
155
|
+
x({ attribute: !1 })
|
|
134
156
|
], h.prototype, "markers", 2);
|
|
135
|
-
|
|
136
|
-
|
|
157
|
+
c([
|
|
158
|
+
x({ type: Number })
|
|
137
159
|
], h.prototype, "forecast", 2);
|
|
138
|
-
|
|
139
|
-
|
|
160
|
+
c([
|
|
161
|
+
x({ type: Number })
|
|
140
162
|
], h.prototype, "baseline", 2);
|
|
141
|
-
|
|
142
|
-
|
|
163
|
+
c([
|
|
164
|
+
x({ attribute: "label-values" })
|
|
143
165
|
], h.prototype, "labelValues", 2);
|
|
144
|
-
|
|
145
|
-
|
|
166
|
+
c([
|
|
167
|
+
x()
|
|
146
168
|
], h.prototype, "label", 2);
|
|
147
|
-
|
|
148
|
-
|
|
169
|
+
c([
|
|
170
|
+
H()
|
|
171
|
+
], h.prototype, "width", 2);
|
|
172
|
+
h = c([
|
|
173
|
+
N("baht-line-chart")
|
|
149
174
|
], h);
|
|
150
175
|
export {
|
|
151
176
|
h as BahtLineChart
|
|
@@ -16,6 +16,10 @@ export declare class BahtModal extends BahtElement {
|
|
|
16
16
|
/** One muted line under the heading; also becomes the dialog's aria-describedby. */
|
|
17
17
|
description: string;
|
|
18
18
|
showClose: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Scrim click requests close. Off by default: a stray click outside the panel
|
|
21
|
+
* must not throw away what the user typed — close via ×, Escape or your buttons.
|
|
22
|
+
*/
|
|
19
23
|
closeOnScrim: boolean;
|
|
20
24
|
private bodyEl;
|
|
21
25
|
private get titleId();
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import { nothing as a, html as h } from "lit";
|
|
2
|
-
import { property as c, query as f, state as
|
|
3
|
-
import { boolOff as
|
|
2
|
+
import { property as c, query as f, state as m, customElement as b } from "lit/decorators.js";
|
|
3
|
+
import { boolOff as y, BahtElement as v, hasDom as p, adoptLightChildren as u } from "../base.js";
|
|
4
4
|
import { afterExit as g } from "../motion.js";
|
|
5
5
|
import { t as $ } from "../../core/i18n.js";
|
|
6
6
|
import { renderIllustration as k } from "./illustrations.js";
|
|
7
|
-
var C = Object.defineProperty, S = Object.getOwnPropertyDescriptor,
|
|
8
|
-
for (var o = n > 1 ? void 0 : n ? S(i, e) : i,
|
|
9
|
-
(d = t[
|
|
7
|
+
var C = Object.defineProperty, S = Object.getOwnPropertyDescriptor, r = (t, i, e, n) => {
|
|
8
|
+
for (var o = n > 1 ? void 0 : n ? S(i, e) : i, l = t.length - 1, d; l >= 0; l--)
|
|
9
|
+
(d = t[l]) && (o = (n ? d(i, e, o) : d(o)) || o);
|
|
10
10
|
return n && o && C(i, e, o), o;
|
|
11
11
|
};
|
|
12
|
+
const E = {
|
|
13
|
+
fromAttribute: (t) => t !== null && t !== "false",
|
|
14
|
+
toAttribute: (t) => t ? "" : null
|
|
15
|
+
};
|
|
12
16
|
let s = class extends v {
|
|
13
17
|
constructor() {
|
|
14
|
-
super(...arguments), this.open = !1, this.heading = "", this.description = "", this.showClose = !0, this.closeOnScrim = !
|
|
18
|
+
super(...arguments), this.open = !1, this.heading = "", this.description = "", this.showClose = !0, this.closeOnScrim = !1, this.closing = !1, this.closeToken = 0, this.previousFocus = null, this.onKeydown = (t) => {
|
|
15
19
|
!this.open || s.openStack.at(-1) !== this || (t.key === "Escape" ? this.requestClose("escape") : t.key === "Tab" && this.trapFocus(t));
|
|
16
20
|
};
|
|
17
21
|
}
|
|
@@ -36,12 +40,12 @@ let s = class extends v {
|
|
|
36
40
|
e == null || e.focus(), t.preventDefault();
|
|
37
41
|
return;
|
|
38
42
|
}
|
|
39
|
-
const n = i[0], o = i[i.length - 1],
|
|
40
|
-
if (!this.contains(
|
|
43
|
+
const n = i[0], o = i[i.length - 1], l = document.activeElement;
|
|
44
|
+
if (!this.contains(l)) {
|
|
41
45
|
n.focus(), t.preventDefault();
|
|
42
46
|
return;
|
|
43
47
|
}
|
|
44
|
-
t.shiftKey && (
|
|
48
|
+
t.shiftKey && (l === n || l === e) ? (o.focus(), t.preventDefault()) : !t.shiftKey && l === o && (n.focus(), t.preventDefault());
|
|
45
49
|
}
|
|
46
50
|
connectedCallback() {
|
|
47
51
|
super.connectedCallback(), p() && document.addEventListener("keydown", this.onKeydown);
|
|
@@ -110,29 +114,29 @@ let s = class extends v {
|
|
|
110
114
|
}
|
|
111
115
|
};
|
|
112
116
|
s.openStack = [];
|
|
113
|
-
|
|
117
|
+
r([
|
|
114
118
|
c({ type: Boolean, reflect: !0 })
|
|
115
119
|
], s.prototype, "open", 2);
|
|
116
|
-
|
|
120
|
+
r([
|
|
117
121
|
c()
|
|
118
122
|
], s.prototype, "heading", 2);
|
|
119
|
-
|
|
123
|
+
r([
|
|
120
124
|
c()
|
|
121
125
|
], s.prototype, "description", 2);
|
|
122
|
-
|
|
123
|
-
c({ attribute: "show-close", converter:
|
|
126
|
+
r([
|
|
127
|
+
c({ attribute: "show-close", converter: y })
|
|
124
128
|
], s.prototype, "showClose", 2);
|
|
125
|
-
|
|
126
|
-
c({ attribute: "close-on-scrim", converter:
|
|
129
|
+
r([
|
|
130
|
+
c({ attribute: "close-on-scrim", converter: E })
|
|
127
131
|
], s.prototype, "closeOnScrim", 2);
|
|
128
|
-
|
|
132
|
+
r([
|
|
129
133
|
f(".baht-modal-body")
|
|
130
134
|
], s.prototype, "bodyEl", 2);
|
|
131
|
-
|
|
132
|
-
|
|
135
|
+
r([
|
|
136
|
+
m()
|
|
133
137
|
], s.prototype, "closing", 2);
|
|
134
|
-
s =
|
|
135
|
-
|
|
138
|
+
s = r([
|
|
139
|
+
b("baht-modal")
|
|
136
140
|
], s);
|
|
137
141
|
export {
|
|
138
142
|
s as BahtModal
|
package/dist/core/i18n.d.ts
CHANGED
|
@@ -28,6 +28,10 @@ export interface MessageCatalog {
|
|
|
28
28
|
removeRow: string;
|
|
29
29
|
minRows: string;
|
|
30
30
|
maxRows: string;
|
|
31
|
+
/** `min_rows: 1`, where "{n} rows" would read "1 rows". */
|
|
32
|
+
minRowsOne: string;
|
|
33
|
+
/** `max_rows: 1`. */
|
|
34
|
+
maxRowsOne: string;
|
|
31
35
|
next: string;
|
|
32
36
|
submit: string;
|
|
33
37
|
back: string;
|
package/dist/core/i18n.js
CHANGED
|
@@ -28,6 +28,8 @@ const n = {
|
|
|
28
28
|
removeRow: "Remove row",
|
|
29
29
|
minRows: "Add at least {n} rows",
|
|
30
30
|
maxRows: "Add at most {n} rows",
|
|
31
|
+
minRowsOne: "Add at least one row",
|
|
32
|
+
maxRowsOne: "Add at most one row",
|
|
31
33
|
next: "Next",
|
|
32
34
|
submit: "Submit",
|
|
33
35
|
back: "Back",
|
|
@@ -93,6 +95,8 @@ const n = {
|
|
|
93
95
|
removeRow: "ลบแถว",
|
|
94
96
|
minRows: "ต้องมีอย่างน้อย {n} แถว",
|
|
95
97
|
maxRows: "ต้องไม่เกิน {n} แถว",
|
|
98
|
+
minRowsOne: "ต้องมีอย่างน้อย 1 แถว",
|
|
99
|
+
maxRowsOne: "ต้องไม่เกิน 1 แถว",
|
|
96
100
|
next: "ถัดไป",
|
|
97
101
|
submit: "ส่งข้อมูล",
|
|
98
102
|
back: "ย้อนกลับ",
|
package/dist/core/validators.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { defaultValue as
|
|
1
|
+
import { defaultValue as w } from "./defaults.js";
|
|
2
2
|
import { compareValues as k } from "./engine/conditions.js";
|
|
3
|
-
import { isoDaysOf as x, dateModeOf as
|
|
4
|
-
import { t as
|
|
3
|
+
import { isoDaysOf as x, dateModeOf as _, rangeInteriorDays as b, isDateDisabled as A } from "./dates.js";
|
|
4
|
+
import { t as i } from "./i18n.js";
|
|
5
5
|
const L = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
6
|
-
function
|
|
6
|
+
function l(e) {
|
|
7
7
|
return e == null ? !0 : typeof e == "string" ? e === "" : Array.isArray(e) ? e.length === 0 : typeof e == "boolean" ? !e : !1;
|
|
8
8
|
}
|
|
9
9
|
function d(e) {
|
|
@@ -16,14 +16,14 @@ function h(e, t) {
|
|
|
16
16
|
const r = Number(n.value);
|
|
17
17
|
return Number.isNaN(r) ? (console.warn(
|
|
18
18
|
`[bahtui] ${t} validator has non-numeric value ${JSON.stringify(n.value)} — skipped`
|
|
19
|
-
), null) : typeof s != "string" ? null : (e === "minLength" ? s.length < r : s.length > r) ? n.message ??
|
|
19
|
+
), null) : typeof s != "string" ? null : (e === "minLength" ? s.length < r : s.length > r) ? n.message ?? i(e, { n: n.value }) : null;
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
function f(e) {
|
|
23
23
|
return (t, n) => E(n).some((r) => {
|
|
24
24
|
const o = k(r, t.value);
|
|
25
25
|
return o !== null && (e === "min" ? o < 0 : o > 0);
|
|
26
|
-
}) ? t.message ??
|
|
26
|
+
}) ? t.message ?? i(e, { n: t.value }) : null;
|
|
27
27
|
}
|
|
28
28
|
const C = {
|
|
29
29
|
eq: (e) => e === 0,
|
|
@@ -32,39 +32,39 @@ const C = {
|
|
|
32
32
|
gte: (e) => e >= 0,
|
|
33
33
|
lt: (e) => e < 0,
|
|
34
34
|
lte: (e) => e <= 0
|
|
35
|
-
},
|
|
35
|
+
}, R = (e, t, n, s) => {
|
|
36
36
|
const r = s == null ? void 0 : s[e.field ?? ""];
|
|
37
|
-
if (r === void 0 ||
|
|
37
|
+
if (r === void 0 || l(r)) return null;
|
|
38
38
|
const o = k(t, r);
|
|
39
39
|
if (o === null) return null;
|
|
40
40
|
const a = e.op ?? "eq";
|
|
41
41
|
if (C[a](o)) return null;
|
|
42
42
|
const m = `compare${a[0].toUpperCase()}${a.slice(1)}`;
|
|
43
|
-
return e.message ??
|
|
44
|
-
},
|
|
43
|
+
return e.message ?? i(m, { other: e.field });
|
|
44
|
+
}, $ = (e, t) => {
|
|
45
45
|
if (typeof t != "string") return null;
|
|
46
46
|
const n = D(String(e.value));
|
|
47
|
-
return n ? n.test(t) ? null : e.message ??
|
|
48
|
-
},
|
|
47
|
+
return n ? n.test(t) ? null : e.message ?? i("pattern") : null;
|
|
48
|
+
}, O = (e, t, n) => {
|
|
49
49
|
var o;
|
|
50
50
|
const s = (o = n == null ? void 0 : n.validators) == null ? void 0 : o[e.fn ?? ""];
|
|
51
51
|
if (!s)
|
|
52
52
|
return console.warn(`[bahtui] unknown custom validator "${e.fn}" — skipped`), null;
|
|
53
53
|
const r = s(t);
|
|
54
54
|
return r === null ? null : e.message ?? r;
|
|
55
|
-
},
|
|
56
|
-
required: (e, t) =>
|
|
55
|
+
}, q = {
|
|
56
|
+
required: (e, t) => l(t) ? e.message ?? i("required") : null,
|
|
57
57
|
minLength: h("minLength", "min_length"),
|
|
58
58
|
maxLength: h("maxLength", "max_length"),
|
|
59
59
|
min: f("min"),
|
|
60
60
|
max: f("max"),
|
|
61
|
-
pattern:
|
|
62
|
-
email: (e, t) => typeof t == "string" && !L.test(t) ? e.message ??
|
|
63
|
-
compare:
|
|
64
|
-
custom:
|
|
61
|
+
pattern: $,
|
|
62
|
+
email: (e, t) => typeof t == "string" && !L.test(t) ? e.message ?? i("email") : null,
|
|
63
|
+
compare: R,
|
|
64
|
+
custom: O
|
|
65
65
|
};
|
|
66
|
-
function
|
|
67
|
-
return
|
|
66
|
+
function N(e, t, n, s) {
|
|
67
|
+
return q[e.type](e, t, n, s);
|
|
68
68
|
}
|
|
69
69
|
const g = /* @__PURE__ */ new Map();
|
|
70
70
|
function D(e) {
|
|
@@ -80,10 +80,10 @@ function D(e) {
|
|
|
80
80
|
return t;
|
|
81
81
|
}
|
|
82
82
|
function S(e, t, n, s) {
|
|
83
|
-
const r = [], o = d(e), a =
|
|
83
|
+
const r = [], o = d(e), a = l(t);
|
|
84
84
|
for (const m of o) {
|
|
85
85
|
if (m.type !== "required" && a) continue;
|
|
86
|
-
const c =
|
|
86
|
+
const c = N(m, t, n, s);
|
|
87
87
|
c !== null && r.push({ key: e.key, message: c });
|
|
88
88
|
}
|
|
89
89
|
return e.type === "repeater" && r.push(...V(e, t, n)), e.type === "file" && r.push(...T(e, t)), e.type === "date" && !a && r.push(...M(e, t)), r;
|
|
@@ -92,7 +92,7 @@ function M(e, t) {
|
|
|
92
92
|
var s, r;
|
|
93
93
|
if (!((s = e.disabled_dates) != null && s.length) && !((r = e.disabled_weekdays) != null && r.length)) return [];
|
|
94
94
|
const n = x(t);
|
|
95
|
-
return
|
|
95
|
+
return _(e) === "range" && n.length === 2 && n.push(...b(n[0], n[1])), n.some((o) => A(e, o)) ? [{ key: e.key, message: i("dateDisabled") }] : [];
|
|
96
96
|
}
|
|
97
97
|
function P(e) {
|
|
98
98
|
return e !== null && typeof e == "object" && typeof e.url == "string" && typeof e.size == "number" && typeof e.name == "string";
|
|
@@ -106,22 +106,29 @@ function z(e, t, n) {
|
|
|
106
106
|
function T(e, t) {
|
|
107
107
|
const n = (Array.isArray(t) ? t : [t]).filter(P), s = [];
|
|
108
108
|
for (const r of n)
|
|
109
|
-
e.max_size !== void 0 && r.size > e.max_size && s.push({ key: e.key, message:
|
|
109
|
+
e.max_size !== void 0 && r.size > e.max_size && s.push({ key: e.key, message: i("fileTooLarge") }), e.accept && !z(e.accept, r.name, r.type ?? "") && s.push({ key: e.key, message: i("fileTypeNotAllowed") });
|
|
110
110
|
return s;
|
|
111
111
|
}
|
|
112
112
|
function V(e, t, n) {
|
|
113
113
|
if (t != null && !Array.isArray(t))
|
|
114
|
-
return [{ key: e.key, message:
|
|
114
|
+
return [{ key: e.key, message: i("pattern") }];
|
|
115
115
|
const s = Array.isArray(t) ? t : [], r = [];
|
|
116
|
-
e.min_rows !== void 0 && s.length < e.min_rows
|
|
116
|
+
if (e.min_rows !== void 0 && s.length < e.min_rows) {
|
|
117
|
+
const a = e.min_rows === 1 ? i("minRowsOne") : i("minRows", { n: e.min_rows });
|
|
118
|
+
r.push({ key: e.key, message: a });
|
|
119
|
+
}
|
|
120
|
+
if (e.max_rows !== void 0 && s.length > e.max_rows) {
|
|
121
|
+
const a = e.max_rows === 1 ? i("maxRowsOne") : i("maxRows", { n: e.max_rows });
|
|
122
|
+
r.push({ key: e.key, message: a });
|
|
123
|
+
}
|
|
117
124
|
const o = [...e.fields ?? []].sort((a, m) => a.order - m.order);
|
|
118
125
|
return s.forEach((a, m) => {
|
|
119
|
-
const c = a !== null && typeof a == "object" && !Array.isArray(a) ? a : {},
|
|
120
|
-
for (const
|
|
121
|
-
|
|
122
|
-
for (const
|
|
123
|
-
if (!(
|
|
124
|
-
for (const y of S(
|
|
126
|
+
const c = a !== null && typeof a == "object" && !Array.isArray(a) ? a : {}, p = {};
|
|
127
|
+
for (const u of o)
|
|
128
|
+
u.type === "label" || u.type === "section" || u.type === "repeater" || (p[u.key] = Object.hasOwn(c, u.key) ? c[u.key] : w(u));
|
|
129
|
+
for (const u of o)
|
|
130
|
+
if (!(u.type === "label" || u.type === "section" || u.type === "repeater"))
|
|
131
|
+
for (const y of S(u, p[u.key], n, p))
|
|
125
132
|
r.push({ key: `${e.key}[${m}].${y.key}`, message: y.message });
|
|
126
133
|
}), r;
|
|
127
134
|
}
|
package/dist/css/components.css
CHANGED
|
@@ -396,6 +396,10 @@
|
|
|
396
396
|
display: flex;
|
|
397
397
|
align-items: center;
|
|
398
398
|
gap: var(--baht-space-2);
|
|
399
|
+
/* A narrow card (a 1/4 option width in a phone-width form) drops the label
|
|
400
|
+
under its icon instead of pushing it past the card edge into the next one. */
|
|
401
|
+
flex-wrap: wrap;
|
|
402
|
+
min-width: 0;
|
|
399
403
|
}
|
|
400
404
|
/* `option.width` — same fractions as `field.width`, against the card row's
|
|
401
405
|
own gap (`--baht-space-3`) instead of the form grid's `--baht-field-gap`,
|
|
@@ -407,6 +411,7 @@
|
|
|
407
411
|
.baht-option-card--w-1-4 {
|
|
408
412
|
flex: 0 0 calc(25% - var(--baht-space-3) * 3 / 4);
|
|
409
413
|
min-width: 0;
|
|
414
|
+
padding-inline: var(--baht-space-3);
|
|
410
415
|
}
|
|
411
416
|
.baht-option-card--w-1-2 {
|
|
412
417
|
flex: 0 0 calc(50% - var(--baht-space-3) / 2);
|
|
@@ -449,6 +454,11 @@
|
|
|
449
454
|
.baht-option-card-title {
|
|
450
455
|
font-weight: 600;
|
|
451
456
|
color: var(--baht-color-text);
|
|
457
|
+
/* Last resort when even its own line is too narrow: clip, never overflow. */
|
|
458
|
+
min-width: 0;
|
|
459
|
+
max-width: 100%;
|
|
460
|
+
overflow: hidden;
|
|
461
|
+
text-overflow: ellipsis;
|
|
452
462
|
}
|
|
453
463
|
.baht-option-card-desc {
|
|
454
464
|
font-size: var(--baht-text-sm);
|
|
@@ -2546,16 +2556,17 @@ code.baht-code {
|
|
|
2546
2556
|
vertical-align: middle;
|
|
2547
2557
|
background: var(--baht-color-text-muted);
|
|
2548
2558
|
}
|
|
2549
|
-
/* A row
|
|
2550
|
-
never
|
|
2559
|
+
/* A row with its own marker (a budget line) gets a caption lane above its
|
|
2560
|
+
bars: the label sits there beside its line and never covers a bar or the
|
|
2561
|
+
bar's value. */
|
|
2562
|
+
.baht-bar-chart-track--marked {
|
|
2563
|
+
padding-top: 1.1rem;
|
|
2564
|
+
}
|
|
2551
2565
|
.baht-bar-chart-marker-label--row {
|
|
2552
|
-
top:
|
|
2566
|
+
top: 0;
|
|
2553
2567
|
bottom: auto;
|
|
2554
2568
|
z-index: 2;
|
|
2555
|
-
|
|
2556
|
-
background: var(--baht-chart-surface);
|
|
2557
|
-
padding: 0 4px;
|
|
2558
|
-
border-radius: var(--baht-radius-xs);
|
|
2569
|
+
padding: 0 2px;
|
|
2559
2570
|
}
|
|
2560
2571
|
.baht-bar-chart-marker-label--row::before {
|
|
2561
2572
|
display: none; /* the line it names is right beside it */
|
|
@@ -10100,6 +10100,35 @@
|
|
|
10100
10100
|
"description": "Accessible summary; falls back to a generated sentence.",
|
|
10101
10101
|
"attribute": "label"
|
|
10102
10102
|
},
|
|
10103
|
+
{
|
|
10104
|
+
"kind": "field",
|
|
10105
|
+
"name": "width",
|
|
10106
|
+
"privacy": "private",
|
|
10107
|
+
"default": "640",
|
|
10108
|
+
"description": "Drawing width in SVG units. It follows the host up to `W`, so on a phone\none unit is one CSS pixel and tick text keeps its real size instead of\nshrinking with a 640-wide drawing scaled into a 360px card.",
|
|
10109
|
+
"type": {
|
|
10110
|
+
"text": "number"
|
|
10111
|
+
}
|
|
10112
|
+
},
|
|
10113
|
+
{
|
|
10114
|
+
"kind": "field",
|
|
10115
|
+
"name": "resizeObserver",
|
|
10116
|
+
"type": {
|
|
10117
|
+
"text": "ResizeObserver | undefined"
|
|
10118
|
+
},
|
|
10119
|
+
"privacy": "private"
|
|
10120
|
+
},
|
|
10121
|
+
{
|
|
10122
|
+
"kind": "method",
|
|
10123
|
+
"name": "measure",
|
|
10124
|
+
"privacy": "private",
|
|
10125
|
+
"return": {
|
|
10126
|
+
"type": {
|
|
10127
|
+
"text": "void"
|
|
10128
|
+
}
|
|
10129
|
+
},
|
|
10130
|
+
"description": "Host width → drawing width. Never runs on the server (`hasDom` guard)."
|
|
10131
|
+
},
|
|
10103
10132
|
{
|
|
10104
10133
|
"kind": "field",
|
|
10105
10134
|
"name": "plot",
|
|
@@ -11548,7 +11577,8 @@
|
|
|
11548
11577
|
"type": {
|
|
11549
11578
|
"text": "boolean"
|
|
11550
11579
|
},
|
|
11551
|
-
"default": "
|
|
11580
|
+
"default": "false",
|
|
11581
|
+
"description": "Scrim click requests close. Off by default: a stray click outside the panel\nmust not throw away what the user typed — close via ×, Escape or your buttons.",
|
|
11552
11582
|
"attribute": "close-on-scrim"
|
|
11553
11583
|
},
|
|
11554
11584
|
{
|
|
@@ -11751,7 +11781,8 @@
|
|
|
11751
11781
|
"type": {
|
|
11752
11782
|
"text": "boolean"
|
|
11753
11783
|
},
|
|
11754
|
-
"default": "
|
|
11784
|
+
"default": "false",
|
|
11785
|
+
"description": "Scrim click requests close. Off by default: a stray click outside the panel\nmust not throw away what the user typed — close via ×, Escape or your buttons.",
|
|
11755
11786
|
"fieldName": "closeOnScrim"
|
|
11756
11787
|
},
|
|
11757
11788
|
{
|
package/dist/overlay.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export interface DialogOptions {
|
|
|
8
8
|
cancelText?: string;
|
|
9
9
|
/** Secondary monospace block under the message (error detail, payload, …). */
|
|
10
10
|
detail?: string;
|
|
11
|
-
/** Allow Escape
|
|
11
|
+
/** Allow Escape to cancel. Default true. A scrim click never cancels. */
|
|
12
12
|
dismissible?: boolean;
|
|
13
13
|
}
|
|
14
14
|
export interface PromptOptions extends DialogOptions {
|
package/dist/overlay.js
CHANGED
|
@@ -12,8 +12,8 @@ function p(e) {
|
|
|
12
12
|
return I(() => L(e));
|
|
13
13
|
}
|
|
14
14
|
async function L(e) {
|
|
15
|
-
const t = document.activeElement,
|
|
16
|
-
n.heading = e.title ?? "", n.showClose = !1, n.closeOnScrim =
|
|
15
|
+
const t = document.activeElement, r = e.dismissible !== !1, E = e.tone === "danger" ? "danger" : "primary", n = document.createElement("baht-modal");
|
|
16
|
+
n.heading = e.title ?? "", n.showClose = !1, n.closeOnScrim = !1;
|
|
17
17
|
const c = document.createElement("div");
|
|
18
18
|
c.className = `baht-dialog${e.tone ? ` baht-dialog--${e.tone}` : ""}`;
|
|
19
19
|
const b = document.createElement("p");
|
|
@@ -25,8 +25,8 @@ async function L(e) {
|
|
|
25
25
|
e.showInput && (a = document.createElement("input"), a.className = "baht-control baht-dialog-input", a.type = "text", a.value = e.value ?? "", e.placeholder && (a.placeholder = e.placeholder), c.appendChild(a));
|
|
26
26
|
const u = document.createElement("div");
|
|
27
27
|
u.className = "baht-dialog-actions";
|
|
28
|
-
let
|
|
29
|
-
e.showCancel && (
|
|
28
|
+
let o = null;
|
|
29
|
+
e.showCancel && (o = document.createElement("baht-button"), o.className = "baht-dialog-cancel", o.variant = "secondary", o.label = e.cancelText ?? "Cancel", u.appendChild(o));
|
|
30
30
|
const i = document.createElement("baht-button");
|
|
31
31
|
i.className = "baht-dialog-confirm", i.variant = E, i.label = e.confirmText ?? "OK", u.appendChild(i), c.appendChild(u), n.appendChild(c), document.body.appendChild(n), n.open = !0;
|
|
32
32
|
let h;
|
|
@@ -36,24 +36,24 @@ async function L(e) {
|
|
|
36
36
|
v.observe(document.documentElement, { childList: !0, subtree: !0 });
|
|
37
37
|
const g = await new Promise((d) => {
|
|
38
38
|
let C = !1;
|
|
39
|
-
const m = (
|
|
40
|
-
C || (C = !0, d(
|
|
39
|
+
const m = (s) => {
|
|
40
|
+
C || (C = !0, d(s));
|
|
41
41
|
};
|
|
42
42
|
h = () => {
|
|
43
43
|
m({ confirmed: !1, reason: "detached" });
|
|
44
44
|
}, i.addEventListener("click", () => {
|
|
45
45
|
m({ confirmed: !0, reason: "confirm", ...a ? { value: a.value } : {} });
|
|
46
|
-
}),
|
|
46
|
+
}), o == null || o.addEventListener("click", () => {
|
|
47
47
|
m({ confirmed: !1, reason: "cancel" });
|
|
48
|
-
}), n.addEventListener("baht-close", (
|
|
49
|
-
if (!
|
|
50
|
-
const x =
|
|
48
|
+
}), n.addEventListener("baht-close", (s) => {
|
|
49
|
+
if (!r) return;
|
|
50
|
+
const x = s.detail.reason;
|
|
51
51
|
m({ confirmed: !1, reason: x === "scrim" ? "scrim" : "escape" });
|
|
52
|
-
}), a == null || a.addEventListener("keydown", (
|
|
53
|
-
|
|
52
|
+
}), a == null || a.addEventListener("keydown", (s) => {
|
|
53
|
+
s.key === "Enter" && !s.isComposing && m({ confirmed: !0, reason: "confirm", value: s.target.value });
|
|
54
54
|
}), n.updateComplete.then(() => {
|
|
55
|
-
var
|
|
56
|
-
return (
|
|
55
|
+
var s;
|
|
56
|
+
return (s = a ?? i.querySelector("button")) == null ? void 0 : s.focus();
|
|
57
57
|
});
|
|
58
58
|
});
|
|
59
59
|
v.disconnect(), n.open = !1;
|
|
@@ -97,7 +97,7 @@ const P = {
|
|
|
97
97
|
},
|
|
98
98
|
/** Single text input. Resolves the value, or null on cancel/dismiss. */
|
|
99
99
|
async prompt(e, t = {}) {
|
|
100
|
-
const
|
|
100
|
+
const r = await p({
|
|
101
101
|
title: "Input needed",
|
|
102
102
|
confirmText: "OK",
|
|
103
103
|
...t,
|
|
@@ -105,14 +105,14 @@ const P = {
|
|
|
105
105
|
showCancel: !0,
|
|
106
106
|
showInput: !0
|
|
107
107
|
});
|
|
108
|
-
return
|
|
108
|
+
return r.confirmed ? r.value ?? "" : null;
|
|
109
109
|
}
|
|
110
110
|
};
|
|
111
|
-
let
|
|
111
|
+
let l = null;
|
|
112
112
|
function S() {
|
|
113
|
-
return
|
|
113
|
+
return l != null && l.isConnected || (l = document.querySelector("baht-toast") ?? document.body.appendChild(document.createElement("baht-toast"))), l;
|
|
114
114
|
}
|
|
115
|
-
const f = (e) => (t,
|
|
115
|
+
const f = (e) => (t, r = {}) => T.show(t, { ...r, tone: e }), T = {
|
|
116
116
|
show(e, t = {}) {
|
|
117
117
|
return S().show({ message: e, ...t });
|
|
118
118
|
},
|
|
@@ -121,7 +121,7 @@ const f = (e) => (t, s = {}) => T.show(t, { ...s, tone: e }), T = {
|
|
|
121
121
|
warning: f("warning"),
|
|
122
122
|
danger: f("danger"),
|
|
123
123
|
dismiss(e) {
|
|
124
|
-
|
|
124
|
+
l == null || l.dismiss(e);
|
|
125
125
|
}
|
|
126
126
|
};
|
|
127
127
|
export {
|
package/dist/tokens.css
CHANGED
|
@@ -830,6 +830,10 @@
|
|
|
830
830
|
display: flex;
|
|
831
831
|
align-items: center;
|
|
832
832
|
gap: var(--baht-space-2);
|
|
833
|
+
/* A narrow card (a 1/4 option width in a phone-width form) drops the label
|
|
834
|
+
under its icon instead of pushing it past the card edge into the next one. */
|
|
835
|
+
flex-wrap: wrap;
|
|
836
|
+
min-width: 0;
|
|
833
837
|
}
|
|
834
838
|
/* `option.width` — same fractions as `field.width`, against the card row's
|
|
835
839
|
own gap (`--baht-space-3`) instead of the form grid's `--baht-field-gap`,
|
|
@@ -841,6 +845,7 @@
|
|
|
841
845
|
.baht-option-card--w-1-4 {
|
|
842
846
|
flex: 0 0 calc(25% - var(--baht-space-3) * 3 / 4);
|
|
843
847
|
min-width: 0;
|
|
848
|
+
padding-inline: var(--baht-space-3);
|
|
844
849
|
}
|
|
845
850
|
.baht-option-card--w-1-2 {
|
|
846
851
|
flex: 0 0 calc(50% - var(--baht-space-3) / 2);
|
|
@@ -883,6 +888,11 @@
|
|
|
883
888
|
.baht-option-card-title {
|
|
884
889
|
font-weight: 600;
|
|
885
890
|
color: var(--baht-color-text);
|
|
891
|
+
/* Last resort when even its own line is too narrow: clip, never overflow. */
|
|
892
|
+
min-width: 0;
|
|
893
|
+
max-width: 100%;
|
|
894
|
+
overflow: hidden;
|
|
895
|
+
text-overflow: ellipsis;
|
|
886
896
|
}
|
|
887
897
|
.baht-option-card-desc {
|
|
888
898
|
font-size: var(--baht-text-sm);
|
|
@@ -2980,16 +2990,17 @@ code.baht-code {
|
|
|
2980
2990
|
vertical-align: middle;
|
|
2981
2991
|
background: var(--baht-color-text-muted);
|
|
2982
2992
|
}
|
|
2983
|
-
/* A row
|
|
2984
|
-
never
|
|
2993
|
+
/* A row with its own marker (a budget line) gets a caption lane above its
|
|
2994
|
+
bars: the label sits there beside its line and never covers a bar or the
|
|
2995
|
+
bar's value. */
|
|
2996
|
+
.baht-bar-chart-track--marked {
|
|
2997
|
+
padding-top: 1.1rem;
|
|
2998
|
+
}
|
|
2985
2999
|
.baht-bar-chart-marker-label--row {
|
|
2986
|
-
top:
|
|
3000
|
+
top: 0;
|
|
2987
3001
|
bottom: auto;
|
|
2988
3002
|
z-index: 2;
|
|
2989
|
-
|
|
2990
|
-
background: var(--baht-chart-surface);
|
|
2991
|
-
padding: 0 4px;
|
|
2992
|
-
border-radius: var(--baht-radius-xs);
|
|
3003
|
+
padding: 0 2px;
|
|
2993
3004
|
}
|
|
2994
3005
|
.baht-bar-chart-marker-label--row::before {
|
|
2995
3006
|
display: none; /* the line it names is right beside it */
|
|
@@ -710,7 +710,11 @@
|
|
|
710
710
|
"values": []
|
|
711
711
|
},
|
|
712
712
|
{ "name": "show-close", "values": [] },
|
|
713
|
-
{
|
|
713
|
+
{
|
|
714
|
+
"name": "close-on-scrim",
|
|
715
|
+
"description": "Scrim click requests close. Off by default: a stray click outside the panel\nmust not throw away what the user typed — close via ×, Escape or your buttons.",
|
|
716
|
+
"values": []
|
|
717
|
+
},
|
|
714
718
|
{ "name": "defer-hydration", "values": [] }
|
|
715
719
|
],
|
|
716
720
|
"references": []
|
package/dist/web-types.json
CHANGED
|
@@ -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.
|
|
4
|
+
"version": "0.10.0",
|
|
5
5
|
"description-markup": "markdown",
|
|
6
6
|
"contributions": {
|
|
7
7
|
"html": {
|
|
@@ -1645,7 +1645,8 @@
|
|
|
1645
1645
|
},
|
|
1646
1646
|
{
|
|
1647
1647
|
"name": "close-on-scrim",
|
|
1648
|
-
"
|
|
1648
|
+
"description": "Scrim click requests close. Off by default: a stray click outside the panel\nmust not throw away what the user typed — close via ×, Escape or your buttons.",
|
|
1649
|
+
"value": { "type": "boolean", "default": "false" }
|
|
1649
1650
|
},
|
|
1650
1651
|
{ "name": "defer-hydration", "value": { "type": "string" } }
|
|
1651
1652
|
],
|
|
@@ -1660,7 +1661,11 @@
|
|
|
1660
1661
|
"type": "string"
|
|
1661
1662
|
},
|
|
1662
1663
|
{ "name": "showClose", "type": "boolean" },
|
|
1663
|
-
{
|
|
1664
|
+
{
|
|
1665
|
+
"name": "closeOnScrim",
|
|
1666
|
+
"description": "Scrim click requests close. Off by default: a stray click outside the panel\nmust not throw away what the user typed — close via ×, Escape or your buttons.",
|
|
1667
|
+
"type": "boolean"
|
|
1668
|
+
}
|
|
1664
1669
|
],
|
|
1665
1670
|
"events": [{ "name": "name", "type": "CustomEvent" }]
|
|
1666
1671
|
}
|