@agent-native/core 0.131.3 → 0.131.5
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 +2 -2
- package/corpus/core/CHANGELOG.md +12 -0
- package/corpus/core/docs/content/docs-components.mdx +491 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/client/AgentPanel.tsx +58 -34
- package/corpus/core/src/localization/default-messages.ts +6 -0
- package/corpus/templates/content/.agents/skills/content-product-development/SKILL.md +47 -0
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +3 -1
- package/corpus/templates/design/actions/get-design.ts +11 -3
- package/corpus/templates/design/actions/present-design-variants.ts +62 -5
- package/corpus/templates/design/app/components/design/BreakpointBar.tsx +64 -1
- package/corpus/templates/design/app/components/design/EditPanel.tsx +199 -25
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +160 -46
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +7 -1
- package/corpus/templates/design/app/components/design/edit-panel/effects-properties.tsx +59 -12
- package/corpus/templates/design/app/components/design/edit-panel/fill-properties.tsx +1 -1
- package/corpus/templates/design/app/components/design/edit-panel/inspector-controls.tsx +34 -29
- package/corpus/templates/design/app/components/design/edit-panel/stroke-properties.tsx +2 -2
- package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +28 -10
- package/corpus/templates/design/app/components/design/inspector/design-icons.tsx +15 -28
- package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +4 -3
- package/corpus/templates/design/app/components/design/multi-screen/chrome-transitions.ts +12 -8
- package/corpus/templates/design/app/components/design/multi-screen/culling.ts +34 -9
- package/corpus/templates/design/app/components/design/multi-screen/frame-geometry.ts +13 -27
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +8 -1
- package/corpus/templates/design/app/components/design/multi-screen/zoom-gesture.ts +95 -0
- package/corpus/templates/design/app/i18n-data.ts +121 -10
- package/corpus/templates/design/app/pages/design-editor/data-operations.ts +45 -0
- package/corpus/templates/design/app/pages/design-editor/layout-operations.ts +59 -0
- package/corpus/templates/design/app/pages/design-editor/text-edit-utils.ts +115 -40
- package/corpus/templates/design/changelog/2026-07-28-generated-design-variants-no-longer-overlap-each-other-on-th.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-auto-layout-direction-icons-show-an-arrow.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-breakpoints-no-longer-overlap-neighbouring-screens.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-canvas-is-more-responsive-when-selecting-and-adding-frames.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-canvas-zoom-is-smoother-and-labels-hold-their-size.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-double-click-a-frame-now-drills-into-its-layers.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-export-preview-shows-the-real-render.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-figma-parity-shortcuts.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-more-breakpoint-width-presets.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-resize-a-selected-frame-to-a-device-preset.md +6 -0
- package/corpus/templates/design/changelog/2026-07-29-text-tool-reaches-the-right-surface.md +6 -0
- package/corpus/templates/design/shared/canvas-frames.ts +23 -0
- package/corpus/templates/design/shared/code-layer.ts +54 -2
- package/corpus/templates/design/shared/responsive-frame-layout.ts +55 -0
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +16 -5
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/localization/default-messages.d.ts +6 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +6 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/docs/content/docs-components.mdx +491 -0
- package/package.json +1 -1
- package/src/client/AgentPanel.tsx +58 -34
- package/src/localization/default-messages.ts +6 -0
|
@@ -90,7 +90,8 @@ const enUS = {
|
|
|
90
90
|
pageHelpDescription:
|
|
91
91
|
"Edit typography, spacing, sizing, borders and fill for whatever you select. Page defaults below.",
|
|
92
92
|
sections: {
|
|
93
|
-
page: "
|
|
93
|
+
page: "Screen",
|
|
94
|
+
canvas: "Canvas",
|
|
94
95
|
typography: "Typography",
|
|
95
96
|
autoLayout: "Auto layout",
|
|
96
97
|
positionLayout: "Position",
|
|
@@ -145,6 +146,9 @@ const enUS = {
|
|
|
145
146
|
shadow: "Shadow",
|
|
146
147
|
filter: "Filter",
|
|
147
148
|
addLayer: "Add layer",
|
|
149
|
+
addFill: "Add fill",
|
|
150
|
+
addStroke: "Add stroke",
|
|
151
|
+
addEffect: "Add effect",
|
|
148
152
|
removeLayer: "Remove layer",
|
|
149
153
|
showLayer: "Show layer",
|
|
150
154
|
hideLayer: "Hide layer",
|
|
@@ -364,8 +368,13 @@ const enUS = {
|
|
|
364
368
|
dotted: "Dotted",
|
|
365
369
|
double: "Double",
|
|
366
370
|
},
|
|
371
|
+
exportPreview: {
|
|
372
|
+
rendering: "Rendering preview…",
|
|
373
|
+
failed: "Preview unavailable",
|
|
374
|
+
},
|
|
367
375
|
framePresets: {
|
|
368
376
|
title: "Frame",
|
|
377
|
+
applyToFrame: "Resize to preset",
|
|
369
378
|
categories: {
|
|
370
379
|
phone: "Phone",
|
|
371
380
|
tablet: "Tablet",
|
|
@@ -1154,6 +1163,8 @@ const enUS = {
|
|
|
1154
1163
|
},
|
|
1155
1164
|
},
|
|
1156
1165
|
multiScreenCanvas: {
|
|
1166
|
+
addBreakpointToAllScreens:
|
|
1167
|
+
"Add {{label}} breakpoint ({{width}}px) to all screens",
|
|
1157
1168
|
duplicate: "Duplicate",
|
|
1158
1169
|
fork: "Fork",
|
|
1159
1170
|
fullView: "Full view",
|
|
@@ -1718,7 +1729,8 @@ const designLocaleOverrides = {
|
|
|
1718
1729
|
pageHelpDescription:
|
|
1719
1730
|
"编辑您选择的任何版式、间距、大小、边框和填充。页面默认如下。",
|
|
1720
1731
|
sections: {
|
|
1721
|
-
page: "
|
|
1732
|
+
page: "画面",
|
|
1733
|
+
canvas: "画布",
|
|
1722
1734
|
typography: "版式",
|
|
1723
1735
|
flexLayout: "弹性布局",
|
|
1724
1736
|
layout: "布局",
|
|
@@ -2119,7 +2131,8 @@ const designLocaleOverrides = {
|
|
|
2119
2131
|
pageHelpDescription:
|
|
2120
2132
|
"Edite tipografía, espaciado, tamaño, bordes y rellene lo que seleccione. Valores predeterminados de página a continuación.",
|
|
2121
2133
|
sections: {
|
|
2122
|
-
page: "
|
|
2134
|
+
page: "Pantalla",
|
|
2135
|
+
canvas: "Lienzo",
|
|
2123
2136
|
typography: "Tipografía",
|
|
2124
2137
|
flexLayout: "Diseño flexible",
|
|
2125
2138
|
layout: "Disposición",
|
|
@@ -2541,7 +2554,8 @@ const designLocaleOverrides = {
|
|
|
2541
2554
|
pageHelpDescription:
|
|
2542
2555
|
"Modifiez la typographie, l'espacement, le dimensionnement, les bordures et remplissez ce que vous sélectionnez. Valeurs par défaut de la page ci-dessous.",
|
|
2543
2556
|
sections: {
|
|
2544
|
-
page: "
|
|
2557
|
+
page: "Écran",
|
|
2558
|
+
canvas: "Canevas",
|
|
2545
2559
|
typography: "Typographie",
|
|
2546
2560
|
flexLayout: "Disposition flexible",
|
|
2547
2561
|
layout: "Mise en page",
|
|
@@ -2967,7 +2981,8 @@ const designLocaleOverrides = {
|
|
|
2967
2981
|
pageHelpDescription:
|
|
2968
2982
|
"Bearbeiten Sie Typografie, Abstände, Größen, Ränder und Füllung für alles, was Sie auswählen. Seitenstandards unten.",
|
|
2969
2983
|
sections: {
|
|
2970
|
-
page: "
|
|
2984
|
+
page: "Screen",
|
|
2985
|
+
canvas: "Arbeitsfläche",
|
|
2971
2986
|
typography: "Typografie",
|
|
2972
2987
|
flexLayout: "Flex-Layout",
|
|
2973
2988
|
layout: "Layout",
|
|
@@ -3394,7 +3409,8 @@ const designLocaleOverrides = {
|
|
|
3394
3409
|
pageHelpDescription:
|
|
3395
3410
|
"選択した内容のタイポグラフィ、間隔、サイズ、境界線、塗りつぶしを編集します。ページのデフォルトは以下です。",
|
|
3396
3411
|
sections: {
|
|
3397
|
-
page: "
|
|
3412
|
+
page: "画面",
|
|
3413
|
+
canvas: "キャンバス",
|
|
3398
3414
|
typography: "タイポグラフィ",
|
|
3399
3415
|
flexLayout: "フレックスレイアウト",
|
|
3400
3416
|
layout: "レイアウト",
|
|
@@ -3816,7 +3832,8 @@ const designLocaleOverrides = {
|
|
|
3816
3832
|
pageHelpDescription:
|
|
3817
3833
|
"선택한 항목에 대해 타이포그래피, 간격, 크기, 테두리 및 채우기를 편집하세요. 아래는 페이지 기본값입니다.",
|
|
3818
3834
|
sections: {
|
|
3819
|
-
page: "
|
|
3835
|
+
page: "화면",
|
|
3836
|
+
canvas: "캔버스",
|
|
3820
3837
|
typography: "타이포그래피",
|
|
3821
3838
|
flexLayout: "플렉스 레이아웃",
|
|
3822
3839
|
layout: "공들여 나열한 것",
|
|
@@ -4231,7 +4248,8 @@ const designLocaleOverrides = {
|
|
|
4231
4248
|
pageHelpDescription:
|
|
4232
4249
|
"Edite tipografia, espaçamento, dimensionamento, bordas e preenchimento de acordo com o que você selecionar. Padrões de página abaixo.",
|
|
4233
4250
|
sections: {
|
|
4234
|
-
page: "
|
|
4251
|
+
page: "Tela",
|
|
4252
|
+
canvas: "Tela de trabalho",
|
|
4235
4253
|
typography: "Tipografia",
|
|
4236
4254
|
flexLayout: "Layout flexível",
|
|
4237
4255
|
layout: "Disposição",
|
|
@@ -4653,7 +4671,8 @@ const designLocaleOverrides = {
|
|
|
4653
4671
|
pageHelpDescription:
|
|
4654
4672
|
"टाइपोग्राफी, रिक्ति, आकार, सीमाएँ संपादित करें और जो भी आप चुनें उसे भरें। पृष्ठ डिफ़ॉल्ट नीचे है.",
|
|
4655
4673
|
sections: {
|
|
4656
|
-
page: "
|
|
4674
|
+
page: "स्क्रीन",
|
|
4675
|
+
canvas: "कैनवास",
|
|
4657
4676
|
typography: "टाइपोग्राफी",
|
|
4658
4677
|
flexLayout: "फ्लेक्स लेआउट",
|
|
4659
4678
|
layout: "लेआउट",
|
|
@@ -5066,7 +5085,8 @@ const designLocaleOverrides = {
|
|
|
5066
5085
|
pageHelpDescription:
|
|
5067
5086
|
"تحرير الطباعة، والتباعد، والتحجيم، والحدود وملء ما تحدده. الإعدادات الافتراضية للصفحة أدناه.",
|
|
5068
5087
|
sections: {
|
|
5069
|
-
page: "
|
|
5088
|
+
page: "الشاشة",
|
|
5089
|
+
canvas: "لوحة الرسم",
|
|
5070
5090
|
typography: "الطباعة",
|
|
5071
5091
|
flexLayout: "تخطيط مرن",
|
|
5072
5092
|
layout: "تَخطِيط",
|
|
@@ -7889,6 +7909,8 @@ const designModeFeatureOverrides = {
|
|
|
7889
7909
|
},
|
|
7890
7910
|
},
|
|
7891
7911
|
multiScreenCanvas: {
|
|
7912
|
+
addBreakpointToAllScreens:
|
|
7913
|
+
"為所有畫面新增 {{label}} 中斷點({{width}}px)",
|
|
7892
7914
|
duplicate: "複製",
|
|
7893
7915
|
fork: "分支",
|
|
7894
7916
|
fullView: "完整檢視",
|
|
@@ -8059,6 +8081,7 @@ const designModeFeatureOverrides = {
|
|
|
8059
8081
|
},
|
|
8060
8082
|
},
|
|
8061
8083
|
multiScreenCanvas: {
|
|
8084
|
+
addBreakpointToAllScreens: "为所有画面添加 {{label}} 断点({{width}}px)",
|
|
8062
8085
|
duplicate: "复制",
|
|
8063
8086
|
fork: "分支",
|
|
8064
8087
|
fullView: "完整视图",
|
|
@@ -8230,6 +8253,8 @@ const designModeFeatureOverrides = {
|
|
|
8230
8253
|
},
|
|
8231
8254
|
},
|
|
8232
8255
|
multiScreenCanvas: {
|
|
8256
|
+
addBreakpointToAllScreens:
|
|
8257
|
+
"Añadir punto de ruptura {{label}} ({{width}}px) a todas las pantallas",
|
|
8233
8258
|
duplicate: "Duplicar",
|
|
8234
8259
|
fork: "Bifurcar",
|
|
8235
8260
|
fullView: "Vista completa",
|
|
@@ -8422,6 +8447,8 @@ const designModeFeatureOverrides = {
|
|
|
8422
8447
|
},
|
|
8423
8448
|
},
|
|
8424
8449
|
multiScreenCanvas: {
|
|
8450
|
+
addBreakpointToAllScreens:
|
|
8451
|
+
"Ajouter le point de rupture {{label}} ({{width}}px) à tous les écrans",
|
|
8425
8452
|
duplicate: "Dupliquer",
|
|
8426
8453
|
fork: "Créer une branche",
|
|
8427
8454
|
fullView: "Vue complète",
|
|
@@ -8611,6 +8638,8 @@ const designModeFeatureOverrides = {
|
|
|
8611
8638
|
},
|
|
8612
8639
|
},
|
|
8613
8640
|
multiScreenCanvas: {
|
|
8641
|
+
addBreakpointToAllScreens:
|
|
8642
|
+
"{{label}}-Breakpoint ({{width}}px) zu allen Screens hinzufügen",
|
|
8614
8643
|
duplicate: "Duplizieren",
|
|
8615
8644
|
fork: "Abzweigen",
|
|
8616
8645
|
fullView: "Vollansicht",
|
|
@@ -8805,6 +8834,8 @@ const designModeFeatureOverrides = {
|
|
|
8805
8834
|
},
|
|
8806
8835
|
},
|
|
8807
8836
|
multiScreenCanvas: {
|
|
8837
|
+
addBreakpointToAllScreens:
|
|
8838
|
+
"すべての画面に {{label}} ブレークポイント({{width}}px)を追加",
|
|
8808
8839
|
duplicate: "複製",
|
|
8809
8840
|
fork: "分岐",
|
|
8810
8841
|
fullView: "全体表示",
|
|
@@ -8994,6 +9025,8 @@ const designModeFeatureOverrides = {
|
|
|
8994
9025
|
},
|
|
8995
9026
|
},
|
|
8996
9027
|
multiScreenCanvas: {
|
|
9028
|
+
addBreakpointToAllScreens:
|
|
9029
|
+
"모든 화면에 {{label}} 중단점({{width}}px) 추가",
|
|
8997
9030
|
duplicate: "복제",
|
|
8998
9031
|
fork: "분기",
|
|
8999
9032
|
fullView: "전체 보기",
|
|
@@ -9180,6 +9213,8 @@ const designModeFeatureOverrides = {
|
|
|
9180
9213
|
},
|
|
9181
9214
|
},
|
|
9182
9215
|
multiScreenCanvas: {
|
|
9216
|
+
addBreakpointToAllScreens:
|
|
9217
|
+
"Adicionar ponto de quebra {{label}} ({{width}}px) a todas as telas",
|
|
9183
9218
|
duplicate: "Duplicar",
|
|
9184
9219
|
fork: "Ramificar",
|
|
9185
9220
|
fullView: "Vista completa",
|
|
@@ -9366,6 +9401,8 @@ const designModeFeatureOverrides = {
|
|
|
9366
9401
|
},
|
|
9367
9402
|
},
|
|
9368
9403
|
multiScreenCanvas: {
|
|
9404
|
+
addBreakpointToAllScreens:
|
|
9405
|
+
"सभी स्क्रीन में {{label}} ब्रेकपॉइंट ({{width}}px) जोड़ें",
|
|
9369
9406
|
duplicate: "डुप्लिकेट",
|
|
9370
9407
|
fork: "फोर्क",
|
|
9371
9408
|
fullView: "पूर्ण दृश्य",
|
|
@@ -9552,6 +9589,8 @@ const designModeFeatureOverrides = {
|
|
|
9552
9589
|
},
|
|
9553
9590
|
},
|
|
9554
9591
|
multiScreenCanvas: {
|
|
9592
|
+
addBreakpointToAllScreens:
|
|
9593
|
+
"إضافة نقطة توقف {{label}} ({{width}}px) إلى جميع الشاشات",
|
|
9555
9594
|
duplicate: "تكرار",
|
|
9556
9595
|
fork: "تفريع",
|
|
9557
9596
|
fullView: "عرض كامل",
|
|
@@ -9695,6 +9734,9 @@ const designCanvasFeatureOverrides = {
|
|
|
9695
9734
|
editPanel: {
|
|
9696
9735
|
labels: {
|
|
9697
9736
|
addLayer: "新增图层",
|
|
9737
|
+
addFill: "添加填充",
|
|
9738
|
+
addStroke: "添加描边",
|
|
9739
|
+
addEffect: "添加效果",
|
|
9698
9740
|
removeLayer: "移除图层",
|
|
9699
9741
|
showLayer: "显示图层",
|
|
9700
9742
|
hideLayer: "隐藏图层",
|
|
@@ -9795,6 +9837,9 @@ const designCanvasFeatureOverrides = {
|
|
|
9795
9837
|
editPanel: {
|
|
9796
9838
|
labels: {
|
|
9797
9839
|
addLayer: "Añadir capa",
|
|
9840
|
+
addFill: "Añadir relleno",
|
|
9841
|
+
addStroke: "Añadir trazo",
|
|
9842
|
+
addEffect: "Añadir efecto",
|
|
9798
9843
|
removeLayer: "Eliminar capa",
|
|
9799
9844
|
showLayer: "Mostrar capa",
|
|
9800
9845
|
hideLayer: "Ocultar capa",
|
|
@@ -9897,6 +9942,9 @@ const designCanvasFeatureOverrides = {
|
|
|
9897
9942
|
editPanel: {
|
|
9898
9943
|
labels: {
|
|
9899
9944
|
addLayer: "Ajouter un calque",
|
|
9945
|
+
addFill: "Ajouter un remplissage",
|
|
9946
|
+
addStroke: "Ajouter un contour",
|
|
9947
|
+
addEffect: "Ajouter un effet",
|
|
9900
9948
|
removeLayer: "Supprimer le calque",
|
|
9901
9949
|
showLayer: "Afficher le calque",
|
|
9902
9950
|
hideLayer: "Masquer le calque",
|
|
@@ -9999,6 +10047,9 @@ const designCanvasFeatureOverrides = {
|
|
|
9999
10047
|
editPanel: {
|
|
10000
10048
|
labels: {
|
|
10001
10049
|
addLayer: "Ebene hinzufügen",
|
|
10050
|
+
addFill: "Füllung hinzufügen",
|
|
10051
|
+
addStroke: "Kontur hinzufügen",
|
|
10052
|
+
addEffect: "Effekt hinzufügen",
|
|
10002
10053
|
removeLayer: "Ebene entfernen",
|
|
10003
10054
|
showLayer: "Ebene anzeigen",
|
|
10004
10055
|
hideLayer: "Ebene ausblenden",
|
|
@@ -10097,6 +10148,9 @@ const designCanvasFeatureOverrides = {
|
|
|
10097
10148
|
editPanel: {
|
|
10098
10149
|
labels: {
|
|
10099
10150
|
addLayer: "レイヤーを追加",
|
|
10151
|
+
addFill: "塗りを追加",
|
|
10152
|
+
addStroke: "線を追加",
|
|
10153
|
+
addEffect: "エフェクトを追加",
|
|
10100
10154
|
removeLayer: "レイヤーを削除",
|
|
10101
10155
|
showLayer: "レイヤーを表示",
|
|
10102
10156
|
hideLayer: "レイヤーを非表示",
|
|
@@ -10195,6 +10249,9 @@ const designCanvasFeatureOverrides = {
|
|
|
10195
10249
|
editPanel: {
|
|
10196
10250
|
labels: {
|
|
10197
10251
|
addLayer: "레이어 추가",
|
|
10252
|
+
addFill: "칠 추가",
|
|
10253
|
+
addStroke: "선 추가",
|
|
10254
|
+
addEffect: "효과 추가",
|
|
10198
10255
|
removeLayer: "레이어 제거",
|
|
10199
10256
|
showLayer: "레이어 표시",
|
|
10200
10257
|
hideLayer: "레이어 숨기기",
|
|
@@ -10295,6 +10352,9 @@ const designCanvasFeatureOverrides = {
|
|
|
10295
10352
|
editPanel: {
|
|
10296
10353
|
labels: {
|
|
10297
10354
|
addLayer: "Adicionar camada",
|
|
10355
|
+
addFill: "Adicionar preenchimento",
|
|
10356
|
+
addStroke: "Adicionar contorno",
|
|
10357
|
+
addEffect: "Adicionar efeito",
|
|
10298
10358
|
removeLayer: "Remover camada",
|
|
10299
10359
|
showLayer: "Mostrar camada",
|
|
10300
10360
|
hideLayer: "Ocultar camada",
|
|
@@ -10393,6 +10453,9 @@ const designCanvasFeatureOverrides = {
|
|
|
10393
10453
|
editPanel: {
|
|
10394
10454
|
labels: {
|
|
10395
10455
|
addLayer: "परत जोड़ें",
|
|
10456
|
+
addFill: "भराव जोड़ें",
|
|
10457
|
+
addStroke: "स्ट्रोक जोड़ें",
|
|
10458
|
+
addEffect: "प्रभाव जोड़ें",
|
|
10396
10459
|
removeLayer: "परत हटाएं",
|
|
10397
10460
|
showLayer: "परत दिखाएं",
|
|
10398
10461
|
hideLayer: "परत छिपाएं",
|
|
@@ -10491,6 +10554,9 @@ const designCanvasFeatureOverrides = {
|
|
|
10491
10554
|
editPanel: {
|
|
10492
10555
|
labels: {
|
|
10493
10556
|
addLayer: "إضافة طبقة",
|
|
10557
|
+
addFill: "إضافة تعبئة",
|
|
10558
|
+
addStroke: "إضافة حدود",
|
|
10559
|
+
addEffect: "إضافة تأثير",
|
|
10494
10560
|
removeLayer: "إزالة طبقة",
|
|
10495
10561
|
showLayer: "إظهار الطبقة",
|
|
10496
10562
|
hideLayer: "إخفاء الطبقة",
|
|
@@ -13312,8 +13378,13 @@ const designFillStylesComingSoonOverrides = {
|
|
|
13312
13378
|
const designFramePresetsOverrides = {
|
|
13313
13379
|
"zh-CN": {
|
|
13314
13380
|
editPanel: {
|
|
13381
|
+
exportPreview: {
|
|
13382
|
+
rendering: "正在生成预览…",
|
|
13383
|
+
failed: "无法生成预览",
|
|
13384
|
+
},
|
|
13315
13385
|
framePresets: {
|
|
13316
13386
|
title: "画框",
|
|
13387
|
+
applyToFrame: "调整为预设尺寸",
|
|
13317
13388
|
categories: {
|
|
13318
13389
|
phone: "手机",
|
|
13319
13390
|
tablet: "平板",
|
|
@@ -13329,8 +13400,13 @@ const designFramePresetsOverrides = {
|
|
|
13329
13400
|
},
|
|
13330
13401
|
"es-ES": {
|
|
13331
13402
|
editPanel: {
|
|
13403
|
+
exportPreview: {
|
|
13404
|
+
rendering: "Generando vista previa…",
|
|
13405
|
+
failed: "Vista previa no disponible",
|
|
13406
|
+
},
|
|
13332
13407
|
framePresets: {
|
|
13333
13408
|
title: "Marco",
|
|
13409
|
+
applyToFrame: "Cambiar a tamaño predefinido",
|
|
13334
13410
|
categories: {
|
|
13335
13411
|
phone: "Teléfono",
|
|
13336
13412
|
tablet: "Tableta",
|
|
@@ -13346,8 +13422,13 @@ const designFramePresetsOverrides = {
|
|
|
13346
13422
|
},
|
|
13347
13423
|
"fr-FR": {
|
|
13348
13424
|
editPanel: {
|
|
13425
|
+
exportPreview: {
|
|
13426
|
+
rendering: "Génération de l'aperçu…",
|
|
13427
|
+
failed: "Aperçu indisponible",
|
|
13428
|
+
},
|
|
13349
13429
|
framePresets: {
|
|
13350
13430
|
title: "Cadre",
|
|
13431
|
+
applyToFrame: "Redimensionner selon un préréglage",
|
|
13351
13432
|
categories: {
|
|
13352
13433
|
phone: "Téléphone",
|
|
13353
13434
|
tablet: "Tablette",
|
|
@@ -13363,8 +13444,13 @@ const designFramePresetsOverrides = {
|
|
|
13363
13444
|
},
|
|
13364
13445
|
"de-DE": {
|
|
13365
13446
|
editPanel: {
|
|
13447
|
+
exportPreview: {
|
|
13448
|
+
rendering: "Vorschau wird erstellt…",
|
|
13449
|
+
failed: "Vorschau nicht verfügbar",
|
|
13450
|
+
},
|
|
13366
13451
|
framePresets: {
|
|
13367
13452
|
title: "Rahmen",
|
|
13453
|
+
applyToFrame: "Auf Voreinstellung anpassen",
|
|
13368
13454
|
categories: {
|
|
13369
13455
|
phone: "Telefon",
|
|
13370
13456
|
tablet: "Tablet",
|
|
@@ -13380,8 +13466,13 @@ const designFramePresetsOverrides = {
|
|
|
13380
13466
|
},
|
|
13381
13467
|
"ja-JP": {
|
|
13382
13468
|
editPanel: {
|
|
13469
|
+
exportPreview: {
|
|
13470
|
+
rendering: "プレビューを生成中…",
|
|
13471
|
+
failed: "プレビューを表示できません",
|
|
13472
|
+
},
|
|
13383
13473
|
framePresets: {
|
|
13384
13474
|
title: "フレーム",
|
|
13475
|
+
applyToFrame: "プリセットサイズに変更",
|
|
13385
13476
|
categories: {
|
|
13386
13477
|
phone: "電話",
|
|
13387
13478
|
tablet: "タブレット",
|
|
@@ -13397,8 +13488,13 @@ const designFramePresetsOverrides = {
|
|
|
13397
13488
|
},
|
|
13398
13489
|
"ko-KR": {
|
|
13399
13490
|
editPanel: {
|
|
13491
|
+
exportPreview: {
|
|
13492
|
+
rendering: "미리 보기 생성 중…",
|
|
13493
|
+
failed: "미리 보기를 사용할 수 없음",
|
|
13494
|
+
},
|
|
13400
13495
|
framePresets: {
|
|
13401
13496
|
title: "프레임",
|
|
13497
|
+
applyToFrame: "사전 설정 크기로 조정",
|
|
13402
13498
|
categories: {
|
|
13403
13499
|
phone: "휴대폰",
|
|
13404
13500
|
tablet: "태블릿",
|
|
@@ -13414,8 +13510,13 @@ const designFramePresetsOverrides = {
|
|
|
13414
13510
|
},
|
|
13415
13511
|
"pt-BR": {
|
|
13416
13512
|
editPanel: {
|
|
13513
|
+
exportPreview: {
|
|
13514
|
+
rendering: "Gerando pré-visualização…",
|
|
13515
|
+
failed: "Pré-visualização indisponível",
|
|
13516
|
+
},
|
|
13417
13517
|
framePresets: {
|
|
13418
13518
|
title: "Quadro",
|
|
13519
|
+
applyToFrame: "Redimensionar para predefinição",
|
|
13419
13520
|
categories: {
|
|
13420
13521
|
phone: "Celular",
|
|
13421
13522
|
tablet: "Tablet",
|
|
@@ -13431,8 +13532,13 @@ const designFramePresetsOverrides = {
|
|
|
13431
13532
|
},
|
|
13432
13533
|
"hi-IN": {
|
|
13433
13534
|
editPanel: {
|
|
13535
|
+
exportPreview: {
|
|
13536
|
+
rendering: "पूर्वावलोकन बन रहा है…",
|
|
13537
|
+
failed: "पूर्वावलोकन उपलब्ध नहीं",
|
|
13538
|
+
},
|
|
13434
13539
|
framePresets: {
|
|
13435
13540
|
title: "फ़्रेम",
|
|
13541
|
+
applyToFrame: "प्रीसेट आकार में बदलें",
|
|
13436
13542
|
categories: {
|
|
13437
13543
|
phone: "फ़ोन",
|
|
13438
13544
|
tablet: "टैबलेट",
|
|
@@ -13448,8 +13554,13 @@ const designFramePresetsOverrides = {
|
|
|
13448
13554
|
},
|
|
13449
13555
|
"ar-SA": {
|
|
13450
13556
|
editPanel: {
|
|
13557
|
+
exportPreview: {
|
|
13558
|
+
rendering: "جارٍ إنشاء المعاينة…",
|
|
13559
|
+
failed: "المعاينة غير متوفرة",
|
|
13560
|
+
},
|
|
13451
13561
|
framePresets: {
|
|
13452
13562
|
title: "الإطار",
|
|
13563
|
+
applyToFrame: "تغيير الحجم إلى إعداد مسبق",
|
|
13453
13564
|
categories: {
|
|
13454
13565
|
phone: "الهاتف",
|
|
13455
13566
|
tablet: "الجهاز اللوحي",
|
|
@@ -2,6 +2,7 @@ import type {
|
|
|
2
2
|
CanvasFrameGeometry,
|
|
3
3
|
CanvasFrameGeometryById,
|
|
4
4
|
} from "@shared/canvas-frames";
|
|
5
|
+
import { parseCssColor } from "@shared/color-utils";
|
|
5
6
|
|
|
6
7
|
export const KEEPALIVE_ACTION_MAX_BYTES = 60_000;
|
|
7
8
|
|
|
@@ -47,6 +48,50 @@ function valuesEqual(left: unknown, right: unknown): boolean {
|
|
|
47
48
|
return JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
|
|
48
49
|
}
|
|
49
50
|
|
|
51
|
+
/** Accepts a canvas background only if it parses as a CSS colour. It is
|
|
52
|
+
* interpolated into a style attribute, so an arbitrary string is an injection
|
|
53
|
+
* vector — this gates both the persisted value and any in-flight draft. */
|
|
54
|
+
export function sanitizeCanvasBackground(value: unknown): string | null {
|
|
55
|
+
if (typeof value !== "string") return null;
|
|
56
|
+
const trimmed = value.trim();
|
|
57
|
+
if (!trimmed) return null;
|
|
58
|
+
return parseCssColor(trimmed) ? trimmed : null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Design-level canvas background, or null when unset/unsafe. */
|
|
62
|
+
export function getDesignCanvasBackground(
|
|
63
|
+
designData: Record<string, unknown> | null | undefined,
|
|
64
|
+
): string | null {
|
|
65
|
+
if (!isRecord(designData)) return null;
|
|
66
|
+
return sanitizeCanvasBackground(designData.canvasBackground);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Breakpoint widths persisted on the design, ascending and de-duplicated.
|
|
70
|
+
* Reads the live design data rather than a screen's mirrored copy so callers
|
|
71
|
+
* running after a mutation see what is actually stored. */
|
|
72
|
+
export function getDesignBreakpointWidths(
|
|
73
|
+
designData: Record<string, unknown> | null | undefined,
|
|
74
|
+
): number[] {
|
|
75
|
+
if (!isRecord(designData)) return [];
|
|
76
|
+
const breakpointSet = designData.breakpointSet;
|
|
77
|
+
if (!isRecord(breakpointSet)) return [];
|
|
78
|
+
const breakpoints = breakpointSet.breakpoints;
|
|
79
|
+
if (!Array.isArray(breakpoints)) return [];
|
|
80
|
+
const widths = new Set<number>();
|
|
81
|
+
for (const entry of breakpoints) {
|
|
82
|
+
if (!isRecord(entry)) continue;
|
|
83
|
+
const widthPx = entry.widthPx;
|
|
84
|
+
if (
|
|
85
|
+
typeof widthPx === "number" &&
|
|
86
|
+
Number.isFinite(widthPx) &&
|
|
87
|
+
widthPx > 0
|
|
88
|
+
) {
|
|
89
|
+
widths.add(widthPx);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return [...widths].sort((a, b) => a - b);
|
|
93
|
+
}
|
|
94
|
+
|
|
50
95
|
export function viewportSizeFromFrameGeometry(
|
|
51
96
|
geometry: CanvasFrameGeometry | undefined,
|
|
52
97
|
): { width: number; height: number } | null {
|
|
@@ -109,6 +109,65 @@ export function computeDistributedPositions(
|
|
|
109
109
|
return next;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
/** One screen's own frame box plus the footprint its responsive row occupies. */
|
|
113
|
+
export interface ReflowCandidate {
|
|
114
|
+
id: string;
|
|
115
|
+
/** Resolved frame geometry, including screens with no persisted entry yet. */
|
|
116
|
+
geometry: { x: number; y: number; width: number; height: number };
|
|
117
|
+
/** Space actually painted, breakpoint frames included. */
|
|
118
|
+
footprint: AlignableRect;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function footprintsOverlap(rects: readonly AlignableRect[]): boolean {
|
|
122
|
+
return rects.some((a, i) =>
|
|
123
|
+
rects.some(
|
|
124
|
+
(b, j) =>
|
|
125
|
+
i !== j &&
|
|
126
|
+
a.x < b.x + b.width &&
|
|
127
|
+
b.x < a.x + a.width &&
|
|
128
|
+
a.y < b.y + b.height &&
|
|
129
|
+
b.y < a.y + a.height,
|
|
130
|
+
),
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Re-packs a board whose responsive rows have grown into each other, returning
|
|
136
|
+
* complete geometry per screen — including screens that had no persisted entry
|
|
137
|
+
* and were positioned by `getInitialFrameGeometry`. Returning only the moved
|
|
138
|
+
* x/y would drop those screens at the write-back, which is exactly the
|
|
139
|
+
* default-layout board that needs the reflow most.
|
|
140
|
+
*
|
|
141
|
+
* Empty when there is nothing to do, so a deliberately arranged,
|
|
142
|
+
* non-overlapping board is never rearranged.
|
|
143
|
+
*/
|
|
144
|
+
export function computeOverlapReflowGeometry(
|
|
145
|
+
candidates: readonly ReflowCandidate[],
|
|
146
|
+
): Map<string, { x: number; y: number; width: number; height: number }> {
|
|
147
|
+
const result = new Map<
|
|
148
|
+
string,
|
|
149
|
+
{ x: number; y: number; width: number; height: number }
|
|
150
|
+
>();
|
|
151
|
+
if (candidates.length < 2) return result;
|
|
152
|
+
const footprints = candidates.map((candidate) => candidate.footprint);
|
|
153
|
+
if (!footprintsOverlap(footprints)) return result;
|
|
154
|
+
const positions = computeTidyPositions(footprints);
|
|
155
|
+
if (positions.size === 0) return result;
|
|
156
|
+
for (const candidate of candidates) {
|
|
157
|
+
const position = positions.get(candidate.id);
|
|
158
|
+
if (!position) continue;
|
|
159
|
+
// Translate by the footprint's delta rather than adopting the packed origin
|
|
160
|
+
// as the frame origin. A rotated group's AABB origin is not its frame
|
|
161
|
+
// origin, so assigning it directly shifts the frame by the rotation offset.
|
|
162
|
+
result.set(candidate.id, {
|
|
163
|
+
...candidate.geometry,
|
|
164
|
+
x: candidate.geometry.x + (position.x - candidate.footprint.x),
|
|
165
|
+
y: candidate.geometry.y + (position.y - candidate.footprint.y),
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
|
|
112
171
|
export function computeTidyPositions(
|
|
113
172
|
rects: readonly AlignableRect[],
|
|
114
173
|
): Map<string, { x: number; y: number }> {
|