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' | 'chart.gantt'; /** 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"`, `"number:2"` (fixed fraction digits), `"currency"`, `"currency:EUR"`, `"percent"`, `"percent:1"`, * `"date"`, `"datetime"`, `"time"`, `"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(0.97444, 'number:4') // "0.9744" * 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 * {hw=Hardware} = an option whose value (`hw`) differs from its label; `\,` and `\=` escape */ 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; /** A number that grows on every change — compare it to know whether the locale changed since you last looked. */ export declare function getLocaleRevision(): number; /** * 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; export declare function getPrimaryDataField(widget: string): string | undefined; /** * 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` * - **chart.gantt:** first string → `y` (row), first two number or date-like fields → `start`/`end`, next string → `label` * - **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` * 3. `data` → the shape the widget reads: columns become rows, and a chart's or table's nested * rows read by dotted path ({@link toRows}) * * 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; /** * Call `listener` whenever the locale changes — `setDefaultLocale()` to another value, or `registerLocale()`. * Returns the unsubscribe function. `` subscribes while connected and re-renders, so a runtime language * switch reaches what is already on screen. */ export declare function onLocaleChange(listener: () => void): () => void; 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; /** What a validation error is about — stable for code to branch on, while its text follows the locale. */ export declare type SpecErrorCode = 'not-object' | 'too-deep' | 'widget-required' | 'widget-unknown' | 'type-invalid' | 'fields-formdown-exclusive' | 'data-not-array' | 'data-not-object' | 'children-required' | 'child-invalid' | 'layout-invalid' | 'field-invalid' | 'action-invalid'; /** The message for `issue` in `strings` (English by default), prefixed with its place in a compose tree. */ export declare function specErrorMessage(issue: ValidationIssue, strings?: UWidgetLocaleStrings): string; /** * 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; /** Entry-point elements this instance is waiting on, so it re-renders once each is registered. */ private _awaitedElements; /** This widget's chrome strings — its own `locale`, else the default locale. */ private get _strings(); /** Locale subscription while connected, and the revision seen when detached (to catch up on re-attach). */ private _unsubscribeLocale?; private _detachedLocaleRevision?; 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; /** * A known widget whose element lives in an entry point that has not been imported. Says which * entry is missing — in the card, and once per type in the console if it is still missing after a * short grace (a lazily imported entry is on its way, not forgotten) — instead of a generic fallback * whose label (the spec title) reads like a rendered widget. Re-renders when the element is * registered later, so a lazily imported entry takes over without the host doing anything. */ private renderMissingEntry; 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., `"number:2"`, `"currency"`, `"currency:EUR"`, `"percent"`). */ format?: 'number' | `number:${number}` | 'currency' | `currency:${string}` | 'percent' | `percent:${number}` | 'date' | 'datetime' | 'time' | 'bytes'; /** Text alignment within the column. */ align?: 'left' | 'center' | 'right'; /** * Semantic emphasis applied to this column's cells (bold + color token). * Reuses uw-metric's variant vocabulary so highlight semantics stay * consistent across the widget catalog. */ variant?: 'success' | 'warning' | 'danger' | 'info' | 'neutral'; } 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/confirm submit · interactive rating pick | Field values · `{ value }` | * | `action` | Action button · form cancel · citation link | `{ url }` / field values / `{ url, title }` | * | `change` | Form field edited | `{ field, value }` | * | `select` | Table row / list item · chart mark | Row fields + `_index` · `{ name, seriesName, value, dataIndex, _index? }` | * * The full table is in `docs/widgets.md` (Events). */ 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. * * `select` on `table`/`list`: the row's fields plus `_index`, its index in `spec.data`. On a * chart: `name`, `seriesName`, `value` and `dataIndex` (the mark's index within its series), plus * `_index` where a series index does not identify the row — `chart.gantt`, and `chart.scatter` * with a `color` mapping. */ 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; /** * Choices for select, multiselect, radio, and checkbox types. A string is a value shown as * itself; `{ value, label }` shows `label` and submits `value`. */ options?: (string | UWidgetFieldOption)[]; /** 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; } /** * A choice whose submitted value differs from the text shown for it. * * @example * ```json * { "value": "hw", "label": "Hardware" } * ``` */ export declare interface UWidgetFieldOption { /** The value submitted when this choice is picked. */ value: string; /** The text shown for it. Defaults to `value`. */ label?: 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. Korean ships as `@iyulab/u-widgets/locales/ko` (importing it * registers `ko`); consumers register other locales: * registerLocale('ja', { prev: '前へ', next: '次へ', ... }); */ export declare interface UWidgetLocaleStrings { prev: string; next: string; searchPlaceholder: string; searchTable: string; previousPage: string; nextPage: string; tablePagination: string; dataTable: string; /** Appended (visually hidden) to the accessible name of links that open a new tab — citations, markdown links. */ opensInNewTab: string; required: string; minLength: string; maxLength: string; minValue: string; maxValue: string; invalidEmail: string; invalidUrl: string; invalidPattern: string; actions: string; citations: string; gallery: string; keyValuePairs: string; status: string; steps: string; /** Rating with no label or title — template with {value}, {max}. */ ratingOutOf: string; code: string; copy: string; copied: string; moduleNotLoaded: string; unknownWidget: string; addImportHint: string; didYouMean: string; invalidSpec: string; specErrorNotObject: string; /** {max} — the nesting limit. */ specErrorTooDeep: string; specErrorWidgetRequired: string; /** {widget} — a widget the library does not have (reported by `checkSpec`). */ specErrorWidgetUnknown: string; specErrorTypeInvalid: string; specErrorFieldsFormdownExclusive: string; /** {widget}, {got} — the JavaScript type it got. */ specErrorDataNotArray: string; /** {widget}, {got} — the JavaScript type it got, or `array`. */ specErrorDataNotObject: string; specErrorChildrenRequired: string; /** {index} */ specErrorChildInvalid: string; /** {options} — the layouts, comma-separated. */ specErrorLayoutInvalid: string; /** {index} */ specErrorFieldInvalid: string; /** {index} */ specErrorActionInvalid: 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` * - **chart.gantt:** `y` (row), `start`, `end`, `label`, `color` * - **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[]; /** * Interval start field (gantt charts). A number, or a date-like string / timestamp for a time * axis. Rows come from `y`; a row can hold several intervals. */ start?: string; /** Interval end field (gantt charts). Same kind as `start`; an end before its start is drawn in order. */ end?: string; /** Label field (pie/funnel charts; in-bar segment label for gantt 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; /** * Total-flag field (waterfall charts). Names a per-row field whose truthy value * marks that row as an absolute total bar drawn from zero (not a delta stacked on * the running total). Total rows reset the running total to their own value, so a * leading total acts as an opening balance and a trailing total as a closing * balance. Omit for a pure cumulative-delta waterfall (current default behavior). */ total?: 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; /** One validation error, as data: its message is {@link specErrorMessage} of it in a locale. */ export declare interface ValidationIssue { code: SpecErrorCode; /** Values the message names — the widget, the type it got, an index. */ params: Record; /** Where in a compose tree the error is (`["children[1]", "children[0]"]`); empty at the top level. */ path: string[]; } /** Result of spec validation via {@link validate}. */ export declare interface ValidationResult { /** Whether the spec passed all validation checks. */ valid: boolean; /** Error messages (English) — issues that prevent correct rendering. */ errors: string[]; /** The same errors as data, in the same order — for showing them in the reader's language. */ issues: ValidationIssue[]; /** Warning messages — non-fatal issues or recommendations. */ warnings: string[]; } /** * Widget types rendered by an element that ships in a separate entry point. * * `` only renders these once their entry has been imported (the entry registers the * element and pulls in its peer dependency). Build tools can use this map to check statically that * every widget type a page renders has its entry imported. */ /** The separate entry point a widget type needs, and the element that entry registers. */ export declare interface WidgetEntry { /** Import specifier of the entry point, e.g. `'@iyulab/u-widgets/charts'`. */ entry: string; /** Custom element the entry registers, e.g. `'uw-chart'`. */ element: string; } /** * The entry point a known widget type needs beyond the core import, or `undefined` when the core * entry renders it (or the type is not a known widget). * * @example * ```ts * widgetEntry('chart.waterfall') // → { entry: '@iyulab/u-widgets/charts', element: 'uw-chart' } * widgetEntry('math') // → { entry: '@iyulab/u-widgets/math', element: 'uw-math' } * widgetEntry('metric') // → undefined * ``` */ export declare function widgetEntry(widget: string): WidgetEntry | undefined; /** * 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 { 'uw-math': import('@iyulab/u-widgets/math').UwMath; } } declare global { interface HTMLElementTagNameMap { 'u-widget': UWidget; } interface GlobalEventHandlersEventMap { 'u-widget-event': CustomEvent; } } declare global { interface HTMLElementTagNameMap { 'uw-chart': import('@iyulab/u-widgets/charts').UwChart; } } declare global { interface HTMLElementTagNameMap { 'uw-metric': HTMLElement; } } declare global { interface HTMLElementTagNameMap { 'uw-compose': HTMLElement; } } declare global { interface HTMLElementTagNameMap { 'uw-gallery': HTMLElement; } } declare global { interface HTMLElementTagNameMap { 'uw-content': HTMLElement; } } declare global { interface HTMLElementTagNameMap { 'uw-gauge': HTMLElement; } } declare global { interface HTMLElementTagNameMap { 'uw-kv': HTMLElement; } } declare global { interface HTMLElementTagNameMap { 'uw-table': HTMLElement; } } declare global { interface HTMLElementTagNameMap { 'uw-code': HTMLElement; } } declare global { interface HTMLElementTagNameMap { 'uw-form': HTMLElement; } } declare global { interface HTMLElementTagNameMap { 'uw-citation': HTMLElement; } } declare global { interface HTMLElementTagNameMap { 'uw-status': HTMLElement; } } declare global { interface HTMLElementTagNameMap { 'uw-rating': HTMLElement; } } declare global { interface HTMLElementTagNameMap { 'uw-steps': HTMLElement; } } declare global { interface HTMLElementTagNameMap { 'uw-video': HTMLElement; } } declare global { namespace JSX { interface IntrinsicElements { 'u-widget': UWidgetElementProps; } } } declare module 'react' { namespace JSX { interface IntrinsicElements { 'u-widget': UWidgetElementProps; } } } // Type stubs for @formdown/core (optional peer dependency) // These provide compile-time types when @formdown/core is not installed. declare module '@formdown/core/form-manager' { export class FormManager { parse(input: string): void; setDefaults(data: Record): void; getInputFields(): Array<{ name: string; type: string; label?: string; required?: boolean; placeholder?: string; /** 0.15+: `value=Label` 로 값과 보이는 글자를 가른다(라벨 없으면 값을 보인다) */ options?: { value: string; label?: string }[]; attributes?: Record; }>; getActions(): Array<{ name: string; type: string; label?: string; /** 단축형 버튼의 종류(`submit`·`reset`) — 이름은 `submit_<무작위>` 가 된다 */ attributes?: Record; }>; } }