@agent-native/core 0.90.1 → 0.90.2

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.
Files changed (295) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +14 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/client/AgentPanel.tsx +1 -1
  5. package/corpus/core/src/client/rich-markdown-editor/useCollabReconcile.ts +11 -6
  6. package/corpus/core/src/client/use-action.ts +39 -2
  7. package/corpus/core/src/client/use-db-sync.ts +44 -18
  8. package/corpus/core/src/db/create-get-db.ts +32 -2
  9. package/corpus/core/src/server/framework-request-handler.ts +52 -4
  10. package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +5 -0
  11. package/corpus/templates/assets/.agents/skills/logo-composite/SKILL.md +34 -6
  12. package/corpus/templates/assets/AGENTS.md +23 -4
  13. package/corpus/templates/assets/actions/_generation-preset-settings.ts +48 -0
  14. package/corpus/templates/assets/actions/_helpers.ts +8 -1
  15. package/corpus/templates/assets/actions/_preset-skeleton-validation.ts +64 -0
  16. package/corpus/templates/assets/actions/create-generation-preset.ts +11 -3
  17. package/corpus/templates/assets/actions/generate-image-batch.ts +7 -2
  18. package/corpus/templates/assets/actions/generate-image.ts +342 -25
  19. package/corpus/templates/assets/actions/get-library.ts +4 -3
  20. package/corpus/templates/assets/actions/navigate.ts +2 -1
  21. package/corpus/templates/assets/actions/refresh-generation-run.ts +5 -1
  22. package/corpus/templates/assets/actions/update-asset.ts +1 -0
  23. package/corpus/templates/assets/actions/update-generation-preset.ts +8 -1
  24. package/corpus/templates/assets/actions/view-screen.ts +8 -1
  25. package/corpus/templates/assets/app/components/generation/GenerationResults.tsx +9 -1
  26. package/corpus/templates/assets/app/hooks/use-image-model-menu.ts +1 -0
  27. package/corpus/templates/assets/app/hooks/use-navigation-state.ts +11 -0
  28. package/corpus/templates/assets/app/i18n/zh-TW.ts +64 -0
  29. package/corpus/templates/assets/app/i18n-data.ts +650 -0
  30. package/corpus/templates/assets/app/routes/asset.$id.tsx +2 -1
  31. package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +44 -33
  32. package/corpus/templates/assets/app/routes/brand-kits.$id_.presets.$presetId.tsx +1474 -0
  33. package/corpus/templates/assets/app/routes/library.tsx +43 -1
  34. package/corpus/templates/assets/server/lib/generation.ts +366 -44
  35. package/corpus/templates/assets/server/lib/image-processing.ts +252 -0
  36. package/corpus/templates/assets/server/lib/preset-skeleton.ts +137 -0
  37. package/corpus/templates/assets/shared/api.ts +47 -0
  38. package/corpus/templates/clips/app/components/library/library-layout.tsx +7 -2
  39. package/corpus/templates/clips/app/components/library/sort-menu.tsx +1 -1
  40. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +114 -33
  41. package/corpus/templates/clips/app/routes/_app.library._index.tsx +27 -1
  42. package/corpus/templates/clips/app/routes/record.tsx +157 -68
  43. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +5 -5
  44. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +20 -3
  45. package/corpus/templates/clips/shared/finalize-recovery.ts +23 -3
  46. package/corpus/templates/content/AGENTS.md +52 -52
  47. package/corpus/templates/content/actions/_builder-cms-read-client.ts +188 -8
  48. package/corpus/templates/content/actions/_builder-docs-client.ts +41 -3
  49. package/corpus/templates/content/actions/_database-source-utils.ts +998 -160
  50. package/corpus/templates/content/actions/_database-utils.ts +44 -4
  51. package/corpus/templates/content/actions/_notion-action-utils.ts +6 -2
  52. package/corpus/templates/content/actions/add-content-database-source-field-property.ts +23 -1
  53. package/corpus/templates/content/actions/attach-content-database-source.ts +85 -12
  54. package/corpus/templates/content/actions/change-content-database-source-role.ts +9 -1
  55. package/corpus/templates/content/actions/delete-content-database.ts +1 -0
  56. package/corpus/templates/content/actions/get-document.ts +11 -2
  57. package/corpus/templates/content/actions/list-content-databases.ts +57 -9
  58. package/corpus/templates/content/actions/prepare-builder-source-review.ts +23 -6
  59. package/corpus/templates/content/actions/refresh-content-database-source.ts +26 -3
  60. package/corpus/templates/content/actions/restore-content-database.ts +1 -0
  61. package/corpus/templates/content/actions/update-document.ts +43 -0
  62. package/corpus/templates/content/app/components/editor/BuilderBodySyncingNotice.tsx +21 -0
  63. package/corpus/templates/content/app/components/editor/DocumentDatabase.tsx +0 -1
  64. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +70 -28
  65. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +69 -17
  66. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +4 -4
  67. package/corpus/templates/content/app/components/editor/body-hydration.ts +112 -0
  68. package/corpus/templates/content/app/components/editor/builder-body-hydration-pump.ts +52 -0
  69. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +9076 -2876
  70. package/corpus/templates/content/app/components/editor/database-sources/BuilderSourceReviewDialog.tsx +41 -1
  71. package/corpus/templates/content/app/components/editor/extensions/ImageBlock.tsx +36 -11
  72. package/corpus/templates/content/app/components/editor/previewDocumentSaveController.ts +21 -1
  73. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +11 -1
  74. package/corpus/templates/content/app/components/sidebar/DocumentTreeItem.tsx +11 -8
  75. package/corpus/templates/content/app/global.css +41 -0
  76. package/corpus/templates/content/app/hooks/use-content-database.ts +346 -42
  77. package/corpus/templates/content/app/hooks/use-db-sync.ts +9 -0
  78. package/corpus/templates/content/app/hooks/use-documents.ts +47 -0
  79. package/corpus/templates/content/app/hooks/use-notion.ts +12 -10
  80. package/corpus/templates/content/app/i18n/zh-TW.ts +35 -0
  81. package/corpus/templates/content/app/i18n-data.ts +355 -0
  82. package/corpus/templates/content/app/root.tsx +22 -0
  83. package/corpus/templates/content/changelog/2026-07-01-builder-database-sources-keep-loading-rows-in-the-background.md +6 -0
  84. package/corpus/templates/content/changelog/2026-07-01-builder-source-attach-starts-with-usable-rows.md +6 -0
  85. package/corpus/templates/content/changelog/2026-07-01-builder-source-attachment-now-stays-connected-after-large.md +6 -0
  86. package/corpus/templates/content/changelog/2026-07-01-builder-source-refreshes-now-show-progress-for-large-docs-blog.md +6 -0
  87. package/corpus/templates/content/changelog/2026-07-01-database-pages-now-delete-to-trash-without-route-errors.md +6 -0
  88. package/corpus/templates/content/changelog/2026-07-02-builder-source-refreshes-recover-from-stalled-background-row.md +6 -0
  89. package/corpus/templates/content/changelog/2026-07-02-builder-sourced-rows-open-with-sync-protection.md +6 -0
  90. package/corpus/templates/content/changelog/2026-07-02-database-rows-and-pages-open-faster-from-recently-loaded-dat.md +6 -0
  91. package/corpus/templates/content/changelog/2026-07-02-preview-panels-close-reliably-narrow-sidebar-row-actions-sta.md +6 -0
  92. package/corpus/templates/content/changelog/2026-07-06-builder-sync-progress-no-longer-shows-continue.md +6 -0
  93. package/corpus/templates/content/shared/api.ts +13 -0
  94. package/corpus/templates/content/shared/builder-mdx.ts +16 -3
  95. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +23 -13
  96. package/corpus/templates/design/.agents/skills/responsive-breakpoints/SKILL.md +98 -0
  97. package/corpus/templates/design/.agents/skills/shader-fills/SKILL.md +162 -0
  98. package/corpus/templates/design/AGENTS.md +9 -2
  99. package/corpus/templates/design/actions/add-breakpoint.ts +6 -3
  100. package/corpus/templates/design/actions/apply-a11y-fix.ts +57 -37
  101. package/corpus/templates/design/actions/apply-component-prop-edit.ts +41 -20
  102. package/corpus/templates/design/actions/apply-motion-edit.ts +251 -38
  103. package/corpus/templates/design/actions/apply-shader-fill.ts +90 -66
  104. package/corpus/templates/design/actions/apply-visual-edit.ts +282 -55
  105. package/corpus/templates/design/actions/create-component.ts +29 -60
  106. package/corpus/templates/design/actions/create-file.ts +9 -2
  107. package/corpus/templates/design/actions/duplicate-design.ts +31 -2
  108. package/corpus/templates/design/actions/edit-design.ts +36 -38
  109. package/corpus/templates/design/actions/generate-design-title.ts +87 -0
  110. package/corpus/templates/design/actions/generate-design.ts +53 -18
  111. package/corpus/templates/design/actions/generate-screens.ts +108 -4
  112. package/corpus/templates/design/actions/get-motion-timeline.ts +35 -7
  113. package/corpus/templates/design/actions/insert-asset.ts +34 -29
  114. package/corpus/templates/design/actions/insert-design-native-asset.ts +129 -32
  115. package/corpus/templates/design/actions/insert-figma-library-asset.ts +35 -30
  116. package/corpus/templates/design/actions/present-design-variants.ts +7 -2
  117. package/corpus/templates/design/actions/remove-motion-timeline.ts +31 -36
  118. package/corpus/templates/design/actions/update-file.ts +190 -75
  119. package/corpus/templates/design/app/components/design/BreakpointBar.tsx +403 -0
  120. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +469 -222
  121. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +708 -53
  122. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +83 -3
  123. package/corpus/templates/design/app/components/design/EditPanel.tsx +1091 -6948
  124. package/corpus/templates/design/app/components/design/LayersPanel.tsx +419 -85
  125. package/corpus/templates/design/app/components/design/MotionDock.tsx +1124 -103
  126. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +2610 -1398
  127. package/corpus/templates/design/app/components/design/ReadOnlyDesignBanner.tsx +22 -0
  128. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +2182 -235
  129. package/corpus/templates/design/app/components/design/bridge/motion-preview.bridge.ts +187 -11
  130. package/corpus/templates/design/app/components/design/bridge/shader-fill-preview.bridge.ts +376 -1
  131. package/corpus/templates/design/app/components/design/bridge/shader-runtime.bridge.ts +746 -0
  132. package/corpus/templates/design/app/components/design/canvas-primitive-style.ts +17 -0
  133. package/corpus/templates/design/app/components/design/code-workbench/SideBar.tsx +1 -1
  134. package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +1 -3
  135. package/corpus/templates/design/app/components/design/code-workbench/quickinput/QuickInput.tsx +1 -1
  136. package/corpus/templates/design/app/components/design/edit-panel/appearance-properties.tsx +518 -0
  137. package/corpus/templates/design/app/components/design/edit-panel/code-inspect-helpers.tsx +562 -0
  138. package/corpus/templates/design/app/components/design/edit-panel/component-section.tsx +763 -0
  139. package/corpus/templates/design/app/components/design/edit-panel/document-colors.ts +94 -0
  140. package/corpus/templates/design/app/components/design/edit-panel/effects-properties.tsx +780 -0
  141. package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +446 -0
  142. package/corpus/templates/design/app/components/design/edit-panel/element-identity.ts +79 -0
  143. package/corpus/templates/design/app/components/design/edit-panel/field-primitives.tsx +315 -0
  144. package/corpus/templates/design/app/components/design/edit-panel/fill-gradient-helpers.ts +344 -0
  145. package/corpus/templates/design/app/components/design/edit-panel/fill-properties.tsx +594 -0
  146. package/corpus/templates/design/app/components/design/edit-panel/frame-presets-panel.tsx +119 -0
  147. package/corpus/templates/design/app/components/design/edit-panel/inspector-controls.tsx +248 -0
  148. package/corpus/templates/design/app/components/design/edit-panel/interaction-state-helpers.ts +45 -0
  149. package/corpus/templates/design/app/components/design/edit-panel/layout-properties.tsx +693 -0
  150. package/corpus/templates/design/app/components/design/edit-panel/panel-primitives.tsx +724 -0
  151. package/corpus/templates/design/app/components/design/edit-panel/position-helpers.ts +207 -0
  152. package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +628 -0
  153. package/corpus/templates/design/app/components/design/edit-panel/selection-helpers.ts +91 -0
  154. package/corpus/templates/design/app/components/design/edit-panel/stroke-properties.tsx +649 -0
  155. package/corpus/templates/design/app/components/design/edit-panel/style-change-types.ts +118 -0
  156. package/corpus/templates/design/app/components/design/edit-panel/style-options.ts +88 -0
  157. package/corpus/templates/design/app/components/design/edit-panel/transform-helpers.ts +100 -0
  158. package/corpus/templates/design/app/components/design/edit-panel/typography-helpers.ts +117 -0
  159. package/corpus/templates/design/app/components/design/edit-panel/typography-properties.tsx +501 -0
  160. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +91 -40
  161. package/corpus/templates/design/app/components/design/inspector/BreakpointOverrideIndicator.tsx +82 -0
  162. package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +189 -87
  163. package/corpus/templates/design/app/components/design/inspector/GlslShaderPanel.tsx +1097 -0
  164. package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +44 -0
  165. package/corpus/templates/design/app/components/design/inspector/InteractionStatePanel.tsx +258 -0
  166. package/corpus/templates/design/app/components/design/inspector/MotionKeyframeDiamond.tsx +144 -0
  167. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +99 -9
  168. package/corpus/templates/design/app/components/design/inspector/frame-size-presets.ts +116 -0
  169. package/corpus/templates/design/app/components/design/inspector/index.ts +26 -0
  170. package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +29 -0
  171. package/corpus/templates/design/app/components/design/multi-screen/alt-hover-measurement.ts +171 -0
  172. package/corpus/templates/design/app/components/design/multi-screen/board-surface-html.ts +220 -0
  173. package/corpus/templates/design/app/components/design/multi-screen/chrome-transitions.ts +35 -0
  174. package/corpus/templates/design/app/components/design/multi-screen/cross-screen-drop.ts +134 -0
  175. package/corpus/templates/design/app/components/design/multi-screen/culling.ts +185 -0
  176. package/corpus/templates/design/app/components/design/multi-screen/gradient-overlay-geometry.ts +120 -0
  177. package/corpus/templates/design/app/components/design/multi-screen/types.ts +892 -0
  178. package/corpus/templates/design/app/components/design/multi-screen/vector-edit-geometry.ts +21 -0
  179. package/corpus/templates/design/app/components/design/types.ts +15 -0
  180. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +109 -5
  181. package/corpus/templates/design/app/global.css +8 -8
  182. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +259 -2
  183. package/corpus/templates/design/app/i18n/zh-TW.ts +163 -9
  184. package/corpus/templates/design/app/i18n-breakpoints.ts +205 -0
  185. package/corpus/templates/design/app/i18n-data.ts +1664 -152
  186. package/corpus/templates/design/app/i18n-motion.ts +563 -0
  187. package/corpus/templates/design/app/lib/design-import.ts +73 -0
  188. package/corpus/templates/design/app/pages/Index.tsx +41 -22
  189. package/corpus/templates/design/changelog/2026-06-29-design-inspector-controls-now-match-figmas-softer-dark-chrome.md +1 -1
  190. package/corpus/templates/design/changelog/2026-06-30-design-now-has-a-figma-style-left-rail-for-file-agent-assets.md +1 -1
  191. package/corpus/templates/design/changelog/2026-06-30-design-tools-now-use-a-quieter-figma-style-list-layout.md +1 -1
  192. package/corpus/templates/design/changelog/2026-06-30-multi-select-outlines-now-stay-consistent-across-all-screens.md +1 -1
  193. package/corpus/templates/design/changelog/2026-07-03-canvas-interactions-now-match-figma-rotation-aware-resizing-.md +1 -1
  194. package/corpus/templates/design/changelog/2026-07-03-layers-panel-matches-figma-top-layer-on-top-drag-with-auto-s.md +1 -1
  195. package/corpus/templates/design/changelog/2026-07-05-designs-get-ai-generated-names-from-your-prompt.md +6 -0
  196. package/corpus/templates/design/changelog/2026-07-05-local-code-screens-keep-their-connection-when-duplicated-and.md +6 -0
  197. package/corpus/templates/design/changelog/2026-07-05-press-a-to-draw-screens-on-the-canvas-inside-a-screen-it-dr.md +6 -0
  198. package/corpus/templates/design/changelog/2026-07-06-3d-rotation-and-perspective-controls-on-every-element.md +6 -0
  199. package/corpus/templates/design/changelog/2026-07-06-ai-generated-and-duplicated-screens-now-get-their-editor-sel.md +6 -0
  200. package/corpus/templates/design/changelog/2026-07-06-applying-shaders-and-fills-in-quick-succession-can-no-longer.md +6 -0
  201. package/corpus/templates/design/changelog/2026-07-06-breakpoint-frames-in-the-overview-now-support-click-to-selec.md +6 -0
  202. package/corpus/templates/design/changelog/2026-07-06-breakpoint-segments-in-the-inspector-now-show-a-device-icon-.md +6 -0
  203. package/corpus/templates/design/changelog/2026-07-06-breakpoint-targeting-now-lives-in-one-compact-control-in-the.md +6 -0
  204. package/corpus/templates/design/changelog/2026-07-06-canvas-edits-can-no-longer-be-overwritten-by-stale-collabora.md +6 -0
  205. package/corpus/templates/design/changelog/2026-07-06-canvas-edits-inside-screens-save-reliably-again.md +6 -0
  206. package/corpus/templates/design/changelog/2026-07-06-cleaner-inspector-removed-the-ask-ai-box-from-the-design-tab.md +6 -0
  207. package/corpus/templates/design/changelog/2026-07-06-clicking-empty-canvas-space-now-deselects-an-element-inside-.md +6 -0
  208. package/corpus/templates/design/changelog/2026-07-06-dragging-an-element-onto-a-rectangle-now-nests-it-inside-wit.md +6 -0
  209. package/corpus/templates/design/changelog/2026-07-06-dragging-screens-and-objects-on-the-canvas-is-now-much-smoot.md +6 -0
  210. package/corpus/templates/design/changelog/2026-07-06-drawing-a-shape-or-text-on-the-canvas-no-longer-flashes-away.md +6 -0
  211. package/corpus/templates/design/changelog/2026-07-06-dropping-an-element-between-two-others-inside-a-screen-now-s.md +6 -0
  212. package/corpus/templates/design/changelog/2026-07-06-duplicating-a-screen-now-places-the-copy-exactly-where-you-d.md +6 -0
  213. package/corpus/templates/design/changelog/2026-07-06-edit-gradients-directly-on-elements-inside-screens-scale-str.md +6 -0
  214. package/corpus/templates/design/changelog/2026-07-06-edits-from-collaborators-and-the-agent-now-update-the-canvas.md +6 -0
  215. package/corpus/templates/design/changelog/2026-07-06-fixed-a-bug-where-most-style-position-and-text-edits-briefly.md +6 -0
  216. package/corpus/templates/design/changelog/2026-07-06-fixed-a-confusing-raw-error-message-when-a-file-upload-fails.md +6 -0
  217. package/corpus/templates/design/changelog/2026-07-06-fixed-a-rare-case-where-an-edit-could-be-silently-overwritte.md +6 -0
  218. package/corpus/templates/design/changelog/2026-07-06-fixed-inserted-assets-sometimes-disappearing-reappearing-or-.md +6 -0
  219. package/corpus/templates/design/changelog/2026-07-06-fixed-inspector-value-scrubbing-producing-erratic-numbers-an.md +6 -0
  220. package/corpus/templates/design/changelog/2026-07-06-fixed-padding-gap-and-min-max-size-scrubbing-not-updating-th.md +6 -0
  221. package/corpus/templates/design/changelog/2026-07-06-fixed-text-stroke-color-turning-black-and-glyphs-disappearin.md +6 -0
  222. package/corpus/templates/design/changelog/2026-07-06-fixed-the-collapsed-effects-and-stroke-inspector-sections-sh.md +6 -0
  223. package/corpus/templates/design/changelog/2026-07-06-fixed-the-new-design-dialog-closing-unexpectedly-when-using-.md +6 -0
  224. package/corpus/templates/design/changelog/2026-07-06-fixed-the-typography-section-missing-when-selecting-text-nes.md +6 -0
  225. package/corpus/templates/design/changelog/2026-07-06-full-view-no-longer-flashes-back-to-the-overview-on-entry-no.md +6 -0
  226. package/corpus/templates/design/changelog/2026-07-06-keyframe-animation-timeline-per-property-keyframes-easing-cu.md +6 -0
  227. package/corpus/templates/design/changelog/2026-07-06-moving-restyling-and-scrubbing-values-on-elements-in-ai-gene.md +6 -0
  228. package/corpus/templates/design/changelog/2026-07-06-padding-and-corner-radius-value-scrubbing-now-snaps-to-whole.md +6 -0
  229. package/corpus/templates/design/changelog/2026-07-06-padding-handles-now-only-resize-on-the-handle-line-itself-sh.md +6 -0
  230. package/corpus/templates/design/changelog/2026-07-06-preview-and-edit-hover-focus-and-pressed-states-with-real-cs.md +6 -0
  231. package/corpus/templates/design/changelog/2026-07-06-promoting-an-element-to-a-component-now-works-correctly-for-.md +6 -0
  232. package/corpus/templates/design/changelog/2026-07-06-reduced-url-history-churn-and-selection-overlay-flicker-whil.md +6 -0
  233. package/corpus/templates/design/changelog/2026-07-06-removed-the-decorative-dot-before-screen-names-in-the-overvi.md +6 -0
  234. package/corpus/templates/design/changelog/2026-07-06-responsive-breakpoints-edit-at-any-width-with-cascading-over.md +6 -0
  235. package/corpus/templates/design/changelog/2026-07-06-screen-labels-no-longer-turn-blue-when-you-hover-inside-the-.md +6 -0
  236. package/corpus/templates/design/changelog/2026-07-06-scrolling-a-screen-with-an-element-selected-stays-smooth-on-.md +6 -0
  237. package/corpus/templates/design/changelog/2026-07-06-selecting-multiple-elements-and-dragging-now-moves-the-whole.md +6 -0
  238. package/corpus/templates/design/changelog/2026-07-06-selection-borders-handles-and-value-readouts-now-stay-the-sa.md +6 -0
  239. package/corpus/templates/design/changelog/2026-07-06-selection-handles-and-editing-chrome-now-stay-a-constant-siz.md +6 -0
  240. package/corpus/templates/design/changelog/2026-07-06-shader-fills-and-effects-ai-authored-or-preset-glsl-shaders-.md +6 -0
  241. package/corpus/templates/design/changelog/2026-07-06-text-drawn-on-the-canvas-now-defaults-to-white-and-inter-in-.md +6 -0
  242. package/corpus/templates/design/changelog/2026-07-06-text-dropped-into-a-shape-now-stays-readable-instead-of-disa.md +6 -0
  243. package/corpus/templates/design/changelog/2026-07-06-the-add-tweak-controls-prompt-no-longer-jumps-to-the-corner-.md +6 -0
  244. package/corpus/templates/design/changelog/2026-07-06-the-padding-value-readout-now-stays-visible-while-you-hover-.md +6 -0
  245. package/corpus/templates/design/changelog/2026-07-06-the-selected-element-attachment-now-clears-from-the-chat-com.md +6 -0
  246. package/corpus/templates/design/changelog/2026-07-06-the-zoom-menu-is-more-compact-with-tight-rows-and-right-alig.md +6 -0
  247. package/corpus/templates/design/changelog/2026-07-06-undo-and-redo-no-longer-flash-the-screen-changes-now-apply-i.md +6 -0
  248. package/corpus/templates/design/changelog/2026-07-06-zoom-presets-like-zoom-to-50-now-stay-on-the-focused-screen-.md +6 -0
  249. package/corpus/templates/design/server/lib/import-design-files.ts +11 -2
  250. package/corpus/templates/design/server/source-workspace.ts +139 -59
  251. package/corpus/templates/design/shared/board-file.ts +11 -2
  252. package/corpus/templates/design/shared/breakpoint-media.ts +543 -0
  253. package/corpus/templates/design/shared/canvas-math.ts +354 -35
  254. package/corpus/templates/design/shared/code-layer.ts +277 -8
  255. package/corpus/templates/design/shared/design-state.ts +11 -4
  256. package/corpus/templates/design/shared/interaction-states.ts +548 -0
  257. package/corpus/templates/design/shared/motion-compiler.ts +186 -23
  258. package/corpus/templates/design/shared/motion-easing.ts +294 -0
  259. package/corpus/templates/design/shared/motion-timeline.ts +400 -34
  260. package/corpus/templates/design/shared/prompt-title.ts +95 -0
  261. package/corpus/templates/design/shared/responsive-classes.ts +448 -10
  262. package/corpus/templates/design/shared/screen-annotation.ts +46 -0
  263. package/corpus/templates/design/shared/shader-fills.ts +1009 -0
  264. package/corpus/templates/design/shared/shader-presets.ts +852 -4
  265. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +15 -2
  266. package/corpus/templates/slides/app/components/editor/ImportButton.tsx +10 -1
  267. package/corpus/templates/slides/app/lib/upload-response.ts +71 -0
  268. package/dist/client/AgentPanel.js +1 -1
  269. package/dist/client/AgentPanel.js.map +1 -1
  270. package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -1
  271. package/dist/client/rich-markdown-editor/useCollabReconcile.js +11 -6
  272. package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -1
  273. package/dist/client/use-action.d.ts +3 -0
  274. package/dist/client/use-action.d.ts.map +1 -1
  275. package/dist/client/use-action.js +34 -3
  276. package/dist/client/use-action.js.map +1 -1
  277. package/dist/client/use-db-sync.d.ts +4 -0
  278. package/dist/client/use-db-sync.d.ts.map +1 -1
  279. package/dist/client/use-db-sync.js +37 -18
  280. package/dist/client/use-db-sync.js.map +1 -1
  281. package/dist/collab/routes.d.ts +1 -1
  282. package/dist/collab/struct-routes.d.ts +1 -1
  283. package/dist/db/create-get-db.d.ts +25 -0
  284. package/dist/db/create-get-db.d.ts.map +1 -1
  285. package/dist/db/create-get-db.js +25 -2
  286. package/dist/db/create-get-db.js.map +1 -1
  287. package/dist/observability/routes.d.ts +3 -3
  288. package/dist/secrets/routes.d.ts +9 -9
  289. package/dist/server/framework-request-handler.d.ts.map +1 -1
  290. package/dist/server/framework-request-handler.js +37 -1
  291. package/dist/server/framework-request-handler.js.map +1 -1
  292. package/package.json +1 -1
  293. package/corpus/templates/design/app/components/design/inspector/InspectorAiActions.tsx +0 -153
  294. package/corpus/templates/design/app/hooks/useAgentEditRequest.ts +0 -133
  295. package/corpus/templates/design/app/pages/DesignEditor.tsx +0 -22924
