bank20baht-ui 0.0.9 → 0.0.11

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
@@ -93,6 +93,40 @@ dep changes, options refetch and the dependent value clears — cascading down c
93
93
  `compare` checks against a sibling field (confirm email = `op: 'eq'`), numeric/date-aware,
94
94
  skips while either side is empty. Works inside repeater rows and on the server.
95
95
 
96
+ ### Feature flags — deploy dark, flip a JSON file
97
+
98
+ ```js
99
+ // schema: gate a field / workflow step / rule
100
+ { order: 9, type: 'text', key: 'promoCode', flag: 'promo' } // '!promo' = the old path
101
+
102
+ // host: flags from one static file — edit it, features flip
103
+ el.flags = await fetch('/flags.json').then((r) => r.json()); // { "promo": true }
104
+ ```
105
+
106
+ Flag-off means **not in the schema**: no render, no validation (a dark `required` can't
107
+ block), nothing in the payload. Missing keys count as off, so new features stay dark until
108
+ the file turns them on. Server side: `validateSubmission(applyFlags(schema, flags), data)`
109
+ with the same JSON — `bank20baht-validator` re-exports `applyFlags`.
110
+
111
+ ### File upload
112
+
113
+ ```js
114
+ // schema:
115
+ { order: 6, type: 'file', key: 'doc', uploader: 'default', accept: '.pdf,image/*', maxSize: 10_485_760 }
116
+
117
+ // registry — File in, serializable ref out:
118
+ el.registry = {
119
+ uploaders: { default: async (file) => {
120
+ const fd = new FormData(); fd.append('file', file);
121
+ return (await fetch('/api/uploads', { method: 'POST', body: fd })).json();
122
+ } },
123
+ };
124
+ ```
125
+
126
+ Picking a file uploads immediately; the value becomes `{ name, size, type, url }` — plain
127
+ JSON, chips with remove buttons in the UI, `maxSize`/`accept` validated on both client and
128
+ server. Omit `uploader` for the old capture-only mode.
129
+
96
130
  ### Drafts / autosave (host pattern)
97
131
 
98
132
  The library is controlled — autosave is three lines in your app:
@@ -1,6 +1,6 @@
1
1
  import { TemplateResult } from 'lit';
2
2
  import { BahtElement } from './base.js';
3
- import { DerivedFieldState, FormDefinition, Registry, ValidationError } from '../core/types.js';
3
+ import { DerivedFieldState, FeatureFlags, FormDefinition, Registry, ValidationError } from '../core/types.js';
4
4
  export interface BahtFormOptions {
5
5
  validateOn?: 'change' | 'blur' | 'submit';
6
6
  }
