@wipco/sdui 0.44.0 → 0.45.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.
- package/dist/index.d.ts +2 -2
- package/dist/index.js +142 -46
- package/dist/meta.d.ts +1 -1
- package/dist/{types-Bx3oingj.d.ts → types--y5jCOV5.d.ts} +16 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import React__default, { CSSProperties, ReactNode, ComponentType } from 'react';
|
|
3
|
-
import { S as SduiPage, a as SduiAction, b as SduiPropValue, c as SduiRule } from './types
|
|
4
|
-
export { d as SduiArgRef, e as SduiCalcRef, f as SduiChild, g as SduiIndexRef, h as SduiItemRef, i as SduiNode, j as SduiPageQuery, k as SduiScalar, l as SduiStateRef } from './types
|
|
3
|
+
import { S as SduiPage, a as SduiAction, b as SduiPropValue, c as SduiRule } from './types--y5jCOV5.js';
|
|
4
|
+
export { d as SduiArgRef, e as SduiCalcRef, f as SduiChild, g as SduiIndexRef, h as SduiItemRef, i as SduiNode, j as SduiPageQuery, k as SduiScalar, l as SduiStateRef } from './types--y5jCOV5.js';
|
|
5
5
|
import { S as SduiBoxProps, a as SduiContainerLayoutProps, b as SduiColumnsScale, c as SduiGapScale, d as SduiWeightScale, e as SduiTextAlignScale } from './layout-C3nRXMwb.js';
|
|
6
6
|
export { C as CHILD_LAYOUT_PROPS, L as LAYOUT_CSS, f as SduiAlignScale, g as SduiChildLayoutProps, h as SduiSizeScale, i as SduiSpanScale, j as childLayoutFrom, k as columnsClass, l as containerLayoutStyle, m as joinClass, n as mergeStyle, t as typographyStyle } from './layout-C3nRXMwb.js';
|
|
7
7
|
import { D as DatePickerProps, a as DateRangePickerProps, T as TimePickerProps } from './DatePicker-BK_jsV7i.js';
|
package/dist/index.js
CHANGED
|
@@ -2017,6 +2017,84 @@ async function runRequestAction(action, deps) {
|
|
|
2017
2017
|
}
|
|
2018
2018
|
}
|
|
2019
2019
|
|
|
2020
|
+
// src/state-path.ts
|
|
2021
|
+
var FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
2022
|
+
function isPlainObject2(value) {
|
|
2023
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2024
|
+
}
|
|
2025
|
+
function normalizeSegment(raw) {
|
|
2026
|
+
if (typeof raw === "number") {
|
|
2027
|
+
return Number.isInteger(raw) && raw >= 0 ? raw : null;
|
|
2028
|
+
}
|
|
2029
|
+
if (typeof raw !== "string" || raw.trim() === "") return null;
|
|
2030
|
+
if (FORBIDDEN_KEYS.has(raw)) return null;
|
|
2031
|
+
const asNumber = Number(raw);
|
|
2032
|
+
if (Number.isInteger(asNumber) && asNumber >= 0 && String(asNumber) === raw) return asNumber;
|
|
2033
|
+
return raw;
|
|
2034
|
+
}
|
|
2035
|
+
function setAtPath(root, path, value) {
|
|
2036
|
+
if (path.length === 0) return { ok: true, next: value };
|
|
2037
|
+
const segments = [];
|
|
2038
|
+
for (const raw of path) {
|
|
2039
|
+
const segment = normalizeSegment(raw);
|
|
2040
|
+
if (segment === null) {
|
|
2041
|
+
return {
|
|
2042
|
+
ok: false,
|
|
2043
|
+
reason: `\uACBD\uB85C \uC870\uAC01\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: ${JSON.stringify(raw)} (\uBE44\uC5B4 \uC788\uC9C0 \uC54A\uC740 \uBB38\uC790\uC5F4\uC774\uB098 0 \uC774\uC0C1 \uC815\uC218\uC5EC\uC57C \uD569\uB2C8\uB2E4)`
|
|
2044
|
+
};
|
|
2045
|
+
}
|
|
2046
|
+
segments.push(segment);
|
|
2047
|
+
}
|
|
2048
|
+
const write = (container, depth) => {
|
|
2049
|
+
const segment = segments[depth];
|
|
2050
|
+
const last = depth === segments.length - 1;
|
|
2051
|
+
if (typeof segment === "number") {
|
|
2052
|
+
if (!Array.isArray(container)) {
|
|
2053
|
+
return {
|
|
2054
|
+
ok: false,
|
|
2055
|
+
reason: `${describe(segments, depth)}: \uBC30\uC5F4\uC774 \uC544\uB2CC \uC790\uB9AC\uC5D0 \uC778\uB371\uC2A4 ${segment}\uB85C \uB4E4\uC5B4\uAC08 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4`
|
|
2056
|
+
};
|
|
2057
|
+
}
|
|
2058
|
+
if (segment >= container.length) {
|
|
2059
|
+
return {
|
|
2060
|
+
ok: false,
|
|
2061
|
+
reason: `${describe(segments, depth)}: \uC778\uB371\uC2A4 ${segment}\uAC00 \uBC94\uC704 \uBC16\uC785\uB2C8\uB2E4(\uAE38\uC774 ${container.length}) \u2014 \uBC30\uC5F4\uC744 \uC778\uB371\uC2A4\uB85C \uB298\uB9AC\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`
|
|
2062
|
+
};
|
|
2063
|
+
}
|
|
2064
|
+
const nextChild2 = last ? { ok: true, next: value } : write(container[segment] ?? null, depth + 1);
|
|
2065
|
+
if (!nextChild2.ok) return nextChild2;
|
|
2066
|
+
const copy = container.slice();
|
|
2067
|
+
copy[segment] = nextChild2.next;
|
|
2068
|
+
return { ok: true, next: copy };
|
|
2069
|
+
}
|
|
2070
|
+
if (Array.isArray(container)) {
|
|
2071
|
+
return {
|
|
2072
|
+
ok: false,
|
|
2073
|
+
reason: `${describe(segments, depth)}: \uBC30\uC5F4\uC5D0 \uBB38\uC790\uC5F4 \uD0A4 '${segment}'\uB85C \uB4E4\uC5B4\uAC08 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4`
|
|
2074
|
+
};
|
|
2075
|
+
}
|
|
2076
|
+
if (container !== null && container !== void 0 && !isPlainObject2(container)) {
|
|
2077
|
+
return {
|
|
2078
|
+
ok: false,
|
|
2079
|
+
reason: `${describe(segments, depth)}: \uAC1D\uCCB4\uAC00 \uC544\uB2CC \uAC12(${typeof container}) \uC548\uC73C\uB85C \uB4E4\uC5B4\uAC08 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4`
|
|
2080
|
+
};
|
|
2081
|
+
}
|
|
2082
|
+
const base = isPlainObject2(container) ? container : {};
|
|
2083
|
+
const nextChild = last ? { ok: true, next: value } : write(base[segment] ?? null, depth + 1);
|
|
2084
|
+
if (!nextChild.ok) return nextChild;
|
|
2085
|
+
return { ok: true, next: { ...base, [segment]: nextChild.next } };
|
|
2086
|
+
};
|
|
2087
|
+
return write(root, 0);
|
|
2088
|
+
}
|
|
2089
|
+
function describe(segments, upto) {
|
|
2090
|
+
let out = "";
|
|
2091
|
+
for (let i = 0; i <= upto; i += 1) {
|
|
2092
|
+
const segment = segments[i];
|
|
2093
|
+
out += typeof segment === "number" ? `[${segment}]` : out === "" ? String(segment) : `.${segment}`;
|
|
2094
|
+
}
|
|
2095
|
+
return out;
|
|
2096
|
+
}
|
|
2097
|
+
|
|
2020
2098
|
// src/validate.ts
|
|
2021
2099
|
var ACTION_NAMES = /* @__PURE__ */ new Set([
|
|
2022
2100
|
"navigate",
|
|
@@ -2055,7 +2133,7 @@ var DENIED_PROPS = /* @__PURE__ */ new Set([
|
|
|
2055
2133
|
"constructor",
|
|
2056
2134
|
"prototype"
|
|
2057
2135
|
]);
|
|
2058
|
-
function
|
|
2136
|
+
function isPlainObject3(v) {
|
|
2059
2137
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
2060
2138
|
}
|
|
2061
2139
|
function checkUrlValue(key, value, path, issues) {
|
|
@@ -2065,7 +2143,7 @@ function checkUrlValue(key, value, path, issues) {
|
|
|
2065
2143
|
}
|
|
2066
2144
|
function validateSpec(page, knownComponents, slotNamesOf) {
|
|
2067
2145
|
const issues = [];
|
|
2068
|
-
if (!
|
|
2146
|
+
if (!isPlainObject3(page)) return [{ path: "$", message: "\uC2A4\uD399\uC774 \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4" }];
|
|
2069
2147
|
if (page.version !== 1) issues.push({ path: "$.version", message: "version\uC740 1\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4" });
|
|
2070
2148
|
validatePageData(page.data, issues);
|
|
2071
2149
|
if (!Array.isArray(page.body)) {
|
|
@@ -2079,7 +2157,7 @@ function validateSpec(page, knownComponents, slotNamesOf) {
|
|
|
2079
2157
|
}
|
|
2080
2158
|
function validatePageData(data, issues) {
|
|
2081
2159
|
if (data === void 0) return;
|
|
2082
|
-
if (!
|
|
2160
|
+
if (!isPlainObject3(data)) {
|
|
2083
2161
|
issues.push({ path: "$.data", message: "data\uB294 \uAC1D\uCCB4\uC5EC\uC57C \uD569\uB2C8\uB2E4" });
|
|
2084
2162
|
return;
|
|
2085
2163
|
}
|
|
@@ -2089,7 +2167,7 @@ function validatePageData(data, issues) {
|
|
|
2089
2167
|
issues.push({ path, message: "\uC0C1\uD0DC \uD0A4\uB294 \uBE44\uC5B4 \uC788\uC9C0 \uC54A\uC544\uC57C \uD558\uACE0 $\uB85C \uC2DC\uC791\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4" });
|
|
2090
2168
|
continue;
|
|
2091
2169
|
}
|
|
2092
|
-
if (!
|
|
2170
|
+
if (!isPlainObject3(raw)) {
|
|
2093
2171
|
issues.push({ path, message: "\uC870\uD68C\uB294 { endpoint, select?, when?, fallback? } \uAC1D\uCCB4\uC5EC\uC57C \uD569\uB2C8\uB2E4" });
|
|
2094
2172
|
continue;
|
|
2095
2173
|
}
|
|
@@ -2101,7 +2179,7 @@ function validatePageData(data, issues) {
|
|
|
2101
2179
|
} else if (!raw.endpoint.startsWith("/")) {
|
|
2102
2180
|
issues.push({ path: `${path}.endpoint`, message: "endpoint\uB294 /\uB85C \uC2DC\uC791\uD558\uB294 \uACBD\uB85C\uC5EC\uC57C \uD569\uB2C8\uB2E4" });
|
|
2103
2181
|
}
|
|
2104
|
-
} else if (!
|
|
2182
|
+
} else if (!isPlainObject3(raw.endpoint)) {
|
|
2105
2183
|
issues.push({ path: `${path}.endpoint`, message: "endpoint\uB294 \uBB38\uC790\uC5F4\uC774\uAC70\uB098 \uAC12 \uCC38\uC870\uC5EC\uC57C \uD569\uB2C8\uB2E4" });
|
|
2106
2184
|
} else {
|
|
2107
2185
|
walkValue(raw.endpoint, `${path}.endpoint`, issues, false);
|
|
@@ -2124,7 +2202,7 @@ function validatePageData(data, issues) {
|
|
|
2124
2202
|
}
|
|
2125
2203
|
function walkChild(child, path, issues, known, slotNamesOf) {
|
|
2126
2204
|
if (typeof child === "string") return;
|
|
2127
|
-
if (!
|
|
2205
|
+
if (!isPlainObject3(child)) {
|
|
2128
2206
|
issues.push({ path, message: "children \uD56D\uBAA9\uC740 \uBB38\uC790\uC5F4 \uB610\uB294 \uB178\uB4DC \uAC1D\uCCB4\uC5EC\uC57C \uD569\uB2C8\uB2E4" });
|
|
2129
2207
|
return;
|
|
2130
2208
|
}
|
|
@@ -2136,7 +2214,7 @@ function walkChild(child, path, issues, known, slotNamesOf) {
|
|
|
2136
2214
|
if (known && !RENDERER_BUILTINS.has(node.component) && !known.has(node.component)) {
|
|
2137
2215
|
issues.push({ path, message: `\uB4F1\uB85D\uB418\uC9C0 \uC54A\uC740 \uCEF4\uD3EC\uB10C\uD2B8: ${node.component}` });
|
|
2138
2216
|
}
|
|
2139
|
-
if (node.props !== void 0 && !
|
|
2217
|
+
if (node.props !== void 0 && !isPlainObject3(node.props)) {
|
|
2140
2218
|
issues.push({ path: `${path}.props`, message: "props\uB294 \uAC1D\uCCB4\uC5EC\uC57C \uD569\uB2C8\uB2E4" });
|
|
2141
2219
|
}
|
|
2142
2220
|
for (const [name, value] of Object.entries(node.props ?? {})) {
|
|
@@ -2150,9 +2228,9 @@ function walkChild(child, path, issues, known, slotNamesOf) {
|
|
|
2150
2228
|
checkUrlValue(name, value, `${path}.props.${name}`, issues);
|
|
2151
2229
|
walkValue(value, `${path}.props.${name}`, issues, name.startsWith("on") || name === "rowClick");
|
|
2152
2230
|
}
|
|
2153
|
-
if (node.component === "Form" &&
|
|
2231
|
+
if (node.component === "Form" && isPlainObject3(node.props) && node.props.rules !== void 0) {
|
|
2154
2232
|
const rules = node.props.rules;
|
|
2155
|
-
if (!
|
|
2233
|
+
if (!isPlainObject3(rules)) {
|
|
2156
2234
|
issues.push({ path: `${path}.props.rules`, message: "rules\uB294 { \uD544\uB4DC: \uADDC\uCE59\uBC30\uC5F4 } \uAC1D\uCCB4\uC5EC\uC57C \uD569\uB2C8\uB2E4" });
|
|
2157
2235
|
} else {
|
|
2158
2236
|
for (const [field, list] of Object.entries(rules)) {
|
|
@@ -2163,15 +2241,15 @@ function walkChild(child, path, issues, known, slotNamesOf) {
|
|
|
2163
2241
|
}
|
|
2164
2242
|
}
|
|
2165
2243
|
if (node.component === "Fragment") {
|
|
2166
|
-
const id =
|
|
2167
|
-
if ((typeof id !== "string" || id === "") && !
|
|
2244
|
+
const id = isPlainObject3(node.props) ? node.props.id : void 0;
|
|
2245
|
+
if ((typeof id !== "string" || id === "") && !isPlainObject3(id)) {
|
|
2168
2246
|
issues.push({
|
|
2169
2247
|
path: `${path}.props.id`,
|
|
2170
2248
|
message: "Fragment.id\uB294 \uBE44\uC5B4 \uC788\uC9C0 \uC54A\uC740 \uBB38\uC790\uC5F4(\uB610\uB294 \uAC12 \uCC38\uC870)\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4"
|
|
2171
2249
|
});
|
|
2172
2250
|
}
|
|
2173
|
-
const args =
|
|
2174
|
-
if (args !== void 0 && !
|
|
2251
|
+
const args = isPlainObject3(node.props) ? node.props.args : void 0;
|
|
2252
|
+
if (args !== void 0 && !isPlainObject3(args)) {
|
|
2175
2253
|
issues.push({
|
|
2176
2254
|
path: `${path}.props.args`,
|
|
2177
2255
|
message: "Fragment.args\uB294 { \uC774\uB984: \uAC12 } \uD3C9\uBA74 \uC624\uBE0C\uC81D\uD2B8\uC5EC\uC57C \uD569\uB2C8\uB2E4"
|
|
@@ -2185,7 +2263,7 @@ function walkChild(child, path, issues, known, slotNamesOf) {
|
|
|
2185
2263
|
}
|
|
2186
2264
|
}
|
|
2187
2265
|
if (node.slots !== void 0) {
|
|
2188
|
-
if (!
|
|
2266
|
+
if (!isPlainObject3(node.slots)) {
|
|
2189
2267
|
issues.push({ path: `${path}.slots`, message: "slots\uB294 \uAC1D\uCCB4\uC5EC\uC57C \uD569\uB2C8\uB2E4" });
|
|
2190
2268
|
} else {
|
|
2191
2269
|
const slotNames = slotNamesOf?.(node.component) ?? null;
|
|
@@ -2221,7 +2299,7 @@ function walkValue(value, path, issues, actionEligible) {
|
|
|
2221
2299
|
value.forEach((v, i) => walkValue(v, `${path}[${i}]`, issues, actionEligible));
|
|
2222
2300
|
return;
|
|
2223
2301
|
}
|
|
2224
|
-
if (!
|
|
2302
|
+
if (!isPlainObject3(value)) return;
|
|
2225
2303
|
if (typeof value.action === "string" && (actionEligible || ACTION_NAMES.has(value.action))) {
|
|
2226
2304
|
if (actionEligible && !ACTION_NAMES.has(value.action)) {
|
|
2227
2305
|
issues.push({ path, message: `\uC54C \uC218 \uC5C6\uB294 \uC561\uC158: ${value.action}` });
|
|
@@ -2248,7 +2326,7 @@ function walkValue(value, path, issues, actionEligible) {
|
|
|
2248
2326
|
}
|
|
2249
2327
|
if ("$calc" in value) {
|
|
2250
2328
|
const calc = value.$calc;
|
|
2251
|
-
if (!
|
|
2329
|
+
if (!isPlainObject3(calc) || typeof calc.op !== "string" || !CALC_OPS.has(calc.op)) {
|
|
2252
2330
|
issues.push({ path, message: "$calc.op\uC774 \uC720\uD6A8\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4" });
|
|
2253
2331
|
} else if (!Array.isArray(calc.args)) {
|
|
2254
2332
|
issues.push({ path: `${path}.$calc.args`, message: "args\uB294 \uBC30\uC5F4\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4" });
|
|
@@ -2277,12 +2355,12 @@ function walkValue(value, path, issues, actionEligible) {
|
|
|
2277
2355
|
}
|
|
2278
2356
|
|
|
2279
2357
|
// src/page-data.ts
|
|
2280
|
-
function
|
|
2358
|
+
function isPlainObject4(value) {
|
|
2281
2359
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2282
2360
|
}
|
|
2283
2361
|
function planPageData(data, resolve) {
|
|
2284
2362
|
if (data === void 0) return [];
|
|
2285
|
-
if (!
|
|
2363
|
+
if (!isPlainObject4(data)) {
|
|
2286
2364
|
warnOnce("page-data:root", "[sdui] page.data\uB294 \uAC1D\uCCB4\uC5EC\uC57C \uD569\uB2C8\uB2E4 \u2014 \uBB34\uC2DC\uD569\uB2C8\uB2E4");
|
|
2287
2365
|
return [];
|
|
2288
2366
|
}
|
|
@@ -2292,7 +2370,7 @@ function planPageData(data, resolve) {
|
|
|
2292
2370
|
warnOnce(`page-data:${key}`, `[sdui] page.data\uC758 \uC0C1\uD0DC \uD0A4 "${key}"\uB294 \uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 \uAC74\uB108\uB701\uB2C8\uB2E4`);
|
|
2293
2371
|
continue;
|
|
2294
2372
|
}
|
|
2295
|
-
if (!
|
|
2373
|
+
if (!isPlainObject4(raw)) {
|
|
2296
2374
|
warnOnce(`page-data:${key}`, `[sdui] page.data.${key}\uB294 \uAC1D\uCCB4\uC5EC\uC57C \uD569\uB2C8\uB2E4 \u2014 \uAC74\uB108\uB701\uB2C8\uB2E4`);
|
|
2297
2375
|
continue;
|
|
2298
2376
|
}
|
|
@@ -2327,7 +2405,7 @@ function pickPath(source, path) {
|
|
|
2327
2405
|
if (path === void 0 || path === "") return source;
|
|
2328
2406
|
let value = source;
|
|
2329
2407
|
for (const segment of path.split(".")) {
|
|
2330
|
-
if (!
|
|
2408
|
+
if (!isPlainObject4(value)) return void 0;
|
|
2331
2409
|
value = value[segment];
|
|
2332
2410
|
}
|
|
2333
2411
|
return value;
|
|
@@ -2358,26 +2436,26 @@ function nearestArgsFrame(scope) {
|
|
|
2358
2436
|
}
|
|
2359
2437
|
return void 0;
|
|
2360
2438
|
}
|
|
2361
|
-
function
|
|
2439
|
+
function isPlainObject5(v) {
|
|
2362
2440
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
2363
2441
|
}
|
|
2364
2442
|
function isStateRef(v) {
|
|
2365
|
-
return
|
|
2443
|
+
return isPlainObject5(v) && typeof v.$state === "string";
|
|
2366
2444
|
}
|
|
2367
2445
|
function isItemRef(v) {
|
|
2368
|
-
return
|
|
2446
|
+
return isPlainObject5(v) && "$item" in v;
|
|
2369
2447
|
}
|
|
2370
2448
|
function isIndexRef(v) {
|
|
2371
|
-
return
|
|
2449
|
+
return isPlainObject5(v) && "$index" in v;
|
|
2372
2450
|
}
|
|
2373
2451
|
function isCalcRef(v) {
|
|
2374
|
-
return
|
|
2452
|
+
return isPlainObject5(v) && isPlainObject5(v.$calc);
|
|
2375
2453
|
}
|
|
2376
2454
|
function isArgRef(v) {
|
|
2377
|
-
return
|
|
2455
|
+
return isPlainObject5(v) && typeof v.$arg === "string";
|
|
2378
2456
|
}
|
|
2379
2457
|
function isAction(v) {
|
|
2380
|
-
return
|
|
2458
|
+
return isPlainObject5(v) && typeof v.action === "string";
|
|
2381
2459
|
}
|
|
2382
2460
|
function isActionList(v) {
|
|
2383
2461
|
return Array.isArray(v) && v.length > 0 && v.every(isAction);
|
|
@@ -2401,7 +2479,7 @@ function expandActionEntries(raw, scope) {
|
|
|
2401
2479
|
return [];
|
|
2402
2480
|
}
|
|
2403
2481
|
function eventValue(arg) {
|
|
2404
|
-
if (
|
|
2482
|
+
if (isPlainObject5(arg) && "target" in arg && typeof arg.preventDefault === "function") {
|
|
2405
2483
|
const target = arg.target;
|
|
2406
2484
|
if (target.type === "checkbox") return target.checked;
|
|
2407
2485
|
if (target.type === "number" || target.type === "range") {
|
|
@@ -2511,7 +2589,7 @@ function childrenOf(node) {
|
|
|
2511
2589
|
}
|
|
2512
2590
|
function renderChild(child, index, scope, engine) {
|
|
2513
2591
|
if (typeof child === "string") return child;
|
|
2514
|
-
if (!
|
|
2592
|
+
if (!isPlainObject5(child)) {
|
|
2515
2593
|
warnOnce2(`child:${String(child)}`, `[sdui] \uC798\uBABB\uB41C \uB178\uB4DC(\uBB38\uC790\uC5F4 \uB610\uB294 \uAC1D\uCCB4\uC5EC\uC57C \uD569\uB2C8\uB2E4): ${String(child)}`);
|
|
2516
2594
|
return /* @__PURE__ */ jsx(SpecErrorCard, { children: "[sdui] \uC798\uBABB\uB41C \uB178\uB4DC \u2014 \uBB38\uC790\uC5F4 \uB610\uB294 \uB178\uB4DC \uAC1D\uCCB4\uC5EC\uC57C \uD569\uB2C8\uB2E4" }, index);
|
|
2517
2595
|
}
|
|
@@ -2526,11 +2604,11 @@ function SduiNodeRenderer({
|
|
|
2526
2604
|
engine
|
|
2527
2605
|
}) {
|
|
2528
2606
|
const { registry, resolveValue, dispatch, resolveAsset } = engine;
|
|
2529
|
-
const slots =
|
|
2607
|
+
const slots = isPlainObject5(node.slots) ? node.slots : void 0;
|
|
2530
2608
|
const childList = childrenOf(node);
|
|
2531
2609
|
if (node.component === "ForEach") {
|
|
2532
2610
|
const source = resolveValue(
|
|
2533
|
-
|
|
2611
|
+
isPlainObject5(node.props) ? node.props.source ?? null : null,
|
|
2534
2612
|
scope
|
|
2535
2613
|
);
|
|
2536
2614
|
const rows = Array.isArray(source) ? source : [];
|
|
@@ -2540,7 +2618,7 @@ function SduiNodeRenderer({
|
|
|
2540
2618
|
}
|
|
2541
2619
|
return /* @__PURE__ */ jsx(Fragment, { children: rows.map((item, rowIndex) => {
|
|
2542
2620
|
const rowScope = [...scope, { item, index: rowIndex }];
|
|
2543
|
-
const rowKey =
|
|
2621
|
+
const rowKey = isPlainObject5(item) && typeof item.id === "string" ? item.id : rowIndex;
|
|
2544
2622
|
return /* @__PURE__ */ jsx(React9.Fragment, { children: childList?.map((child, i) => renderChild(child, i, rowScope, engine)) }, rowKey);
|
|
2545
2623
|
}) });
|
|
2546
2624
|
}
|
|
@@ -2559,7 +2637,7 @@ function SduiNodeRenderer({
|
|
|
2559
2637
|
] });
|
|
2560
2638
|
}
|
|
2561
2639
|
const props = {};
|
|
2562
|
-
for (const [name, raw] of Object.entries(
|
|
2640
|
+
for (const [name, raw] of Object.entries(isPlainObject5(node.props) ? node.props : {})) {
|
|
2563
2641
|
if (DENIED_PROPS2.has(name)) {
|
|
2564
2642
|
warnOnce2(`prop:${name}`, `[sdui] \uC2A4\uD399\uC5D0\uC11C \uD5C8\uC6A9\uB418\uC9C0 \uC54A\uB294 \uD504\uB86D: ${name} \u2014 \uBB34\uC2DC\uD569\uB2C8\uB2E4`);
|
|
2565
2643
|
continue;
|
|
@@ -2598,7 +2676,7 @@ function SduiNodeRenderer({
|
|
|
2598
2676
|
if (childLayout) {
|
|
2599
2677
|
for (const name of CHILD_LAYOUT_PROPS) delete props[name];
|
|
2600
2678
|
if (childLayout.style) {
|
|
2601
|
-
props.style =
|
|
2679
|
+
props.style = isPlainObject5(props.style) ? { ...childLayout.style, ...props.style } : childLayout.style;
|
|
2602
2680
|
}
|
|
2603
2681
|
if (childLayout.className) {
|
|
2604
2682
|
props.className = typeof props.className === "string" && props.className ? `${childLayout.className} ${props.className}` : childLayout.className;
|
|
@@ -2622,7 +2700,7 @@ var FRAGMENT_MAX_DEPTH = 4;
|
|
|
2622
2700
|
function SduiFragment({ node, scope, engine }) {
|
|
2623
2701
|
const adapter = useSduiAdapter();
|
|
2624
2702
|
const chain = React9.useContext(SduiFragmentChainContext);
|
|
2625
|
-
const raw =
|
|
2703
|
+
const raw = isPlainObject5(node.props) ? node.props.id : void 0;
|
|
2626
2704
|
const id = engine.resolveValue(raw, scope);
|
|
2627
2705
|
if (typeof id !== "string" || id === "") {
|
|
2628
2706
|
warnOnce2("fragment:id", "[sdui] <Fragment>\uC5D0 \uBB38\uC790\uC5F4 id\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 \uB80C\uB354\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4");
|
|
@@ -2642,8 +2720,8 @@ function SduiFragment({ node, scope, engine }) {
|
|
|
2642
2720
|
);
|
|
2643
2721
|
return null;
|
|
2644
2722
|
}
|
|
2645
|
-
const rawArgs =
|
|
2646
|
-
if (rawArgs !== void 0 && !
|
|
2723
|
+
const rawArgs = isPlainObject5(node.props) ? node.props.args : void 0;
|
|
2724
|
+
if (rawArgs !== void 0 && !isPlainObject5(rawArgs)) {
|
|
2647
2725
|
warnOnce2(`fragment:args:${id}`, `[sdui] <Fragment ${id}>\uC758 args\uB294 \uD3C9\uBA74 \uC624\uBE0C\uC81D\uD2B8\uC5EC\uC57C \uD569\uB2C8\uB2E4 \u2014 \uBB34\uC2DC\uD569\uB2C8\uB2E4`);
|
|
2648
2726
|
}
|
|
2649
2727
|
const useSpec = adapter?.useSpec;
|
|
@@ -2658,7 +2736,7 @@ function SduiFragment({ node, scope, engine }) {
|
|
|
2658
2736
|
SduiFragmentBody,
|
|
2659
2737
|
{
|
|
2660
2738
|
id,
|
|
2661
|
-
args:
|
|
2739
|
+
args: isPlainObject5(rawArgs) ? rawArgs : void 0,
|
|
2662
2740
|
useSpec,
|
|
2663
2741
|
chain,
|
|
2664
2742
|
scope,
|
|
@@ -2679,13 +2757,13 @@ function SduiFragmentBody({
|
|
|
2679
2757
|
const nextChain = React9.useMemo(() => [...chain, id], [chain, id]);
|
|
2680
2758
|
const bodyScope = React9.useMemo(() => [...scope, { args, callSiteScope: scope }], [scope, args]);
|
|
2681
2759
|
React9.useEffect(() => {
|
|
2682
|
-
if (!DEV || !
|
|
2760
|
+
if (!DEV || !isPlainObject5(spec) || !Array.isArray(spec.body)) return;
|
|
2683
2761
|
validateSpec(spec, new Set(Object.keys(engine.registry))).forEach(
|
|
2684
2762
|
(issue) => console.warn(`[sdui:spec:${id}] ${issue.path} \u2014 ${issue.message}`)
|
|
2685
2763
|
);
|
|
2686
2764
|
}, [spec, engine.registry, id]);
|
|
2687
2765
|
if (spec === void 0) return null;
|
|
2688
|
-
if (spec === null || !
|
|
2766
|
+
if (spec === null || !isPlainObject5(spec) || !Array.isArray(spec.body)) {
|
|
2689
2767
|
warnOnce2(`fragment:missing:${id}`, `[sdui] Fragment \uC2A4\uD399\uC744 \uD574\uC11D\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${id} \u2014 \uB80C\uB354\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`);
|
|
2690
2768
|
return null;
|
|
2691
2769
|
}
|
|
@@ -2815,7 +2893,7 @@ function SduiRenderer({
|
|
|
2815
2893
|
if (head in current) {
|
|
2816
2894
|
let value = current[head];
|
|
2817
2895
|
for (const segment of segments.slice(cut)) {
|
|
2818
|
-
if (!
|
|
2896
|
+
if (!isPlainObject5(value)) return void 0;
|
|
2819
2897
|
value = value[segment];
|
|
2820
2898
|
}
|
|
2821
2899
|
return value;
|
|
@@ -2833,7 +2911,7 @@ function SduiRenderer({
|
|
|
2833
2911
|
const frame = nearestItemFrame(scope);
|
|
2834
2912
|
if (!frame) return null;
|
|
2835
2913
|
if (value.$item === true) return frame.item;
|
|
2836
|
-
return
|
|
2914
|
+
return isPlainObject5(frame.item) ? frame.item[value.$item] ?? null : null;
|
|
2837
2915
|
}
|
|
2838
2916
|
if (isIndexRef(value)) {
|
|
2839
2917
|
return nearestItemFrame(scope)?.index ?? null;
|
|
@@ -2857,7 +2935,7 @@ function SduiRenderer({
|
|
|
2857
2935
|
return evaluateCalc(calc, resolved, (late) => resolveValue(late, scope));
|
|
2858
2936
|
}
|
|
2859
2937
|
if (Array.isArray(value)) return value.map((v) => resolveValue(v, scope));
|
|
2860
|
-
if (
|
|
2938
|
+
if (isPlainObject5(value)) {
|
|
2861
2939
|
const out = {};
|
|
2862
2940
|
for (const [k, v] of Object.entries(value)) {
|
|
2863
2941
|
out[k] = deferChainEntry(value, k) ? v : resolveValue(v, scope);
|
|
@@ -2965,9 +3043,27 @@ function SduiRenderer({
|
|
|
2965
3043
|
}
|
|
2966
3044
|
hostRef.current.navigate(action.to);
|
|
2967
3045
|
break;
|
|
2968
|
-
case "setState":
|
|
2969
|
-
|
|
3046
|
+
case "setState": {
|
|
3047
|
+
const nextValue = action.fromEvent ? eventValue(arg) : action.value;
|
|
3048
|
+
if (!Array.isArray(action.path) || action.path.length === 0) {
|
|
3049
|
+
setEntries({ [action.key]: nextValue });
|
|
3050
|
+
break;
|
|
3051
|
+
}
|
|
3052
|
+
const written = setAtPath(
|
|
3053
|
+
stateRef.current[action.key],
|
|
3054
|
+
action.path,
|
|
3055
|
+
nextValue
|
|
3056
|
+
);
|
|
3057
|
+
if (!written.ok) {
|
|
3058
|
+
warnOnce2(
|
|
3059
|
+
`setState:${action.key}:${written.reason}`,
|
|
3060
|
+
`[sdui] setState(${action.key}) \uACBD\uB85C \uC4F0\uAE30\uB97C \uAC74\uB108\uB701\uB2C8\uB2E4 \u2014 ${written.reason}`
|
|
3061
|
+
);
|
|
3062
|
+
break;
|
|
3063
|
+
}
|
|
3064
|
+
setEntries({ [action.key]: written.next });
|
|
2970
3065
|
break;
|
|
3066
|
+
}
|
|
2971
3067
|
case "open":
|
|
2972
3068
|
setEntries({ [action.key]: true });
|
|
2973
3069
|
break;
|
|
@@ -3026,7 +3122,7 @@ function SduiRenderer({
|
|
|
3026
3122
|
break;
|
|
3027
3123
|
}
|
|
3028
3124
|
const row = current[index];
|
|
3029
|
-
if (!
|
|
3125
|
+
if (!isPlainObject5(row)) break;
|
|
3030
3126
|
const nextValue = (action.fromEvent ? eventValue(arg) : action.value) ?? null;
|
|
3031
3127
|
const next = [...current];
|
|
3032
3128
|
next[index] = { ...row, [action.field]: nextValue };
|
package/dist/meta.d.ts
CHANGED
|
@@ -175,6 +175,22 @@ type SduiAction = {
|
|
|
175
175
|
} | {
|
|
176
176
|
action: 'setState';
|
|
177
177
|
key: string;
|
|
178
|
+
/**
|
|
179
|
+
* 상태 항목 **안쪽 자리**. 주면 항목 전체가 아니라 그 자리만 바꾼다.
|
|
180
|
+
*
|
|
181
|
+
* 조각은 객체 키(문자열)나 배열 인덱스(0 이상 정수)이고, 값 참조를 그대로 쓸 수
|
|
182
|
+
* 있다 — 액션 객체 전체가 디스패치 직전에 풀리기 때문이다:
|
|
183
|
+
*
|
|
184
|
+
* ```json
|
|
185
|
+
* { "action": "setState", "key": "gdRules", "fromEvent": true,
|
|
186
|
+
* "path": [{ "$index": true }, "limits", { "$item": true }, "count"] }
|
|
187
|
+
* ```
|
|
188
|
+
*
|
|
189
|
+
* 이것이 없으면 **동적 키**(등급 이름처럼 사용자가 런타임에 타이핑하는 키)와
|
|
190
|
+
* **중첩 쓰기**(`arrayUpdate`는 최상위 배열의 평탄 필드 하나만 바꾼다)를 스펙으로
|
|
191
|
+
* 말할 수 없었다. 규칙과 거절 조건은 `state-path.ts` 머리말에 있다.
|
|
192
|
+
*/
|
|
193
|
+
path?: SduiPropValue[];
|
|
178
194
|
value?: SduiPropValue;
|
|
179
195
|
/** true면 이벤트 값(input value, 선택된 탭 value, 페이지 번호 등)을 그대로 저장한다. */
|
|
180
196
|
fromEvent?: boolean;
|