@agent-native/core 0.80.0 → 0.80.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.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +28 -0
- package/corpus/core/docs/content/locales/ar-SA/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +14 -1
- package/corpus/core/docs/content/locales/de-DE/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/locales/de-DE/template-design.mdx +15 -1
- package/corpus/core/docs/content/locales/es-ES/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/locales/es-ES/template-design.mdx +15 -1
- package/corpus/core/docs/content/locales/fr-FR/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +15 -1
- package/corpus/core/docs/content/locales/hi-IN/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +15 -1
- package/corpus/core/docs/content/locales/ja-JP/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +16 -1
- package/corpus/core/docs/content/locales/ko-KR/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +14 -1
- package/corpus/core/docs/content/locales/pt-BR/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +14 -1
- package/corpus/core/docs/content/locales/zh-CN/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +14 -1
- package/corpus/core/docs/content/locales/zh-TW/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +14 -1
- package/corpus/core/docs/content/skills-guide.mdx +5 -0
- package/corpus/core/docs/content/template-design.mdx +14 -1
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/application-state/handlers.ts +1 -1
- package/corpus/core/src/brand-kit/index.ts +1 -1
- package/corpus/core/src/cli/skills.ts +18 -0
- package/corpus/core/src/client/AgentPanel.tsx +1 -1
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +1 -1
- package/corpus/core/src/client/extensions/portable-extension.ts +1 -1
- package/corpus/core/src/code-agents/transcript-normalizer.ts +1 -1
- package/corpus/core/src/extensions/path.ts +1 -4
- package/corpus/core/src/integrations/a2a-continuation-processor.ts +1 -1
- package/corpus/core/src/mcp/build-server.ts +2 -2
- package/corpus/core/src/mcp/embed-app.ts +35 -1
- package/corpus/core/src/org/handlers.ts +5 -5
- package/corpus/core/src/org/plugin.ts +2 -2
- package/corpus/core/src/scripts/call-agent.ts +1 -1
- package/corpus/core/src/scripts/db/safety.ts +1 -1
- package/corpus/core/src/server/auth.ts +3 -0
- package/corpus/core/src/server/builder-design-systems.ts +308 -0
- package/corpus/core/src/server/core-routes-plugin.ts +29 -3
- package/corpus/core/src/server/index.ts +8 -0
- package/corpus/core/src/styles/agent-native.css +14 -7
- package/corpus/core/src/usage/store.ts +2 -2
- package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +298 -15
- package/corpus/templates/analytics/actions/get-sql-dashboard.ts +9 -4
- package/corpus/templates/analytics/actions/mutate-dashboard.ts +18 -2
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +12 -2
- package/corpus/templates/analytics/app/hooks/use-replay-storage-status.ts +66 -0
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +37 -0
- package/corpus/templates/analytics/app/i18n-data.ts +404 -0
- package/corpus/templates/analytics/app/pages/Settings.tsx +333 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +2 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/dashboard-layout.ts +121 -3
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +49 -26
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +137 -36
- package/corpus/templates/analytics/changelog/2026-06-29-analytics-agents-can-now-place-new-charts-into-requested-das.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-29-analytics-queries-now-report-failed-source-query-errors-inst.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-29-charts-can-now-be-dropped-between-full-dashboard-rows-to-cre.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-29-dashboard-email-reports-include-the-full-dashboard-image-wit.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-29-main-surface-border-reaches-the-top.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-29-session-replay-now-records-playable-sessions-in-production-a.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-29-set-up-session-replay-storage-from-settings-connect-builder-.md +6 -0
- package/corpus/templates/analytics/scripts/cleanup-empty-session-recordings.ts +102 -0
- package/corpus/templates/analytics/server/lib/dashboard-report.ts +49 -26
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +81 -20
- package/corpus/templates/analytics/server/lib/replay-storage.ts +79 -0
- package/corpus/templates/analytics/server/lib/s3-upload-provider.ts +255 -0
- package/corpus/templates/analytics/server/lib/session-replay.ts +29 -8
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +11 -2
- package/corpus/templates/analytics/server/plugins/onboarding.ts +97 -0
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +24 -0
- package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +105 -5
- package/corpus/templates/content/actions/set-image-alt-text.ts +1 -1
- package/corpus/templates/content/shared/document-export.ts +1 -1
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +8 -18
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +17 -0
- package/corpus/templates/design/actions/add-localhost-screens.ts +32 -5
- package/corpus/templates/design/actions/index-design-system-with-builder.ts +259 -0
- package/corpus/templates/design/actions/update-file.ts +9 -2
- package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +33 -75
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +72 -9
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +41 -39
- package/corpus/templates/design/app/components/design/EditPanel.tsx +1029 -249
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +450 -101
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +978 -154
- package/corpus/templates/design/app/components/design/TweaksPanel.tsx +7 -9
- package/corpus/templates/design/app/components/design/inspector/AlignmentMatrix.tsx +133 -66
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +1234 -344
- package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +144 -94
- package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +301 -72
- package/corpus/templates/design/app/components/design/inspector/FigmaColorPicker.tsx +876 -286
- package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +601 -0
- package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +242 -0
- package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +30 -7
- package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +212 -155
- package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +423 -0
- package/corpus/templates/design/app/components/design/inspector/figma-icons.tsx +487 -107
- package/corpus/templates/design/app/components/design/inspector/index.ts +27 -0
- package/corpus/templates/design/app/global.css +29 -3
- package/corpus/templates/design/app/i18n/zh-TW.ts +13 -0
- package/corpus/templates/design/app/i18n-data.ts +239 -1
- package/corpus/templates/design/app/pages/DesignEditor.tsx +1023 -353
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +57 -221
- package/corpus/templates/design/changelog/2026-06-29-canvas-selection-no-longer-flashes-broken-prototype-html-whe.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-command-menu-selections-are-clearer-in-dark-mode.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-design-mode-top-chrome-now-groups-collaborators-preview-shar.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-element-selection-now-stays-on-the-intended-layer-after-sele.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-screen-overview-full-view-controls-now-sit-above-frames-inst.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-screen-overview-tools-can-draw-shapes-create-screens-and-kee.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-the-pen-tool-now-creates-anchor-based-bezier-vectors-with-ha.md +6 -0
- package/corpus/templates/design/server/handlers/import-figma-system.ts +38 -85
- package/corpus/templates/design/server/lib/design-snapshot.ts +9 -1
- package/corpus/templates/design/shared/code-layer.ts +209 -9
- package/corpus/templates/design/shared/html-content.ts +21 -0
- package/corpus/templates/design/shared/pen-path.ts +207 -0
- package/corpus/templates/mail/app/lib/utils.ts +2 -2
- package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +9 -10
- package/corpus/templates/slides/AGENTS.md +3 -2
- package/corpus/templates/slides/actions/import-file.ts +26 -17
- package/corpus/templates/slides/actions/index-design-system-with-builder.ts +259 -0
- package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +35 -167
- package/corpus/templates/slides/app/components/design-system/fig-import-response.ts +9 -13
- package/corpus/templates/slides/app/context/DeckContext.tsx +1 -1
- package/corpus/templates/slides/app/i18n/ar-SA.ts +9 -37
- package/corpus/templates/slides/app/i18n/de-DE.ts +10 -25
- package/corpus/templates/slides/app/i18n/en-US.ts +9 -26
- package/corpus/templates/slides/app/i18n/es-ES.ts +10 -28
- package/corpus/templates/slides/app/i18n/fr-FR.ts +10 -28
- package/corpus/templates/slides/app/i18n/hi-IN.ts +9 -26
- package/corpus/templates/slides/app/i18n/ja-JP.ts +10 -22
- package/corpus/templates/slides/app/i18n/ko-KR.ts +9 -23
- package/corpus/templates/slides/app/i18n/pt-BR.ts +10 -28
- package/corpus/templates/slides/app/i18n/zh-CN.ts +9 -22
- package/corpus/templates/slides/app/i18n/zh-TW.ts +9 -22
- package/corpus/templates/slides/server/handlers/import-figma-system.ts +44 -12
- package/corpus/templates/slides/server/lib/chat-attachments.ts +1 -1
- package/corpus/templates/videos/app/components/NewCompositionPopover.tsx +1 -1
- package/dist/application-state/handlers.js +1 -1
- package/dist/application-state/handlers.js.map +1 -1
- package/dist/brand-kit/index.d.ts +1 -1
- package/dist/brand-kit/index.js +1 -1
- package/dist/brand-kit/index.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +18 -0
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AgentPanel.js +1 -1
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +1 -1
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/extensions/portable-extension.d.ts +1 -1
- package/dist/client/extensions/portable-extension.d.ts.map +1 -1
- package/dist/client/extensions/portable-extension.js.map +1 -1
- package/dist/code-agents/transcript-normalizer.js +1 -1
- package/dist/code-agents/transcript-normalizer.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/extensions/path.d.ts +1 -1
- package/dist/extensions/path.d.ts.map +1 -1
- package/dist/extensions/path.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/integrations/a2a-continuation-processor.js +1 -1
- package/dist/integrations/a2a-continuation-processor.js.map +1 -1
- package/dist/mcp/build-server.d.ts +1 -1
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +1 -1
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/mcp/embed-app.d.ts.map +1 -1
- package/dist/mcp/embed-app.js +35 -1
- package/dist/mcp/embed-app.js.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +8 -8
- package/dist/org/handlers.js +5 -5
- package/dist/org/handlers.js.map +1 -1
- package/dist/org/plugin.js +2 -2
- package/dist/org/plugin.js.map +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/scripts/call-agent.js +1 -1
- package/dist/scripts/call-agent.js.map +1 -1
- package/dist/scripts/db/safety.js +1 -1
- package/dist/scripts/db/safety.js.map +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +3 -0
- package/dist/server/auth.js.map +1 -1
- package/dist/server/builder-design-systems.d.ts +28 -0
- package/dist/server/builder-design-systems.d.ts.map +1 -0
- package/dist/server/builder-design-systems.js +217 -0
- package/dist/server/builder-design-systems.js.map +1 -0
- package/dist/server/core-routes-plugin.d.ts +1 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +20 -3
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -0
- package/dist/server/index.js.map +1 -1
- package/dist/styles/agent-native.css +14 -7
- package/dist/usage/store.js +2 -2
- package/dist/usage/store.js.map +1 -1
- package/docs/content/locales/ar-SA/skills-guide.mdx +5 -0
- package/docs/content/locales/ar-SA/template-design.mdx +14 -1
- package/docs/content/locales/de-DE/skills-guide.mdx +5 -0
- package/docs/content/locales/de-DE/template-design.mdx +15 -1
- package/docs/content/locales/es-ES/skills-guide.mdx +5 -0
- package/docs/content/locales/es-ES/template-design.mdx +15 -1
- package/docs/content/locales/fr-FR/skills-guide.mdx +5 -0
- package/docs/content/locales/fr-FR/template-design.mdx +15 -1
- package/docs/content/locales/hi-IN/skills-guide.mdx +5 -0
- package/docs/content/locales/hi-IN/template-design.mdx +15 -1
- package/docs/content/locales/ja-JP/skills-guide.mdx +5 -0
- package/docs/content/locales/ja-JP/template-design.mdx +16 -1
- package/docs/content/locales/ko-KR/skills-guide.mdx +5 -0
- package/docs/content/locales/ko-KR/template-design.mdx +14 -1
- package/docs/content/locales/pt-BR/skills-guide.mdx +5 -0
- package/docs/content/locales/pt-BR/template-design.mdx +14 -1
- package/docs/content/locales/zh-CN/skills-guide.mdx +5 -0
- package/docs/content/locales/zh-CN/template-design.mdx +14 -1
- package/docs/content/locales/zh-TW/skills-guide.mdx +5 -0
- package/docs/content/locales/zh-TW/template-design.mdx +14 -1
- package/docs/content/skills-guide.mdx +5 -0
- package/docs/content/template-design.mdx +14 -1
- package/package.json +1 -1
- package/corpus/templates/design/actions/import-figma-file.ts +0 -166
- package/corpus/templates/slides/server/lib/fig-design-system.ts +0 -110
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
|
|
1
3
|
import {
|
|
2
4
|
Select,
|
|
3
5
|
SelectContent,
|
|
@@ -62,28 +64,40 @@ const DEFAULT_LABELS: ConstraintsWidgetLabels = {
|
|
|
62
64
|
};
|
|
63
65
|
|
|
64
66
|
// ── pin-box geometry ────────────────────────────────────────────────────────
|
|
65
|
-
// The preview box is 40×40px (size-10). Inside it sits
|
|
66
|
-
// (representing
|
|
67
|
-
//
|
|
67
|
+
// The preview box is 40×40px (size-10). Inside it sits an 18×14px inner rect
|
|
68
|
+
// (representing a child element) centered at (20,20). The proportions match
|
|
69
|
+
// Figma's "little box" widget — inner rect is ~45–50% of the outer box width
|
|
70
|
+
// and slightly shorter in height to resemble a real element.
|
|
71
|
+
//
|
|
72
|
+
// Edge pins: 5px long, 2px wide, placed 2px from the box edge (flush to border).
|
|
73
|
+
// left : x=2..7, y center=20
|
|
74
|
+
// right : x=33..38, y center=20
|
|
75
|
+
// top : x center=20, y=2..7
|
|
76
|
+
// bottom: x center=20, y=33..38
|
|
68
77
|
//
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
//
|
|
78
|
+
// Gap between pin tip and inner rect edge:
|
|
79
|
+
// left : inner left edge at x=11 → gap from x=7 to x=11 (4px)
|
|
80
|
+
// right : inner right edge at x=29 → gap from x=29 to x=33 (4px)
|
|
81
|
+
// top : inner top edge at y=13 → gap from y=7 to y=13 (6px)
|
|
82
|
+
// bottom: inner bottom edge at y=27 → gap from y=27 to y=33 (6px)
|
|
74
83
|
//
|
|
75
|
-
//
|
|
84
|
+
// Center marker: for h=center or v=center, a single accent line runs through
|
|
85
|
+
// the full width/height of the box (including through the inner rect), drawn
|
|
86
|
+
// on top at the midpoint — matching Figma's solid crosshair treatment.
|
|
87
|
+
//
|
|
88
|
+
// Scale mode: all four pins on that axis render dashed, accent color.
|
|
76
89
|
|
|
77
90
|
const BOX = 40; // viewBox width/height (matches size-10 = 40px)
|
|
78
|
-
const
|
|
79
|
-
const
|
|
80
|
-
const
|
|
81
|
-
const
|
|
82
|
-
const
|
|
83
|
-
const
|
|
91
|
+
const INNER_W = 18; // inner rect width
|
|
92
|
+
const INNER_H = 14; // inner rect height (slightly shorter than wide = realistic element)
|
|
93
|
+
const INNER_X = (BOX - INNER_W) / 2; // 11
|
|
94
|
+
const INNER_Y = (BOX - INNER_H) / 2; // 13
|
|
95
|
+
const PIN_LEN = 5; // visual pin length
|
|
96
|
+
const PIN_W = 2; // pin stroke width (Figma: 2px thick pins)
|
|
97
|
+
const MARGIN = 2; // gap between outer box edge and pin start
|
|
84
98
|
const CENTER = BOX / 2; // 20
|
|
85
99
|
|
|
86
|
-
// Returns whether a given horizontal pin should be active.
|
|
100
|
+
// Returns whether a given horizontal pin should be active (solid/accent).
|
|
87
101
|
function hPinActive(side: "left" | "right", h: HorizontalConstraint): boolean {
|
|
88
102
|
if (side === "left") return h === "left" || h === "left-right";
|
|
89
103
|
return h === "right" || h === "left-right";
|
|
@@ -94,8 +108,11 @@ function vPinActive(side: "top" | "bottom", v: VerticalConstraint): boolean {
|
|
|
94
108
|
return v === "bottom" || v === "top-bottom";
|
|
95
109
|
}
|
|
96
110
|
|
|
97
|
-
// Clicking a left/right pin cycles
|
|
98
|
-
//
|
|
111
|
+
// Clicking a left/right pin cycles the constraint:
|
|
112
|
+
// - if that side is the only active one → "left-right"
|
|
113
|
+
// - if "left-right" or scale/center → single side
|
|
114
|
+
// - if neither active → single side
|
|
115
|
+
// Can't clear both sides; reverts to single side instead.
|
|
99
116
|
function toggleHPin(
|
|
100
117
|
side: "left" | "right",
|
|
101
118
|
current: HorizontalConstraint,
|
|
@@ -155,6 +172,10 @@ function PinBox({
|
|
|
155
172
|
onToggleH,
|
|
156
173
|
onToggleV,
|
|
157
174
|
}: PinBoxProps) {
|
|
175
|
+
const [hoveredPin, setHoveredPin] = useState<
|
|
176
|
+
"left" | "right" | "top" | "bottom" | null
|
|
177
|
+
>(null);
|
|
178
|
+
|
|
158
179
|
const leftOn = hPinActive("left", value.horizontal);
|
|
159
180
|
const rightOn = hPinActive("right", value.horizontal);
|
|
160
181
|
const topOn = vPinActive("top", value.vertical);
|
|
@@ -164,9 +185,47 @@ function PinBox({
|
|
|
164
185
|
const hScale = value.horizontal === "scale";
|
|
165
186
|
const vScale = value.vertical === "scale";
|
|
166
187
|
|
|
167
|
-
//
|
|
168
|
-
//
|
|
169
|
-
|
|
188
|
+
// Colors:
|
|
189
|
+
// active / scale → accent (primary)
|
|
190
|
+
// hovered inactive → slightly brighter muted
|
|
191
|
+
// inactive → muted (30% foreground opacity)
|
|
192
|
+
const ACCENT = "hsl(var(--primary))";
|
|
193
|
+
// Hover: lighten inactive pins on hover — use 55% opacity instead of 30%
|
|
194
|
+
const MUTED = "hsl(var(--foreground) / 0.30)";
|
|
195
|
+
const MUTED_HOVER = "hsl(var(--foreground) / 0.60)";
|
|
196
|
+
const SCALE_DASH = "3 2";
|
|
197
|
+
|
|
198
|
+
// Hit-area size for each pin (larger than the visual stroke for easy clicking
|
|
199
|
+
// — 10px wide / 14px tall centered on the pin midpoint).
|
|
200
|
+
const HIT_CROSS = 10; // perpendicular extent of hit area
|
|
201
|
+
const HIT_LONG = 14; // along-pin extent of hit area (covers pin + gap to inner rect)
|
|
202
|
+
|
|
203
|
+
// Pin color: accent when active or scale; hover-boosted or muted when inactive.
|
|
204
|
+
function pinColor(
|
|
205
|
+
side: "left" | "right" | "top" | "bottom",
|
|
206
|
+
isActive: boolean,
|
|
207
|
+
isScale: boolean,
|
|
208
|
+
): string {
|
|
209
|
+
if (isActive || isScale) return ACCENT;
|
|
210
|
+
if (hoveredPin === side) return MUTED_HOVER;
|
|
211
|
+
return MUTED;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const lColor = pinColor("left", leftOn, hScale);
|
|
215
|
+
const rColor = pinColor("right", rightOn, hScale);
|
|
216
|
+
const tColor = pinColor("top", topOn, vScale);
|
|
217
|
+
const bColor = pinColor("bottom", bottomOn, vScale);
|
|
218
|
+
|
|
219
|
+
const lDash = hScale ? SCALE_DASH : undefined;
|
|
220
|
+
const rDash = hScale ? SCALE_DASH : undefined;
|
|
221
|
+
const tDash = vScale ? SCALE_DASH : undefined;
|
|
222
|
+
const bDash = vScale ? SCALE_DASH : undefined;
|
|
223
|
+
|
|
224
|
+
// Pin end coordinates (tip = closer to inner rect)
|
|
225
|
+
// left pin: x from MARGIN to MARGIN+PIN_LEN, y=CENTER
|
|
226
|
+
// right pin: x from BOX-MARGIN to BOX-MARGIN-PIN_LEN, y=CENTER
|
|
227
|
+
// top pin: x=CENTER, y from MARGIN to MARGIN+PIN_LEN
|
|
228
|
+
// bottom pin: x=CENTER, y from BOX-MARGIN to BOX-MARGIN-PIN_LEN
|
|
170
229
|
|
|
171
230
|
return (
|
|
172
231
|
<svg
|
|
@@ -178,7 +237,7 @@ function PinBox({
|
|
|
178
237
|
"shrink-0 rounded-sm",
|
|
179
238
|
disabled && "pointer-events-none opacity-40",
|
|
180
239
|
)}
|
|
181
|
-
style={{ background: "hsl(var(--muted) / 0.
|
|
240
|
+
style={{ background: "hsl(var(--muted) / 0.4)" }}
|
|
182
241
|
>
|
|
183
242
|
{/* outer border */}
|
|
184
243
|
<rect
|
|
@@ -186,77 +245,61 @@ function PinBox({
|
|
|
186
245
|
y={0.75}
|
|
187
246
|
width={BOX - 1.5}
|
|
188
247
|
height={BOX - 1.5}
|
|
189
|
-
rx={
|
|
248
|
+
rx={2.5}
|
|
190
249
|
fill="none"
|
|
191
|
-
stroke="hsl(var(--
|
|
250
|
+
stroke="hsl(var(--foreground) / 0.20)"
|
|
192
251
|
strokeWidth={1.5}
|
|
193
252
|
/>
|
|
194
253
|
|
|
195
|
-
{/* inner element rect */}
|
|
254
|
+
{/* inner element rect — represents the selected element */}
|
|
196
255
|
<rect
|
|
197
256
|
x={INNER_X}
|
|
198
257
|
y={INNER_Y}
|
|
199
|
-
width={
|
|
200
|
-
height={
|
|
201
|
-
rx={1
|
|
258
|
+
width={INNER_W}
|
|
259
|
+
height={INNER_H}
|
|
260
|
+
rx={1}
|
|
202
261
|
fill="hsl(var(--background))"
|
|
203
|
-
stroke="hsl(var(--foreground) / 0.
|
|
262
|
+
stroke="hsl(var(--foreground) / 0.35)"
|
|
204
263
|
strokeWidth={1}
|
|
205
264
|
/>
|
|
206
265
|
|
|
207
|
-
{/*
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
stroke=
|
|
266
|
+
{/* center crosshair lines — drawn THROUGH the full box width/height
|
|
267
|
+
(including through the inner rect), matching Figma's solid crosshair.
|
|
268
|
+
Only rendered when the constraint is "center" on that axis. */}
|
|
269
|
+
{hCenter && (
|
|
270
|
+
<line
|
|
271
|
+
x1={MARGIN + PIN_LEN}
|
|
272
|
+
y1={CENTER}
|
|
273
|
+
x2={BOX - MARGIN - PIN_LEN}
|
|
274
|
+
y2={CENTER}
|
|
275
|
+
stroke={ACCENT}
|
|
217
276
|
strokeWidth={1}
|
|
218
|
-
|
|
277
|
+
strokeLinecap="round"
|
|
219
278
|
/>
|
|
220
279
|
)}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
{
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
stroke="hsl(var(--primary))"
|
|
232
|
-
strokeWidth={1.5}
|
|
233
|
-
/>
|
|
234
|
-
)}
|
|
235
|
-
{vCenter && (
|
|
236
|
-
<line
|
|
237
|
-
x1={CENTER}
|
|
238
|
-
y1={INNER_Y - 2}
|
|
239
|
-
x2={CENTER}
|
|
240
|
-
y2={INNER_Y + INNER + 2}
|
|
241
|
-
stroke="hsl(var(--primary))"
|
|
242
|
-
strokeWidth={1.5}
|
|
243
|
-
/>
|
|
244
|
-
)}
|
|
245
|
-
</>
|
|
280
|
+
{vCenter && (
|
|
281
|
+
<line
|
|
282
|
+
x1={CENTER}
|
|
283
|
+
y1={MARGIN + PIN_LEN}
|
|
284
|
+
x2={CENTER}
|
|
285
|
+
y2={BOX - MARGIN - PIN_LEN}
|
|
286
|
+
stroke={ACCENT}
|
|
287
|
+
strokeWidth={1}
|
|
288
|
+
strokeLinecap="round"
|
|
289
|
+
/>
|
|
246
290
|
)}
|
|
247
291
|
|
|
248
292
|
{/* edge pins — visual strokes */}
|
|
249
|
-
{/* left pin */}
|
|
293
|
+
{/* left pin: from outer edge toward inner rect */}
|
|
250
294
|
<line
|
|
251
295
|
x1={MARGIN}
|
|
252
296
|
y1={CENTER}
|
|
253
297
|
x2={MARGIN + PIN_LEN}
|
|
254
298
|
y2={CENTER}
|
|
255
|
-
stroke={
|
|
256
|
-
leftOn ? "hsl(var(--primary))" : "hsl(var(--foreground) / 0.35)"
|
|
257
|
-
}
|
|
299
|
+
stroke={lColor}
|
|
258
300
|
strokeWidth={PIN_W}
|
|
259
301
|
strokeLinecap="round"
|
|
302
|
+
strokeDasharray={lDash}
|
|
260
303
|
/>
|
|
261
304
|
{/* right pin */}
|
|
262
305
|
<line
|
|
@@ -264,11 +307,10 @@ function PinBox({
|
|
|
264
307
|
y1={CENTER}
|
|
265
308
|
x2={BOX - MARGIN - PIN_LEN}
|
|
266
309
|
y2={CENTER}
|
|
267
|
-
stroke={
|
|
268
|
-
rightOn ? "hsl(var(--primary))" : "hsl(var(--foreground) / 0.35)"
|
|
269
|
-
}
|
|
310
|
+
stroke={rColor}
|
|
270
311
|
strokeWidth={PIN_W}
|
|
271
312
|
strokeLinecap="round"
|
|
313
|
+
strokeDasharray={rDash}
|
|
272
314
|
/>
|
|
273
315
|
{/* top pin */}
|
|
274
316
|
<line
|
|
@@ -276,9 +318,10 @@ function PinBox({
|
|
|
276
318
|
y1={MARGIN}
|
|
277
319
|
x2={CENTER}
|
|
278
320
|
y2={MARGIN + PIN_LEN}
|
|
279
|
-
stroke={
|
|
321
|
+
stroke={tColor}
|
|
280
322
|
strokeWidth={PIN_W}
|
|
281
323
|
strokeLinecap="round"
|
|
324
|
+
strokeDasharray={tDash}
|
|
282
325
|
/>
|
|
283
326
|
{/* bottom pin */}
|
|
284
327
|
<line
|
|
@@ -286,61 +329,68 @@ function PinBox({
|
|
|
286
329
|
y1={BOX - MARGIN}
|
|
287
330
|
x2={CENTER}
|
|
288
331
|
y2={BOX - MARGIN - PIN_LEN}
|
|
289
|
-
stroke={
|
|
290
|
-
bottomOn ? "hsl(var(--primary))" : "hsl(var(--foreground) / 0.35)"
|
|
291
|
-
}
|
|
332
|
+
stroke={bColor}
|
|
292
333
|
strokeWidth={PIN_W}
|
|
293
334
|
strokeLinecap="round"
|
|
335
|
+
strokeDasharray={bDash}
|
|
294
336
|
/>
|
|
295
337
|
|
|
296
|
-
{/* invisible click targets — rendered on top of strokes */}
|
|
338
|
+
{/* invisible click + hover targets — rendered on top of strokes */}
|
|
297
339
|
{!disabled && (
|
|
298
340
|
<>
|
|
299
341
|
{/* left pin hit area */}
|
|
300
342
|
<rect
|
|
301
|
-
x={
|
|
302
|
-
y={CENTER -
|
|
303
|
-
width={PIN_LEN +
|
|
304
|
-
height={
|
|
343
|
+
x={0}
|
|
344
|
+
y={CENTER - HIT_CROSS / 2}
|
|
345
|
+
width={MARGIN + PIN_LEN + HIT_LONG / 2}
|
|
346
|
+
height={HIT_CROSS}
|
|
305
347
|
fill="transparent"
|
|
306
348
|
className="cursor-pointer"
|
|
307
349
|
onClick={() => onToggleH("left")}
|
|
350
|
+
onMouseEnter={() => setHoveredPin("left")}
|
|
351
|
+
onMouseLeave={() => setHoveredPin(null)}
|
|
308
352
|
role="button"
|
|
309
353
|
aria-label={labels.left}
|
|
310
354
|
/>
|
|
311
355
|
{/* right pin hit area */}
|
|
312
356
|
<rect
|
|
313
|
-
x={BOX - MARGIN - PIN_LEN -
|
|
314
|
-
y={CENTER -
|
|
315
|
-
width={PIN_LEN +
|
|
316
|
-
height={
|
|
357
|
+
x={BOX - MARGIN - PIN_LEN - HIT_LONG / 2}
|
|
358
|
+
y={CENTER - HIT_CROSS / 2}
|
|
359
|
+
width={MARGIN + PIN_LEN + HIT_LONG / 2}
|
|
360
|
+
height={HIT_CROSS}
|
|
317
361
|
fill="transparent"
|
|
318
362
|
className="cursor-pointer"
|
|
319
363
|
onClick={() => onToggleH("right")}
|
|
364
|
+
onMouseEnter={() => setHoveredPin("right")}
|
|
365
|
+
onMouseLeave={() => setHoveredPin(null)}
|
|
320
366
|
role="button"
|
|
321
367
|
aria-label={labels.right}
|
|
322
368
|
/>
|
|
323
369
|
{/* top pin hit area */}
|
|
324
370
|
<rect
|
|
325
|
-
x={CENTER -
|
|
326
|
-
y={
|
|
327
|
-
width={
|
|
328
|
-
height={PIN_LEN +
|
|
371
|
+
x={CENTER - HIT_CROSS / 2}
|
|
372
|
+
y={0}
|
|
373
|
+
width={HIT_CROSS}
|
|
374
|
+
height={MARGIN + PIN_LEN + HIT_LONG / 2}
|
|
329
375
|
fill="transparent"
|
|
330
376
|
className="cursor-pointer"
|
|
331
377
|
onClick={() => onToggleV("top")}
|
|
378
|
+
onMouseEnter={() => setHoveredPin("top")}
|
|
379
|
+
onMouseLeave={() => setHoveredPin(null)}
|
|
332
380
|
role="button"
|
|
333
381
|
aria-label={labels.top}
|
|
334
382
|
/>
|
|
335
383
|
{/* bottom pin hit area */}
|
|
336
384
|
<rect
|
|
337
|
-
x={CENTER -
|
|
338
|
-
y={BOX - MARGIN - PIN_LEN -
|
|
339
|
-
width={
|
|
340
|
-
height={PIN_LEN +
|
|
385
|
+
x={CENTER - HIT_CROSS / 2}
|
|
386
|
+
y={BOX - MARGIN - PIN_LEN - HIT_LONG / 2}
|
|
387
|
+
width={HIT_CROSS}
|
|
388
|
+
height={MARGIN + PIN_LEN + HIT_LONG / 2}
|
|
341
389
|
fill="transparent"
|
|
342
390
|
className="cursor-pointer"
|
|
343
391
|
onClick={() => onToggleV("bottom")}
|
|
392
|
+
onMouseEnter={() => setHoveredPin("bottom")}
|
|
393
|
+
onMouseLeave={() => setHoveredPin(null)}
|
|
344
394
|
role="button"
|
|
345
395
|
aria-label={labels.bottom}
|
|
346
396
|
/>
|
|
@@ -377,7 +427,7 @@ export function ConstraintsWidget({
|
|
|
377
427
|
</span>
|
|
378
428
|
|
|
379
429
|
{/* main row: pin-box LEFT + dropdowns RIGHT */}
|
|
380
|
-
<div className="flex items-center gap-
|
|
430
|
+
<div className="flex items-center gap-1.5">
|
|
381
431
|
{/* pin box */}
|
|
382
432
|
<PinBox
|
|
383
433
|
value={value}
|