@@ -23,6 +23,11 @@ export declare class BahtForm extends BahtElement {
23
23
  * the complete schema, views never change the submit payload.
24
24
  */
25
25
  view?: string;
26
+ /**
27
+ * Feature-flag values (spec 01 §12) — fields whose `flag` is off behave as
28
+ * if they were never in the schema: no render, no validation, no payload.
29
+ */
30
+ flags: FeatureFlags;
26
31
  /** Edits the user made since the host last set `value` (controlled overlay). */
27
32
  private edits;
28
33
  private errors;
@@ -36,6 +41,9 @@ export declare class BahtForm extends BahtElement {
36
41
  private dynamicOptions;
37
42
  private optionsSnapshots;
38
43
  private optionsEpoch;
44
+ /** applyFlags result, memoized on (form, flags) identity. */
45
+ private flagCache;
46
+ private get effectiveForm();
39
47
  protected willUpdate(changed: Map<PropertyKey, unknown>): void;
40
48
  /**
41
49
  * Refetch `optionsFrom` options whose dep snapshot changed. Sync fetchers
@@ -1,6 +1,6 @@
1
1
  import { TemplateResult } from 'lit';
2
2
  import { BahtElement } from './base.js';
3
- import { NestedData, Registry, WorkflowDefinition } from '../core/types.js';
3
+ import { FeatureFlags, NestedData, Registry, WorkflowDefinition } from '../core/types.js';
4
4
  /**
5
5
  * <baht-workflow> — the optional brain (spec 03). Wraps the current form in an
6
6
  * internal <baht-form>, evaluates rules on every change, walks the visible forms
@@ -21,17 +21,26 @@ export declare class BahtWorkflow extends BahtElement {
21
21
  submitLabel?: string;
22
22
  backLabel?: string;
23
23
  showBack: boolean;
24
+ /** Feature-flag values (spec 01 §12): flag-off steps/fields/rules vanish. */
25
+ flags: FeatureFlags;
26
+ /** Render a <baht-steps> progress indicator above the current form. */
27
+ showSteps: boolean;
24
28
  private data;
25
29
  private derived;
26
30
  private current;
27
31
  private approvalError;
28
32
  private history;
29
33
  get currentFormName(): string | null;
34
+ /** applyFlags result, memoized on (workflow, flags) identity. */
35
+ private flagCache;
36
+ private get effectiveWorkflow();
30
37
  protected willUpdate(changed: Map<PropertyKey, unknown>): void;
31
38
  private reevaluate;
32
39
  /** Forms in ascending order whose derived visibility is true. */
33
40
  private get visibleForms();
34
41
  private get currentForm();
42
+ /** Where next() would go from here: a formName or 'end' (spec 03 §6). */
43
+ private get navTarget();
35
44
  private get isLast();
36
45
  private fieldStatesFor;
37
46
  private get formEl();
@@ -43,7 +52,7 @@ export declare class BahtWorkflow extends BahtElement {
43
52
  */
44
53
  setValue(formName: string, patch: Record<string, unknown>): void;
45
54
  next(): void;
46
- /** Advance past the current form: submit+complete on the last one, else step forward. */
55
+ /** Advance past the current form: submit+complete at 'end', else step to navTarget. */
47
56
  private advance;
48
57
  /** Approve the current approval step (same as pressing its Approve button). */
49
58
  approve(): void;
@@ -1,9 +1,22 @@
1
1
  import { TemplateResult } from 'lit';
2
2
  import { BahtFieldBase } from '../base.js';
3
+ import { UploadedFile } from '../../core/types.js';
3
4
  /**
4
- * Capture only (spec 01 §2): value = File handle(s); the lib never uploads.
5
+ * File field (spec 01 §2 + §13). Two modes:
6
+ * - capture (default): value = File handle(s); the lib never uploads.
7
+ * - upload (`field.uploader` + host `uploader` fn from the registry):
8
+ * picking uploads immediately, value becomes serializable UploadedFile
9
+ * ref(s), and the control shows chips with remove buttons.
5
10
  * maxSize (bytes) is enforced here as a soft filter — oversize files rejected.
6
11
  */
7
12
  export declare class BahtFile extends BahtFieldBase {
13
+ /** Resolved registry uploader — <baht-form> injects it when `field.uploader` is set. */
14
+ uploader?: (file: File) => Promise<UploadedFile>;
15
+ private uploadingCount;
16
+ private uploadError;
17
+ private get refs();
18
+ private emitRefs;
19
+ private uploadAll;
20
+ private onPick;
8
21
  protected renderControl(): TemplateResult;
9
22
  }
@@ -0,0 +1,20 @@
1
+ import { TemplateResult } from 'lit';
2
+ import { BahtElement } from '../base.js';
3
+ /**
4
+ * <baht-steps> — wizard progress indicator (spec 03). Standalone display
5
+ * primitive: numbered markers + labels, the current one highlighted, done
6
+ * ones checked. <baht-workflow show-steps> renders it automatically from its
7
+ * visible forms.
8
+ */
9
+ export declare class BahtSteps extends BahtElement {
10
+ /** Step labels in order. */
11
+ steps: string[];
12
+ /** 0-based index of the current step. */
13
+ current: number;
14
+ protected render(): TemplateResult;
15
+ }
16
+ declare global {
17
+ interface HTMLElementTagNameMap {
18
+ 'baht-steps': BahtSteps;
19
+ }
20
+ }
@@ -42,4 +42,5 @@ export { BahtErrorState } from './baht-error-state.js';
42
42
  export { BahtKeyvalueEditor } from './baht-keyvalue-editor.js';
43
43
  export { BahtReferencePicker, type ReferenceOption } from './baht-reference-picker.js';
44
44
  export { BahtRepeater } from './baht-repeater.js';
45
+ export { BahtSteps } from './baht-steps.js';
45
46
  export { TAG_FOR_TYPE } from './tag-map.js';
@@ -0,0 +1,13 @@
1
+ import { NestedData, WorkflowDefinition } from '../types.js';
2
+ /**
3
+ * The step after `current` given the data: a formName or 'end'. Rules run
4
+ * (via evaluate) to decide visibility; hidden targets pass through, cycles
5
+ * of invisible forms end the walk.
6
+ */
7
+ export declare function resolveNext(workflow: WorkflowDefinition, current: string, data: NestedData): string | 'end';
8
+ /**
9
+ * The full path a submission takes from the start form to 'end' under this
10
+ * data — what the server validates against (off-path forms are as good as
11
+ * skipped). Back-edges that revisit a form stop the walk instead of looping.
12
+ */
13
+ export declare function walkPath(workflow: WorkflowDefinition, data: NestedData): string[];
@@ -0,0 +1,19 @@
1
+ import { FeatureFlags, FormDefinition, WorkflowDefinition } from './types.js';
2
+ /**
3
+ * Is a `flag` expression on (spec 01 §12)?
4
+ * - no flag -> always on
5
+ * - 'name' -> on only while flags.name is true
6
+ * - '!name' -> on only while flags.name is NOT true
7
+ * A missing key counts as false — new features stay dark until the flags
8
+ * file explicitly turns them on.
9
+ */
10
+ export declare function flagEnabled(flag: string | undefined, flags: FeatureFlags): boolean;
11
+ /**
12
+ * Resolve every `flag` in a definition against the current flag values:
13
+ * flag-off fields/steps/rules come back REMOVED, as if never authored —
14
+ * they don't render, don't validate, and never reach the payload. Run the
15
+ * same call server-side (bank20baht-validator re-exports it) with the same
16
+ * flags JSON so both sides agree. Returns the input untouched when nothing
17
+ * in it carries a flag.
18
+ */
19
+ export declare function applyFlags<T extends FormDefinition | WorkflowDefinition>(schema: T, flags?: FeatureFlags): T;
@@ -12,6 +12,11 @@ export interface MessageCatalog {
12
12
  compareGte: string;
13
13
  compareLt: string;
14
14
  compareLte: string;
15
+ fileTooLarge: string;
16
+ fileTypeNotAllowed: string;
17
+ uploading: string;
18
+ uploadFailed: string;
19
+ removeFile: string;
15
20
  addRow: string;
16
21
  removeRow: string;
17
22
  minRows: string;
@@ -3,8 +3,10 @@ export { defaultValue } from './defaults.js';
3
3
  export { approvalFields } from './approval.js';
4
4
  export { validateField } from './validators.js';
5
5
  export { resolveViewFields } from './views.js';
6
+ export { applyFlags, flagEnabled } from './flags.js';
6
7
  export { setLocale, t } from './i18n.js';
7
8
  export type { Locale, MessageCatalog, MessageKey } from './i18n.js';
8
9
  export { evaluate } from './engine/evaluate.js';
10
+ export { resolveNext, walkPath } from './engine/graph.js';
9
11
  export { evalCondition, readRef } from './engine/conditions.js';
10
12
  export { evalValueExpr } from './engine/expressions.js';
@@ -52,8 +52,20 @@ export interface FieldDescriptor {
52
52
  accept?: string;
53
53
  multiple?: boolean;
54
54
  maxSize?: number;
55
+ /**
56
+ * Registry uploader name (spec 01 §13). With it, picking a file uploads
57
+ * immediately and the VALUE becomes a serializable UploadedFile ref
58
+ * (arrays when `multiple`) — without it, capture-only File handles (v1).
59
+ */
60
+ uploader?: string;
55
61
  text?: string;
56
62
  variant?: string;
63
+ /**
64
+ * Feature flag gating this field (spec 01 §12): shown only while the flag
65
+ * is on ('name') or off ('!name'). Flag-off = as if the field were never in
66
+ * the schema — not rendered, not validated, absent from the payload.
67
+ */
68
+ flag?: string;
57
69
  fields?: FieldDescriptor[];
58
70
  minRows?: number;
59
71
  maxRows?: number;
@@ -108,6 +120,8 @@ export interface WorkflowForm extends FormDefinition {
108
120
  approval?: ApprovalConfig;
109
121
  /** Name of one of this form's `views` to render for this step (display only). */
110
122
  view?: string;
123
+ /** Feature flag gating this whole step (spec 01 §12). */
124
+ flag?: string;
111
125
  }
112
126
  export type ConditionOp = 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'notIn' | 'contains' | 'notContains' | 'startsWith' | 'endsWith' | 'isEmpty' | 'isNotEmpty';
113
127
  /** Leaf: compare `formName.fieldKey` against a constant or another field. */
@@ -160,12 +174,38 @@ export interface Rule {
160
174
  when?: Condition;
161
175
  then?: Action[];
162
176
  else?: Action[];
177
+ /** Feature flag gating this rule (spec 01 §12). */
178
+ flag?: string;
179
+ }
180
+ /** Flag values — typically fetched from one static JSON file (spec 01 §12). */
181
+ export type FeatureFlags = Record<string, boolean>;
182
+ /**
183
+ * A conditional edge between steps (spec 03 §6). With `transitions` present
184
+ * the wizard routes as a graph: from a form, the first edge whose `when`
185
+ * matches wins; `to: 'end'` submits. Forms with no outgoing edges (and
186
+ * non-matching edge sets) fall back to the next visible form in `order`, so
187
+ * linear authoring keeps working and branches are added only where needed.
188
+ */
189
+ export interface Transition {
190
+ from: string;
191
+ to: string | 'end';
192
+ when?: Condition;
193
+ flag?: string;
163
194
  }
164
195
  /** A Workflow definition — consumed by <baht-workflow> (spec 00 §4.2). */
165
196
  export interface WorkflowDefinition {
166
197
  workflowId: string;
167
198
  forms: WorkflowForm[];
168
199
  rules: Rule[];
200
+ /** Optional graph routing (spec 03 §6); absent = linear by `order`. */
201
+ transitions?: Transition[];
202
+ }
203
+ /** Serializable result of a registry uploader (spec 01 §13). */
204
+ export interface UploadedFile {
205
+ name: string;
206
+ size: number;
207
+ type?: string;
208
+ url: string;
169
209
  }
170
210
  export interface Registry {
171
211
  formatters?: Record<string, (value: unknown) => unknown>;
@@ -173,6 +213,8 @@ export interface Registry {
173
213
  validators?: Record<string, (value: unknown) => string | null>;
174
214
  /** Option fetchers for `optionsFrom` — receive the form's current flat data. */
175
215
  options?: Record<string, (data: Record<string, unknown>) => FieldOption[] | Promise<FieldOption[]>>;
216
+ /** File uploaders for `uploader` — take the picked File, return its ref. */
217
+ uploaders?: Record<string, (file: File) => Promise<UploadedFile>>;
176
218
  }
177
219
  export interface DerivedFieldState {
178
220
  visible: boolean;
@@ -60,6 +60,15 @@
60
60
  "description": "Name of a view from `form.views`. Display-only: when set, only that view's\nfields are rendered and validated (the user can only fix what they see),\nbut getData() still returns the FULL form — the server always validates\nthe complete schema, views never change the submit payload.",
61
61
  "attribute": "view"
62
62
  },
63
+ {
64
+ "kind": "field",
65
+ "name": "flags",
66
+ "type": {
67
+ "text": "FeatureFlags"
68
+ },
69
+ "default": "{}",
70
+ "description": "Feature-flag values (spec 01 §12) — fields whose `flag` is off behave as\nif they were never in the schema: no render, no validation, no payload."
71
+ },
63
72
  {
64
73
  "kind": "field",
65
74
  "name": "edits",
@@ -105,6 +114,25 @@
105
114
  "privacy": "private",
106
115
  "default": "new Map<string, number>()"
107
116
  },
117
+ {
118
+ "kind": "field",
119
+ "name": "flagCache",
120
+ "type": {
121
+ "text": "{ form?: FormDefinition; flags?: FeatureFlags; out?: FormDefinition }"
122
+ },
123
+ "privacy": "private",
124
+ "default": "{}",
125
+ "description": "applyFlags result, memoized on (form, flags) identity."
126
+ },
127
+ {
128
+ "kind": "field",
129
+ "name": "effectiveForm",
130
+ "type": {
131
+ "text": "FormDefinition"
132
+ },
133
+ "privacy": "private",
134
+ "readonly": true
135
+ },
108
136
  {
109
137
  "kind": "method",
110
138
  "name": "syncDynamicOptions",
@@ -401,6 +429,25 @@
401
429
  "default": "true",
402
430
  "attribute": "show-back"
403
431
  },
432
+ {
433
+ "kind": "field",
434
+ "name": "flags",
435
+ "type": {
436
+ "text": "FeatureFlags"
437
+ },
438
+ "default": "{}",
439
+ "description": "Feature-flag values (spec 01 §12): flag-off steps/fields/rules vanish."
440
+ },
441
+ {
442
+ "kind": "field",
443
+ "name": "showSteps",
444
+ "type": {
445
+ "text": "boolean"
446
+ },
447
+ "default": "false",
448
+ "description": "Render a <baht-steps> progress indicator above the current form.",
449
+ "attribute": "show-steps"
450
+ },
404
451
  {
405
452
  "kind": "field",
406
453
  "name": "data",
@@ -454,6 +501,25 @@
454
501
  },
455
502
  "readonly": true
456
503
  },
504
+ {
505
+ "kind": "field",
506
+ "name": "flagCache",
507
+ "type": {
508
+ "text": "{\n workflow?: WorkflowDefinition;\n flags?: FeatureFlags;\n out?: WorkflowDefinition;\n }"
509
+ },
510
+ "privacy": "private",
511
+ "default": "{}",
512
+ "description": "applyFlags result, memoized on (workflow, flags) identity."
513
+ },
514
+ {
515
+ "kind": "field",
516
+ "name": "effectiveWorkflow",
517
+ "type": {
518
+ "text": "WorkflowDefinition"
519
+ },
520
+ "privacy": "private",
521
+ "readonly": true
522
+ },
457
523
  {
458
524
  "kind": "method",
459
525
  "name": "reevaluate",
@@ -483,6 +549,16 @@
483
549
  "privacy": "private",
484
550
  "readonly": true
485
551
  },
552
+ {
553
+ "kind": "field",
554
+ "name": "navTarget",
555
+ "type": {
556
+ "text": "string | 'end'"
557
+ },
558
+ "privacy": "private",
559
+ "description": "Where next() would go from here: a formName or 'end' (spec 03 §6).",
560
+ "readonly": true
561
+ },
486
562
  {
487
563
  "kind": "field",
488
564
  "name": "isLast",
@@ -579,7 +655,7 @@
579
655
  }
580
656
  }
581
657
  ],
582
- "description": "Advance past the current form: submit+complete on the last one, else step forward."
658
+ "description": "Advance past the current form: submit+complete at 'end', else step to navTarget."
583
659
  },
584
660
  {
585
661
  "kind": "method",
@@ -831,6 +907,15 @@
831
907
  },
832
908
  "default": "true",
833
909
  "fieldName": "showBack"
910
+ },
911
+ {
912
+ "name": "show-steps",
913
+ "type": {
914
+ "text": "boolean"
915
+ },
916
+ "default": "false",
917
+ "description": "Render a <baht-steps> progress indicator above the current form.",
918
+ "fieldName": "showSteps"
834
919
  }
835
920
  ],
