bank20baht-ui 0.2.4 → 0.2.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.
- package/README.md +1 -0
- package/dist/chunks/index-BI-29Q8f.js +694 -0
- package/dist/components/primitives/baht-datepicker.d.ts +34 -2
- package/dist/components/primitives/baht-table.d.ts +61 -7
- package/dist/components/primitives/index.d.ts +1 -1
- package/dist/core/dates.d.ts +29 -0
- package/dist/core/i18n.d.ts +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/types.d.ts +21 -0
- package/dist/custom-elements.json +333 -24
- package/dist/engine.js +22 -628
- package/dist/index.js +993 -806
- package/dist/react.d.ts +3 -2
- package/dist/tokens.css +1928 -629
- package/dist/vscode.html-custom-data.json +2 -2
- package/dist/web-types.json +7 -7
- package/package.json +2 -1
|
@@ -1,6 +1,38 @@
|
|
|
1
|
-
import { TemplateResult } from 'lit';
|
|
1
|
+
import { PropertyValues, TemplateResult } from 'lit';
|
|
2
2
|
import { BahtFieldBase } from '../base.js';
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* Calendar field on top of flatpickr. The VALUE is always ISO `yyyy-mm-dd`
|
|
5
|
+
* regardless of `field.dateFormat` (display only):
|
|
6
|
+
* - `dateMode: 'single'` (default) -> `string | null`
|
|
7
|
+
* - `dateMode: 'range'` -> `[start, end] | null` (inclusive)
|
|
8
|
+
* - `dateMode: 'multiple'` -> `string[]`
|
|
9
|
+
* `min` / `max` bound the calendar; `disabledDates` (ISO days or `a/b`
|
|
10
|
+
* intervals) and `disabledWeekdays` (0 = Sun … 6 = Sat) grey days out — and
|
|
11
|
+
* the engine re-checks them on validate, so the calendar is UX, not the gate.
|
|
12
|
+
*
|
|
13
|
+
* The calendar renders INSIDE the element (flatpickr `static`), so it lives in
|
|
14
|
+
* light DOM like every other node and picks up a theme set on any ancestor.
|
|
15
|
+
* Give a clipping ancestor (`overflow: hidden`) room, or it hides the popup.
|
|
16
|
+
*/
|
|
4
17
|
export declare class BahtDatepicker extends BahtFieldBase {
|
|
18
|
+
private fp;
|
|
19
|
+
/**
|
|
20
|
+
* What we last told the host. A controlled host re-feeds `value` after the
|
|
21
|
+
* event, but a slow (or absent) re-feed must not make onClose re-emit the
|
|
22
|
+
* pick onChange already sent — compare against this until `value` catches up.
|
|
23
|
+
*/
|
|
24
|
+
private lastEmitted;
|
|
5
25
|
protected renderControl(): TemplateResult;
|
|
26
|
+
connectedCallback(): void;
|
|
27
|
+
disconnectedCallback(): void;
|
|
28
|
+
protected updated(changed: PropertyValues<this>): void;
|
|
29
|
+
private teardown;
|
|
30
|
+
/** Push the host-fed `value` into the calendar without echoing an event. */
|
|
31
|
+
private syncValue;
|
|
32
|
+
private options;
|
|
33
|
+
private emitIfChanged;
|
|
34
|
+
/** Host value (any mode) -> the Date list flatpickr works with. */
|
|
35
|
+
private datesOf;
|
|
36
|
+
/** flatpickr's selection -> the value shape of the field's mode. */
|
|
37
|
+
private toValue;
|
|
6
38
|
}
|
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import { TemplateResult } from 'lit';
|
|
2
2
|
import { BahtElement } from '../base.js';
|
|
3
3
|
export type CellRenderer = (value: unknown, row: Record<string, unknown>) => unknown;
|
|
4
|
+
/**
|
|
5
|
+
* One column: a plain label, or a reference column with its own fields that
|
|
6
|
+
* the picker can dot-walk into (`requester.department`). Fields nest.
|
|
7
|
+
*/
|
|
8
|
+
export type ColumnSpec = {
|
|
9
|
+
label: string;
|
|
10
|
+
fields?: ColumnMap;
|
|
11
|
+
};
|
|
12
|
+
export type ColumnMap = Record<string, string | ColumnSpec>;
|
|
13
|
+
/** What the picker committed: dotted keys plus the labels the header shows. */
|
|
14
|
+
export type ColumnsChangeDetail = {
|
|
15
|
+
visibleColumns: string[];
|
|
16
|
+
columns: Array<{
|
|
17
|
+
key: string;
|
|
18
|
+
label: string;
|
|
19
|
+
}>;
|
|
20
|
+
};
|
|
4
21
|
/**
|
|
5
22
|
* Server-side data table. `items` is ONE page of rows — the component never
|
|
6
23
|
* slices or fetches; on `baht-page-change` the host fetches the next page and
|
|
@@ -25,9 +42,24 @@ export type CellRenderer = (value: unknown, row: Record<string, unknown>) => unk
|
|
|
25
42
|
* Available/Selected dual-list modal (add/remove, reorder, Select all/Clear
|
|
26
43
|
* all) derived from `columns` (or the first row's keys), no host wiring
|
|
27
44
|
* required. Set `t.columnPicker = false` (JS property — a boolean attribute
|
|
28
|
-
* can't express "off") to hide it
|
|
45
|
+
* can't express "off") to hide it. OK emits `baht-columns-change` with the
|
|
46
|
+
* chosen keys and their labels; persist that and feed it back as
|
|
47
|
+
* `visibleColumns` to remember a person's layout:
|
|
48
|
+
*
|
|
49
|
+
* t.addEventListener('baht-columns-change', (e) => save(e.detail.visibleColumns));
|
|
29
50
|
*
|
|
30
|
-
*
|
|
51
|
+
* Dot-walking (spec: reference columns). A column may declare `fields`, in
|
|
52
|
+
* which case the picker lets the person expand it and pick a sub-field —
|
|
53
|
+
* the key becomes `requester.department`, the header reads
|
|
54
|
+
* "Requested by › Department", and the cell resolves the path on the row.
|
|
55
|
+
* Rows whose values are plain objects get the same treatment automatically
|
|
56
|
+
* when no `columns` map is given.
|
|
57
|
+
*
|
|
58
|
+
* t.columns = {
|
|
59
|
+
* number: 'Number',
|
|
60
|
+
* requester: { label: 'Requested by', fields: { name: 'Name', department: 'Department' } },
|
|
61
|
+
* };
|
|
62
|
+
* t.visibleColumns = ['number', 'requester.name'];
|
|
31
63
|
*
|
|
32
64
|
* `visibleColumns` still works standalone for a host-controlled subset (no
|
|
33
65
|
* refetch) — pass it explicitly and the built-in picker (if also enabled)
|
|
@@ -36,8 +68,8 @@ export type CellRenderer = (value: unknown, row: Record<string, unknown>) => unk
|
|
|
36
68
|
export declare class BahtTable extends BahtElement {
|
|
37
69
|
/** Rows of the CURRENT page. */
|
|
38
70
|
items: Record<string, unknown>[];
|
|
39
|
-
/** column key -> display name;
|
|
40
|
-
columns:
|
|
71
|
+
/** column key -> display name, or a reference column with `fields` (property); empty = derive keys from the first row (`snake_case` -> `Title Case`). */
|
|
72
|
+
columns: ColumnMap;
|
|
41
73
|
loading: boolean;
|
|
42
74
|
error: boolean;
|
|
43
75
|
errorMessage: string;
|
|
@@ -50,9 +82,9 @@ export declare class BahtTable extends BahtElement {
|
|
|
50
82
|
rowKey: string;
|
|
51
83
|
/** Rows emit baht-row-click + get hover/keyboard affordances. */
|
|
52
84
|
clickable: boolean;
|
|
53
|
-
/** Custom cell renderers by column key (functions — a property, never JSON). */
|
|
85
|
+
/** Custom cell renderers by column key, dotted keys included (functions — a property, never JSON). */
|
|
54
86
|
renderers: Record<string, CellRenderer>;
|
|
55
|
-
/** Subset + order of
|
|
87
|
+
/** Subset + order of columns to render (dotted keys allowed); empty/omitted = show all top-level columns. */
|
|
56
88
|
visibleColumns: string[];
|
|
57
89
|
/** Built-in "Columns" toggle — derives its options from `columns`/rows. Set `column-picker="false"` to hide it. */
|
|
58
90
|
columnPicker: boolean;
|
|
@@ -70,22 +102,44 @@ export declare class BahtTable extends BahtElement {
|
|
|
70
102
|
/** Highlighted (not yet moved) options in each list. */
|
|
71
103
|
private pickAvail;
|
|
72
104
|
private pickSel;
|
|
105
|
+
/** Reference columns unfolded in the Available tree (dot-walk). */
|
|
106
|
+
private expanded;
|
|
73
107
|
private readonly onPickerKeydown;
|
|
74
108
|
disconnectedCallback(): void;
|
|
109
|
+
protected willUpdate(changed: Map<PropertyKey, unknown>): void;
|
|
110
|
+
/** The declared map, or one derived from the first row (nested objects become reference columns). */
|
|
111
|
+
private get spec();
|
|
112
|
+
/** Walk a dotted key through the spec; undefined when no such column exists. */
|
|
113
|
+
private specAt;
|
|
114
|
+
private isReference;
|
|
115
|
+
private childrenOf;
|
|
116
|
+
/** Every pickable key, reference fields included (`requester`, `requester.name`, ...). */
|
|
117
|
+
private allPaths;
|
|
75
118
|
private get allColumnKeys();
|
|
76
119
|
private get columnKeys();
|
|
120
|
+
/** "Requested by › Department" for a dotted key; the plain label otherwise. */
|
|
121
|
+
private labelFor;
|
|
122
|
+
/** The row's value at a dotted key (`requester.department`). */
|
|
123
|
+
private static valueAt;
|
|
77
124
|
private openPicker;
|
|
78
125
|
private closePicker;
|
|
79
126
|
private static selectedValues;
|
|
127
|
+
private toggleAvail;
|
|
128
|
+
private toggleExpanded;
|
|
80
129
|
private addToSelected;
|
|
81
130
|
private removeFromSelected;
|
|
82
131
|
private moveSelected;
|
|
83
132
|
private confirmPicker;
|
|
84
|
-
private labelFor;
|
|
85
133
|
private emitRow;
|
|
86
134
|
private cell;
|
|
87
135
|
private renderBody;
|
|
88
136
|
private renderColumnToggle;
|
|
137
|
+
/**
|
|
138
|
+
* One row of the Available tree. A reference column gets an expander that
|
|
139
|
+
* unfolds its fields (the dot-walk); every row is a toggle button so the
|
|
140
|
+
* list works from the keyboard without the native multi-select.
|
|
141
|
+
*/
|
|
142
|
+
private renderAvailRow;
|
|
89
143
|
private renderColumnModal;
|
|
90
144
|
protected render(): TemplateResult;
|
|
91
145
|
}
|
|
@@ -2,7 +2,7 @@ export { BahtButton, type ButtonVariant, type ButtonSize } from './baht-button.j
|
|
|
2
2
|
export { renderIcon, isIconName, type IconName } from './icons.js';
|
|
3
3
|
export { BahtBadge, type BadgeTone } from './baht-badge.js';
|
|
4
4
|
export { BahtCode, type CodeVariant } from './baht-code.js';
|
|
5
|
-
export { BahtTable, type CellRenderer } from './baht-table.js';
|
|
5
|
+
export { BahtTable, type CellRenderer, type ColumnMap, type ColumnSpec, type ColumnsChangeDetail, } from './baht-table.js';
|
|
6
6
|
export { BahtList, type ListItem } from './baht-list.js';
|
|
7
7
|
export { BahtPagination } from './baht-pagination.js';
|
|
8
8
|
export { BahtModal } from './baht-modal.js';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { DateMode, FieldDescriptor } from './types.js';
|
|
2
|
+
/** ISO day -> local Date at midnight, or null when malformed / not a real day. */
|
|
3
|
+
export declare function parseIsoDate(iso: unknown): Date | null;
|
|
4
|
+
/** Local Date -> ISO day. */
|
|
5
|
+
export declare function formatIsoDate(date: Date): string;
|
|
6
|
+
export declare const dateModeOf: (field: FieldDescriptor) => DateMode;
|
|
7
|
+
/**
|
|
8
|
+
* Every ISO day a date value holds, whatever the mode: a single string, a
|
|
9
|
+
* `[start, end]` range (both ends only — the interior is implied) or a list.
|
|
10
|
+
* Non-string entries are dropped; shape errors are the validator's job.
|
|
11
|
+
*/
|
|
12
|
+
export declare function isoDaysOf(value: unknown): string[];
|
|
13
|
+
/**
|
|
14
|
+
* One `disabledDates` entry: an ISO day or an inclusive ISO interval
|
|
15
|
+
* `start/end`. Returns `[from, to]` (from === to for a single day) or null.
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseDisabledEntry(entry: string): [Date, Date] | null;
|
|
18
|
+
/**
|
|
19
|
+
* True when `iso` falls on a disabled weekday or inside a disabled date /
|
|
20
|
+
* interval of the descriptor. Malformed entries never disable anything.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isDateDisabled(field: FieldDescriptor, iso: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Days between a range's ends (inclusive) that a picker would step over —
|
|
25
|
+
* so a range can be rejected when a holiday sits INSIDE it. Capped so a
|
|
26
|
+
* hostile `["1900-01-01","2999-12-31"]` submission cannot spin the server;
|
|
27
|
+
* beyond the cap only the ends are checked.
|
|
28
|
+
*/
|
|
29
|
+
export declare function rangeInteriorDays(start: string, end: string, cap?: number): string[];
|
package/dist/core/i18n.d.ts
CHANGED
package/dist/core/index.d.ts
CHANGED
|
@@ -11,3 +11,4 @@ export { resolveNext, walkPath } from './engine/graph.js';
|
|
|
11
11
|
export { evalCondition, readRef } from './engine/conditions.js';
|
|
12
12
|
export { evalValueExpr } from './engine/expressions.js';
|
|
13
13
|
export { displayValue, type DisplayValue } from './display.js';
|
|
14
|
+
export { formatIsoDate, isDateDisabled, parseDisabledEntry, parseIsoDate } from './dates.js';
|
package/dist/core/types.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/** Control types supported by v1 (spec 01 §2). */
|
|
2
2
|
export type FieldType = 'text' | 'textarea' | 'number' | 'email' | 'password' | 'dropdown' | 'multiselect' | 'checkbox' | 'radio' | 'toggle' | 'date' | 'file' | 'label' | 'section' | 'repeater';
|
|
3
3
|
export type FieldWidth = '1/4' | '1/2' | '3/4' | 'full';
|
|
4
|
+
/** `date` field selection mode (spec 01 §2). */
|
|
5
|
+
export type DateMode = 'single' | 'range' | 'multiple';
|
|
4
6
|
export interface FieldOption {
|
|
5
7
|
key: string;
|
|
6
8
|
label: string;
|
|
@@ -48,6 +50,25 @@ export interface FieldDescriptor {
|
|
|
48
50
|
minLength?: number;
|
|
49
51
|
min?: number | string;
|
|
50
52
|
max?: number | string;
|
|
53
|
+
/**
|
|
54
|
+
* date: selection mode. 'single' (default) -> value is one ISO string;
|
|
55
|
+
* 'range' -> value is `[start, end]` (both ISO, inclusive); 'multiple' ->
|
|
56
|
+
* value is an ISO string[] in pick order.
|
|
57
|
+
*/
|
|
58
|
+
dateMode?: DateMode;
|
|
59
|
+
/**
|
|
60
|
+
* date: DISPLAY format of the typed/rendered text (flatpickr tokens, e.g.
|
|
61
|
+
* 'd/m/Y', 'j M Y'). The VALUE stays ISO yyyy-mm-dd regardless.
|
|
62
|
+
*/
|
|
63
|
+
dateFormat?: string;
|
|
64
|
+
/**
|
|
65
|
+
* date: days that cannot be picked — each entry an ISO date ('2026-04-13')
|
|
66
|
+
* or an inclusive ISO interval ('2026-04-13/2026-04-15'). Enforced by the
|
|
67
|
+
* engine too, so a hand-crafted submission cannot bypass the calendar.
|
|
68
|
+
*/
|
|
69
|
+
disabledDates?: string[];
|
|
70
|
+
/** date: weekdays that cannot be picked, 0 = Sunday … 6 = Saturday. */
|
|
71
|
+
disabledWeekdays?: number[];
|
|
51
72
|
step?: number;
|
|
52
73
|
rows?: number;
|
|
53
74
|
accept?: string;
|