@yoyaflow/yoya-ui 0.1.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,495 @@
1
+ /**
2
+ * yoya-ui core type declarations.
3
+ *
4
+ * The library ships plain JavaScript; these declarations describe the public
5
+ * contract so TypeScript consumers get editor IntelliSense and compile-time
6
+ * checks. They mirror the runtime API in `src/core`.
7
+ */
8
+
9
+ import type { CodeBlock } from './data-display.js';
10
+ import type { DynamicLoaderNode, DynamicLoaderOptions } from './async.js';
11
+ import type { HtmlElementNode } from './html.js';
12
+ import type { VThemeShell } from './layout.js';
13
+ import type { Router } from './router.js';
14
+ import type { VThemeModeSwitch } from './theme.js';
15
+
16
+ // ---------------------------------------------------------------------------
17
+ // Shared primitive types
18
+ // ---------------------------------------------------------------------------
19
+
20
+ /** Class name input accepted by className()/class(): strings, arrays, falsy values. */
21
+ export type ClassNameInput = string | number | null | undefined | false | ClassNameInput[];
22
+
23
+ /** Attribute values supported by attr(). */
24
+ export type AttrValue = string | number | boolean | null | undefined;
25
+
26
+ /** Inline style values supported by style()/styles(). */
27
+ export type StyleValue = string | number | null | undefined;
28
+
29
+ /** Inline style map; keys are camelCase CSS property names. */
30
+ export type StyleInput = Record<string, StyleValue>;
31
+
32
+ /** Options accepted by on(). */
33
+ export type EventOptions = boolean | AddEventListenerOptions;
34
+
35
+ /** Event handler signature used across the library. */
36
+ export type EventHandler<E extends Event = Event> = (event: E) => void;
37
+
38
+ /** A component object with a render() method (form B component). */
39
+ export interface ComponentLike {
40
+ render(): ViewNode;
41
+ [key: string]: any;
42
+ }
43
+
44
+ /** Anything accepted as a child: nodes, components, text, arrays, empty values. */
45
+ export type ChildInput =
46
+ ViewNode | string | number | ComponentLike | null | undefined | ChildInput[];
47
+
48
+ /** Declarative setup callback receiving the node. */
49
+ export type SetupCallback<N> = (node: N) => void;
50
+
51
+ /**
52
+ * Object-form setup accepted by every factory: class/className, attrs, style,
53
+ * children, onXxx event handlers and arbitrary attribute keys.
54
+ */
55
+ export interface ElementOptions {
56
+ class?: ClassNameInput;
57
+ className?: ClassNameInput;
58
+ attrs?: Record<string, AttrValue>;
59
+ style?: StyleInput;
60
+ children?: ChildInput;
61
+ [key: `on${string}`]: EventHandler | undefined;
62
+ [key: string]: unknown;
63
+ }
64
+
65
+ /** Unified setup input: callback, node instance, text, object config or children. */
66
+ export type SetupInput<N = ViewNode> =
67
+ N | string | number | SetupCallback<N> | ElementOptions | ChildInput;
68
+
69
+ /**
70
+ * Signature shared by every element/component factory. Supports the three
71
+ * declarative forms: `factory(callback)`, `factory(text, callback)`,
72
+ * `factory(first, options, callback)` and plain object config.
73
+ */
74
+ export interface ElementFactory<N = ViewNode> {
75
+ (first?: SetupInput<N> | null): N;
76
+ (first: SetupInput<N>, callback: SetupCallback<N>): N;
77
+ (first: SetupInput<N> | null, options: ElementOptions, callback?: SetupCallback<N>): N;
78
+ }
79
+
80
+ /** State types accepted by registerStateAttrs(). */
81
+ export type StateType = 'boolean' | 'string' | 'number' | null | undefined;
82
+
83
+ /** State handler invoked when a registered state changes. */
84
+ export type StateHandler<N = ViewNode> = (value: unknown, node: N, oldValue: unknown) => void;
85
+
86
+ // ---------------------------------------------------------------------------
87
+ // View tree nodes
88
+ // ---------------------------------------------------------------------------
89
+
90
+ /**
91
+ * ViewNode is the base view-tree node: children, event cleanup, state and
92
+ * lifecycle management shared by every node kind.
93
+ */
94
+ export class ViewNode {
95
+ constructor(setup?: SetupInput<ViewNode> | null);
96
+
97
+ /** Unified initialization: function, text, node instance or object config. */
98
+ setup(setup: SetupInput<ViewNode> | null): this;
99
+
100
+ /** Returns a snapshot of child nodes. */
101
+ children(): ViewNode[];
102
+
103
+ /** Removes and schedules all children for destruction. */
104
+ clearChildren(): this;
105
+
106
+ /** Adds children; strings/numbers are wrapped into text nodes. */
107
+ child(...children: ChildInput[]): this;
108
+
109
+ /** Adds a text child. */
110
+ text(content: string | number): this;
111
+
112
+ /** Registers an event listener, bound immediately or at render time. */
113
+ on(eventName: string, handler: EventHandler, options?: EventOptions): this;
114
+
115
+ /** Declares state fields (default boolean) recognized by this node. */
116
+ registerStateAttrs(...attrs: Array<string | Record<string, StateType>>): this;
117
+
118
+ /** Registers a handler invoked when the given state changes. */
119
+ registerStateHandler(stateName: string, handler: StateHandler<this>): this;
120
+
121
+ /** Sets a state value and triggers its handlers. */
122
+ setState(stateName: string, value?: unknown): this;
123
+
124
+ getState(stateName: string): unknown;
125
+ getBooleanState(stateName: string): boolean;
126
+ getStringState(stateName: string): string;
127
+ getNumberState(stateName: string): number;
128
+
129
+ /** Renders (or re-renders) the real DOM node. */
130
+ renderDom(): Node | null;
131
+
132
+ /** Alias of renderDom(); commits the current tree to the DOM. */
133
+ commit(): Node | null;
134
+
135
+ /** Mounts the node into a selector or DOM container. */
136
+ bindTo(target: string | ParentNode): this;
137
+
138
+ /** Destroys the node: cleans events, destroys children and removes its DOM. */
139
+ destroy(): this;
140
+
141
+ /** Serializes this subtree to an HTML string (SSR path). */
142
+ toHTML(): string;
143
+
144
+ /** Post-hydration hook; subclasses may read state back from real DOM. */
145
+ hydrateSnapshot(): this;
146
+ }
147
+
148
+ /** Text node backed by a real Text node. */
149
+ export class VTextNode extends ViewNode {
150
+ constructor(content?: string | number);
151
+
152
+ textContent(): string;
153
+ textContent(value: string | number): this;
154
+
155
+ renderDom(): Text | null;
156
+ toHTML(): string;
157
+ }
158
+
159
+ /**
160
+ * ComponentNode lazily resolves a factory function or a component object with
161
+ * render() and reuses the resolved node.
162
+ */
163
+ export class ComponentNode extends ViewNode {
164
+ constructor(component: ComponentLike);
165
+
166
+ children(): ViewNode[];
167
+ textContent(): string;
168
+ renderDom(): Node | null;
169
+ toHTML(): string;
170
+ destroy(): this;
171
+ }
172
+
173
+ /**
174
+ * ElementNode renders a real DOM Element and synchronizes attrs, classes,
175
+ * styles, events and children.
176
+ */
177
+ export class ElementNode extends ViewNode {
178
+ constructor(tagName: string, setup?: SetupInput<ElementNode> | null);
179
+
180
+ tagName(): string;
181
+
182
+ /** Aggregated text content of this element and its children. */
183
+ textContent(): string;
184
+
185
+ /** Reads an attribute value. */
186
+ attr(name: string): AttrValue | undefined;
187
+ /** Sets a single attribute; null/undefined/false remove it. */
188
+ attr(name: string, value: AttrValue): this;
189
+ /** Sets multiple attributes. */
190
+ attr(attrs: Record<string, AttrValue>): this;
191
+
192
+ id(): AttrValue | undefined;
193
+ id(value: string): this;
194
+
195
+ name(): AttrValue | undefined;
196
+ name(value: string): this;
197
+
198
+ /** Reads the joined class name. */
199
+ className(): string;
200
+ /** Adds classes; supports space-separated strings, arrays and multiple args. */
201
+ className(...classes: ClassNameInput[]): this;
202
+
203
+ class(...classes: ClassNameInput[]): this;
204
+
205
+ replaceClassName(old: string, next: string, tolerate?: boolean): this;
206
+
207
+ /** Reads a single style property. */
208
+ style(name: string): StyleValue | undefined;
209
+ /** Sets a single style property; null/undefined/'' remove it. */
210
+ style(name: string, value: StyleValue): this;
211
+ /** Sets multiple styles. */
212
+ style(styles: StyleInput): this;
213
+
214
+ /** Sets multiple styles. */
215
+ styles(styles: StyleInput): this;
216
+
217
+ child(...children: ChildInput[]): this;
218
+
219
+ renderDom(): Element | null;
220
+ toHTML(): string;
221
+
222
+ // Shortcuts registered on ElementNode (inherited by HtmlElementNode).
223
+ /** vStateNode shortcut: creates a stateful object component. */
224
+ vStateNode(config: StateNodeConfig): StateNodeComponent;
225
+ /** vDynamicLoader shortcut: lazily loads a module with status views. */
226
+ vDynamicLoader(
227
+ first?: DynamicLoaderOptions | (() => unknown) | SetupCallback<DynamicLoaderNode>,
228
+ options?: ElementOptions,
229
+ callback?: SetupCallback<DynamicLoaderNode>
230
+ ): DynamicLoaderNode;
231
+ /** vThemeShell shortcut: themed surface container. */
232
+ vThemeShell(
233
+ first?: SetupInput<VThemeShell> | null,
234
+ options?: ElementOptions,
235
+ callback?: SetupCallback<VThemeShell>
236
+ ): VThemeShell;
237
+ /** codeBlock shortcut: code block with copy button (inherited by HtmlElementNode). */
238
+ codeBlock(
239
+ first?: SetupInput<CodeBlock> | null,
240
+ options?: ElementOptions,
241
+ callback?: SetupCallback<CodeBlock>
242
+ ): CodeBlock;
243
+ /** vThemeModeSwitch shortcut: theme light/dark/system switcher. */
244
+ vThemeModeSwitch(
245
+ first?: SetupInput<VThemeModeSwitch> | null,
246
+ options?: ElementOptions,
247
+ callback?: SetupCallback<VThemeModeSwitch>
248
+ ): VThemeModeSwitch;
249
+ /** vRouter shortcut: declarative router container. */
250
+ vRouter(
251
+ first?: SetupInput<Router> | null,
252
+ options?: ElementOptions,
253
+ callback?: SetupCallback<Router>
254
+ ): Router;
255
+ /** vLink shortcut: router link. */
256
+ vLink(
257
+ routerInstance: Router,
258
+ setup?: SetupInput<HtmlElementNode> | null,
259
+ callback?: SetupCallback<HtmlElementNode>
260
+ ): HtmlElementNode;
261
+ /** vRouterView shortcut: current route outlet. */
262
+ vRouterView(
263
+ routerInstance: Router,
264
+ setup?: SetupInput<HtmlElementNode> | null,
265
+ callback?: SetupCallback<HtmlElementNode>
266
+ ): HtmlElementNode;
267
+ /** vRouterViews shortcut: multi-outlet router view. */
268
+ vRouterViews(
269
+ routerInstance: Router,
270
+ setup?: SetupInput<HtmlElementNode> | null,
271
+ callback?: SetupCallback<HtmlElementNode>
272
+ ): HtmlElementNode;
273
+ }
274
+
275
+ // ---------------------------------------------------------------------------
276
+ // Node helpers
277
+ // ---------------------------------------------------------------------------
278
+
279
+ /** Creates a factory for the given tag using ElementNode or a subclass. */
280
+ export function createElementFactory(
281
+ tagName: string,
282
+ NodeClass?: new (tagName: string, setup?: unknown) => ElementNode
283
+ ): ElementFactory;
284
+
285
+ /** Applies { attrs, style } options to a node (component object support). */
286
+ export function applyElementOptions(
287
+ node: ViewNode | ComponentLike,
288
+ options: ElementOptions | null
289
+ ): ViewNode | ComponentLike;
290
+
291
+ /** Minimal HTML escaping used by toHTML(). */
292
+ export function escapeHtml(value: unknown): string;
293
+
294
+ /** Normalizes any child input into a ViewNode. */
295
+ export function normalizeChild(child: ViewNode | ComponentLike | string | number): ViewNode;
296
+
297
+ /** Normalizes (first, second, third) factory arguments into { first, options, callback }. */
298
+ export function normalizeSetupArguments(
299
+ first?: unknown,
300
+ second?: unknown,
301
+ third?: unknown
302
+ ): { first: unknown; options: unknown; callback: unknown };
303
+
304
+ /** Registers factories as parent shortcut methods on a node class. */
305
+ export function registerChildFactories(
306
+ NodeClass: new (...args: any[]) => ViewNode,
307
+ factories: Record<string, (...args: any[]) => ViewNode>,
308
+ options?: { override?: boolean }
309
+ ): void;
310
+
311
+ /** Resolves a mount target: CSS selector string or DOM container. */
312
+ export function resolveTarget(target: string | ParentNode): ParentNode | null;
313
+
314
+ /** Creates a text node. */
315
+ export function vText(content?: string | number): VTextNode;
316
+ /** Alias of vText(). */
317
+ export const text: typeof vText;
318
+
319
+ // ---------------------------------------------------------------------------
320
+ // Client-only (SSR placeholder)
321
+ // ---------------------------------------------------------------------------
322
+
323
+ /** Node that renders a placeholder during SSR and loads content on hydration. */
324
+ export class ClientOnlyNode extends ViewNode {
325
+ constructor(loader: () => Promise<unknown> | unknown);
326
+ toHTML(): string;
327
+ renderDom(): Node | null;
328
+ children(): ViewNode[];
329
+ textContent(): string;
330
+ destroy(): this;
331
+ }
332
+
333
+ /** Creates a client-only node; the loader runs only on the client. */
334
+ export function vClientOnly(loader: () => Promise<unknown> | unknown): ClientOnlyNode;
335
+
336
+ // ---------------------------------------------------------------------------
337
+ // i18n
338
+ // ---------------------------------------------------------------------------
339
+
340
+ export interface I18nOptions {
341
+ /** Stable identifier for this locale context; enables registry lookup and multi-locale persistence. */
342
+ key?: string;
343
+ language?: string;
344
+ fallbackLanguage?: string;
345
+ storageKey?: string | null;
346
+ storage?: Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>;
347
+ messages?: Record<string, unknown>;
348
+ }
349
+
350
+ /** Minimal i18n manager: language, dictionaries, subscriptions, persistence. */
351
+ export class I18n {
352
+ constructor(options?: I18nOptions);
353
+
354
+ /** Returns this instance's locale key, or null when not configured. */
355
+ key(): string | null;
356
+ getLanguage(): string;
357
+ setLanguage(language: string): this;
358
+ getFallbackLanguage(): string;
359
+ setFallbackLanguage(language: string): this;
360
+ clearPersistedLanguage(): this;
361
+
362
+ /** Registers or merges a dictionary for one language. */
363
+ register(language: string, messages?: Record<string, unknown>): this;
364
+
365
+ /** Registers one or more corpora: multi-language files or { language, messages }. */
366
+ registerMessages(corpus?: Record<string, unknown> | Array<unknown>): this;
367
+
368
+ /** Translates a key with dot-path lookup, fallback language and {name} params. */
369
+ t(key: string, params?: Record<string, unknown>, defaultValue?: unknown): string;
370
+
371
+ /** Creates a text node that refreshes when the language changes. */
372
+ text(key: string, params?: Record<string, unknown>, defaultValue?: unknown): I18nTextNode;
373
+
374
+ /** Subscribes to language changes; returns an unsubscribe function. */
375
+ subscribe(listener: (i18n: I18n) => void): () => void;
376
+ }
377
+
378
+ /** Text node bound to an I18n instance; refreshes on language changes. */
379
+ export class I18nTextNode extends VTextNode {
380
+ constructor(i18n: I18n, key: string, params?: Record<string, unknown>, defaultValue?: unknown);
381
+
382
+ key(): string;
383
+ key(value: string): this;
384
+ params(): Record<string, unknown>;
385
+ params(value: Record<string, unknown>): this;
386
+ defaultValue(): unknown;
387
+ defaultValue(value: unknown): this;
388
+ refresh(): this;
389
+ destroy(): this;
390
+ }
391
+
392
+ /** Creates an I18n instance. */
393
+ export function createI18n(options?: I18nOptions): I18n;
394
+
395
+ /** Default shared I18n instance. */
396
+ export const i18n: I18n;
397
+
398
+ /** Registers an I18n instance by its key; returns an unregister function. */
399
+ export function registerI18n(instance: I18n): () => void;
400
+
401
+ /** Removes an I18n instance from the registry (accepts a key or instance). */
402
+ export function unregisterI18n(keyOrInstance: string | I18n): string | undefined;
403
+
404
+ /** Looks up a registered I18n instance by key; returns null when missing. */
405
+ export function getI18n(key: string): I18n | null;
406
+
407
+ /** Returns a copy of the registry as { key: instance }. */
408
+ export function listI18n(): Map<string, I18n>;
409
+
410
+ /** Reads all persisted locale identifiers ({ key: language }) from the shared record. */
411
+ export function getPersistedI18nLocales(
412
+ storage?: Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>
413
+ ): Record<string, string>;
414
+
415
+ /** Creates a translated text node on the default instance. */
416
+ export function i18nText(key: string, params?: Record<string, unknown>): I18nTextNode;
417
+
418
+ /** Installs the "content".s(key, locale?) string shortcut; returns the locale. */
419
+ export function installI18nStringShortcut(locale?: I18n): I18n;
420
+
421
+ /** Runs build() with the string shortcut scoped to the given I18n instance. */
422
+ export function withI18nStringShortcut<T>(locale: I18n, build: () => T): T;
423
+
424
+ // ---------------------------------------------------------------------------
425
+ // State node (vStateNode)
426
+ // ---------------------------------------------------------------------------
427
+
428
+ export interface StateNodeConfig<S extends Record<string, unknown> = Record<string, unknown>> {
429
+ state?: S | (() => S);
430
+ render(state: S, component: StateNodeComponent<S>): ChildInput;
431
+ update?(state: S, component: StateNodeComponent<S>, changed: Set<string>): boolean | void;
432
+ [key: string]: any;
433
+ }
434
+
435
+ /** Object component returned by vStateNode(). */
436
+ export interface StateNodeComponent<S extends Record<string, unknown> = Record<string, unknown>> {
437
+ destroy(): StateNodeComponent<S>;
438
+ getState(): S;
439
+ render(): ElementNode;
440
+ setState(
441
+ patch: Partial<S> | ((state: S) => Partial<S> | null | undefined)
442
+ ): StateNodeComponent<S>;
443
+ state(): S;
444
+ subscribe(listener: (state: S, component: StateNodeComponent<S>) => void): () => void;
445
+ [key: string]: any;
446
+ }
447
+
448
+ /** Creates a stateful object component with render/update lifecycle. */
449
+ export function vStateNode<S extends Record<string, unknown> = Record<string, unknown>>(
450
+ config: StateNodeConfig<S>
451
+ ): StateNodeComponent<S>;
452
+
453
+ // ---------------------------------------------------------------------------
454
+ // Theme
455
+ // ---------------------------------------------------------------------------
456
+
457
+ export type YoyaMode = 'light' | 'dark' | 'system';
458
+
459
+ export interface ThemePersistOptions {
460
+ persist?: boolean;
461
+ }
462
+
463
+ export interface InitYoyaThemeOptions extends ThemePersistOptions {
464
+ mode?: YoyaMode;
465
+ theme?: string;
466
+ }
467
+
468
+ /** Sets the light/dark/system mode on documentElement; returns the applied mode. */
469
+ export function setYoyaMode(mode?: YoyaMode, options?: ThemePersistOptions): YoyaMode;
470
+ export function getYoyaMode(): YoyaMode;
471
+ export function resolveYoyaMode(): 'light' | 'dark';
472
+
473
+ /** Sets or clears the named brand theme on documentElement; returns the theme name. */
474
+ export function setYoyaTheme(name?: string, options?: ThemePersistOptions): string;
475
+ export function getYoyaTheme(): string;
476
+
477
+ /** Initializes theme mode/name from explicit values or persisted storage. */
478
+ export function initYoyaTheme(options?: InitYoyaThemeOptions): {
479
+ mode: YoyaMode;
480
+ theme: string;
481
+ };
482
+
483
+ declare global {
484
+ interface String {
485
+ /**
486
+ * i18n string shortcut: "default text".s(key, paramsOrLocale?, maybeLocale?).
487
+ * The locale argument may be an I18n instance or a registered locale key.
488
+ */
489
+ s(
490
+ key: string,
491
+ paramsOrLocale?: Record<string, unknown> | I18n | string,
492
+ maybeLocale?: I18n | string
493
+ ): I18nTextNode;
494
+ }
495
+ }
package/types/css.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Ambient declaration for the stylesheet import:
3
+ * `import 'yoya-ui/ui.css';`
4
+ */
5
+ declare module 'yoya-ui/ui.css';