@agent-native/core 0.182.1 → 0.182.2-nightly-20260917210345
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/templates/clips/app/root.tsx +59 -10
- package/corpus/templates/clips/changelog/2026-09-17-desktop-popover-closes-when-clicking-away.md +6 -0
- package/corpus/templates/clips/changelog/2026-09-17-self-hosted-extension-sign-in.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/background.ts +45 -25
- package/corpus/templates/clips/chrome-extension/src/content-script.ts +43 -0
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +55 -6
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +1 -0
- package/corpus/templates/design/actions/add-localhost-screens.ts +54 -22
- package/corpus/templates/design/actions/apply-visual-edit.ts +1 -0
- package/corpus/templates/design/actions/create-design-from-template.ts +50 -35
- package/corpus/templates/design/actions/create-design-version.ts +21 -0
- package/corpus/templates/design/actions/create-file.ts +35 -33
- package/corpus/templates/design/actions/delete-design.ts +29 -28
- package/corpus/templates/design/actions/delete-file.ts +154 -23
- package/corpus/templates/design/actions/generate-design.ts +28 -16
- package/corpus/templates/design/actions/get-component-details.ts +187 -33
- package/corpus/templates/design/actions/get-design-version.ts +9 -1
- package/corpus/templates/design/actions/go-to-main-component.ts +37 -35
- package/corpus/templates/design/actions/index-components.ts +241 -126
- package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +12 -9
- package/corpus/templates/design/actions/present-design-variants.ts +68 -72
- package/corpus/templates/design/actions/rename-component.ts +294 -0
- package/corpus/templates/design/actions/rename-screen.ts +10 -10
- package/corpus/templates/design/actions/update-file.ts +327 -330
- package/corpus/templates/design/actions/update-screen-source.ts +2 -43
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +1 -0
- package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbench.tsx +8 -1
- package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +55 -33
- package/corpus/templates/design/app/components/design/code-workbench/workspace/create-providers.ts +2 -0
- package/corpus/templates/design/app/components/design/code-workbench/workspace/inline-provider.ts +4 -2
- package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +5 -1
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +57 -9
- package/corpus/templates/design/app/components/design/types.ts +1 -0
- package/corpus/templates/design/app/hooks/use-design-versions.ts +3 -2
- package/corpus/templates/design/app/i18n-breakpoints.ts +0 -110
- package/corpus/templates/design/app/i18n-data.ts +0 -10
- package/corpus/templates/design/app/pages/DesignEditor.tsx +250 -107
- package/corpus/templates/design/app/pages/design-editor/commands/apply-file-content-update.ts +2 -0
- package/corpus/templates/design/app/pages/design-editor/commands/delete-files.ts +69 -47
- package/corpus/templates/design/app/pages/design-editor/commands/redo.ts +8 -1
- package/corpus/templates/design/app/pages/design-editor/commands/save-file-content.ts +107 -2
- package/corpus/templates/design/app/pages/design-editor/commands/undo.ts +26 -1
- package/corpus/templates/design/app/pages/design-editor/editor-state.ts +63 -2
- package/corpus/templates/design/app/pages/design-editor/nudge-intent.ts +74 -22
- package/corpus/templates/design/app/pages/design-editor/source-publication.ts +14 -2
- package/corpus/templates/design/changelog/2026-09-16-design-components-retain-linked-identities-when-edited-and-d.md +6 -0
- package/corpus/templates/design/changelog/2026-09-17-screen-deletion-is-immediate-and-undoable-with-history-that-.md +6 -0
- package/corpus/templates/design/e2e/fixtures/design-component-react/index.html +98 -0
- package/corpus/templates/design/e2e/fixtures/design-component-react/inline-component.html +65 -0
- package/corpus/templates/design/server/lib/design-data-mutation.ts +9 -5
- package/corpus/templates/design/server/lib/design-snapshot.ts +28 -16
- package/corpus/templates/design/server/lib/design-versions.ts +208 -130
- package/corpus/templates/design/server/lib/fusion-screens.ts +46 -20
- package/corpus/templates/design/server/lib/import-design-files.ts +5 -1
- package/corpus/templates/design/server/lib/localhost-connection.ts +54 -0
- package/corpus/templates/design/server/source-workspace.ts +412 -356
- package/corpus/templates/design/shared/component-library.ts +36 -6
- package/corpus/templates/design/shared/component-model.ts +8 -2
- package/dist/automation/index.d.ts +1 -1
- package/dist/client/chat/agentkit-protocol.js +148 -34
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/server/core-routes-plugin.d.ts +1 -1
- package/package.json +4 -4
- package/corpus/templates/design/app/components/design/editor/PendingScreenDeletionDialog.tsx +0 -66
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "../server/lib/design-data-mutation.js";
|
|
11
11
|
import { snapshotDesignBeforeAgentEdit } from "../server/lib/design-versions.js";
|
|
12
12
|
import {
|
|
13
|
-
|
|
13
|
+
fetchLocalhostSnapshot,
|
|
14
14
|
resolveLocalhostConnectionScope,
|
|
15
15
|
} from "../server/lib/localhost-connection.js";
|
|
16
16
|
import {
|
|
@@ -113,47 +113,6 @@ export function screenSourceMetadataForStatic(
|
|
|
113
113
|
return next;
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
async function fetchFallbackSnapshot(args: {
|
|
117
|
-
bridgeUrl: string;
|
|
118
|
-
previewToken: string | null;
|
|
119
|
-
url: string;
|
|
120
|
-
}): Promise<string> {
|
|
121
|
-
if (!args.previewToken) {
|
|
122
|
-
throw new Error(
|
|
123
|
-
"This URL-backed screen has no preview token. Reload the frame or reconnect the localhost app before switching it to static HTML.",
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
const endpoint = new URL("/snapshot", args.bridgeUrl);
|
|
127
|
-
endpoint.searchParams.set("url", args.url);
|
|
128
|
-
let response: Response;
|
|
129
|
-
try {
|
|
130
|
-
response = await fetch(endpoint, {
|
|
131
|
-
headers: {
|
|
132
|
-
accept: "application/json",
|
|
133
|
-
"x-design-preview-token": args.previewToken,
|
|
134
|
-
},
|
|
135
|
-
});
|
|
136
|
-
} catch (error) {
|
|
137
|
-
throw new Error(
|
|
138
|
-
`Could not reach the localhost bridge for snapshot (${error instanceof Error ? error.message : String(error)}).`,
|
|
139
|
-
);
|
|
140
|
-
}
|
|
141
|
-
if (!response.ok) {
|
|
142
|
-
const errorText = await response.text().catch(() => response.statusText);
|
|
143
|
-
throw localhostBridgeRequestError("snapshot", response.status, errorText);
|
|
144
|
-
}
|
|
145
|
-
let payload: { html?: unknown } | null;
|
|
146
|
-
try {
|
|
147
|
-
payload = (await response.json()) as { html?: unknown } | null;
|
|
148
|
-
} catch {
|
|
149
|
-
throw new Error("The localhost bridge returned invalid snapshot JSON.");
|
|
150
|
-
}
|
|
151
|
-
if (!payload || typeof payload.html !== "string") {
|
|
152
|
-
throw new Error("The localhost bridge returned no HTML snapshot.");
|
|
153
|
-
}
|
|
154
|
-
return payload.html;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
116
|
export default defineAction({
|
|
158
117
|
description:
|
|
159
118
|
"Change one Design screen between static HTML and a live localhost URL. " +
|
|
@@ -348,7 +307,7 @@ export default defineAction({
|
|
|
348
307
|
}
|
|
349
308
|
const rawSnapshot =
|
|
350
309
|
snapshotHtml ??
|
|
351
|
-
(await
|
|
310
|
+
(await fetchLocalhostSnapshot({
|
|
352
311
|
bridgeUrl: connection.bridgeUrl,
|
|
353
312
|
previewToken: connection.previewToken,
|
|
354
313
|
url: currentUrl,
|
|
@@ -3605,6 +3605,7 @@ declare var __INITIAL_SOURCE_HEAD__: string;
|
|
|
3605
3605
|
alignItems: parentStyles.alignItems,
|
|
3606
3606
|
justifyContent: parentStyles.justifyContent,
|
|
3607
3607
|
gap: parentStyles.gap,
|
|
3608
|
+
gridAutoFlow: parentStyles.gridAutoFlow,
|
|
3608
3609
|
gridTemplateColumns: parentStyles.gridTemplateColumns,
|
|
3609
3610
|
gridTemplateRows: parentStyles.gridTemplateRows,
|
|
3610
3611
|
position: parentStyles.position,
|
|
@@ -69,6 +69,7 @@ export interface CodeWorkbenchProps {
|
|
|
69
69
|
selectedNodeId?: string | null;
|
|
70
70
|
selectedSelector?: string | null;
|
|
71
71
|
localhostConnections?: CodeWorkbenchLocalhostConnection[];
|
|
72
|
+
onDeleteInlineFile?: (fileId: string) => void | Promise<void>;
|
|
72
73
|
onActiveFileChange?: (file: CodeWorkbenchActiveFile | null) => void;
|
|
73
74
|
onRequestLocalWriteConsent?: (
|
|
74
75
|
connectionId: string,
|
|
@@ -84,9 +85,15 @@ export function CodeWorkbench(props: CodeWorkbenchProps) {
|
|
|
84
85
|
createWorkspaceProviders({
|
|
85
86
|
designId: props.designId,
|
|
86
87
|
canEdit: props.canEdit,
|
|
88
|
+
onDeleteInlineFile: props.onDeleteInlineFile,
|
|
87
89
|
localhostConnections: props.localhostConnections ?? [],
|
|
88
90
|
}),
|
|
89
|
-
[
|
|
91
|
+
[
|
|
92
|
+
props.designId,
|
|
93
|
+
props.canEdit,
|
|
94
|
+
props.localhostConnections,
|
|
95
|
+
props.onDeleteInlineFile,
|
|
96
|
+
],
|
|
90
97
|
);
|
|
91
98
|
return (
|
|
92
99
|
<WorkbenchProvider key={props.designId} providers={providers}>
|
|
@@ -179,16 +179,36 @@ export function FileTree({
|
|
|
179
179
|
[api, handleWriteError, providerKey, renameDraft],
|
|
180
180
|
);
|
|
181
181
|
|
|
182
|
-
const commitDelete = useCallback(
|
|
182
|
+
const commitDelete = useCallback(
|
|
183
|
+
async (target: TreeNode) => {
|
|
184
|
+
try {
|
|
185
|
+
await api.deleteFile(providerKey, target.path);
|
|
186
|
+
} catch (error) {
|
|
187
|
+
handleWriteError(error);
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
[api, handleWriteError, providerKey],
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
const confirmDelete = useCallback(() => {
|
|
183
194
|
if (!deleteTarget) return;
|
|
184
195
|
const target = deleteTarget;
|
|
185
196
|
setDeleteTarget(null);
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
197
|
+
void commitDelete(target);
|
|
198
|
+
}, [commitDelete, deleteTarget]);
|
|
199
|
+
|
|
200
|
+
const requestDelete = useCallback(
|
|
201
|
+
(target: TreeNode) => {
|
|
202
|
+
if (providerKey.startsWith("inline:")) {
|
|
203
|
+
// Inline Design files are covered by the editor's durable undo/history
|
|
204
|
+
// boundary; external providers remain confirmation-gated below.
|
|
205
|
+
void commitDelete(target);
|
|
206
|
+
} else {
|
|
207
|
+
setDeleteTarget(target);
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
[commitDelete, providerKey],
|
|
211
|
+
);
|
|
192
212
|
|
|
193
213
|
const commitNewFile = useCallback(async () => {
|
|
194
214
|
if (!pendingNewFile) return;
|
|
@@ -496,7 +516,7 @@ export function FileTree({
|
|
|
496
516
|
{canDeleteNode ? (
|
|
497
517
|
<ContextMenuItem
|
|
498
518
|
className="text-[12px] text-destructive focus:text-destructive"
|
|
499
|
-
onSelect={() =>
|
|
519
|
+
onSelect={() => requestDelete(row.node)}
|
|
500
520
|
>
|
|
501
521
|
{"Delete" /* i18n-ignore */}
|
|
502
522
|
</ContextMenuItem>
|
|
@@ -572,32 +592,34 @@ export function FileTree({
|
|
|
572
592
|
/>
|
|
573
593
|
</div>
|
|
574
594
|
) : null}
|
|
595
|
+
<AlertDialog
|
|
596
|
+
open={Boolean(deleteTarget)}
|
|
597
|
+
onOpenChange={(open) => {
|
|
598
|
+
if (!open) setDeleteTarget(null);
|
|
599
|
+
}}
|
|
600
|
+
>
|
|
601
|
+
<AlertDialogContent>
|
|
602
|
+
<AlertDialogHeader>
|
|
603
|
+
<AlertDialogTitle>
|
|
604
|
+
{"Delete file?" /* i18n-ignore */}
|
|
605
|
+
</AlertDialogTitle>
|
|
606
|
+
<AlertDialogDescription>
|
|
607
|
+
{deleteTarget?.path
|
|
608
|
+
? `"${deleteTarget.path}" will be permanently deleted.` /* i18n-ignore */
|
|
609
|
+
: ""}
|
|
610
|
+
</AlertDialogDescription>
|
|
611
|
+
</AlertDialogHeader>
|
|
612
|
+
<AlertDialogFooter>
|
|
613
|
+
<AlertDialogCancel>
|
|
614
|
+
{"Cancel" /* i18n-ignore */}
|
|
615
|
+
</AlertDialogCancel>
|
|
616
|
+
<AlertDialogAction onClick={confirmDelete}>
|
|
617
|
+
{"Delete" /* i18n-ignore */}
|
|
618
|
+
</AlertDialogAction>
|
|
619
|
+
</AlertDialogFooter>
|
|
620
|
+
</AlertDialogContent>
|
|
621
|
+
</AlertDialog>
|
|
575
622
|
</div>
|
|
576
|
-
<AlertDialog
|
|
577
|
-
open={Boolean(deleteTarget)}
|
|
578
|
-
onOpenChange={(open) => {
|
|
579
|
-
if (!open) setDeleteTarget(null);
|
|
580
|
-
}}
|
|
581
|
-
>
|
|
582
|
-
<AlertDialogContent>
|
|
583
|
-
<AlertDialogHeader>
|
|
584
|
-
<AlertDialogTitle>
|
|
585
|
-
{"Delete file?" /* i18n-ignore */}
|
|
586
|
-
</AlertDialogTitle>
|
|
587
|
-
<AlertDialogDescription>
|
|
588
|
-
{deleteTarget?.path
|
|
589
|
-
? `"${deleteTarget.path}" will be permanently deleted.` /* i18n-ignore */
|
|
590
|
-
: ""}
|
|
591
|
-
</AlertDialogDescription>
|
|
592
|
-
</AlertDialogHeader>
|
|
593
|
-
<AlertDialogFooter>
|
|
594
|
-
<AlertDialogCancel>{"Cancel" /* i18n-ignore */}</AlertDialogCancel>
|
|
595
|
-
<AlertDialogAction onClick={() => void commitDelete()}>
|
|
596
|
-
{"Delete" /* i18n-ignore */}
|
|
597
|
-
</AlertDialogAction>
|
|
598
|
-
</AlertDialogFooter>
|
|
599
|
-
</AlertDialogContent>
|
|
600
|
-
</AlertDialog>
|
|
601
623
|
</div>
|
|
602
624
|
);
|
|
603
625
|
}
|
package/corpus/templates/design/app/components/design/code-workbench/workspace/create-providers.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type { WorkspaceProvider } from "./types";
|
|
|
5
5
|
export interface CreateWorkspaceProvidersOptions {
|
|
6
6
|
designId: string;
|
|
7
7
|
canEdit: boolean;
|
|
8
|
+
onDeleteInlineFile?: (fileId: string) => void | Promise<void>;
|
|
8
9
|
localhostConnections: Array<{
|
|
9
10
|
connectionId: string;
|
|
10
11
|
label: string;
|
|
@@ -24,6 +25,7 @@ export function createWorkspaceProviders(
|
|
|
24
25
|
createInlineProvider({
|
|
25
26
|
designId: options.designId,
|
|
26
27
|
canEdit: options.canEdit,
|
|
28
|
+
onDeleteFile: options.onDeleteInlineFile,
|
|
27
29
|
}),
|
|
28
30
|
];
|
|
29
31
|
for (const connection of options.localhostConnections) {
|
package/corpus/templates/design/app/components/design/code-workbench/workspace/inline-provider.ts
CHANGED
|
@@ -54,12 +54,13 @@ interface CreateFileResponse {
|
|
|
54
54
|
export interface CreateInlineProviderOptions {
|
|
55
55
|
designId: string;
|
|
56
56
|
canEdit: boolean;
|
|
57
|
+
onDeleteFile?: (fileId: string) => void | Promise<void>;
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
export function createInlineProvider(
|
|
60
61
|
options: CreateInlineProviderOptions,
|
|
61
62
|
): WorkspaceProvider {
|
|
62
|
-
const { designId, canEdit } = options;
|
|
63
|
+
const { designId, canEdit, onDeleteFile } = options;
|
|
63
64
|
const key = `inline:${designId}`;
|
|
64
65
|
// path -> fileId, populated by listFiles and refreshed on demand so
|
|
65
66
|
// renameFile/deleteFile can resolve a file's id without re-listing when
|
|
@@ -177,7 +178,8 @@ export function createInlineProvider(
|
|
|
177
178
|
|
|
178
179
|
async function deleteFile(path: string): Promise<void> {
|
|
179
180
|
const id = await resolveFileId(path);
|
|
180
|
-
|
|
181
|
+
if (onDeleteFile) await onDeleteFile(id);
|
|
182
|
+
else await callAction("delete-file", { id });
|
|
181
183
|
fileIdByPath.delete(path);
|
|
182
184
|
}
|
|
183
185
|
|
|
@@ -460,7 +460,11 @@ export function commitElementMinMax(
|
|
|
460
460
|
onStyleChange(property, kind === "min" ? "0px" : "none", meta);
|
|
461
461
|
return;
|
|
462
462
|
}
|
|
463
|
-
onStyleChange(
|
|
463
|
+
onStyleChange(
|
|
464
|
+
property,
|
|
465
|
+
`${Math.max(0, Math.round(value * 10) / 10)}px`,
|
|
466
|
+
meta,
|
|
467
|
+
);
|
|
464
468
|
}
|
|
465
469
|
|
|
466
470
|
export function inferElementSizing(
|
|
@@ -128,6 +128,35 @@ export interface AutoLayoutPadding {
|
|
|
128
128
|
left: number;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
const OPPOSITE_PADDING_SIDE: Record<
|
|
132
|
+
keyof AutoLayoutPadding,
|
|
133
|
+
keyof AutoLayoutPadding
|
|
134
|
+
> = {
|
|
135
|
+
top: "bottom",
|
|
136
|
+
right: "left",
|
|
137
|
+
bottom: "top",
|
|
138
|
+
left: "right",
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
type PaddingChangeMeta = {
|
|
142
|
+
source: ScrubInputChangeMeta["source"];
|
|
143
|
+
phase: ScrubInputChangeMeta["phase"];
|
|
144
|
+
altKey?: boolean;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
/** Apply Figma's Alt/Option mirror to one unlinked padding side. */
|
|
148
|
+
export function mirrorPaddingChange(
|
|
149
|
+
padding: AutoLayoutPadding,
|
|
150
|
+
side: keyof AutoLayoutPadding,
|
|
151
|
+
meta?: PaddingChangeMeta,
|
|
152
|
+
): AutoLayoutPadding {
|
|
153
|
+
if (!meta?.altKey) return padding;
|
|
154
|
+
return {
|
|
155
|
+
...padding,
|
|
156
|
+
[OPPOSITE_PADDING_SIDE[side]]: padding[side],
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
131
160
|
export interface AutoLayoutMatrixValue {
|
|
132
161
|
direction: AutoLayoutDirection;
|
|
133
162
|
wrap: AutoLayoutWrap;
|
|
@@ -424,6 +453,14 @@ export function AutoLayoutMatrix({
|
|
|
424
453
|
value.paddingMixed?.top || value.paddingMixed?.bottom,
|
|
425
454
|
);
|
|
426
455
|
|
|
456
|
+
const updatePadding = (
|
|
457
|
+
side: keyof AutoLayoutPadding,
|
|
458
|
+
padding: AutoLayoutPadding,
|
|
459
|
+
meta?: PaddingChangeMeta,
|
|
460
|
+
) => {
|
|
461
|
+
onPaddingChange(mirrorPaddingChange(padding, side, meta), meta);
|
|
462
|
+
};
|
|
463
|
+
|
|
427
464
|
const activeFlow = getFlowOption(value);
|
|
428
465
|
const isBlock = activeFlow === "normal";
|
|
429
466
|
const canResizeToFit =
|
|
@@ -731,7 +768,8 @@ export function AutoLayoutMatrix({
|
|
|
731
768
|
value={horizontalPaddingValue}
|
|
732
769
|
mixed={horizontalPaddingMixed}
|
|
733
770
|
onChange={(next, meta) =>
|
|
734
|
-
|
|
771
|
+
updatePadding(
|
|
772
|
+
"left",
|
|
735
773
|
{
|
|
736
774
|
top: value.padding.top,
|
|
737
775
|
bottom: value.padding.bottom,
|
|
@@ -752,7 +790,8 @@ export function AutoLayoutMatrix({
|
|
|
752
790
|
value={verticalPaddingValue}
|
|
753
791
|
mixed={verticalPaddingMixed}
|
|
754
792
|
onChange={(next, meta) =>
|
|
755
|
-
|
|
793
|
+
updatePadding(
|
|
794
|
+
"top",
|
|
756
795
|
{
|
|
757
796
|
top: next,
|
|
758
797
|
bottom: next,
|
|
@@ -788,7 +827,11 @@ export function AutoLayoutMatrix({
|
|
|
788
827
|
value={value.padding.top}
|
|
789
828
|
mixed={value.paddingMixed?.top}
|
|
790
829
|
onChange={(next, meta) =>
|
|
791
|
-
|
|
830
|
+
updatePadding(
|
|
831
|
+
"top",
|
|
832
|
+
{ ...value.padding, top: next },
|
|
833
|
+
meta,
|
|
834
|
+
)
|
|
792
835
|
}
|
|
793
836
|
disabled={disabled}
|
|
794
837
|
/>
|
|
@@ -804,7 +847,8 @@ export function AutoLayoutMatrix({
|
|
|
804
847
|
value={value.padding.right}
|
|
805
848
|
mixed={value.paddingMixed?.right}
|
|
806
849
|
onChange={(next, meta) =>
|
|
807
|
-
|
|
850
|
+
updatePadding(
|
|
851
|
+
"right",
|
|
808
852
|
{ ...value.padding, right: next },
|
|
809
853
|
meta,
|
|
810
854
|
)
|
|
@@ -819,7 +863,8 @@ export function AutoLayoutMatrix({
|
|
|
819
863
|
value={value.padding.bottom}
|
|
820
864
|
mixed={value.paddingMixed?.bottom}
|
|
821
865
|
onChange={(next, meta) =>
|
|
822
|
-
|
|
866
|
+
updatePadding(
|
|
867
|
+
"bottom",
|
|
823
868
|
{ ...value.padding, bottom: next },
|
|
824
869
|
meta,
|
|
825
870
|
)
|
|
@@ -838,7 +883,8 @@ export function AutoLayoutMatrix({
|
|
|
838
883
|
value={value.padding.left}
|
|
839
884
|
mixed={value.paddingMixed?.left}
|
|
840
885
|
onChange={(next, meta) =>
|
|
841
|
-
|
|
886
|
+
updatePadding(
|
|
887
|
+
"left",
|
|
842
888
|
{ ...value.padding, left: next },
|
|
843
889
|
meta,
|
|
844
890
|
)
|
|
@@ -1945,7 +1991,7 @@ export function SizingField({
|
|
|
1945
1991
|
? "Mixed"
|
|
1946
1992
|
: resolvedSize == null
|
|
1947
1993
|
? ""
|
|
1948
|
-
: String(
|
|
1994
|
+
: String(roundToOneDecimal(resolvedSize));
|
|
1949
1995
|
|
|
1950
1996
|
const addMinLabel = isWidth ? labels.addMinWidth : labels.addMinHeight;
|
|
1951
1997
|
const addMaxLabel = isWidth ? labels.addMaxWidth : labels.addMaxHeight;
|
|
@@ -1958,7 +2004,7 @@ export function SizingField({
|
|
|
1958
2004
|
const openEditor = (kind: "min" | "max") => {
|
|
1959
2005
|
// Commit immediately so the shown row always reflects real state and
|
|
1960
2006
|
// persists across selection changes, remounts, and parent re-renders.
|
|
1961
|
-
const seed = Math.max(0,
|
|
2007
|
+
const seed = Math.max(0, roundToOneDecimal(resolvedSize ?? 0));
|
|
1962
2008
|
const seedValue = kind === "min" ? seed : seed || 1;
|
|
1963
2009
|
onMinMaxChange?.(sizingAxis, kind, seedValue);
|
|
1964
2010
|
};
|
|
@@ -2250,7 +2296,9 @@ function ConstraintSubRow({
|
|
|
2250
2296
|
icon={icon}
|
|
2251
2297
|
prefix="icon"
|
|
2252
2298
|
value={value}
|
|
2253
|
-
onChange={(next, meta) =>
|
|
2299
|
+
onChange={(next, meta) =>
|
|
2300
|
+
onChange(Math.max(0, roundToOneDecimal(next)), meta)
|
|
2301
|
+
}
|
|
2254
2302
|
unit="px"
|
|
2255
2303
|
min={0}
|
|
2256
2304
|
step={1}
|
|
@@ -8,6 +8,7 @@ export interface DesignVersionChatContext {
|
|
|
8
8
|
runId?: string;
|
|
9
9
|
turnId?: string;
|
|
10
10
|
actionName?: string;
|
|
11
|
+
surface?: "editor";
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
export interface DesignVersionListEntry {
|
|
@@ -15,7 +16,7 @@ export interface DesignVersionListEntry {
|
|
|
15
16
|
designId: string;
|
|
16
17
|
label: string | null;
|
|
17
18
|
createdAt: string | null;
|
|
18
|
-
source: "chat" | "legacy";
|
|
19
|
+
source: "chat" | "editor" | "legacy";
|
|
19
20
|
fileCount: number;
|
|
20
21
|
chatContext: DesignVersionChatContext | null;
|
|
21
22
|
editable?: boolean;
|
|
@@ -40,7 +41,7 @@ export interface DesignVersionDetail {
|
|
|
40
41
|
designId: string;
|
|
41
42
|
label: string | null;
|
|
42
43
|
createdAt: string | null;
|
|
43
|
-
source: "chat" | "legacy";
|
|
44
|
+
source: "chat" | "editor" | "legacy";
|
|
44
45
|
fileCount: number;
|
|
45
46
|
chatContext: DesignVersionChatContext | null;
|
|
46
47
|
/** Present on list entries; optional on detail until the action always returns it. */
|
|
@@ -27,16 +27,6 @@ export const breakpointBarOverrides = {
|
|
|
27
27
|
"Responsive edits affect this breakpoint and smaller sizes by default. Change the scope beside the breakpoint control.",
|
|
28
28
|
},
|
|
29
29
|
},
|
|
30
|
-
screenDeletion: {
|
|
31
|
-
titleOne: "Delete this screen?",
|
|
32
|
-
titleMany: "Delete {{count}} screens?",
|
|
33
|
-
descriptionOne:
|
|
34
|
-
'"{{filename}}" and all of its responsive variants will be deleted. You can undo this while the editor remains open.',
|
|
35
|
-
descriptionMany:
|
|
36
|
-
"These screens and all of their responsive variants will be deleted. You can undo this while the editor remains open.",
|
|
37
|
-
cancel: "Cancel",
|
|
38
|
-
confirm: "Delete",
|
|
39
|
-
},
|
|
40
30
|
tweaksHelp:
|
|
41
31
|
"Tweaks are breakpoint- and state-specific visual overrides layered on the base design. Reset a control to return to the inherited value.",
|
|
42
32
|
},
|
|
@@ -64,16 +54,6 @@ export const breakpointBarOverrides = {
|
|
|
64
54
|
"响应式编辑默认影响此断点及更小尺寸。可在断点控件旁更改范围。",
|
|
65
55
|
},
|
|
66
56
|
},
|
|
67
|
-
screenDeletion: {
|
|
68
|
-
titleOne: "删除此屏幕?",
|
|
69
|
-
titleMany: "删除 {{count}} 个屏幕?",
|
|
70
|
-
descriptionOne:
|
|
71
|
-
"将删除“{{filename}}”及其所有响应式变体。编辑器保持打开时可以撤销。",
|
|
72
|
-
descriptionMany:
|
|
73
|
-
"将删除这些屏幕及其所有响应式变体。编辑器保持打开时可以撤销。",
|
|
74
|
-
cancel: "取消",
|
|
75
|
-
confirm: "删除",
|
|
76
|
-
},
|
|
77
57
|
tweaksHelp:
|
|
78
58
|
"调整项是叠加在基础设计上的断点和状态专属视觉覆盖。重置控件可恢复继承值。",
|
|
79
59
|
},
|
|
@@ -101,16 +81,6 @@ export const breakpointBarOverrides = {
|
|
|
101
81
|
"響應式編輯預設會影響此中斷點及更小尺寸。可在中斷點控制旁變更範圍。",
|
|
102
82
|
},
|
|
103
83
|
},
|
|
104
|
-
screenDeletion: {
|
|
105
|
-
titleOne: "刪除此畫面?",
|
|
106
|
-
titleMany: "刪除 {{count}} 個畫面?",
|
|
107
|
-
descriptionOne:
|
|
108
|
-
"將刪除「{{filename}}」及其所有響應式變體。編輯器保持開啟時可以復原。",
|
|
109
|
-
descriptionMany:
|
|
110
|
-
"將刪除這些畫面及其所有響應式變體。編輯器保持開啟時可以復原。",
|
|
111
|
-
cancel: "取消",
|
|
112
|
-
confirm: "刪除",
|
|
113
|
-
},
|
|
114
84
|
tweaksHelp:
|
|
115
85
|
"調整項是疊加在基礎設計上的中斷點與狀態專屬視覺覆寫。重設控制項可回到繼承值。",
|
|
116
86
|
},
|
|
@@ -138,16 +108,6 @@ export const breakpointBarOverrides = {
|
|
|
138
108
|
"Las ediciones adaptables afectan este punto y tamaños menores de forma predeterminada. Cambia el ámbito junto al control.",
|
|
139
109
|
},
|
|
140
110
|
},
|
|
141
|
-
screenDeletion: {
|
|
142
|
-
titleOne: "¿Eliminar esta pantalla?",
|
|
143
|
-
titleMany: "¿Eliminar {{count}} pantallas?",
|
|
144
|
-
descriptionOne:
|
|
145
|
-
"Se eliminarán “{{filename}}” y todas sus variantes adaptables. Puedes deshacerlo mientras el editor siga abierto.",
|
|
146
|
-
descriptionMany:
|
|
147
|
-
"Se eliminarán estas pantallas y todas sus variantes adaptables. Puedes deshacerlo mientras el editor siga abierto.",
|
|
148
|
-
cancel: "Cancelar",
|
|
149
|
-
confirm: "Eliminar",
|
|
150
|
-
},
|
|
151
111
|
tweaksHelp:
|
|
152
112
|
"Los ajustes son modificaciones visuales por punto de quiebre y estado superpuestas al diseño base. Restablece un control para volver al valor heredado.",
|
|
153
113
|
},
|
|
@@ -175,16 +135,6 @@ export const breakpointBarOverrides = {
|
|
|
175
135
|
"Les modifications responsive affectent ce point et les tailles inférieures par défaut. Modifiez la portée à côté du contrôle.",
|
|
176
136
|
},
|
|
177
137
|
},
|
|
178
|
-
screenDeletion: {
|
|
179
|
-
titleOne: "Supprimer cet écran ?",
|
|
180
|
-
titleMany: "Supprimer {{count}} écrans ?",
|
|
181
|
-
descriptionOne:
|
|
182
|
-
"« {{filename}} » et toutes ses variantes responsive seront supprimés. Vous pouvez annuler tant que l’éditeur reste ouvert.",
|
|
183
|
-
descriptionMany:
|
|
184
|
-
"Ces écrans et toutes leurs variantes responsive seront supprimés. Vous pouvez annuler tant que l’éditeur reste ouvert.",
|
|
185
|
-
cancel: "Annuler",
|
|
186
|
-
confirm: "Supprimer",
|
|
187
|
-
},
|
|
188
138
|
tweaksHelp:
|
|
189
139
|
"Les ajustements sont des surcharges visuelles propres aux points d’arrêt et aux états, superposées au design de base. Réinitialisez un contrôle pour revenir à la valeur héritée.",
|
|
190
140
|
},
|
|
@@ -212,16 +162,6 @@ export const breakpointBarOverrides = {
|
|
|
212
162
|
"Responsive Änderungen gelten standardmäßig für diesen Haltepunkt und kleinere Größen. Der Bereich kann daneben geändert werden.",
|
|
213
163
|
},
|
|
214
164
|
},
|
|
215
|
-
screenDeletion: {
|
|
216
|
-
titleOne: "Diesen Bildschirm löschen?",
|
|
217
|
-
titleMany: "{{count}} Bildschirme löschen?",
|
|
218
|
-
descriptionOne:
|
|
219
|
-
"„{{filename}}“ und alle responsiven Varianten werden gelöscht. Solange der Editor geöffnet bleibt, können Sie dies rückgängig machen.",
|
|
220
|
-
descriptionMany:
|
|
221
|
-
"Diese Bildschirme und alle responsiven Varianten werden gelöscht. Solange der Editor geöffnet bleibt, können Sie dies rückgängig machen.",
|
|
222
|
-
cancel: "Abbrechen",
|
|
223
|
-
confirm: "Löschen",
|
|
224
|
-
},
|
|
225
165
|
tweaksHelp:
|
|
226
166
|
"Anpassungen sind breakpoint- und zustandsspezifische visuelle Überschreibungen über dem Basisdesign. Setzen Sie ein Steuerelement zurück, um den geerbten Wert wiederherzustellen.",
|
|
227
167
|
},
|
|
@@ -249,16 +189,6 @@ export const breakpointBarOverrides = {
|
|
|
249
189
|
"レスポンシブ編集は既定でこのブレークポイント以下に適用されます。横のコントロールで範囲を変更できます。",
|
|
250
190
|
},
|
|
251
191
|
},
|
|
252
|
-
screenDeletion: {
|
|
253
|
-
titleOne: "この画面を削除しますか?",
|
|
254
|
-
titleMany: "{{count}} 個の画面を削除しますか?",
|
|
255
|
-
descriptionOne:
|
|
256
|
-
"「{{filename}}」とすべてのレスポンシブバリエーションが削除されます。エディターを開いている間は元に戻せます。",
|
|
257
|
-
descriptionMany:
|
|
258
|
-
"これらの画面とすべてのレスポンシブバリエーションが削除されます。エディターを開いている間は元に戻せます。",
|
|
259
|
-
cancel: "キャンセル",
|
|
260
|
-
confirm: "削除",
|
|
261
|
-
},
|
|
262
192
|
tweaksHelp:
|
|
263
193
|
"調整はベースデザインに重ねる、ブレークポイントおよび状態固有の視覚的オーバーライドです。コントロールをリセットすると継承値に戻ります。",
|
|
264
194
|
},
|
|
@@ -286,16 +216,6 @@ export const breakpointBarOverrides = {
|
|
|
286
216
|
"반응형 편집은 기본적으로 이 중단점과 더 작은 크기에 적용됩니다. 옆의 컨트롤에서 범위를 변경하세요.",
|
|
287
217
|
},
|
|
288
218
|
},
|
|
289
|
-
screenDeletion: {
|
|
290
|
-
titleOne: "이 화면을 삭제할까요?",
|
|
291
|
-
titleMany: "화면 {{count}}개를 삭제할까요?",
|
|
292
|
-
descriptionOne:
|
|
293
|
-
"“{{filename}}” 및 모든 반응형 변형이 삭제됩니다. 편집기가 열려 있는 동안 실행 취소할 수 있습니다.",
|
|
294
|
-
descriptionMany:
|
|
295
|
-
"이 화면들과 모든 반응형 변형이 삭제됩니다. 편집기가 열려 있는 동안 실행 취소할 수 있습니다.",
|
|
296
|
-
cancel: "취소",
|
|
297
|
-
confirm: "삭제",
|
|
298
|
-
},
|
|
299
219
|
tweaksHelp:
|
|
300
220
|
"조정은 기본 디자인 위에 적용되는 중단점 및 상태별 시각적 재정의입니다. 컨트롤을 재설정하면 상속된 값으로 돌아갑니다.",
|
|
301
221
|
},
|
|
@@ -323,16 +243,6 @@ export const breakpointBarOverrides = {
|
|
|
323
243
|
"As edições responsivas afetam este ponto e tamanhos menores por padrão. Altere o escopo ao lado do controle.",
|
|
324
244
|
},
|
|
325
245
|
},
|
|
326
|
-
screenDeletion: {
|
|
327
|
-
titleOne: "Excluir esta tela?",
|
|
328
|
-
titleMany: "Excluir {{count}} telas?",
|
|
329
|
-
descriptionOne:
|
|
330
|
-
"“{{filename}}” e todas as suas variações responsivas serão excluídas. Você pode desfazer enquanto o editor permanecer aberto.",
|
|
331
|
-
descriptionMany:
|
|
332
|
-
"Estas telas e todas as suas variações responsivas serão excluídas. Você pode desfazer enquanto o editor permanecer aberto.",
|
|
333
|
-
cancel: "Cancelar",
|
|
334
|
-
confirm: "Excluir",
|
|
335
|
-
},
|
|
336
246
|
tweaksHelp:
|
|
337
247
|
"Os ajustes são substituições visuais específicas de breakpoint e estado sobre o design base. Redefina um controle para voltar ao valor herdado.",
|
|
338
248
|
},
|
|
@@ -360,16 +270,6 @@ export const breakpointBarOverrides = {
|
|
|
360
270
|
"रेस्पॉन्सिव संपादन डिफ़ॉल्ट रूप से इस ब्रेकपॉइंट और छोटे आकारों पर लागू होते हैं। पास के कंट्रोल से दायरा बदलें।",
|
|
361
271
|
},
|
|
362
272
|
},
|
|
363
|
-
screenDeletion: {
|
|
364
|
-
titleOne: "यह स्क्रीन हटाएँ?",
|
|
365
|
-
titleMany: "{{count}} स्क्रीन हटाएँ?",
|
|
366
|
-
descriptionOne:
|
|
367
|
-
"“{{filename}}” और उसके सभी रेस्पॉन्सिव रूप हटाए जाएँगे। एडिटर खुला रहने तक आप इसे पूर्ववत कर सकते हैं।",
|
|
368
|
-
descriptionMany:
|
|
369
|
-
"ये स्क्रीन और इनके सभी रेस्पॉन्सिव रूप हटाए जाएँगे। एडिटर खुला रहने तक आप इसे पूर्ववत कर सकते हैं।",
|
|
370
|
-
cancel: "रद्द करें",
|
|
371
|
-
confirm: "हटाएँ",
|
|
372
|
-
},
|
|
373
273
|
tweaksHelp:
|
|
374
274
|
"ट्वीक्स आधार डिज़ाइन पर लागू ब्रेकपॉइंट और स्थिति-विशिष्ट विज़ुअल ओवरराइड हैं। विरासत में मिले मान पर लौटने के लिए कंट्रोल रीसेट करें।",
|
|
375
275
|
},
|
|
@@ -397,16 +297,6 @@ export const breakpointBarOverrides = {
|
|
|
397
297
|
"تؤثر التعديلات المتجاوبة افتراضيًا في نقطة التوقف هذه والأحجام الأصغر. غيّر النطاق بجوار عنصر التحكم.",
|
|
398
298
|
},
|
|
399
299
|
},
|
|
400
|
-
screenDeletion: {
|
|
401
|
-
titleOne: "حذف هذه الشاشة؟",
|
|
402
|
-
titleMany: "حذف {{count}} شاشة؟",
|
|
403
|
-
descriptionOne:
|
|
404
|
-
'سيتم حذف "{{filename}}" وجميع تنويعاته المتجاوبة. يمكنك التراجع ما دام المحرر مفتوحًا.',
|
|
405
|
-
descriptionMany:
|
|
406
|
-
"سيتم حذف هذه الشاشات وجميع تنويعاتها المتجاوبة. يمكنك التراجع ما دام المحرر مفتوحًا.",
|
|
407
|
-
cancel: "إلغاء",
|
|
408
|
-
confirm: "حذف",
|
|
409
|
-
},
|
|
410
300
|
tweaksHelp:
|
|
411
301
|
"التعديلات هي تجاوزات مرئية خاصة بنقطة التوقف والحالة فوق التصميم الأساسي. أعد ضبط عنصر التحكم للعودة إلى القيمة الموروثة.",
|
|
412
302
|
},
|
|
@@ -529,16 +529,6 @@ const enUS = {
|
|
|
529
529
|
zoomToPreset: "Zoom to {{percent}}%",
|
|
530
530
|
exit: "Exit responsive preview",
|
|
531
531
|
},
|
|
532
|
-
screenDeletion: {
|
|
533
|
-
titleOne: "Delete this screen?",
|
|
534
|
-
titleMany: "Delete {{count}} screens?",
|
|
535
|
-
descriptionOne:
|
|
536
|
-
'"{{filename}}" and all of its responsive variants will be deleted. You can undo this while the editor remains open.',
|
|
537
|
-
descriptionMany:
|
|
538
|
-
"These screens and all of their responsive variants will be deleted. You can undo this while the editor remains open.",
|
|
539
|
-
cancel: "Cancel",
|
|
540
|
-
confirm: "Delete",
|
|
541
|
-
},
|
|
542
532
|
motion: {
|
|
543
533
|
dockLabel: "Motion dock",
|
|
544
534
|
collapseDock: "Collapse motion dock",
|