cdp-material-sdk 0.1.1 → 0.1.2
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/dist/index.js +41 -38
- package/dist/portable.d.ts +1 -0
- package/dist/portable.js +33 -30
- package/dist/protocol/drill.d.ts +32 -0
- package/dist/protocol/traits.d.ts +1 -0
- package/dist/{validateManifest-ZPFDq790.js → validateManifest-DspYuz81.js} +102 -89
- package/docs/component-development/README.md +7 -0
- package/docs/component-development/recipes//345/243/260/346/230/216/345/261/202/347/272/247/344/270/213/351/222/273/350/203/275/345/212/233.md +34 -0
- package/docs/component-development/reference/Traits/350/203/275/345/212/233/346/250/241/345/236/213.md +19 -0
- package/docs/component-development/reference//345/261/202/347/272/247/344/270/213/351/222/273/350/203/275/345/212/233/346/250/241/345/236/213.md +80 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,44 +1,47 @@
|
|
|
1
|
-
import { C as e, a as t, b as n, c as
|
|
2
|
-
import { D as
|
|
1
|
+
import { C as e, a as t, b as n, c as E, D as i, d as T, e as _, f as o, g as O, E as N, F as R, I as A, h as D, L as r, i as I, j as C, N as L, k as l, O as S, l as u, S as d, m as P, n as Y, o as m, p, q as M, r as g, s as c, t as G, u as v, v as K, w as F, x as f, y as x } from "./validateManifest-DspYuz81.js";
|
|
2
|
+
import { D as y, a as h, b, P as k, r as z, s as H, u as J, c as U, d as j } from "./useFieldRegistry-CwjlA-ja.js";
|
|
3
3
|
export {
|
|
4
4
|
e as CATEGORY_LABELS,
|
|
5
5
|
t as COMPONENT_CATEGORY,
|
|
6
6
|
n as COMPONENT_STATE_KEY,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
N as
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
7
|
+
E as COMPONENT_TRAIT,
|
|
8
|
+
i as DATA_FIELD_ROLE,
|
|
9
|
+
T as DRILL_ACTION,
|
|
10
|
+
_ as DRILL_EVENT,
|
|
11
|
+
o as DRILL_STATE,
|
|
12
|
+
O as DYNAMIC_ENUM_KEY,
|
|
13
|
+
y as DataContainerRuntimeContext,
|
|
14
|
+
h as DataScope,
|
|
15
|
+
b as DataScopeContext,
|
|
16
|
+
N as ENGINE_EVENT_TYPE,
|
|
17
|
+
R as FIELD_ROLE_KEY,
|
|
18
|
+
A as INJECT_PATH_ROOT,
|
|
19
|
+
D as INJECT_PATH_SLOT_PROPS,
|
|
20
|
+
r as LOADING_PROP_NAME,
|
|
21
|
+
I as LOADING_STRATEGY,
|
|
22
|
+
C as LOADING_WRAPPER_TYPE,
|
|
23
|
+
L as NOTIFY_ERROR_STRATEGY,
|
|
24
|
+
l as NOTIFY_TIMING,
|
|
25
|
+
S as OptionItemSchema,
|
|
23
26
|
u as OptionsSchema,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
27
|
+
k as PageContext,
|
|
28
|
+
d as SLOT_KEY,
|
|
29
|
+
P as STANDARD_EVENT_KEYS,
|
|
30
|
+
Y as diagnoseMissingActionImpls,
|
|
31
|
+
m as diagnoseMissingStateKeys,
|
|
32
|
+
p as isCustomEventKey,
|
|
33
|
+
M as isStandardEventKey,
|
|
34
|
+
g as normalizeAdapterEvents,
|
|
35
|
+
c as normalizeManifestEvents,
|
|
36
|
+
G as printSingleValidationResult,
|
|
37
|
+
v as printValidationResult,
|
|
38
|
+
z as resolveDataContainerRuntimeValue,
|
|
39
|
+
H as shouldUseDataContainerRuntimeFallback,
|
|
40
|
+
K as useConcurrentLoading,
|
|
41
|
+
J as useDataContainer,
|
|
42
|
+
U as useDataContainerApi,
|
|
43
|
+
F as useDualLoading,
|
|
44
|
+
j as useFieldRegistry,
|
|
45
|
+
f as validateManifest,
|
|
46
|
+
x as validateManifests
|
|
44
47
|
};
|
package/dist/portable.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from './hooks/useConcurrentLoading';
|
|
|
7
7
|
export * from './hooks/useDualLoading';
|
|
8
8
|
export * from './protocol/adapter';
|
|
9
9
|
export * from './protocol/common-schemas';
|
|
10
|
+
export * from './protocol/drill';
|
|
10
11
|
export * from './protocol/events';
|
|
11
12
|
export * from './protocol/manifest';
|
|
12
13
|
export * from './protocol/manifest-types';
|
package/dist/portable.js
CHANGED
|
@@ -1,34 +1,37 @@
|
|
|
1
|
-
import { C as E, a as
|
|
1
|
+
import { C as E, a as T, b as _, c as e, D as i, d as n, e as t, f as O, g as N, E as A, F as I, I as R, h as L, L as o, i as S, j as D, N as Y, k as P, O as d, l, S as C, m as M, n as r, o as m, p as G, q as g, r as p, s as u, t as K, u as v, v as c, w as f, x as F, y as V } from "./validateManifest-DspYuz81.js";
|
|
2
2
|
export {
|
|
3
3
|
E as CATEGORY_LABELS,
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
T as COMPONENT_CATEGORY,
|
|
5
|
+
_ as COMPONENT_STATE_KEY,
|
|
6
|
+
e as COMPONENT_TRAIT,
|
|
7
7
|
i as DATA_FIELD_ROLE,
|
|
8
|
-
n as
|
|
9
|
-
t as
|
|
10
|
-
O as
|
|
11
|
-
N as
|
|
12
|
-
A as
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
m as
|
|
27
|
-
G as
|
|
28
|
-
g as
|
|
29
|
-
p as
|
|
30
|
-
u as
|
|
31
|
-
K as
|
|
32
|
-
v as
|
|
33
|
-
c as
|
|
8
|
+
n as DRILL_ACTION,
|
|
9
|
+
t as DRILL_EVENT,
|
|
10
|
+
O as DRILL_STATE,
|
|
11
|
+
N as DYNAMIC_ENUM_KEY,
|
|
12
|
+
A as ENGINE_EVENT_TYPE,
|
|
13
|
+
I as FIELD_ROLE_KEY,
|
|
14
|
+
R as INJECT_PATH_ROOT,
|
|
15
|
+
L as INJECT_PATH_SLOT_PROPS,
|
|
16
|
+
o as LOADING_PROP_NAME,
|
|
17
|
+
S as LOADING_STRATEGY,
|
|
18
|
+
D as LOADING_WRAPPER_TYPE,
|
|
19
|
+
Y as NOTIFY_ERROR_STRATEGY,
|
|
20
|
+
P as NOTIFY_TIMING,
|
|
21
|
+
d as OptionItemSchema,
|
|
22
|
+
l as OptionsSchema,
|
|
23
|
+
C as SLOT_KEY,
|
|
24
|
+
M as STANDARD_EVENT_KEYS,
|
|
25
|
+
r as diagnoseMissingActionImpls,
|
|
26
|
+
m as diagnoseMissingStateKeys,
|
|
27
|
+
G as isCustomEventKey,
|
|
28
|
+
g as isStandardEventKey,
|
|
29
|
+
p as normalizeAdapterEvents,
|
|
30
|
+
u as normalizeManifestEvents,
|
|
31
|
+
K as printSingleValidationResult,
|
|
32
|
+
v as printValidationResult,
|
|
33
|
+
c as useConcurrentLoading,
|
|
34
|
+
f as useDualLoading,
|
|
35
|
+
F as validateManifest,
|
|
36
|
+
V as validateManifests
|
|
34
37
|
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export declare const DRILL_ACTION: {
|
|
2
|
+
readonly PUSH: "drillPush";
|
|
3
|
+
readonly POP_TO: "drillPopTo";
|
|
4
|
+
readonly RESET: "drillReset";
|
|
5
|
+
};
|
|
6
|
+
export declare const DRILL_STATE: {
|
|
7
|
+
readonly PATH: "drillPath";
|
|
8
|
+
};
|
|
9
|
+
export declare const DRILL_EVENT: {
|
|
10
|
+
readonly NAVIGATE_REQUEST: "drill:navigateRequest";
|
|
11
|
+
readonly RESET_REQUEST: "drill:resetRequest";
|
|
12
|
+
};
|
|
13
|
+
export interface DrillFrame {
|
|
14
|
+
level: string;
|
|
15
|
+
key: string | number;
|
|
16
|
+
label: string;
|
|
17
|
+
record?: unknown;
|
|
18
|
+
}
|
|
19
|
+
export interface DrillNavigateRequest {
|
|
20
|
+
index: number;
|
|
21
|
+
}
|
|
22
|
+
export interface DrillPushParams {
|
|
23
|
+
frame: DrillFrame;
|
|
24
|
+
}
|
|
25
|
+
export interface DrillPopToParams {
|
|
26
|
+
index: number;
|
|
27
|
+
}
|
|
28
|
+
export interface DrillRuntimeProps {
|
|
29
|
+
drillPath?: readonly DrillFrame[];
|
|
30
|
+
onDrillNavigateRequest?: (request: DrillNavigateRequest) => void;
|
|
31
|
+
onDrillResetRequest?: () => void;
|
|
32
|
+
}
|
|
@@ -3,5 +3,6 @@ export declare const COMPONENT_TRAIT: {
|
|
|
3
3
|
readonly DATA_CONTAINER: "Data.Container";
|
|
4
4
|
readonly LAYOUT_CONTAINER: "Layout.Container";
|
|
5
5
|
readonly INTERACTION_CLICKABLE: "Interaction.Clickable";
|
|
6
|
+
readonly INTERACTION_DRILLABLE: "Interaction.Drillable";
|
|
6
7
|
};
|
|
7
8
|
export type ComponentTrait = typeof COMPONENT_TRAIT[keyof typeof COMPONENT_TRAIT];
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { useState as
|
|
2
|
-
const
|
|
3
|
-
const [t, e] =
|
|
4
|
-
|
|
1
|
+
import { useState as T, useRef as g, useEffect as L, useCallback as u, useMemo as m } from "react";
|
|
2
|
+
const S = () => {
|
|
3
|
+
const [t, e] = T(0), [o, n] = T(void 0), c = g(0);
|
|
4
|
+
L(() => {
|
|
5
5
|
c.current = t;
|
|
6
6
|
}, [t]);
|
|
7
|
-
const a =
|
|
8
|
-
const
|
|
9
|
-
return
|
|
10
|
-
}), a()), [a]), r =
|
|
7
|
+
const a = u(() => c.current > 0, []), s = u((p) => (e((E) => E + 1), p && n(p), a()), [a]), l = u(() => (e((p) => {
|
|
8
|
+
const E = Math.max(0, p - 1);
|
|
9
|
+
return E === 0 && n(void 0), E;
|
|
10
|
+
}), a()), [a]), r = u(() => {
|
|
11
11
|
e(0), n(void 0);
|
|
12
12
|
}, []);
|
|
13
|
-
return
|
|
13
|
+
return m(() => ({
|
|
14
14
|
isLoading: t > 0,
|
|
15
15
|
loadingText: o,
|
|
16
16
|
startLoading: s,
|
|
17
|
-
stopLoading:
|
|
17
|
+
stopLoading: l,
|
|
18
18
|
getLoading: a,
|
|
19
19
|
resetLoading: r
|
|
20
|
-
}), [a, t, o, r, s,
|
|
21
|
-
},
|
|
20
|
+
}), [a, t, o, r, s, l]);
|
|
21
|
+
}, V = () => {
|
|
22
22
|
const {
|
|
23
23
|
isLoading: t,
|
|
24
24
|
loadingText: e,
|
|
@@ -26,10 +26,10 @@ const _ = () => {
|
|
|
26
26
|
stopLoading: n,
|
|
27
27
|
getLoading: c,
|
|
28
28
|
resetLoading: a
|
|
29
|
-
} =
|
|
30
|
-
return
|
|
31
|
-
|
|
32
|
-
}, [r]),
|
|
29
|
+
} = S(), [s, l] = T(!1), r = m(() => t || s, [t, s]), p = g(!1);
|
|
30
|
+
return L(() => {
|
|
31
|
+
p.current = r;
|
|
32
|
+
}, [r]), m(() => ({
|
|
33
33
|
actionLoading: t,
|
|
34
34
|
actionLoadingText: e,
|
|
35
35
|
startActionLoading: o,
|
|
@@ -37,9 +37,9 @@ const _ = () => {
|
|
|
37
37
|
getActionLoading: c,
|
|
38
38
|
resetActionLoading: a,
|
|
39
39
|
dataLoading: s,
|
|
40
|
-
setDataLoading:
|
|
40
|
+
setDataLoading: l,
|
|
41
41
|
isLoading: r,
|
|
42
|
-
isLoadingRef:
|
|
42
|
+
isLoadingRef: p
|
|
43
43
|
}), [
|
|
44
44
|
t,
|
|
45
45
|
e,
|
|
@@ -62,7 +62,7 @@ function N(t) {
|
|
|
62
62
|
});
|
|
63
63
|
return e;
|
|
64
64
|
}
|
|
65
|
-
function
|
|
65
|
+
function O(t) {
|
|
66
66
|
if (!t)
|
|
67
67
|
return [];
|
|
68
68
|
const e = [];
|
|
@@ -73,8 +73,8 @@ function S(t) {
|
|
|
73
73
|
});
|
|
74
74
|
return e;
|
|
75
75
|
}
|
|
76
|
-
function
|
|
77
|
-
const e = N(t?.events), o =
|
|
76
|
+
function I(t) {
|
|
77
|
+
const e = N(t?.events), o = O(t?.customEvents);
|
|
78
78
|
return {
|
|
79
79
|
standard: e,
|
|
80
80
|
custom: o,
|
|
@@ -82,25 +82,34 @@ function v(t) {
|
|
|
82
82
|
allKeys: [...e.map((n) => n.type), ...o.map((n) => n.type)]
|
|
83
83
|
};
|
|
84
84
|
}
|
|
85
|
-
const
|
|
85
|
+
const v = {
|
|
86
86
|
type: "object",
|
|
87
87
|
properties: {
|
|
88
88
|
label: { type: "string", title: "显示名称" },
|
|
89
89
|
value: { type: "string", title: "选项值" },
|
|
90
90
|
disabled: { type: "boolean", title: "是否禁用" }
|
|
91
91
|
}
|
|
92
|
-
},
|
|
92
|
+
}, x = {
|
|
93
93
|
type: "array",
|
|
94
94
|
title: "选项列表",
|
|
95
|
-
items:
|
|
95
|
+
items: v
|
|
96
96
|
}, J = {
|
|
97
|
+
PUSH: "drillPush",
|
|
98
|
+
POP_TO: "drillPopTo",
|
|
99
|
+
RESET: "drillReset"
|
|
100
|
+
}, W = {
|
|
101
|
+
PATH: "drillPath"
|
|
102
|
+
}, q = {
|
|
103
|
+
NAVIGATE_REQUEST: "drill:navigateRequest",
|
|
104
|
+
RESET_REQUEST: "drill:resetRequest"
|
|
105
|
+
}, Q = {
|
|
97
106
|
BEFORE: "before",
|
|
98
107
|
AFTER: "after",
|
|
99
108
|
BOTH: "both"
|
|
100
|
-
},
|
|
109
|
+
}, X = {
|
|
101
110
|
IGNORE: "ignore",
|
|
102
111
|
STOP: "stop"
|
|
103
|
-
},
|
|
112
|
+
}, R = {
|
|
104
113
|
MOUNT: "mount",
|
|
105
114
|
UNMOUNT: "unmount",
|
|
106
115
|
CLICK: "click",
|
|
@@ -113,14 +122,14 @@ const $ = {
|
|
|
113
122
|
ITEM_LONG_PRESS: "itemLongPress",
|
|
114
123
|
DATA_FETCH: "dataFetch",
|
|
115
124
|
OPTIONS_FETCH: "optionsFetch"
|
|
116
|
-
},
|
|
117
|
-
function f(t) {
|
|
118
|
-
return L.has(t);
|
|
119
|
-
}
|
|
125
|
+
}, $ = Object.values(R), h = new Set($), C = /^[^:\s]+:[^:\s]+$/;
|
|
120
126
|
function y(t) {
|
|
121
|
-
return
|
|
127
|
+
return h.has(t);
|
|
122
128
|
}
|
|
123
|
-
|
|
129
|
+
function f(t) {
|
|
130
|
+
return C.test(t) && !h.has(t);
|
|
131
|
+
}
|
|
132
|
+
const Z = "x-dynamic-enum", tt = "x-slot", D = "$root", et = "__state", nt = "x-fieldRole", ot = {
|
|
124
133
|
ATTRIBUTE: "attribute",
|
|
125
134
|
DIMENSION: "dimension",
|
|
126
135
|
MEASURE: "measure"
|
|
@@ -156,19 +165,20 @@ function w(t) {
|
|
|
156
165
|
allKeys: [...e.map((n) => n.type), ...o.map((n) => n.type)]
|
|
157
166
|
};
|
|
158
167
|
}
|
|
159
|
-
const
|
|
168
|
+
const at = {
|
|
160
169
|
NATIVE: "native",
|
|
161
170
|
WRAPPER: "wrapper",
|
|
162
171
|
NONE: "none"
|
|
163
|
-
},
|
|
172
|
+
}, st = {
|
|
164
173
|
SPIN: "spin",
|
|
165
174
|
SKELETON: "skeleton",
|
|
166
175
|
WAVE: "wave"
|
|
167
|
-
},
|
|
176
|
+
}, rt = "loading", A = {
|
|
168
177
|
DATA_FIELD: "Data.Field",
|
|
169
178
|
DATA_CONTAINER: "Data.Container",
|
|
170
179
|
LAYOUT_CONTAINER: "Layout.Container",
|
|
171
|
-
INTERACTION_CLICKABLE: "Interaction.Clickable"
|
|
180
|
+
INTERACTION_CLICKABLE: "Interaction.Clickable",
|
|
181
|
+
INTERACTION_DRILLABLE: "Interaction.Drillable"
|
|
172
182
|
}, d = {
|
|
173
183
|
GENERAL: "General",
|
|
174
184
|
FLOAT: "Float",
|
|
@@ -181,7 +191,7 @@ const et = {
|
|
|
181
191
|
PAGE: "Page",
|
|
182
192
|
DEV: "Dev",
|
|
183
193
|
HTML_TEMPLATE: "HtmlTemplate"
|
|
184
|
-
},
|
|
194
|
+
}, it = {
|
|
185
195
|
[d.GENERAL]: "通用",
|
|
186
196
|
[d.FLOAT]: "悬浮",
|
|
187
197
|
[d.LAYOUT]: "布局",
|
|
@@ -193,17 +203,17 @@ const et = {
|
|
|
193
203
|
[d.PAGE]: "页面",
|
|
194
204
|
[d.DEV]: "调试",
|
|
195
205
|
[d.HTML_TEMPLATE]: "HTML 模板"
|
|
196
|
-
}, b = "slotProps.root", Y = [A.DATA_FIELD, A.DATA_CONTAINER], K = [D, b],
|
|
206
|
+
}, b = "slotProps.root", Y = [A.DATA_FIELD, A.DATA_CONTAINER], K = [D, b], _ = ["string", "number", "boolean", "array", "object", "integer", "null"];
|
|
197
207
|
function i(t, e, o, n, c) {
|
|
198
208
|
t.push({ type: e, field: o, message: n, severity: c });
|
|
199
209
|
}
|
|
200
|
-
function
|
|
210
|
+
function U(t, e, o) {
|
|
201
211
|
const n = t.type;
|
|
202
212
|
if (!t.meta)
|
|
203
213
|
return i(e, n, "meta", "meta 字段是必填的", "error"), !1;
|
|
204
214
|
if (t.meta.title || i(e, n, "meta.title", "title 是必填的", "error"), t.meta.category ? Object.values(d).includes(t.meta.category) || i(e, n, "meta.category", `无效的 category: ${t.meta.category}`, "error") : i(e, n, "meta.category", "category 是必填的", "error"), t.meta.valueSchema) {
|
|
205
215
|
const a = t.meta.valueSchema.type;
|
|
206
|
-
a && typeof a == "string" && !
|
|
216
|
+
a && typeof a == "string" && !_.includes(a) && i(e, n, "meta.valueSchema.type", `无效的 valueSchema type: ${a}`, "error");
|
|
207
217
|
}
|
|
208
218
|
return t.traits?.some((a) => Y.includes(a)) && !t.meta.valueSchema && i(
|
|
209
219
|
o,
|
|
@@ -213,28 +223,28 @@ function F(t, e, o) {
|
|
|
213
223
|
"warning"
|
|
214
224
|
), !0;
|
|
215
225
|
}
|
|
216
|
-
function
|
|
217
|
-
const n = t.type, c = w(t), a = new Set(c.standard.map((
|
|
218
|
-
if (c.all.length > 0 && (c.standard.forEach((
|
|
219
|
-
|
|
220
|
-
}), c.custom.forEach((
|
|
221
|
-
|
|
226
|
+
function H(t, e, o) {
|
|
227
|
+
const n = t.type, c = w(t), a = new Set(c.standard.map((l) => l.type)), s = new Set(c.custom.map((l) => l.type));
|
|
228
|
+
if (c.all.length > 0 && (c.standard.forEach((l, r) => {
|
|
229
|
+
l.type || i(e, n, `events[${r}].type`, "事件类型不能为空", "error"), l.type && !y(l.type) && i(e, n, `events[${r}].type`, `标准事件类型必须属于 EngineEventProtocol: ${l.type}`, "error");
|
|
230
|
+
}), c.custom.forEach((l) => {
|
|
231
|
+
l.type || i(e, n, "customEvents.type", "自定义事件类型不能为空", "error"), l.type && !f(l.type) && i(e, n, `customEvents.${l.type}`, `自定义事件类型必须是 namespaced 形态: ${l.type}`, "error"), l.payloadSchema || i(e, n, `customEvents.${l.type}.payloadSchema`, "自定义事件必须声明 payloadSchema", "error");
|
|
222
232
|
})), t.adapter) {
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
r.type || i(e, n, `adapter.events[${
|
|
226
|
-
}),
|
|
227
|
-
r.type || i(e, n, "adapter.customEvents.type", "Adapter 自定义事件类型不能为空", "error"), r.type && !
|
|
233
|
+
const l = I(t.adapter);
|
|
234
|
+
l.standard.forEach((r, p) => {
|
|
235
|
+
r.type || i(e, n, `adapter.events[${p}].type`, "Adapter 事件类型不能为空", "error"), r.type && !y(r.type) && i(e, n, `adapter.events[${p}].type`, `Adapter 标准事件类型必须属于 EngineEventProtocol: ${r.type}`, "error"), r.type && y(r.type) && !a.has(r.type) && i(e, n, `adapter.events[${p}].type`, `Adapter 标准事件必须先在 manifest.events 中声明: ${r.type}`, "error"), r.propName || i(e, n, `adapter.events[${p}].propName`, "Adapter propName 不能为空", "error");
|
|
236
|
+
}), l.custom.forEach((r) => {
|
|
237
|
+
r.type || i(e, n, "adapter.customEvents.type", "Adapter 自定义事件类型不能为空", "error"), r.type && !f(r.type) && i(e, n, `adapter.customEvents.${r.type}`, `Adapter 自定义事件类型必须是 namespaced 形态: ${r.type}`, "error"), r.type && f(r.type) && !s.has(r.type) && i(e, n, `adapter.customEvents.${r.type}`, `Adapter 自定义事件必须先在 manifest.customEvents 中声明: ${r.type}`, "error"), r.propName || i(e, n, `adapter.customEvents.${r.type}.propName`, "Adapter customEvents propName 不能为空", "error");
|
|
228
238
|
});
|
|
229
239
|
}
|
|
230
240
|
}
|
|
231
|
-
function
|
|
241
|
+
function F(t, e, o) {
|
|
232
242
|
const n = t.type, c = t.actions;
|
|
233
243
|
if (c)
|
|
234
244
|
for (const [a, s] of Object.entries(c))
|
|
235
245
|
s && (s.title || i(e, n, `actions.${a}.title`, `动作 "${a}" 缺少 title`, "error"), s.returns || i(o, n, `actions.${a}.returns`, `动作 "${a}" 未声明 returns schema,建议补充`, "warning"), s.params && s.params.type !== "object" && i(e, n, `actions.${a}.params.type`, '动作参数 schema 的 type 必须为 "object"', "error"));
|
|
236
246
|
}
|
|
237
|
-
function
|
|
247
|
+
function G(t, e, o) {
|
|
238
248
|
const n = t.type, c = t.engine?.render?.injection?.rootPath;
|
|
239
249
|
c ? typeof c == "string" && !K.includes(c) && i(
|
|
240
250
|
o,
|
|
@@ -250,7 +260,7 @@ function H(t, e, o) {
|
|
|
250
260
|
"warning"
|
|
251
261
|
);
|
|
252
262
|
}
|
|
253
|
-
function
|
|
263
|
+
function j(t, e, o) {
|
|
254
264
|
const n = t.type, c = t.slots;
|
|
255
265
|
if (c)
|
|
256
266
|
for (const [a, s] of Object.entries(c))
|
|
@@ -266,17 +276,17 @@ function k(t, e, o) {
|
|
|
266
276
|
const n = t.type, c = t.state;
|
|
267
277
|
if (c)
|
|
268
278
|
for (const [a, s] of Object.entries(c))
|
|
269
|
-
s && (s.title || i(e, n, `state.${a}.title`, `状态 "${a}" 缺少 title`, "error"), s.schema ? s.schema.type && typeof s.schema.type == "string" && !
|
|
279
|
+
s && (s.title || i(e, n, `state.${a}.title`, `状态 "${a}" 缺少 title`, "error"), s.schema ? s.schema.type && typeof s.schema.type == "string" && !_.includes(s.schema.type) && i(e, n, `state.${a}.schema.type`, `状态 "${a}" 的 schema.type 无效: ${s.schema.type}`, "error") : i(e, n, `state.${a}.schema`, `状态 "${a}" 缺少 schema`, "error"));
|
|
270
280
|
}
|
|
271
281
|
function z(t) {
|
|
272
282
|
const e = [], o = [];
|
|
273
|
-
return t.type || i(e, t.type || "Unknown", "type", "type 字段是必填的", "error"),
|
|
283
|
+
return t.type || i(e, t.type || "Unknown", "type", "type 字段是必填的", "error"), U(t, e, o) ? (H(t, e), F(t, e, o), k(t, e), j(t, e, o), G(t, e, o), {
|
|
274
284
|
valid: e.length === 0,
|
|
275
285
|
errors: e,
|
|
276
286
|
warnings: o
|
|
277
287
|
}) : { valid: !1, errors: e, warnings: o };
|
|
278
288
|
}
|
|
279
|
-
function
|
|
289
|
+
function ct(t) {
|
|
280
290
|
const e = [], o = [];
|
|
281
291
|
for (const n of t) {
|
|
282
292
|
const c = z(n);
|
|
@@ -288,13 +298,13 @@ function st(t) {
|
|
|
288
298
|
warnings: o
|
|
289
299
|
};
|
|
290
300
|
}
|
|
291
|
-
function
|
|
301
|
+
function lt(t, e) {
|
|
292
302
|
return !t || !e ? [] : t.filter((o) => typeof e[o] != "function");
|
|
293
303
|
}
|
|
294
|
-
function
|
|
304
|
+
function pt(t, e) {
|
|
295
305
|
return !t?.state || !e ? [] : Object.keys(t.state).filter((o) => !(o in e));
|
|
296
306
|
}
|
|
297
|
-
function
|
|
307
|
+
function dt(t) {
|
|
298
308
|
t.valid ? console.log("✅ 所有 Manifest 验证通过") : console.error(`❌ 发现 ${t.errors.length} 个错误`), t.errors.length > 0 && (console.error(`
|
|
299
309
|
错误列表:`), t.errors.forEach((e) => {
|
|
300
310
|
console.error(` ❌ [${e.type}] ${e.field}: ${e.message}`);
|
|
@@ -303,7 +313,7 @@ function ct(t) {
|
|
|
303
313
|
console.warn(` ⚠️ [${e.type}] ${e.field}: ${e.message}`);
|
|
304
314
|
}));
|
|
305
315
|
}
|
|
306
|
-
function
|
|
316
|
+
function Et(t, e = "[Registry]") {
|
|
307
317
|
if (!t.valid && t.errors.length > 0) {
|
|
308
318
|
const o = t.errors[0]?.type || "Unknown";
|
|
309
319
|
console.error(`${e} ❌ Manifest validation failed for '${o}':`), t.errors.forEach((n) => console.error(` - ${n.field}: ${n.message}`));
|
|
@@ -314,35 +324,38 @@ function pt(t, e = "[Registry]") {
|
|
|
314
324
|
}
|
|
315
325
|
}
|
|
316
326
|
export {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
327
|
+
it as C,
|
|
328
|
+
ot as D,
|
|
329
|
+
R as E,
|
|
330
|
+
nt as F,
|
|
321
331
|
D as I,
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
332
|
+
rt as L,
|
|
333
|
+
X as N,
|
|
334
|
+
v as O,
|
|
335
|
+
tt as S,
|
|
326
336
|
d as a,
|
|
327
|
-
|
|
337
|
+
et as b,
|
|
328
338
|
A as c,
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
339
|
+
J as d,
|
|
340
|
+
q as e,
|
|
341
|
+
W as f,
|
|
342
|
+
Z as g,
|
|
343
|
+
b as h,
|
|
344
|
+
at as i,
|
|
345
|
+
st as j,
|
|
346
|
+
Q as k,
|
|
347
|
+
x as l,
|
|
348
|
+
$ as m,
|
|
349
|
+
lt as n,
|
|
350
|
+
pt as o,
|
|
351
|
+
f as p,
|
|
352
|
+
y as q,
|
|
353
|
+
I as r,
|
|
354
|
+
w as s,
|
|
355
|
+
Et as t,
|
|
356
|
+
dt as u,
|
|
357
|
+
S as v,
|
|
358
|
+
V as w,
|
|
359
|
+
z as x,
|
|
360
|
+
ct as y
|
|
348
361
|
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: recipe
|
|
3
|
+
capability: drill
|
|
4
|
+
related:
|
|
5
|
+
- reference/层级下钻能力模型.md
|
|
6
|
+
- recipes/声明事件.md
|
|
7
|
+
- recipes/声明动作与状态.md
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# 声明层级下钻能力
|
|
11
|
+
|
|
12
|
+
## 适用场景
|
|
13
|
+
|
|
14
|
+
组件需要展示宿主维护的层级路径,并请求返回历史层或根层时使用。普通详情跳转不属于层级下钻。
|
|
15
|
+
|
|
16
|
+
## 步骤
|
|
17
|
+
|
|
18
|
+
1. 在 manifest 的 `traits` 中加入 `COMPONENT_TRAIT.INTERACTION_DRILLABLE`。
|
|
19
|
+
2. 组件接收 `DrillRuntimeProps`,受控渲染 `drillPath`。
|
|
20
|
+
3. 点击历史节点时调用 `onDrillNavigateRequest({ index })`;返回根层时调用 `onDrillResetRequest()`。
|
|
21
|
+
4. 在组件库内共享路径视图,不在每个 Chart、Table 或 CardList 重复实现。
|
|
22
|
+
5. 用 `validateManifest()` 检查 manifest。
|
|
23
|
+
|
|
24
|
+
不要在组件内保存第二份路径,也不要重复声明 trait 自动提供的 actions、state 和 events。数据查询、参数加工与更新成功后的 `drillPush` / `drillPopTo` / `drillReset` 由宿主事件编排完成。
|
|
25
|
+
|
|
26
|
+
## 自检
|
|
27
|
+
|
|
28
|
+
- 空路径不产生额外 DOM 或高度。
|
|
29
|
+
- 路径点击只发请求,不立即修改状态。
|
|
30
|
+
- 查询成功后再调用对应下钻 action。
|
|
31
|
+
|
|
32
|
+
## 关联文档
|
|
33
|
+
|
|
34
|
+
- [层级下钻能力模型](../reference/层级下钻能力模型.md)
|
|
@@ -24,6 +24,7 @@ Traits 之间不互斥,一个组件可以同时声明多个 trait。例如 For
|
|
|
24
24
|
| `Data.Container` | `COMPONENT_TRAIT.DATA_CONTAINER` | Form、Table、List、CardList | 组件管理一组数据作用域 |
|
|
25
25
|
| `Layout.Container` | `COMPONENT_TRAIT.LAYOUT_CONTAINER` | 通用容器:Card、Grid、Section;强组合关系:Tabs、Steps、Form(带 `nesting` 类型约束) | 组件具备**默认 children 区域**(与 `manifest.slots` 是两条独立机制) |
|
|
26
26
|
| `Interaction.Clickable` | `COMPONENT_TRAIT.INTERACTION_CLICKABLE` | Button、Link、ClickableCard | 组件具备点击交互语义 |
|
|
27
|
+
| `Interaction.Drillable` | `COMPONENT_TRAIT.INTERACTION_DRILLABLE` | Chart、Table、CardList | 宿主为组件实例提供受控下钻路径、动作和导航请求事件 |
|
|
27
28
|
|
|
28
29
|
---
|
|
29
30
|
|
|
@@ -154,6 +155,23 @@ Traits 之间不互斥,一个组件可以同时声明多个 trait。例如 For
|
|
|
154
155
|
|
|
155
156
|
---
|
|
156
157
|
|
|
158
|
+
## INTERACTION_DRILLABLE
|
|
159
|
+
|
|
160
|
+
### 什么时候声明
|
|
161
|
+
|
|
162
|
+
组件能够沿数据层级进入下一层并返回历史层,例如图表维度下钻、表格或卡片列表的下一级记录。
|
|
163
|
+
|
|
164
|
+
### 作者要做什么
|
|
165
|
+
|
|
166
|
+
- 声明 `COMPONENT_TRAIT.INTERACTION_DRILLABLE`。
|
|
167
|
+
- 接收宿主注入的 `drillPath`,并以适合自身布局的方式展示路径。
|
|
168
|
+
- 用户选择历史层时调用 `onDrillNavigateRequest({ index })`。
|
|
169
|
+
- 不在组件内部维护第二份路径状态,也不在 manifest 重复声明 trait 自动提供的 props、event、actions 和 state。
|
|
170
|
+
|
|
171
|
+
完整契约与编排边界见 [层级下钻能力模型](./层级下钻能力模型.md)。
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
157
175
|
## Traits 与 valueSchema
|
|
158
176
|
|
|
159
177
|
声明 `DATA_FIELD` 或 `DATA_CONTAINER` 时,建议同时声明 `meta.valueSchema`。
|
|
@@ -194,6 +212,7 @@ meta: {
|
|
|
194
212
|
| `DATA_CONTAINER` | 用于管理子字段数据作用域;必须在子组件渲染区域提供 `DataScope`。与 `LAYOUT_CONTAINER` 不互斥,Form 这类容器应同时声明 |
|
|
195
213
|
| `LAYOUT_CONTAINER` | 控制**默认 children 区域**开关,仅影响 `schema.children` 是否被宿主递归渲染。具名子区域走 `manifest.slots`,与本 trait 互不依赖 |
|
|
196
214
|
| `INTERACTION_CLICKABLE` | 表示具备点击语义;需要编排响应时再声明 click event |
|
|
215
|
+
| `INTERACTION_DRILLABLE` | 表示具备层级下钻语义;宿主维护路径状态,组件只做受控展示与导航请求 |
|
|
197
216
|
|
|
198
217
|
数据 trait 与 `meta.valueSchema` 的校验级别见 [validateManifest 校验规则](./validateManifest校验规则.md)。
|
|
199
218
|
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: reference
|
|
3
|
+
capability: drill
|
|
4
|
+
related:
|
|
5
|
+
- recipes/声明层级下钻能力.md
|
|
6
|
+
- reference/Traits能力模型.md
|
|
7
|
+
- reference/Events模型.md
|
|
8
|
+
- reference/ActionsState模型.md
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# 层级下钻能力模型
|
|
12
|
+
|
|
13
|
+
`INTERACTION_DRILLABLE` 声明组件能够沿数据层级进入、返回和复位。它只定义跨包契约:宿主维护路径状态并执行编排,组件通过受控 props 展示路径并发出导航请求。当 `drillPath` 为空时表示根层,当前层由末帧派生,不单独保存。
|
|
14
|
+
|
|
15
|
+
## 组件作者接入
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import type { DrillRuntimeProps } from 'cdp-material-sdk/portable';
|
|
19
|
+
import { COMPONENT_TRAIT } from 'cdp-material-sdk/portable';
|
|
20
|
+
|
|
21
|
+
export const manifest = {
|
|
22
|
+
// ...
|
|
23
|
+
traits: [COMPONENT_TRAIT.INTERACTION_DRILLABLE],
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export function Chart({
|
|
27
|
+
drillPath = [],
|
|
28
|
+
onDrillNavigateRequest,
|
|
29
|
+
onDrillResetRequest,
|
|
30
|
+
}: DrillRuntimeProps) {
|
|
31
|
+
return (
|
|
32
|
+
<DrillPathView
|
|
33
|
+
items={drillPath}
|
|
34
|
+
onNavigate={(index) => onDrillNavigateRequest?.({ index })}
|
|
35
|
+
onReset={() => onDrillResetRequest?.()}
|
|
36
|
+
/>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
组件负责路径 UI 的位置与样式,但不自行保存第二份路径状态。一个组件库内的 Chart、Table、CardList 应复用库内共享的纯展示组件。
|
|
42
|
+
|
|
43
|
+
## 宿主自动提供的契约
|
|
44
|
+
|
|
45
|
+
| 类别 | 名称 | 语义 |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| Prop | `drillPath` | 当前组件实例的受控路径,类型为 `DrillFrame[]` |
|
|
48
|
+
| Prop | `onDrillNavigateRequest` | 用户点击历史路径节点时调用,参数为 `{ index }` |
|
|
49
|
+
| Prop | `onDrillResetRequest` | 用户请求返回根层时调用 |
|
|
50
|
+
| Event | `drill:navigateRequest` | 将返回请求交给事件编排 |
|
|
51
|
+
| Event | `drill:resetRequest` | 将返回根层请求交给事件编排 |
|
|
52
|
+
| Action | `drillPush({ frame })` | 成功取得下一层数据后追加路径 |
|
|
53
|
+
| Action | `drillPopTo({ index })` | 成功取得历史层数据后截断路径 |
|
|
54
|
+
| Action | `drillReset()` | 返回根层 |
|
|
55
|
+
| State | `drillPath` | 供表达式读取的当前路径快照 |
|
|
56
|
+
|
|
57
|
+
以上字段由 trait 对应的宿主 Feature 自动注入,组件 manifest 不要重复声明 props、event、actions 或 state。
|
|
58
|
+
|
|
59
|
+
## 编排边界
|
|
60
|
+
|
|
61
|
+
下钻状态不负责查询。推荐顺序是:
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
itemClick
|
|
65
|
+
→ 参数加工 / 条件判断
|
|
66
|
+
→ 查询并更新组件数据
|
|
67
|
+
→ component.invoke(drillPush, { frame })
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
返回历史层同理:先查询并更新数据,成功后再调用 `drillPopTo`。查询失败时路径保持不变。
|
|
71
|
+
|
|
72
|
+
## 公共导出
|
|
73
|
+
|
|
74
|
+
以下内容均从 `cdp-material-sdk/portable` 导入:
|
|
75
|
+
|
|
76
|
+
- `COMPONENT_TRAIT.INTERACTION_DRILLABLE`
|
|
77
|
+
- `DRILL_ACTION`、`DRILL_STATE`、`DRILL_EVENT`
|
|
78
|
+
- `DrillFrame`、`DrillNavigateRequest`、`DrillPushParams`、`DrillPopToParams`、`DrillRuntimeProps`
|
|
79
|
+
|
|
80
|
+
SDK 不提供下钻 Hook、HOC 或面包屑 UI;这些分别属于宿主 Feature 和外置 UI 库。
|