@iyulab/u-widgets 0.9.2 → 0.11.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.
@@ -0,0 +1,219 @@
1
+ import { CSSResult } from 'lit';
2
+ import { LitElement } from 'lit';
3
+ import { nothing } from 'lit';
4
+ import { TemplateResult } from 'lit-html';
5
+
6
+ /** Supported input field types for form widgets. */
7
+ declare type FieldType = 'text' | 'email' | 'password' | 'tel' | 'url' | 'textarea' | 'number' | 'select' | 'multiselect' | 'date' | 'datetime' | 'time' | 'toggle' | 'range' | 'radio' | 'checkbox';
8
+
9
+ /**
10
+ * Action button definition.
11
+ *
12
+ * Reserved actions: `"submit"`, `"cancel"`, `"navigate"`.
13
+ * Custom action strings are forwarded to the host via the `u-widget-event`.
14
+ *
15
+ * @example
16
+ * ```json
17
+ * { "label": "Submit", "action": "submit", "style": "primary" }
18
+ * ```
19
+ */
20
+ declare interface UWidgetAction {
21
+ /** Button display text. */
22
+ label: string;
23
+ /** Action identifier emitted in the widget event. */
24
+ action: string;
25
+ /** Visual style hint. */
26
+ style?: 'primary' | 'danger' | 'default';
27
+ /** Whether the button is disabled. */
28
+ disabled?: boolean;
29
+ /** URL for `"navigate"` actions. */
30
+ url?: string;
31
+ }
32
+
33
+ /**
34
+ * Child widget spec inside a compose widget.
35
+ * Inherits `type` and `version` from the parent — no need to repeat them.
36
+ */
37
+ declare interface UWidgetChildSpec extends Omit<UWidgetSpec, 'type' | 'version'> {
38
+ /** Grid column span within the parent compose layout. */
39
+ span?: number;
40
+ /** When true, the child is initially collapsed (uses native `<details>`). */
41
+ collapsed?: boolean;
42
+ }
43
+
44
+ /**
45
+ * Column definition for table widgets.
46
+ *
47
+ * @example
48
+ * ```json
49
+ * { "field": "price", "label": "Price", "format": "currency", "align": "right" }
50
+ * ```
51
+ */
52
+ declare interface UWidgetColumnDefinition {
53
+ /** Data field name to display in this column. */
54
+ field: string;
55
+ /** Display header label. Defaults to the field name. */
56
+ label?: string;
57
+ /** Value formatting hint (e.g., `"currency"`, `"currency:EUR"`, `"percent"`). */
58
+ format?: 'number' | 'currency' | 'percent' | 'date' | 'datetime' | 'bytes';
59
+ /** Text alignment within the column. */
60
+ align?: 'left' | 'center' | 'right';
61
+ }
62
+
63
+ /**
64
+ * Field definition for form/confirm input widgets.
65
+ *
66
+ * @example
67
+ * ```json
68
+ * { "field": "email", "label": "Email", "type": "email", "required": true }
69
+ * ```
70
+ */
71
+ declare interface UWidgetFieldDefinition {
72
+ /** Data field name (maps to `data[field]` for defaults and output). */
73
+ field: string;
74
+ /** Display label. Defaults to the field name. */
75
+ label?: string;
76
+ /** Input type. Defaults to `"text"`. */
77
+ type?: FieldType;
78
+ /** Whether the field must be filled before submit. */
79
+ required?: boolean;
80
+ /** Placeholder text shown when the field is empty. */
81
+ placeholder?: string;
82
+ /** Options for select, multiselect, radio, and checkbox types. */
83
+ options?: string[];
84
+ /** Minimum character length for text inputs. */
85
+ minLength?: number;
86
+ /** Maximum character length for text inputs. */
87
+ maxLength?: number;
88
+ /** Custom regex pattern for validation (e.g. `"^[A-Z]{3}$"`). */
89
+ pattern?: string;
90
+ /** Number of visible rows for textarea type. */
91
+ rows?: number;
92
+ /** Minimum value (number) or date string. */
93
+ min?: number | string;
94
+ /** Maximum value (number) or date string. */
95
+ max?: number | string;
96
+ /** Step increment for number and range inputs. */
97
+ step?: number;
98
+ /** Custom validation error message (overrides locale default). */
99
+ message?: string;
100
+ }
101
+
102
+ /**
103
+ * Mapping connects data fields to visual channels.
104
+ *
105
+ * Which keys are relevant depends on the widget type:
106
+ * - **chart.bar/line/area:** `x`, `y`
107
+ * - **chart.pie/funnel:** `label`, `value`
108
+ * - **chart.scatter:** `x`, `y`, `color`, `size`
109
+ * - **chart.radar:** `axis`, `value`
110
+ * - **table:** `columns`
111
+ * - **list:** `primary`, `secondary`, `avatar`, `icon`, `trailing`
112
+ *
113
+ * When omitted, mapping is auto-inferred from the data shape.
114
+ */
115
+ declare interface UWidgetMapping {
116
+ /** Category axis field (chart x-axis). */
117
+ x?: string;
118
+ /** Value axis field(s). A string for single series, string[] for multi-series. */
119
+ y?: string | string[];
120
+ /** Label field (pie/funnel charts). */
121
+ label?: string;
122
+ /** Value field (pie/funnel/heatmap). */
123
+ value?: string;
124
+ /** Color grouping field (scatter). */
125
+ color?: string;
126
+ /** Size encoding field (scatter bubble). */
127
+ size?: string;
128
+ /** Opacity encoding field (scatter). Maps data values to point opacity (0.1–1.0). */
129
+ opacity?: string;
130
+ /** Axis field (radar chart indicators). */
131
+ axis?: string;
132
+ /** Explicit column definitions for table widgets. */
133
+ columns?: UWidgetColumnDefinition[];
134
+ /** Primary text field (list widget). */
135
+ primary?: string;
136
+ /** Secondary/subtitle text field (list widget). */
137
+ secondary?: string;
138
+ /** Icon letter field (list widget fallback when no avatar). */
139
+ icon?: string;
140
+ /** Avatar image URL field (list widget). */
141
+ avatar?: string;
142
+ /** Trailing value field displayed on the right (list widget). */
143
+ trailing?: string;
144
+ /** Badge/tag field (list widget). */
145
+ badge?: string;
146
+ }
147
+
148
+ /**
149
+ * The u-widget spec envelope — a single, consistent structure for all widgets.
150
+ *
151
+ * Only `widget` is required. All other fields are optional or auto-inferred.
152
+ *
153
+ * @example
154
+ * ```ts
155
+ * const spec: UWidgetSpec = {
156
+ * widget: 'chart.bar',
157
+ * data: [{ name: 'A', value: 30 }, { name: 'B', value: 70 }],
158
+ * mapping: { x: 'name', y: 'value' },
159
+ * };
160
+ * ```
161
+ */
162
+ declare interface UWidgetSpec {
163
+ /** Widget type identifier (e.g., `"chart.bar"`, `"metric"`, `"form"`). */
164
+ widget: string;
165
+ /** Unique identifier for event correlation and compose children. */
166
+ id?: string;
167
+ /** Optional display title rendered above the widget. */
168
+ title?: string;
169
+ /** Optional description text rendered below the title. */
170
+ description?: string;
171
+ /** Inline data — an object (metric/gauge) or array of records (chart/table). */
172
+ data?: Record<string, unknown> | Record<string, unknown>[];
173
+ /** Maps data fields to visual channels. Auto-inferred when omitted. */
174
+ mapping?: UWidgetMapping;
175
+ /** Field definitions for form/confirm widgets. */
176
+ fields?: UWidgetFieldDefinition[];
177
+ /** Formdown shorthand syntax for form fields (mutually exclusive with `fields`). */
178
+ formdown?: string;
179
+ /**
180
+ * Widget-specific rendering options.
181
+ *
182
+ * Chart widgets support an `echarts` sub-key for native ECharts option passthrough:
183
+ * ```json
184
+ * { "options": { "echarts": { "tooltip": { "trigger": "axis" } } } }
185
+ * ```
186
+ * All keys in `options.echarts` are deep-merged into the generated ECharts option.
187
+ * @see https://echarts.apache.org/en/option.html
188
+ */
189
+ options?: Record<string, unknown>;
190
+ /** Action buttons displayed below the widget. */
191
+ actions?: UWidgetAction[];
192
+ /** Interchange format type marker. Always `"u-widget"` if present. */
193
+ type?: 'u-widget';
194
+ /** Interchange format version string. */
195
+ version?: string;
196
+ /** Layout mode for compose widget: `"stack"` (default), `"row"`, or `"grid"`. */
197
+ layout?: 'stack' | 'row' | 'grid';
198
+ /** Number of grid columns for compose `"grid"` layout. Default: 2. */
199
+ columns?: number;
200
+ /** Child widget specs for compose widget. */
201
+ children?: UWidgetChildSpec[];
202
+ /** Grid column span for children inside a compose `"grid"` layout. */
203
+ span?: number;
204
+ }
205
+
206
+ /**
207
+ * <uw-math> — LaTeX math expression renderer via KaTeX.
208
+ *
209
+ * Uses MathML output for zero-CSS rendering in Shadow DOM.
210
+ * Loaded via the `u-widgets/math` entry point. Requires `katex` as a peer dependency.
211
+ */
212
+ export declare class UwMath extends LitElement {
213
+ static styles: CSSResult[];
214
+ spec: UWidgetSpec | null;
215
+ theme: string | null;
216
+ render(): typeof nothing | TemplateResult<1>;
217
+ }
218
+
219
+ export { }
@@ -0,0 +1,95 @@
1
+ import { css as m, LitElement as u, nothing as p, html as c } from "lit";
2
+ import { property as d, customElement as h } from "lit/decorators.js";
3
+ import { t as f } from "./tokens-byMop3gk.js";
4
+ import g from "katex";
5
+ var v = Object.defineProperty, y = Object.getOwnPropertyDescriptor, l = (o, t, a, r) => {
6
+ for (var e = r > 1 ? void 0 : r ? y(t, a) : t, s = o.length - 1, n; s >= 0; s--)
7
+ (n = o[s]) && (e = (r ? n(t, a, e) : n(e)) || e);
8
+ return r && e && v(t, a, e), e;
9
+ };
10
+ let i = class extends u {
11
+ constructor() {
12
+ super(...arguments), this.spec = null, this.theme = null;
13
+ }
14
+ render() {
15
+ if (!this.spec) return p;
16
+ const o = this.spec.data;
17
+ if (!o) return p;
18
+ const t = String(o.expression ?? "").trim();
19
+ if (!t) return p;
20
+ const r = !!((this.spec.options ?? {}).displayMode ?? !1);
21
+ try {
22
+ const e = g.renderToString(t, {
23
+ displayMode: r,
24
+ throwOnError: !0,
25
+ output: "mathml"
26
+ });
27
+ return c`
28
+ <div
29
+ class="math-block"
30
+ part="math"
31
+ data-display=${String(r)}
32
+ .innerHTML=${e}
33
+ ></div>
34
+ `;
35
+ } catch (e) {
36
+ const s = e instanceof Error ? e.message : "Invalid expression";
37
+ return c`
38
+ <div class="math-error" part="math-error">
39
+ ${s}
40
+ <code>${t}</code>
41
+ </div>
42
+ `;
43
+ }
44
+ }
45
+ };
46
+ i.styles = [f, m`
47
+ :host {
48
+ display: block;
49
+ font-family: system-ui, -apple-system, sans-serif;
50
+ container: uw-math / inline-size;
51
+ }
52
+
53
+ .math-block {
54
+ color: var(--u-widget-text, #1a1a2e);
55
+ overflow-x: auto;
56
+ font-size: 1rem;
57
+ line-height: 1.6;
58
+ }
59
+
60
+ .math-block[data-display="true"] {
61
+ text-align: center;
62
+ padding: 8px 0;
63
+ font-size: 1.2rem;
64
+ }
65
+
66
+ .math-error {
67
+ padding: 8px 12px;
68
+ border-radius: 4px;
69
+ border: 1px solid var(--u-widget-negative, #dc2626);
70
+ background: color-mix(in srgb, var(--u-widget-negative, #dc2626) 8%, var(--u-widget-bg, #fff));
71
+ font-size: 0.8125rem;
72
+ color: var(--u-widget-negative, #dc2626);
73
+ }
74
+
75
+ .math-error code {
76
+ display: block;
77
+ margin-top: 4px;
78
+ font-size: 0.75rem;
79
+ color: var(--u-widget-text-secondary, #64748b);
80
+ word-break: break-all;
81
+ }
82
+ `];
83
+ l([
84
+ d({ type: Object })
85
+ ], i.prototype, "spec", 2);
86
+ l([
87
+ d({ type: String, reflect: !0 })
88
+ ], i.prototype, "theme", 2);
89
+ i = l([
90
+ h("uw-math")
91
+ ], i);
92
+ export {
93
+ i as UwMath
94
+ };
95
+ //# sourceMappingURL=u-widgets-math.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"u-widgets-math.js","sources":["../src/elements/uw-math.ts"],"sourcesContent":["import { LitElement, html, css, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport type { UWidgetSpec } from '../core/types.js';\nimport { themeStyles } from '../styles/tokens.js';\nimport katex from 'katex';\n\n/**\n * <uw-math> — LaTeX math expression renderer via KaTeX.\n *\n * Uses MathML output for zero-CSS rendering in Shadow DOM.\n * Loaded via the `u-widgets/math` entry point. Requires `katex` as a peer dependency.\n */\n@customElement('uw-math')\nexport class UwMath extends LitElement {\n static styles = [themeStyles, css`\n :host {\n display: block;\n font-family: system-ui, -apple-system, sans-serif;\n container: uw-math / inline-size;\n }\n\n .math-block {\n color: var(--u-widget-text, #1a1a2e);\n overflow-x: auto;\n font-size: 1rem;\n line-height: 1.6;\n }\n\n .math-block[data-display=\"true\"] {\n text-align: center;\n padding: 8px 0;\n font-size: 1.2rem;\n }\n\n .math-error {\n padding: 8px 12px;\n border-radius: 4px;\n border: 1px solid var(--u-widget-negative, #dc2626);\n background: color-mix(in srgb, var(--u-widget-negative, #dc2626) 8%, var(--u-widget-bg, #fff));\n font-size: 0.8125rem;\n color: var(--u-widget-negative, #dc2626);\n }\n\n .math-error code {\n display: block;\n margin-top: 4px;\n font-size: 0.75rem;\n color: var(--u-widget-text-secondary, #64748b);\n word-break: break-all;\n }\n `];\n\n @property({ type: Object })\n spec: UWidgetSpec | null = null;\n\n @property({ type: String, reflect: true })\n theme: string | null = null;\n\n render() {\n if (!this.spec) return nothing;\n\n const data = this.spec.data as Record<string, unknown> | undefined;\n if (!data) return nothing;\n\n const expression = String(data.expression ?? '').trim();\n if (!expression) return nothing;\n\n const options = (this.spec.options ?? {}) as Record<string, unknown>;\n const displayMode = Boolean(options.displayMode ?? false);\n\n try {\n // SAFETY: output must be 'mathml' — pure MathML has no script/event vectors,\n // making .innerHTML safe. Switching to 'html' or 'htmlAndMathml' would require\n // KaTeX CSS and introduce potential XSS via custom macros.\n const rendered = katex.renderToString(expression, {\n displayMode,\n throwOnError: true,\n output: 'mathml',\n });\n\n return html`\n <div\n class=\"math-block\"\n part=\"math\"\n data-display=${String(displayMode)}\n .innerHTML=${rendered}\n ></div>\n `;\n } catch (e) {\n const msg = e instanceof Error ? e.message : 'Invalid expression';\n return html`\n <div class=\"math-error\" part=\"math-error\">\n ${msg}\n <code>${expression}</code>\n </div>\n `;\n }\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'uw-math': UwMath;\n }\n}\n"],"names":["UwMath","LitElement","nothing","data","expression","displayMode","rendered","katex","html","msg","themeStyles","css","__decorateClass","property","customElement"],"mappings":";;;;;;;;;AAaO,IAAMA,IAAN,cAAqBC,EAAW;AAAA,EAAhC,cAAA;AAAA,UAAA,GAAA,SAAA,GAwCL,KAAA,OAA2B,MAG3B,KAAA,QAAuB;AAAA,EAAA;AAAA,EAEvB,SAAS;AACP,QAAI,CAAC,KAAK,KAAM,QAAOC;AAEvB,UAAMC,IAAO,KAAK,KAAK;AACvB,QAAI,CAACA,EAAM,QAAOD;AAElB,UAAME,IAAa,OAAOD,EAAK,cAAc,EAAE,EAAE,KAAA;AACjD,QAAI,CAACC,EAAY,QAAOF;AAGxB,UAAMG,IAAc,IADH,KAAK,KAAK,WAAW,CAAA,GACF,eAAe;AAEnD,QAAI;AAIF,YAAMC,IAAWC,EAAM,eAAeH,GAAY;AAAA,QAChD,aAAAC;AAAA,QACA,cAAc;AAAA,QACd,QAAQ;AAAA,MAAA,CACT;AAED,aAAOG;AAAA;AAAA;AAAA;AAAA,yBAIY,OAAOH,CAAW,CAAC;AAAA,uBACrBC,CAAQ;AAAA;AAAA;AAAA,IAG3B,SAAS,GAAG;AACV,YAAMG,IAAM,aAAa,QAAQ,EAAE,UAAU;AAC7C,aAAOD;AAAA;AAAA,YAEDC,CAAG;AAAA,kBACGL,CAAU;AAAA;AAAA;AAAA,IAGxB;AAAA,EACF;AACF;AArFaJ,EACJ,SAAS,CAACU,GAAaC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAoC7B;AAGDC,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAvCfb,EAwCX,WAAA,QAAA,CAAA;AAGAY,EAAA;AAAA,EADCC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GA1C9Bb,EA2CX,WAAA,SAAA,CAAA;AA3CWA,IAANY,EAAA;AAAA,EADNE,EAAc,SAAS;AAAA,GACXd,CAAA;"}
@@ -0,0 +1,265 @@
1
+ import { CSSResult } from 'lit';
2
+ import { EventName } from '@lit/react';
3
+ import { LitElement } from 'lit';
4
+ import { nothing } from 'lit';
5
+ import { ReactWebComponent } from '@lit/react';
6
+ import { TemplateResult } from 'lit-html';
7
+
8
+ /** Supported input field types for form widgets. */
9
+ declare type FieldType = 'text' | 'email' | 'password' | 'tel' | 'url' | 'textarea' | 'number' | 'select' | 'multiselect' | 'date' | 'datetime' | 'time' | 'toggle' | 'range' | 'radio' | 'checkbox';
10
+
11
+ export declare const UWidget: ReactWebComponent<UWidget_2, {
12
+ onWidgetEvent: EventName<CustomEvent>;
13
+ }>;
14
+
15
+ /**
16
+ * <u-widget> — Entry point router element.
17
+ * Reads spec.widget and delegates to the appropriate sub-component.
18
+ *
19
+ * Supports theme attribute: theme="dark" | theme="light" | (auto via prefers-color-scheme)
20
+ */
21
+ declare class UWidget_2 extends LitElement {
22
+ static styles: CSSResult[];
23
+ spec: UWidgetSpec | null;
24
+ /** Theme override: "dark" | "light" | null (auto via prefers-color-scheme). */
25
+ theme: string | null;
26
+ /** Locale tag (e.g. 'ko', 'en-US'). Propagated to sub-components via spec.options.locale. */
27
+ locale: string | null;
28
+ connectedCallback(): void;
29
+ disconnectedCallback(): void;
30
+ private _handleInternalEvent;
31
+ render(): typeof nothing | TemplateResult<1>;
32
+ private renderWidget;
33
+ /** Render standalone "actions" widget — a group of action buttons. */
34
+ private renderActionsWidget;
35
+ /** Render inline divider widget. */
36
+ private renderDivider;
37
+ /** Render inline header widget. */
38
+ private renderHeader;
39
+ /** Dispatch an action event from the global action bar or actions widget. */
40
+ private _dispatchAction;
41
+ private renderFallback;
42
+ private renderError;
43
+ }
44
+
45
+ /**
46
+ * Action button definition.
47
+ *
48
+ * Reserved actions: `"submit"`, `"cancel"`, `"navigate"`.
49
+ * Custom action strings are forwarded to the host via the `u-widget-event`.
50
+ *
51
+ * @example
52
+ * ```json
53
+ * { "label": "Submit", "action": "submit", "style": "primary" }
54
+ * ```
55
+ */
56
+ export declare interface UWidgetAction {
57
+ /** Button display text. */
58
+ label: string;
59
+ /** Action identifier emitted in the widget event. */
60
+ action: string;
61
+ /** Visual style hint. */
62
+ style?: 'primary' | 'danger' | 'default';
63
+ /** Whether the button is disabled. */
64
+ disabled?: boolean;
65
+ /** URL for `"navigate"` actions. */
66
+ url?: string;
67
+ }
68
+
69
+ /**
70
+ * Child widget spec inside a compose widget.
71
+ * Inherits `type` and `version` from the parent — no need to repeat them.
72
+ */
73
+ declare interface UWidgetChildSpec extends Omit<UWidgetSpec, 'type' | 'version'> {
74
+ /** Grid column span within the parent compose layout. */
75
+ span?: number;
76
+ /** When true, the child is initially collapsed (uses native `<details>`). */
77
+ collapsed?: boolean;
78
+ }
79
+
80
+ /**
81
+ * Column definition for table widgets.
82
+ *
83
+ * @example
84
+ * ```json
85
+ * { "field": "price", "label": "Price", "format": "currency", "align": "right" }
86
+ * ```
87
+ */
88
+ declare interface UWidgetColumnDefinition {
89
+ /** Data field name to display in this column. */
90
+ field: string;
91
+ /** Display header label. Defaults to the field name. */
92
+ label?: string;
93
+ /** Value formatting hint (e.g., `"currency"`, `"currency:EUR"`, `"percent"`). */
94
+ format?: 'number' | 'currency' | 'percent' | 'date' | 'datetime' | 'bytes';
95
+ /** Text alignment within the column. */
96
+ align?: 'left' | 'center' | 'right';
97
+ }
98
+
99
+ /**
100
+ * Event payload emitted by `<u-widget>` via the `u-widget-event` custom event.
101
+ *
102
+ * | type | trigger | payload |
103
+ * |---|---|---|
104
+ * | `submit` | Form submit button | Form field values |
105
+ * | `action` | Custom action button | Action data |
106
+ * | `change` | Input value change | Changed field and value |
107
+ * | `select` | Chart element click | Selected data point |
108
+ */
109
+ export declare interface UWidgetEvent {
110
+ /** Event category. */
111
+ type: 'submit' | 'action' | 'change' | 'select';
112
+ /** The widget type that emitted this event. */
113
+ widget: string;
114
+ /** Widget instance `id` (if set in the spec). */
115
+ id?: string;
116
+ /** Action identifier (for `"action"` type events). */
117
+ action?: string;
118
+ /** Event payload data. */
119
+ data?: Record<string, unknown>;
120
+ }
121
+
122
+ /**
123
+ * Field definition for form/confirm input widgets.
124
+ *
125
+ * @example
126
+ * ```json
127
+ * { "field": "email", "label": "Email", "type": "email", "required": true }
128
+ * ```
129
+ */
130
+ declare interface UWidgetFieldDefinition {
131
+ /** Data field name (maps to `data[field]` for defaults and output). */
132
+ field: string;
133
+ /** Display label. Defaults to the field name. */
134
+ label?: string;
135
+ /** Input type. Defaults to `"text"`. */
136
+ type?: FieldType;
137
+ /** Whether the field must be filled before submit. */
138
+ required?: boolean;
139
+ /** Placeholder text shown when the field is empty. */
140
+ placeholder?: string;
141
+ /** Options for select, multiselect, radio, and checkbox types. */
142
+ options?: string[];
143
+ /** Minimum character length for text inputs. */
144
+ minLength?: number;
145
+ /** Maximum character length for text inputs. */
146
+ maxLength?: number;
147
+ /** Custom regex pattern for validation (e.g. `"^[A-Z]{3}$"`). */
148
+ pattern?: string;
149
+ /** Number of visible rows for textarea type. */
150
+ rows?: number;
151
+ /** Minimum value (number) or date string. */
152
+ min?: number | string;
153
+ /** Maximum value (number) or date string. */
154
+ max?: number | string;
155
+ /** Step increment for number and range inputs. */
156
+ step?: number;
157
+ /** Custom validation error message (overrides locale default). */
158
+ message?: string;
159
+ }
160
+
161
+ /**
162
+ * Mapping connects data fields to visual channels.
163
+ *
164
+ * Which keys are relevant depends on the widget type:
165
+ * - **chart.bar/line/area:** `x`, `y`
166
+ * - **chart.pie/funnel:** `label`, `value`
167
+ * - **chart.scatter:** `x`, `y`, `color`, `size`
168
+ * - **chart.radar:** `axis`, `value`
169
+ * - **table:** `columns`
170
+ * - **list:** `primary`, `secondary`, `avatar`, `icon`, `trailing`
171
+ *
172
+ * When omitted, mapping is auto-inferred from the data shape.
173
+ */
174
+ declare interface UWidgetMapping {
175
+ /** Category axis field (chart x-axis). */
176
+ x?: string;
177
+ /** Value axis field(s). A string for single series, string[] for multi-series. */
178
+ y?: string | string[];
179
+ /** Label field (pie/funnel charts). */
180
+ label?: string;
181
+ /** Value field (pie/funnel/heatmap). */
182
+ value?: string;
183
+ /** Color grouping field (scatter). */
184
+ color?: string;
185
+ /** Size encoding field (scatter bubble). */
186
+ size?: string;
187
+ /** Opacity encoding field (scatter). Maps data values to point opacity (0.1–1.0). */
188
+ opacity?: string;
189
+ /** Axis field (radar chart indicators). */
190
+ axis?: string;
191
+ /** Explicit column definitions for table widgets. */
192
+ columns?: UWidgetColumnDefinition[];
193
+ /** Primary text field (list widget). */
194
+ primary?: string;
195
+ /** Secondary/subtitle text field (list widget). */
196
+ secondary?: string;
197
+ /** Icon letter field (list widget fallback when no avatar). */
198
+ icon?: string;
199
+ /** Avatar image URL field (list widget). */
200
+ avatar?: string;
201
+ /** Trailing value field displayed on the right (list widget). */
202
+ trailing?: string;
203
+ /** Badge/tag field (list widget). */
204
+ badge?: string;
205
+ }
206
+
207
+ /**
208
+ * The u-widget spec envelope — a single, consistent structure for all widgets.
209
+ *
210
+ * Only `widget` is required. All other fields are optional or auto-inferred.
211
+ *
212
+ * @example
213
+ * ```ts
214
+ * const spec: UWidgetSpec = {
215
+ * widget: 'chart.bar',
216
+ * data: [{ name: 'A', value: 30 }, { name: 'B', value: 70 }],
217
+ * mapping: { x: 'name', y: 'value' },
218
+ * };
219
+ * ```
220
+ */
221
+ export declare interface UWidgetSpec {
222
+ /** Widget type identifier (e.g., `"chart.bar"`, `"metric"`, `"form"`). */
223
+ widget: string;
224
+ /** Unique identifier for event correlation and compose children. */
225
+ id?: string;
226
+ /** Optional display title rendered above the widget. */
227
+ title?: string;
228
+ /** Optional description text rendered below the title. */
229
+ description?: string;
230
+ /** Inline data — an object (metric/gauge) or array of records (chart/table). */
231
+ data?: Record<string, unknown> | Record<string, unknown>[];
232
+ /** Maps data fields to visual channels. Auto-inferred when omitted. */
233
+ mapping?: UWidgetMapping;
234
+ /** Field definitions for form/confirm widgets. */
235
+ fields?: UWidgetFieldDefinition[];
236
+ /** Formdown shorthand syntax for form fields (mutually exclusive with `fields`). */
237
+ formdown?: string;
238
+ /**
239
+ * Widget-specific rendering options.
240
+ *
241
+ * Chart widgets support an `echarts` sub-key for native ECharts option passthrough:
242
+ * ```json
243
+ * { "options": { "echarts": { "tooltip": { "trigger": "axis" } } } }
244
+ * ```
245
+ * All keys in `options.echarts` are deep-merged into the generated ECharts option.
246
+ * @see https://echarts.apache.org/en/option.html
247
+ */
248
+ options?: Record<string, unknown>;
249
+ /** Action buttons displayed below the widget. */
250
+ actions?: UWidgetAction[];
251
+ /** Interchange format type marker. Always `"u-widget"` if present. */
252
+ type?: 'u-widget';
253
+ /** Interchange format version string. */
254
+ version?: string;
255
+ /** Layout mode for compose widget: `"stack"` (default), `"row"`, or `"grid"`. */
256
+ layout?: 'stack' | 'row' | 'grid';
257
+ /** Number of grid columns for compose `"grid"` layout. Default: 2. */
258
+ columns?: number;
259
+ /** Child widget specs for compose widget. */
260
+ children?: UWidgetChildSpec[];
261
+ /** Grid column span for children inside a compose `"grid"` layout. */
262
+ span?: number;
263
+ }
264
+
265
+ export { }
@@ -0,0 +1,15 @@
1
+ import e from "react";
2
+ import { createComponent as t } from "@lit/react";
3
+ import { UWidget as o } from "@iyulab/u-widgets";
4
+ const n = t({
5
+ tagName: "u-widget",
6
+ elementClass: o,
7
+ react: e,
8
+ events: {
9
+ onWidgetEvent: "u-widget-event"
10
+ }
11
+ });
12
+ export {
13
+ n as UWidget
14
+ };
15
+ //# sourceMappingURL=u-widgets-react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"u-widgets-react.js","sources":["../src/react.ts"],"sourcesContent":["/**\n * @module u-widgets/react\n *\n * React wrapper for `<u-widget>` custom element.\n * Uses `@lit/react` to bridge Lit properties and React props.\n *\n * Requires the base package to be imported separately to register the element:\n *\n * @example\n * ```tsx\n * import '@iyulab/u-widgets'; // registers <u-widget>\n * import { UWidget } from '@iyulab/u-widgets/react';\n *\n * function App() {\n * return (\n * <UWidget\n * spec={{ widget: 'metric', data: { value: 42 } }}\n * onWidgetEvent={(e) => console.log(e.detail)}\n * />\n * );\n * }\n * ```\n */\nimport React from 'react';\nimport { createComponent, type EventName } from '@lit/react';\nimport { UWidget as UWidgetElement } from '@iyulab/u-widgets';\n\nexport const UWidget = createComponent({\n tagName: 'u-widget',\n elementClass: UWidgetElement,\n react: React,\n events: {\n onWidgetEvent: 'u-widget-event' as EventName<CustomEvent>,\n },\n});\n\n// Re-export core types for convenience\nexport type { UWidgetSpec, UWidgetEvent, UWidgetAction } from '@iyulab/u-widgets';\n"],"names":["UWidget","createComponent","UWidgetElement","React"],"mappings":";;;AA2BO,MAAMA,IAAUC,EAAgB;AAAA,EACrC,SAAS;AAAA,EACT,cAAcC;AAAAA,EACd,OAAOC;AAAA,EACP,QAAQ;AAAA,IACN,eAAe;AAAA,EAAA;AAEnB,CAAC;"}