import { CSSResult } from 'lit'; import { LitElement } from 'lit'; import { nothing } from 'lit'; import { TemplateResult } from 'lit-html'; /** * Chart widget type identifiers using dot notation (`chart.`). * * @example * ```json * { "widget": "chart.bar", "data": [...] } * ``` */ 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' | 'chart.histogram'; /** Supported input field types for form widgets. */ export declare type FieldType = 'text' | 'email' | 'password' | 'tel' | 'url' | 'textarea' | 'number' | 'select' | 'multiselect' | 'date' | 'datetime' | 'time' | 'toggle' | 'range' | 'radio' | 'checkbox'; /** * Format a template string by replacing {key} placeholders. */ export declare function formatTemplate(template: string, params: Record): string; /** * Format a value according to a format hint string. * * Supported formats: `"number"`, `"currency"`, `"currency:EUR"`, `"percent"`, * `"date"`, `"datetime"`, `"bytes"`. Returns `String(value)` for unknown formats. * * @param value - The value to format (coerced to number where needed). * @param format - Format hint, optionally with a parameter after `:` (e.g., `"currency:USD"`). * @param locale - BCP 47 locale tag for number/currency formatting. Falls back to browser default. * @returns Formatted string. Null/undefined values render as `—` (em-dash) so * empty cells in tables/metrics are visually distinct from "0". * * @example * ```ts * formatValue(1234.5, 'number') // "1,234.5" * formatValue(1234.5, 'currency:EUR') // "€1,234.50" * formatValue(73, 'percent') // "73%" * formatValue(1536000, 'bytes') // "1.5 MB" * formatValue(null, 'currency:KRW') // "—" * ``` */ export declare function formatValue(value: unknown, format?: string, locale?: string): string; export declare type FormdownParser = (input: string, data?: Record) => FormdownResult; /** * Parse a formdown string into fields and actions. * * Formdown syntax (subset): * @fieldName*(Label){opt1,opt2}: type[] * @[action "Label"] * * Type markers: * [] text @[] email #[] number * ?[] password %[] tel &[] url * T{n}[] textarea d[] date dt[] datetime * t[] time s[] select r[] radio * c[] checkbox ^[] toggle R[] range * ms[] multiselect * * * = required, (Label) = display label, {a,b,c} = options */ export declare interface FormdownResult { fields: UWidgetFieldDefinition[]; actions: UWidgetAction[]; } /** * Get the English defaults (for testing / reference). */ export declare function getDefaultLocale(): UWidgetLocaleStrings; /** * Get the active global default locale set via setDefaultLocale(). * Returns undefined if not set. */ export declare function getEffectiveLocale(): string | undefined; export declare function getFormdownParser(): FormdownParser; /** * Resolve locale strings for the given language tag. * * Resolution order: * 1. Exact match (e.g. 'ko-KR') * 2. Base language (e.g. 'ko') * 3. English fallback */ export declare function getLocaleStrings(lang?: string): UWidgetLocaleStrings; /** * Auto-infer a mapping from data shape and widget type. * * Inference rules: * - **chart.bar/line/area:** first string field → `x`, number fields → `y` * - **chart.pie/funnel:** first string → `label`, first number → `value` * - **chart.scatter:** first two number fields → `x`, `y` * - **chart.radar:** first string → `axis`, number fields → `y` * - **chart.heatmap:** two string fields + number → `x`, `y`, `value` * - **chart.box:** string → `x`, five number fields (min/q1/median/q3/max) → `y` * - **table:** all keys → `columns` * - **list:** first string → `primary`, second string → `secondary` * - **metric/gauge/progress/form:** no mapping needed (returns `undefined`) * * @param widget - Widget type identifier. * @param data - The spec's `data` field (object or array of records). * @returns Inferred mapping, or `undefined` if not applicable. * * @example * ```ts * infer('chart.bar', [{ name: 'A', value: 30 }]); * // → { x: 'name', y: 'value' } * ``` */ export declare function infer(widget: string, data: Record | Record[] | undefined): UWidgetMapping | undefined; /** * Type guard that checks if a value is a valid {@link UWidgetSpec}. * * Equivalent to `validate(value).valid`, but narrows the TypeScript type. * * @param value - The value to check. * @returns `true` if the value passes validation. */ export declare function isWidgetSpec(value: unknown): value is UWidgetSpec; /** * Normalize a spec for internal processing. * * Transformations applied: * 1. Deprecated `mapping.fields` → top-level `fields` * 2. `formdown` string → parsed `fields` + `actions` * * Returns a shallow copy; the original spec is not mutated. * * @param spec - The widget spec to normalize. * @returns A normalized copy of the spec. */ export declare function normalize(spec: UWidgetSpec): UWidgetSpec; export declare function parseFormdown(input: string, _data?: Record): FormdownResult; export declare function registerFormdownParser(parser: FormdownParser): void; /** * Register a locale for u-widgets chrome strings. * Partial overrides are merged with English defaults. */ export declare function registerLocale(lang: string, strings: Partial): void; /** * Resolve the locale to use for a widget. * * Priority: widgetLocale > setDefaultLocale() > document.lang > undefined */ export declare function resolveLocale(widgetLocale?: string | null): string | undefined; /** * Set the global default locale for all u-widgets. * * Resolution order (highest priority first): * 1. Per-widget `locale` attribute/property * 2. setDefaultLocale() value * 3. document.documentElement.lang (browser only) * 4. English fallback * * @example * ```ts * import { setDefaultLocale } from '@iyulab/u-widgets'; * setDefaultLocale('ko-KR'); * ``` */ export declare function setDefaultLocale(lang: string | undefined): void; /** * Widget name suggestion for typo detection. * * Compares an unrecognized widget name against all known types * using Levenshtein distance and returns the closest match. */ /** * Suggest a known widget name for a potentially mistyped input. * * Returns the closest match if the Levenshtein distance is within * a reasonable threshold (max 3, and less than half the input length). * Returns `undefined` if no good match is found. * * @param input - The unrecognized widget name. * @returns The suggested widget name, or `undefined`. * * @example * ```ts * suggestWidget('chart.barr') // → 'chart.bar' * suggestWidget('metrc') // → 'metric' * suggestWidget('xyzabc') // → undefined * ``` */ export declare function suggestWidget(input: string): string | undefined; /** * — Entry point router element. * Reads spec.widget and delegates to the appropriate sub-component. * * Supports theme attribute: theme="dark" | theme="light" | (auto via color-scheme inheritance) */ export declare class UWidget extends LitElement { static styles: CSSResult[]; spec: UWidgetSpec | null; /** Theme override: "dark" | "light" | null (auto via color-scheme inheritance). */ theme: string | null; /** Locale tag (e.g. 'ko', 'en-US'). Propagated to sub-components via spec.options.locale. */ locale: string | null; connectedCallback(): void; disconnectedCallback(): void; private _handleInternalEvent; render(): typeof nothing | TemplateResult<1>; private renderWidget; /** Render standalone "actions" widget — a group of action buttons. */ private renderActionsWidget; /** Render inline divider widget. */ private renderDivider; /** Render inline header widget. */ private renderHeader; /** Dispatch an action event from the global action bar or actions widget. */ private _dispatchAction; private renderFallback; private renderError; } /** * Action button definition. * * Reserved actions: `"submit"`, `"cancel"`, `"navigate"`. * Custom action strings are forwarded to the host via the `u-widget-event`. * * @example * ```json * { "label": "Submit", "action": "submit", "style": "primary" } * ``` */ export declare interface UWidgetAction { /** Button display text. */ label: string; /** Action identifier emitted in the widget event. */ action: string; /** Visual style hint. */ style?: 'primary' | 'danger' | 'default'; /** Whether the button is disabled. */ disabled?: boolean; /** URL for `"navigate"` actions. */ url?: string; } /** * Child widget spec inside a compose widget. * Inherits `type` and `version` from the parent — no need to repeat them. */ export declare interface UWidgetChildSpec extends Omit { /** Grid column span within the parent compose layout. */ span?: number; /** When true, the child is initially collapsed (uses native `
`). */ collapsed?: boolean; } /** * Column definition for table widgets. * * @example * ```json * { "field": "price", "label": "Price", "format": "currency", "align": "right" } * ``` */ export declare interface UWidgetColumnDefinition { /** Data field name to display in this column. */ field: string; /** Display header label. Defaults to the field name. */ label?: string; /** Value formatting hint (e.g., `"currency"`, `"currency:EUR"`, `"percent"`). */ format?: 'number' | 'currency' | 'percent' | 'date' | 'datetime' | 'bytes'; /** Text alignment within the column. */ align?: 'left' | 'center' | 'right'; } export declare interface UWidgetElementProps { /** Widget spec — object (via property binding) or JSON string (via attribute). */ spec?: UWidgetSpec | string; /** Theme override. Omit for color-scheme auto-detection. */ theme?: 'light' | 'dark'; /** BCP 47 locale tag, e.g. 'ko-KR'. */ locale?: string; id?: string; class?: string; style?: string; [key: string]: unknown; } /** * Event payload emitted by `` via the `u-widget-event` custom event. * * | type | trigger | payload | * |---|---|---| * | `submit` | Form submit button | Form field values | * | `action` | Custom action button | Action data | * | `change` | Input value change | Changed field and value | * | `select` | Chart element click | Selected data point | */ export declare interface UWidgetEvent { /** Event category. */ type: 'submit' | 'action' | 'change' | 'select'; /** The widget type that emitted this event. */ widget: string; /** Widget instance `id` (if set in the spec). */ id?: string; /** Action identifier (for `"action"` type events). */ action?: string; /** Event payload data. */ data?: Record; } /** * Field definition for form/confirm input widgets. * * @example * ```json * { "field": "email", "label": "Email", "type": "email", "required": true } * ``` */ export declare interface UWidgetFieldDefinition { /** Data field name (maps to `data[field]` for defaults and output). */ field: string; /** Display label. Defaults to the field name. */ label?: string; /** Input type. Defaults to `"text"`. */ type?: FieldType; /** Whether the field must be filled before submit. */ required?: boolean; /** Placeholder text shown when the field is empty. */ placeholder?: string; /** Options for select, multiselect, radio, and checkbox types. */ options?: string[]; /** Minimum character length for text inputs. */ minLength?: number; /** Maximum character length for text inputs. */ maxLength?: number; /** Custom regex pattern for validation (e.g. `"^[A-Z]{3}$"`). */ pattern?: string; /** Number of visible rows for textarea type. */ rows?: number; /** Minimum value (number) or date string. */ min?: number | string; /** Maximum value (number) or date string. */ max?: number | string; /** Step increment for number and range inputs. */ step?: number; /** Custom validation error message (overrides locale default). */ message?: string; } /** * Lightweight locale registry for u-widgets. * * Scope: library-internal chrome strings only (validation messages, * pagination labels, ARIA labels). NOT a general i18n framework. * * English is the built-in default. Consumers register other locales: * registerLocale('ko', { prev: '이전', next: '다음', ... }); */ export declare interface UWidgetLocaleStrings { prev: string; next: string; searchPlaceholder: string; searchTable: string; previousPage: string; nextPage: string; tablePagination: string; dataTable: string; required: string; minLength: string; maxLength: string; minValue: string; maxValue: string; invalidEmail: string; invalidUrl: string; invalidPattern: string; } /** * Mapping connects data fields to visual channels. * * Which keys are relevant depends on the widget type: * - **chart.bar/line/area:** `x`, `y` * - **chart.pie/funnel:** `label`, `value` * - **chart.scatter:** `x`, `y`, `color`, `size` * - **chart.radar:** `axis`, `value` * - **table:** `columns` * - **list:** `primary`, `secondary`, `avatar`, `icon`, `trailing` * * When omitted, mapping is auto-inferred from the data shape. */ export declare interface UWidgetMapping { /** Category axis field (chart x-axis). */ x?: string; /** Value axis field(s). A string for single series, string[] for multi-series. */ y?: string | string[]; /** Label field (pie/funnel charts). */ label?: string; /** Value field (pie/funnel/heatmap). */ value?: string; /** Color grouping field (scatter). */ color?: string; /** Size encoding field (scatter bubble). */ size?: string; /** Opacity encoding field (scatter). Maps data values to point opacity (0.1–1.0). */ opacity?: string; /** Axis field (radar chart indicators). */ axis?: string; /** Explicit column definitions for table widgets. */ columns?: UWidgetColumnDefinition[]; /** Primary text field (list widget). */ primary?: string; /** Secondary/subtitle text field (list widget). */ secondary?: string; /** Icon letter field (list widget fallback when no avatar). */ icon?: string; /** Avatar image URL field (list widget). */ avatar?: string; /** Trailing value field displayed on the right (list widget). */ trailing?: string; /** Badge/tag field (list widget). */ badge?: string; } /** * The u-widget spec envelope — a single, consistent structure for all widgets. * * Only `widget` is required. All other fields are optional or auto-inferred. * * @example * ```ts * const spec: UWidgetSpec = { * widget: 'chart.bar', * data: [{ name: 'A', value: 30 }, { name: 'B', value: 70 }], * mapping: { x: 'name', y: 'value' }, * }; * ``` */ export declare interface UWidgetSpec { /** Widget type identifier (e.g., `"chart.bar"`, `"metric"`, `"form"`). */ widget: string; /** Unique identifier for event correlation and compose children. */ id?: string; /** Optional display title rendered above the widget. */ title?: string; /** Optional description text rendered below the title. */ description?: string; /** Inline data — an object (metric/gauge) or array of records (chart/table). */ data?: Record | Record[]; /** Maps data fields to visual channels. Auto-inferred when omitted. */ mapping?: UWidgetMapping; /** Field definitions for form/confirm widgets. */ fields?: UWidgetFieldDefinition[]; /** Formdown shorthand syntax for form fields (mutually exclusive with `fields`). */ formdown?: string; /** * Widget-specific rendering options. * * Chart widgets support an `echarts` sub-key for native ECharts option passthrough: * ```json * { "options": { "echarts": { "tooltip": { "trigger": "axis" } } } } * ``` * All keys in `options.echarts` are deep-merged into the generated ECharts option. * @see https://echarts.apache.org/en/option.html */ options?: Record; /** Action buttons displayed below the widget. */ actions?: UWidgetAction[]; /** Interchange format type marker. Always `"u-widget"` if present. */ type?: 'u-widget'; /** Interchange format version string. */ version?: string; /** Layout mode for compose widget: `"stack"` (default), `"row"`, or `"grid"`. */ layout?: 'stack' | 'row' | 'grid'; /** Number of grid columns for compose `"grid"` layout. Default: 2. */ columns?: number; /** Child widget specs for compose widget. */ children?: UWidgetChildSpec[]; /** Grid column span for children inside a compose `"grid"` layout. */ span?: number; } /** * Validate a u-widget spec. * * Checks structural correctness: required fields, data type expectations, * compose children, field/action definitions. Also validates that mapping * fields exist in the data (produces warnings, not errors). * * @param spec - The spec object to validate (any type accepted for safety). * @returns Validation result with `valid`, `errors`, and `warnings`. * * @example * ```ts * const result = validate({ widget: 'metric', data: { value: 42 } }); * console.log(result.valid); // true * ``` */ export declare function validate(spec: unknown, _depth?: number): ValidationResult; /** Result of spec validation via {@link validate}. */ export declare interface ValidationResult { /** Whether the spec passed all validation checks. */ valid: boolean; /** Error messages — issues that prevent correct rendering. */ errors: string[]; /** Warning messages — non-fatal issues or recommendations. */ warnings: string[]; } /** * All supported widget type identifiers. * * - **Display:** chart.*, metric, stat-group, gauge, progress, table, list * - **Input:** form, confirm * - **Composition:** compose * - **Content:** markdown, image, callout */ 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' | 'math' | 'actions' | 'divider' | 'header'; export { } declare global { interface HTMLElementTagNameMap { 'u-widget': import('@iyulab/u-widgets').UWidget; } namespace JSX { interface IntrinsicElements { 'u-widget': UWidgetElementProps; } } } declare module "react" { namespace JSX { interface IntrinsicElements { "u-widget": UWidgetElementProps; } } }