@iyulab/u-widgets 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,478 @@
1
+ import { CSSResult } from 'lit';
2
+ import { LitElement } from 'lit';
3
+ import { nothing } from 'lit';
4
+ import { TemplateResult } from 'lit-html';
5
+
6
+ /**
7
+ * Chart widget type identifiers using dot notation (`chart.<variant>`).
8
+ *
9
+ * @example
10
+ * ```json
11
+ * { "widget": "chart.bar", "data": [...] }
12
+ * ```
13
+ */
14
+ export declare type ChartType = 'chart.bar' | 'chart.line' | 'chart.area' | 'chart.pie' | 'chart.scatter' | 'chart.radar' | 'chart.heatmap' | 'chart.box' | 'chart.funnel' | 'chart.waterfall' | 'chart.treemap';
15
+
16
+ /** Supported input field types for form widgets. */
17
+ export declare type FieldType = 'text' | 'email' | 'password' | 'tel' | 'url' | 'textarea' | 'number' | 'select' | 'multiselect' | 'date' | 'datetime' | 'time' | 'toggle' | 'range' | 'radio' | 'checkbox';
18
+
19
+ /**
20
+ * Format a template string by replacing {key} placeholders.
21
+ */
22
+ export declare function formatTemplate(template: string, params: Record<string, string | number>): string;
23
+
24
+ /**
25
+ * Format a value according to a format hint string.
26
+ *
27
+ * Supported formats: `"number"`, `"currency"`, `"currency:EUR"`, `"percent"`,
28
+ * `"date"`, `"datetime"`, `"bytes"`. Returns `String(value)` for unknown formats.
29
+ *
30
+ * @param value - The value to format (coerced to number where needed).
31
+ * @param format - Format hint, optionally with a parameter after `:` (e.g., `"currency:USD"`).
32
+ * @param locale - BCP 47 locale tag for number/currency formatting. Falls back to browser default.
33
+ * @returns Formatted string, or empty string if value is null/undefined.
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * formatValue(1234.5, 'number') // "1,234.5"
38
+ * formatValue(1234.5, 'currency:EUR') // "€1,234.50"
39
+ * formatValue(73, 'percent') // "73%"
40
+ * formatValue(1536000, 'bytes') // "1.5 MB"
41
+ * ```
42
+ */
43
+ export declare function formatValue(value: unknown, format?: string, locale?: string): string;
44
+
45
+ export declare type FormdownParser = (input: string, data?: Record<string, unknown>) => FormdownResult;
46
+
47
+ /**
48
+ * Parse a formdown string into fields and actions.
49
+ *
50
+ * Formdown syntax (subset):
51
+ * @fieldName*(Label){opt1,opt2}: type[]
52
+ * @[action "Label"]
53
+ *
54
+ * Type markers:
55
+ * [] text @[] email #[] number
56
+ * ?[] password %[] tel &[] url
57
+ * T{n}[] textarea d[] date dt[] datetime
58
+ * t[] time s[] select r[] radio
59
+ * c[] checkbox ^[] toggle R[] range
60
+ * ms[] multiselect
61
+ *
62
+ * * = required, (Label) = display label, {a,b,c} = options
63
+ */
64
+ export declare interface FormdownResult {
65
+ fields: UWidgetFieldDefinition[];
66
+ actions: UWidgetAction[];
67
+ }
68
+
69
+ /**
70
+ * Get the English defaults (for testing / reference).
71
+ */
72
+ export declare function getDefaultLocale(): UWidgetLocaleStrings;
73
+
74
+ export declare function getFormdownParser(): FormdownParser;
75
+
76
+ /**
77
+ * Resolve locale strings for the given language tag.
78
+ *
79
+ * Resolution order:
80
+ * 1. Exact match (e.g. 'ko-KR')
81
+ * 2. Base language (e.g. 'ko')
82
+ * 3. English fallback
83
+ */
84
+ export declare function getLocaleStrings(lang?: string): UWidgetLocaleStrings;
85
+
86
+ /**
87
+ * Auto-infer a mapping from data shape and widget type.
88
+ *
89
+ * Inference rules:
90
+ * - **chart.bar/line/area:** first string field → `x`, number fields → `y`
91
+ * - **chart.pie/funnel:** first string → `label`, first number → `value`
92
+ * - **chart.scatter:** first two number fields → `x`, `y`
93
+ * - **chart.radar:** first string → `axis`, number fields → `y`
94
+ * - **chart.heatmap:** two string fields + number → `x`, `y`, `value`
95
+ * - **chart.box:** string → `x`, five number fields (min/q1/median/q3/max) → `y`
96
+ * - **table:** all keys → `columns`
97
+ * - **list:** first string → `primary`, second string → `secondary`
98
+ * - **metric/gauge/progress/form:** no mapping needed (returns `undefined`)
99
+ *
100
+ * @param widget - Widget type identifier.
101
+ * @param data - The spec's `data` field (object or array of records).
102
+ * @returns Inferred mapping, or `undefined` if not applicable.
103
+ *
104
+ * @example
105
+ * ```ts
106
+ * infer('chart.bar', [{ name: 'A', value: 30 }]);
107
+ * // → { x: 'name', y: 'value' }
108
+ * ```
109
+ */
110
+ export declare function infer(widget: string, data: Record<string, unknown> | Record<string, unknown>[] | undefined): UWidgetMapping | undefined;
111
+
112
+ /**
113
+ * Type guard that checks if a value is a valid {@link UWidgetSpec}.
114
+ *
115
+ * Equivalent to `validate(value).valid`, but narrows the TypeScript type.
116
+ *
117
+ * @param value - The value to check.
118
+ * @returns `true` if the value passes validation.
119
+ */
120
+ export declare function isWidgetSpec(value: unknown): value is UWidgetSpec;
121
+
122
+ /**
123
+ * Normalize a spec for internal processing.
124
+ *
125
+ * Transformations applied:
126
+ * 1. Deprecated `mapping.fields` → top-level `fields`
127
+ * 2. `formdown` string → parsed `fields` + `actions`
128
+ *
129
+ * Returns a shallow copy; the original spec is not mutated.
130
+ *
131
+ * @param spec - The widget spec to normalize.
132
+ * @returns A normalized copy of the spec.
133
+ */
134
+ export declare function normalize(spec: UWidgetSpec): UWidgetSpec;
135
+
136
+ export declare function parseFormdown(input: string, _data?: Record<string, unknown>): FormdownResult;
137
+
138
+ export declare function registerFormdownParser(parser: FormdownParser): void;
139
+
140
+ /**
141
+ * Register a locale for u-widgets chrome strings.
142
+ * Partial overrides are merged with English defaults.
143
+ */
144
+ export declare function registerLocale(lang: string, strings: Partial<UWidgetLocaleStrings>): void;
145
+
146
+ /**
147
+ * Widget name suggestion for typo detection.
148
+ *
149
+ * Compares an unrecognized widget name against all known types
150
+ * using Levenshtein distance and returns the closest match.
151
+ */
152
+ /**
153
+ * Suggest a known widget name for a potentially mistyped input.
154
+ *
155
+ * Returns the closest match if the Levenshtein distance is within
156
+ * a reasonable threshold (max 3, and less than half the input length).
157
+ * Returns `undefined` if no good match is found.
158
+ *
159
+ * @param input - The unrecognized widget name.
160
+ * @returns The suggested widget name, or `undefined`.
161
+ *
162
+ * @example
163
+ * ```ts
164
+ * suggestWidget('chart.barr') // → 'chart.bar'
165
+ * suggestWidget('metrc') // → 'metric'
166
+ * suggestWidget('xyzabc') // → undefined
167
+ * ```
168
+ */
169
+ export declare function suggestWidget(input: string): string | undefined;
170
+
171
+ /**
172
+ * <u-widget> — Entry point router element.
173
+ * Reads spec.widget and delegates to the appropriate sub-component.
174
+ *
175
+ * Supports theme attribute: theme="dark" | theme="light" | (auto via prefers-color-scheme)
176
+ */
177
+ export declare class UWidget extends LitElement {
178
+ static styles: CSSResult[];
179
+ spec: UWidgetSpec | null;
180
+ /** Theme override: "dark" | "light" | null (auto via prefers-color-scheme). */
181
+ theme: string | null;
182
+ /** Locale tag (e.g. 'ko', 'en-US'). Propagated to sub-components via spec.options.locale. */
183
+ locale: string | null;
184
+ connectedCallback(): void;
185
+ disconnectedCallback(): void;
186
+ private _handleInternalEvent;
187
+ render(): typeof nothing | TemplateResult<1>;
188
+ private renderWidget;
189
+ /** Render standalone "actions" widget — a group of action buttons. */
190
+ private renderActionsWidget;
191
+ /** Render inline divider widget. */
192
+ private renderDivider;
193
+ /** Render inline header widget. */
194
+ private renderHeader;
195
+ /** Dispatch an action event from the global action bar or actions widget. */
196
+ private _dispatchAction;
197
+ private renderFallback;
198
+ private renderError;
199
+ }
200
+
201
+ /**
202
+ * Action button definition.
203
+ *
204
+ * Reserved actions: `"submit"`, `"cancel"`, `"navigate"`.
205
+ * Custom action strings are forwarded to the host via the `u-widget-event`.
206
+ *
207
+ * @example
208
+ * ```json
209
+ * { "label": "Submit", "action": "submit", "style": "primary" }
210
+ * ```
211
+ */
212
+ export declare interface UWidgetAction {
213
+ /** Button display text. */
214
+ label: string;
215
+ /** Action identifier emitted in the widget event. */
216
+ action: string;
217
+ /** Visual style hint. */
218
+ style?: 'primary' | 'danger' | 'default';
219
+ /** Whether the button is disabled. */
220
+ disabled?: boolean;
221
+ /** URL for `"navigate"` actions. */
222
+ url?: string;
223
+ }
224
+
225
+ /**
226
+ * Child widget spec inside a compose widget.
227
+ * Inherits `type` and `version` from the parent — no need to repeat them.
228
+ */
229
+ export declare interface UWidgetChildSpec extends Omit<UWidgetSpec, 'type' | 'version'> {
230
+ /** Grid column span within the parent compose layout. */
231
+ span?: number;
232
+ /** When true, the child is initially collapsed (uses native `<details>`). */
233
+ collapsed?: boolean;
234
+ }
235
+
236
+ /**
237
+ * Column definition for table widgets.
238
+ *
239
+ * @example
240
+ * ```json
241
+ * { "field": "price", "label": "Price", "format": "currency", "align": "right" }
242
+ * ```
243
+ */
244
+ export declare interface UWidgetColumnDefinition {
245
+ /** Data field name to display in this column. */
246
+ field: string;
247
+ /** Display header label. Defaults to the field name. */
248
+ label?: string;
249
+ /** Value formatting hint (e.g., `"currency"`, `"currency:EUR"`, `"percent"`). */
250
+ format?: 'number' | 'currency' | 'percent' | 'date' | 'datetime' | 'bytes';
251
+ /** Text alignment within the column. */
252
+ align?: 'left' | 'center' | 'right';
253
+ }
254
+
255
+ /**
256
+ * Event payload emitted by `<u-widget>` via the `u-widget-event` custom event.
257
+ *
258
+ * | type | trigger | payload |
259
+ * |---|---|---|
260
+ * | `submit` | Form submit button | Form field values |
261
+ * | `action` | Custom action button | Action data |
262
+ * | `change` | Input value change | Changed field and value |
263
+ * | `select` | Chart element click | Selected data point |
264
+ */
265
+ export declare interface UWidgetEvent {
266
+ /** Event category. */
267
+ type: 'submit' | 'action' | 'change' | 'select';
268
+ /** The widget type that emitted this event. */
269
+ widget: string;
270
+ /** Widget instance `id` (if set in the spec). */
271
+ id?: string;
272
+ /** Action identifier (for `"action"` type events). */
273
+ action?: string;
274
+ /** Event payload data. */
275
+ data?: Record<string, unknown>;
276
+ }
277
+
278
+ /**
279
+ * Field definition for form/confirm input widgets.
280
+ *
281
+ * @example
282
+ * ```json
283
+ * { "field": "email", "label": "Email", "type": "email", "required": true }
284
+ * ```
285
+ */
286
+ export declare interface UWidgetFieldDefinition {
287
+ /** Data field name (maps to `data[field]` for defaults and output). */
288
+ field: string;
289
+ /** Display label. Defaults to the field name. */
290
+ label?: string;
291
+ /** Input type. Defaults to `"text"`. */
292
+ type?: FieldType;
293
+ /** Whether the field must be filled before submit. */
294
+ required?: boolean;
295
+ /** Placeholder text shown when the field is empty. */
296
+ placeholder?: string;
297
+ /** Options for select, multiselect, radio, and checkbox types. */
298
+ options?: string[];
299
+ /** Minimum character length for text inputs. */
300
+ minLength?: number;
301
+ /** Maximum character length for text inputs. */
302
+ maxLength?: number;
303
+ /** Custom regex pattern for validation (e.g. `"^[A-Z]{3}$"`). */
304
+ pattern?: string;
305
+ /** Number of visible rows for textarea type. */
306
+ rows?: number;
307
+ /** Minimum value (number) or date string. */
308
+ min?: number | string;
309
+ /** Maximum value (number) or date string. */
310
+ max?: number | string;
311
+ /** Step increment for number and range inputs. */
312
+ step?: number;
313
+ /** Custom validation error message (overrides locale default). */
314
+ message?: string;
315
+ }
316
+
317
+ /**
318
+ * Lightweight locale registry for u-widgets.
319
+ *
320
+ * Scope: library-internal chrome strings only (validation messages,
321
+ * pagination labels, ARIA labels). NOT a general i18n framework.
322
+ *
323
+ * English is the built-in default. Consumers register other locales:
324
+ * registerLocale('ko', { prev: '이전', next: '다음', ... });
325
+ */
326
+ export declare interface UWidgetLocaleStrings {
327
+ prev: string;
328
+ next: string;
329
+ searchPlaceholder: string;
330
+ searchTable: string;
331
+ previousPage: string;
332
+ nextPage: string;
333
+ tablePagination: string;
334
+ dataTable: string;
335
+ required: string;
336
+ minLength: string;
337
+ maxLength: string;
338
+ minValue: string;
339
+ maxValue: string;
340
+ invalidEmail: string;
341
+ invalidUrl: string;
342
+ invalidPattern: string;
343
+ }
344
+
345
+ /**
346
+ * Mapping connects data fields to visual channels.
347
+ *
348
+ * Which keys are relevant depends on the widget type:
349
+ * - **chart.bar/line/area:** `x`, `y`
350
+ * - **chart.pie/funnel:** `label`, `value`
351
+ * - **chart.scatter:** `x`, `y`, `color`, `size`
352
+ * - **chart.radar:** `axis`, `value`
353
+ * - **table:** `columns`
354
+ * - **list:** `primary`, `secondary`, `avatar`, `icon`, `trailing`
355
+ *
356
+ * When omitted, mapping is auto-inferred from the data shape.
357
+ */
358
+ export declare interface UWidgetMapping {
359
+ /** Category axis field (chart x-axis). */
360
+ x?: string;
361
+ /** Value axis field(s). A string for single series, string[] for multi-series. */
362
+ y?: string | string[];
363
+ /** Label field (pie/funnel charts). */
364
+ label?: string;
365
+ /** Value field (pie/funnel/heatmap). */
366
+ value?: string;
367
+ /** Color grouping field (scatter). */
368
+ color?: string;
369
+ /** Size encoding field (scatter bubble). */
370
+ size?: string;
371
+ /** Opacity encoding field (scatter). Maps data values to point opacity (0.1–1.0). */
372
+ opacity?: string;
373
+ /** Axis field (radar chart indicators). */
374
+ axis?: string;
375
+ /** Explicit column definitions for table widgets. */
376
+ columns?: UWidgetColumnDefinition[];
377
+ /** Primary text field (list widget). */
378
+ primary?: string;
379
+ /** Secondary/subtitle text field (list widget). */
380
+ secondary?: string;
381
+ /** Icon letter field (list widget fallback when no avatar). */
382
+ icon?: string;
383
+ /** Avatar image URL field (list widget). */
384
+ avatar?: string;
385
+ /** Trailing value field displayed on the right (list widget). */
386
+ trailing?: string;
387
+ /** Badge/tag field (list widget). */
388
+ badge?: string;
389
+ }
390
+
391
+ /**
392
+ * The u-widget spec envelope — a single, consistent structure for all widgets.
393
+ *
394
+ * Only `widget` is required. All other fields are optional or auto-inferred.
395
+ *
396
+ * @example
397
+ * ```ts
398
+ * const spec: UWidgetSpec = {
399
+ * widget: 'chart.bar',
400
+ * data: [{ name: 'A', value: 30 }, { name: 'B', value: 70 }],
401
+ * mapping: { x: 'name', y: 'value' },
402
+ * };
403
+ * ```
404
+ */
405
+ export declare interface UWidgetSpec {
406
+ /** Widget type identifier (e.g., `"chart.bar"`, `"metric"`, `"form"`). */
407
+ widget: string;
408
+ /** Unique identifier for event correlation and compose children. */
409
+ id?: string;
410
+ /** Optional display title rendered above the widget. */
411
+ title?: string;
412
+ /** Optional description text rendered below the title. */
413
+ description?: string;
414
+ /** Inline data — an object (metric/gauge) or array of records (chart/table). */
415
+ data?: Record<string, unknown> | Record<string, unknown>[];
416
+ /** Maps data fields to visual channels. Auto-inferred when omitted. */
417
+ mapping?: UWidgetMapping;
418
+ /** Field definitions for form/confirm widgets. */
419
+ fields?: UWidgetFieldDefinition[];
420
+ /** Formdown shorthand syntax for form fields (mutually exclusive with `fields`). */
421
+ formdown?: string;
422
+ /** Widget-specific rendering options. */
423
+ options?: Record<string, unknown>;
424
+ /** Action buttons displayed below the widget. */
425
+ actions?: UWidgetAction[];
426
+ /** Interchange format type marker. Always `"u-widget"` if present. */
427
+ type?: 'u-widget';
428
+ /** Interchange format version string. */
429
+ version?: string;
430
+ /** Layout mode for compose widget: `"stack"` (default), `"row"`, or `"grid"`. */
431
+ layout?: 'stack' | 'row' | 'grid';
432
+ /** Number of grid columns for compose `"grid"` layout. Default: 2. */
433
+ columns?: number;
434
+ /** Child widget specs for compose widget. */
435
+ children?: UWidgetChildSpec[];
436
+ /** Grid column span for children inside a compose `"grid"` layout. */
437
+ span?: number;
438
+ }
439
+
440
+ /**
441
+ * Validate a u-widget spec.
442
+ *
443
+ * Checks structural correctness: required fields, data type expectations,
444
+ * compose children, field/action definitions. Also validates that mapping
445
+ * fields exist in the data (produces warnings, not errors).
446
+ *
447
+ * @param spec - The spec object to validate (any type accepted for safety).
448
+ * @returns Validation result with `valid`, `errors`, and `warnings`.
449
+ *
450
+ * @example
451
+ * ```ts
452
+ * const result = validate({ widget: 'metric', data: { value: 42 } });
453
+ * console.log(result.valid); // true
454
+ * ```
455
+ */
456
+ export declare function validate(spec: unknown, _depth?: number): ValidationResult;
457
+
458
+ /** Result of spec validation via {@link validate}. */
459
+ export declare interface ValidationResult {
460
+ /** Whether the spec passed all validation checks. */
461
+ valid: boolean;
462
+ /** Error messages — issues that prevent correct rendering. */
463
+ errors: string[];
464
+ /** Warning messages — non-fatal issues or recommendations. */
465
+ warnings: string[];
466
+ }
467
+
468
+ /**
469
+ * All supported widget type identifiers.
470
+ *
471
+ * - **Display:** chart.*, metric, stat-group, gauge, progress, table, list
472
+ * - **Input:** form, confirm
473
+ * - **Composition:** compose
474
+ * - **Content:** markdown, image, callout
475
+ */
476
+ export declare type WidgetType = ChartType | 'metric' | 'stat-group' | 'gauge' | 'progress' | 'table' | 'list' | 'form' | 'confirm' | 'compose' | 'markdown' | 'image' | 'callout' | 'kv' | 'code' | 'citation' | 'status' | 'steps' | 'rating' | 'video' | 'gallery' | 'actions' | 'divider' | 'header';
477
+
478
+ export { }