@@ -0,0 +1,501 @@
1
+ import { useT } from "@agent-native/core/client";
2
+ import {
3
+ IconAlignCenter,
4
+ IconAlignJustified,
5
+ IconAlignLeft,
6
+ IconAlignRight,
7
+ IconArrowAutofitHeight,
8
+ IconArrowAutofitWidth,
9
+ IconLayoutAlignBottom,
10
+ IconLayoutAlignMiddle,
11
+ IconLayoutAlignTop,
12
+ IconLetterCase,
13
+ IconLetterSpacing,
14
+ IconLineHeight,
15
+ IconSquare,
16
+ } from "@tabler/icons-react";
17
+ import { useState } from "react";
18
+
19
+ import { Button } from "@/components/ui/button";
20
+ import {
21
+ Popover,
22
+ PopoverContent,
23
+ PopoverTrigger,
24
+ } from "@/components/ui/popover";
25
+ import {
26
+ Select,
27
+ SelectContent,
28
+ SelectItem,
29
+ SelectTrigger,
30
+ SelectValue,
31
+ } from "@/components/ui/select";
32
+ import {
33
+ Tooltip,
34
+ TooltipContent,
35
+ TooltipTrigger,
36
+ } from "@/components/ui/tooltip";
37
+ import { cn } from "@/lib/utils";
38
+
39
+ import { ScrubInput } from "../inspector";
40
+ import { IconLayoutSettings } from "../inspector/design-icons";
41
+ import type { ElementInfo } from "../types";
42
+ import { InspectorIconButton, InspectorSegment } from "./inspector-controls";
43
+ import { authoredStyleValue } from "./interaction-state-helpers";
44
+ import { PanelSection } from "./panel-primitives";
45
+ import { roundToOneDecimal } from "./position-helpers";
46
+ import { isMixedValue, MIXED_VALUE } from "./selection-helpers";
47
+ import type { StyleChangeHandler } from "./style-change-types";
48
+ import { parseNumericValue, resolveLineHeight } from "./style-options";
49
+ import {
50
+ displayFontFamilyName,
51
+ FONT_FAMILY_OPTIONS,
52
+ FONT_WEIGHT_OPTIONS,
53
+ resolveFontFamilySelectValue,
54
+ type TextResizeMode,
55
+ } from "./typography-helpers";
56
+
57
+ function TextResizeControls({
58
+ resizeMode,
59
+ onResizeModeChange,
60
+ }: {
61
+ resizeMode: TextResizeMode;
62
+ onResizeModeChange: (mode: TextResizeMode) => void;
63
+ }) {
64
+ const t = useT();
65
+
66
+ return (
67
+ <InspectorSegment>
68
+ <InspectorIconButton
69
+ label={t("editPanel.textResize.autoWidth")}
70
+ active={resizeMode === "auto-width"}
71
+ onClick={() => onResizeModeChange("auto-width")}
72
+ >
73
+ <IconArrowAutofitWidth className="size-3.5" />
74
+ </InspectorIconButton>
75
+ <InspectorIconButton
76
+ label={t("editPanel.textResize.autoHeight")}
77
+ active={resizeMode === "auto-height"}
78
+ onClick={() => onResizeModeChange("auto-height")}
79
+ >
80
+ <IconArrowAutofitHeight className="size-3.5" />
81
+ </InspectorIconButton>
82
+ <InspectorIconButton
83
+ label={t("editPanel.textResize.fixed")}
84
+ active={resizeMode === "fixed"}
85
+ onClick={() => onResizeModeChange("fixed")}
86
+ >
87
+ <IconSquare className="size-3.5" />
88
+ </InspectorIconButton>
89
+ </InspectorSegment>
90
+ );
91
+ }
92
+
93
+ function TypographyDetailsPopover({
94
+ resizeMode,
95
+ onResizeModeChange,
96
+ }: {
97
+ resizeMode: TextResizeMode;
98
+ onResizeModeChange: (mode: TextResizeMode) => void;
99
+ }) {
100
+ const [open, setOpen] = useState(false);
101
+
102
+ return (
103
+ <Popover open={open} onOpenChange={setOpen}>
104
+ <Tooltip>
105
+ <TooltipTrigger asChild>
106
+ <PopoverTrigger asChild>
107
+ <Button
108
+ type="button"
109
+ variant="ghost"
110
+ size="icon"
111
+ aria-label={"Typography details" /* i18n-ignore design action */}
112
+ aria-pressed={open}
113
+ className={cn(
114
+ "h-6 min-w-6 cursor-pointer rounded-md text-muted-foreground hover:bg-[var(--design-editor-panel-raised-bg)] hover:text-foreground",
115
+ open &&
116
+ "bg-[var(--design-editor-accent-color)]/20 text-[var(--design-editor-accent-color)] hover:text-[var(--design-editor-accent-color)]",
117
+ )}
118
+ >
119
+ <IconLayoutSettings className="size-3.5" />
120
+ </Button>
121
+ </PopoverTrigger>
122
+ </TooltipTrigger>
123
+ <TooltipContent>
124
+ {"Typography details" /* i18n-ignore design action */}
125
+ </TooltipContent>
126
+ </Tooltip>
127
+ <PopoverContent
128
+ side="left"
129
+ align="end"
130
+ sideOffset={8}
131
+ className="z-[100010] w-[360px] rounded-xl border-[var(--design-editor-control-border)] bg-[var(--design-editor-panel-bg)] p-0 text-foreground shadow-2xl"
132
+ >
133
+ <div className="flex items-center gap-1 border-b border-[var(--design-editor-control-border)] p-2.5">
134
+ <div className="flex rounded-md bg-[var(--design-editor-control-bg)] p-0.5">
135
+ <span className="rounded bg-[var(--design-editor-panel-raised-bg)] px-2.5 py-1 !text-[11px] font-semibold text-foreground">
136
+ {"Basics" /* i18n-ignore design typography details tab */}
137
+ </span>
138
+ <span className="px-2.5 py-1 !text-[11px] font-medium text-muted-foreground">
139
+ {"Details" /* i18n-ignore design typography details tab */}
140
+ </span>
141
+ <span className="px-2.5 py-1 !text-[11px] font-medium text-muted-foreground">
142
+ {"Variable" /* i18n-ignore design typography details tab */}
143
+ </span>
144
+ </div>
145
+ </div>
146
+ <div className="space-y-3 p-4 !text-[11px]">
147
+ <div className="flex h-20 items-center justify-center rounded-md bg-[var(--design-editor-control-bg)] text-[18px] text-muted-foreground/80">
148
+ {"Preview" /* i18n-ignore design typography details preview */}
149
+ </div>
150
+ <div className="flex items-center justify-between gap-3">
151
+ <span className="!text-[11px] font-medium text-muted-foreground">
152
+ {"Text box" /* i18n-ignore design typography details label */}
153
+ </span>
154
+ <TextResizeControls
155
+ resizeMode={resizeMode}
156
+ onResizeModeChange={onResizeModeChange}
157
+ />
158
+ </div>
159
+ </div>
160
+ </PopoverContent>
161
+ </Popover>
162
+ );
163
+ }
164
+
165
+ /** Text element properties */
166
+ export function TypographyProperties({
167
+ element,
168
+ onStyleChange,
169
+ }: {
170
+ element: ElementInfo;
171
+ onStyleChange: StyleChangeHandler;
172
+ }) {
173
+ const t = useT();
174
+ const styles = element.computedStyles;
175
+ const baseFontFamilyOptions = FONT_FAMILY_OPTIONS.map((option) => ({
176
+ value: option.value,
177
+ label: t(`editPanel.fontFamilies.${option.key}`),
178
+ }));
179
+ const fontFamily = resolveFontFamilySelectValue(styles.fontFamily);
180
+ const fontFamilyOptions = FONT_FAMILY_OPTIONS.some(
181
+ (option) => option.value === fontFamily,
182
+ )
183
+ ? baseFontFamilyOptions
184
+ : [
185
+ {
186
+ value: fontFamily,
187
+ label: displayFontFamilyName(styles.fontFamily || fontFamily),
188
+ },
189
+ ...baseFontFamilyOptions,
190
+ ];
191
+ const fontWeightOptions = FONT_WEIGHT_OPTIONS.map((option) => ({
192
+ value: option.value,
193
+ label: t(`editPanel.fontWeights.${option.key}`),
194
+ }));
195
+ const textAlign = styles.textAlign || "left";
196
+
197
+ // Mixed-selection guards: a multi-selection with differing values injects
198
+ // the MIXED_VALUE sentinel string into these computedStyles fields (see
199
+ // mixedElementFromSelection/sameOrMixed). Parsing that sentinel with
200
+ // parseNumericValue/Number() silently yields 0/NaN-fallback instead of
201
+ // reflecting "differs across selection", which previously showed a
202
+ // fabricated 0 (size), 1.2 (line-height), or blank (tracking) rather than
203
+ // the Mixed state ScrubInput already knows how to render — same pattern as
204
+ // the rotation field above.
205
+ const fontWeightIsMixed = isMixedValue(styles.fontWeight);
206
+ const fontSizeIsMixed = isMixedValue(styles.fontSize);
207
+ const lineHeightIsMixed = isMixedValue(styles.lineHeight);
208
+ const letterSpacingIsMixed = isMixedValue(styles.letterSpacing);
209
+
210
+ // M1 · Text resizing mode (auto-width / auto-height / fixed). the design
211
+ // editor's text nodes always expose this segment. Read authored
212
+ // (inlineStyles) values, not computed ones: an absolutely-positioned
213
+ // element's computed width/height always resolve to a real px value even
214
+ // when the author never set them, so "auto" and "a specific 200px" were
215
+ // indistinguishable before — every text node misread as "fixed". Falls
216
+ // back to the computed-style heuristic for older payloads that predate
217
+ // inlineStyles. Convention (matches DesignEditor primitive creation and
218
+ // setResizeMode below): auto-width = width unset/max-content + pre-wrap;
219
+ // auto-height = fixed width + height unset/auto; fixed = both fixed. A
220
+ // drag-created box (display:flex, explicit width+height, whiteSpace
221
+ // unset→normal) correctly falls through to "fixed".
222
+ const authoredResizeWidth = authoredStyleValue(element, "width");
223
+ const authoredResizeHeight = authoredStyleValue(element, "height");
224
+ const authoredWhiteSpace = authoredStyleValue(element, "whiteSpace");
225
+ const hasInlineStyleInfo = Boolean(element.inlineStyles);
226
+ const widthIsAuto = hasInlineStyleInfo
227
+ ? !authoredResizeWidth || authoredResizeWidth === "max-content"
228
+ : !styles.width ||
229
+ styles.width === "auto" ||
230
+ styles.width === "max-content";
231
+ const heightIsAuto = hasInlineStyleInfo
232
+ ? !authoredResizeHeight || authoredResizeHeight === "auto"
233
+ : !styles.height || styles.height === "auto";
234
+ const isPreWrapOrNoWrap = hasInlineStyleInfo
235
+ ? authoredWhiteSpace === "pre-wrap" || authoredWhiteSpace === "nowrap"
236
+ : styles.whiteSpace === "nowrap";
237
+ const resizeMode: TextResizeMode =
238
+ widthIsAuto && isPreWrapOrNoWrap
239
+ ? "auto-width"
240
+ : !heightIsAuto && !widthIsAuto
241
+ ? "fixed"
242
+ : "auto-height";
243
+ const currentWidth = styles.width && !widthIsAuto ? styles.width : "200px";
244
+ const currentHeight = styles.height && !heightIsAuto ? styles.height : "48px";
245
+ const setResizeMode = (mode: TextResizeMode) => {
246
+ if (mode === "auto-width") {
247
+ onStyleChange("width", "max-content");
248
+ onStyleChange("height", "auto");
249
+ onStyleChange("whiteSpace", "pre-wrap");
250
+ } else if (mode === "auto-height") {
251
+ onStyleChange("width", currentWidth);
252
+ onStyleChange("height", "auto");
253
+ onStyleChange("whiteSpace", "normal");
254
+ } else {
255
+ onStyleChange("width", currentWidth);
256
+ onStyleChange("height", currentHeight);
257
+ onStyleChange("whiteSpace", "normal");
258
+ }
259
+ };
260
+
261
+ // M2 · Vertical text alignment (top / middle / bottom). For an auto-layout
262
+ // text container (display:flex) this maps to whichever flex property
263
+ // controls the vertical/cross axis — justifyContent when flex-direction is
264
+ // column, alignItems when row (the DesignEditor drag-created default; see
265
+ // primitive creation, which sets display:flex + alignItems:center with no
266
+ // explicit flex-direction, i.e. row). For any non-flex display,
267
+ // `verticalAlign` is a no-op: it only affects how an inline/inline-block/
268
+ // table-cell box sits relative to *sibling* line-box content, not how its
269
+ // own content sits within its own box — exactly the case for point text
270
+ // (inline-block). So instead of ever writing verticalAlign, convert the
271
+ // element to flex the same way a drag-created box is authored, then read/
272
+ // write through the row-axis property (alignItems) like that default.
273
+ const display = (styles.display || "").toLowerCase();
274
+ const isFlexText = display.includes("flex");
275
+ const isColumnFlexText =
276
+ isFlexText && styles.flexDirection?.includes("column");
277
+ const verticalAlignSourceProp = isColumnFlexText
278
+ ? styles.justifyContent
279
+ : styles.alignItems;
280
+ const verticalAlign = !isFlexText
281
+ ? "top"
282
+ : verticalAlignSourceProp === "center"
283
+ ? "middle"
284
+ : verticalAlignSourceProp === "flex-end"
285
+ ? "bottom"
286
+ : "top";
287
+ const setVerticalAlign = (mode: "top" | "middle" | "bottom") => {
288
+ // Converting a non-flex element matches the drag-created fixed-size text
289
+ // box exactly: display:flex, default (row) flex-direction — so the
290
+ // vertical axis is alignItems, same as the pre-existing row case below.
291
+ if (!isFlexText) onStyleChange("display", "flex");
292
+ const cssValue =
293
+ mode === "middle"
294
+ ? "center"
295
+ : mode === "bottom"
296
+ ? "flex-end"
297
+ : "flex-start";
298
+ onStyleChange(isColumnFlexText ? "justifyContent" : "alignItems", cssValue);
299
+ };
300
+
301
+ return (
302
+ <PanelSection title={t("editPanel.sections.typography")}>
303
+ {/* Row 1: font family full-width.
304
+ Wrapped in a height-constrained div so the SelectTrigger button's
305
+ hit-target is exactly h-6 (24 px) and cannot visually or physically
306
+ overlap the weight/size row below (bug: trigger extended ~12 px into
307
+ the next row, causing clicks meant for the size input to open this
308
+ dropdown instead). */}
309
+ <div className="h-6 overflow-hidden">
310
+ <Select
311
+ value={fontFamily}
312
+ onValueChange={(v) => onStyleChange("fontFamily", v)}
313
+ >
314
+ <SelectTrigger
315
+ aria-label={t("editPanel.labels.font")}
316
+ className="h-6 w-full rounded-md border-[var(--design-editor-control-border)] bg-[var(--design-editor-control-bg)] px-1.5 !text-[11px] shadow-none focus:ring-1 focus:ring-[var(--design-editor-accent-color)]"
317
+ >
318
+ <SelectValue />
319
+ </SelectTrigger>
320
+ <SelectContent>
321
+ {fontFamilyOptions.map((opt) => (
322
+ <SelectItem
323
+ key={opt.value}
324
+ value={opt.value}
325
+ className="!text-[11px]"
326
+ >
327
+ {opt.label}
328
+ </SelectItem>
329
+ ))}
330
+ </SelectContent>
331
+ </Select>
332
+ </div>
333
+
334
+ {/* Row 2: weight + size side by side */}
335
+ <div className="grid grid-cols-2 gap-1.5">
336
+ <Select
337
+ value={fontWeightIsMixed ? MIXED_VALUE : styles.fontWeight || "400"}
338
+ onValueChange={(v) => onStyleChange("fontWeight", v)}
339
+ >
340
+ <SelectTrigger className="h-6 rounded-md border-[var(--design-editor-control-border)] bg-[var(--design-editor-control-bg)] px-1.5 !text-[11px] shadow-none focus:ring-1 focus:ring-[var(--design-editor-accent-color)]">
341
+ <SelectValue />
342
+ </SelectTrigger>
343
+ <SelectContent>
344
+ {fontWeightIsMixed ? (
345
+ <SelectItem
346
+ value={MIXED_VALUE}
347
+ disabled
348
+ className="!text-[11px] text-muted-foreground"
349
+ >
350
+ {MIXED_VALUE}
351
+ </SelectItem>
352
+ ) : null}
353
+ {fontWeightOptions.map((opt) => (
354
+ <SelectItem
355
+ key={opt.value}
356
+ value={opt.value}
357
+ className="!text-[11px]"
358
+ >
359
+ {opt.label}
360
+ </SelectItem>
361
+ ))}
362
+ </SelectContent>
363
+ </Select>
364
+ <ScrubInput
365
+ label={t("editPanel.labels.size")}
366
+ ariaLabel={t("editPanel.labels.size")}
367
+ icon={IconLetterCase}
368
+ value={
369
+ fontSizeIsMixed
370
+ ? 0
371
+ : styles.fontSize
372
+ ? parseNumericValue(styles.fontSize)
373
+ : 16
374
+ }
375
+ mixed={fontSizeIsMixed}
376
+ onChange={(value, meta) =>
377
+ onStyleChange(
378
+ "fontSize",
379
+ `${Math.max(1, roundToOneDecimal(value))}px`,
380
+ meta,
381
+ )
382
+ }
383
+ unit="px"
384
+ min={1}
385
+ precision={1}
386
+ className="gap-0"
387
+ labelClassName="h-6 w-6 justify-center gap-0 rounded-l-md rounded-r-none border border-r-0 border-[var(--design-editor-control-border)] bg-[var(--design-editor-control-bg)] !text-[11px] [&>span]:hidden"
388
+ inputClassName="h-6 rounded-l-none rounded-r-md border-[var(--design-editor-control-border)] bg-[var(--design-editor-control-bg)] shadow-none focus-visible:ring-1 focus-visible:ring-[var(--design-editor-accent-color)]"
389
+ />
390
+ </div>
391
+
392
+ {/* Row 3: line-height + letter-spacing with design-editor leading icons */}
393
+ <div className="grid grid-cols-2 gap-1.5">
394
+ <ScrubInput
395
+ label={t("editPanel.labels.lineHeight")}
396
+ ariaLabel={t("editPanel.labels.lineHeight")}
397
+ icon={IconLineHeight}
398
+ value={
399
+ lineHeightIsMixed
400
+ ? 0
401
+ : resolveLineHeight(styles.lineHeight, styles.fontSize)
402
+ }
403
+ mixed={lineHeightIsMixed}
404
+ onChange={(value, meta) =>
405
+ onStyleChange("lineHeight", String(Math.max(0.1, value)), meta)
406
+ }
407
+ min={0.1}
408
+ step={0.1}
409
+ precision={2}
410
+ className="gap-0"
411
+ labelClassName="h-6 w-6 justify-center gap-0 rounded-l-md rounded-r-none border border-r-0 border-[var(--design-editor-control-border)] bg-[var(--design-editor-control-bg)] !text-[11px] [&>span]:hidden"
412
+ inputClassName="h-6 rounded-l-none rounded-r-md border-[var(--design-editor-control-border)] bg-[var(--design-editor-control-bg)] shadow-none focus-visible:ring-1 focus-visible:ring-[var(--design-editor-accent-color)]"
413
+ />
414
+ <ScrubInput
415
+ label={t("editPanel.labels.tracking")}
416
+ ariaLabel={t("editPanel.labels.tracking")}
417
+ icon={IconLetterSpacing}
418
+ value={
419
+ letterSpacingIsMixed
420
+ ? 0
421
+ : styles.letterSpacing
422
+ ? parseNumericValue(styles.letterSpacing)
423
+ : 0
424
+ }
425
+ mixed={letterSpacingIsMixed}
426
+ onChange={(value, meta) =>
427
+ onStyleChange("letterSpacing", `${value}px`, meta)
428
+ }
429
+ unit="px"
430
+ precision={1}
431
+ className="gap-0"
432
+ labelClassName="h-6 w-6 justify-center gap-0 rounded-l-md rounded-r-none border border-r-0 border-[var(--design-editor-control-border)] bg-[var(--design-editor-control-bg)] !text-[11px] [&>span]:hidden"
433
+ inputClassName="h-6 rounded-l-none rounded-r-md border-[var(--design-editor-control-border)] bg-[var(--design-editor-control-bg)] shadow-none focus-visible:ring-1 focus-visible:ring-[var(--design-editor-accent-color)]"
434
+ />
435
+ </div>
436
+
437
+ {/* Row 4: horizontal + vertical text alignment */}
438
+ <div className="flex items-center gap-1.5">
439
+ <InspectorSegment>
440
+ <InspectorIconButton
441
+ label={t("editPanel.textAligns.left")}
442
+ active={textAlign === "left" || textAlign === "start"}
443
+ onClick={() => onStyleChange("textAlign", "left")}
444
+ >
445
+ <IconAlignLeft className="size-3.5" />
446
+ </InspectorIconButton>
447
+ <InspectorIconButton
448
+ label={t("editPanel.textAligns.center")}
449
+ active={textAlign === "center"}
450
+ onClick={() => onStyleChange("textAlign", "center")}
451
+ >
452
+ <IconAlignCenter className="size-3.5" />
453
+ </InspectorIconButton>
454
+ <InspectorIconButton
455
+ label={t("editPanel.textAligns.right")}
456
+ active={textAlign === "right" || textAlign === "end"}
457
+ onClick={() => onStyleChange("textAlign", "right")}
458
+ >
459
+ <IconAlignRight className="size-3.5" />
460
+ </InspectorIconButton>
461
+ <InspectorIconButton
462
+ label={t("editPanel.textAligns.justify")}
463
+ active={textAlign === "justify"}
464
+ onClick={() => onStyleChange("textAlign", "justify")}
465
+ >
466
+ <IconAlignJustified className="size-3.5" />
467
+ </InspectorIconButton>
468
+ </InspectorSegment>
469
+ <InspectorSegment>
470
+ <InspectorIconButton
471
+ label={"Align top" /* i18n-ignore design vertical text align */}
472
+ active={verticalAlign === "top"}
473
+ onClick={() => setVerticalAlign("top")}
474
+ >
475
+ <IconLayoutAlignTop className="size-3.5" />
476
+ </InspectorIconButton>
477
+ <InspectorIconButton
478
+ label={"Align middle" /* i18n-ignore design vertical text align */}
479
+ active={verticalAlign === "middle"}
480
+ onClick={() => setVerticalAlign("middle")}
481
+ >
482
+ <IconLayoutAlignMiddle className="size-3.5" />
483
+ </InspectorIconButton>
484
+ <InspectorIconButton
485
+ label={"Align bottom" /* i18n-ignore design vertical text align */}
486
+ active={verticalAlign === "bottom"}
487
+ onClick={() => setVerticalAlign("bottom")}
488
+ >
489
+ <IconLayoutAlignBottom className="size-3.5" />
490
+ </InspectorIconButton>
491
+ </InspectorSegment>
492
+ <div className="ml-auto shrink-0">
493
+ <TypographyDetailsPopover
494
+ resizeMode={resizeMode}
495
+ onResizeModeChange={setResizeMode}
496
+ />
497
+ </div>
498
+ </div>
499
+ </PanelSection>
500
+ );
501
+ }