@safe-ugc-ui/react 0.6.0 → 1.0.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 +43 -5
- package/dist/index.js +623 -41
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/UGCRenderer.tsx
|
|
2
|
-
import { useEffect, useMemo as useMemo2, useState as
|
|
2
|
+
import { useEffect as useEffect2, useMemo as useMemo2, useState as useState4 } from "react";
|
|
3
3
|
import { validate, validateRaw } from "@safe-ugc-ui/validator";
|
|
4
4
|
import { COMPACT_BREAKPOINT_MAX_WIDTH } from "@safe-ugc-ui/types";
|
|
5
5
|
|
|
@@ -29,7 +29,9 @@ import {
|
|
|
29
29
|
} from "@safe-ugc-ui/types";
|
|
30
30
|
|
|
31
31
|
// src/state-resolver.ts
|
|
32
|
-
import {
|
|
32
|
+
import {
|
|
33
|
+
PROTOTYPE_POLLUTION_SEGMENTS
|
|
34
|
+
} from "@safe-ugc-ui/types";
|
|
33
35
|
function parseRefSegments(path) {
|
|
34
36
|
const segments = [];
|
|
35
37
|
const dotParts = path.split(".");
|
|
@@ -89,6 +91,111 @@ function resolveValue(value, state, locals) {
|
|
|
89
91
|
}
|
|
90
92
|
return value;
|
|
91
93
|
}
|
|
94
|
+
function stringifyTextScalar(value) {
|
|
95
|
+
if (value === void 0) return "";
|
|
96
|
+
if (value === null) return "null";
|
|
97
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
98
|
+
return String(value);
|
|
99
|
+
}
|
|
100
|
+
return "";
|
|
101
|
+
}
|
|
102
|
+
function isTemplateObject(value) {
|
|
103
|
+
return typeof value === "object" && value !== null && "$template" in value && Array.isArray(value.$template);
|
|
104
|
+
}
|
|
105
|
+
function resolveTemplate(value, state, locals) {
|
|
106
|
+
if (!isTemplateObject(value)) {
|
|
107
|
+
return void 0;
|
|
108
|
+
}
|
|
109
|
+
return value.$template.map((part) => stringifyTextScalar(resolveValue(part, state, locals))).join("");
|
|
110
|
+
}
|
|
111
|
+
function resolveTextValue(value, state, locals) {
|
|
112
|
+
const template = resolveTemplate(value, state, locals);
|
|
113
|
+
if (template !== void 0) {
|
|
114
|
+
return template;
|
|
115
|
+
}
|
|
116
|
+
return stringifyTextScalar(resolveValue(value, state, locals));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// src/condition-resolver.ts
|
|
120
|
+
import { MAX_CONDITION_DEPTH, isRef } from "@safe-ugc-ui/types";
|
|
121
|
+
function resolveOperand(operand, state, locals) {
|
|
122
|
+
if (isRef(operand)) {
|
|
123
|
+
const resolved = resolveRef(operand.$ref, state, locals);
|
|
124
|
+
if (resolved === null || typeof resolved === "string" || typeof resolved === "number" || typeof resolved === "boolean") {
|
|
125
|
+
return resolved;
|
|
126
|
+
}
|
|
127
|
+
return void 0;
|
|
128
|
+
}
|
|
129
|
+
return operand;
|
|
130
|
+
}
|
|
131
|
+
function compareValues(op, left, right) {
|
|
132
|
+
if (left === void 0 || right === void 0) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
if (op === "eq") return left === right;
|
|
136
|
+
if (op === "ne") return left !== right;
|
|
137
|
+
if (left === null || right === null) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
if (typeof left !== typeof right) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
if (typeof left !== "number" && typeof left !== "string" || typeof right !== "number" && typeof right !== "string") {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
switch (op) {
|
|
147
|
+
case "gt":
|
|
148
|
+
return left > right;
|
|
149
|
+
case "gte":
|
|
150
|
+
return left >= right;
|
|
151
|
+
case "lt":
|
|
152
|
+
return left < right;
|
|
153
|
+
case "lte":
|
|
154
|
+
return left <= right;
|
|
155
|
+
default:
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function evaluateCondition(condition, state, locals, depth = 1) {
|
|
160
|
+
if (depth > MAX_CONDITION_DEPTH) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
if (typeof condition === "boolean") {
|
|
164
|
+
return condition;
|
|
165
|
+
}
|
|
166
|
+
if (isRef(condition)) {
|
|
167
|
+
return resolveRef(condition.$ref, state, locals) === true;
|
|
168
|
+
}
|
|
169
|
+
if (typeof condition !== "object" || condition === null || Array.isArray(condition)) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
const conditionObj = condition;
|
|
173
|
+
switch (conditionObj.op) {
|
|
174
|
+
case "not":
|
|
175
|
+
return !evaluateCondition(conditionObj.value, state, locals, depth + 1);
|
|
176
|
+
case "and":
|
|
177
|
+
return Array.isArray(conditionObj.values) && conditionObj.values.every(
|
|
178
|
+
(value) => evaluateCondition(value, state, locals, depth + 1)
|
|
179
|
+
);
|
|
180
|
+
case "or":
|
|
181
|
+
return Array.isArray(conditionObj.values) && conditionObj.values.some(
|
|
182
|
+
(value) => evaluateCondition(value, state, locals, depth + 1)
|
|
183
|
+
);
|
|
184
|
+
case "eq":
|
|
185
|
+
case "ne":
|
|
186
|
+
case "gt":
|
|
187
|
+
case "gte":
|
|
188
|
+
case "lt":
|
|
189
|
+
case "lte":
|
|
190
|
+
return compareValues(
|
|
191
|
+
conditionObj.op,
|
|
192
|
+
resolveOperand(conditionObj.left, state, locals),
|
|
193
|
+
resolveOperand(conditionObj.right, state, locals)
|
|
194
|
+
);
|
|
195
|
+
default:
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
92
199
|
|
|
93
200
|
// src/style-mapper.ts
|
|
94
201
|
import { ALLOWED_TRANSITION_PROPERTIES } from "@safe-ugc-ui/types";
|
|
@@ -103,6 +210,7 @@ var DIRECT_MAP_PROPS = [
|
|
|
103
210
|
"gap",
|
|
104
211
|
"width",
|
|
105
212
|
"height",
|
|
213
|
+
"aspectRatio",
|
|
106
214
|
"minWidth",
|
|
107
215
|
"maxWidth",
|
|
108
216
|
"minHeight",
|
|
@@ -159,6 +267,19 @@ function containsForbiddenCssFunction(value) {
|
|
|
159
267
|
const lower = value.toLowerCase();
|
|
160
268
|
return FORBIDDEN_CSS_FUNCTIONS_LOWER.some((fn) => lower.includes(fn));
|
|
161
269
|
}
|
|
270
|
+
function isValidAspectRatio(value) {
|
|
271
|
+
if (typeof value === "number") {
|
|
272
|
+
return Number.isFinite(value) && value > 0;
|
|
273
|
+
}
|
|
274
|
+
if (typeof value !== "string" || containsForbiddenCssFunction(value)) {
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
const match = value.match(/^\s*([0-9]+(?:\.[0-9]+)?)\s*\/\s*([0-9]+(?:\.[0-9]+)?)\s*$/);
|
|
278
|
+
if (!match) {
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
return Number(match[1]) > 0 && Number(match[2]) > 0;
|
|
282
|
+
}
|
|
162
283
|
function resolveStyleValue(value, state, locals) {
|
|
163
284
|
return resolveValue(value, state, locals);
|
|
164
285
|
}
|
|
@@ -369,6 +490,9 @@ function mapStyle(style, state, locals) {
|
|
|
369
490
|
if (typeof resolved === "string" && containsForbiddenCssFunction(resolved)) {
|
|
370
491
|
continue;
|
|
371
492
|
}
|
|
493
|
+
if (prop === "aspectRatio" && !isValidAspectRatio(resolved)) {
|
|
494
|
+
continue;
|
|
495
|
+
}
|
|
372
496
|
css[prop] = resolved;
|
|
373
497
|
}
|
|
374
498
|
}
|
|
@@ -520,9 +644,40 @@ function Column({ style, hoverStyle, children }) {
|
|
|
520
644
|
|
|
521
645
|
// src/components/Text.tsx
|
|
522
646
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
523
|
-
function
|
|
647
|
+
function getClampStyle(maxLines, truncate) {
|
|
648
|
+
if (!maxLines || maxLines < 1) {
|
|
649
|
+
return void 0;
|
|
650
|
+
}
|
|
651
|
+
if (maxLines === 1) {
|
|
652
|
+
return {
|
|
653
|
+
display: "inline-block",
|
|
654
|
+
maxWidth: "100%",
|
|
655
|
+
overflow: "hidden",
|
|
656
|
+
whiteSpace: "nowrap",
|
|
657
|
+
textOverflow: truncate ?? "ellipsis"
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
return {
|
|
661
|
+
display: "-webkit-box",
|
|
662
|
+
maxWidth: "100%",
|
|
663
|
+
overflow: "hidden",
|
|
664
|
+
textOverflow: truncate ?? "ellipsis",
|
|
665
|
+
WebkitBoxOrient: "vertical",
|
|
666
|
+
WebkitLineClamp: maxLines
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
function Text({
|
|
670
|
+
content,
|
|
671
|
+
spans,
|
|
672
|
+
maxLines,
|
|
673
|
+
truncate,
|
|
674
|
+
style,
|
|
675
|
+
hoverStyle
|
|
676
|
+
}) {
|
|
524
677
|
const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);
|
|
525
|
-
|
|
678
|
+
const clampStyle = getClampStyle(maxLines, truncate);
|
|
679
|
+
const mergedStyle = clampStyle ? { ...resolvedStyle, ...clampStyle } : resolvedStyle;
|
|
680
|
+
return /* @__PURE__ */ jsx5("span", { style: mergedStyle, onMouseEnter, onMouseLeave, children: spans?.map((span, index) => /* @__PURE__ */ jsx5("span", { style: span.style, children: span.text }, index)) ?? content ?? "" });
|
|
526
681
|
}
|
|
527
682
|
|
|
528
683
|
// src/components/Image.tsx
|
|
@@ -755,13 +910,279 @@ function Toggle({ value, onToggle, onAction, disabled, style, hoverStyle }) {
|
|
|
755
910
|
);
|
|
756
911
|
}
|
|
757
912
|
|
|
913
|
+
// src/components/Accordion.tsx
|
|
914
|
+
import { useId, useState as useState2 } from "react";
|
|
915
|
+
import { jsx as jsx18, jsxs } from "react/jsx-runtime";
|
|
916
|
+
function getInitialExpandedIds(items, defaultExpanded, allowMultiple) {
|
|
917
|
+
const enabledIds = new Set(
|
|
918
|
+
items.filter((item) => item.disabled !== true).map((item) => item.id)
|
|
919
|
+
);
|
|
920
|
+
const initial = (defaultExpanded ?? []).filter((id) => enabledIds.has(id));
|
|
921
|
+
return allowMultiple ? initial : initial.slice(0, 1);
|
|
922
|
+
}
|
|
923
|
+
function Accordion({
|
|
924
|
+
items,
|
|
925
|
+
allowMultiple = false,
|
|
926
|
+
defaultExpanded,
|
|
927
|
+
style,
|
|
928
|
+
hoverStyle
|
|
929
|
+
}) {
|
|
930
|
+
const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);
|
|
931
|
+
const [expandedIds, setExpandedIds] = useState2(
|
|
932
|
+
() => getInitialExpandedIds(items, defaultExpanded, allowMultiple)
|
|
933
|
+
);
|
|
934
|
+
const baseId = useId();
|
|
935
|
+
const expandedSet = new Set(expandedIds);
|
|
936
|
+
const toggleItem = (itemId, disabled) => {
|
|
937
|
+
if (disabled) {
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
setExpandedIds((current) => {
|
|
941
|
+
const currentSet = new Set(current);
|
|
942
|
+
if (allowMultiple) {
|
|
943
|
+
if (currentSet.has(itemId)) {
|
|
944
|
+
currentSet.delete(itemId);
|
|
945
|
+
} else {
|
|
946
|
+
currentSet.add(itemId);
|
|
947
|
+
}
|
|
948
|
+
return [...currentSet];
|
|
949
|
+
}
|
|
950
|
+
return currentSet.has(itemId) ? [] : [itemId];
|
|
951
|
+
});
|
|
952
|
+
};
|
|
953
|
+
return /* @__PURE__ */ jsx18("div", { style: resolvedStyle, onMouseEnter, onMouseLeave, children: items.map((item) => {
|
|
954
|
+
const expanded = expandedSet.has(item.id);
|
|
955
|
+
const buttonId = `${baseId}-${item.id}-button`;
|
|
956
|
+
const panelId = `${baseId}-${item.id}-panel`;
|
|
957
|
+
return /* @__PURE__ */ jsxs(
|
|
958
|
+
"div",
|
|
959
|
+
{
|
|
960
|
+
style: {
|
|
961
|
+
borderTop: "1px solid rgba(148, 163, 184, 0.25)"
|
|
962
|
+
},
|
|
963
|
+
children: [
|
|
964
|
+
/* @__PURE__ */ jsxs(
|
|
965
|
+
"button",
|
|
966
|
+
{
|
|
967
|
+
id: buttonId,
|
|
968
|
+
type: "button",
|
|
969
|
+
"aria-expanded": expanded,
|
|
970
|
+
"aria-controls": panelId,
|
|
971
|
+
disabled: item.disabled,
|
|
972
|
+
onClick: () => toggleItem(item.id, item.disabled),
|
|
973
|
+
style: {
|
|
974
|
+
width: "100%",
|
|
975
|
+
display: "flex",
|
|
976
|
+
alignItems: "center",
|
|
977
|
+
justifyContent: "space-between",
|
|
978
|
+
padding: "12px 0",
|
|
979
|
+
background: "transparent",
|
|
980
|
+
border: "none",
|
|
981
|
+
color: "inherit",
|
|
982
|
+
textAlign: "left",
|
|
983
|
+
cursor: item.disabled ? "default" : "pointer",
|
|
984
|
+
opacity: item.disabled ? 0.5 : 1
|
|
985
|
+
},
|
|
986
|
+
children: [
|
|
987
|
+
/* @__PURE__ */ jsx18("span", { children: item.label }),
|
|
988
|
+
/* @__PURE__ */ jsx18("span", { "aria-hidden": "true", children: expanded ? "-" : "+" })
|
|
989
|
+
]
|
|
990
|
+
}
|
|
991
|
+
),
|
|
992
|
+
expanded ? /* @__PURE__ */ jsx18(
|
|
993
|
+
"div",
|
|
994
|
+
{
|
|
995
|
+
id: panelId,
|
|
996
|
+
role: "region",
|
|
997
|
+
"aria-labelledby": buttonId,
|
|
998
|
+
style: { paddingBottom: 12 },
|
|
999
|
+
children: item.content
|
|
1000
|
+
}
|
|
1001
|
+
) : null
|
|
1002
|
+
]
|
|
1003
|
+
},
|
|
1004
|
+
item.id
|
|
1005
|
+
);
|
|
1006
|
+
}) });
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
// src/components/Tabs.tsx
|
|
1010
|
+
import {
|
|
1011
|
+
useEffect,
|
|
1012
|
+
useId as useId2,
|
|
1013
|
+
useRef,
|
|
1014
|
+
useState as useState3
|
|
1015
|
+
} from "react";
|
|
1016
|
+
import { jsx as jsx19, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1017
|
+
function getEnabledTabIds(tabs) {
|
|
1018
|
+
return tabs.filter((tab) => tab.disabled !== true).map((tab) => tab.id);
|
|
1019
|
+
}
|
|
1020
|
+
function getInitialSelectedTab(tabs, defaultTab) {
|
|
1021
|
+
const enabledIds = getEnabledTabIds(tabs);
|
|
1022
|
+
if (enabledIds.length === 0) {
|
|
1023
|
+
return void 0;
|
|
1024
|
+
}
|
|
1025
|
+
if (defaultTab && enabledIds.includes(defaultTab)) {
|
|
1026
|
+
return defaultTab;
|
|
1027
|
+
}
|
|
1028
|
+
return enabledIds[0];
|
|
1029
|
+
}
|
|
1030
|
+
function getNextEnabledIndex(tabs, startIndex, direction) {
|
|
1031
|
+
for (let offset = 1; offset <= tabs.length; offset++) {
|
|
1032
|
+
const nextIndex = (startIndex + direction * offset + tabs.length) % tabs.length;
|
|
1033
|
+
if (tabs[nextIndex]?.disabled !== true) {
|
|
1034
|
+
return nextIndex;
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
return startIndex;
|
|
1038
|
+
}
|
|
1039
|
+
function focusTab(buttonRefs, index) {
|
|
1040
|
+
buttonRefs.current[index]?.focus();
|
|
1041
|
+
}
|
|
1042
|
+
function Tabs({
|
|
1043
|
+
tabs,
|
|
1044
|
+
defaultTab,
|
|
1045
|
+
style,
|
|
1046
|
+
hoverStyle
|
|
1047
|
+
}) {
|
|
1048
|
+
const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);
|
|
1049
|
+
const [selectedTab, setSelectedTab] = useState3(
|
|
1050
|
+
() => getInitialSelectedTab(tabs, defaultTab)
|
|
1051
|
+
);
|
|
1052
|
+
const baseId = useId2();
|
|
1053
|
+
const buttonRefs = useRef([]);
|
|
1054
|
+
useEffect(() => {
|
|
1055
|
+
setSelectedTab((current) => {
|
|
1056
|
+
const enabledIds = getEnabledTabIds(tabs);
|
|
1057
|
+
if (enabledIds.length === 0) {
|
|
1058
|
+
return void 0;
|
|
1059
|
+
}
|
|
1060
|
+
if (current && enabledIds.includes(current)) {
|
|
1061
|
+
return current;
|
|
1062
|
+
}
|
|
1063
|
+
if (defaultTab && enabledIds.includes(defaultTab)) {
|
|
1064
|
+
return defaultTab;
|
|
1065
|
+
}
|
|
1066
|
+
return enabledIds[0];
|
|
1067
|
+
});
|
|
1068
|
+
}, [tabs, defaultTab]);
|
|
1069
|
+
const selectedItem = tabs.find((tab) => tab.id === selectedTab && tab.disabled !== true) ?? tabs.find((tab) => tab.disabled !== true);
|
|
1070
|
+
const activateTab = (index, focus = false) => {
|
|
1071
|
+
const tab = tabs[index];
|
|
1072
|
+
if (!tab || tab.disabled) {
|
|
1073
|
+
return;
|
|
1074
|
+
}
|
|
1075
|
+
setSelectedTab(tab.id);
|
|
1076
|
+
if (focus) {
|
|
1077
|
+
focusTab(buttonRefs, index);
|
|
1078
|
+
}
|
|
1079
|
+
};
|
|
1080
|
+
const onTabKeyDown = (event, index) => {
|
|
1081
|
+
switch (event.key) {
|
|
1082
|
+
case "ArrowRight":
|
|
1083
|
+
case "ArrowDown": {
|
|
1084
|
+
event.preventDefault();
|
|
1085
|
+
activateTab(getNextEnabledIndex(tabs, index, 1), true);
|
|
1086
|
+
break;
|
|
1087
|
+
}
|
|
1088
|
+
case "ArrowLeft":
|
|
1089
|
+
case "ArrowUp": {
|
|
1090
|
+
event.preventDefault();
|
|
1091
|
+
activateTab(getNextEnabledIndex(tabs, index, -1), true);
|
|
1092
|
+
break;
|
|
1093
|
+
}
|
|
1094
|
+
case "Home": {
|
|
1095
|
+
event.preventDefault();
|
|
1096
|
+
const firstEnabledIndex = tabs.findIndex((tab) => tab.disabled !== true);
|
|
1097
|
+
if (firstEnabledIndex >= 0) {
|
|
1098
|
+
activateTab(firstEnabledIndex, true);
|
|
1099
|
+
}
|
|
1100
|
+
break;
|
|
1101
|
+
}
|
|
1102
|
+
case "End": {
|
|
1103
|
+
event.preventDefault();
|
|
1104
|
+
const lastEnabledIndex = [...tabs].map((tab, currentIndex) => ({ tab, currentIndex })).reverse().find(({ tab }) => tab.disabled !== true);
|
|
1105
|
+
if (lastEnabledIndex) {
|
|
1106
|
+
activateTab(lastEnabledIndex.currentIndex, true);
|
|
1107
|
+
}
|
|
1108
|
+
break;
|
|
1109
|
+
}
|
|
1110
|
+
default:
|
|
1111
|
+
break;
|
|
1112
|
+
}
|
|
1113
|
+
};
|
|
1114
|
+
return /* @__PURE__ */ jsxs2("div", { style: resolvedStyle, onMouseEnter, onMouseLeave, children: [
|
|
1115
|
+
/* @__PURE__ */ jsx19(
|
|
1116
|
+
"div",
|
|
1117
|
+
{
|
|
1118
|
+
role: "tablist",
|
|
1119
|
+
"aria-orientation": "horizontal",
|
|
1120
|
+
style: {
|
|
1121
|
+
display: "flex",
|
|
1122
|
+
gap: 8,
|
|
1123
|
+
borderBottom: "1px solid rgba(148, 163, 184, 0.25)",
|
|
1124
|
+
paddingBottom: 8
|
|
1125
|
+
},
|
|
1126
|
+
children: tabs.map((tab, index) => {
|
|
1127
|
+
const selected = selectedItem?.id === tab.id;
|
|
1128
|
+
const tabId = `${baseId}-${tab.id}-tab`;
|
|
1129
|
+
const panelId = `${baseId}-${tab.id}-panel`;
|
|
1130
|
+
return /* @__PURE__ */ jsx19(
|
|
1131
|
+
"button",
|
|
1132
|
+
{
|
|
1133
|
+
ref: (element) => {
|
|
1134
|
+
buttonRefs.current[index] = element;
|
|
1135
|
+
},
|
|
1136
|
+
id: tabId,
|
|
1137
|
+
type: "button",
|
|
1138
|
+
role: "tab",
|
|
1139
|
+
"aria-selected": selected,
|
|
1140
|
+
"aria-controls": panelId,
|
|
1141
|
+
disabled: tab.disabled,
|
|
1142
|
+
tabIndex: selected ? 0 : -1,
|
|
1143
|
+
onClick: () => activateTab(index),
|
|
1144
|
+
onKeyDown: (event) => onTabKeyDown(event, index),
|
|
1145
|
+
style: {
|
|
1146
|
+
padding: "8px 12px",
|
|
1147
|
+
borderRadius: 8,
|
|
1148
|
+
border: "none",
|
|
1149
|
+
background: selected ? "rgba(148, 163, 184, 0.16)" : "transparent",
|
|
1150
|
+
color: "inherit",
|
|
1151
|
+
cursor: tab.disabled ? "default" : "pointer",
|
|
1152
|
+
opacity: tab.disabled ? 0.5 : 1,
|
|
1153
|
+
fontWeight: selected ? 600 : 400
|
|
1154
|
+
},
|
|
1155
|
+
children: tab.label
|
|
1156
|
+
},
|
|
1157
|
+
tab.id
|
|
1158
|
+
);
|
|
1159
|
+
})
|
|
1160
|
+
}
|
|
1161
|
+
),
|
|
1162
|
+
selectedItem ? /* @__PURE__ */ jsx19(
|
|
1163
|
+
"div",
|
|
1164
|
+
{
|
|
1165
|
+
id: `${baseId}-${selectedItem.id}-panel`,
|
|
1166
|
+
role: "tabpanel",
|
|
1167
|
+
"aria-labelledby": `${baseId}-${selectedItem.id}-tab`,
|
|
1168
|
+
style: { paddingTop: 12 },
|
|
1169
|
+
children: selectedItem.content
|
|
1170
|
+
}
|
|
1171
|
+
) : null
|
|
1172
|
+
] });
|
|
1173
|
+
}
|
|
1174
|
+
|
|
758
1175
|
// src/node-renderer.tsx
|
|
759
|
-
import { jsx as
|
|
1176
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
760
1177
|
function isForLoop(obj) {
|
|
761
1178
|
if (obj == null || typeof obj !== "object" || Array.isArray(obj)) return false;
|
|
762
1179
|
const o = obj;
|
|
763
1180
|
return typeof o.for === "string" && typeof o.in === "string" && o.template != null;
|
|
764
1181
|
}
|
|
1182
|
+
function isFragmentUse(obj) {
|
|
1183
|
+
if (obj == null || typeof obj !== "object" || Array.isArray(obj)) return false;
|
|
1184
|
+
return typeof obj.$use === "string";
|
|
1185
|
+
}
|
|
765
1186
|
function utf8ByteLength(str) {
|
|
766
1187
|
let bytes = 0;
|
|
767
1188
|
for (let i = 0; i < str.length; i++) {
|
|
@@ -844,20 +1265,125 @@ function mergeEffectiveNodeStyle(node, ctx) {
|
|
|
844
1265
|
...compactStyleWithoutInteractiveFields
|
|
845
1266
|
};
|
|
846
1267
|
}
|
|
1268
|
+
function resolveTextPayload(node, ctx) {
|
|
1269
|
+
const rawSpans = Array.isArray(node.spans) ? node.spans : void 0;
|
|
1270
|
+
if (rawSpans) {
|
|
1271
|
+
const spans = rawSpans.map((span) => {
|
|
1272
|
+
const rawSpan = span;
|
|
1273
|
+
const spanStyle = rawSpan.style != null && typeof rawSpan.style === "object" && !Array.isArray(rawSpan.style) ? rawSpan.style : void 0;
|
|
1274
|
+
return {
|
|
1275
|
+
text: resolveTextValue(rawSpan.text, ctx.state, ctx.locals),
|
|
1276
|
+
style: spanStyle ? mapStyle(spanStyle, ctx.state, ctx.locals) : void 0,
|
|
1277
|
+
rawStyleBytes: spanStyle ? utf8ByteLength(JSON.stringify(spanStyle)) : 0
|
|
1278
|
+
};
|
|
1279
|
+
});
|
|
1280
|
+
const combinedText = spans.map((span) => span.text).join("");
|
|
1281
|
+
return {
|
|
1282
|
+
spans: spans.map(({ rawStyleBytes: _rawStyleBytes, ...span }) => span),
|
|
1283
|
+
textBytes: utf8ByteLength(combinedText),
|
|
1284
|
+
styleBytes: spans.reduce((sum, span) => sum + span.rawStyleBytes, 0)
|
|
1285
|
+
};
|
|
1286
|
+
}
|
|
1287
|
+
const content = resolveTextValue(node.content, ctx.state, ctx.locals);
|
|
1288
|
+
return {
|
|
1289
|
+
content,
|
|
1290
|
+
textBytes: utf8ByteLength(content),
|
|
1291
|
+
styleBytes: 0
|
|
1292
|
+
};
|
|
1293
|
+
}
|
|
1294
|
+
function resolveAccordionItems(node, ctx, key) {
|
|
1295
|
+
const rawItems = Array.isArray(node.items) ? node.items : [];
|
|
1296
|
+
return rawItems.flatMap((item, index) => {
|
|
1297
|
+
if (item == null || typeof item !== "object" || Array.isArray(item)) {
|
|
1298
|
+
return [];
|
|
1299
|
+
}
|
|
1300
|
+
const rawItem = item;
|
|
1301
|
+
const id = typeof rawItem.id === "string" ? rawItem.id : `item-${index}`;
|
|
1302
|
+
const label = resolveTextValue(rawItem.label, ctx.state, ctx.locals);
|
|
1303
|
+
const resolvedDisabled = resolveValue(rawItem.disabled, ctx.state, ctx.locals);
|
|
1304
|
+
const disabled = typeof resolvedDisabled === "boolean" ? resolvedDisabled : void 0;
|
|
1305
|
+
const content = renderNode(
|
|
1306
|
+
rawItem.content,
|
|
1307
|
+
ctx,
|
|
1308
|
+
`${String(key)}.items[${index}].content`
|
|
1309
|
+
);
|
|
1310
|
+
return [{ id, label, content, disabled }];
|
|
1311
|
+
});
|
|
1312
|
+
}
|
|
1313
|
+
function resolveTabsItems(node, ctx, key) {
|
|
1314
|
+
const rawTabs = Array.isArray(node.tabs) ? node.tabs : [];
|
|
1315
|
+
return rawTabs.flatMap((tab, index) => {
|
|
1316
|
+
if (tab == null || typeof tab !== "object" || Array.isArray(tab)) {
|
|
1317
|
+
return [];
|
|
1318
|
+
}
|
|
1319
|
+
const rawTab = tab;
|
|
1320
|
+
const id = typeof rawTab.id === "string" ? rawTab.id : `tab-${index}`;
|
|
1321
|
+
const label = resolveTextValue(rawTab.label, ctx.state, ctx.locals);
|
|
1322
|
+
const resolvedDisabled = resolveValue(rawTab.disabled, ctx.state, ctx.locals);
|
|
1323
|
+
const disabled = typeof resolvedDisabled === "boolean" ? resolvedDisabled : void 0;
|
|
1324
|
+
const content = renderNode(
|
|
1325
|
+
rawTab.content,
|
|
1326
|
+
ctx,
|
|
1327
|
+
`${String(key)}.tabs[${index}].content`
|
|
1328
|
+
);
|
|
1329
|
+
return [{ id, label, content, disabled }];
|
|
1330
|
+
});
|
|
1331
|
+
}
|
|
847
1332
|
function renderNode(node, ctx, key) {
|
|
848
1333
|
if (node == null || typeof node !== "object") return null;
|
|
1334
|
+
if (isFragmentUse(node)) {
|
|
1335
|
+
if ("$if" in node && !evaluateCondition(node.$if, ctx.state, ctx.locals)) {
|
|
1336
|
+
return null;
|
|
1337
|
+
}
|
|
1338
|
+
if ((ctx.fragmentStack?.length ?? 0) > 0) {
|
|
1339
|
+
ctx.onError?.([{
|
|
1340
|
+
code: "RUNTIME_FRAGMENT_NESTED_USE",
|
|
1341
|
+
message: 'Fragments may not contain nested "$use" references',
|
|
1342
|
+
path: String(key)
|
|
1343
|
+
}]);
|
|
1344
|
+
return null;
|
|
1345
|
+
}
|
|
1346
|
+
if (ctx.fragmentStack?.includes(node.$use)) {
|
|
1347
|
+
ctx.onError?.([{
|
|
1348
|
+
code: "RUNTIME_FRAGMENT_CYCLE",
|
|
1349
|
+
message: `Fragment "${node.$use}" recursively references itself`,
|
|
1350
|
+
path: String(key)
|
|
1351
|
+
}]);
|
|
1352
|
+
return null;
|
|
1353
|
+
}
|
|
1354
|
+
const fragment = ctx.fragments?.[node.$use];
|
|
1355
|
+
if (fragment == null) {
|
|
1356
|
+
ctx.onError?.([{
|
|
1357
|
+
code: "RUNTIME_FRAGMENT_NOT_FOUND",
|
|
1358
|
+
message: `Fragment "${node.$use}" was not found`,
|
|
1359
|
+
path: String(key)
|
|
1360
|
+
}]);
|
|
1361
|
+
return null;
|
|
1362
|
+
}
|
|
1363
|
+
return renderNode(
|
|
1364
|
+
fragment,
|
|
1365
|
+
{
|
|
1366
|
+
...ctx,
|
|
1367
|
+
fragmentStack: [...ctx.fragmentStack ?? [], node.$use]
|
|
1368
|
+
},
|
|
1369
|
+
key
|
|
1370
|
+
);
|
|
1371
|
+
}
|
|
849
1372
|
const n = node;
|
|
850
1373
|
if (!n.type) return null;
|
|
1374
|
+
if ("$if" in n && !evaluateCondition(n.$if, ctx.state, ctx.locals)) {
|
|
1375
|
+
return null;
|
|
1376
|
+
}
|
|
851
1377
|
const mergedRawStyle = mergeEffectiveNodeStyle(n, ctx);
|
|
852
1378
|
const rv = (val) => resolveValue(val, ctx.state, ctx.locals);
|
|
853
|
-
|
|
1379
|
+
let styleDelta = mergedRawStyle ? utf8ByteLength(JSON.stringify(mergedRawStyle)) : 0;
|
|
854
1380
|
const overflowDelta = mergedRawStyle?.overflow === "auto" ? 1 : 0;
|
|
855
|
-
let
|
|
1381
|
+
let resolvedTextPayload;
|
|
856
1382
|
let textDelta = 0;
|
|
857
1383
|
if (n.type === "Text") {
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
1384
|
+
resolvedTextPayload = resolveTextPayload(n, ctx);
|
|
1385
|
+
textDelta = resolvedTextPayload.textBytes;
|
|
1386
|
+
styleDelta += resolvedTextPayload.styleBytes;
|
|
861
1387
|
}
|
|
862
1388
|
if (ctx.limits.nodeCount + 1 > MAX_NODE_COUNT) {
|
|
863
1389
|
ctx.onError?.([{ code: "RUNTIME_NODE_LIMIT", message: `Node count exceeds maximum of ${MAX_NODE_COUNT}`, path: String(key) }]);
|
|
@@ -885,17 +1411,31 @@ function renderNode(node, ctx, key) {
|
|
|
885
1411
|
const childElements = renderChildren(n.children, ctx);
|
|
886
1412
|
switch (n.type) {
|
|
887
1413
|
case "Box":
|
|
888
|
-
return /* @__PURE__ */
|
|
1414
|
+
return /* @__PURE__ */ jsx20(Box, { style: cssStyle, hoverStyle: cssHoverStyle, children: childElements }, key);
|
|
889
1415
|
case "Row":
|
|
890
|
-
return /* @__PURE__ */
|
|
1416
|
+
return /* @__PURE__ */ jsx20(Row, { style: cssStyle, hoverStyle: cssHoverStyle, children: childElements }, key);
|
|
891
1417
|
case "Column":
|
|
892
|
-
return /* @__PURE__ */
|
|
1418
|
+
return /* @__PURE__ */ jsx20(Column, { style: cssStyle, hoverStyle: cssHoverStyle, children: childElements }, key);
|
|
893
1419
|
case "Stack":
|
|
894
|
-
return /* @__PURE__ */
|
|
1420
|
+
return /* @__PURE__ */ jsx20(Stack, { style: cssStyle, hoverStyle: cssHoverStyle, children: childElements }, key);
|
|
895
1421
|
case "Grid":
|
|
896
|
-
return /* @__PURE__ */
|
|
897
|
-
case "Text":
|
|
898
|
-
|
|
1422
|
+
return /* @__PURE__ */ jsx20(Grid, { style: cssStyle, hoverStyle: cssHoverStyle, children: childElements }, key);
|
|
1423
|
+
case "Text": {
|
|
1424
|
+
const maxLines = typeof n.maxLines === "number" ? n.maxLines : void 0;
|
|
1425
|
+
const truncate = n.truncate === "clip" || n.truncate === "ellipsis" ? n.truncate : void 0;
|
|
1426
|
+
return /* @__PURE__ */ jsx20(
|
|
1427
|
+
Text,
|
|
1428
|
+
{
|
|
1429
|
+
content: resolvedTextPayload?.content,
|
|
1430
|
+
spans: resolvedTextPayload?.spans,
|
|
1431
|
+
maxLines,
|
|
1432
|
+
truncate,
|
|
1433
|
+
style: cssStyle,
|
|
1434
|
+
hoverStyle: cssHoverStyle
|
|
1435
|
+
},
|
|
1436
|
+
key
|
|
1437
|
+
);
|
|
1438
|
+
}
|
|
899
1439
|
case "Image": {
|
|
900
1440
|
let src = rv(n.src);
|
|
901
1441
|
if (typeof src !== "string" || !src) return null;
|
|
@@ -906,7 +1446,7 @@ function renderNode(node, ctx, key) {
|
|
|
906
1446
|
if (typeof resolved === "string" && resolved.trim().toLowerCase().startsWith("javascript:")) return null;
|
|
907
1447
|
const resolvedAlt = rv(n.alt);
|
|
908
1448
|
const alt = typeof resolvedAlt === "string" ? resolvedAlt : void 0;
|
|
909
|
-
return /* @__PURE__ */
|
|
1449
|
+
return /* @__PURE__ */ jsx20(Image, { src: resolved, alt, style: cssStyle, hoverStyle: cssHoverStyle }, key);
|
|
910
1450
|
}
|
|
911
1451
|
case "Avatar": {
|
|
912
1452
|
let src = rv(n.src);
|
|
@@ -918,7 +1458,7 @@ function renderNode(node, ctx, key) {
|
|
|
918
1458
|
if (typeof resolved === "string" && resolved.trim().toLowerCase().startsWith("javascript:")) return null;
|
|
919
1459
|
const resolvedSize = rv(n.size);
|
|
920
1460
|
const size = typeof resolvedSize === "number" || typeof resolvedSize === "string" ? resolvedSize : void 0;
|
|
921
|
-
return /* @__PURE__ */
|
|
1461
|
+
return /* @__PURE__ */ jsx20(Avatar, { src: resolved, size, style: cssStyle, hoverStyle: cssHoverStyle }, key);
|
|
922
1462
|
}
|
|
923
1463
|
case "Icon": {
|
|
924
1464
|
const resolvedName = rv(n.name);
|
|
@@ -927,7 +1467,7 @@ function renderNode(node, ctx, key) {
|
|
|
927
1467
|
const size = typeof resolvedSize === "number" || typeof resolvedSize === "string" ? resolvedSize : void 0;
|
|
928
1468
|
const resolvedColor = rv(n.color);
|
|
929
1469
|
const color = typeof resolvedColor === "string" ? resolvedColor : void 0;
|
|
930
|
-
return /* @__PURE__ */
|
|
1470
|
+
return /* @__PURE__ */ jsx20(
|
|
931
1471
|
Icon,
|
|
932
1472
|
{
|
|
933
1473
|
name,
|
|
@@ -943,14 +1483,14 @@ function renderNode(node, ctx, key) {
|
|
|
943
1483
|
case "Spacer": {
|
|
944
1484
|
const resolvedSize = rv(n.size);
|
|
945
1485
|
const size = typeof resolvedSize === "number" || typeof resolvedSize === "string" ? resolvedSize : void 0;
|
|
946
|
-
return /* @__PURE__ */
|
|
1486
|
+
return /* @__PURE__ */ jsx20(Spacer, { size, style: cssStyle, hoverStyle: cssHoverStyle }, key);
|
|
947
1487
|
}
|
|
948
1488
|
case "Divider": {
|
|
949
1489
|
const resolvedColor = rv(n.color);
|
|
950
1490
|
const color = typeof resolvedColor === "string" ? resolvedColor : void 0;
|
|
951
1491
|
const resolvedThickness = rv(n.thickness);
|
|
952
1492
|
const thickness = typeof resolvedThickness === "number" || typeof resolvedThickness === "string" ? resolvedThickness : void 0;
|
|
953
|
-
return /* @__PURE__ */
|
|
1493
|
+
return /* @__PURE__ */ jsx20(Divider, { color, thickness, style: cssStyle, hoverStyle: cssHoverStyle }, key);
|
|
954
1494
|
}
|
|
955
1495
|
case "ProgressBar": {
|
|
956
1496
|
const resolvedValue = rv(n.value);
|
|
@@ -959,33 +1499,33 @@ function renderNode(node, ctx, key) {
|
|
|
959
1499
|
const max = typeof resolvedMax === "number" ? resolvedMax : 100;
|
|
960
1500
|
const resolvedColor = rv(n.color);
|
|
961
1501
|
const color = typeof resolvedColor === "string" ? resolvedColor : void 0;
|
|
962
|
-
return /* @__PURE__ */
|
|
1502
|
+
return /* @__PURE__ */ jsx20(ProgressBar, { value, max, color, style: cssStyle, hoverStyle: cssHoverStyle }, key);
|
|
963
1503
|
}
|
|
964
1504
|
case "Badge": {
|
|
965
|
-
const
|
|
966
|
-
const label = typeof resolvedLabel === "string" ? resolvedLabel : "";
|
|
1505
|
+
const label = resolveTextValue(n.label, ctx.state, ctx.locals);
|
|
967
1506
|
const resolvedColor = rv(n.color);
|
|
968
1507
|
const color = typeof resolvedColor === "string" ? resolvedColor : void 0;
|
|
969
|
-
return /* @__PURE__ */
|
|
1508
|
+
return /* @__PURE__ */ jsx20(Badge, { label, color, style: cssStyle, hoverStyle: cssHoverStyle }, key);
|
|
970
1509
|
}
|
|
971
1510
|
case "Chip": {
|
|
972
|
-
const
|
|
973
|
-
const label = typeof resolvedLabel === "string" ? resolvedLabel : "";
|
|
1511
|
+
const label = resolveTextValue(n.label, ctx.state, ctx.locals);
|
|
974
1512
|
const resolvedColor = rv(n.color);
|
|
975
1513
|
const color = typeof resolvedColor === "string" ? resolvedColor : void 0;
|
|
976
|
-
return /* @__PURE__ */
|
|
1514
|
+
return /* @__PURE__ */ jsx20(Chip, { label, color, style: cssStyle, hoverStyle: cssHoverStyle }, key);
|
|
977
1515
|
}
|
|
978
1516
|
case "Button": {
|
|
979
|
-
const
|
|
980
|
-
const label = typeof resolvedLabel === "string" ? resolvedLabel : "";
|
|
1517
|
+
const label = resolveTextValue(n.label, ctx.state, ctx.locals);
|
|
981
1518
|
const actionVal = n.action;
|
|
982
1519
|
const action = typeof actionVal === "string" ? actionVal : "";
|
|
983
|
-
|
|
1520
|
+
const resolvedDisabled = rv(n.disabled);
|
|
1521
|
+
const disabled = typeof resolvedDisabled === "boolean" ? resolvedDisabled : void 0;
|
|
1522
|
+
return /* @__PURE__ */ jsx20(
|
|
984
1523
|
Button,
|
|
985
1524
|
{
|
|
986
1525
|
label,
|
|
987
1526
|
action,
|
|
988
1527
|
onAction: ctx.onAction,
|
|
1528
|
+
disabled,
|
|
989
1529
|
style: cssStyle,
|
|
990
1530
|
hoverStyle: cssHoverStyle
|
|
991
1531
|
},
|
|
@@ -997,12 +1537,47 @@ function renderNode(node, ctx, key) {
|
|
|
997
1537
|
const value = typeof resolvedValue === "boolean" ? resolvedValue : false;
|
|
998
1538
|
const onToggleVal = n.onToggle;
|
|
999
1539
|
const onToggle = typeof onToggleVal === "string" ? onToggleVal : "";
|
|
1000
|
-
|
|
1540
|
+
const resolvedDisabled = rv(n.disabled);
|
|
1541
|
+
const disabled = typeof resolvedDisabled === "boolean" ? resolvedDisabled : void 0;
|
|
1542
|
+
return /* @__PURE__ */ jsx20(
|
|
1001
1543
|
Toggle,
|
|
1002
1544
|
{
|
|
1003
1545
|
value,
|
|
1004
1546
|
onToggle,
|
|
1005
1547
|
onAction: ctx.onAction,
|
|
1548
|
+
disabled,
|
|
1549
|
+
style: cssStyle,
|
|
1550
|
+
hoverStyle: cssHoverStyle
|
|
1551
|
+
},
|
|
1552
|
+
key
|
|
1553
|
+
);
|
|
1554
|
+
}
|
|
1555
|
+
case "Accordion": {
|
|
1556
|
+
const items = resolveAccordionItems(n, ctx, key);
|
|
1557
|
+
const allowMultiple = n.allowMultiple === true;
|
|
1558
|
+
const defaultExpanded = Array.isArray(n.defaultExpanded) ? n.defaultExpanded.filter(
|
|
1559
|
+
(value) => typeof value === "string"
|
|
1560
|
+
) : void 0;
|
|
1561
|
+
return /* @__PURE__ */ jsx20(
|
|
1562
|
+
Accordion,
|
|
1563
|
+
{
|
|
1564
|
+
items,
|
|
1565
|
+
allowMultiple,
|
|
1566
|
+
defaultExpanded,
|
|
1567
|
+
style: cssStyle,
|
|
1568
|
+
hoverStyle: cssHoverStyle
|
|
1569
|
+
},
|
|
1570
|
+
key
|
|
1571
|
+
);
|
|
1572
|
+
}
|
|
1573
|
+
case "Tabs": {
|
|
1574
|
+
const tabs = resolveTabsItems(n, ctx, key);
|
|
1575
|
+
const defaultTab = typeof n.defaultTab === "string" ? n.defaultTab : void 0;
|
|
1576
|
+
return /* @__PURE__ */ jsx20(
|
|
1577
|
+
Tabs,
|
|
1578
|
+
{
|
|
1579
|
+
tabs,
|
|
1580
|
+
defaultTab,
|
|
1006
1581
|
style: cssStyle,
|
|
1007
1582
|
hoverStyle: cssHoverStyle
|
|
1008
1583
|
},
|
|
@@ -1050,7 +1625,7 @@ function renderForLoop(loop, ctx) {
|
|
|
1050
1625
|
}
|
|
1051
1626
|
return elements;
|
|
1052
1627
|
}
|
|
1053
|
-
function renderTree(rootNode, state, assets, cardStyles, iconResolver, onAction, onError, responsive = { compact: false }) {
|
|
1628
|
+
function renderTree(rootNode, state, assets, cardStyles, iconResolver, onAction, onError, responsive = { compact: false }, fragments) {
|
|
1054
1629
|
const limits = {
|
|
1055
1630
|
nodeCount: 0,
|
|
1056
1631
|
textBytes: 0,
|
|
@@ -1061,6 +1636,8 @@ function renderTree(rootNode, state, assets, cardStyles, iconResolver, onAction,
|
|
|
1061
1636
|
state,
|
|
1062
1637
|
assets,
|
|
1063
1638
|
cardStyles,
|
|
1639
|
+
fragments,
|
|
1640
|
+
fragmentStack: [],
|
|
1064
1641
|
iconResolver,
|
|
1065
1642
|
onAction,
|
|
1066
1643
|
onError,
|
|
@@ -1071,7 +1648,7 @@ function renderTree(rootNode, state, assets, cardStyles, iconResolver, onAction,
|
|
|
1071
1648
|
}
|
|
1072
1649
|
|
|
1073
1650
|
// src/UGCRenderer.tsx
|
|
1074
|
-
import { jsx as
|
|
1651
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
1075
1652
|
function UGCRenderer({
|
|
1076
1653
|
card,
|
|
1077
1654
|
viewName,
|
|
@@ -1082,8 +1659,8 @@ function UGCRenderer({
|
|
|
1082
1659
|
iconResolver,
|
|
1083
1660
|
onAction
|
|
1084
1661
|
}) {
|
|
1085
|
-
const [containerElement, setContainerElement] =
|
|
1086
|
-
const [containerWidth, setContainerWidth] =
|
|
1662
|
+
const [containerElement, setContainerElement] = useState4(null);
|
|
1663
|
+
const [containerWidth, setContainerWidth] = useState4(
|
|
1087
1664
|
typeof window === "undefined" ? null : window.innerWidth
|
|
1088
1665
|
);
|
|
1089
1666
|
const result = useMemo2(() => {
|
|
@@ -1103,14 +1680,16 @@ function UGCRenderer({
|
|
|
1103
1680
|
...stateOverride ?? {}
|
|
1104
1681
|
};
|
|
1105
1682
|
const cardStyles = cardObj.styles;
|
|
1683
|
+
const fragments = cardObj.fragments;
|
|
1106
1684
|
return {
|
|
1107
1685
|
valid: true,
|
|
1108
1686
|
rootNode: views[selectedView],
|
|
1109
1687
|
state: mergedState,
|
|
1110
|
-
cardStyles
|
|
1688
|
+
cardStyles,
|
|
1689
|
+
fragments
|
|
1111
1690
|
};
|
|
1112
1691
|
}, [card, viewName, stateOverride]);
|
|
1113
|
-
|
|
1692
|
+
useEffect2(() => {
|
|
1114
1693
|
if (!containerElement) {
|
|
1115
1694
|
return;
|
|
1116
1695
|
}
|
|
@@ -1146,7 +1725,7 @@ function UGCRenderer({
|
|
|
1146
1725
|
}
|
|
1147
1726
|
return null;
|
|
1148
1727
|
}
|
|
1149
|
-
return /* @__PURE__ */
|
|
1728
|
+
return /* @__PURE__ */ jsx21(UGCContainer, { ref: setContainerElement, style: containerStyle2, children: renderTree(
|
|
1150
1729
|
result.rootNode,
|
|
1151
1730
|
result.state,
|
|
1152
1731
|
assets,
|
|
@@ -1154,10 +1733,12 @@ function UGCRenderer({
|
|
|
1154
1733
|
iconResolver,
|
|
1155
1734
|
onAction,
|
|
1156
1735
|
onError,
|
|
1157
|
-
responsive
|
|
1736
|
+
responsive,
|
|
1737
|
+
result.fragments
|
|
1158
1738
|
) });
|
|
1159
1739
|
}
|
|
1160
1740
|
export {
|
|
1741
|
+
Accordion,
|
|
1161
1742
|
Avatar,
|
|
1162
1743
|
Badge,
|
|
1163
1744
|
Box,
|
|
@@ -1172,6 +1753,7 @@ export {
|
|
|
1172
1753
|
Row,
|
|
1173
1754
|
Spacer,
|
|
1174
1755
|
Stack,
|
|
1756
|
+
Tabs,
|
|
1175
1757
|
Text,
|
|
1176
1758
|
Toggle,
|
|
1177
1759
|
UGCContainer,
|