@yoyaflow/yoya-ui 0.3.2 → 0.3.3
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.
- package/README.md +347 -108
- package/README.zh-CN.md +321 -121
- package/dist/yoya-ui.umd.js +2 -2
- package/dist/yoya.core.js +845 -286
- package/dist/yoya.devtools.js +223 -0
- package/dist/yoya.echart.js +341 -84
- package/dist/yoya.ssr.js +1347 -759
- package/dist/yoya.ui.css +71 -0
- package/dist/yoya.ui.js +3358 -2480
- package/package.json +13 -1
- package/types/core.d.ts +122 -1
- package/types/data-display.d.ts +44 -2
- package/types/devtools.d.ts +156 -0
- package/types/feedback.d.ts +13 -0
- package/types/form.d.ts +1 -1
- package/types/ssr.d.ts +27 -7
- package/types/yoya.devtools.d.ts +5 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yoyaflow/yoya-ui",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "A browser-native JS UI library with declarative HTML authoring: component library, router, i18n, theming and layout, works with or without a build tool, SSR-ready.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
"types": "./types/yoya.core.d.ts",
|
|
19
19
|
"import": "./dist/yoya.core.js"
|
|
20
20
|
},
|
|
21
|
+
"./devtools": {
|
|
22
|
+
"types": "./types/yoya.devtools.d.ts",
|
|
23
|
+
"import": "./dist/yoya.devtools.js"
|
|
24
|
+
},
|
|
21
25
|
"./echart": {
|
|
22
26
|
"types": "./types/yoya.echart.d.ts",
|
|
23
27
|
"import": "./dist/yoya.echart.js"
|
|
@@ -81,12 +85,20 @@
|
|
|
81
85
|
"node": "^20.19.0 || ^22.13.0 || >=24.0.0"
|
|
82
86
|
},
|
|
83
87
|
"devDependencies": {
|
|
88
|
+
"@codemirror/lang-javascript": "^6.2.5",
|
|
89
|
+
"@codemirror/state": "^6.7.4",
|
|
90
|
+
"@codemirror/theme-one-dark": "^6.1.3",
|
|
84
91
|
"@eslint/js": "^10.0.1",
|
|
85
92
|
"@preact/signals-core": "^1.14.4",
|
|
93
|
+
"@toast-ui/editor": "^3.2.2",
|
|
94
|
+
"ag-grid-community": "^36.1.0",
|
|
95
|
+
"codemirror": "^6.0.2",
|
|
86
96
|
"eslint": "^10.8.1",
|
|
87
97
|
"globals": "^17.11.0",
|
|
88
98
|
"jsdom": "^29.1.1",
|
|
99
|
+
"leaflet": "^1.9.4",
|
|
89
100
|
"prettier": "^3.9.6",
|
|
101
|
+
"quill": "^2.0.3",
|
|
90
102
|
"typescript": "^7.0.2",
|
|
91
103
|
"vite": "^8.2.0",
|
|
92
104
|
"vitest": "^4.1.10"
|
package/types/core.d.ts
CHANGED
|
@@ -58,6 +58,7 @@ export interface ElementOptions {
|
|
|
58
58
|
attrs?: Record<string, AttrValue>;
|
|
59
59
|
style?: StyleInput;
|
|
60
60
|
children?: ChildInput;
|
|
61
|
+
access?: AccessSpec;
|
|
61
62
|
[key: `on${string}`]: EventHandler | undefined;
|
|
62
63
|
[key: string]: unknown;
|
|
63
64
|
}
|
|
@@ -83,6 +84,114 @@ export type StateType = 'boolean' | 'string' | 'number' | null | undefined;
|
|
|
83
84
|
/** State handler invoked when a registered state changes. */
|
|
84
85
|
export type StateHandler<N = ViewNode> = (value: unknown, node: N, oldValue: unknown) => void;
|
|
85
86
|
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// Access control
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
|
|
91
|
+
export type AccessLevel = 'read' | 'write';
|
|
92
|
+
|
|
93
|
+
/** Permission code on a node. Components pass bare resource codes, e.g. "system:member"; read/write level is decided by the user's grants. */
|
|
94
|
+
export type AccessSpec = string;
|
|
95
|
+
|
|
96
|
+
/** Options accepted by createAccess(). */
|
|
97
|
+
export interface AccessOptions {
|
|
98
|
+
/** Granted permission strings, e.g. ["r.system:member", "w.system:member"]. */
|
|
99
|
+
permissions?: string[];
|
|
100
|
+
/** Roles held by the current request, e.g. ["admin"]. */
|
|
101
|
+
roles?: string[];
|
|
102
|
+
/** Roles that bypass every check (default ["super_admin"]). */
|
|
103
|
+
superAdmins?: string[];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Per-request permission context: decided by withAccess scope. */
|
|
107
|
+
export interface AccessContext {
|
|
108
|
+
roles(): string[];
|
|
109
|
+
permissions(): string[];
|
|
110
|
+
isSuper(): boolean;
|
|
111
|
+
/** True when any grant (bare / r. / w.) covers the code. */
|
|
112
|
+
has(spec: AccessSpec): boolean;
|
|
113
|
+
/** True when a read grant (bare / r. / w.) covers the code. */
|
|
114
|
+
canRead(spec: AccessSpec): boolean;
|
|
115
|
+
/** True when a write grant (bare or w.) covers the code. */
|
|
116
|
+
canWrite(spec: AccessSpec): boolean;
|
|
117
|
+
setPermissions(permissions: string[]): AccessContext;
|
|
118
|
+
subscribe(listener: () => void): () => void;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** Creates a per-request access context. */
|
|
122
|
+
export function createAccess(options?: AccessOptions): AccessContext;
|
|
123
|
+
|
|
124
|
+
/** Normalizes an access spec into { code, level }. */
|
|
125
|
+
export function parseAccessSpec(
|
|
126
|
+
spec: AccessSpec | { code: string; level?: AccessLevel }
|
|
127
|
+
): { code: string; level: AccessLevel } | null;
|
|
128
|
+
|
|
129
|
+
/** Returns the resource code of a spec, without the read/write prefix. */
|
|
130
|
+
export function stripAccessCode(spec: AccessSpec): string;
|
|
131
|
+
|
|
132
|
+
/** Runs build() with the access context active, then restores the outer one. */
|
|
133
|
+
export function withAccess<T>(access: AccessContext | null, build: () => T): T;
|
|
134
|
+
|
|
135
|
+
/** Returns the access context active in the current render scope. */
|
|
136
|
+
export function currentAccess(): AccessContext | null;
|
|
137
|
+
|
|
138
|
+
/** Installs a global access context (single-user SPA); overridden by SSR options.access or withAccess scope. */
|
|
139
|
+
export function installAccess(access: AccessContext | null): AccessContext | null;
|
|
140
|
+
|
|
141
|
+
// ---
|
|
142
|
+
// Generic scoped context
|
|
143
|
+
// ---
|
|
144
|
+
|
|
145
|
+
/** Per-render provider map injected by withContext / SSR options.context. */
|
|
146
|
+
export type ContextProviders = Record<string, unknown>;
|
|
147
|
+
|
|
148
|
+
/** Runs build() with the providers active, then restores the outer scope. */
|
|
149
|
+
export function withContext<T>(providers: ContextProviders | null | undefined, build: () => T): T;
|
|
150
|
+
|
|
151
|
+
/** Installs a global fallback context (single-user SPA). */
|
|
152
|
+
export function installContext(
|
|
153
|
+
providers: ContextProviders | null | undefined
|
|
154
|
+
): ContextProviders | null;
|
|
155
|
+
|
|
156
|
+
/** Removes the globally installed fallback context. */
|
|
157
|
+
export function clearInstalledContext(): null;
|
|
158
|
+
|
|
159
|
+
/** Returns the nearest value for a key; falls back to installed context and defaultValue. */
|
|
160
|
+
export function currentContext<T = unknown>(key: string, defaultValue?: T): T | undefined;
|
|
161
|
+
|
|
162
|
+
/** Returns a shallow merged snapshot of the active context. */
|
|
163
|
+
export function snapshotContext(): ContextProviders;
|
|
164
|
+
|
|
165
|
+
// ---
|
|
166
|
+
// Accessibility primitives
|
|
167
|
+
// ---
|
|
168
|
+
|
|
169
|
+
export interface FocusTrapOptions {
|
|
170
|
+
onEscape?: (event: Event) => void;
|
|
171
|
+
restoreFocus?: boolean;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export interface FocusTrapHandle {
|
|
175
|
+
activate(): void;
|
|
176
|
+
destroy(): void;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export function getFocusableElements(root: Element | null | undefined): Element[];
|
|
180
|
+
export function createFocusTrap(
|
|
181
|
+
root: Element | null | undefined,
|
|
182
|
+
options?: FocusTrapOptions
|
|
183
|
+
): FocusTrapHandle;
|
|
184
|
+
export function announce(
|
|
185
|
+
message: string,
|
|
186
|
+
options?: { politeness?: 'polite' | 'assertive'; dedupeKey?: string }
|
|
187
|
+
): HTMLElement | null;
|
|
188
|
+
export function moveByKey(options: {
|
|
189
|
+
key: string;
|
|
190
|
+
items: readonly unknown[];
|
|
191
|
+
currentIndex?: number;
|
|
192
|
+
shiftKey?: boolean;
|
|
193
|
+
}): number;
|
|
194
|
+
|
|
86
195
|
// ---------------------------------------------------------------------------
|
|
87
196
|
// View tree nodes
|
|
88
197
|
// ---------------------------------------------------------------------------
|
|
@@ -109,6 +218,9 @@ export class ViewNode {
|
|
|
109
218
|
/** Adds a text child. */
|
|
110
219
|
text(content: string | number): this;
|
|
111
220
|
|
|
221
|
+
/** Declares access control: bare default read, "w.xxx" write, "r.xxx" read. */
|
|
222
|
+
access(spec: AccessSpec): this;
|
|
223
|
+
|
|
112
224
|
/** Registers an event listener, bound immediately or at render time. */
|
|
113
225
|
on(eventName: string, handler: EventHandler, options?: EventOptions): this;
|
|
114
226
|
|
|
@@ -362,6 +474,12 @@ export class I18n {
|
|
|
362
474
|
/** Registers or merges a dictionary for one language. */
|
|
363
475
|
register(language: string, messages?: Record<string, unknown>): this;
|
|
364
476
|
|
|
477
|
+
/** Lazily registers a language; returns a promise resolved after merge and notify. */
|
|
478
|
+
registerLocale(
|
|
479
|
+
name: string,
|
|
480
|
+
loader: () => Record<string, unknown> | Promise<Record<string, unknown>>
|
|
481
|
+
): Promise<this>;
|
|
482
|
+
|
|
365
483
|
/** Registers one or more corpora: multi-language files or { language, messages }. */
|
|
366
484
|
registerMessages(corpus?: Record<string, unknown> | Array<unknown>): this;
|
|
367
485
|
|
|
@@ -559,7 +677,10 @@ export function bindWindowEvent(
|
|
|
559
677
|
): () => void;
|
|
560
678
|
|
|
561
679
|
/** Injects a <style> into <head>; dataAttribute is used for dedup and identification. */
|
|
562
|
-
export function injectDocumentStyle(
|
|
680
|
+
export function injectDocumentStyle(
|
|
681
|
+
styleText: string,
|
|
682
|
+
dataAttribute?: string | null
|
|
683
|
+
): HTMLStyleElement | null;
|
|
563
684
|
|
|
564
685
|
/** Initializes theme mode/name from explicit values or persisted storage. */
|
|
565
686
|
export function initYoyaTheme(options?: InitYoyaThemeOptions): {
|
package/types/data-display.d.ts
CHANGED
|
@@ -344,7 +344,9 @@ export interface TreeRanger {
|
|
|
344
344
|
[key: string]: any;
|
|
345
345
|
}
|
|
346
346
|
|
|
347
|
-
export function vTreeRanger(
|
|
347
|
+
export function vTreeRanger(
|
|
348
|
+
setup?: TreeRangerColumn[] | TreeRangerOptions | SetupCallback<TreeRanger>
|
|
349
|
+
): TreeRanger;
|
|
348
350
|
export const treeRanger: typeof vTreeRanger;
|
|
349
351
|
export function vTreeRangerColumn(setup?: unknown): unknown;
|
|
350
352
|
|
|
@@ -518,6 +520,39 @@ export const vProgress: ElementFactory<VProgress>;
|
|
|
518
520
|
export const vRingStat: ElementFactory<VRingStat>;
|
|
519
521
|
export const vScroll: ElementFactory<VScroll>;
|
|
520
522
|
export const vSparkline: ElementFactory<VSparkline>;
|
|
523
|
+
export interface TreeTableColumn {
|
|
524
|
+
key?: string;
|
|
525
|
+
title?: ChildInput;
|
|
526
|
+
dataIndex?: string;
|
|
527
|
+
sorter?: boolean;
|
|
528
|
+
filterOptions?: Array<{ label: ChildInput; value: string | number }>;
|
|
529
|
+
render?: (value: unknown, row: Record<string, unknown>, index: number) => ChildInput;
|
|
530
|
+
editable?: boolean;
|
|
531
|
+
fixed?: 'left' | 'right' | string;
|
|
532
|
+
validate?: (value: unknown) => string | null | undefined;
|
|
533
|
+
width?: string | number;
|
|
534
|
+
[key: string]: any;
|
|
535
|
+
}
|
|
536
|
+
/** Tree table: flat rows with indent, expand/collapse, selection linkage, lazy load. */
|
|
537
|
+
export class VTreeTable extends HtmlElementNode {
|
|
538
|
+
columns(value?: Array<string | number | TreeTableColumn>): this;
|
|
539
|
+
nodes(value?: Array<Record<string, any>>): this;
|
|
540
|
+
rowKey(handler?: (node: Record<string, unknown>, index: number) => string | number): this;
|
|
541
|
+
rowSelection(value?: boolean): boolean | VTreeTable;
|
|
542
|
+
lazyLoad(
|
|
543
|
+
handler?: (
|
|
544
|
+
node: Record<string, unknown>
|
|
545
|
+
) => Array<Record<string, unknown>> | Promise<Array<Record<string, unknown>>>
|
|
546
|
+
): VTreeTable;
|
|
547
|
+
expandedKeys(value?: Array<string>): Array<string> | VTreeTable;
|
|
548
|
+
expandKeys(value?: Array<string>): VTreeTable;
|
|
549
|
+
checkedKeys(value?: Array<string>): Array<string> | VTreeTable;
|
|
550
|
+
expandAll(): VTreeTable;
|
|
551
|
+
collapseAll(): VTreeTable;
|
|
552
|
+
visibleRowCount(): number;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
export const vTreeTable: ElementFactory<VTreeTable>;
|
|
521
556
|
export const vTable: ElementFactory<VTable>;
|
|
522
557
|
export const vTbody: ElementFactory<VTbody>;
|
|
523
558
|
export const vTd: ElementFactory<VTd>;
|
|
@@ -556,7 +591,10 @@ export class VImagePreview extends HtmlElementNode {
|
|
|
556
591
|
}
|
|
557
592
|
|
|
558
593
|
export const vImagePreview: ElementFactory<VImagePreview> & {
|
|
559
|
-
(
|
|
594
|
+
(
|
|
595
|
+
first?: SetupInput<VImagePreview> | null,
|
|
596
|
+
callback?: SetupCallback<VImagePreview>
|
|
597
|
+
): VImagePreview;
|
|
560
598
|
};
|
|
561
599
|
|
|
562
600
|
/** Parent-shortcut surface merged onto HtmlElementNode. */
|
|
@@ -601,6 +639,10 @@ export interface DataDisplayParentShortcuts {
|
|
|
601
639
|
first?: SetupInput<VSparkline> | null,
|
|
602
640
|
callback?: SetupCallback<VSparkline>
|
|
603
641
|
): VSparkline;
|
|
642
|
+
vTreeTable(
|
|
643
|
+
first?: SetupInput<VTreeTable> | null,
|
|
644
|
+
callback?: SetupCallback<VTreeTable>
|
|
645
|
+
): VTreeTable;
|
|
604
646
|
vTable(first?: SetupInput<VTable> | null, callback?: SetupCallback<VTable>): VTable;
|
|
605
647
|
vTimeline(first?: SetupInput<VTimeline> | null, callback?: SetupCallback<VTimeline>): VTimeline;
|
|
606
648
|
vTimelineItem(
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* yoya-ui devtools type declarations.
|
|
3
|
+
*
|
|
4
|
+
* The devtools runtime ships as a separate entry so the production main
|
|
5
|
+
* bundle never contains the debug surface. All hooks are opt-in and are
|
|
6
|
+
* no-ops until `enableDevtools()` is called.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { ViewNode } from './core.js';
|
|
10
|
+
|
|
11
|
+
/** Base shape shared by every devtools lifecycle event. */
|
|
12
|
+
export interface DevtoolsEventBase {
|
|
13
|
+
/** Event kind: 'commit' | 'destroy' (extended by update/state kinds). */
|
|
14
|
+
type: string;
|
|
15
|
+
/** The view node the event belongs to, when one exists. */
|
|
16
|
+
node?: unknown;
|
|
17
|
+
/** Monotonically increasing event sequence across the stream. */
|
|
18
|
+
seq: number;
|
|
19
|
+
/** Stable id of the node the event belongs to. */
|
|
20
|
+
nodeId?: number;
|
|
21
|
+
/** Human-readable node description (tag/classes/text/component). */
|
|
22
|
+
nodeLabel?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Emitted when an element is first rendered into the DOM. */
|
|
26
|
+
export interface DevtoolsCommitEvent extends DevtoolsEventBase {
|
|
27
|
+
type: 'commit';
|
|
28
|
+
kind: 'mount' | 'update';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Emitted when a node is destroyed. */
|
|
32
|
+
export interface DevtoolsDestroyEvent extends DevtoolsEventBase {
|
|
33
|
+
type: 'destroy';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Emitted when an attribute (including the mirrored class) changes. */
|
|
37
|
+
export interface DevtoolsAttrEvent extends DevtoolsEventBase {
|
|
38
|
+
type: 'attr';
|
|
39
|
+
name: string;
|
|
40
|
+
previous?: DevtoolsAttrValue;
|
|
41
|
+
next?: DevtoolsAttrValue;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Emitted when an inline style property changes. */
|
|
45
|
+
export interface DevtoolsStyleEvent extends DevtoolsEventBase {
|
|
46
|
+
type: 'style';
|
|
47
|
+
name: string;
|
|
48
|
+
previous?: string;
|
|
49
|
+
next?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Emitted when a child is added, removed, or reordered. */
|
|
53
|
+
export interface DevtoolsChildEvent extends DevtoolsEventBase {
|
|
54
|
+
type: 'child';
|
|
55
|
+
added?: number[];
|
|
56
|
+
removed?: number[];
|
|
57
|
+
reordered?: boolean;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Emitted when a mounted text node's content changes. */
|
|
61
|
+
export interface DevtoolsTextEvent extends DevtoolsEventBase {
|
|
62
|
+
type: 'text';
|
|
63
|
+
from?: string;
|
|
64
|
+
to: string;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Emitted when a vStateNode state change is applied. */
|
|
68
|
+
export interface DevtoolsStateEvent extends DevtoolsEventBase {
|
|
69
|
+
type: 'state';
|
|
70
|
+
/** Per-key before/after values for the changed state entries. */
|
|
71
|
+
changed: Record<string, { from: unknown; to: unknown }>;
|
|
72
|
+
/** Full state snapshot after the change was applied. */
|
|
73
|
+
state: Record<string, unknown>;
|
|
74
|
+
/** How the change was applied: update | bindings | rebuild | pending. */
|
|
75
|
+
handling: 'update' | 'bindings' | 'rebuild' | 'pending' | 'none';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Lifecycle events currently emitted by the devtools hook. */
|
|
79
|
+
export type DevtoolsEvent =
|
|
80
|
+
| DevtoolsCommitEvent
|
|
81
|
+
| DevtoolsDestroyEvent
|
|
82
|
+
| DevtoolsAttrEvent
|
|
83
|
+
| DevtoolsStyleEvent
|
|
84
|
+
| DevtoolsChildEvent
|
|
85
|
+
| DevtoolsTextEvent
|
|
86
|
+
| DevtoolsStateEvent;
|
|
87
|
+
|
|
88
|
+
/** Listener callback for the devtools event stream. */
|
|
89
|
+
export type DevtoolsListener = (event: DevtoolsEvent) => void;
|
|
90
|
+
|
|
91
|
+
/** Turns the devtools event stream on. Returns the new enabled state. */
|
|
92
|
+
export function enableDevtools(): boolean;
|
|
93
|
+
|
|
94
|
+
/** Turns the devtools event stream off. Returns the new enabled state. */
|
|
95
|
+
export function disableDevtools(): boolean;
|
|
96
|
+
|
|
97
|
+
/** Whether the devtools event stream is currently enabled. */
|
|
98
|
+
export function isDevtoolsEnabled(): boolean;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Subscribes to lifecycle events emitted while devtools is enabled.
|
|
102
|
+
* Returns an unsubscribe function; listener errors never break rendering.
|
|
103
|
+
*/
|
|
104
|
+
export function subscribeDevtools(listener: DevtoolsListener): () => void;
|
|
105
|
+
|
|
106
|
+
/** Attribute values reflected from the node's attribute map. */
|
|
107
|
+
export type DevtoolsAttrValue = string | number | boolean;
|
|
108
|
+
|
|
109
|
+
/** Plain-shape snapshot of a node subtree for inspection. */
|
|
110
|
+
export interface DevtoolsSnapshot {
|
|
111
|
+
/** Node kind: element | text | component | view | root. */
|
|
112
|
+
kind: string;
|
|
113
|
+
/** Stable per-node identifier assigned while devtools is active. */
|
|
114
|
+
id?: number;
|
|
115
|
+
/** Element tag name for element nodes. */
|
|
116
|
+
tagName?: string;
|
|
117
|
+
/** Element attribute map, including the mirrored class attribute. */
|
|
118
|
+
attrs?: Record<string, DevtoolsAttrValue>;
|
|
119
|
+
/** Text content for text nodes. */
|
|
120
|
+
text?: string;
|
|
121
|
+
/** Child snapshots. */
|
|
122
|
+
children: DevtoolsSnapshot[];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Returns a plain-shape snapshot of a node subtree. */
|
|
126
|
+
export function getDevtoolsSnapshot(root: ViewNode | null): DevtoolsSnapshot;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Returns the rendered DOM node for a snapshot id (element or text node),
|
|
130
|
+
* or null when the node is not rendered or has been destroyed.
|
|
131
|
+
*/
|
|
132
|
+
export function getDevtoolsDom(id: number): Element | Text | null;
|
|
133
|
+
|
|
134
|
+
/** Declared access spec on a node. */
|
|
135
|
+
export interface DevtoolsAccessDetail {
|
|
136
|
+
code: string;
|
|
137
|
+
level: 'write' | 'read';
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Scope details for a snapshot id (access/context/i18n). */
|
|
141
|
+
export interface DevtoolsScope {
|
|
142
|
+
id: number;
|
|
143
|
+
access: DevtoolsAccessDetail | null;
|
|
144
|
+
/** Effective permission result for the node, when available. */
|
|
145
|
+
permissionState?: 'active' | 'readonly' | 'hidden';
|
|
146
|
+
/** Context captured while the node was built, when devtools was on. */
|
|
147
|
+
context: Record<string, unknown> | null;
|
|
148
|
+
/** i18n instance detail for translated text nodes. */
|
|
149
|
+
i18n: { key?: string; language: string } | null;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Returns scope details for a snapshot id, or null when the node has been
|
|
154
|
+
* destroyed (or the id is unknown).
|
|
155
|
+
*/
|
|
156
|
+
export function getDevtoolsScope(id: number): DevtoolsScope | null;
|
package/types/feedback.d.ts
CHANGED
|
@@ -93,6 +93,19 @@ export const toast: {
|
|
|
93
93
|
clear(): VMessageContainer;
|
|
94
94
|
};
|
|
95
95
|
|
|
96
|
+
export interface ConfirmOptions {
|
|
97
|
+
title?: ChildInput;
|
|
98
|
+
content?: ChildInput;
|
|
99
|
+
confirmText?: ChildInput;
|
|
100
|
+
cancelText?: ChildInput;
|
|
101
|
+
danger?: boolean;
|
|
102
|
+
onConfirm?: () => boolean | void | Promise<boolean>;
|
|
103
|
+
onCancel?: () => void;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** 命令式确认弹窗:resolves true on confirm, false on cancel / danger. */
|
|
107
|
+
export function vConfirm(options?: ConfirmOptions): Promise<boolean>;
|
|
108
|
+
|
|
96
109
|
export const vDialog: ElementFactory<VDialog>;
|
|
97
110
|
export const vMessage: ElementFactory<VMessage>;
|
|
98
111
|
export const vMessageContainer: ElementFactory<VMessageContainer>;
|
package/types/form.d.ts
CHANGED
|
@@ -74,7 +74,7 @@ export class VSvgIconPicker extends HtmlElementNode {
|
|
|
74
74
|
disabled(): boolean;
|
|
75
75
|
disabled(next: boolean): VSvgIconPicker;
|
|
76
76
|
name(): string;
|
|
77
|
-
name(next: string):
|
|
77
|
+
name(next: string): this;
|
|
78
78
|
required(): boolean;
|
|
79
79
|
required(next: boolean): VSvgIconPicker;
|
|
80
80
|
icons(): string[];
|
package/types/ssr.d.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
AccessContext,
|
|
3
|
+
ComponentLike,
|
|
4
|
+
ContextProviders,
|
|
5
|
+
ElementNode,
|
|
6
|
+
I18n,
|
|
7
|
+
ViewNode
|
|
8
|
+
} from './core.js';
|
|
2
9
|
import type { HtmlElementNode } from './html.js';
|
|
3
10
|
|
|
4
11
|
export type PageFactory<S = unknown> = (state: S) => ViewNode | ComponentLike | PageFactory<S>;
|
|
@@ -12,7 +19,18 @@ export interface SsrI18nOption<S = unknown> {
|
|
|
12
19
|
i18n?: I18n | ((state: S | null) => I18n);
|
|
13
20
|
}
|
|
14
21
|
|
|
15
|
-
|
|
22
|
+
/** Optional access binding: an AccessContext, or a factory resolved per build. */
|
|
23
|
+
export interface SsrAccessOption {
|
|
24
|
+
access?: AccessContext | (() => AccessContext | null) | null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Optional generic context binding: a provider map, or a factory resolved per build. */
|
|
28
|
+
export interface SsrContextOption {
|
|
29
|
+
context?: ContextProviders | ((state: unknown) => ContextProviders);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface RenderOptions<S = unknown>
|
|
33
|
+
extends SsrI18nOption<S>, SsrAccessOption, SsrContextOption {
|
|
16
34
|
maxNodes?: number;
|
|
17
35
|
state?: S | null;
|
|
18
36
|
}
|
|
@@ -70,7 +88,7 @@ export function mount<S = unknown>(
|
|
|
70
88
|
component: ViewNode | ComponentLike | PageFactory<S>,
|
|
71
89
|
target: string | ParentNode,
|
|
72
90
|
state?: S | null,
|
|
73
|
-
options?: SsrI18nOption<S>
|
|
91
|
+
options?: SsrI18nOption<S> & SsrAccessOption & SsrContextOption
|
|
74
92
|
): ViewNode;
|
|
75
93
|
|
|
76
94
|
/** Hydrates server-rendered DOM: adopts elements and binds pending events. */
|
|
@@ -78,11 +96,11 @@ export function hydrate<S = unknown>(
|
|
|
78
96
|
component: ViewNode | ComponentLike | PageFactory<S>,
|
|
79
97
|
target: string | ParentNode,
|
|
80
98
|
state?: S | null,
|
|
81
|
-
options?: SsrI18nOption<S>
|
|
99
|
+
options?: SsrI18nOption<S> & SsrAccessOption & SsrContextOption
|
|
82
100
|
): ViewNode;
|
|
83
101
|
|
|
84
102
|
/** Document builder node used by renderPage: head/body callbacks build the page. */
|
|
85
|
-
export class PageDocumentNode extends
|
|
103
|
+
export class PageDocumentNode extends ElementNode {
|
|
86
104
|
head(callback: (node: HtmlElementNode, state: unknown) => void): PageDocumentNode;
|
|
87
105
|
body(callback: (node: HtmlElementNode, state: unknown) => void): PageDocumentNode;
|
|
88
106
|
vBody(...args: unknown[]): PageDocumentNode;
|
|
@@ -92,7 +110,8 @@ export interface RenderPageConfig<S = unknown> {
|
|
|
92
110
|
page: (page: PageDocumentNode, state: S | null) => void;
|
|
93
111
|
}
|
|
94
112
|
|
|
95
|
-
export interface RenderPageOptions<S = unknown>
|
|
113
|
+
export interface RenderPageOptions<S = unknown>
|
|
114
|
+
extends SsrI18nOption<S>, SsrAccessOption, SsrContextOption {
|
|
96
115
|
/** Per-request dictionary; builds an I18n instance from state.lang. */
|
|
97
116
|
messages?: Record<string, any>;
|
|
98
117
|
maxNodes?: number;
|
|
@@ -111,7 +130,8 @@ export function renderPage<S = unknown>(
|
|
|
111
130
|
options?: RenderPageOptions<S>
|
|
112
131
|
): string;
|
|
113
132
|
|
|
114
|
-
export interface HydrateOrMountOptions<S = unknown>
|
|
133
|
+
export interface HydrateOrMountOptions<S = unknown>
|
|
134
|
+
extends SsrI18nOption<S>, SsrAccessOption, SsrContextOption {
|
|
115
135
|
messages?: Record<string, any>;
|
|
116
136
|
stateId?: string;
|
|
117
137
|
target?: string | ParentNode;
|