836
921
  "superclass": {
@@ -3022,9 +3107,98 @@
3022
3107
  "declarations": [
3023
3108
  {
3024
3109
  "kind": "class",
3025
- "description": "Capture only (spec 01 §2): value = File handle(s); the lib never uploads.\nmaxSize (bytes) is enforced here as a soft filter — oversize files rejected.",
3110
+ "description": "File field (spec 01 §2 + §13). Two modes:\n- capture (default): value = File handle(s); the lib never uploads.\n- upload (`field.uploader` + host `uploader` fn from the registry):\n picking uploads immediately, value becomes serializable UploadedFile\n ref(s), and the control shows chips with remove buttons.\nmaxSize (bytes) is enforced here as a soft filter — oversize files rejected.",
3026
3111
  "name": "BahtFile",
3027
3112
  "members": [
3113
+ {
3114
+ "kind": "field",
3115
+ "name": "uploader",
3116
+ "type": {
3117
+ "text": "(file: File) => Promise<UploadedFile> | undefined"
3118
+ },
3119
+ "description": "Resolved registry uploader — <baht-form> injects it when `field.uploader` is set."
3120
+ },
3121
+ {
3122
+ "kind": "field",
3123
+ "name": "uploadingCount",
3124
+ "type": {
3125
+ "text": "number"
3126
+ },
3127
+ "privacy": "private",
3128
+ "default": "0"
3129
+ },
3130
+ {
3131
+ "kind": "field",
3132
+ "name": "uploadError",
3133
+ "type": {
3134
+ "text": "string | null"
3135
+ },
3136
+ "privacy": "private",
3137
+ "default": "null"
3138
+ },
3139
+ {
3140
+ "kind": "field",
3141
+ "name": "refs",
3142
+ "type": {
3143
+ "text": "UploadedFile[]"
3144
+ },
3145
+ "privacy": "private",
3146
+ "readonly": true
3147
+ },
3148
+ {
3149
+ "kind": "method",
3150
+ "name": "emitRefs",
3151
+ "privacy": "private",
3152
+ "return": {
3153
+ "type": {
3154
+ "text": "void"
3155
+ }
3156
+ },
3157
+ "parameters": [
3158
+ {
3159
+ "name": "refs",
3160
+ "type": {
3161
+ "text": "UploadedFile[]"
3162
+ }
3163
+ }
3164
+ ]
3165
+ },
3166
+ {
3167
+ "kind": "method",
3168
+ "name": "uploadAll",
3169
+ "privacy": "private",
3170
+ "return": {
3171
+ "type": {
3172
+ "text": "Promise<void>"
3173
+ }
3174
+ },
3175
+ "parameters": [
3176
+ {
3177
+ "name": "files",
3178
+ "type": {
3179
+ "text": "File[]"
3180
+ }
3181
+ }
3182
+ ]
3183
+ },
3184
+ {
3185
+ "kind": "method",
3186
+ "name": "onPick",
3187
+ "privacy": "private",
3188
+ "return": {
3189
+ "type": {
3190
+ "text": "void"
3191
+ }
3192
+ },
3193
+ "parameters": [
3194
+ {
3195
+ "name": "e",
3196
+ "type": {
3197
+ "text": "Event"
3198
+ }
3199
+ }
3200
+ ]
3201
+ },
3028
3202
  {
3029
3203
  "kind": "method",
3030
3204
  "name": "renderControl",
@@ -7706,6 +7880,73 @@
7706
7880
  }
7707
7881
  ]
7708
7882
  },
7883
+ {
7884
+ "kind": "javascript-module",
7885
+ "path": "src/components/primitives/baht-steps.ts",
7886
+ "declarations": [
7887
+ {
7888
+ "kind": "class",
7889
+ "description": "<baht-steps> — wizard progress indicator (spec 03). Standalone display\nprimitive: numbered markers + labels, the current one highlighted, done\nones checked. <baht-workflow show-steps> renders it automatically from its\nvisible forms.",
7890
+ "name": "BahtSteps",
7891
+ "members": [
7892
+ {
7893
+ "kind": "field",
7894
+ "name": "steps",
7895
+ "type": {
7896
+ "text": "string[]"
7897
+ },
7898
+ "default": "[]",
7899
+ "description": "Step labels in order."
7900
+ },
7901
+ {
7902
+ "kind": "field",
7903
+ "name": "current",
7904
+ "type": {
7905
+ "text": "number"
7906
+ },
7907
+ "default": "0",
7908
+ "description": "0-based index of the current step.",
7909
+ "attribute": "current"
7910
+ }
7911
+ ],
7912
+ "attributes": [
7913
+ {
7914
+ "name": "current",
7915
+ "type": {
7916
+ "text": "number"
7917
+ },
7918
+ "default": "0",
7919
+ "description": "0-based index of the current step.",
7920
+ "fieldName": "current"
7921
+ }
7922
+ ],
7923
+ "superclass": {
7924
+ "name": "BahtElement",
7925
+ "module": "/src/components/base.js"
7926
+ },
7927
+ "tagName": "baht-steps",
7928
+ "customElement": true
7929
+ }
7930
+ ],
7931
+ "exports": [
7932
+ {
7933
+ "kind": "js",
7934
+ "name": "BahtSteps",
7935
+ "declaration": {
7936
+ "name": "BahtSteps",
7937
+ "module": "src/components/primitives/baht-steps.ts"
7938
+ }
7939
+ },
7940
+ {
7941
+ "kind": "custom-element-definition",
7942
+ "name": "baht-steps",
7943
+ "declaration": {
7944
+ "name": "BahtSteps",
7945
+ "module": "src/components/primitives/baht-steps.ts"
7946
+ }
7947
+ }
7948
+ ]
7949
+ },
7709
7950
  {
7710
7951
  "kind": "javascript-module",
7711
7952
  "path": "src/components/primitives/baht-table.ts",
@@ -9531,6 +9772,14 @@
9531
9772
  "module": "./baht-repeater.js"
9532
9773
  }
9533
9774
  },
9775
+ {
9776
+ "kind": "js",
9777
+ "name": "BahtSteps",
9778
+ "declaration": {
9779
+ "name": "BahtSteps",
9780
+ "module": "./baht-steps.js"
9781
+ }
9782
+ },
9534
9783
  {
9535
9784
  "kind": "js",
9536
9785
  "name": "TAG_FOR_TYPE",