import { type Schema } from 'effect'; import type { Attribute, Child, Html } from '../html/index.js'; /** Type-level kebab-case to PascalCase, used to convert event names like * `'change-rating'` into the corresponding factory name `'OnChangeRating'`. */ type KebabToPascal = S extends `${infer Head}-${infer Tail}` ? `${Capitalize}${KebabToPascal}` : Capitalize; type PropertyFactory = (value: ValueType) => Attribute; type EventFactory = (toMessage: (detail: DetailType) => Message) => Attribute; /** @internal */ type PropertyFactories> = { readonly [K in keyof Properties as Capitalize]: PropertyFactory>; }; /** @internal */ type EventFactories> = { readonly [K in keyof Events as `On${KebabToPascal}`]: EventFactory>; }; /** Typed call site for a defined custom element. The element constructor * itself is callable; each declared property gets a PascalCase factory * method, and each declared event gets an `On{PascalCase}` factory method. */ export type ElementBuilder, Events extends Record> = ((attributes?: ReadonlyArray>, children?: ReadonlyArray) => Html) & PropertyFactories & EventFactories; /** Configuration accepted by `CustomElement.define`. */ export interface CustomElementConfig, Events extends Record> { readonly tag: Tag; readonly properties: Properties; readonly events: Events; } /** A defined custom element, untyped on Message at definition time so the * spec can be exported and shared across modules. Call `.withMessage()` * inside a view module to mint a typed `ElementBuilder` bound to the * consumer's Message universe. */ export interface CustomElementSpec, Events extends Record> { readonly tag: Tag; readonly properties: Properties; readonly events: Events; readonly withMessage: () => ElementBuilder; } /** The typed builder for a given spec and Message universe. Equivalent to * the value `Spec.withMessage()` returns, expressed as a type * consumers can name without reaching for `ReturnType`. */ export type Builder = Spec extends CustomElementSpec ? ElementBuilder : never; /** * Define a typed binding for a custom element. The returned spec describes * the element's properties and events with Schema, and exposes a * `.withMessage()` factory that yields a typed `ElementBuilder` for * the consumer's Message universe. * * Property changes diff across renders; declared `CustomEvent`s are * converted to Messages by the runtime. * * @example * ```ts * // main.ts * import 'vanilla-colorful/hex-color-picker.js' * import { CustomElement } from 'foldkit' * * const hexColorPicker = CustomElement.define({ * tag: 'hex-color-picker', * properties: { * color: S.String, * }, * events: { * 'color-changed': S.Struct({ value: S.String }), * }, * }) * * const picker = hexColorPicker.withMessage() * * picker( * [ * picker.Color(model.fillColor), * picker.OnColorChanged(detail => ChangedFillColor({ value: detail.value })), * ], * [], * ) * ``` */ export declare const define: , Events extends Record>(config: CustomElementConfig) => CustomElementSpec; export {}; //# sourceMappingURL=index.d.ts.map