diff --git a/.gitignore b/.gitignore index 94a69ff..a84e5d3 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,6 @@ src/styled *.log .DS_Store *.tgz + +# Figma fidelity audit scratch (playwright + screenshots) +.audit/ diff --git a/package.json b/package.json index 0918fc0..20ec80e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@aymurai/ui", - "version": "0.2.1", + "version": "0.3.0", "description": "AymurAI shared React component library, extracted from the Figma UI Library and authored with Panda CSS.", "license": "MIT", "type": "module", diff --git a/src/components/archives/ArchiveProgress.tsx b/src/components/archives/ArchiveProgress.tsx index 4c93aae..b328ab9 100644 --- a/src/components/archives/ArchiveProgress.tsx +++ b/src/components/archives/ArchiveProgress.tsx @@ -80,6 +80,17 @@ function ProgressBar({ const pct = Math.min(100, Math.max(0, progress)); + // Figma renders the active/completed fill with a 45° diagonal hatch texture + // (a "barber-pole" loading pattern): periwinkle stripes over the light-blue + // in-progress fill, white stripes over the navy completed fill. Applied as an + // inline backgroundImage (gradients are not tokenizable). + const stripe = + status === "completed" + ? "repeating-linear-gradient(135deg, rgba(255,255,255,0.5) 0px, rgba(255,255,255,0.5) 2px, transparent 2px, transparent 7px)" + : status === "default" + ? "repeating-linear-gradient(135deg, rgba(63,71,157,0.35) 0px, rgba(63,71,157,0.35) 2px, transparent 2px, transparent 7px)" + : undefined; + return (
); @@ -161,6 +172,7 @@ function ProgressLabel({ + Detuviste el procesamiento de este archivo + + ); + } + return ( - {/* Error message */} + {/* Error message — Figma: 14px italic, two lines, constrained to card width. */} {isError && (

- {type === "preview-error" - ? "Error de carga.\nVolvelo a intentar." - : "Error de guardado.\nVolver a cargar archivo."} + {type === "preview-error" ? ( + <> + Error de carga. + + Volvelo a intentar. + + + ) : ( + <> + + Error de guardado. + + + Volver a cargar archivo. + + + )}

)} diff --git a/src/components/avatar/Avatar.stories.tsx b/src/components/avatar/Avatar.stories.tsx index b3a01cf..291d74d 100644 --- a/src/components/avatar/Avatar.stories.tsx +++ b/src/components/avatar/Avatar.stories.tsx @@ -14,7 +14,19 @@ const meta = { size: { control: "inline-radio", options: ["sm", "md"] }, color: { control: "inline-radio", - options: ["primary", "secondary", "warning", "success"], + options: [ + "primary", + "secondary", + "warning", + "success", + "violet", + "green", + "red", + "yellow", + "pink", + "orange", + "green-light", + ], }, }, } satisfies Meta; @@ -23,17 +35,37 @@ export default meta; type Story = StoryObj; export const Default: Story = { - args: { initials: "AD", size: "sm", color: "primary" }, + args: { initials: "AD", size: "sm", color: "violet" }, }; +/** Figma bg/category/* speaker-palette — one avatar per colour, both sizes. */ export const Matrix: Story = { render: () => ( -
- - - - - +
+
+ + + + + + + +
+
+ + + + + + + +
+
+ + + + +
), }; diff --git a/src/components/big-icon-button/BigIconButton.tsx b/src/components/big-icon-button/BigIconButton.tsx index 3cf555e..5d04429 100644 --- a/src/components/big-icon-button/BigIconButton.tsx +++ b/src/components/big-icon-button/BigIconButton.tsx @@ -60,7 +60,9 @@ const bigIconButton = cva({ bg: "action.pressed", color: "text.onbutton-alternative", }, - "&:disabled": { bg: "action.disabled", color: "text.onbutton-default" }, + // TOKEN GAP: Figma action-disabled for this component = #E2EBF3 (blue-tinted), + // not the warm-grey #E0DDE2 stored in action.disabled. Escape until token updated. + "&:disabled": { bg: "[#E2EBF3]", color: "text.onbutton-default" }, }, secondary: { bg: "bg.secondary", @@ -68,21 +70,24 @@ const bigIconButton = cva({ borderWidth: "[2px]", borderStyle: "solid", borderColor: "action.alt-default", - "&:hover:enabled": { borderColor: "action.hover" }, + // TOKEN GAP: Figma secondary-hover border = #728197 (muted blue-grey); + // action.hover = #110041 is wrong here. Escape until token promoted. + "&:hover:enabled": { borderColor: "[#728197]" }, "&:active:enabled": { bg: "action.pressed", color: "text.onbutton-alternative", borderColor: "action.pressed", }, + // TOKEN GAP: Figma disabled border uses same #E2EBF3 as primary disabled bg. "&:disabled": { - borderColor: "action.disabled", + borderColor: "[#E2EBF3]", color: "text.onbutton-disabled", }, }, tertiary: { bg: "[transparent]", color: "text.onbutton-default", - "&:hover:enabled": { bg: "bg.primary-alternative" }, + // Figma tertiary hover: no bg fill — stays transparent. "&:active:enabled": { bg: "action.pressed", color: "text.onbutton-alternative", diff --git a/src/components/button-link/ButtonLink.stories.tsx b/src/components/button-link/ButtonLink.stories.tsx index 3a26ee3..e164672 100644 --- a/src/components/button-link/ButtonLink.stories.tsx +++ b/src/components/button-link/ButtonLink.stories.tsx @@ -45,24 +45,24 @@ export const SizeMAlternative: Story = { }; // Figma: Size=S, Type=Default (21:5355) +// Note: Size=S always renders a built-in CaretDown — do not pass iconRight. export const SizeSDefault: Story = { args: { size: "S", type: "Default", children: "call to action", iconLeft: , - iconRight: , }, }; // Figma: Size=S, Type=Alternative (21:5359) +// Note: Size=S always renders a built-in CaretDown — do not pass iconRight. export const SizeSAlternative: Story = { args: { size: "S", type: "Alternative", children: "call to action", iconLeft: , - iconRight: , }, parameters: { backgrounds: { default: "dark" } }, }; @@ -99,12 +99,8 @@ export const Matrix: Story = { Size M / Alternative
- } - iconRight={} - > + {/* Size=S: built-in CaretDown replaces iconRight */} + }> Size S / Default
} - iconRight={} > Size S / Alternative diff --git a/src/components/button-link/ButtonLink.tsx b/src/components/button-link/ButtonLink.tsx index 3b81cbb..45a2628 100644 --- a/src/components/button-link/ButtonLink.tsx +++ b/src/components/button-link/ButtonLink.tsx @@ -96,12 +96,14 @@ export function ButtonLink({ > {iconLeft && } {children} - {iconRight && } - {/* Figma Size=S carries a trailing caret-down (angle-down-small). */} - {size === "S" && ( + {/* Figma Size=S always carries a trailing caret-down (angle-down-small) + as the exclusive right slot. For Size=M the caller controls iconRight. */} + {size === "S" ? ( + ) : ( + iconRight && )} ); diff --git a/src/components/callout/Callout.tsx b/src/components/callout/Callout.tsx index 4dfad52..14debbb 100644 --- a/src/components/callout/Callout.tsx +++ b/src/components/callout/Callout.tsx @@ -11,6 +11,12 @@ import type { HTMLAttributes } from "react"; * * Figma: Toast family node 1994:30384 — Error / Warning / Success / Info. */ + +/** + * Container recipe — background + border only. + * Message text color is always text.default (set in base); accent color is + * applied separately to the icon and dismiss button via accentRecipe. + */ const calloutRecipe = cva({ base: { ...hstack.raw({ @@ -27,6 +33,8 @@ const calloutRecipe = cva({ width: "full", + // Message text is always text.default (#110041) across all variants. + color: "text.default", textStyle: "label.md.default", // Figma: Archivo 16/120% }, variants: { @@ -34,22 +42,18 @@ const calloutRecipe = cva({ error: { bg: "system.error-secondary", borderColor: "system.error", - color: "system.error", }, warning: { bg: "system.warning-secondary", borderColor: "system.warning", - color: "system.warning", }, success: { bg: "system.success-secondary", borderColor: "system.success", - color: "system.success", }, info: { bg: "system.info-secondary", borderColor: "system.info", - color: "text.default", }, }, noBorder: { @@ -64,6 +68,24 @@ const calloutRecipe = cva({ }, }); +/** + * Accent recipe — maps variant to its accent color. + * Applied only to the icon element and the dismiss (X) button so the accent + * colour is scoped to those chrome elements, not the message text. + */ +const accentRecipe = cva({ + base: {}, + variants: { + variant: { + error: { color: "system.error" }, + warning: { color: "system.warning" }, + success: { color: "system.success" }, + info: { color: "system.info" }, + }, + }, + defaultVariants: { variant: "info" }, +}); + export type CalloutVariant = "error" | "warning" | "success" | "info"; export interface CalloutProps extends HTMLAttributes { @@ -83,17 +105,15 @@ export function Callout({ className, ...props }: CalloutProps) { + const accent = accentRecipe({ variant }); return (
-