@agent-native/core 0.80.10 → 0.80.11
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/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +6 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/agent/production-agent.ts +108 -15
- package/corpus/core/src/client/AssistantChat.tsx +123 -26
- package/corpus/core/src/client/sse-event-processor.ts +9 -0
- package/corpus/templates/assets/.agents/skills/image-generation/SKILL.md +9 -2
- package/corpus/templates/assets/AGENTS.md +4 -0
- package/corpus/templates/assets/actions/_tool-activity.ts +46 -0
- package/corpus/templates/assets/actions/generate-image-batch.ts +26 -5
- package/corpus/templates/assets/actions/generate-image.ts +118 -67
- package/corpus/templates/assets/actions/list-draft-assets.ts +50 -0
- package/corpus/templates/assets/actions/rerun-generation-run.ts +52 -31
- package/corpus/templates/assets/app/components/create/RecentDraftsSection.tsx +100 -0
- package/corpus/templates/assets/app/i18n/zh-TW.ts +7 -0
- package/corpus/templates/assets/app/i18n-data.ts +61 -0
- package/corpus/templates/assets/app/routes/_index.tsx +4 -0
- package/corpus/templates/assets/app/routes/library.tsx +145 -38
- package/corpus/templates/assets/changelog/2026-06-29-image-generation-can-now-render-requested-text-and-respect-b.md +6 -0
- package/corpus/templates/assets/changelog/2026-06-30-image-generation-no-longer-looks-stuck-while-the-provider-is-still-working.md +6 -0
- package/corpus/templates/assets/changelog/2026-06-30-tagged-presets-now-control-the-image-aspect-ratio.md +6 -0
- package/corpus/templates/assets/server/lib/generation.ts +135 -11
- package/corpus/templates/assets/shared/api.ts +4 -0
- package/corpus/templates/clips/actions/list-ai-requests.ts +60 -0
- package/corpus/templates/clips/app/hooks/use-auto-title.ts +24 -25
- package/corpus/templates/design/actions/apply-component-prop-edit.ts +13 -5
- package/corpus/templates/design/actions/apply-design-state.ts +17 -4
- package/corpus/templates/design/actions/apply-motion-edit.ts +9 -46
- package/corpus/templates/design/actions/delete-design.ts +20 -0
- package/corpus/templates/design/actions/get-component-details.ts +16 -7
- package/corpus/templates/design/actions/index-design-tokens.ts +8 -4
- package/corpus/templates/design/actions/list-design-states.ts +19 -1
- package/corpus/templates/design/actions/open-component-source.ts +7 -2
- package/corpus/templates/design/actions/preview-component-prop-edit.ts +32 -26
- package/corpus/templates/design/actions/preview-shader-fill.ts +9 -11
- package/corpus/templates/design/actions/run-design-audit.ts +21 -6
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +139 -14
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +20 -3
- package/corpus/templates/design/app/components/design/EditPanel.tsx +428 -31
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +110 -30
- package/corpus/templates/design/app/components/design/MotionDock.tsx +9 -0
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +1 -1
- package/corpus/templates/design/app/components/design/ReviewPanel.tsx +12 -5
- package/corpus/templates/design/app/components/design/StatesPanel.tsx +4 -2
- package/corpus/templates/design/app/components/design/TokensPanel.tsx +13 -8
- package/corpus/templates/design/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/design/app/i18n-data.ts +11 -0
- package/corpus/templates/design/app/pages/DesignEditor.tsx +684 -179
- package/corpus/templates/design/changelog/2026-06-30-design-token-edits-now-stay-visible-in-previews-and-token-li.md +6 -0
- package/corpus/templates/design/e2e/global-setup.ts +94 -2
- package/corpus/templates/design/shared/component-model.ts +35 -0
- package/corpus/templates/design/shared/motion-compiler.ts +79 -8
- package/corpus/templates/design/shared/resolve-tweaks.ts +32 -9
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +94 -10
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +14 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +115 -22
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +10 -0
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/package.json +1 -1
|
@@ -170,7 +170,7 @@ export interface LayersPanelProps {
|
|
|
170
170
|
canMoveLayer?: (intent: LayersPanelMoveIntent) => boolean;
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
interface FlatLayerRow {
|
|
173
|
+
export interface FlatLayerRow {
|
|
174
174
|
node: LayersPanelNode;
|
|
175
175
|
rowKey: string;
|
|
176
176
|
depth: number;
|
|
@@ -412,6 +412,65 @@ function collectAncestorIds(
|
|
|
412
412
|
return Array.from(ancestors);
|
|
413
413
|
}
|
|
414
414
|
|
|
415
|
+
export function getLayerSelectionAnchorFromExternalSelection(args: {
|
|
416
|
+
selectedIds: readonly string[];
|
|
417
|
+
selectableVisibleIds: readonly string[];
|
|
418
|
+
}): string | null {
|
|
419
|
+
const selectableVisibleIdSet = new Set(args.selectableVisibleIds);
|
|
420
|
+
return (
|
|
421
|
+
[...args.selectedIds]
|
|
422
|
+
.reverse()
|
|
423
|
+
.find((id) => selectableVisibleIdSet.has(id)) ?? null
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
export function getTreeOrderedLayerIds(
|
|
428
|
+
ids: readonly string[],
|
|
429
|
+
visibleRows: readonly FlatLayerRow[],
|
|
430
|
+
): string[] {
|
|
431
|
+
const idSet = new Set(ids.filter((id) => id && !id.startsWith("__")));
|
|
432
|
+
const orderedIds = visibleRows
|
|
433
|
+
.map((row) => row.node.id)
|
|
434
|
+
.filter((id) => idSet.has(id));
|
|
435
|
+
const orderedIdSet = new Set(orderedIds);
|
|
436
|
+
return [
|
|
437
|
+
...orderedIds,
|
|
438
|
+
...ids.filter((id) => id && !id.startsWith("__") && !orderedIdSet.has(id)),
|
|
439
|
+
];
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
export function getDraggedLayerIdsForRows(args: {
|
|
443
|
+
selectedIds: readonly string[];
|
|
444
|
+
nodeId: string;
|
|
445
|
+
visibleRows: readonly FlatLayerRow[];
|
|
446
|
+
}): string[] {
|
|
447
|
+
const rawDraggedIds = args.selectedIds.includes(args.nodeId)
|
|
448
|
+
? getTreeOrderedLayerIds(args.selectedIds, args.visibleRows)
|
|
449
|
+
: [args.nodeId];
|
|
450
|
+
const draggedIdSet = new Set(rawDraggedIds);
|
|
451
|
+
return rawDraggedIds.filter((id) => {
|
|
452
|
+
const rowForId = args.visibleRows.find((row) => row.node.id === id);
|
|
453
|
+
return !rowForId?.ancestorIds.some((ancestorId) =>
|
|
454
|
+
draggedIdSet.has(ancestorId),
|
|
455
|
+
);
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
export function shouldResyncLayerSelectionAnchor(args: {
|
|
460
|
+
selectionSignature: string;
|
|
461
|
+
lastPanelSelectionSignature: string;
|
|
462
|
+
currentAnchor: string | null;
|
|
463
|
+
selectableVisibleIds: readonly string[];
|
|
464
|
+
}) {
|
|
465
|
+
const anchorStillVisible =
|
|
466
|
+
args.currentAnchor !== null &&
|
|
467
|
+
args.selectableVisibleIds.includes(args.currentAnchor);
|
|
468
|
+
return (
|
|
469
|
+
args.selectionSignature !== args.lastPanelSelectionSignature ||
|
|
470
|
+
!anchorStillVisible
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
|
|
415
474
|
function layerCanShowBadge(node: LayersPanelNode) {
|
|
416
475
|
return (
|
|
417
476
|
node.type === "file" ||
|
|
@@ -451,6 +510,7 @@ export function LayersPanel({
|
|
|
451
510
|
const labels = useMemo(() => mergeLabels(labelsProp, t), [labelsProp, t]);
|
|
452
511
|
const selectedIdSet = useMemo(() => new Set(selectedIds), [selectedIds]);
|
|
453
512
|
const selectedIdsRef = useRef<readonly string[]>(selectedIds);
|
|
513
|
+
const lastPanelSelectionSignatureRef = useRef(selectedIds.join("\0"));
|
|
454
514
|
const expandedIdSet = useMemo(() => new Set(expandedIds), [expandedIds]);
|
|
455
515
|
const lastSelectionAnchorRef = useRef<string | null>(selectedIds[0] ?? null);
|
|
456
516
|
const searchInputRef = useRef<HTMLInputElement>(null);
|
|
@@ -486,9 +546,35 @@ export function LayersPanel({
|
|
|
486
546
|
[roots, selectedIdSet],
|
|
487
547
|
);
|
|
488
548
|
|
|
549
|
+
const selectableVisibleIds = useMemo(
|
|
550
|
+
() =>
|
|
551
|
+
visibleRows
|
|
552
|
+
.map(({ node }) => node)
|
|
553
|
+
.filter((node) => node.selectable !== false)
|
|
554
|
+
.map((node) => node.id),
|
|
555
|
+
[visibleRows],
|
|
556
|
+
);
|
|
557
|
+
|
|
489
558
|
useLayoutEffect(() => {
|
|
490
559
|
selectedIdsRef.current = selectedIds;
|
|
491
|
-
|
|
560
|
+
const signature = selectedIds.join("\0");
|
|
561
|
+
if (
|
|
562
|
+
!shouldResyncLayerSelectionAnchor({
|
|
563
|
+
selectionSignature: signature,
|
|
564
|
+
lastPanelSelectionSignature: lastPanelSelectionSignatureRef.current,
|
|
565
|
+
currentAnchor: lastSelectionAnchorRef.current,
|
|
566
|
+
selectableVisibleIds,
|
|
567
|
+
})
|
|
568
|
+
) {
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
lastPanelSelectionSignatureRef.current = signature;
|
|
572
|
+
lastSelectionAnchorRef.current =
|
|
573
|
+
getLayerSelectionAnchorFromExternalSelection({
|
|
574
|
+
selectedIds,
|
|
575
|
+
selectableVisibleIds,
|
|
576
|
+
});
|
|
577
|
+
}, [selectableVisibleIds, selectedIds]);
|
|
492
578
|
|
|
493
579
|
useEffect(() => {
|
|
494
580
|
if (selectedAncestorIds.length === 0) return;
|
|
@@ -522,15 +608,6 @@ export function LayersPanel({
|
|
|
522
608
|
return () => window.cancelAnimationFrame(frame);
|
|
523
609
|
}, [selectedScrollRowKey]);
|
|
524
610
|
|
|
525
|
-
const selectableVisibleIds = useMemo(
|
|
526
|
-
() =>
|
|
527
|
-
visibleRows
|
|
528
|
-
.map(({ node }) => node)
|
|
529
|
-
.filter((node) => node.selectable !== false)
|
|
530
|
-
.map((node) => node.id),
|
|
531
|
-
[visibleRows],
|
|
532
|
-
);
|
|
533
|
-
|
|
534
611
|
const selectNode = useCallback(
|
|
535
612
|
(
|
|
536
613
|
id: string,
|
|
@@ -582,6 +659,7 @@ export function LayersPanel({
|
|
|
582
659
|
if (!options.range) {
|
|
583
660
|
lastSelectionAnchorRef.current = id;
|
|
584
661
|
}
|
|
662
|
+
lastPanelSelectionSignatureRef.current = nextIds.join("\0");
|
|
585
663
|
onSelectionChange(nextIds, { id, selectedIds: nextIds, ...options });
|
|
586
664
|
},
|
|
587
665
|
[onSelectionChange, selectableVisibleIds],
|
|
@@ -948,12 +1026,15 @@ function LayerRow({
|
|
|
948
1026
|
};
|
|
949
1027
|
|
|
950
1028
|
const handleKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {
|
|
951
|
-
const
|
|
1029
|
+
const getFocusableButtons = () => {
|
|
952
1030
|
const tree = event.currentTarget.closest('[role="tree"]');
|
|
953
|
-
if (!tree) return
|
|
954
|
-
|
|
1031
|
+
if (!tree) return [];
|
|
1032
|
+
return Array.from(
|
|
955
1033
|
tree.querySelectorAll<HTMLButtonElement>("[data-layer-row-button]"),
|
|
956
1034
|
).filter((button) => !button.disabled);
|
|
1035
|
+
};
|
|
1036
|
+
const focusVisibleButton = (nextIndex: number) => {
|
|
1037
|
+
const buttons = getFocusableButtons();
|
|
957
1038
|
const target =
|
|
958
1039
|
buttons[Math.max(0, Math.min(buttons.length - 1, nextIndex))];
|
|
959
1040
|
target?.focus();
|
|
@@ -971,6 +1052,8 @@ function LayerRow({
|
|
|
971
1052
|
const currentIndex = visibleRows.findIndex(
|
|
972
1053
|
(visibleRow) => visibleRow.rowKey === row.rowKey,
|
|
973
1054
|
);
|
|
1055
|
+
const focusableButtons = getFocusableButtons();
|
|
1056
|
+
const currentFocusableIndex = focusableButtons.indexOf(event.currentTarget);
|
|
974
1057
|
|
|
975
1058
|
if (event.key === "Enter" || event.key === " " || event.key === "Space") {
|
|
976
1059
|
event.preventDefault();
|
|
@@ -990,12 +1073,12 @@ function LayerRow({
|
|
|
990
1073
|
}
|
|
991
1074
|
if (event.key === "ArrowDown") {
|
|
992
1075
|
event.preventDefault();
|
|
993
|
-
focusVisibleButton(
|
|
1076
|
+
focusVisibleButton(currentFocusableIndex + 1);
|
|
994
1077
|
return;
|
|
995
1078
|
}
|
|
996
1079
|
if (event.key === "ArrowUp") {
|
|
997
1080
|
event.preventDefault();
|
|
998
|
-
focusVisibleButton(
|
|
1081
|
+
focusVisibleButton(currentFocusableIndex - 1);
|
|
999
1082
|
return;
|
|
1000
1083
|
}
|
|
1001
1084
|
if (event.key === "Home") {
|
|
@@ -1005,7 +1088,7 @@ function LayerRow({
|
|
|
1005
1088
|
}
|
|
1006
1089
|
if (event.key === "End") {
|
|
1007
1090
|
event.preventDefault();
|
|
1008
|
-
focusVisibleButton(
|
|
1091
|
+
focusVisibleButton(focusableButtons.length - 1);
|
|
1009
1092
|
return;
|
|
1010
1093
|
}
|
|
1011
1094
|
if (event.key === "ArrowRight" && hasChildren && !isExpanded) {
|
|
@@ -1015,9 +1098,13 @@ function LayerRow({
|
|
|
1015
1098
|
}
|
|
1016
1099
|
if (event.key === "ArrowRight" && hasChildren && isExpanded) {
|
|
1017
1100
|
event.preventDefault();
|
|
1018
|
-
const
|
|
1101
|
+
const nextButton = focusableButtons[currentFocusableIndex + 1];
|
|
1102
|
+
const childId = nextButton?.dataset.layerNodeId;
|
|
1103
|
+
const child = childId
|
|
1104
|
+
? visibleRows.find((visibleRow) => visibleRow.node.id === childId)
|
|
1105
|
+
: null;
|
|
1019
1106
|
if (child?.ancestorIds.includes(node.id)) {
|
|
1020
|
-
focusVisibleButton(
|
|
1107
|
+
focusVisibleButton(currentFocusableIndex + 1);
|
|
1021
1108
|
}
|
|
1022
1109
|
return;
|
|
1023
1110
|
}
|
|
@@ -1038,17 +1125,10 @@ function LayerRow({
|
|
|
1038
1125
|
event.preventDefault();
|
|
1039
1126
|
return;
|
|
1040
1127
|
}
|
|
1041
|
-
const
|
|
1042
|
-
|
|
1043
|
-
:
|
|
1044
|
-
|
|
1045
|
-
// When a parent is moved, its children move with it automatically.
|
|
1046
|
-
const draggedIdSet = new Set(rawDraggedIds);
|
|
1047
|
-
const draggedIds = rawDraggedIds.filter((id) => {
|
|
1048
|
-
const rowForId = visibleRows.find((r) => r.node.id === id);
|
|
1049
|
-
return !rowForId?.ancestorIds.some((ancestorId) =>
|
|
1050
|
-
draggedIdSet.has(ancestorId),
|
|
1051
|
-
);
|
|
1128
|
+
const draggedIds = getDraggedLayerIdsForRows({
|
|
1129
|
+
selectedIds,
|
|
1130
|
+
nodeId: node.id,
|
|
1131
|
+
visibleRows,
|
|
1052
1132
|
});
|
|
1053
1133
|
event.dataTransfer.effectAllowed = "move";
|
|
1054
1134
|
event.dataTransfer.setData("application/x-design-layer-id", node.id);
|
|
@@ -174,6 +174,14 @@ export function MotionDock({
|
|
|
174
174
|
() => new Set(tracks.map((t) => t.targetNodeId)),
|
|
175
175
|
);
|
|
176
176
|
|
|
177
|
+
useEffect(() => {
|
|
178
|
+
setExpandedNodeIds((current) => {
|
|
179
|
+
const next = new Set(current);
|
|
180
|
+
for (const track of tracks) next.add(track.targetNodeId);
|
|
181
|
+
return next.size === current.size ? current : next;
|
|
182
|
+
});
|
|
183
|
+
}, [tracks]);
|
|
184
|
+
|
|
177
185
|
// Ruler / track area ref for pointer math.
|
|
178
186
|
const trackAreaRef = useRef<HTMLDivElement>(null);
|
|
179
187
|
|
|
@@ -403,6 +411,7 @@ export function MotionDock({
|
|
|
403
411
|
// ── Render ────────────────────────────────────────────────────────────────
|
|
404
412
|
return (
|
|
405
413
|
<div
|
|
414
|
+
aria-label="Motion dock"
|
|
406
415
|
className={cn(
|
|
407
416
|
"flex flex-col border-t border-border bg-background transition-all duration-150 select-none",
|
|
408
417
|
isOpen ? "" : "h-8",
|
|
@@ -4377,7 +4377,7 @@ const Screen = memo(function Screen({
|
|
|
4377
4377
|
)}
|
|
4378
4378
|
{creationToolActive ? (
|
|
4379
4379
|
<span
|
|
4380
|
-
className="absolute inset-0 z-20 cursor-crosshair"
|
|
4380
|
+
className="pointer-events-auto absolute inset-0 z-20 cursor-crosshair"
|
|
4381
4381
|
aria-hidden="true"
|
|
4382
4382
|
/>
|
|
4383
4383
|
) : null}
|
|
@@ -63,6 +63,12 @@ export interface ReviewFixSource {
|
|
|
63
63
|
filename?: string;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
export interface ReviewFixResult {
|
|
67
|
+
applied?: boolean;
|
|
68
|
+
fileId?: string;
|
|
69
|
+
patchedContent?: string;
|
|
70
|
+
}
|
|
71
|
+
|
|
66
72
|
/** Per-finding state for the optimistic Fix flow. */
|
|
67
73
|
type FixStatus = "idle" | "pending" | "fixed" | "error";
|
|
68
74
|
|
|
@@ -116,7 +122,7 @@ export interface ReviewPanelProps {
|
|
|
116
122
|
* Called after a fix is successfully applied — e.g. to refetch the audit so
|
|
117
123
|
* the resolved finding drops out of the list. The applied finding is passed.
|
|
118
124
|
*/
|
|
119
|
-
onFixApplied?: (finding: A11yFinding) => void;
|
|
125
|
+
onFixApplied?: (finding: A11yFinding, result?: ReviewFixResult) => void;
|
|
120
126
|
className?: string;
|
|
121
127
|
}
|
|
122
128
|
|
|
@@ -186,7 +192,7 @@ function FindingRow({
|
|
|
186
192
|
finding: A11yFinding;
|
|
187
193
|
onClick?: (finding: A11yFinding) => void;
|
|
188
194
|
fixSource?: ReviewFixSource;
|
|
189
|
-
onFixApplied?: (finding: A11yFinding) => void;
|
|
195
|
+
onFixApplied?: (finding: A11yFinding, result?: ReviewFixResult) => void;
|
|
190
196
|
}) {
|
|
191
197
|
const cfg = SEVERITY_CONFIG[finding.severity];
|
|
192
198
|
const Icon = cfg.icon;
|
|
@@ -213,6 +219,7 @@ function FindingRow({
|
|
|
213
219
|
designId: fixSource?.designId,
|
|
214
220
|
fileId: fixSource?.fileId,
|
|
215
221
|
filename: fixSource?.filename,
|
|
222
|
+
includeContent: true,
|
|
216
223
|
finding: {
|
|
217
224
|
id: finding.id,
|
|
218
225
|
severity: finding.severity,
|
|
@@ -224,10 +231,10 @@ function FindingRow({
|
|
|
224
231
|
wcag: finding.wcag,
|
|
225
232
|
fixAvailable: finding.fixAvailable,
|
|
226
233
|
},
|
|
227
|
-
})) as
|
|
234
|
+
})) as ReviewFixResult | undefined;
|
|
228
235
|
if (res?.applied) {
|
|
229
236
|
setFixStatus("fixed");
|
|
230
|
-
onFixApplied?.(finding);
|
|
237
|
+
onFixApplied?.(finding, res);
|
|
231
238
|
} else {
|
|
232
239
|
// The engine could not apply it (e.g. selector no longer resolves).
|
|
233
240
|
setFixStatus("error");
|
|
@@ -374,7 +381,7 @@ function A11ySection({
|
|
|
374
381
|
onRunAudit?: () => void;
|
|
375
382
|
onFindingClick?: (finding: A11yFinding) => void;
|
|
376
383
|
fixSource?: ReviewFixSource;
|
|
377
|
-
onFixApplied?: (finding: A11yFinding) => void;
|
|
384
|
+
onFixApplied?: (finding: A11yFinding, result?: ReviewFixResult) => void;
|
|
378
385
|
}) {
|
|
379
386
|
const errors = findings.filter((f) => f.severity === "error");
|
|
380
387
|
const warnings = findings.filter((f) => f.severity === "warning");
|
|
@@ -58,6 +58,8 @@ interface DesignStateRow {
|
|
|
58
58
|
breakpoint: DesignStateBreakpoint;
|
|
59
59
|
sourceRef?: string | null;
|
|
60
60
|
route?: string | null;
|
|
61
|
+
fixtureData?: Record<string, unknown> | null;
|
|
62
|
+
captureData?: Record<string, unknown> | null;
|
|
61
63
|
previewRef?: string | null;
|
|
62
64
|
createdAt?: string | null;
|
|
63
65
|
updatedAt?: string | null;
|
|
@@ -76,7 +78,7 @@ export interface StatesPanelProps {
|
|
|
76
78
|
breakpoints: Array<{ id: string; label: string; widthPx: number }>;
|
|
77
79
|
/** Whether the design's source supports live captures. */
|
|
78
80
|
canCapture?: boolean;
|
|
79
|
-
onStateSelect: (stateId: string | null) => void;
|
|
81
|
+
onStateSelect: (stateId: string | null, row?: DesignStateRow) => void;
|
|
80
82
|
onBreakpointSelect: (breakpointId: string) => void;
|
|
81
83
|
onAddBreakpoint?: () => void;
|
|
82
84
|
onCapture?: () => void;
|
|
@@ -455,7 +457,7 @@ export function StatesPanel({
|
|
|
455
457
|
key={row.id}
|
|
456
458
|
row={row}
|
|
457
459
|
isActive={activeStateId === row.id}
|
|
458
|
-
onSelect={() => onStateSelect(row.id)}
|
|
460
|
+
onSelect={() => onStateSelect(row.id, row)}
|
|
459
461
|
onDelete={() => handleDeleteState(row.id)}
|
|
460
462
|
/>
|
|
461
463
|
))}
|
|
@@ -182,18 +182,21 @@ function TokenRow({
|
|
|
182
182
|
)}
|
|
183
183
|
|
|
184
184
|
{/* Friendly name */}
|
|
185
|
-
<
|
|
186
|
-
|
|
185
|
+
<button
|
|
186
|
+
type="button"
|
|
187
|
+
className="min-w-0 flex-1 cursor-pointer truncate bg-transparent p-0 text-left text-[11px] text-foreground"
|
|
187
188
|
onClick={onStartEdit}
|
|
189
|
+
aria-label={`Edit ${token.name}`}
|
|
188
190
|
title={token.name}
|
|
189
191
|
>
|
|
190
192
|
{token.name}
|
|
191
|
-
</
|
|
193
|
+
</button>
|
|
192
194
|
|
|
193
195
|
{/* Value / edit input */}
|
|
194
196
|
{editing ? (
|
|
195
197
|
<Input
|
|
196
198
|
ref={inputRef}
|
|
199
|
+
aria-label={`Token value for ${token.name}`}
|
|
197
200
|
value={editDraft}
|
|
198
201
|
onChange={(e) => onDraftChange(e.target.value)}
|
|
199
202
|
onKeyDown={(e) => {
|
|
@@ -204,20 +207,22 @@ function TokenRow({
|
|
|
204
207
|
className="h-5 w-24 px-1 py-0 text-[11px] font-mono"
|
|
205
208
|
/>
|
|
206
209
|
) : (
|
|
207
|
-
<
|
|
208
|
-
|
|
210
|
+
<button
|
|
211
|
+
type="button"
|
|
212
|
+
className="max-w-[6rem] cursor-pointer truncate bg-transparent p-0 text-right font-mono text-[10px] text-muted-foreground hover:text-foreground"
|
|
209
213
|
title={token.value}
|
|
214
|
+
aria-label={`Edit value for ${token.name}`}
|
|
210
215
|
onClick={onStartEdit}
|
|
211
216
|
>
|
|
212
217
|
{token.value}
|
|
213
|
-
</
|
|
218
|
+
</button>
|
|
214
219
|
)}
|
|
215
220
|
|
|
216
221
|
{/* CSS var chip (hidden when editing, visible on hover) */}
|
|
217
222
|
{!editing && (
|
|
218
223
|
<Tooltip>
|
|
219
224
|
<TooltipTrigger asChild>
|
|
220
|
-
<span className="hidden cursor-default select-all rounded bg-muted px-1 py-0 font-mono text-[9px] text-muted-foreground/70 group-hover:inline">
|
|
225
|
+
<span className="pointer-events-none hidden max-w-[5.5rem] shrink-0 cursor-default select-all truncate rounded bg-muted px-1 py-0 font-mono text-[9px] text-muted-foreground/70 group-hover:inline-block">
|
|
221
226
|
{token.cssVar}
|
|
222
227
|
</span>
|
|
223
228
|
</TooltipTrigger>
|
|
@@ -231,7 +236,7 @@ function TokenRow({
|
|
|
231
236
|
{!editing && (
|
|
232
237
|
<Badge
|
|
233
238
|
variant="outline"
|
|
234
|
-
className="hidden h-4 cursor-default px-1 py-0 text-[9px] text-muted-foreground/60 group-hover:flex"
|
|
239
|
+
className="pointer-events-none hidden h-4 shrink-0 cursor-default px-1 py-0 text-[9px] text-muted-foreground/60 group-hover:flex"
|
|
235
240
|
>
|
|
236
241
|
{token.source}
|
|
237
242
|
</Badge>
|
|
@@ -438,6 +438,7 @@ const enUS = {
|
|
|
438
438
|
layerMoveFailed: "Could not move that layer",
|
|
439
439
|
duplicateElementFailed: "Could not duplicate that element",
|
|
440
440
|
saveCopyError: "Could not save a copy of this design",
|
|
441
|
+
auditRunFailed: "Unable to run design audit",
|
|
441
442
|
componentCreated: "Component created",
|
|
442
443
|
componentCreateFailed: "Could not create component",
|
|
443
444
|
},
|
|
@@ -8912,6 +8913,7 @@ const designPublicShareOverrides = {
|
|
|
8912
8913
|
shareEditorLinkDescription: "有權限的任何人都能在編輯器中開啟這個設計。",
|
|
8913
8914
|
toasts: {
|
|
8914
8915
|
saveCopyError: "無法儲存這個設計的副本",
|
|
8916
|
+
auditRunFailed: "無法執行設計稽核",
|
|
8915
8917
|
},
|
|
8916
8918
|
},
|
|
8917
8919
|
visualEdit: {
|
|
@@ -8941,6 +8943,7 @@ const designPublicShareOverrides = {
|
|
|
8941
8943
|
"有访问权限的任何人都可以在编辑器中打开此设计。",
|
|
8942
8944
|
toasts: {
|
|
8943
8945
|
saveCopyError: "无法保存此设计的副本",
|
|
8946
|
+
auditRunFailed: "无法运行设计审核",
|
|
8944
8947
|
},
|
|
8945
8948
|
},
|
|
8946
8949
|
visualEdit: {
|
|
@@ -8970,6 +8973,7 @@ const designPublicShareOverrides = {
|
|
|
8970
8973
|
"Cualquier persona con acceso puede abrir este diseño en el editor.",
|
|
8971
8974
|
toasts: {
|
|
8972
8975
|
saveCopyError: "No se pudo guardar una copia de este diseño",
|
|
8976
|
+
auditRunFailed: "No se pudo ejecutar la auditoria de diseno",
|
|
8973
8977
|
},
|
|
8974
8978
|
},
|
|
8975
8979
|
visualEdit: {
|
|
@@ -8999,6 +9003,7 @@ const designPublicShareOverrides = {
|
|
|
8999
9003
|
"Toute personne ayant acces peut ouvrir ce design dans l'editeur.",
|
|
9000
9004
|
toasts: {
|
|
9001
9005
|
saveCopyError: "Impossible d'enregistrer une copie de ce design",
|
|
9006
|
+
auditRunFailed: "Impossible d'executer l'audit de design",
|
|
9002
9007
|
},
|
|
9003
9008
|
},
|
|
9004
9009
|
visualEdit: {
|
|
@@ -9029,6 +9034,7 @@ const designPublicShareOverrides = {
|
|
|
9029
9034
|
toasts: {
|
|
9030
9035
|
saveCopyError:
|
|
9031
9036
|
"Eine Kopie dieses Designs konnte nicht gespeichert werden",
|
|
9037
|
+
auditRunFailed: "Design-Audit konnte nicht ausgefuehrt werden",
|
|
9032
9038
|
},
|
|
9033
9039
|
},
|
|
9034
9040
|
visualEdit: {
|
|
@@ -9058,6 +9064,7 @@ const designPublicShareOverrides = {
|
|
|
9058
9064
|
"アクセス権のある人は、このデザインをエディターで開けます。",
|
|
9059
9065
|
toasts: {
|
|
9060
9066
|
saveCopyError: "このデザインのコピーを保存できませんでした",
|
|
9067
|
+
auditRunFailed: "デザイン監査を実行できませんでした",
|
|
9061
9068
|
},
|
|
9062
9069
|
},
|
|
9063
9070
|
visualEdit: {
|
|
@@ -9087,6 +9094,7 @@ const designPublicShareOverrides = {
|
|
|
9087
9094
|
"액세스 권한이 있는 누구나 편집기에서 이 디자인을 열 수 있습니다.",
|
|
9088
9095
|
toasts: {
|
|
9089
9096
|
saveCopyError: "이 디자인의 사본을 저장할 수 없습니다",
|
|
9097
|
+
auditRunFailed: "디자인 감사를 실행할 수 없습니다",
|
|
9090
9098
|
},
|
|
9091
9099
|
},
|
|
9092
9100
|
visualEdit: {
|
|
@@ -9116,6 +9124,7 @@ const designPublicShareOverrides = {
|
|
|
9116
9124
|
"Qualquer pessoa com acesso pode abrir este design no editor.",
|
|
9117
9125
|
toasts: {
|
|
9118
9126
|
saveCopyError: "Nao foi possivel salvar uma copia deste design",
|
|
9127
|
+
auditRunFailed: "Nao foi possivel executar a auditoria de design",
|
|
9119
9128
|
},
|
|
9120
9129
|
},
|
|
9121
9130
|
visualEdit: {
|
|
@@ -9145,6 +9154,7 @@ const designPublicShareOverrides = {
|
|
|
9145
9154
|
"access वाला कोई भी व्यक्ति इस design को editor में खोल सकता है।",
|
|
9146
9155
|
toasts: {
|
|
9147
9156
|
saveCopyError: "इस design की copy सहेजी नहीं जा सकी",
|
|
9157
|
+
auditRunFailed: "design audit चलाया नहीं जा सका",
|
|
9148
9158
|
},
|
|
9149
9159
|
},
|
|
9150
9160
|
visualEdit: {
|
|
@@ -9174,6 +9184,7 @@ const designPublicShareOverrides = {
|
|
|
9174
9184
|
"يمكن لاي شخص لديه صلاحية الوصول فتح هذا التصميم في المحرر.",
|
|
9175
9185
|
toasts: {
|
|
9176
9186
|
saveCopyError: "تعذر حفظ نسخة من هذا التصميم",
|
|
9187
|
+
auditRunFailed: "تعذر تشغيل تدقيق التصميم",
|
|
9177
9188
|
},
|
|
9178
9189
|
},
|
|
9179
9190
|
visualEdit: {
|