feat(studio): non-destructive crop + cross-project asset view

This commit is contained in:
Miguel Angel Simon Sierra
2026-07-06 23:40:32 -04:00
parent 8c3590a90e
commit 676f461f6a
39 changed files with 1646 additions and 208 deletions
@@ -160,6 +160,16 @@ const BOX_SHADOW_PRESETS = {
export type BoxShadowPreset = keyof typeof BOX_SHADOW_PRESETS | "custom";
export {
buildClipPathValue,
buildInsetClipPathSides,
buildInsetClipPathValue,
getClipPathInsetPx,
inferClipPathPreset,
parseInsetClipPathSides,
type ClipPathInsetSides,
} from "./clipPathHelpers";
/* ------------------------------------------------------------------ */
/* Shared types */
/* ------------------------------------------------------------------ */
@@ -314,23 +324,6 @@ export function buildBoxShadowPresetValue(
return BOX_SHADOW_PRESETS[preset];
}
export function inferClipPathPreset(
value: string | undefined,
): "none" | "inset" | "circle" | "custom" {
const normalized = value?.trim();
if (!normalized || normalized === "none") return "none";
if (/^inset\(/i.test(normalized)) return "inset";
if (/^circle\(/i.test(normalized)) return "circle";
return "custom";
}
export function getClipPathInsetPx(value: string | undefined): number {
const match = /^inset\(\s*(-?\d+(?:\.\d+)?)px\b/i.exec(value?.trim() ?? "");
if (!match) return 0;
const parsed = Number.parseFloat(match[1]);
return Number.isFinite(parsed) ? Math.max(0, parsed) : 0;
}
export function buildStrokeWidthStyleUpdates(
nextWidth: string,
currentBorderStyle: string | undefined,
@@ -359,23 +352,6 @@ export function buildStrokeStyleUpdates(
return updates;
}
export function buildClipPathValue(
preset: "none" | "inset" | "circle" | "custom",
radiusValue: number,
fallback: string | undefined,
) {
if (preset === "custom") return fallback?.trim() || "none";
if (preset === "circle") return "circle(50% at 50% 50%)";
if (preset === "inset") {
return `inset(0 round ${formatNumericValue(Math.max(0, radiusValue))}px)`;
}
return "none";
}
export function buildInsetClipPathValue(insetPx: number, radiusValue: number): string {
return `inset(${formatNumericValue(Math.max(0, insetPx))}px round ${formatNumericValue(Math.max(0, radiusValue))}px)`;
}
export function adjustNumericToken(
value: string,
direction: 1 | -1,