@safe-ugc-ui/react 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.js +109 -18
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -289,6 +289,7 @@ interface RenderContext {
|
|
|
289
289
|
limits: RuntimeLimits;
|
|
290
290
|
responsive: {
|
|
291
291
|
compact: boolean;
|
|
292
|
+
medium: boolean;
|
|
292
293
|
};
|
|
293
294
|
}
|
|
294
295
|
/**
|
|
@@ -316,6 +317,7 @@ declare function renderTree(rootNode: unknown, state: Record<string, unknown>, a
|
|
|
316
317
|
path: string;
|
|
317
318
|
}>) => void, responsive?: {
|
|
318
319
|
compact: boolean;
|
|
320
|
+
medium?: boolean;
|
|
319
321
|
}, fragments?: Record<string, unknown>): ReactNode;
|
|
320
322
|
|
|
321
323
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
// src/UGCRenderer.tsx
|
|
2
2
|
import { useEffect as useEffect2, useMemo as useMemo2, useState as useState4 } from "react";
|
|
3
3
|
import { validate, validateRaw } from "@safe-ugc-ui/validator";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
COMPACT_BREAKPOINT_MAX_WIDTH,
|
|
6
|
+
MEDIUM_BREAKPOINT_MAX_WIDTH
|
|
7
|
+
} from "@safe-ugc-ui/types";
|
|
5
8
|
|
|
6
9
|
// src/UGCContainer.tsx
|
|
7
10
|
import { forwardRef } from "react";
|
|
@@ -300,6 +303,19 @@ function resolveStructuredString(value, state, locals) {
|
|
|
300
303
|
}
|
|
301
304
|
return resolved;
|
|
302
305
|
}
|
|
306
|
+
function resolveStructuredLength(value, state, locals) {
|
|
307
|
+
const resolved = resolveStyleValue(value, state, locals);
|
|
308
|
+
if (typeof resolved === "number") {
|
|
309
|
+
return resolved;
|
|
310
|
+
}
|
|
311
|
+
if (typeof resolved === "string" && !containsForbiddenCssFunction(resolved)) {
|
|
312
|
+
return resolved;
|
|
313
|
+
}
|
|
314
|
+
return void 0;
|
|
315
|
+
}
|
|
316
|
+
function toCssLength(value) {
|
|
317
|
+
return typeof value === "number" ? `${value}px` : value;
|
|
318
|
+
}
|
|
303
319
|
function transformToCss(transform) {
|
|
304
320
|
const parts = [];
|
|
305
321
|
if (transform.rotate !== void 0) {
|
|
@@ -468,6 +484,62 @@ function resolveBorderObject(border, state, locals) {
|
|
|
468
484
|
if (color !== void 0) resolved.color = color;
|
|
469
485
|
return resolved;
|
|
470
486
|
}
|
|
487
|
+
function clipPathToCss(clipPath) {
|
|
488
|
+
switch (clipPath.type) {
|
|
489
|
+
case "circle":
|
|
490
|
+
return `circle(${toCssLength(clipPath.radius)})`;
|
|
491
|
+
case "ellipse":
|
|
492
|
+
return `ellipse(${toCssLength(clipPath.rx)} ${toCssLength(clipPath.ry)})`;
|
|
493
|
+
case "inset": {
|
|
494
|
+
const base = [
|
|
495
|
+
toCssLength(clipPath.top),
|
|
496
|
+
toCssLength(clipPath.right),
|
|
497
|
+
toCssLength(clipPath.bottom),
|
|
498
|
+
toCssLength(clipPath.left)
|
|
499
|
+
].join(" ");
|
|
500
|
+
const round = clipPath.round;
|
|
501
|
+
return round !== void 0 ? `inset(${base} round ${toCssLength(round)})` : `inset(${base})`;
|
|
502
|
+
}
|
|
503
|
+
default:
|
|
504
|
+
return "";
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
function resolveClipPathObject(clipPath, state, locals) {
|
|
508
|
+
if (!isRecord(clipPath) || typeof clipPath.type !== "string") {
|
|
509
|
+
return void 0;
|
|
510
|
+
}
|
|
511
|
+
switch (clipPath.type) {
|
|
512
|
+
case "circle": {
|
|
513
|
+
const radius = resolveStructuredLength(clipPath.radius, state, locals);
|
|
514
|
+
return radius !== void 0 ? { type: "circle", radius } : void 0;
|
|
515
|
+
}
|
|
516
|
+
case "ellipse": {
|
|
517
|
+
const rx = resolveStructuredLength(clipPath.rx, state, locals);
|
|
518
|
+
const ry = resolveStructuredLength(clipPath.ry, state, locals);
|
|
519
|
+
return rx !== void 0 && ry !== void 0 ? { type: "ellipse", rx, ry } : void 0;
|
|
520
|
+
}
|
|
521
|
+
case "inset": {
|
|
522
|
+
const top = resolveStructuredLength(clipPath.top, state, locals);
|
|
523
|
+
const right = resolveStructuredLength(clipPath.right, state, locals);
|
|
524
|
+
const bottom = resolveStructuredLength(clipPath.bottom, state, locals);
|
|
525
|
+
const left = resolveStructuredLength(clipPath.left, state, locals);
|
|
526
|
+
const round = resolveStructuredLength(clipPath.round, state, locals);
|
|
527
|
+
if (top === void 0 || right === void 0 || bottom === void 0 || left === void 0) {
|
|
528
|
+
return void 0;
|
|
529
|
+
}
|
|
530
|
+
return {
|
|
531
|
+
type: "inset",
|
|
532
|
+
top,
|
|
533
|
+
right,
|
|
534
|
+
bottom,
|
|
535
|
+
left,
|
|
536
|
+
...round !== void 0 ? { round } : {}
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
default:
|
|
540
|
+
return void 0;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
471
543
|
var FLEX_ALIGNMENT_MAP = {
|
|
472
544
|
start: "flex-start",
|
|
473
545
|
end: "flex-end"
|
|
@@ -545,6 +617,17 @@ function mapStyle(style, state, locals) {
|
|
|
545
617
|
css.transition = transitionCss;
|
|
546
618
|
}
|
|
547
619
|
}
|
|
620
|
+
const resolvedBackdropBlur = resolveStructuredNumber(style.backdropBlur, state, locals);
|
|
621
|
+
if (resolvedBackdropBlur !== void 0 && Number.isFinite(resolvedBackdropBlur) && resolvedBackdropBlur >= 0) {
|
|
622
|
+
css.backdropFilter = `blur(${resolvedBackdropBlur}px)`;
|
|
623
|
+
}
|
|
624
|
+
const resolvedClipPath = resolveClipPathObject(style.clipPath, state, locals);
|
|
625
|
+
if (resolvedClipPath) {
|
|
626
|
+
const clipPathCss = clipPathToCss(resolvedClipPath);
|
|
627
|
+
if (clipPathCss) {
|
|
628
|
+
css.clipPath = clipPathCss;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
548
631
|
return css;
|
|
549
632
|
}
|
|
550
633
|
var CSS_PROPERTY_NAME_MAP = {
|
|
@@ -1235,34 +1318,38 @@ function mergeStyleWithCardStyles(nodeStyle, cardStyles) {
|
|
|
1235
1318
|
hoverStyle: mergedHoverStyle
|
|
1236
1319
|
};
|
|
1237
1320
|
}
|
|
1238
|
-
function
|
|
1321
|
+
function getResponsiveOverrideStyle(nodeResponsive, mode) {
|
|
1239
1322
|
if (!nodeResponsive) return void 0;
|
|
1240
|
-
const
|
|
1241
|
-
if (
|
|
1323
|
+
const override = nodeResponsive[mode];
|
|
1324
|
+
if (override == null || typeof override !== "object" || Array.isArray(override)) {
|
|
1242
1325
|
return void 0;
|
|
1243
1326
|
}
|
|
1244
|
-
return
|
|
1327
|
+
return override;
|
|
1245
1328
|
}
|
|
1246
1329
|
function mergeEffectiveNodeStyle(node, ctx) {
|
|
1247
1330
|
const baseStyle = mergeStyleWithCardStyles(node.style, ctx.cardStyles);
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1331
|
+
const mediumOverride = mergeNamedStyle(
|
|
1332
|
+
getResponsiveOverrideStyle(node.responsive, "medium"),
|
|
1333
|
+
ctx.cardStyles
|
|
1334
|
+
);
|
|
1251
1335
|
const compactOverride = mergeNamedStyle(
|
|
1252
|
-
|
|
1336
|
+
getResponsiveOverrideStyle(node.responsive, "compact"),
|
|
1253
1337
|
ctx.cardStyles
|
|
1254
1338
|
);
|
|
1255
|
-
if (!compactOverride) {
|
|
1256
|
-
return baseStyle;
|
|
1257
|
-
}
|
|
1258
1339
|
const {
|
|
1259
|
-
hoverStyle:
|
|
1260
|
-
transition:
|
|
1340
|
+
hoverStyle: _mediumHoverStyle,
|
|
1341
|
+
transition: _mediumTransition,
|
|
1342
|
+
...mediumStyleWithoutInteractiveFields
|
|
1343
|
+
} = mediumOverride ?? {};
|
|
1344
|
+
const {
|
|
1345
|
+
hoverStyle: _compactHoverStyle,
|
|
1346
|
+
transition: _compactTransition,
|
|
1261
1347
|
...compactStyleWithoutInteractiveFields
|
|
1262
|
-
} = compactOverride;
|
|
1348
|
+
} = compactOverride ?? {};
|
|
1263
1349
|
return {
|
|
1264
1350
|
...baseStyle ?? {},
|
|
1265
|
-
...
|
|
1351
|
+
...ctx.responsive.medium ? mediumStyleWithoutInteractiveFields : {},
|
|
1352
|
+
...ctx.responsive.compact ? compactStyleWithoutInteractiveFields : {}
|
|
1266
1353
|
};
|
|
1267
1354
|
}
|
|
1268
1355
|
function resolveTextPayload(node, ctx) {
|
|
@@ -1625,7 +1712,7 @@ function renderForLoop(loop, ctx) {
|
|
|
1625
1712
|
}
|
|
1626
1713
|
return elements;
|
|
1627
1714
|
}
|
|
1628
|
-
function renderTree(rootNode, state, assets, cardStyles, iconResolver, onAction, onError, responsive = { compact: false }, fragments) {
|
|
1715
|
+
function renderTree(rootNode, state, assets, cardStyles, iconResolver, onAction, onError, responsive = { compact: false, medium: false }, fragments) {
|
|
1629
1716
|
const limits = {
|
|
1630
1717
|
nodeCount: 0,
|
|
1631
1718
|
textBytes: 0,
|
|
@@ -1642,7 +1729,10 @@ function renderTree(rootNode, state, assets, cardStyles, iconResolver, onAction,
|
|
|
1642
1729
|
onAction,
|
|
1643
1730
|
onError,
|
|
1644
1731
|
limits,
|
|
1645
|
-
responsive
|
|
1732
|
+
responsive: {
|
|
1733
|
+
compact: responsive.compact,
|
|
1734
|
+
medium: responsive.medium ?? responsive.compact
|
|
1735
|
+
}
|
|
1646
1736
|
};
|
|
1647
1737
|
return renderNode(rootNode, ctx, "root");
|
|
1648
1738
|
}
|
|
@@ -1715,6 +1805,7 @@ function UGCRenderer({
|
|
|
1715
1805
|
}, [containerElement]);
|
|
1716
1806
|
const responsive = useMemo2(
|
|
1717
1807
|
() => ({
|
|
1808
|
+
medium: containerWidth != null && containerWidth <= MEDIUM_BREAKPOINT_MAX_WIDTH,
|
|
1718
1809
|
compact: containerWidth != null && containerWidth <= COMPACT_BREAKPOINT_MAX_WIDTH
|
|
1719
1810
|
}),
|
|
1720
1811
|
[containerWidth]
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/UGCRenderer.tsx","../src/UGCContainer.tsx","../src/node-renderer.tsx","../src/state-resolver.ts","../src/condition-resolver.ts","../src/style-mapper.ts","../src/asset-resolver.ts","../src/hooks/useHoverStyle.ts","../src/components/Box.tsx","../src/components/Row.tsx","../src/components/Column.tsx","../src/components/Text.tsx","../src/components/Image.tsx","../src/components/Stack.tsx","../src/components/Grid.tsx","../src/components/Spacer.tsx","../src/components/Divider.tsx","../src/components/Icon.tsx","../src/components/ProgressBar.tsx","../src/components/Avatar.tsx","../src/components/Badge.tsx","../src/components/Chip.tsx","../src/components/Button.tsx","../src/components/Toggle.tsx","../src/components/Accordion.tsx","../src/components/Tabs.tsx"],"sourcesContent":["/**\n * @safe-ugc-ui/react --- UGC Renderer\n *\n * Top-level component that validates and renders a UGC card.\n *\n * Pipeline:\n * 1. Accept a card (UGCCard object or raw JSON string)\n * 2. Validate via @safe-ugc-ui/validator\n * 3. If invalid, render nothing (or optional error fallback)\n * 4. If valid, wrap in UGCContainer and render the view tree\n *\n * Props:\n * - card: UGCCard object or raw JSON string\n * - viewName: Name of the view to render (defaults to first view)\n * - assets: Mapping of asset keys to actual URLs\n * - state: Optional state override (merged with card.state)\n * - onError: Optional error callback\n * - iconResolver: Optional callback to resolve icon names to ReactNode\n * - onAction: Optional callback for Button/Toggle actions\n */\n\nimport { useEffect, useMemo, useState } from 'react';\nimport type { CSSProperties, ReactNode } from 'react';\nimport { validate, validateRaw } from '@safe-ugc-ui/validator';\nimport { COMPACT_BREAKPOINT_MAX_WIDTH, type UGCCard } from '@safe-ugc-ui/types';\n\nimport { UGCContainer } from './UGCContainer.js';\nimport { renderTree } from './node-renderer.js';\nimport type { AssetMap } from './asset-resolver.js';\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\nexport interface UGCRendererProps {\n /** The UGC card to render --- either a parsed object or a raw JSON string. */\n card: UGCCard | string;\n\n /** Name of the view to render. Defaults to the first view in the card. */\n viewName?: string;\n\n /** Asset map: keys are asset identifiers, values are resolved URLs. */\n assets?: AssetMap;\n\n /** Optional state override. Merged on top of the card's own state. */\n state?: Record<string, unknown>;\n\n /** Optional CSS style for the outer container. */\n containerStyle?: CSSProperties;\n\n /** Optional callback invoked when validation fails or runtime limits are hit. */\n onError?: (errors: Array<{ code: string; message: string; path: string }>) => void;\n\n /** Optional callback to resolve icon names to React elements. */\n iconResolver?: (name: string) => ReactNode;\n\n /** Optional callback for Button/Toggle interaction actions. */\n onAction?: (type: string, actionId: string, payload?: unknown) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * Top-level UGC card renderer.\n *\n * Validates the card, then renders the specified view inside a secure\n * UGCContainer. Returns null if validation fails.\n */\nexport function UGCRenderer({\n card,\n viewName,\n assets = {},\n state: stateOverride,\n containerStyle,\n onError,\n iconResolver,\n onAction,\n}: UGCRendererProps) {\n const [containerElement, setContainerElement] = useState<HTMLDivElement | null>(null);\n const [containerWidth, setContainerWidth] = useState<number | null>(\n typeof window === 'undefined' ? null : window.innerWidth,\n );\n\n const result = useMemo(() => {\n // 1. Validate\n const validationResult =\n typeof card === 'string' ? validateRaw(card) : validate(card);\n\n if (!validationResult.valid) {\n return { valid: false as const, errors: validationResult.errors };\n }\n\n // 2. Parse card object\n const cardObj: UGCCard =\n typeof card === 'string'\n ? (JSON.parse(card) as UGCCard)\n : card;\n\n // 3. Determine which view to render\n const views = cardObj.views;\n const viewKeys = Object.keys(views);\n const selectedView = viewName && viewName in views\n ? viewName\n : viewKeys[0];\n\n if (!selectedView || !(selectedView in views)) {\n return { valid: false as const, errors: [] };\n }\n\n // 4. Merge state\n const mergedState: Record<string, unknown> = {\n ...(cardObj.state ?? {}),\n ...(stateOverride ?? {}),\n };\n\n // 5. Extract card-level styles\n const cardStyles = cardObj.styles as Record<string, Record<string, unknown>> | undefined;\n const fragments = cardObj.fragments as Record<string, unknown> | undefined;\n\n return {\n valid: true as const,\n rootNode: views[selectedView],\n state: mergedState,\n cardStyles,\n fragments,\n };\n }, [card, viewName, stateOverride]);\n\n useEffect(() => {\n if (!containerElement) {\n return;\n }\n\n const updateWidth = (nextWidth?: number) => {\n if (typeof nextWidth === 'number' && Number.isFinite(nextWidth)) {\n setContainerWidth(nextWidth);\n return;\n }\n setContainerWidth(containerElement.getBoundingClientRect().width);\n };\n\n updateWidth();\n\n if (typeof ResizeObserver === 'function') {\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0];\n updateWidth(entry?.contentRect?.width);\n });\n observer.observe(containerElement);\n return () => observer.disconnect();\n }\n\n const handleResize = () => updateWidth();\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, [containerElement]);\n\n const responsive = useMemo(\n () => ({\n compact:\n containerWidth != null &&\n containerWidth <= COMPACT_BREAKPOINT_MAX_WIDTH,\n }),\n [containerWidth],\n );\n\n // Handle invalid cards\n if (!result.valid) {\n if (onError && result.errors.length > 0) {\n onError(result.errors);\n }\n return null;\n }\n\n // Render the view tree inside the secure container\n return (\n <UGCContainer ref={setContainerElement} style={containerStyle}>\n {renderTree(\n result.rootNode,\n result.state,\n assets,\n result.cardStyles,\n iconResolver,\n onAction,\n onError,\n responsive,\n result.fragments,\n )}\n </UGCContainer>\n );\n}\n","/**\n * @safe-ugc-ui/react — UGC Container\n *\n * Wrapper component that provides security isolation for UGC content.\n *\n * CSS isolation features:\n * - overflow: hidden — prevents content from escaping bounds\n * - isolation: isolate — creates a new stacking context\n * - contain: content — limits layout/paint/style to this subtree\n * - position: relative — establishes positioning context for children\n */\n\nimport { forwardRef } from 'react';\nimport type { CSSProperties, ReactNode } from 'react';\n\ninterface UGCContainerProps {\n children?: ReactNode;\n style?: CSSProperties;\n}\n\nconst containerStyle: CSSProperties = {\n overflow: 'hidden',\n isolation: 'isolate',\n contain: 'content',\n position: 'relative',\n};\n\n/**\n * Security isolation wrapper for UGC content.\n * All UGC card renderings should be wrapped in this container.\n */\nexport const UGCContainer = forwardRef<HTMLDivElement, UGCContainerProps>(\n function UGCContainer({ children, style }, ref) {\n const mergedStyle: CSSProperties = style\n ? { ...containerStyle, ...style }\n : containerStyle;\n\n return <div ref={ref} style={mergedStyle}>{children}</div>;\n },\n);\n","/**\n * @safe-ugc-ui/react --- Node Renderer\n *\n * Recursive renderer that maps UGC node types to React components.\n * Supports all currently implemented component types, for-loop rendering, style reference merge,\n * and runtime limits pre-check.\n *\n * For each node:\n * 1. Pre-check runtime limits (node count, style bytes, overflow, text bytes)\n * 2. Merge $style with inline styles (including hoverStyle.$style)\n * 3. Resolve $ref values in node fields using state-resolver (with locals)\n * 4. Map style fields to React CSSProperties using style-mapper\n * 5. Resolve asset paths for Image/Avatar src using asset-resolver\n * 6. Render the appropriate component\n * 7. Recursively render children (arrays and for-loops)\n */\n\nimport type { CSSProperties, ReactNode } from 'react';\nimport {\n MAX_NODE_COUNT,\n MAX_LOOP_ITERATIONS,\n TEXT_CONTENT_TOTAL_MAX_BYTES,\n STYLE_OBJECTS_TOTAL_MAX_BYTES,\n MAX_OVERFLOW_AUTO_COUNT,\n} from '@safe-ugc-ui/types';\n\nimport { resolveRef, resolveTextValue, resolveValue } from './state-resolver.js';\nimport { evaluateCondition } from './condition-resolver.js';\nimport { mapStyle } from './style-mapper.js';\nimport { resolveAsset } from './asset-resolver.js';\nimport type { AssetMap } from './asset-resolver.js';\nimport { Box } from './components/Box.js';\nimport { Row } from './components/Row.js';\nimport { Column } from './components/Column.js';\nimport { Text } from './components/Text.js';\nimport { Image } from './components/Image.js';\nimport { Stack } from './components/Stack.js';\nimport { Grid } from './components/Grid.js';\nimport { Spacer } from './components/Spacer.js';\nimport { Divider } from './components/Divider.js';\nimport { Icon } from './components/Icon.js';\nimport { ProgressBar } from './components/ProgressBar.js';\nimport { Avatar } from './components/Avatar.js';\nimport { Badge } from './components/Badge.js';\nimport { Chip } from './components/Chip.js';\nimport { Button } from './components/Button.js';\nimport { Toggle } from './components/Toggle.js';\nimport { Accordion } from './components/Accordion.js';\nimport { Tabs } from './components/Tabs.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * A generic UGC node shape. We use Record<string, unknown> for flexibility\n * since the validator has already verified the structure before rendering.\n */\ninterface UGCNodeLike {\n type: string;\n style?: Record<string, unknown>;\n responsive?: Record<string, unknown>;\n children?: unknown;\n [key: string]: unknown;\n}\n\ninterface ForLoopLike {\n for: string;\n in: string;\n template: unknown;\n}\n\ninterface FragmentUseLike {\n $use: string;\n $if?: unknown;\n [key: string]: unknown;\n}\n\ninterface ResolvedTextSpan {\n text: string;\n style?: CSSProperties;\n}\n\ninterface ResolvedTextPayload {\n content?: string;\n spans?: ResolvedTextSpan[];\n textBytes: number;\n styleBytes: number;\n}\n\ninterface ResolvedAccordionItem {\n id: string;\n label: string;\n content: ReactNode;\n disabled?: boolean;\n}\n\ninterface ResolvedTabsItem {\n id: string;\n label: string;\n content: ReactNode;\n disabled?: boolean;\n}\n\n/**\n * Runtime limits tracking object. Mutated during rendering to\n * track cumulative resource usage across the entire card.\n */\nexport interface RuntimeLimits {\n nodeCount: number;\n textBytes: number;\n styleBytes: number;\n overflowAutoCount: number;\n}\n\nexport interface RenderContext {\n state: Record<string, unknown>;\n assets: AssetMap;\n locals?: Record<string, unknown>;\n cardStyles?: Record<string, Record<string, unknown>>;\n fragments?: Record<string, unknown>;\n fragmentStack?: string[];\n iconResolver?: (name: string) => ReactNode;\n onAction?: (type: string, actionId: string, payload?: unknown) => void;\n onError?: (errors: Array<{ code: string; message: string; path: string }>) => void;\n limits: RuntimeLimits;\n responsive: {\n compact: boolean;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction isForLoop(obj: unknown): obj is ForLoopLike {\n if (obj == null || typeof obj !== 'object' || Array.isArray(obj)) return false;\n const o = obj as Record<string, unknown>;\n return typeof o.for === 'string' && typeof o.in === 'string' && o.template != null;\n}\n\nfunction isFragmentUse(obj: unknown): obj is FragmentUseLike {\n if (obj == null || typeof obj !== 'object' || Array.isArray(obj)) return false;\n return typeof (obj as Record<string, unknown>).$use === 'string';\n}\n\nfunction utf8ByteLength(str: string): number {\n let bytes = 0;\n for (let i = 0; i < str.length; i++) {\n const code = str.charCodeAt(i);\n if (code <= 0x7f) {\n bytes += 1;\n } else if (code <= 0x7ff) {\n bytes += 2;\n } else if (code >= 0xd800 && code <= 0xdbff) {\n // Surrogate pair → 4 UTF-8 bytes\n bytes += 4;\n i++; // skip low surrogate\n } else {\n bytes += 3;\n }\n }\n return bytes;\n}\n\n/**\n * Merge a single style object from cardStyles with inline style overrides.\n * Returns the merged raw style (unresolved $ref values) and the style\n * without $style key.\n */\nfunction mergeNamedStyle(\n style: Record<string, unknown> | undefined,\n cardStyles: Record<string, Record<string, unknown>> | undefined,\n): Record<string, unknown> | undefined {\n if (!style) return undefined;\n\n const rawStyleName = style.$style;\n const styleName = typeof rawStyleName === 'string' ? rawStyleName.trim() : rawStyleName;\n if (!styleName || typeof styleName !== 'string' || !cardStyles) {\n // Return style without $style key if present\n if (style.$style !== undefined) {\n const { $style: _, ...rest } = style;\n return rest;\n }\n return style;\n }\n\n const baseStyle = cardStyles[styleName];\n if (!baseStyle) return style;\n\n // Merge: base from cardStyles, overridden by inline (excluding $style key)\n const { $style: _, ...inlineWithout$style } = style;\n return { ...baseStyle, ...inlineWithout$style };\n}\n\n/**\n * Merge node style and nested hoverStyle against cardStyles.\n */\nfunction mergeStyleWithCardStyles(\n nodeStyle: Record<string, unknown> | undefined,\n cardStyles: Record<string, Record<string, unknown>> | undefined,\n): Record<string, unknown> | undefined {\n const mergedStyle = mergeNamedStyle(nodeStyle, cardStyles);\n if (!mergedStyle) return undefined;\n\n const rawHoverStyle = mergedStyle.hoverStyle;\n if (typeof rawHoverStyle !== 'object' || rawHoverStyle === null || Array.isArray(rawHoverStyle)) {\n return mergedStyle;\n }\n\n const mergedHoverStyle = mergeNamedStyle(\n rawHoverStyle as Record<string, unknown>,\n cardStyles,\n );\n\n if (!mergedHoverStyle) {\n return mergedStyle;\n }\n\n return {\n ...mergedStyle,\n hoverStyle: mergedHoverStyle,\n };\n}\n\nfunction getCompactResponsiveStyle(\n nodeResponsive: Record<string, unknown> | undefined,\n): Record<string, unknown> | undefined {\n if (!nodeResponsive) return undefined;\n\n const compact = nodeResponsive.compact;\n if (\n compact == null ||\n typeof compact !== 'object' ||\n Array.isArray(compact)\n ) {\n return undefined;\n }\n\n return compact as Record<string, unknown>;\n}\n\nfunction mergeEffectiveNodeStyle(\n node: UGCNodeLike,\n ctx: RenderContext,\n): Record<string, unknown> | undefined {\n const baseStyle = mergeStyleWithCardStyles(node.style, ctx.cardStyles);\n if (!ctx.responsive.compact) {\n return baseStyle;\n }\n\n const compactOverride = mergeNamedStyle(\n getCompactResponsiveStyle(node.responsive),\n ctx.cardStyles,\n );\n\n if (!compactOverride) {\n return baseStyle;\n }\n\n const {\n hoverStyle: _hoverStyle,\n transition: _transition,\n ...compactStyleWithoutInteractiveFields\n } = compactOverride;\n\n return {\n ...(baseStyle ?? {}),\n ...compactStyleWithoutInteractiveFields,\n };\n}\n\nfunction resolveTextPayload(\n node: UGCNodeLike,\n ctx: RenderContext,\n): ResolvedTextPayload {\n const rawSpans = Array.isArray(node.spans) ? node.spans : undefined;\n\n if (rawSpans) {\n const spans = rawSpans.map((span) => {\n const rawSpan = span as Record<string, unknown>;\n const spanStyle =\n rawSpan.style != null &&\n typeof rawSpan.style === 'object' &&\n !Array.isArray(rawSpan.style)\n ? rawSpan.style as Record<string, unknown>\n : undefined;\n\n return {\n text: resolveTextValue(rawSpan.text, ctx.state, ctx.locals),\n style: spanStyle ? mapStyle(spanStyle, ctx.state, ctx.locals) : undefined,\n rawStyleBytes: spanStyle ? utf8ByteLength(JSON.stringify(spanStyle)) : 0,\n };\n });\n\n const combinedText = spans.map((span) => span.text).join('');\n return {\n spans: spans.map(({ rawStyleBytes: _rawStyleBytes, ...span }) => span),\n textBytes: utf8ByteLength(combinedText),\n styleBytes: spans.reduce((sum, span) => sum + span.rawStyleBytes, 0),\n };\n }\n\n const content = resolveTextValue(node.content, ctx.state, ctx.locals);\n return {\n content,\n textBytes: utf8ByteLength(content),\n styleBytes: 0,\n };\n}\n\nfunction resolveAccordionItems(\n node: UGCNodeLike,\n ctx: RenderContext,\n key: string | number,\n): ResolvedAccordionItem[] {\n const rawItems = Array.isArray(node.items) ? node.items : [];\n\n return rawItems.flatMap((item, index) => {\n if (\n item == null ||\n typeof item !== 'object' ||\n Array.isArray(item)\n ) {\n return [];\n }\n\n const rawItem = item as Record<string, unknown>;\n const id = typeof rawItem.id === 'string' ? rawItem.id : `item-${index}`;\n const label = resolveTextValue(rawItem.label, ctx.state, ctx.locals);\n const resolvedDisabled = resolveValue(rawItem.disabled, ctx.state, ctx.locals);\n const disabled = typeof resolvedDisabled === 'boolean' ? resolvedDisabled : undefined;\n const content = renderNode(\n rawItem.content,\n ctx,\n `${String(key)}.items[${index}].content`,\n );\n\n return [{ id, label, content, disabled }];\n });\n}\n\nfunction resolveTabsItems(\n node: UGCNodeLike,\n ctx: RenderContext,\n key: string | number,\n): ResolvedTabsItem[] {\n const rawTabs = Array.isArray(node.tabs) ? node.tabs : [];\n\n return rawTabs.flatMap((tab, index) => {\n if (\n tab == null ||\n typeof tab !== 'object' ||\n Array.isArray(tab)\n ) {\n return [];\n }\n\n const rawTab = tab as Record<string, unknown>;\n const id = typeof rawTab.id === 'string' ? rawTab.id : `tab-${index}`;\n const label = resolveTextValue(rawTab.label, ctx.state, ctx.locals);\n const resolvedDisabled = resolveValue(rawTab.disabled, ctx.state, ctx.locals);\n const disabled = typeof resolvedDisabled === 'boolean' ? resolvedDisabled : undefined;\n const content = renderNode(\n rawTab.content,\n ctx,\n `${String(key)}.tabs[${index}].content`,\n );\n\n return [{ id, label, content, disabled }];\n });\n}\n\n// ---------------------------------------------------------------------------\n// renderNode --- recursive node renderer\n// ---------------------------------------------------------------------------\n\n/**\n * Render a single UGC node to a React element.\n *\n * Performs runtime limits pre-check BEFORE rendering to prevent\n * DOM pollution when limits are exceeded.\n */\nexport function renderNode(\n node: unknown,\n ctx: RenderContext,\n key: string | number,\n): ReactNode {\n if (node == null || typeof node !== 'object') return null;\n\n if (isFragmentUse(node)) {\n if ('$if' in node && !evaluateCondition(node.$if, ctx.state, ctx.locals)) {\n return null;\n }\n\n if ((ctx.fragmentStack?.length ?? 0) > 0) {\n ctx.onError?.([{\n code: 'RUNTIME_FRAGMENT_NESTED_USE',\n message: 'Fragments may not contain nested \"$use\" references',\n path: String(key),\n }]);\n return null;\n }\n\n if (ctx.fragmentStack?.includes(node.$use)) {\n ctx.onError?.([{\n code: 'RUNTIME_FRAGMENT_CYCLE',\n message: `Fragment \"${node.$use}\" recursively references itself`,\n path: String(key),\n }]);\n return null;\n }\n\n const fragment = ctx.fragments?.[node.$use];\n if (fragment == null) {\n ctx.onError?.([{\n code: 'RUNTIME_FRAGMENT_NOT_FOUND',\n message: `Fragment \"${node.$use}\" was not found`,\n path: String(key),\n }]);\n return null;\n }\n\n return renderNode(\n fragment,\n {\n ...ctx,\n fragmentStack: [...(ctx.fragmentStack ?? []), node.$use],\n },\n key,\n );\n }\n\n const n = node as UGCNodeLike;\n if (!n.type) return null;\n\n if ('$if' in n && !evaluateCondition(n.$if, ctx.state, ctx.locals)) {\n return null;\n }\n\n // --- Compute all deltas before committing any ---\n const mergedRawStyle = mergeEffectiveNodeStyle(n, ctx);\n const rv = (val: unknown) => resolveValue(val, ctx.state, ctx.locals);\n\n let styleDelta = mergedRawStyle ? utf8ByteLength(JSON.stringify(mergedRawStyle)) : 0;\n const overflowDelta = mergedRawStyle?.overflow === 'auto' ? 1 : 0;\n\n // Text payload: resolve once, reuse in render\n let resolvedTextPayload: ResolvedTextPayload | undefined;\n let textDelta = 0;\n if (n.type === 'Text') {\n resolvedTextPayload = resolveTextPayload(n, ctx);\n textDelta = resolvedTextPayload.textBytes;\n styleDelta += resolvedTextPayload.styleBytes;\n }\n\n // --- Batch limit checks (all-or-nothing) ---\n if (ctx.limits.nodeCount + 1 > MAX_NODE_COUNT) {\n ctx.onError?.([{ code: 'RUNTIME_NODE_LIMIT', message: `Node count exceeds maximum of ${MAX_NODE_COUNT}`, path: String(key) }]);\n return null;\n }\n if (ctx.limits.styleBytes + styleDelta > STYLE_OBJECTS_TOTAL_MAX_BYTES) {\n ctx.onError?.([{ code: 'RUNTIME_STYLE_LIMIT', message: `Style bytes exceed maximum of ${STYLE_OBJECTS_TOTAL_MAX_BYTES}`, path: String(key) }]);\n return null;\n }\n if (ctx.limits.overflowAutoCount + overflowDelta > MAX_OVERFLOW_AUTO_COUNT) {\n ctx.onError?.([{ code: 'RUNTIME_OVERFLOW_LIMIT', message: `Overflow auto count exceeds maximum of ${MAX_OVERFLOW_AUTO_COUNT}`, path: String(key) }]);\n return null;\n }\n if (ctx.limits.textBytes + textDelta > TEXT_CONTENT_TOTAL_MAX_BYTES) {\n ctx.onError?.([{ code: 'RUNTIME_TEXT_LIMIT', message: `Text bytes exceed maximum of ${TEXT_CONTENT_TOTAL_MAX_BYTES}`, path: String(key) }]);\n return null;\n }\n\n // --- All checks passed: commit all deltas at once ---\n ctx.limits.nodeCount += 1;\n ctx.limits.styleBytes += styleDelta;\n ctx.limits.overflowAutoCount += overflowDelta;\n ctx.limits.textBytes += textDelta;\n\n // Resolve style to CSS\n const cssStyle = mapStyle(mergedRawStyle, ctx.state, ctx.locals);\n\n // Resolve hoverStyle to CSS (if present)\n const rawHoverStyle = mergedRawStyle?.hoverStyle as Record<string, unknown> | undefined;\n const cssHoverStyle = rawHoverStyle ? mapStyle(rawHoverStyle, ctx.state, ctx.locals) : undefined;\n\n // Render children recursively\n const childElements = renderChildren(n.children, ctx);\n\n switch (n.type) {\n case 'Box':\n return <Box key={key} style={cssStyle} hoverStyle={cssHoverStyle}>{childElements}</Box>;\n\n case 'Row':\n return <Row key={key} style={cssStyle} hoverStyle={cssHoverStyle}>{childElements}</Row>;\n\n case 'Column':\n return <Column key={key} style={cssStyle} hoverStyle={cssHoverStyle}>{childElements}</Column>;\n\n case 'Stack':\n return <Stack key={key} style={cssStyle} hoverStyle={cssHoverStyle}>{childElements}</Stack>;\n\n case 'Grid':\n return <Grid key={key} style={cssStyle} hoverStyle={cssHoverStyle}>{childElements}</Grid>;\n\n case 'Text': {\n const maxLines = typeof n.maxLines === 'number' ? n.maxLines : undefined;\n const truncate = n.truncate === 'clip' || n.truncate === 'ellipsis'\n ? n.truncate\n : undefined;\n\n return (\n <Text\n key={key}\n content={resolvedTextPayload?.content}\n spans={resolvedTextPayload?.spans}\n maxLines={maxLines}\n truncate={truncate}\n style={cssStyle}\n hoverStyle={cssHoverStyle}\n />\n );\n }\n\n case 'Image': {\n let src = rv((n as Record<string, unknown>).src);\n if (typeof src !== 'string' || !src) return null;\n if (!src.startsWith('@assets/')) return null;\n if (src.includes('../')) return null;\n const resolved = resolveAsset(src, ctx.assets);\n if (!resolved) return null;\n if (typeof resolved === 'string' && resolved.trim().toLowerCase().startsWith('javascript:')) return null;\n const resolvedAlt = rv((n as Record<string, unknown>).alt);\n const alt = typeof resolvedAlt === 'string' ? resolvedAlt : undefined;\n return <Image key={key} src={resolved} alt={alt} style={cssStyle} hoverStyle={cssHoverStyle} />;\n }\n\n case 'Avatar': {\n let src = rv((n as Record<string, unknown>).src);\n if (typeof src !== 'string' || !src) return null;\n if (!src.startsWith('@assets/')) return null;\n if (src.includes('../')) return null;\n const resolved = resolveAsset(src, ctx.assets);\n if (!resolved) return null;\n if (typeof resolved === 'string' && resolved.trim().toLowerCase().startsWith('javascript:')) return null;\n const resolvedSize = rv((n as Record<string, unknown>).size);\n const size = typeof resolvedSize === 'number' || typeof resolvedSize === 'string'\n ? resolvedSize : undefined;\n return <Avatar key={key} src={resolved} size={size} style={cssStyle} hoverStyle={cssHoverStyle} />;\n }\n\n case 'Icon': {\n const resolvedName = rv((n as Record<string, unknown>).name);\n const name = typeof resolvedName === 'string' ? resolvedName : '';\n const resolvedSize = rv((n as Record<string, unknown>).size);\n const size = typeof resolvedSize === 'number' || typeof resolvedSize === 'string'\n ? resolvedSize : undefined;\n const resolvedColor = rv((n as Record<string, unknown>).color);\n const color = typeof resolvedColor === 'string' ? resolvedColor : undefined;\n return (\n <Icon\n key={key}\n name={name}\n size={size}\n color={color}\n iconResolver={ctx.iconResolver}\n style={cssStyle}\n hoverStyle={cssHoverStyle}\n />\n );\n }\n\n case 'Spacer': {\n const resolvedSize = rv((n as Record<string, unknown>).size);\n const size = typeof resolvedSize === 'number' || typeof resolvedSize === 'string'\n ? resolvedSize : undefined;\n return <Spacer key={key} size={size} style={cssStyle} hoverStyle={cssHoverStyle} />;\n }\n\n case 'Divider': {\n const resolvedColor = rv((n as Record<string, unknown>).color);\n const color = typeof resolvedColor === 'string' ? resolvedColor : undefined;\n const resolvedThickness = rv((n as Record<string, unknown>).thickness);\n const thickness = typeof resolvedThickness === 'number' || typeof resolvedThickness === 'string'\n ? resolvedThickness : undefined;\n return <Divider key={key} color={color} thickness={thickness} style={cssStyle} hoverStyle={cssHoverStyle} />;\n }\n\n case 'ProgressBar': {\n const resolvedValue = rv((n as Record<string, unknown>).value);\n const value = typeof resolvedValue === 'number' ? resolvedValue : 0;\n const resolvedMax = rv((n as Record<string, unknown>).max);\n const max = typeof resolvedMax === 'number' ? resolvedMax : 100;\n const resolvedColor = rv((n as Record<string, unknown>).color);\n const color = typeof resolvedColor === 'string' ? resolvedColor : undefined;\n return <ProgressBar key={key} value={value} max={max} color={color} style={cssStyle} hoverStyle={cssHoverStyle} />;\n }\n\n case 'Badge': {\n const label = resolveTextValue((n as Record<string, unknown>).label, ctx.state, ctx.locals);\n const resolvedColor = rv((n as Record<string, unknown>).color);\n const color = typeof resolvedColor === 'string' ? resolvedColor : undefined;\n return <Badge key={key} label={label} color={color} style={cssStyle} hoverStyle={cssHoverStyle} />;\n }\n\n case 'Chip': {\n const label = resolveTextValue((n as Record<string, unknown>).label, ctx.state, ctx.locals);\n const resolvedColor = rv((n as Record<string, unknown>).color);\n const color = typeof resolvedColor === 'string' ? resolvedColor : undefined;\n return <Chip key={key} label={label} color={color} style={cssStyle} hoverStyle={cssHoverStyle} />;\n }\n\n case 'Button': {\n const label = resolveTextValue((n as Record<string, unknown>).label, ctx.state, ctx.locals);\n const actionVal = (n as Record<string, unknown>).action;\n const action = typeof actionVal === 'string' ? actionVal : '';\n const resolvedDisabled = rv((n as Record<string, unknown>).disabled);\n const disabled = typeof resolvedDisabled === 'boolean' ? resolvedDisabled : undefined;\n return (\n <Button\n key={key}\n label={label}\n action={action}\n onAction={ctx.onAction}\n disabled={disabled}\n style={cssStyle}\n hoverStyle={cssHoverStyle}\n />\n );\n }\n\n case 'Toggle': {\n const resolvedValue = rv((n as Record<string, unknown>).value);\n const value = typeof resolvedValue === 'boolean' ? resolvedValue : false;\n const onToggleVal = (n as Record<string, unknown>).onToggle;\n const onToggle = typeof onToggleVal === 'string' ? onToggleVal : '';\n const resolvedDisabled = rv((n as Record<string, unknown>).disabled);\n const disabled = typeof resolvedDisabled === 'boolean' ? resolvedDisabled : undefined;\n return (\n <Toggle\n key={key}\n value={value}\n onToggle={onToggle}\n onAction={ctx.onAction}\n disabled={disabled}\n style={cssStyle}\n hoverStyle={cssHoverStyle}\n />\n );\n }\n\n case 'Accordion': {\n const items = resolveAccordionItems(n, ctx, key);\n const allowMultiple = (n as Record<string, unknown>).allowMultiple === true;\n const defaultExpanded = Array.isArray((n as Record<string, unknown>).defaultExpanded)\n ? ((n as Record<string, unknown>).defaultExpanded as unknown[]).filter(\n (value): value is string => typeof value === 'string',\n )\n : undefined;\n\n return (\n <Accordion\n key={key}\n items={items}\n allowMultiple={allowMultiple}\n defaultExpanded={defaultExpanded}\n style={cssStyle}\n hoverStyle={cssHoverStyle}\n />\n );\n }\n\n case 'Tabs': {\n const tabs = resolveTabsItems(n, ctx, key);\n const defaultTab = typeof (n as Record<string, unknown>).defaultTab === 'string'\n ? (n as Record<string, unknown>).defaultTab as string\n : undefined;\n\n return (\n <Tabs\n key={key}\n tabs={tabs}\n defaultTab={defaultTab}\n style={cssStyle}\n hoverStyle={cssHoverStyle}\n />\n );\n }\n\n default:\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// renderChildren --- handle children arrays and for-loops\n// ---------------------------------------------------------------------------\n\nfunction renderChildren(\n children: unknown,\n ctx: RenderContext,\n): ReactNode[] | null {\n if (!children) return null;\n\n // Array children\n if (Array.isArray(children)) {\n return children.map((child, index) => renderNode(child, ctx, index));\n }\n\n // For-loop children\n if (isForLoop(children)) {\n return renderForLoop(children, ctx);\n }\n\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// renderForLoop --- iterate over state array, render template per item\n// ---------------------------------------------------------------------------\n\nfunction renderForLoop(\n loop: ForLoopLike,\n ctx: RenderContext,\n): ReactNode[] {\n // Resolve the source array from state (or locals)\n const source = resolveRef(loop.in, ctx.state, ctx.locals);\n if (source === undefined) {\n // Soft skip: source not found (may be provided at runtime or optional)\n return [];\n }\n if (!Array.isArray(source)) {\n // Hard error: source exists but is not an array (type mismatch)\n ctx.onError?.([{\n code: 'RUNTIME_LOOP_SOURCE_INVALID',\n message: `Loop source \"${loop.in}\" is not an array (got ${typeof source})`,\n path: `for(${loop.for} in ${loop.in})`,\n }]);\n return [];\n }\n\n // Cap iterations\n const maxIter = Math.min(source.length, MAX_LOOP_ITERATIONS);\n const elements: ReactNode[] = [];\n\n for (let i = 0; i < maxIter; i++) {\n const item = source[i];\n const newLocals: Record<string, unknown> = {\n ...ctx.locals,\n [loop.for]: item,\n index: i,\n };\n const childCtx: RenderContext = { ...ctx, locals: newLocals };\n elements.push(renderNode(loop.template, childCtx, i));\n }\n\n return elements;\n}\n\n// ---------------------------------------------------------------------------\n// RenderTree --- render an entire view tree\n// ---------------------------------------------------------------------------\n\n/**\n * Render a full view tree starting from the root node.\n *\n * @param rootNode - The root node of the view\n * @param state - Card state for $ref resolution\n * @param assets - Asset map for @assets/ resolution\n * @param cardStyles - Optional card-level named styles\n * @param iconResolver - Optional icon resolver callback\n * @param onAction - Optional action callback for Button/Toggle\n * @param onError - Optional error callback\n * @returns A React element tree\n */\nexport function renderTree(\n rootNode: unknown,\n state: Record<string, unknown>,\n assets: AssetMap,\n cardStyles?: Record<string, Record<string, unknown>>,\n iconResolver?: (name: string) => ReactNode,\n onAction?: (type: string, actionId: string, payload?: unknown) => void,\n onError?: (errors: Array<{ code: string; message: string; path: string }>) => void,\n responsive: { compact: boolean } = { compact: false },\n fragments?: Record<string, unknown>,\n): ReactNode {\n const limits: RuntimeLimits = {\n nodeCount: 0,\n textBytes: 0,\n styleBytes: 0,\n overflowAutoCount: 0,\n };\n const ctx: RenderContext = {\n state,\n assets,\n cardStyles,\n fragments,\n fragmentStack: [],\n iconResolver,\n onAction,\n onError,\n limits,\n responsive,\n };\n return renderNode(rootNode, ctx, 'root');\n}\n","/**\n * @safe-ugc-ui/react — State Resolver\n *\n * Resolves $ref values from card state.\n *\n * - $ref: looks up a dotted path in the state object\n * - Literal values pass through unchanged\n */\n\nimport {\n PROTOTYPE_POLLUTION_SEGMENTS,\n} from '@safe-ugc-ui/types';\n\n/**\n * Parse a $ref path into individual segments.\n * Handles both dot notation and bracket notation:\n * \"items[0].name\" → [\"items\", \"0\", \"name\"]\n * \"data[2][3]\" → [\"data\", \"2\", \"3\"]\n * \"simple.path\" → [\"simple\", \"path\"]\n */\nfunction parseRefSegments(path: string): string[] {\n const segments: string[] = [];\n const dotParts = path.split('.');\n for (const part of dotParts) {\n if (!part) continue;\n // Check for bracket notation: extract base and indices\n const bracketPattern = /\\[(\\d+)\\]/g;\n let match: RegExpExecArray | null;\n\n // Find the base name (before first bracket)\n const firstBracket = part.indexOf('[');\n if (firstBracket > 0) {\n segments.push(part.slice(0, firstBracket));\n } else if (firstBracket === -1) {\n // No brackets at all\n segments.push(part);\n continue;\n }\n\n // Extract all bracket indices\n while ((match = bracketPattern.exec(part)) !== null) {\n segments.push(match[1]);\n }\n\n // If part starts with [ and no base was added\n if (firstBracket === 0) {\n // Edge case: segment is just [0] with no base name\n // This shouldn't normally happen but handle gracefully\n }\n }\n return segments;\n}\n\n/**\n * Resolves a $ref path (e.g. \"$hp\", \"$items[0].name\") from card state.\n *\n * - Strips leading '$' from the path\n * - Parses dot notation and bracket notation into segments\n * - Blocks __proto__, constructor, prototype segments\n * - Max depth of 5 segments per spec\n * - Returns undefined if path doesn't exist\n */\nexport function resolveRef(\n refPath: string,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): unknown {\n const path = refPath.startsWith('$') ? refPath.slice(1) : refPath;\n const segments = parseRefSegments(path);\n\n // Block prototype pollution\n for (const seg of segments) {\n if ((PROTOTYPE_POLLUTION_SEGMENTS as readonly string[]).includes(seg)) {\n return undefined;\n }\n }\n\n // Max depth check\n if (segments.length > 5) return undefined;\n\n // Choose starting object: locals first, then state\n const firstSeg = segments[0];\n let current: unknown;\n if (locals && firstSeg && firstSeg in locals) {\n current = locals;\n } else {\n current = state;\n }\n\n // Traverse\n for (const seg of segments) {\n if (current == null || typeof current !== 'object') return undefined;\n if (Array.isArray(current)) {\n const idx = parseInt(seg, 10);\n if (isNaN(idx)) return undefined;\n current = current[idx];\n } else {\n current = (current as Record<string, unknown>)[seg];\n }\n }\n return current;\n}\n\n/**\n * Resolve a value that might be a literal or $ref.\n * - Literal: return as-is\n * - $ref: resolve from state\n */\nexport function resolveValue(\n value: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): unknown {\n if (value == null) return value;\n if (typeof value === 'object' && value !== null) {\n if ('$ref' in value && typeof (value as Record<string, unknown>).$ref === 'string') {\n return resolveRef((value as Record<string, unknown>).$ref as string, state, locals);\n }\n }\n return value;\n}\n\nfunction stringifyTextScalar(value: unknown): string {\n if (value === undefined) return '';\n if (value === null) return 'null';\n if (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n return String(value);\n }\n return '';\n}\n\nfunction isTemplateObject(\n value: unknown,\n): value is { $template: unknown[] } {\n return (\n typeof value === 'object' &&\n value !== null &&\n '$template' in value &&\n Array.isArray((value as Record<string, unknown>).$template)\n );\n}\n\nexport function resolveTemplate(\n value: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): string | undefined {\n if (!isTemplateObject(value)) {\n return undefined;\n }\n\n return value.$template\n .map((part) => stringifyTextScalar(resolveValue(part, state, locals)))\n .join('');\n}\n\nexport function resolveTextValue(\n value: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): string {\n const template = resolveTemplate(value, state, locals);\n if (template !== undefined) {\n return template;\n }\n\n return stringifyTextScalar(resolveValue(value, state, locals));\n}\n","/**\n * @safe-ugc-ui/react — Condition Resolver\n *\n * Evaluates the small declarative condition AST used by node-level `$if`.\n * This intentionally does not support general expressions or computation.\n */\n\nimport { MAX_CONDITION_DEPTH, isRef } from '@safe-ugc-ui/types';\nimport { resolveRef } from './state-resolver.js';\n\ntype ConditionOperand = string | number | boolean | null | { $ref: string };\n\nfunction resolveOperand(\n operand: ConditionOperand,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): string | number | boolean | null | undefined {\n if (isRef(operand)) {\n const resolved = resolveRef(operand.$ref, state, locals);\n if (\n resolved === null ||\n typeof resolved === 'string' ||\n typeof resolved === 'number' ||\n typeof resolved === 'boolean'\n ) {\n return resolved;\n }\n return undefined;\n }\n\n return operand;\n}\n\nfunction compareValues(\n op: string,\n left: string | number | boolean | null | undefined,\n right: string | number | boolean | null | undefined,\n): boolean {\n if (left === undefined || right === undefined) {\n return false;\n }\n\n if (op === 'eq') return left === right;\n if (op === 'ne') return left !== right;\n\n if (left === null || right === null) {\n return false;\n }\n\n if (typeof left !== typeof right) {\n return false;\n }\n\n if (\n (typeof left !== 'number' && typeof left !== 'string') ||\n (typeof right !== 'number' && typeof right !== 'string')\n ) {\n return false;\n }\n\n switch (op) {\n case 'gt':\n return left > right;\n case 'gte':\n return left >= right;\n case 'lt':\n return left < right;\n case 'lte':\n return left <= right;\n default:\n return false;\n }\n}\n\nexport function evaluateCondition(\n condition: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n depth: number = 1,\n): boolean {\n if (depth > MAX_CONDITION_DEPTH) {\n return false;\n }\n\n if (typeof condition === 'boolean') {\n return condition;\n }\n\n if (isRef(condition)) {\n return resolveRef(condition.$ref, state, locals) === true;\n }\n\n if (typeof condition !== 'object' || condition === null || Array.isArray(condition)) {\n return false;\n }\n\n const conditionObj = condition as Record<string, unknown>;\n switch (conditionObj.op) {\n case 'not':\n return !evaluateCondition(conditionObj.value, state, locals, depth + 1);\n case 'and':\n return Array.isArray(conditionObj.values) &&\n conditionObj.values.every((value) =>\n evaluateCondition(value, state, locals, depth + 1),\n );\n case 'or':\n return Array.isArray(conditionObj.values) &&\n conditionObj.values.some((value) =>\n evaluateCondition(value, state, locals, depth + 1),\n );\n case 'eq':\n case 'ne':\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte':\n return compareValues(\n conditionObj.op,\n resolveOperand(conditionObj.left as ConditionOperand, state, locals),\n resolveOperand(conditionObj.right as ConditionOperand, state, locals),\n );\n default:\n return false;\n }\n}\n","/**\n * @safe-ugc-ui/react — Style Mapper\n *\n * Maps StyleProps objects from the UGC card schema to React CSSProperties.\n * Uses a whitelist approach: only recognized style properties are mapped.\n *\n * Handles special cases:\n * - border / borderTop/Right/Bottom/Left objects -> CSS shorthand strings\n * - transform object -> CSS transform string\n * - boxShadow object(s) -> CSS box-shadow string\n * - textShadow object(s) -> CSS text-shadow string\n * - backgroundGradient object -> CSS background string\n * - fontFamily token -> CSS font-family stack\n * - Dynamic values ($ref) are resolved via state-resolver\n */\n\nimport type { CSSProperties } from 'react';\nimport { ALLOWED_TRANSITION_PROPERTIES } from '@safe-ugc-ui/types';\nimport { resolveValue } from './state-resolver.js';\n\n// ---------------------------------------------------------------------------\n// Whitelist of style properties that map directly to CSS\n// ---------------------------------------------------------------------------\n\nconst DIRECT_MAP_PROPS = [\n 'display', 'flexDirection', 'justifyContent', 'alignItems', 'alignSelf',\n 'flexWrap', 'flex', 'gap', 'width', 'height', 'aspectRatio', 'minWidth', 'maxWidth',\n 'minHeight', 'maxHeight', 'padding', 'paddingTop', 'paddingRight',\n 'paddingBottom', 'paddingLeft', 'margin', 'marginTop', 'marginRight',\n 'marginBottom', 'marginLeft', 'backgroundColor', 'color', 'borderRadius',\n 'borderRadiusTopLeft', 'borderRadiusTopRight',\n 'borderRadiusBottomLeft', 'borderRadiusBottomRight',\n 'fontSize', 'fontWeight', 'fontStyle', 'textAlign', 'textDecoration',\n 'lineHeight', 'letterSpacing', 'opacity', 'overflow', 'position',\n 'top', 'right', 'bottom', 'left', 'zIndex',\n 'gridTemplateColumns', 'gridTemplateRows', 'gridColumn', 'gridRow',\n 'objectFit', 'objectPosition',\n] as const;\n\nconst FONT_FAMILY_STACKS: Record<string, string> = {\n sans: 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\n serif: 'ui-serif, Georgia, Cambria, \"Times New Roman\", serif',\n mono: 'ui-monospace, \"SFMono-Regular\", \"SF Mono\", Consolas, \"Liberation Mono\", Menlo, monospace',\n rounded: '\"SF Pro Rounded\", ui-rounded, \"Hiragino Maru Gothic ProN\", \"Nunito\", system-ui, sans-serif',\n display: '\"Avenir Next\", \"Trebuchet MS\", \"Segoe UI\", sans-serif',\n handwriting: '\"Bradley Hand\", \"Segoe Print\", \"Comic Sans MS\", \"Marker Felt\", cursive',\n};\n\n// ---------------------------------------------------------------------------\n// Forbidden CSS functions (defense-in-depth)\n// ---------------------------------------------------------------------------\n\nconst FORBIDDEN_CSS_FUNCTIONS_LOWER = ['url(', 'var(', 'calc(', 'env(', 'expression('];\n\nfunction containsForbiddenCssFunction(value: string): boolean {\n const lower = value.toLowerCase();\n return FORBIDDEN_CSS_FUNCTIONS_LOWER.some(fn => lower.includes(fn));\n}\n\nfunction isValidAspectRatio(value: unknown): value is string | number {\n if (typeof value === 'number') {\n return Number.isFinite(value) && value > 0;\n }\n\n if (typeof value !== 'string' || containsForbiddenCssFunction(value)) {\n return false;\n }\n\n const match = value.match(/^\\s*([0-9]+(?:\\.[0-9]+)?)\\s*\\/\\s*([0-9]+(?:\\.[0-9]+)?)\\s*$/);\n if (!match) {\n return false;\n }\n\n return Number(match[1]) > 0 && Number(match[2]) > 0;\n}\n\n// ---------------------------------------------------------------------------\n// Helper: resolve a style value (may be literal or $ref)\n// ---------------------------------------------------------------------------\n\nfunction resolveStyleValue(\n value: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): unknown {\n return resolveValue(value, state, locals);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction resolveStructuredNumber(\n value: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): number | undefined {\n const resolved = resolveStyleValue(value, state, locals);\n return typeof resolved === 'number' ? resolved : undefined;\n}\n\nfunction resolveStructuredString(\n value: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): string | undefined {\n const resolved = resolveStyleValue(value, state, locals);\n if (typeof resolved !== 'string') {\n return undefined;\n }\n if (containsForbiddenCssFunction(resolved)) {\n return undefined;\n }\n return resolved;\n}\n\n// ---------------------------------------------------------------------------\n// Helper: transform object -> CSS transform string\n// ---------------------------------------------------------------------------\n\nfunction transformToCss(transform: Record<string, unknown>): string {\n const parts: string[] = [];\n\n if (transform.rotate !== undefined) {\n parts.push(`rotate(${String(transform.rotate)})`);\n }\n if (transform.scale !== undefined) {\n parts.push(`scale(${String(transform.scale)})`);\n }\n if (transform.translateX !== undefined) {\n parts.push(`translateX(${String(transform.translateX)}px)`);\n }\n if (transform.translateY !== undefined) {\n parts.push(`translateY(${String(transform.translateY)}px)`);\n }\n\n return parts.join(' ');\n}\n\nfunction resolveTransformObject(\n transform: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n if (!isRecord(transform)) {\n return undefined;\n }\n\n const resolved: Record<string, unknown> = {};\n const rotate = resolveStructuredString(transform.rotate, state, locals);\n const scale = resolveStructuredNumber(transform.scale, state, locals);\n const translateX = resolveStructuredNumber(transform.translateX, state, locals);\n const translateY = resolveStructuredNumber(transform.translateY, state, locals);\n\n if (rotate !== undefined) resolved.rotate = rotate;\n if (scale !== undefined) resolved.scale = scale;\n if (translateX !== undefined) resolved.translateX = translateX;\n if (translateY !== undefined) resolved.translateY = translateY;\n\n return resolved;\n}\n\n// ---------------------------------------------------------------------------\n// Helper: shadow object(s) -> CSS box-shadow string\n// ---------------------------------------------------------------------------\n\nfunction singleShadowToCss(shadow: Record<string, unknown>): string {\n const offsetX = shadow.offsetX ?? 0;\n const offsetY = shadow.offsetY ?? 0;\n const blur = shadow.blur ?? 0;\n const spread = shadow.spread ?? 0;\n const color = shadow.color ?? '#000';\n return `${String(offsetX)}px ${String(offsetY)}px ${String(blur)}px ${String(spread)}px ${String(color)}`;\n}\n\nfunction resolveShadowObject(\n shadow: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n if (!isRecord(shadow)) {\n return undefined;\n }\n\n const resolved: Record<string, unknown> = {};\n const offsetX = resolveStructuredNumber(shadow.offsetX, state, locals);\n const offsetY = resolveStructuredNumber(shadow.offsetY, state, locals);\n const blur = resolveStructuredNumber(shadow.blur, state, locals);\n const spread = resolveStructuredNumber(shadow.spread, state, locals);\n const color = resolveStructuredString(shadow.color, state, locals);\n\n if (offsetX !== undefined) resolved.offsetX = offsetX;\n if (offsetY !== undefined) resolved.offsetY = offsetY;\n if (blur !== undefined) resolved.blur = blur;\n if (spread !== undefined) resolved.spread = spread;\n if (color !== undefined) resolved.color = color;\n\n return resolved;\n}\n\nfunction shadowToCss(shadow: unknown): string {\n if (Array.isArray(shadow)) {\n return shadow\n .map((s) => singleShadowToCss(s as Record<string, unknown>))\n .join(', ');\n }\n if (typeof shadow === 'object' && shadow !== null) {\n return singleShadowToCss(shadow as Record<string, unknown>);\n }\n return '';\n}\n\nfunction resolveBoxShadowValue(\n shadow: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): unknown {\n if (Array.isArray(shadow)) {\n return shadow\n .map((item) => resolveShadowObject(item, state, locals))\n .filter((item): item is Record<string, unknown> => item !== undefined);\n }\n\n return resolveShadowObject(shadow, state, locals);\n}\n\n// ---------------------------------------------------------------------------\n// Helper: text shadow object(s) -> CSS text-shadow string\n// ---------------------------------------------------------------------------\n\nfunction singleTextShadowToCss(shadow: Record<string, unknown>): string {\n const offsetX = shadow.offsetX ?? 0;\n const offsetY = shadow.offsetY ?? 0;\n const blur = shadow.blur ?? 0;\n const color = shadow.color ?? '#000';\n return `${String(offsetX)}px ${String(offsetY)}px ${String(blur)}px ${String(color)}`;\n}\n\nfunction resolveTextShadowObject(\n shadow: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n if (!isRecord(shadow)) {\n return undefined;\n }\n\n const resolved: Record<string, unknown> = {};\n const offsetX = resolveStructuredNumber(shadow.offsetX, state, locals);\n const offsetY = resolveStructuredNumber(shadow.offsetY, state, locals);\n const blur = resolveStructuredNumber(shadow.blur, state, locals);\n const color = resolveStructuredString(shadow.color, state, locals);\n\n if (offsetX !== undefined) resolved.offsetX = offsetX;\n if (offsetY !== undefined) resolved.offsetY = offsetY;\n if (blur !== undefined) resolved.blur = blur;\n if (color !== undefined) resolved.color = color;\n\n return resolved;\n}\n\nfunction textShadowToCss(shadow: unknown): string {\n if (Array.isArray(shadow)) {\n return shadow\n .map((s) => singleTextShadowToCss(s as Record<string, unknown>))\n .join(', ');\n }\n if (typeof shadow === 'object' && shadow !== null) {\n return singleTextShadowToCss(shadow as Record<string, unknown>);\n }\n return '';\n}\n\nfunction resolveTextShadowValue(\n shadow: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): unknown {\n if (Array.isArray(shadow)) {\n return shadow\n .map((item) => resolveTextShadowObject(item, state, locals))\n .filter((item): item is Record<string, unknown> => item !== undefined);\n }\n\n return resolveTextShadowObject(shadow, state, locals);\n}\n\n// ---------------------------------------------------------------------------\n// Helper: gradient object -> CSS background string\n// ---------------------------------------------------------------------------\n\nfunction gradientToCss(gradient: Record<string, unknown>): string {\n const stops = gradient.stops as Array<{ color: string; position: string }> | undefined;\n if (!stops || !Array.isArray(stops)) return '';\n\n const stopsStr = stops\n .map((s) => `${s.color} ${s.position}`)\n .join(', ');\n\n if (gradient.type === 'radial') {\n return `radial-gradient(circle, ${stopsStr})`;\n }\n\n if (gradient.type === 'repeating-linear') {\n const direction = (gradient.direction as string) ?? '180deg';\n return `repeating-linear-gradient(${direction}, ${stopsStr})`;\n }\n\n // Default to linear\n const direction = (gradient.direction as string) ?? '180deg';\n return `linear-gradient(${direction}, ${stopsStr})`;\n}\n\nfunction resolveGradientStop(\n stop: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): { color: string; position: string } | undefined {\n if (!isRecord(stop)) {\n return undefined;\n }\n\n const color = resolveStructuredString(stop.color, state, locals);\n const position = resolveStructuredString(stop.position, state, locals);\n if (color === undefined || position === undefined) {\n return undefined;\n }\n\n return { color, position };\n}\n\nfunction resolveGradientObject(\n gradient: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n if (!isRecord(gradient) || !Array.isArray(gradient.stops)) {\n return undefined;\n }\n\n const resolvedStops = gradient.stops\n .map((stop) => resolveGradientStop(stop, state, locals))\n .filter((stop): stop is { color: string; position: string } => stop !== undefined);\n\n const resolved: Record<string, unknown> = {\n type: gradient.type,\n stops: resolvedStops,\n };\n\n const direction = resolveStructuredString(gradient.direction, state, locals);\n if (direction !== undefined) {\n resolved.direction = direction;\n }\n\n return resolved;\n}\n\n// ---------------------------------------------------------------------------\n// Helper: border object -> CSS border shorthand string\n// ---------------------------------------------------------------------------\n\nfunction borderToCss(border: Record<string, unknown>): string {\n const width = border.width ?? 0;\n const style = border.style ?? 'solid';\n const color = border.color ?? '#000';\n return `${String(width)}px ${String(style)} ${String(color)}`;\n}\n\nconst BORDER_STYLE_VALUES = new Set(['solid', 'dashed', 'dotted', 'none']);\n\nfunction resolveBorderObject(\n border: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n if (!isRecord(border)) {\n return undefined;\n }\n\n const resolved: Record<string, unknown> = {};\n const width = resolveStructuredNumber(border.width, state, locals);\n const style = resolveStructuredString(border.style, state, locals);\n const color = resolveStructuredString(border.color, state, locals);\n\n if (width !== undefined) resolved.width = width;\n if (style !== undefined && BORDER_STYLE_VALUES.has(style)) resolved.style = style;\n if (color !== undefined) resolved.color = color;\n\n return resolved;\n}\n\n// ---------------------------------------------------------------------------\n// Helper: map spec alignment values to CSS flexbox values\n// ---------------------------------------------------------------------------\n\nconst FLEX_ALIGNMENT_MAP: Record<string, string> = {\n start: 'flex-start',\n end: 'flex-end',\n};\n\nconst FLEX_ALIGNMENT_PROPS = new Set([\n 'justifyContent',\n 'alignItems',\n 'alignSelf',\n]);\n\n// ---------------------------------------------------------------------------\n// Main: mapStyle\n// ---------------------------------------------------------------------------\n\n/**\n * Convert a UGC StyleProps object to React CSSProperties.\n *\n * @param style - The style object from a UGC node (may contain $ref values)\n * @param state - The card state for resolving $ref values\n * @param locals - Optional local variables for resolving $ref values (checked before state)\n * @returns A React CSSProperties object\n */\nexport function mapStyle(\n style: Record<string, unknown> | undefined,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): CSSProperties {\n if (!style) return {};\n\n const css: CSSProperties = {};\n\n // Direct-mapped properties (resolve dynamic values)\n for (const prop of DIRECT_MAP_PROPS) {\n if (prop in style) {\n let resolved = resolveStyleValue(style[prop], state, locals);\n if (resolved !== undefined) {\n // Map spec alignment values (start/end) to CSS flexbox values\n if (\n FLEX_ALIGNMENT_PROPS.has(prop) &&\n typeof resolved === 'string' &&\n resolved in FLEX_ALIGNMENT_MAP\n ) {\n resolved = FLEX_ALIGNMENT_MAP[resolved];\n }\n // Block forbidden CSS functions (defense-in-depth)\n if (typeof resolved === 'string' && containsForbiddenCssFunction(resolved)) {\n continue;\n }\n if (prop === 'aspectRatio' && !isValidAspectRatio(resolved)) {\n continue;\n }\n (css as Record<string, unknown>)[prop] = resolved;\n }\n }\n }\n\n const fontFamilyToken = resolveStructuredString(style.fontFamily, state, locals);\n if (fontFamilyToken && fontFamilyToken in FONT_FAMILY_STACKS) {\n css.fontFamily = FONT_FAMILY_STACKS[fontFamilyToken];\n }\n\n // Transform object -> CSS transform string\n const resolvedTransform = resolveTransformObject(style.transform, state, locals);\n if (resolvedTransform) {\n const transformCss = transformToCss(resolvedTransform);\n if (transformCss) {\n css.transform = transformCss;\n }\n }\n\n // Border shorthand\n const resolvedBorder = resolveBorderObject(style.border, state, locals);\n if (resolvedBorder) {\n css.border = borderToCss(resolvedBorder);\n }\n\n // Border sides (borderTop, borderRight, borderBottom, borderLeft)\n for (const side of ['borderTop', 'borderRight', 'borderBottom', 'borderLeft'] as const) {\n const resolvedSide = resolveBorderObject(style[side], state, locals);\n if (resolvedSide) {\n (css as Record<string, unknown>)[side] = borderToCss(resolvedSide);\n }\n }\n\n // Box shadow\n if (style.boxShadow) {\n const resolvedShadow = resolveBoxShadowValue(style.boxShadow, state, locals);\n const shadowCss = shadowToCss(resolvedShadow);\n if (shadowCss) {\n css.boxShadow = shadowCss;\n }\n }\n\n // Text shadow\n if (style.textShadow) {\n const resolvedShadow = resolveTextShadowValue(style.textShadow, state, locals);\n const shadowCss = textShadowToCss(resolvedShadow);\n if (shadowCss) {\n css.textShadow = shadowCss;\n }\n }\n\n // Background gradient -> CSS background\n const resolvedGradient = resolveGradientObject(style.backgroundGradient, state, locals);\n if (resolvedGradient) {\n const backgroundCss = gradientToCss(resolvedGradient);\n if (backgroundCss) {\n css.background = backgroundCss;\n }\n }\n\n // Transition object(s) -> CSS transition string\n if (style.transition) {\n const transitionCss = mapTransition(style.transition);\n if (transitionCss) {\n css.transition = transitionCss;\n }\n }\n\n return css;\n}\n\n// ---------------------------------------------------------------------------\n// mapTransition — convert structured transition to CSS string\n// ---------------------------------------------------------------------------\n\n/**\n * Convert a TransitionDef or TransitionDef[] to a CSS transition string.\n *\n * @example\n * mapTransition({ property: 'height', duration: 600, easing: 'ease' })\n * // => \"height 600ms ease\"\n *\n * mapTransition([\n * { property: 'height', duration: 600, easing: 'ease' },\n * { property: 'opacity', duration: 300 },\n * ])\n * // => \"height 600ms ease, opacity 300ms\"\n */\n/**\n * Map from SUU camelCase property names to valid CSS property names.\n * Most properties are simple camelCase → kebab-case, but some\n * (like borderRadius directional variants) have non-obvious CSS names.\n */\nconst CSS_PROPERTY_NAME_MAP: Record<string, string> = {\n borderRadiusTopLeft: 'border-top-left-radius',\n borderRadiusTopRight: 'border-top-right-radius',\n borderRadiusBottomLeft: 'border-bottom-left-radius',\n borderRadiusBottomRight: 'border-bottom-right-radius',\n};\n\n/**\n * Convert a SUU camelCase property name to its CSS property name.\n * Uses explicit mapping for irregular names, falls back to\n * generic camelCase → kebab-case conversion.\n */\nfunction toCssPropertyName(prop: string): string {\n if (prop in CSS_PROPERTY_NAME_MAP) {\n return CSS_PROPERTY_NAME_MAP[prop];\n }\n return prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);\n}\n\nexport function mapTransition(transition: unknown): string | undefined {\n if (!transition) return undefined;\n\n const items = Array.isArray(transition) ? transition : [transition];\n const parts: string[] = [];\n\n for (const item of items) {\n if (typeof item !== 'object' || item === null) continue;\n const t = item as Record<string, unknown>;\n const property = t.property;\n const duration = t.duration;\n if (typeof property !== 'string' || typeof duration !== 'number') continue;\n\n // Defense-in-depth: reject properties not in whitelist at render time\n if (!(ALLOWED_TRANSITION_PROPERTIES as readonly string[]).includes(property)) {\n continue;\n }\n\n // Defense-in-depth: reject easing values that aren't in the allowed set\n const ALLOWED_EASINGS = new Set(['ease', 'linear', 'ease-in', 'ease-out', 'ease-in-out']);\n\n // Convert SUU property name to valid CSS property name\n const cssProperty = toCssPropertyName(property);\n\n let part = `${cssProperty} ${duration}ms`;\n if (typeof t.easing === 'string' && ALLOWED_EASINGS.has(t.easing)) {\n part += ` ${t.easing}`;\n }\n if (typeof t.delay === 'number' && t.delay > 0) {\n part += ` ${t.delay}ms`;\n }\n parts.push(part);\n }\n\n return parts.length > 0 ? parts.join(', ') : undefined;\n}\n","/**\n * @safe-ugc-ui/react — Asset Resolver\n *\n * Maps @assets/ paths used by card creators to actual platform-provided URLs.\n * Card authors reference assets as \"@assets/name.png\", and the hosting platform\n * provides a mapping to real URLs (blob:, data:, or CDN URLs).\n */\n\nexport type AssetMap = Record<string, string>;\n\n/**\n * Resolve an asset path to its actual URL.\n *\n * Card creators use `@assets/name.png`; the platform provides actual URLs.\n * Looks up by full path first, then by the key after `@assets/`.\n *\n * @param path - The asset path (e.g. \"@assets/avatar.png\")\n * @param assets - The asset map from the platform\n * @returns The resolved URL, or undefined if not found\n */\nexport function resolveAsset(\n path: string,\n assets: AssetMap,\n): string | undefined {\n if (!path.startsWith('@assets/')) return undefined;\n\n // Try full path match first\n if (path in assets) return assets[path];\n\n // Try key-only match (strip @assets/ prefix)\n const key = path.slice('@assets/'.length);\n if (key in assets) return assets[key];\n\n return undefined;\n}\n","/**\n * @safe-ugc-ui/react — useHoverStyle Hook\n *\n * Manages hover state for components with hoverStyle support.\n * Returns the merged style and mouse event handlers.\n *\n * When hoverStyle is not provided, returns base style with no handlers\n * to avoid unnecessary re-renders.\n */\n\nimport { useState, useMemo, type CSSProperties } from 'react';\n\ninterface UseHoverStyleResult {\n style: CSSProperties | undefined;\n onMouseEnter: (() => void) | undefined;\n onMouseLeave: (() => void) | undefined;\n}\n\nexport function useHoverStyle(\n baseStyle: CSSProperties | undefined,\n hoverStyle: CSSProperties | undefined,\n): UseHoverStyleResult {\n const [hovered, setHovered] = useState(false);\n\n const mergedStyle = useMemo(() => {\n if (!hoverStyle || !hovered) return baseStyle;\n return { ...baseStyle, ...hoverStyle };\n }, [baseStyle, hoverStyle, hovered]);\n\n if (!hoverStyle) {\n return { style: baseStyle, onMouseEnter: undefined, onMouseLeave: undefined };\n }\n\n return {\n style: mergedStyle,\n onMouseEnter: () => setHovered(true),\n onMouseLeave: () => setHovered(false),\n };\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface BoxProps {\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n children?: ReactNode;\n}\n\nexport function Box({ style, hoverStyle, children }: BoxProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return <div style={resolvedStyle} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>{children}</div>;\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface RowProps {\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n children?: ReactNode;\n}\n\nconst rowBase: CSSProperties = {\n display: 'flex',\n flexDirection: 'row',\n};\n\nexport function Row({ style, hoverStyle, children }: RowProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return <div style={{ ...rowBase, ...resolvedStyle }} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>{children}</div>;\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface ColumnProps {\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n children?: ReactNode;\n}\n\nconst columnBase: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n};\n\nexport function Column({ style, hoverStyle, children }: ColumnProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return <div style={{ ...columnBase, ...resolvedStyle }} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>{children}</div>;\n}\n","import type { CSSProperties } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface TextSpan {\n text: string;\n style?: CSSProperties;\n}\n\ninterface TextComponentProps {\n content?: string;\n spans?: TextSpan[];\n maxLines?: number;\n truncate?: 'ellipsis' | 'clip';\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nfunction getClampStyle(\n maxLines: number | undefined,\n truncate: 'ellipsis' | 'clip' | undefined,\n): CSSProperties | undefined {\n if (!maxLines || maxLines < 1) {\n return undefined;\n }\n\n if (maxLines === 1) {\n return {\n display: 'inline-block',\n maxWidth: '100%',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n textOverflow: truncate ?? 'ellipsis',\n };\n }\n\n return {\n display: '-webkit-box',\n maxWidth: '100%',\n overflow: 'hidden',\n textOverflow: truncate ?? 'ellipsis',\n WebkitBoxOrient: 'vertical',\n WebkitLineClamp: maxLines,\n };\n}\n\n/**\n * Renders text content safely. NEVER uses dangerouslySetInnerHTML.\n * All content is rendered as text nodes via React's built-in escaping.\n */\nexport function Text({\n content,\n spans,\n maxLines,\n truncate,\n style,\n hoverStyle,\n}: TextComponentProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n const clampStyle = getClampStyle(maxLines, truncate);\n const mergedStyle = clampStyle ? { ...resolvedStyle, ...clampStyle } : resolvedStyle;\n\n return (\n <span style={mergedStyle} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>\n {spans?.map((span, index) => (\n <span key={index} style={span.style}>\n {span.text}\n </span>\n )) ?? content ?? ''}\n </span>\n );\n}\n","import type { CSSProperties } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface ImageComponentProps {\n src: string;\n alt?: string;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\n/**\n * Renders an image. Defense-in-depth: at the render level, we still\n * verify the src is a safe URL scheme. In practice, src will already\n * be resolved by asset-resolver before reaching this component.\n *\n * Allowed schemes:\n * - blob: (platform-provided blob URLs)\n * - data: (inline data URIs)\n * - https: (resolved CDN URLs from asset-resolver)\n * - http: (resolved URLs — platform decides)\n *\n * If the src starts with @assets/, it was not resolved and we render nothing.\n */\nexport function Image({ src, alt, style, hoverStyle }: ImageComponentProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n\n // SECURITY: reject unresolved @assets/ paths (should already be resolved)\n if (src.startsWith('@assets/')) {\n return null;\n }\n\n return <img src={src} alt={alt ?? ''} style={resolvedStyle} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} />;\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface StackProps {\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n children?: ReactNode;\n}\n\nconst stackBase: CSSProperties = {\n position: 'relative',\n};\n\nexport function Stack({ style, hoverStyle, children }: StackProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return <div style={{ ...stackBase, ...resolvedStyle }} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>{children}</div>;\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface GridProps {\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n children?: ReactNode;\n}\n\nconst gridBase: CSSProperties = {\n display: 'grid',\n};\n\nexport function Grid({ style, hoverStyle, children }: GridProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return <div style={{ ...gridBase, ...resolvedStyle }} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>{children}</div>;\n}\n","import type { CSSProperties } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface SpacerProps {\n size?: number | string;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nexport function Spacer({ size, style, hoverStyle }: SpacerProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return <div style={{ width: size, height: size, flexShrink: 0, ...resolvedStyle }} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} />;\n}\n","import type { CSSProperties } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface DividerProps {\n color?: string;\n thickness?: number | string;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nfunction formatThickness(thickness: number | string | undefined): string {\n if (thickness == null) return '1px';\n if (typeof thickness === 'number') return `${thickness}px`;\n // Numeric string (e.g. \"2\") → append px\n if (/^-?\\d+(\\.\\d+)?$/.test(thickness)) return `${thickness}px`;\n // Already has unit (e.g. \"2px\", \"1rem\") → use as-is\n return thickness;\n}\n\nexport function Divider({ color, thickness, style, hoverStyle }: DividerProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return (\n <div\n style={{\n borderTop: `${formatThickness(thickness)} solid ${color ?? '#e0e0e0'}`,\n width: '100%',\n ...resolvedStyle,\n }}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n />\n );\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface IconProps {\n name: string;\n size?: number | string;\n color?: string;\n iconResolver?: (name: string) => ReactNode;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nexport function Icon({ name, size, color, iconResolver, style, hoverStyle }: IconProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n\n if (!iconResolver) {\n return null;\n }\n\n return (\n <span\n style={{\n fontSize: size,\n color,\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n ...resolvedStyle,\n }}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {iconResolver(name)}\n </span>\n );\n}\n","import type { CSSProperties } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface ProgressBarProps {\n value: number;\n max: number;\n color?: string;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nexport function ProgressBar({ value, max, color, style, hoverStyle }: ProgressBarProps) {\n const percentage = max <= 0 ? 0 : Math.min(100, Math.max(0, (value / max) * 100));\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n\n return (\n <div\n style={{\n backgroundColor: '#e0e0e0',\n borderRadius: 4,\n overflow: 'hidden',\n ...resolvedStyle,\n }}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n <div\n style={{\n width: `${percentage}%`,\n backgroundColor: color ?? '#4caf50',\n height: 8,\n }}\n />\n </div>\n );\n}\n","import type { CSSProperties } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface AvatarProps {\n src: string;\n alt?: string;\n size?: number | string;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nexport function Avatar({ src, alt, size, style, hoverStyle }: AvatarProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return (\n <img\n src={src}\n alt={alt ?? ''}\n style={{\n width: size ?? 40,\n height: size ?? 40,\n borderRadius: '50%',\n objectFit: 'cover',\n ...resolvedStyle,\n }}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n />\n );\n}\n","import type { CSSProperties } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface BadgeProps {\n label: string;\n color?: string;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nexport function Badge({ label, color, style, hoverStyle }: BadgeProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return (\n <span\n style={{\n display: 'inline-block',\n padding: '2px 8px',\n borderRadius: 12,\n backgroundColor: color ?? '#e0e0e0',\n fontSize: 12,\n ...resolvedStyle,\n }}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {label}\n </span>\n );\n}\n","import type { CSSProperties } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface ChipProps {\n label: string;\n color?: string;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nexport function Chip({ label, color, style, hoverStyle }: ChipProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return (\n <span\n style={{\n display: 'inline-block',\n padding: '4px 12px',\n borderRadius: 16,\n border: `1px solid ${color ?? '#e0e0e0'}`,\n fontSize: 14,\n ...resolvedStyle,\n }}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {label}\n </span>\n );\n}\n","import type { CSSProperties } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface ButtonProps {\n label: string;\n action: string;\n onAction?: (type: string, actionId: string) => void;\n disabled?: boolean;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nexport function Button({ label, action, onAction, disabled, style, hoverStyle }: ButtonProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return (\n <button\n disabled={disabled}\n onClick={() => onAction?.('button', action)}\n style={{\n padding: '8px 16px',\n borderRadius: 6,\n border: '1px solid #ccc',\n cursor: disabled ? 'default' : 'pointer',\n ...resolvedStyle,\n }}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {label}\n </button>\n );\n}\n","import type { CSSProperties } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface ToggleProps {\n value: boolean;\n onToggle: string;\n onAction?: (type: string, actionId: string, payload?: unknown) => void;\n disabled?: boolean;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nexport function Toggle({ value, onToggle, onAction, disabled, style, hoverStyle }: ToggleProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return (\n <button\n disabled={disabled}\n onClick={() => onAction?.('toggle', onToggle, { value: !value })}\n style={{\n padding: '6px 16px',\n borderRadius: 12,\n border: '1px solid #ccc',\n backgroundColor: value ? '#4caf50' : '#e0e0e0',\n color: value ? '#fff' : '#333',\n cursor: disabled ? 'default' : 'pointer',\n ...resolvedStyle,\n }}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {value ? 'ON' : 'OFF'}\n </button>\n );\n}\n","import { useId, useState, type CSSProperties, type ReactNode } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface AccordionItem {\n id: string;\n label: string;\n content?: ReactNode;\n disabled?: boolean;\n}\n\ninterface AccordionProps {\n items: AccordionItem[];\n allowMultiple?: boolean;\n defaultExpanded?: string[];\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nfunction getInitialExpandedIds(\n items: AccordionItem[],\n defaultExpanded: string[] | undefined,\n allowMultiple: boolean,\n): string[] {\n const enabledIds = new Set(\n items.filter((item) => item.disabled !== true).map((item) => item.id),\n );\n const initial = (defaultExpanded ?? []).filter((id) => enabledIds.has(id));\n return allowMultiple ? initial : initial.slice(0, 1);\n}\n\nexport function Accordion({\n items,\n allowMultiple = false,\n defaultExpanded,\n style,\n hoverStyle,\n}: AccordionProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n const [expandedIds, setExpandedIds] = useState<string[]>(\n () => getInitialExpandedIds(items, defaultExpanded, allowMultiple),\n );\n const baseId = useId();\n\n const expandedSet = new Set(expandedIds);\n\n const toggleItem = (itemId: string, disabled: boolean | undefined) => {\n if (disabled) {\n return;\n }\n\n setExpandedIds((current) => {\n const currentSet = new Set(current);\n if (allowMultiple) {\n if (currentSet.has(itemId)) {\n currentSet.delete(itemId);\n } else {\n currentSet.add(itemId);\n }\n return [...currentSet];\n }\n\n return currentSet.has(itemId) ? [] : [itemId];\n });\n };\n\n return (\n <div style={resolvedStyle} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>\n {items.map((item) => {\n const expanded = expandedSet.has(item.id);\n const buttonId = `${baseId}-${item.id}-button`;\n const panelId = `${baseId}-${item.id}-panel`;\n\n return (\n <div\n key={item.id}\n style={{\n borderTop: '1px solid rgba(148, 163, 184, 0.25)',\n }}\n >\n <button\n id={buttonId}\n type=\"button\"\n aria-expanded={expanded}\n aria-controls={panelId}\n disabled={item.disabled}\n onClick={() => toggleItem(item.id, item.disabled)}\n style={{\n width: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '12px 0',\n background: 'transparent',\n border: 'none',\n color: 'inherit',\n textAlign: 'left',\n cursor: item.disabled ? 'default' : 'pointer',\n opacity: item.disabled ? 0.5 : 1,\n }}\n >\n <span>{item.label}</span>\n <span aria-hidden=\"true\">{expanded ? '-' : '+'}</span>\n </button>\n {expanded ? (\n <div\n id={panelId}\n role=\"region\"\n aria-labelledby={buttonId}\n style={{ paddingBottom: 12 }}\n >\n {item.content}\n </div>\n ) : null}\n </div>\n );\n })}\n </div>\n );\n}\n","import {\n useEffect,\n useId,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type MutableRefObject,\n type ReactNode,\n} from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface TabsItem {\n id: string;\n label: string;\n content?: ReactNode;\n disabled?: boolean;\n}\n\ninterface TabsProps {\n tabs: TabsItem[];\n defaultTab?: string;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nfunction getEnabledTabIds(tabs: TabsItem[]): string[] {\n return tabs.filter((tab) => tab.disabled !== true).map((tab) => tab.id);\n}\n\nfunction getInitialSelectedTab(\n tabs: TabsItem[],\n defaultTab: string | undefined,\n): string | undefined {\n const enabledIds = getEnabledTabIds(tabs);\n if (enabledIds.length === 0) {\n return undefined;\n }\n\n if (defaultTab && enabledIds.includes(defaultTab)) {\n return defaultTab;\n }\n\n return enabledIds[0];\n}\n\nfunction getNextEnabledIndex(\n tabs: TabsItem[],\n startIndex: number,\n direction: 1 | -1,\n): number {\n for (let offset = 1; offset <= tabs.length; offset++) {\n const nextIndex =\n (startIndex + direction * offset + tabs.length) % tabs.length;\n if (tabs[nextIndex]?.disabled !== true) {\n return nextIndex;\n }\n }\n\n return startIndex;\n}\n\nfunction focusTab(\n buttonRefs: MutableRefObject<Array<HTMLButtonElement | null>>,\n index: number,\n): void {\n buttonRefs.current[index]?.focus();\n}\n\nexport function Tabs({\n tabs,\n defaultTab,\n style,\n hoverStyle,\n}: TabsProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n const [selectedTab, setSelectedTab] = useState<string | undefined>(\n () => getInitialSelectedTab(tabs, defaultTab),\n );\n const baseId = useId();\n const buttonRefs = useRef<Array<HTMLButtonElement | null>>([]);\n\n useEffect(() => {\n setSelectedTab((current) => {\n const enabledIds = getEnabledTabIds(tabs);\n if (enabledIds.length === 0) {\n return undefined;\n }\n\n if (current && enabledIds.includes(current)) {\n return current;\n }\n\n if (defaultTab && enabledIds.includes(defaultTab)) {\n return defaultTab;\n }\n\n return enabledIds[0];\n });\n }, [tabs, defaultTab]);\n\n const selectedItem =\n tabs.find((tab) => tab.id === selectedTab && tab.disabled !== true) ??\n tabs.find((tab) => tab.disabled !== true);\n\n const activateTab = (index: number, focus = false) => {\n const tab = tabs[index];\n if (!tab || tab.disabled) {\n return;\n }\n\n setSelectedTab(tab.id);\n if (focus) {\n focusTab(buttonRefs, index);\n }\n };\n\n const onTabKeyDown = (\n event: KeyboardEvent<HTMLButtonElement>,\n index: number,\n ) => {\n switch (event.key) {\n case 'ArrowRight':\n case 'ArrowDown': {\n event.preventDefault();\n activateTab(getNextEnabledIndex(tabs, index, 1), true);\n break;\n }\n\n case 'ArrowLeft':\n case 'ArrowUp': {\n event.preventDefault();\n activateTab(getNextEnabledIndex(tabs, index, -1), true);\n break;\n }\n\n case 'Home': {\n event.preventDefault();\n const firstEnabledIndex = tabs.findIndex((tab) => tab.disabled !== true);\n if (firstEnabledIndex >= 0) {\n activateTab(firstEnabledIndex, true);\n }\n break;\n }\n\n case 'End': {\n event.preventDefault();\n const lastEnabledIndex = [...tabs]\n .map((tab, currentIndex) => ({ tab, currentIndex }))\n .reverse()\n .find(({ tab }) => tab.disabled !== true);\n if (lastEnabledIndex) {\n activateTab(lastEnabledIndex.currentIndex, true);\n }\n break;\n }\n\n default:\n break;\n }\n };\n\n return (\n <div style={resolvedStyle} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>\n <div\n role=\"tablist\"\n aria-orientation=\"horizontal\"\n style={{\n display: 'flex',\n gap: 8,\n borderBottom: '1px solid rgba(148, 163, 184, 0.25)',\n paddingBottom: 8,\n }}\n >\n {tabs.map((tab, index) => {\n const selected = selectedItem?.id === tab.id;\n const tabId = `${baseId}-${tab.id}-tab`;\n const panelId = `${baseId}-${tab.id}-panel`;\n\n return (\n <button\n key={tab.id}\n ref={(element) => {\n buttonRefs.current[index] = element;\n }}\n id={tabId}\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n aria-controls={panelId}\n disabled={tab.disabled}\n tabIndex={selected ? 0 : -1}\n onClick={() => activateTab(index)}\n onKeyDown={(event) => onTabKeyDown(event, index)}\n style={{\n padding: '8px 12px',\n borderRadius: 8,\n border: 'none',\n background: selected ? 'rgba(148, 163, 184, 0.16)' : 'transparent',\n color: 'inherit',\n cursor: tab.disabled ? 'default' : 'pointer',\n opacity: tab.disabled ? 0.5 : 1,\n fontWeight: selected ? 600 : 400,\n }}\n >\n {tab.label}\n </button>\n );\n })}\n </div>\n {selectedItem ? (\n <div\n id={`${baseId}-${selectedItem.id}-panel`}\n role=\"tabpanel\"\n aria-labelledby={`${baseId}-${selectedItem.id}-tab`}\n style={{ paddingTop: 12 }}\n >\n {selectedItem.content}\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":["useEffect","useMemo","useState","UGCContainer","direction","jsx","jsx","jsx","jsx","jsx","jsx","jsx","jsx","jsx","jsx","jsx","jsx","jsx","jsx","jsx","jsx","useState","jsx","useState","useId","useState","jsx","jsxs","useState","useId","jsx","_","jsx","containerStyle","useState","useMemo","useEffect"]}
|
|
1
|
+
{"version":3,"sources":["../src/UGCRenderer.tsx","../src/UGCContainer.tsx","../src/node-renderer.tsx","../src/state-resolver.ts","../src/condition-resolver.ts","../src/style-mapper.ts","../src/asset-resolver.ts","../src/hooks/useHoverStyle.ts","../src/components/Box.tsx","../src/components/Row.tsx","../src/components/Column.tsx","../src/components/Text.tsx","../src/components/Image.tsx","../src/components/Stack.tsx","../src/components/Grid.tsx","../src/components/Spacer.tsx","../src/components/Divider.tsx","../src/components/Icon.tsx","../src/components/ProgressBar.tsx","../src/components/Avatar.tsx","../src/components/Badge.tsx","../src/components/Chip.tsx","../src/components/Button.tsx","../src/components/Toggle.tsx","../src/components/Accordion.tsx","../src/components/Tabs.tsx"],"sourcesContent":["/**\n * @safe-ugc-ui/react --- UGC Renderer\n *\n * Top-level component that validates and renders a UGC card.\n *\n * Pipeline:\n * 1. Accept a card (UGCCard object or raw JSON string)\n * 2. Validate via @safe-ugc-ui/validator\n * 3. If invalid, render nothing (or optional error fallback)\n * 4. If valid, wrap in UGCContainer and render the view tree\n *\n * Props:\n * - card: UGCCard object or raw JSON string\n * - viewName: Name of the view to render (defaults to first view)\n * - assets: Mapping of asset keys to actual URLs\n * - state: Optional state override (merged with card.state)\n * - onError: Optional error callback\n * - iconResolver: Optional callback to resolve icon names to ReactNode\n * - onAction: Optional callback for Button/Toggle actions\n */\n\nimport { useEffect, useMemo, useState } from 'react';\nimport type { CSSProperties, ReactNode } from 'react';\nimport { validate, validateRaw } from '@safe-ugc-ui/validator';\nimport {\n COMPACT_BREAKPOINT_MAX_WIDTH,\n MEDIUM_BREAKPOINT_MAX_WIDTH,\n type UGCCard,\n} from '@safe-ugc-ui/types';\n\nimport { UGCContainer } from './UGCContainer.js';\nimport { renderTree } from './node-renderer.js';\nimport type { AssetMap } from './asset-resolver.js';\n\n// ---------------------------------------------------------------------------\n// Props\n// ---------------------------------------------------------------------------\n\nexport interface UGCRendererProps {\n /** The UGC card to render --- either a parsed object or a raw JSON string. */\n card: UGCCard | string;\n\n /** Name of the view to render. Defaults to the first view in the card. */\n viewName?: string;\n\n /** Asset map: keys are asset identifiers, values are resolved URLs. */\n assets?: AssetMap;\n\n /** Optional state override. Merged on top of the card's own state. */\n state?: Record<string, unknown>;\n\n /** Optional CSS style for the outer container. */\n containerStyle?: CSSProperties;\n\n /** Optional callback invoked when validation fails or runtime limits are hit. */\n onError?: (errors: Array<{ code: string; message: string; path: string }>) => void;\n\n /** Optional callback to resolve icon names to React elements. */\n iconResolver?: (name: string) => ReactNode;\n\n /** Optional callback for Button/Toggle interaction actions. */\n onAction?: (type: string, actionId: string, payload?: unknown) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * Top-level UGC card renderer.\n *\n * Validates the card, then renders the specified view inside a secure\n * UGCContainer. Returns null if validation fails.\n */\nexport function UGCRenderer({\n card,\n viewName,\n assets = {},\n state: stateOverride,\n containerStyle,\n onError,\n iconResolver,\n onAction,\n}: UGCRendererProps) {\n const [containerElement, setContainerElement] = useState<HTMLDivElement | null>(null);\n const [containerWidth, setContainerWidth] = useState<number | null>(\n typeof window === 'undefined' ? null : window.innerWidth,\n );\n\n const result = useMemo(() => {\n // 1. Validate\n const validationResult =\n typeof card === 'string' ? validateRaw(card) : validate(card);\n\n if (!validationResult.valid) {\n return { valid: false as const, errors: validationResult.errors };\n }\n\n // 2. Parse card object\n const cardObj: UGCCard =\n typeof card === 'string'\n ? (JSON.parse(card) as UGCCard)\n : card;\n\n // 3. Determine which view to render\n const views = cardObj.views;\n const viewKeys = Object.keys(views);\n const selectedView = viewName && viewName in views\n ? viewName\n : viewKeys[0];\n\n if (!selectedView || !(selectedView in views)) {\n return { valid: false as const, errors: [] };\n }\n\n // 4. Merge state\n const mergedState: Record<string, unknown> = {\n ...(cardObj.state ?? {}),\n ...(stateOverride ?? {}),\n };\n\n // 5. Extract card-level styles\n const cardStyles = cardObj.styles as Record<string, Record<string, unknown>> | undefined;\n const fragments = cardObj.fragments as Record<string, unknown> | undefined;\n\n return {\n valid: true as const,\n rootNode: views[selectedView],\n state: mergedState,\n cardStyles,\n fragments,\n };\n }, [card, viewName, stateOverride]);\n\n useEffect(() => {\n if (!containerElement) {\n return;\n }\n\n const updateWidth = (nextWidth?: number) => {\n if (typeof nextWidth === 'number' && Number.isFinite(nextWidth)) {\n setContainerWidth(nextWidth);\n return;\n }\n setContainerWidth(containerElement.getBoundingClientRect().width);\n };\n\n updateWidth();\n\n if (typeof ResizeObserver === 'function') {\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0];\n updateWidth(entry?.contentRect?.width);\n });\n observer.observe(containerElement);\n return () => observer.disconnect();\n }\n\n const handleResize = () => updateWidth();\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, [containerElement]);\n\n const responsive = useMemo(\n () => ({\n medium:\n containerWidth != null &&\n containerWidth <= MEDIUM_BREAKPOINT_MAX_WIDTH,\n compact:\n containerWidth != null &&\n containerWidth <= COMPACT_BREAKPOINT_MAX_WIDTH,\n }),\n [containerWidth],\n );\n\n // Handle invalid cards\n if (!result.valid) {\n if (onError && result.errors.length > 0) {\n onError(result.errors);\n }\n return null;\n }\n\n // Render the view tree inside the secure container\n return (\n <UGCContainer ref={setContainerElement} style={containerStyle}>\n {renderTree(\n result.rootNode,\n result.state,\n assets,\n result.cardStyles,\n iconResolver,\n onAction,\n onError,\n responsive,\n result.fragments,\n )}\n </UGCContainer>\n );\n}\n","/**\n * @safe-ugc-ui/react — UGC Container\n *\n * Wrapper component that provides security isolation for UGC content.\n *\n * CSS isolation features:\n * - overflow: hidden — prevents content from escaping bounds\n * - isolation: isolate — creates a new stacking context\n * - contain: content — limits layout/paint/style to this subtree\n * - position: relative — establishes positioning context for children\n */\n\nimport { forwardRef } from 'react';\nimport type { CSSProperties, ReactNode } from 'react';\n\ninterface UGCContainerProps {\n children?: ReactNode;\n style?: CSSProperties;\n}\n\nconst containerStyle: CSSProperties = {\n overflow: 'hidden',\n isolation: 'isolate',\n contain: 'content',\n position: 'relative',\n};\n\n/**\n * Security isolation wrapper for UGC content.\n * All UGC card renderings should be wrapped in this container.\n */\nexport const UGCContainer = forwardRef<HTMLDivElement, UGCContainerProps>(\n function UGCContainer({ children, style }, ref) {\n const mergedStyle: CSSProperties = style\n ? { ...containerStyle, ...style }\n : containerStyle;\n\n return <div ref={ref} style={mergedStyle}>{children}</div>;\n },\n);\n","/**\n * @safe-ugc-ui/react --- Node Renderer\n *\n * Recursive renderer that maps UGC node types to React components.\n * Supports all currently implemented component types, for-loop rendering, style reference merge,\n * and runtime limits pre-check.\n *\n * For each node:\n * 1. Pre-check runtime limits (node count, style bytes, overflow, text bytes)\n * 2. Merge $style with inline styles (including hoverStyle.$style)\n * 3. Resolve $ref values in node fields using state-resolver (with locals)\n * 4. Map style fields to React CSSProperties using style-mapper\n * 5. Resolve asset paths for Image/Avatar src using asset-resolver\n * 6. Render the appropriate component\n * 7. Recursively render children (arrays and for-loops)\n */\n\nimport type { CSSProperties, ReactNode } from 'react';\nimport {\n MAX_NODE_COUNT,\n MAX_LOOP_ITERATIONS,\n TEXT_CONTENT_TOTAL_MAX_BYTES,\n STYLE_OBJECTS_TOTAL_MAX_BYTES,\n MAX_OVERFLOW_AUTO_COUNT,\n} from '@safe-ugc-ui/types';\n\nimport { resolveRef, resolveTextValue, resolveValue } from './state-resolver.js';\nimport { evaluateCondition } from './condition-resolver.js';\nimport { mapStyle } from './style-mapper.js';\nimport { resolveAsset } from './asset-resolver.js';\nimport type { AssetMap } from './asset-resolver.js';\nimport { Box } from './components/Box.js';\nimport { Row } from './components/Row.js';\nimport { Column } from './components/Column.js';\nimport { Text } from './components/Text.js';\nimport { Image } from './components/Image.js';\nimport { Stack } from './components/Stack.js';\nimport { Grid } from './components/Grid.js';\nimport { Spacer } from './components/Spacer.js';\nimport { Divider } from './components/Divider.js';\nimport { Icon } from './components/Icon.js';\nimport { ProgressBar } from './components/ProgressBar.js';\nimport { Avatar } from './components/Avatar.js';\nimport { Badge } from './components/Badge.js';\nimport { Chip } from './components/Chip.js';\nimport { Button } from './components/Button.js';\nimport { Toggle } from './components/Toggle.js';\nimport { Accordion } from './components/Accordion.js';\nimport { Tabs } from './components/Tabs.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * A generic UGC node shape. We use Record<string, unknown> for flexibility\n * since the validator has already verified the structure before rendering.\n */\ninterface UGCNodeLike {\n type: string;\n style?: Record<string, unknown>;\n responsive?: Record<string, unknown>;\n children?: unknown;\n [key: string]: unknown;\n}\n\ninterface ForLoopLike {\n for: string;\n in: string;\n template: unknown;\n}\n\ninterface FragmentUseLike {\n $use: string;\n $if?: unknown;\n [key: string]: unknown;\n}\n\ninterface ResolvedTextSpan {\n text: string;\n style?: CSSProperties;\n}\n\ninterface ResolvedTextPayload {\n content?: string;\n spans?: ResolvedTextSpan[];\n textBytes: number;\n styleBytes: number;\n}\n\ninterface ResolvedAccordionItem {\n id: string;\n label: string;\n content: ReactNode;\n disabled?: boolean;\n}\n\ninterface ResolvedTabsItem {\n id: string;\n label: string;\n content: ReactNode;\n disabled?: boolean;\n}\n\n/**\n * Runtime limits tracking object. Mutated during rendering to\n * track cumulative resource usage across the entire card.\n */\nexport interface RuntimeLimits {\n nodeCount: number;\n textBytes: number;\n styleBytes: number;\n overflowAutoCount: number;\n}\n\nexport interface RenderContext {\n state: Record<string, unknown>;\n assets: AssetMap;\n locals?: Record<string, unknown>;\n cardStyles?: Record<string, Record<string, unknown>>;\n fragments?: Record<string, unknown>;\n fragmentStack?: string[];\n iconResolver?: (name: string) => ReactNode;\n onAction?: (type: string, actionId: string, payload?: unknown) => void;\n onError?: (errors: Array<{ code: string; message: string; path: string }>) => void;\n limits: RuntimeLimits;\n responsive: {\n compact: boolean;\n medium: boolean;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction isForLoop(obj: unknown): obj is ForLoopLike {\n if (obj == null || typeof obj !== 'object' || Array.isArray(obj)) return false;\n const o = obj as Record<string, unknown>;\n return typeof o.for === 'string' && typeof o.in === 'string' && o.template != null;\n}\n\nfunction isFragmentUse(obj: unknown): obj is FragmentUseLike {\n if (obj == null || typeof obj !== 'object' || Array.isArray(obj)) return false;\n return typeof (obj as Record<string, unknown>).$use === 'string';\n}\n\nfunction utf8ByteLength(str: string): number {\n let bytes = 0;\n for (let i = 0; i < str.length; i++) {\n const code = str.charCodeAt(i);\n if (code <= 0x7f) {\n bytes += 1;\n } else if (code <= 0x7ff) {\n bytes += 2;\n } else if (code >= 0xd800 && code <= 0xdbff) {\n // Surrogate pair → 4 UTF-8 bytes\n bytes += 4;\n i++; // skip low surrogate\n } else {\n bytes += 3;\n }\n }\n return bytes;\n}\n\n/**\n * Merge a single style object from cardStyles with inline style overrides.\n * Returns the merged raw style (unresolved $ref values) and the style\n * without $style key.\n */\nfunction mergeNamedStyle(\n style: Record<string, unknown> | undefined,\n cardStyles: Record<string, Record<string, unknown>> | undefined,\n): Record<string, unknown> | undefined {\n if (!style) return undefined;\n\n const rawStyleName = style.$style;\n const styleName = typeof rawStyleName === 'string' ? rawStyleName.trim() : rawStyleName;\n if (!styleName || typeof styleName !== 'string' || !cardStyles) {\n // Return style without $style key if present\n if (style.$style !== undefined) {\n const { $style: _, ...rest } = style;\n return rest;\n }\n return style;\n }\n\n const baseStyle = cardStyles[styleName];\n if (!baseStyle) return style;\n\n // Merge: base from cardStyles, overridden by inline (excluding $style key)\n const { $style: _, ...inlineWithout$style } = style;\n return { ...baseStyle, ...inlineWithout$style };\n}\n\n/**\n * Merge node style and nested hoverStyle against cardStyles.\n */\nfunction mergeStyleWithCardStyles(\n nodeStyle: Record<string, unknown> | undefined,\n cardStyles: Record<string, Record<string, unknown>> | undefined,\n): Record<string, unknown> | undefined {\n const mergedStyle = mergeNamedStyle(nodeStyle, cardStyles);\n if (!mergedStyle) return undefined;\n\n const rawHoverStyle = mergedStyle.hoverStyle;\n if (typeof rawHoverStyle !== 'object' || rawHoverStyle === null || Array.isArray(rawHoverStyle)) {\n return mergedStyle;\n }\n\n const mergedHoverStyle = mergeNamedStyle(\n rawHoverStyle as Record<string, unknown>,\n cardStyles,\n );\n\n if (!mergedHoverStyle) {\n return mergedStyle;\n }\n\n return {\n ...mergedStyle,\n hoverStyle: mergedHoverStyle,\n };\n}\n\nfunction getResponsiveOverrideStyle(\n nodeResponsive: Record<string, unknown> | undefined,\n mode: 'medium' | 'compact',\n): Record<string, unknown> | undefined {\n if (!nodeResponsive) return undefined;\n\n const override = nodeResponsive[mode];\n if (\n override == null ||\n typeof override !== 'object' ||\n Array.isArray(override)\n ) {\n return undefined;\n }\n\n return override as Record<string, unknown>;\n}\n\nfunction mergeEffectiveNodeStyle(\n node: UGCNodeLike,\n ctx: RenderContext,\n): Record<string, unknown> | undefined {\n const baseStyle = mergeStyleWithCardStyles(node.style, ctx.cardStyles);\n const mediumOverride = mergeNamedStyle(\n getResponsiveOverrideStyle(node.responsive, 'medium'),\n ctx.cardStyles,\n );\n const compactOverride = mergeNamedStyle(\n getResponsiveOverrideStyle(node.responsive, 'compact'),\n ctx.cardStyles,\n );\n\n const {\n hoverStyle: _mediumHoverStyle,\n transition: _mediumTransition,\n ...mediumStyleWithoutInteractiveFields\n } = mediumOverride ?? {};\n\n const {\n hoverStyle: _compactHoverStyle,\n transition: _compactTransition,\n ...compactStyleWithoutInteractiveFields\n } = compactOverride ?? {};\n\n return {\n ...(baseStyle ?? {}),\n ...(ctx.responsive.medium ? mediumStyleWithoutInteractiveFields : {}),\n ...(ctx.responsive.compact ? compactStyleWithoutInteractiveFields : {}),\n };\n}\n\nfunction resolveTextPayload(\n node: UGCNodeLike,\n ctx: RenderContext,\n): ResolvedTextPayload {\n const rawSpans = Array.isArray(node.spans) ? node.spans : undefined;\n\n if (rawSpans) {\n const spans = rawSpans.map((span) => {\n const rawSpan = span as Record<string, unknown>;\n const spanStyle =\n rawSpan.style != null &&\n typeof rawSpan.style === 'object' &&\n !Array.isArray(rawSpan.style)\n ? rawSpan.style as Record<string, unknown>\n : undefined;\n\n return {\n text: resolveTextValue(rawSpan.text, ctx.state, ctx.locals),\n style: spanStyle ? mapStyle(spanStyle, ctx.state, ctx.locals) : undefined,\n rawStyleBytes: spanStyle ? utf8ByteLength(JSON.stringify(spanStyle)) : 0,\n };\n });\n\n const combinedText = spans.map((span) => span.text).join('');\n return {\n spans: spans.map(({ rawStyleBytes: _rawStyleBytes, ...span }) => span),\n textBytes: utf8ByteLength(combinedText),\n styleBytes: spans.reduce((sum, span) => sum + span.rawStyleBytes, 0),\n };\n }\n\n const content = resolveTextValue(node.content, ctx.state, ctx.locals);\n return {\n content,\n textBytes: utf8ByteLength(content),\n styleBytes: 0,\n };\n}\n\nfunction resolveAccordionItems(\n node: UGCNodeLike,\n ctx: RenderContext,\n key: string | number,\n): ResolvedAccordionItem[] {\n const rawItems = Array.isArray(node.items) ? node.items : [];\n\n return rawItems.flatMap((item, index) => {\n if (\n item == null ||\n typeof item !== 'object' ||\n Array.isArray(item)\n ) {\n return [];\n }\n\n const rawItem = item as Record<string, unknown>;\n const id = typeof rawItem.id === 'string' ? rawItem.id : `item-${index}`;\n const label = resolveTextValue(rawItem.label, ctx.state, ctx.locals);\n const resolvedDisabled = resolveValue(rawItem.disabled, ctx.state, ctx.locals);\n const disabled = typeof resolvedDisabled === 'boolean' ? resolvedDisabled : undefined;\n const content = renderNode(\n rawItem.content,\n ctx,\n `${String(key)}.items[${index}].content`,\n );\n\n return [{ id, label, content, disabled }];\n });\n}\n\nfunction resolveTabsItems(\n node: UGCNodeLike,\n ctx: RenderContext,\n key: string | number,\n): ResolvedTabsItem[] {\n const rawTabs = Array.isArray(node.tabs) ? node.tabs : [];\n\n return rawTabs.flatMap((tab, index) => {\n if (\n tab == null ||\n typeof tab !== 'object' ||\n Array.isArray(tab)\n ) {\n return [];\n }\n\n const rawTab = tab as Record<string, unknown>;\n const id = typeof rawTab.id === 'string' ? rawTab.id : `tab-${index}`;\n const label = resolveTextValue(rawTab.label, ctx.state, ctx.locals);\n const resolvedDisabled = resolveValue(rawTab.disabled, ctx.state, ctx.locals);\n const disabled = typeof resolvedDisabled === 'boolean' ? resolvedDisabled : undefined;\n const content = renderNode(\n rawTab.content,\n ctx,\n `${String(key)}.tabs[${index}].content`,\n );\n\n return [{ id, label, content, disabled }];\n });\n}\n\n// ---------------------------------------------------------------------------\n// renderNode --- recursive node renderer\n// ---------------------------------------------------------------------------\n\n/**\n * Render a single UGC node to a React element.\n *\n * Performs runtime limits pre-check BEFORE rendering to prevent\n * DOM pollution when limits are exceeded.\n */\nexport function renderNode(\n node: unknown,\n ctx: RenderContext,\n key: string | number,\n): ReactNode {\n if (node == null || typeof node !== 'object') return null;\n\n if (isFragmentUse(node)) {\n if ('$if' in node && !evaluateCondition(node.$if, ctx.state, ctx.locals)) {\n return null;\n }\n\n if ((ctx.fragmentStack?.length ?? 0) > 0) {\n ctx.onError?.([{\n code: 'RUNTIME_FRAGMENT_NESTED_USE',\n message: 'Fragments may not contain nested \"$use\" references',\n path: String(key),\n }]);\n return null;\n }\n\n if (ctx.fragmentStack?.includes(node.$use)) {\n ctx.onError?.([{\n code: 'RUNTIME_FRAGMENT_CYCLE',\n message: `Fragment \"${node.$use}\" recursively references itself`,\n path: String(key),\n }]);\n return null;\n }\n\n const fragment = ctx.fragments?.[node.$use];\n if (fragment == null) {\n ctx.onError?.([{\n code: 'RUNTIME_FRAGMENT_NOT_FOUND',\n message: `Fragment \"${node.$use}\" was not found`,\n path: String(key),\n }]);\n return null;\n }\n\n return renderNode(\n fragment,\n {\n ...ctx,\n fragmentStack: [...(ctx.fragmentStack ?? []), node.$use],\n },\n key,\n );\n }\n\n const n = node as UGCNodeLike;\n if (!n.type) return null;\n\n if ('$if' in n && !evaluateCondition(n.$if, ctx.state, ctx.locals)) {\n return null;\n }\n\n // --- Compute all deltas before committing any ---\n const mergedRawStyle = mergeEffectiveNodeStyle(n, ctx);\n const rv = (val: unknown) => resolveValue(val, ctx.state, ctx.locals);\n\n let styleDelta = mergedRawStyle ? utf8ByteLength(JSON.stringify(mergedRawStyle)) : 0;\n const overflowDelta = mergedRawStyle?.overflow === 'auto' ? 1 : 0;\n\n // Text payload: resolve once, reuse in render\n let resolvedTextPayload: ResolvedTextPayload | undefined;\n let textDelta = 0;\n if (n.type === 'Text') {\n resolvedTextPayload = resolveTextPayload(n, ctx);\n textDelta = resolvedTextPayload.textBytes;\n styleDelta += resolvedTextPayload.styleBytes;\n }\n\n // --- Batch limit checks (all-or-nothing) ---\n if (ctx.limits.nodeCount + 1 > MAX_NODE_COUNT) {\n ctx.onError?.([{ code: 'RUNTIME_NODE_LIMIT', message: `Node count exceeds maximum of ${MAX_NODE_COUNT}`, path: String(key) }]);\n return null;\n }\n if (ctx.limits.styleBytes + styleDelta > STYLE_OBJECTS_TOTAL_MAX_BYTES) {\n ctx.onError?.([{ code: 'RUNTIME_STYLE_LIMIT', message: `Style bytes exceed maximum of ${STYLE_OBJECTS_TOTAL_MAX_BYTES}`, path: String(key) }]);\n return null;\n }\n if (ctx.limits.overflowAutoCount + overflowDelta > MAX_OVERFLOW_AUTO_COUNT) {\n ctx.onError?.([{ code: 'RUNTIME_OVERFLOW_LIMIT', message: `Overflow auto count exceeds maximum of ${MAX_OVERFLOW_AUTO_COUNT}`, path: String(key) }]);\n return null;\n }\n if (ctx.limits.textBytes + textDelta > TEXT_CONTENT_TOTAL_MAX_BYTES) {\n ctx.onError?.([{ code: 'RUNTIME_TEXT_LIMIT', message: `Text bytes exceed maximum of ${TEXT_CONTENT_TOTAL_MAX_BYTES}`, path: String(key) }]);\n return null;\n }\n\n // --- All checks passed: commit all deltas at once ---\n ctx.limits.nodeCount += 1;\n ctx.limits.styleBytes += styleDelta;\n ctx.limits.overflowAutoCount += overflowDelta;\n ctx.limits.textBytes += textDelta;\n\n // Resolve style to CSS\n const cssStyle = mapStyle(mergedRawStyle, ctx.state, ctx.locals);\n\n // Resolve hoverStyle to CSS (if present)\n const rawHoverStyle = mergedRawStyle?.hoverStyle as Record<string, unknown> | undefined;\n const cssHoverStyle = rawHoverStyle ? mapStyle(rawHoverStyle, ctx.state, ctx.locals) : undefined;\n\n // Render children recursively\n const childElements = renderChildren(n.children, ctx);\n\n switch (n.type) {\n case 'Box':\n return <Box key={key} style={cssStyle} hoverStyle={cssHoverStyle}>{childElements}</Box>;\n\n case 'Row':\n return <Row key={key} style={cssStyle} hoverStyle={cssHoverStyle}>{childElements}</Row>;\n\n case 'Column':\n return <Column key={key} style={cssStyle} hoverStyle={cssHoverStyle}>{childElements}</Column>;\n\n case 'Stack':\n return <Stack key={key} style={cssStyle} hoverStyle={cssHoverStyle}>{childElements}</Stack>;\n\n case 'Grid':\n return <Grid key={key} style={cssStyle} hoverStyle={cssHoverStyle}>{childElements}</Grid>;\n\n case 'Text': {\n const maxLines = typeof n.maxLines === 'number' ? n.maxLines : undefined;\n const truncate = n.truncate === 'clip' || n.truncate === 'ellipsis'\n ? n.truncate\n : undefined;\n\n return (\n <Text\n key={key}\n content={resolvedTextPayload?.content}\n spans={resolvedTextPayload?.spans}\n maxLines={maxLines}\n truncate={truncate}\n style={cssStyle}\n hoverStyle={cssHoverStyle}\n />\n );\n }\n\n case 'Image': {\n let src = rv((n as Record<string, unknown>).src);\n if (typeof src !== 'string' || !src) return null;\n if (!src.startsWith('@assets/')) return null;\n if (src.includes('../')) return null;\n const resolved = resolveAsset(src, ctx.assets);\n if (!resolved) return null;\n if (typeof resolved === 'string' && resolved.trim().toLowerCase().startsWith('javascript:')) return null;\n const resolvedAlt = rv((n as Record<string, unknown>).alt);\n const alt = typeof resolvedAlt === 'string' ? resolvedAlt : undefined;\n return <Image key={key} src={resolved} alt={alt} style={cssStyle} hoverStyle={cssHoverStyle} />;\n }\n\n case 'Avatar': {\n let src = rv((n as Record<string, unknown>).src);\n if (typeof src !== 'string' || !src) return null;\n if (!src.startsWith('@assets/')) return null;\n if (src.includes('../')) return null;\n const resolved = resolveAsset(src, ctx.assets);\n if (!resolved) return null;\n if (typeof resolved === 'string' && resolved.trim().toLowerCase().startsWith('javascript:')) return null;\n const resolvedSize = rv((n as Record<string, unknown>).size);\n const size = typeof resolvedSize === 'number' || typeof resolvedSize === 'string'\n ? resolvedSize : undefined;\n return <Avatar key={key} src={resolved} size={size} style={cssStyle} hoverStyle={cssHoverStyle} />;\n }\n\n case 'Icon': {\n const resolvedName = rv((n as Record<string, unknown>).name);\n const name = typeof resolvedName === 'string' ? resolvedName : '';\n const resolvedSize = rv((n as Record<string, unknown>).size);\n const size = typeof resolvedSize === 'number' || typeof resolvedSize === 'string'\n ? resolvedSize : undefined;\n const resolvedColor = rv((n as Record<string, unknown>).color);\n const color = typeof resolvedColor === 'string' ? resolvedColor : undefined;\n return (\n <Icon\n key={key}\n name={name}\n size={size}\n color={color}\n iconResolver={ctx.iconResolver}\n style={cssStyle}\n hoverStyle={cssHoverStyle}\n />\n );\n }\n\n case 'Spacer': {\n const resolvedSize = rv((n as Record<string, unknown>).size);\n const size = typeof resolvedSize === 'number' || typeof resolvedSize === 'string'\n ? resolvedSize : undefined;\n return <Spacer key={key} size={size} style={cssStyle} hoverStyle={cssHoverStyle} />;\n }\n\n case 'Divider': {\n const resolvedColor = rv((n as Record<string, unknown>).color);\n const color = typeof resolvedColor === 'string' ? resolvedColor : undefined;\n const resolvedThickness = rv((n as Record<string, unknown>).thickness);\n const thickness = typeof resolvedThickness === 'number' || typeof resolvedThickness === 'string'\n ? resolvedThickness : undefined;\n return <Divider key={key} color={color} thickness={thickness} style={cssStyle} hoverStyle={cssHoverStyle} />;\n }\n\n case 'ProgressBar': {\n const resolvedValue = rv((n as Record<string, unknown>).value);\n const value = typeof resolvedValue === 'number' ? resolvedValue : 0;\n const resolvedMax = rv((n as Record<string, unknown>).max);\n const max = typeof resolvedMax === 'number' ? resolvedMax : 100;\n const resolvedColor = rv((n as Record<string, unknown>).color);\n const color = typeof resolvedColor === 'string' ? resolvedColor : undefined;\n return <ProgressBar key={key} value={value} max={max} color={color} style={cssStyle} hoverStyle={cssHoverStyle} />;\n }\n\n case 'Badge': {\n const label = resolveTextValue((n as Record<string, unknown>).label, ctx.state, ctx.locals);\n const resolvedColor = rv((n as Record<string, unknown>).color);\n const color = typeof resolvedColor === 'string' ? resolvedColor : undefined;\n return <Badge key={key} label={label} color={color} style={cssStyle} hoverStyle={cssHoverStyle} />;\n }\n\n case 'Chip': {\n const label = resolveTextValue((n as Record<string, unknown>).label, ctx.state, ctx.locals);\n const resolvedColor = rv((n as Record<string, unknown>).color);\n const color = typeof resolvedColor === 'string' ? resolvedColor : undefined;\n return <Chip key={key} label={label} color={color} style={cssStyle} hoverStyle={cssHoverStyle} />;\n }\n\n case 'Button': {\n const label = resolveTextValue((n as Record<string, unknown>).label, ctx.state, ctx.locals);\n const actionVal = (n as Record<string, unknown>).action;\n const action = typeof actionVal === 'string' ? actionVal : '';\n const resolvedDisabled = rv((n as Record<string, unknown>).disabled);\n const disabled = typeof resolvedDisabled === 'boolean' ? resolvedDisabled : undefined;\n return (\n <Button\n key={key}\n label={label}\n action={action}\n onAction={ctx.onAction}\n disabled={disabled}\n style={cssStyle}\n hoverStyle={cssHoverStyle}\n />\n );\n }\n\n case 'Toggle': {\n const resolvedValue = rv((n as Record<string, unknown>).value);\n const value = typeof resolvedValue === 'boolean' ? resolvedValue : false;\n const onToggleVal = (n as Record<string, unknown>).onToggle;\n const onToggle = typeof onToggleVal === 'string' ? onToggleVal : '';\n const resolvedDisabled = rv((n as Record<string, unknown>).disabled);\n const disabled = typeof resolvedDisabled === 'boolean' ? resolvedDisabled : undefined;\n return (\n <Toggle\n key={key}\n value={value}\n onToggle={onToggle}\n onAction={ctx.onAction}\n disabled={disabled}\n style={cssStyle}\n hoverStyle={cssHoverStyle}\n />\n );\n }\n\n case 'Accordion': {\n const items = resolveAccordionItems(n, ctx, key);\n const allowMultiple = (n as Record<string, unknown>).allowMultiple === true;\n const defaultExpanded = Array.isArray((n as Record<string, unknown>).defaultExpanded)\n ? ((n as Record<string, unknown>).defaultExpanded as unknown[]).filter(\n (value): value is string => typeof value === 'string',\n )\n : undefined;\n\n return (\n <Accordion\n key={key}\n items={items}\n allowMultiple={allowMultiple}\n defaultExpanded={defaultExpanded}\n style={cssStyle}\n hoverStyle={cssHoverStyle}\n />\n );\n }\n\n case 'Tabs': {\n const tabs = resolveTabsItems(n, ctx, key);\n const defaultTab = typeof (n as Record<string, unknown>).defaultTab === 'string'\n ? (n as Record<string, unknown>).defaultTab as string\n : undefined;\n\n return (\n <Tabs\n key={key}\n tabs={tabs}\n defaultTab={defaultTab}\n style={cssStyle}\n hoverStyle={cssHoverStyle}\n />\n );\n }\n\n default:\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// renderChildren --- handle children arrays and for-loops\n// ---------------------------------------------------------------------------\n\nfunction renderChildren(\n children: unknown,\n ctx: RenderContext,\n): ReactNode[] | null {\n if (!children) return null;\n\n // Array children\n if (Array.isArray(children)) {\n return children.map((child, index) => renderNode(child, ctx, index));\n }\n\n // For-loop children\n if (isForLoop(children)) {\n return renderForLoop(children, ctx);\n }\n\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// renderForLoop --- iterate over state array, render template per item\n// ---------------------------------------------------------------------------\n\nfunction renderForLoop(\n loop: ForLoopLike,\n ctx: RenderContext,\n): ReactNode[] {\n // Resolve the source array from state (or locals)\n const source = resolveRef(loop.in, ctx.state, ctx.locals);\n if (source === undefined) {\n // Soft skip: source not found (may be provided at runtime or optional)\n return [];\n }\n if (!Array.isArray(source)) {\n // Hard error: source exists but is not an array (type mismatch)\n ctx.onError?.([{\n code: 'RUNTIME_LOOP_SOURCE_INVALID',\n message: `Loop source \"${loop.in}\" is not an array (got ${typeof source})`,\n path: `for(${loop.for} in ${loop.in})`,\n }]);\n return [];\n }\n\n // Cap iterations\n const maxIter = Math.min(source.length, MAX_LOOP_ITERATIONS);\n const elements: ReactNode[] = [];\n\n for (let i = 0; i < maxIter; i++) {\n const item = source[i];\n const newLocals: Record<string, unknown> = {\n ...ctx.locals,\n [loop.for]: item,\n index: i,\n };\n const childCtx: RenderContext = { ...ctx, locals: newLocals };\n elements.push(renderNode(loop.template, childCtx, i));\n }\n\n return elements;\n}\n\n// ---------------------------------------------------------------------------\n// RenderTree --- render an entire view tree\n// ---------------------------------------------------------------------------\n\n/**\n * Render a full view tree starting from the root node.\n *\n * @param rootNode - The root node of the view\n * @param state - Card state for $ref resolution\n * @param assets - Asset map for @assets/ resolution\n * @param cardStyles - Optional card-level named styles\n * @param iconResolver - Optional icon resolver callback\n * @param onAction - Optional action callback for Button/Toggle\n * @param onError - Optional error callback\n * @returns A React element tree\n */\nexport function renderTree(\n rootNode: unknown,\n state: Record<string, unknown>,\n assets: AssetMap,\n cardStyles?: Record<string, Record<string, unknown>>,\n iconResolver?: (name: string) => ReactNode,\n onAction?: (type: string, actionId: string, payload?: unknown) => void,\n onError?: (errors: Array<{ code: string; message: string; path: string }>) => void,\n responsive: { compact: boolean; medium?: boolean } = { compact: false, medium: false },\n fragments?: Record<string, unknown>,\n): ReactNode {\n const limits: RuntimeLimits = {\n nodeCount: 0,\n textBytes: 0,\n styleBytes: 0,\n overflowAutoCount: 0,\n };\n const ctx: RenderContext = {\n state,\n assets,\n cardStyles,\n fragments,\n fragmentStack: [],\n iconResolver,\n onAction,\n onError,\n limits,\n responsive: {\n compact: responsive.compact,\n medium: responsive.medium ?? responsive.compact,\n },\n };\n return renderNode(rootNode, ctx, 'root');\n}\n","/**\n * @safe-ugc-ui/react — State Resolver\n *\n * Resolves $ref values from card state.\n *\n * - $ref: looks up a dotted path in the state object\n * - Literal values pass through unchanged\n */\n\nimport {\n PROTOTYPE_POLLUTION_SEGMENTS,\n} from '@safe-ugc-ui/types';\n\n/**\n * Parse a $ref path into individual segments.\n * Handles both dot notation and bracket notation:\n * \"items[0].name\" → [\"items\", \"0\", \"name\"]\n * \"data[2][3]\" → [\"data\", \"2\", \"3\"]\n * \"simple.path\" → [\"simple\", \"path\"]\n */\nfunction parseRefSegments(path: string): string[] {\n const segments: string[] = [];\n const dotParts = path.split('.');\n for (const part of dotParts) {\n if (!part) continue;\n // Check for bracket notation: extract base and indices\n const bracketPattern = /\\[(\\d+)\\]/g;\n let match: RegExpExecArray | null;\n\n // Find the base name (before first bracket)\n const firstBracket = part.indexOf('[');\n if (firstBracket > 0) {\n segments.push(part.slice(0, firstBracket));\n } else if (firstBracket === -1) {\n // No brackets at all\n segments.push(part);\n continue;\n }\n\n // Extract all bracket indices\n while ((match = bracketPattern.exec(part)) !== null) {\n segments.push(match[1]);\n }\n\n // If part starts with [ and no base was added\n if (firstBracket === 0) {\n // Edge case: segment is just [0] with no base name\n // This shouldn't normally happen but handle gracefully\n }\n }\n return segments;\n}\n\n/**\n * Resolves a $ref path (e.g. \"$hp\", \"$items[0].name\") from card state.\n *\n * - Strips leading '$' from the path\n * - Parses dot notation and bracket notation into segments\n * - Blocks __proto__, constructor, prototype segments\n * - Max depth of 5 segments per spec\n * - Returns undefined if path doesn't exist\n */\nexport function resolveRef(\n refPath: string,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): unknown {\n const path = refPath.startsWith('$') ? refPath.slice(1) : refPath;\n const segments = parseRefSegments(path);\n\n // Block prototype pollution\n for (const seg of segments) {\n if ((PROTOTYPE_POLLUTION_SEGMENTS as readonly string[]).includes(seg)) {\n return undefined;\n }\n }\n\n // Max depth check\n if (segments.length > 5) return undefined;\n\n // Choose starting object: locals first, then state\n const firstSeg = segments[0];\n let current: unknown;\n if (locals && firstSeg && firstSeg in locals) {\n current = locals;\n } else {\n current = state;\n }\n\n // Traverse\n for (const seg of segments) {\n if (current == null || typeof current !== 'object') return undefined;\n if (Array.isArray(current)) {\n const idx = parseInt(seg, 10);\n if (isNaN(idx)) return undefined;\n current = current[idx];\n } else {\n current = (current as Record<string, unknown>)[seg];\n }\n }\n return current;\n}\n\n/**\n * Resolve a value that might be a literal or $ref.\n * - Literal: return as-is\n * - $ref: resolve from state\n */\nexport function resolveValue(\n value: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): unknown {\n if (value == null) return value;\n if (typeof value === 'object' && value !== null) {\n if ('$ref' in value && typeof (value as Record<string, unknown>).$ref === 'string') {\n return resolveRef((value as Record<string, unknown>).$ref as string, state, locals);\n }\n }\n return value;\n}\n\nfunction stringifyTextScalar(value: unknown): string {\n if (value === undefined) return '';\n if (value === null) return 'null';\n if (\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ) {\n return String(value);\n }\n return '';\n}\n\nfunction isTemplateObject(\n value: unknown,\n): value is { $template: unknown[] } {\n return (\n typeof value === 'object' &&\n value !== null &&\n '$template' in value &&\n Array.isArray((value as Record<string, unknown>).$template)\n );\n}\n\nexport function resolveTemplate(\n value: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): string | undefined {\n if (!isTemplateObject(value)) {\n return undefined;\n }\n\n return value.$template\n .map((part) => stringifyTextScalar(resolveValue(part, state, locals)))\n .join('');\n}\n\nexport function resolveTextValue(\n value: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): string {\n const template = resolveTemplate(value, state, locals);\n if (template !== undefined) {\n return template;\n }\n\n return stringifyTextScalar(resolveValue(value, state, locals));\n}\n","/**\n * @safe-ugc-ui/react — Condition Resolver\n *\n * Evaluates the small declarative condition AST used by node-level `$if`.\n * This intentionally does not support general expressions or computation.\n */\n\nimport { MAX_CONDITION_DEPTH, isRef } from '@safe-ugc-ui/types';\nimport { resolveRef } from './state-resolver.js';\n\ntype ConditionOperand = string | number | boolean | null | { $ref: string };\n\nfunction resolveOperand(\n operand: ConditionOperand,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): string | number | boolean | null | undefined {\n if (isRef(operand)) {\n const resolved = resolveRef(operand.$ref, state, locals);\n if (\n resolved === null ||\n typeof resolved === 'string' ||\n typeof resolved === 'number' ||\n typeof resolved === 'boolean'\n ) {\n return resolved;\n }\n return undefined;\n }\n\n return operand;\n}\n\nfunction compareValues(\n op: string,\n left: string | number | boolean | null | undefined,\n right: string | number | boolean | null | undefined,\n): boolean {\n if (left === undefined || right === undefined) {\n return false;\n }\n\n if (op === 'eq') return left === right;\n if (op === 'ne') return left !== right;\n\n if (left === null || right === null) {\n return false;\n }\n\n if (typeof left !== typeof right) {\n return false;\n }\n\n if (\n (typeof left !== 'number' && typeof left !== 'string') ||\n (typeof right !== 'number' && typeof right !== 'string')\n ) {\n return false;\n }\n\n switch (op) {\n case 'gt':\n return left > right;\n case 'gte':\n return left >= right;\n case 'lt':\n return left < right;\n case 'lte':\n return left <= right;\n default:\n return false;\n }\n}\n\nexport function evaluateCondition(\n condition: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n depth: number = 1,\n): boolean {\n if (depth > MAX_CONDITION_DEPTH) {\n return false;\n }\n\n if (typeof condition === 'boolean') {\n return condition;\n }\n\n if (isRef(condition)) {\n return resolveRef(condition.$ref, state, locals) === true;\n }\n\n if (typeof condition !== 'object' || condition === null || Array.isArray(condition)) {\n return false;\n }\n\n const conditionObj = condition as Record<string, unknown>;\n switch (conditionObj.op) {\n case 'not':\n return !evaluateCondition(conditionObj.value, state, locals, depth + 1);\n case 'and':\n return Array.isArray(conditionObj.values) &&\n conditionObj.values.every((value) =>\n evaluateCondition(value, state, locals, depth + 1),\n );\n case 'or':\n return Array.isArray(conditionObj.values) &&\n conditionObj.values.some((value) =>\n evaluateCondition(value, state, locals, depth + 1),\n );\n case 'eq':\n case 'ne':\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte':\n return compareValues(\n conditionObj.op,\n resolveOperand(conditionObj.left as ConditionOperand, state, locals),\n resolveOperand(conditionObj.right as ConditionOperand, state, locals),\n );\n default:\n return false;\n }\n}\n","/**\n * @safe-ugc-ui/react — Style Mapper\n *\n * Maps StyleProps objects from the UGC card schema to React CSSProperties.\n * Uses a whitelist approach: only recognized style properties are mapped.\n *\n * Handles special cases:\n * - border / borderTop/Right/Bottom/Left objects -> CSS shorthand strings\n * - transform object -> CSS transform string\n * - boxShadow object(s) -> CSS box-shadow string\n * - textShadow object(s) -> CSS text-shadow string\n * - backgroundGradient object -> CSS background string\n * - fontFamily token -> CSS font-family stack\n * - Dynamic values ($ref) are resolved via state-resolver\n */\n\nimport type { CSSProperties } from 'react';\nimport { ALLOWED_TRANSITION_PROPERTIES } from '@safe-ugc-ui/types';\nimport { resolveValue } from './state-resolver.js';\n\n// ---------------------------------------------------------------------------\n// Whitelist of style properties that map directly to CSS\n// ---------------------------------------------------------------------------\n\nconst DIRECT_MAP_PROPS = [\n 'display', 'flexDirection', 'justifyContent', 'alignItems', 'alignSelf',\n 'flexWrap', 'flex', 'gap', 'width', 'height', 'aspectRatio', 'minWidth', 'maxWidth',\n 'minHeight', 'maxHeight', 'padding', 'paddingTop', 'paddingRight',\n 'paddingBottom', 'paddingLeft', 'margin', 'marginTop', 'marginRight',\n 'marginBottom', 'marginLeft', 'backgroundColor', 'color', 'borderRadius',\n 'borderRadiusTopLeft', 'borderRadiusTopRight',\n 'borderRadiusBottomLeft', 'borderRadiusBottomRight',\n 'fontSize', 'fontWeight', 'fontStyle', 'textAlign', 'textDecoration',\n 'lineHeight', 'letterSpacing', 'opacity', 'overflow', 'position',\n 'top', 'right', 'bottom', 'left', 'zIndex',\n 'gridTemplateColumns', 'gridTemplateRows', 'gridColumn', 'gridRow',\n 'objectFit', 'objectPosition',\n] as const;\n\nconst FONT_FAMILY_STACKS: Record<string, string> = {\n sans: 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\n serif: 'ui-serif, Georgia, Cambria, \"Times New Roman\", serif',\n mono: 'ui-monospace, \"SFMono-Regular\", \"SF Mono\", Consolas, \"Liberation Mono\", Menlo, monospace',\n rounded: '\"SF Pro Rounded\", ui-rounded, \"Hiragino Maru Gothic ProN\", \"Nunito\", system-ui, sans-serif',\n display: '\"Avenir Next\", \"Trebuchet MS\", \"Segoe UI\", sans-serif',\n handwriting: '\"Bradley Hand\", \"Segoe Print\", \"Comic Sans MS\", \"Marker Felt\", cursive',\n};\n\n// ---------------------------------------------------------------------------\n// Forbidden CSS functions (defense-in-depth)\n// ---------------------------------------------------------------------------\n\nconst FORBIDDEN_CSS_FUNCTIONS_LOWER = ['url(', 'var(', 'calc(', 'env(', 'expression('];\n\nfunction containsForbiddenCssFunction(value: string): boolean {\n const lower = value.toLowerCase();\n return FORBIDDEN_CSS_FUNCTIONS_LOWER.some(fn => lower.includes(fn));\n}\n\nfunction isValidAspectRatio(value: unknown): value is string | number {\n if (typeof value === 'number') {\n return Number.isFinite(value) && value > 0;\n }\n\n if (typeof value !== 'string' || containsForbiddenCssFunction(value)) {\n return false;\n }\n\n const match = value.match(/^\\s*([0-9]+(?:\\.[0-9]+)?)\\s*\\/\\s*([0-9]+(?:\\.[0-9]+)?)\\s*$/);\n if (!match) {\n return false;\n }\n\n return Number(match[1]) > 0 && Number(match[2]) > 0;\n}\n\n// ---------------------------------------------------------------------------\n// Helper: resolve a style value (may be literal or $ref)\n// ---------------------------------------------------------------------------\n\nfunction resolveStyleValue(\n value: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): unknown {\n return resolveValue(value, state, locals);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction resolveStructuredNumber(\n value: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): number | undefined {\n const resolved = resolveStyleValue(value, state, locals);\n return typeof resolved === 'number' ? resolved : undefined;\n}\n\nfunction resolveStructuredString(\n value: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): string | undefined {\n const resolved = resolveStyleValue(value, state, locals);\n if (typeof resolved !== 'string') {\n return undefined;\n }\n if (containsForbiddenCssFunction(resolved)) {\n return undefined;\n }\n return resolved;\n}\n\nfunction resolveStructuredLength(\n value: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): string | number | undefined {\n const resolved = resolveStyleValue(value, state, locals);\n if (typeof resolved === 'number') {\n return resolved;\n }\n if (typeof resolved === 'string' && !containsForbiddenCssFunction(resolved)) {\n return resolved;\n }\n return undefined;\n}\n\nfunction toCssLength(value: string | number): string {\n return typeof value === 'number' ? `${value}px` : value;\n}\n\n// ---------------------------------------------------------------------------\n// Helper: transform object -> CSS transform string\n// ---------------------------------------------------------------------------\n\nfunction transformToCss(transform: Record<string, unknown>): string {\n const parts: string[] = [];\n\n if (transform.rotate !== undefined) {\n parts.push(`rotate(${String(transform.rotate)})`);\n }\n if (transform.scale !== undefined) {\n parts.push(`scale(${String(transform.scale)})`);\n }\n if (transform.translateX !== undefined) {\n parts.push(`translateX(${String(transform.translateX)}px)`);\n }\n if (transform.translateY !== undefined) {\n parts.push(`translateY(${String(transform.translateY)}px)`);\n }\n\n return parts.join(' ');\n}\n\nfunction resolveTransformObject(\n transform: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n if (!isRecord(transform)) {\n return undefined;\n }\n\n const resolved: Record<string, unknown> = {};\n const rotate = resolveStructuredString(transform.rotate, state, locals);\n const scale = resolveStructuredNumber(transform.scale, state, locals);\n const translateX = resolveStructuredNumber(transform.translateX, state, locals);\n const translateY = resolveStructuredNumber(transform.translateY, state, locals);\n\n if (rotate !== undefined) resolved.rotate = rotate;\n if (scale !== undefined) resolved.scale = scale;\n if (translateX !== undefined) resolved.translateX = translateX;\n if (translateY !== undefined) resolved.translateY = translateY;\n\n return resolved;\n}\n\n// ---------------------------------------------------------------------------\n// Helper: shadow object(s) -> CSS box-shadow string\n// ---------------------------------------------------------------------------\n\nfunction singleShadowToCss(shadow: Record<string, unknown>): string {\n const offsetX = shadow.offsetX ?? 0;\n const offsetY = shadow.offsetY ?? 0;\n const blur = shadow.blur ?? 0;\n const spread = shadow.spread ?? 0;\n const color = shadow.color ?? '#000';\n return `${String(offsetX)}px ${String(offsetY)}px ${String(blur)}px ${String(spread)}px ${String(color)}`;\n}\n\nfunction resolveShadowObject(\n shadow: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n if (!isRecord(shadow)) {\n return undefined;\n }\n\n const resolved: Record<string, unknown> = {};\n const offsetX = resolveStructuredNumber(shadow.offsetX, state, locals);\n const offsetY = resolveStructuredNumber(shadow.offsetY, state, locals);\n const blur = resolveStructuredNumber(shadow.blur, state, locals);\n const spread = resolveStructuredNumber(shadow.spread, state, locals);\n const color = resolveStructuredString(shadow.color, state, locals);\n\n if (offsetX !== undefined) resolved.offsetX = offsetX;\n if (offsetY !== undefined) resolved.offsetY = offsetY;\n if (blur !== undefined) resolved.blur = blur;\n if (spread !== undefined) resolved.spread = spread;\n if (color !== undefined) resolved.color = color;\n\n return resolved;\n}\n\nfunction shadowToCss(shadow: unknown): string {\n if (Array.isArray(shadow)) {\n return shadow\n .map((s) => singleShadowToCss(s as Record<string, unknown>))\n .join(', ');\n }\n if (typeof shadow === 'object' && shadow !== null) {\n return singleShadowToCss(shadow as Record<string, unknown>);\n }\n return '';\n}\n\nfunction resolveBoxShadowValue(\n shadow: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): unknown {\n if (Array.isArray(shadow)) {\n return shadow\n .map((item) => resolveShadowObject(item, state, locals))\n .filter((item): item is Record<string, unknown> => item !== undefined);\n }\n\n return resolveShadowObject(shadow, state, locals);\n}\n\n// ---------------------------------------------------------------------------\n// Helper: text shadow object(s) -> CSS text-shadow string\n// ---------------------------------------------------------------------------\n\nfunction singleTextShadowToCss(shadow: Record<string, unknown>): string {\n const offsetX = shadow.offsetX ?? 0;\n const offsetY = shadow.offsetY ?? 0;\n const blur = shadow.blur ?? 0;\n const color = shadow.color ?? '#000';\n return `${String(offsetX)}px ${String(offsetY)}px ${String(blur)}px ${String(color)}`;\n}\n\nfunction resolveTextShadowObject(\n shadow: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n if (!isRecord(shadow)) {\n return undefined;\n }\n\n const resolved: Record<string, unknown> = {};\n const offsetX = resolveStructuredNumber(shadow.offsetX, state, locals);\n const offsetY = resolveStructuredNumber(shadow.offsetY, state, locals);\n const blur = resolveStructuredNumber(shadow.blur, state, locals);\n const color = resolveStructuredString(shadow.color, state, locals);\n\n if (offsetX !== undefined) resolved.offsetX = offsetX;\n if (offsetY !== undefined) resolved.offsetY = offsetY;\n if (blur !== undefined) resolved.blur = blur;\n if (color !== undefined) resolved.color = color;\n\n return resolved;\n}\n\nfunction textShadowToCss(shadow: unknown): string {\n if (Array.isArray(shadow)) {\n return shadow\n .map((s) => singleTextShadowToCss(s as Record<string, unknown>))\n .join(', ');\n }\n if (typeof shadow === 'object' && shadow !== null) {\n return singleTextShadowToCss(shadow as Record<string, unknown>);\n }\n return '';\n}\n\nfunction resolveTextShadowValue(\n shadow: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): unknown {\n if (Array.isArray(shadow)) {\n return shadow\n .map((item) => resolveTextShadowObject(item, state, locals))\n .filter((item): item is Record<string, unknown> => item !== undefined);\n }\n\n return resolveTextShadowObject(shadow, state, locals);\n}\n\n// ---------------------------------------------------------------------------\n// Helper: gradient object -> CSS background string\n// ---------------------------------------------------------------------------\n\nfunction gradientToCss(gradient: Record<string, unknown>): string {\n const stops = gradient.stops as Array<{ color: string; position: string }> | undefined;\n if (!stops || !Array.isArray(stops)) return '';\n\n const stopsStr = stops\n .map((s) => `${s.color} ${s.position}`)\n .join(', ');\n\n if (gradient.type === 'radial') {\n return `radial-gradient(circle, ${stopsStr})`;\n }\n\n if (gradient.type === 'repeating-linear') {\n const direction = (gradient.direction as string) ?? '180deg';\n return `repeating-linear-gradient(${direction}, ${stopsStr})`;\n }\n\n // Default to linear\n const direction = (gradient.direction as string) ?? '180deg';\n return `linear-gradient(${direction}, ${stopsStr})`;\n}\n\nfunction resolveGradientStop(\n stop: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): { color: string; position: string } | undefined {\n if (!isRecord(stop)) {\n return undefined;\n }\n\n const color = resolveStructuredString(stop.color, state, locals);\n const position = resolveStructuredString(stop.position, state, locals);\n if (color === undefined || position === undefined) {\n return undefined;\n }\n\n return { color, position };\n}\n\nfunction resolveGradientObject(\n gradient: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n if (!isRecord(gradient) || !Array.isArray(gradient.stops)) {\n return undefined;\n }\n\n const resolvedStops = gradient.stops\n .map((stop) => resolveGradientStop(stop, state, locals))\n .filter((stop): stop is { color: string; position: string } => stop !== undefined);\n\n const resolved: Record<string, unknown> = {\n type: gradient.type,\n stops: resolvedStops,\n };\n\n const direction = resolveStructuredString(gradient.direction, state, locals);\n if (direction !== undefined) {\n resolved.direction = direction;\n }\n\n return resolved;\n}\n\n// ---------------------------------------------------------------------------\n// Helper: border object -> CSS border shorthand string\n// ---------------------------------------------------------------------------\n\nfunction borderToCss(border: Record<string, unknown>): string {\n const width = border.width ?? 0;\n const style = border.style ?? 'solid';\n const color = border.color ?? '#000';\n return `${String(width)}px ${String(style)} ${String(color)}`;\n}\n\nconst BORDER_STYLE_VALUES = new Set(['solid', 'dashed', 'dotted', 'none']);\n\nfunction resolveBorderObject(\n border: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n if (!isRecord(border)) {\n return undefined;\n }\n\n const resolved: Record<string, unknown> = {};\n const width = resolveStructuredNumber(border.width, state, locals);\n const style = resolveStructuredString(border.style, state, locals);\n const color = resolveStructuredString(border.color, state, locals);\n\n if (width !== undefined) resolved.width = width;\n if (style !== undefined && BORDER_STYLE_VALUES.has(style)) resolved.style = style;\n if (color !== undefined) resolved.color = color;\n\n return resolved;\n}\n\nfunction clipPathToCss(clipPath: Record<string, unknown>): string {\n switch (clipPath.type) {\n case 'circle':\n return `circle(${toCssLength(clipPath.radius as string | number)})`;\n\n case 'ellipse':\n return `ellipse(${toCssLength(clipPath.rx as string | number)} ${toCssLength(clipPath.ry as string | number)})`;\n\n case 'inset': {\n const base = [\n toCssLength(clipPath.top as string | number),\n toCssLength(clipPath.right as string | number),\n toCssLength(clipPath.bottom as string | number),\n toCssLength(clipPath.left as string | number),\n ].join(' ');\n\n const round = clipPath.round;\n return round !== undefined\n ? `inset(${base} round ${toCssLength(round as string | number)})`\n : `inset(${base})`;\n }\n\n default:\n return '';\n }\n}\n\nfunction resolveClipPathObject(\n clipPath: unknown,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n if (!isRecord(clipPath) || typeof clipPath.type !== 'string') {\n return undefined;\n }\n\n switch (clipPath.type) {\n case 'circle': {\n const radius = resolveStructuredLength(clipPath.radius, state, locals);\n return radius !== undefined ? { type: 'circle', radius } : undefined;\n }\n\n case 'ellipse': {\n const rx = resolveStructuredLength(clipPath.rx, state, locals);\n const ry = resolveStructuredLength(clipPath.ry, state, locals);\n return rx !== undefined && ry !== undefined\n ? { type: 'ellipse', rx, ry }\n : undefined;\n }\n\n case 'inset': {\n const top = resolveStructuredLength(clipPath.top, state, locals);\n const right = resolveStructuredLength(clipPath.right, state, locals);\n const bottom = resolveStructuredLength(clipPath.bottom, state, locals);\n const left = resolveStructuredLength(clipPath.left, state, locals);\n const round = resolveStructuredLength(clipPath.round, state, locals);\n\n if (\n top === undefined ||\n right === undefined ||\n bottom === undefined ||\n left === undefined\n ) {\n return undefined;\n }\n\n return {\n type: 'inset',\n top,\n right,\n bottom,\n left,\n ...(round !== undefined ? { round } : {}),\n };\n }\n\n default:\n return undefined;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helper: map spec alignment values to CSS flexbox values\n// ---------------------------------------------------------------------------\n\nconst FLEX_ALIGNMENT_MAP: Record<string, string> = {\n start: 'flex-start',\n end: 'flex-end',\n};\n\nconst FLEX_ALIGNMENT_PROPS = new Set([\n 'justifyContent',\n 'alignItems',\n 'alignSelf',\n]);\n\n// ---------------------------------------------------------------------------\n// Main: mapStyle\n// ---------------------------------------------------------------------------\n\n/**\n * Convert a UGC StyleProps object to React CSSProperties.\n *\n * @param style - The style object from a UGC node (may contain $ref values)\n * @param state - The card state for resolving $ref values\n * @param locals - Optional local variables for resolving $ref values (checked before state)\n * @returns A React CSSProperties object\n */\nexport function mapStyle(\n style: Record<string, unknown> | undefined,\n state: Record<string, unknown>,\n locals?: Record<string, unknown>,\n): CSSProperties {\n if (!style) return {};\n\n const css: CSSProperties = {};\n\n // Direct-mapped properties (resolve dynamic values)\n for (const prop of DIRECT_MAP_PROPS) {\n if (prop in style) {\n let resolved = resolveStyleValue(style[prop], state, locals);\n if (resolved !== undefined) {\n // Map spec alignment values (start/end) to CSS flexbox values\n if (\n FLEX_ALIGNMENT_PROPS.has(prop) &&\n typeof resolved === 'string' &&\n resolved in FLEX_ALIGNMENT_MAP\n ) {\n resolved = FLEX_ALIGNMENT_MAP[resolved];\n }\n // Block forbidden CSS functions (defense-in-depth)\n if (typeof resolved === 'string' && containsForbiddenCssFunction(resolved)) {\n continue;\n }\n if (prop === 'aspectRatio' && !isValidAspectRatio(resolved)) {\n continue;\n }\n (css as Record<string, unknown>)[prop] = resolved;\n }\n }\n }\n\n const fontFamilyToken = resolveStructuredString(style.fontFamily, state, locals);\n if (fontFamilyToken && fontFamilyToken in FONT_FAMILY_STACKS) {\n css.fontFamily = FONT_FAMILY_STACKS[fontFamilyToken];\n }\n\n // Transform object -> CSS transform string\n const resolvedTransform = resolveTransformObject(style.transform, state, locals);\n if (resolvedTransform) {\n const transformCss = transformToCss(resolvedTransform);\n if (transformCss) {\n css.transform = transformCss;\n }\n }\n\n // Border shorthand\n const resolvedBorder = resolveBorderObject(style.border, state, locals);\n if (resolvedBorder) {\n css.border = borderToCss(resolvedBorder);\n }\n\n // Border sides (borderTop, borderRight, borderBottom, borderLeft)\n for (const side of ['borderTop', 'borderRight', 'borderBottom', 'borderLeft'] as const) {\n const resolvedSide = resolveBorderObject(style[side], state, locals);\n if (resolvedSide) {\n (css as Record<string, unknown>)[side] = borderToCss(resolvedSide);\n }\n }\n\n // Box shadow\n if (style.boxShadow) {\n const resolvedShadow = resolveBoxShadowValue(style.boxShadow, state, locals);\n const shadowCss = shadowToCss(resolvedShadow);\n if (shadowCss) {\n css.boxShadow = shadowCss;\n }\n }\n\n // Text shadow\n if (style.textShadow) {\n const resolvedShadow = resolveTextShadowValue(style.textShadow, state, locals);\n const shadowCss = textShadowToCss(resolvedShadow);\n if (shadowCss) {\n css.textShadow = shadowCss;\n }\n }\n\n // Background gradient -> CSS background\n const resolvedGradient = resolveGradientObject(style.backgroundGradient, state, locals);\n if (resolvedGradient) {\n const backgroundCss = gradientToCss(resolvedGradient);\n if (backgroundCss) {\n css.background = backgroundCss;\n }\n }\n\n // Transition object(s) -> CSS transition string\n if (style.transition) {\n const transitionCss = mapTransition(style.transition);\n if (transitionCss) {\n css.transition = transitionCss;\n }\n }\n\n const resolvedBackdropBlur = resolveStructuredNumber(style.backdropBlur, state, locals);\n if (\n resolvedBackdropBlur !== undefined &&\n Number.isFinite(resolvedBackdropBlur) &&\n resolvedBackdropBlur >= 0\n ) {\n (css as Record<string, unknown>).backdropFilter = `blur(${resolvedBackdropBlur}px)`;\n }\n\n const resolvedClipPath = resolveClipPathObject(style.clipPath, state, locals);\n if (resolvedClipPath) {\n const clipPathCss = clipPathToCss(resolvedClipPath);\n if (clipPathCss) {\n (css as Record<string, unknown>).clipPath = clipPathCss;\n }\n }\n\n return css;\n}\n\n// ---------------------------------------------------------------------------\n// mapTransition — convert structured transition to CSS string\n// ---------------------------------------------------------------------------\n\n/**\n * Convert a TransitionDef or TransitionDef[] to a CSS transition string.\n *\n * @example\n * mapTransition({ property: 'height', duration: 600, easing: 'ease' })\n * // => \"height 600ms ease\"\n *\n * mapTransition([\n * { property: 'height', duration: 600, easing: 'ease' },\n * { property: 'opacity', duration: 300 },\n * ])\n * // => \"height 600ms ease, opacity 300ms\"\n */\n/**\n * Map from SUU camelCase property names to valid CSS property names.\n * Most properties are simple camelCase → kebab-case, but some\n * (like borderRadius directional variants) have non-obvious CSS names.\n */\nconst CSS_PROPERTY_NAME_MAP: Record<string, string> = {\n borderRadiusTopLeft: 'border-top-left-radius',\n borderRadiusTopRight: 'border-top-right-radius',\n borderRadiusBottomLeft: 'border-bottom-left-radius',\n borderRadiusBottomRight: 'border-bottom-right-radius',\n};\n\n/**\n * Convert a SUU camelCase property name to its CSS property name.\n * Uses explicit mapping for irregular names, falls back to\n * generic camelCase → kebab-case conversion.\n */\nfunction toCssPropertyName(prop: string): string {\n if (prop in CSS_PROPERTY_NAME_MAP) {\n return CSS_PROPERTY_NAME_MAP[prop];\n }\n return prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);\n}\n\nexport function mapTransition(transition: unknown): string | undefined {\n if (!transition) return undefined;\n\n const items = Array.isArray(transition) ? transition : [transition];\n const parts: string[] = [];\n\n for (const item of items) {\n if (typeof item !== 'object' || item === null) continue;\n const t = item as Record<string, unknown>;\n const property = t.property;\n const duration = t.duration;\n if (typeof property !== 'string' || typeof duration !== 'number') continue;\n\n // Defense-in-depth: reject properties not in whitelist at render time\n if (!(ALLOWED_TRANSITION_PROPERTIES as readonly string[]).includes(property)) {\n continue;\n }\n\n // Defense-in-depth: reject easing values that aren't in the allowed set\n const ALLOWED_EASINGS = new Set(['ease', 'linear', 'ease-in', 'ease-out', 'ease-in-out']);\n\n // Convert SUU property name to valid CSS property name\n const cssProperty = toCssPropertyName(property);\n\n let part = `${cssProperty} ${duration}ms`;\n if (typeof t.easing === 'string' && ALLOWED_EASINGS.has(t.easing)) {\n part += ` ${t.easing}`;\n }\n if (typeof t.delay === 'number' && t.delay > 0) {\n part += ` ${t.delay}ms`;\n }\n parts.push(part);\n }\n\n return parts.length > 0 ? parts.join(', ') : undefined;\n}\n","/**\n * @safe-ugc-ui/react — Asset Resolver\n *\n * Maps @assets/ paths used by card creators to actual platform-provided URLs.\n * Card authors reference assets as \"@assets/name.png\", and the hosting platform\n * provides a mapping to real URLs (blob:, data:, or CDN URLs).\n */\n\nexport type AssetMap = Record<string, string>;\n\n/**\n * Resolve an asset path to its actual URL.\n *\n * Card creators use `@assets/name.png`; the platform provides actual URLs.\n * Looks up by full path first, then by the key after `@assets/`.\n *\n * @param path - The asset path (e.g. \"@assets/avatar.png\")\n * @param assets - The asset map from the platform\n * @returns The resolved URL, or undefined if not found\n */\nexport function resolveAsset(\n path: string,\n assets: AssetMap,\n): string | undefined {\n if (!path.startsWith('@assets/')) return undefined;\n\n // Try full path match first\n if (path in assets) return assets[path];\n\n // Try key-only match (strip @assets/ prefix)\n const key = path.slice('@assets/'.length);\n if (key in assets) return assets[key];\n\n return undefined;\n}\n","/**\n * @safe-ugc-ui/react — useHoverStyle Hook\n *\n * Manages hover state for components with hoverStyle support.\n * Returns the merged style and mouse event handlers.\n *\n * When hoverStyle is not provided, returns base style with no handlers\n * to avoid unnecessary re-renders.\n */\n\nimport { useState, useMemo, type CSSProperties } from 'react';\n\ninterface UseHoverStyleResult {\n style: CSSProperties | undefined;\n onMouseEnter: (() => void) | undefined;\n onMouseLeave: (() => void) | undefined;\n}\n\nexport function useHoverStyle(\n baseStyle: CSSProperties | undefined,\n hoverStyle: CSSProperties | undefined,\n): UseHoverStyleResult {\n const [hovered, setHovered] = useState(false);\n\n const mergedStyle = useMemo(() => {\n if (!hoverStyle || !hovered) return baseStyle;\n return { ...baseStyle, ...hoverStyle };\n }, [baseStyle, hoverStyle, hovered]);\n\n if (!hoverStyle) {\n return { style: baseStyle, onMouseEnter: undefined, onMouseLeave: undefined };\n }\n\n return {\n style: mergedStyle,\n onMouseEnter: () => setHovered(true),\n onMouseLeave: () => setHovered(false),\n };\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface BoxProps {\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n children?: ReactNode;\n}\n\nexport function Box({ style, hoverStyle, children }: BoxProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return <div style={resolvedStyle} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>{children}</div>;\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface RowProps {\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n children?: ReactNode;\n}\n\nconst rowBase: CSSProperties = {\n display: 'flex',\n flexDirection: 'row',\n};\n\nexport function Row({ style, hoverStyle, children }: RowProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return <div style={{ ...rowBase, ...resolvedStyle }} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>{children}</div>;\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface ColumnProps {\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n children?: ReactNode;\n}\n\nconst columnBase: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n};\n\nexport function Column({ style, hoverStyle, children }: ColumnProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return <div style={{ ...columnBase, ...resolvedStyle }} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>{children}</div>;\n}\n","import type { CSSProperties } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface TextSpan {\n text: string;\n style?: CSSProperties;\n}\n\ninterface TextComponentProps {\n content?: string;\n spans?: TextSpan[];\n maxLines?: number;\n truncate?: 'ellipsis' | 'clip';\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nfunction getClampStyle(\n maxLines: number | undefined,\n truncate: 'ellipsis' | 'clip' | undefined,\n): CSSProperties | undefined {\n if (!maxLines || maxLines < 1) {\n return undefined;\n }\n\n if (maxLines === 1) {\n return {\n display: 'inline-block',\n maxWidth: '100%',\n overflow: 'hidden',\n whiteSpace: 'nowrap',\n textOverflow: truncate ?? 'ellipsis',\n };\n }\n\n return {\n display: '-webkit-box',\n maxWidth: '100%',\n overflow: 'hidden',\n textOverflow: truncate ?? 'ellipsis',\n WebkitBoxOrient: 'vertical',\n WebkitLineClamp: maxLines,\n };\n}\n\n/**\n * Renders text content safely. NEVER uses dangerouslySetInnerHTML.\n * All content is rendered as text nodes via React's built-in escaping.\n */\nexport function Text({\n content,\n spans,\n maxLines,\n truncate,\n style,\n hoverStyle,\n}: TextComponentProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n const clampStyle = getClampStyle(maxLines, truncate);\n const mergedStyle = clampStyle ? { ...resolvedStyle, ...clampStyle } : resolvedStyle;\n\n return (\n <span style={mergedStyle} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>\n {spans?.map((span, index) => (\n <span key={index} style={span.style}>\n {span.text}\n </span>\n )) ?? content ?? ''}\n </span>\n );\n}\n","import type { CSSProperties } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface ImageComponentProps {\n src: string;\n alt?: string;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\n/**\n * Renders an image. Defense-in-depth: at the render level, we still\n * verify the src is a safe URL scheme. In practice, src will already\n * be resolved by asset-resolver before reaching this component.\n *\n * Allowed schemes:\n * - blob: (platform-provided blob URLs)\n * - data: (inline data URIs)\n * - https: (resolved CDN URLs from asset-resolver)\n * - http: (resolved URLs — platform decides)\n *\n * If the src starts with @assets/, it was not resolved and we render nothing.\n */\nexport function Image({ src, alt, style, hoverStyle }: ImageComponentProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n\n // SECURITY: reject unresolved @assets/ paths (should already be resolved)\n if (src.startsWith('@assets/')) {\n return null;\n }\n\n return <img src={src} alt={alt ?? ''} style={resolvedStyle} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} />;\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface StackProps {\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n children?: ReactNode;\n}\n\nconst stackBase: CSSProperties = {\n position: 'relative',\n};\n\nexport function Stack({ style, hoverStyle, children }: StackProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return <div style={{ ...stackBase, ...resolvedStyle }} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>{children}</div>;\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface GridProps {\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n children?: ReactNode;\n}\n\nconst gridBase: CSSProperties = {\n display: 'grid',\n};\n\nexport function Grid({ style, hoverStyle, children }: GridProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return <div style={{ ...gridBase, ...resolvedStyle }} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>{children}</div>;\n}\n","import type { CSSProperties } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface SpacerProps {\n size?: number | string;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nexport function Spacer({ size, style, hoverStyle }: SpacerProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return <div style={{ width: size, height: size, flexShrink: 0, ...resolvedStyle }} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} />;\n}\n","import type { CSSProperties } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface DividerProps {\n color?: string;\n thickness?: number | string;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nfunction formatThickness(thickness: number | string | undefined): string {\n if (thickness == null) return '1px';\n if (typeof thickness === 'number') return `${thickness}px`;\n // Numeric string (e.g. \"2\") → append px\n if (/^-?\\d+(\\.\\d+)?$/.test(thickness)) return `${thickness}px`;\n // Already has unit (e.g. \"2px\", \"1rem\") → use as-is\n return thickness;\n}\n\nexport function Divider({ color, thickness, style, hoverStyle }: DividerProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return (\n <div\n style={{\n borderTop: `${formatThickness(thickness)} solid ${color ?? '#e0e0e0'}`,\n width: '100%',\n ...resolvedStyle,\n }}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n />\n );\n}\n","import type { CSSProperties, ReactNode } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface IconProps {\n name: string;\n size?: number | string;\n color?: string;\n iconResolver?: (name: string) => ReactNode;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nexport function Icon({ name, size, color, iconResolver, style, hoverStyle }: IconProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n\n if (!iconResolver) {\n return null;\n }\n\n return (\n <span\n style={{\n fontSize: size,\n color,\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n ...resolvedStyle,\n }}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {iconResolver(name)}\n </span>\n );\n}\n","import type { CSSProperties } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface ProgressBarProps {\n value: number;\n max: number;\n color?: string;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nexport function ProgressBar({ value, max, color, style, hoverStyle }: ProgressBarProps) {\n const percentage = max <= 0 ? 0 : Math.min(100, Math.max(0, (value / max) * 100));\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n\n return (\n <div\n style={{\n backgroundColor: '#e0e0e0',\n borderRadius: 4,\n overflow: 'hidden',\n ...resolvedStyle,\n }}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n <div\n style={{\n width: `${percentage}%`,\n backgroundColor: color ?? '#4caf50',\n height: 8,\n }}\n />\n </div>\n );\n}\n","import type { CSSProperties } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface AvatarProps {\n src: string;\n alt?: string;\n size?: number | string;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nexport function Avatar({ src, alt, size, style, hoverStyle }: AvatarProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return (\n <img\n src={src}\n alt={alt ?? ''}\n style={{\n width: size ?? 40,\n height: size ?? 40,\n borderRadius: '50%',\n objectFit: 'cover',\n ...resolvedStyle,\n }}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n />\n );\n}\n","import type { CSSProperties } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface BadgeProps {\n label: string;\n color?: string;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nexport function Badge({ label, color, style, hoverStyle }: BadgeProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return (\n <span\n style={{\n display: 'inline-block',\n padding: '2px 8px',\n borderRadius: 12,\n backgroundColor: color ?? '#e0e0e0',\n fontSize: 12,\n ...resolvedStyle,\n }}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {label}\n </span>\n );\n}\n","import type { CSSProperties } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface ChipProps {\n label: string;\n color?: string;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nexport function Chip({ label, color, style, hoverStyle }: ChipProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return (\n <span\n style={{\n display: 'inline-block',\n padding: '4px 12px',\n borderRadius: 16,\n border: `1px solid ${color ?? '#e0e0e0'}`,\n fontSize: 14,\n ...resolvedStyle,\n }}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {label}\n </span>\n );\n}\n","import type { CSSProperties } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface ButtonProps {\n label: string;\n action: string;\n onAction?: (type: string, actionId: string) => void;\n disabled?: boolean;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nexport function Button({ label, action, onAction, disabled, style, hoverStyle }: ButtonProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return (\n <button\n disabled={disabled}\n onClick={() => onAction?.('button', action)}\n style={{\n padding: '8px 16px',\n borderRadius: 6,\n border: '1px solid #ccc',\n cursor: disabled ? 'default' : 'pointer',\n ...resolvedStyle,\n }}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {label}\n </button>\n );\n}\n","import type { CSSProperties } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface ToggleProps {\n value: boolean;\n onToggle: string;\n onAction?: (type: string, actionId: string, payload?: unknown) => void;\n disabled?: boolean;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nexport function Toggle({ value, onToggle, onAction, disabled, style, hoverStyle }: ToggleProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n return (\n <button\n disabled={disabled}\n onClick={() => onAction?.('toggle', onToggle, { value: !value })}\n style={{\n padding: '6px 16px',\n borderRadius: 12,\n border: '1px solid #ccc',\n backgroundColor: value ? '#4caf50' : '#e0e0e0',\n color: value ? '#fff' : '#333',\n cursor: disabled ? 'default' : 'pointer',\n ...resolvedStyle,\n }}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n {value ? 'ON' : 'OFF'}\n </button>\n );\n}\n","import { useId, useState, type CSSProperties, type ReactNode } from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface AccordionItem {\n id: string;\n label: string;\n content?: ReactNode;\n disabled?: boolean;\n}\n\ninterface AccordionProps {\n items: AccordionItem[];\n allowMultiple?: boolean;\n defaultExpanded?: string[];\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nfunction getInitialExpandedIds(\n items: AccordionItem[],\n defaultExpanded: string[] | undefined,\n allowMultiple: boolean,\n): string[] {\n const enabledIds = new Set(\n items.filter((item) => item.disabled !== true).map((item) => item.id),\n );\n const initial = (defaultExpanded ?? []).filter((id) => enabledIds.has(id));\n return allowMultiple ? initial : initial.slice(0, 1);\n}\n\nexport function Accordion({\n items,\n allowMultiple = false,\n defaultExpanded,\n style,\n hoverStyle,\n}: AccordionProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n const [expandedIds, setExpandedIds] = useState<string[]>(\n () => getInitialExpandedIds(items, defaultExpanded, allowMultiple),\n );\n const baseId = useId();\n\n const expandedSet = new Set(expandedIds);\n\n const toggleItem = (itemId: string, disabled: boolean | undefined) => {\n if (disabled) {\n return;\n }\n\n setExpandedIds((current) => {\n const currentSet = new Set(current);\n if (allowMultiple) {\n if (currentSet.has(itemId)) {\n currentSet.delete(itemId);\n } else {\n currentSet.add(itemId);\n }\n return [...currentSet];\n }\n\n return currentSet.has(itemId) ? [] : [itemId];\n });\n };\n\n return (\n <div style={resolvedStyle} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>\n {items.map((item) => {\n const expanded = expandedSet.has(item.id);\n const buttonId = `${baseId}-${item.id}-button`;\n const panelId = `${baseId}-${item.id}-panel`;\n\n return (\n <div\n key={item.id}\n style={{\n borderTop: '1px solid rgba(148, 163, 184, 0.25)',\n }}\n >\n <button\n id={buttonId}\n type=\"button\"\n aria-expanded={expanded}\n aria-controls={panelId}\n disabled={item.disabled}\n onClick={() => toggleItem(item.id, item.disabled)}\n style={{\n width: '100%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '12px 0',\n background: 'transparent',\n border: 'none',\n color: 'inherit',\n textAlign: 'left',\n cursor: item.disabled ? 'default' : 'pointer',\n opacity: item.disabled ? 0.5 : 1,\n }}\n >\n <span>{item.label}</span>\n <span aria-hidden=\"true\">{expanded ? '-' : '+'}</span>\n </button>\n {expanded ? (\n <div\n id={panelId}\n role=\"region\"\n aria-labelledby={buttonId}\n style={{ paddingBottom: 12 }}\n >\n {item.content}\n </div>\n ) : null}\n </div>\n );\n })}\n </div>\n );\n}\n","import {\n useEffect,\n useId,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n type MutableRefObject,\n type ReactNode,\n} from 'react';\nimport { useHoverStyle } from '../hooks/useHoverStyle.js';\n\ninterface TabsItem {\n id: string;\n label: string;\n content?: ReactNode;\n disabled?: boolean;\n}\n\ninterface TabsProps {\n tabs: TabsItem[];\n defaultTab?: string;\n style?: CSSProperties;\n hoverStyle?: CSSProperties;\n}\n\nfunction getEnabledTabIds(tabs: TabsItem[]): string[] {\n return tabs.filter((tab) => tab.disabled !== true).map((tab) => tab.id);\n}\n\nfunction getInitialSelectedTab(\n tabs: TabsItem[],\n defaultTab: string | undefined,\n): string | undefined {\n const enabledIds = getEnabledTabIds(tabs);\n if (enabledIds.length === 0) {\n return undefined;\n }\n\n if (defaultTab && enabledIds.includes(defaultTab)) {\n return defaultTab;\n }\n\n return enabledIds[0];\n}\n\nfunction getNextEnabledIndex(\n tabs: TabsItem[],\n startIndex: number,\n direction: 1 | -1,\n): number {\n for (let offset = 1; offset <= tabs.length; offset++) {\n const nextIndex =\n (startIndex + direction * offset + tabs.length) % tabs.length;\n if (tabs[nextIndex]?.disabled !== true) {\n return nextIndex;\n }\n }\n\n return startIndex;\n}\n\nfunction focusTab(\n buttonRefs: MutableRefObject<Array<HTMLButtonElement | null>>,\n index: number,\n): void {\n buttonRefs.current[index]?.focus();\n}\n\nexport function Tabs({\n tabs,\n defaultTab,\n style,\n hoverStyle,\n}: TabsProps) {\n const { style: resolvedStyle, onMouseEnter, onMouseLeave } = useHoverStyle(style, hoverStyle);\n const [selectedTab, setSelectedTab] = useState<string | undefined>(\n () => getInitialSelectedTab(tabs, defaultTab),\n );\n const baseId = useId();\n const buttonRefs = useRef<Array<HTMLButtonElement | null>>([]);\n\n useEffect(() => {\n setSelectedTab((current) => {\n const enabledIds = getEnabledTabIds(tabs);\n if (enabledIds.length === 0) {\n return undefined;\n }\n\n if (current && enabledIds.includes(current)) {\n return current;\n }\n\n if (defaultTab && enabledIds.includes(defaultTab)) {\n return defaultTab;\n }\n\n return enabledIds[0];\n });\n }, [tabs, defaultTab]);\n\n const selectedItem =\n tabs.find((tab) => tab.id === selectedTab && tab.disabled !== true) ??\n tabs.find((tab) => tab.disabled !== true);\n\n const activateTab = (index: number, focus = false) => {\n const tab = tabs[index];\n if (!tab || tab.disabled) {\n return;\n }\n\n setSelectedTab(tab.id);\n if (focus) {\n focusTab(buttonRefs, index);\n }\n };\n\n const onTabKeyDown = (\n event: KeyboardEvent<HTMLButtonElement>,\n index: number,\n ) => {\n switch (event.key) {\n case 'ArrowRight':\n case 'ArrowDown': {\n event.preventDefault();\n activateTab(getNextEnabledIndex(tabs, index, 1), true);\n break;\n }\n\n case 'ArrowLeft':\n case 'ArrowUp': {\n event.preventDefault();\n activateTab(getNextEnabledIndex(tabs, index, -1), true);\n break;\n }\n\n case 'Home': {\n event.preventDefault();\n const firstEnabledIndex = tabs.findIndex((tab) => tab.disabled !== true);\n if (firstEnabledIndex >= 0) {\n activateTab(firstEnabledIndex, true);\n }\n break;\n }\n\n case 'End': {\n event.preventDefault();\n const lastEnabledIndex = [...tabs]\n .map((tab, currentIndex) => ({ tab, currentIndex }))\n .reverse()\n .find(({ tab }) => tab.disabled !== true);\n if (lastEnabledIndex) {\n activateTab(lastEnabledIndex.currentIndex, true);\n }\n break;\n }\n\n default:\n break;\n }\n };\n\n return (\n <div style={resolvedStyle} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>\n <div\n role=\"tablist\"\n aria-orientation=\"horizontal\"\n style={{\n display: 'flex',\n gap: 8,\n borderBottom: '1px solid rgba(148, 163, 184, 0.25)',\n paddingBottom: 8,\n }}\n >\n {tabs.map((tab, index) => {\n const selected = selectedItem?.id === tab.id;\n const tabId = `${baseId}-${tab.id}-tab`;\n const panelId = `${baseId}-${tab.id}-panel`;\n\n return (\n <button\n key={tab.id}\n ref={(element) => {\n buttonRefs.current[index] = element;\n }}\n id={tabId}\n type=\"button\"\n role=\"tab\"\n aria-selected={selected}\n aria-controls={panelId}\n disabled={tab.disabled}\n tabIndex={selected ? 0 : -1}\n onClick={() => activateTab(index)}\n onKeyDown={(event) => onTabKeyDown(event, index)}\n style={{\n padding: '8px 12px',\n borderRadius: 8,\n border: 'none',\n background: selected ? 'rgba(148, 163, 184, 0.16)' : 'transparent',\n color: 'inherit',\n cursor: tab.disabled ? 'default' : 'pointer',\n opacity: tab.disabled ? 0.5 : 1,\n fontWeight: selected ? 600 : 400,\n }}\n >\n {tab.label}\n </button>\n );\n })}\n </div>\n {selectedItem ? (\n <div\n id={`${baseId}-${selectedItem.id}-panel`}\n role=\"tabpanel\"\n aria-labelledby={`${baseId}-${selectedItem.id}-tab`}\n style={{ paddingTop: 12 }}\n >\n {selectedItem.content}\n </div>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":["useEffect","useMemo","useState","UGCContainer","direction","jsx","jsx","jsx","jsx","jsx","jsx","jsx","jsx","jsx","jsx","jsx","jsx","jsx","jsx","jsx","jsx","useState","jsx","useState","useId","useState","jsx","jsxs","useState","useId","jsx","_","jsx","containerStyle","useState","useMemo","useEffect"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@safe-ugc-ui/react",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "React renderer for Safe UGC UI cards with sandboxed execution",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"dist"
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@safe-ugc-ui/
|
|
25
|
-
"@safe-ugc-ui/
|
|
24
|
+
"@safe-ugc-ui/validator": "1.1.0",
|
|
25
|
+
"@safe-ugc-ui/types": "1.1.0"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"react": "^18.0.0 || ^19.0.0",
|