diff --git a/pendiente.md b/pendiente.md index 4b7fed66c..d19d7902d 100644 --- a/pendiente.md +++ b/pendiente.md @@ -2,18 +2,21 @@ ## Forma (shape) — asignar la familia de borde por componente -Permitir que cada componente reciba la **familia de forma** (`rounded` · `continuous` · `cut` · -`scoop`) como prop / `data-attr`, además del default del tema. Diferenciador fuerte sobre todo -en **chips y badges** — p. ej. un badge `cut` o `scoop` para una categoría frente al chip -`continuous` por defecto, sin inventar variantes nuevas. - -- **API propuesta**: prop `shape` en el wrapper eidos (``, - ``) → emite `data-shape="{family}"` en el elemento. Hereda del tema si no - se especifica. (Mecánica ya existente: la regla `[data-shape='{family}']` está en el motor; - solo falta exponer la prop en las recipes.) +Que cada componente reciba la **familia de forma** (`rounded` · `continuous` · `cut` · `scoop`) +como prop, además del default del tema. Diferenciador fuerte en **chips y badges**. + +- ✅ **Hecho (2026-06-05)**: canon `SHAPE_FAMILIES` + tipo `ShapeFamily` en `lib/types`; prop + `shape` en **Badge · Card · Button** → emite `data-shape="{family}"` (la regla + `[data-shape]` del motor hace el resto). Ortogonal a `rounded` (magnitud); default = arco. +- ⏳ **Pendiente — extender la prop** a más superficies: inputs (text-field/number-field/ + textarea/search-field), `tags-input` (los tags = chips, caso ideal de `cut`/`scoop`), + contenidos flotantes (popover/dropdown/select content). Mismo patrón de 3 ediciones + (import `ShapeFamily` + prop + `data-shape`). - **No** aplicar familias a círculos / píldoras (avatares): las deformaría (un avatar `continuous` se vuelve squircle, un `cut` octágono). El default de esos componentes debe quedarse en `rounded`. +- **Demo en componentes reales**: falta un control `shape` en las demos de badge/button/card + (hoy la prop existe y está verificada por probe, pero no se enseña en su demo). - **scoop / cóncavo**: en Chromium actual, `corner-shape: scoop` con `border` + `box-shadow` proyecta la sombra DENTRO de los entrantes y el borde de 1px hace costura en las esquinas cóncavas → se ve sucio. Para chips/badges `scoop` (y `cut`), preferir **relleno plano** sin diff --git a/src/uix/eidos/components/badge/badge.svelte b/src/uix/eidos/components/badge/badge.svelte index dfc4783a6..8df4518ae 100644 --- a/src/uix/eidos/components/badge/badge.svelte +++ b/src/uix/eidos/components/badge/badge.svelte @@ -21,6 +21,7 @@ size = 'md', color = 'primary', rounded = 'full', + shape, dot = false, removable = false, onRemove, @@ -45,6 +46,7 @@ data-size={resolvedSize} data-color={color} data-rounded={resolvedRounded} + data-shape={shape} data-dot={dot ? '' : undefined} data-removable={removable ? '' : undefined} {...rest} diff --git a/src/uix/eidos/components/badge/types.ts b/src/uix/eidos/components/badge/types.ts index aeb29c708..25dfd9a85 100644 --- a/src/uix/eidos/components/badge/types.ts +++ b/src/uix/eidos/components/badge/types.ts @@ -1,5 +1,5 @@ import type { Snippet } from 'svelte'; -import type { ChipVariant, ColorRole, ResponsiveProp, Size } from '$uix/eidos/lib/types'; +import type { ChipVariant, ColorRole, ResponsiveProp, ShapeFamily, Size } from '$uix/eidos/lib/types'; import type { BoxProps } from '../box/types'; /** @@ -43,8 +43,17 @@ export type BadgeProps = Omit & { size?: ResponsiveProp; /** Accent palette. @default 'primary' */ color?: BadgeColor; - /** Corner radius. @default 'full' (pill) */ + /** Corner radius (magnitude). @default 'full' (pill) */ rounded?: ResponsiveProp; + /** + * Corner shape family — `rounded` (arc, default) · `continuous` (squircle) · `cut` (bevel) · + * `scoop` (concave). Orthogonal to `rounded` (which sets the radius magnitude); a strong + * differentiator for badges/chips. Degrades to the arc where `corner-shape` is unsupported. + * For `cut`/`scoop`, prefer a filled variant (`soft`/`solid`) — concave corners + a border or + * drop-shadow seam at the corner. + * @default 'rounded' + */ + shape?: ShapeFamily; /** * Show a small coloured dot before the label — status-pill style. * Independent from `icon` (you can render both, though that's diff --git a/src/uix/eidos/components/button/button.svelte b/src/uix/eidos/components/button/button.svelte index 44855c6dc..99953f93d 100644 --- a/src/uix/eidos/components/button/button.svelte +++ b/src/uix/eidos/components/button/button.svelte @@ -18,6 +18,7 @@ variant = 'solid', size = 'md', rounded, + shape, block = false, iconOnly = false, loading = false, @@ -43,6 +44,7 @@ data-variant={variant} data-size={resolvedSize} data-rounded={resolvedRounded ?? undefined} + data-shape={shape} data-block={block ? '' : undefined} data-icon-only={iconOnly ? '' : undefined} data-has-icon={icon || (loading && spinnerPlacement === 'start') ? '' : undefined} diff --git a/src/uix/eidos/components/button/types.ts b/src/uix/eidos/components/button/types.ts index 0f22d396a..85c87df2b 100644 --- a/src/uix/eidos/components/button/types.ts +++ b/src/uix/eidos/components/button/types.ts @@ -1,6 +1,6 @@ import type { Snippet } from 'svelte'; import type { ProviderProps, SpinnerProps } from '$soma/components/button'; -import type { ResponsiveProp, Size } from '$uix/eidos/lib/types'; +import type { ResponsiveProp, ShapeFamily, Size } from '$uix/eidos/lib/types'; /** * Button visual variant. The 6-variant set ported from air covers the @@ -40,8 +40,14 @@ export type ButtonProps = ProviderProps & { variant?: ButtonVariant; /** Sizing scale. @default 'md' */ size?: ResponsiveProp; - /** Corner radius. @default inherits from size */ + /** Corner radius (magnitude). @default inherits from size */ rounded?: ResponsiveProp; + /** + * Corner shape family — `rounded` (arc) · `continuous` (squircle) · `cut` (bevel) · `scoop` + * (concave). Orthogonal to `rounded` (radius magnitude). A squircle button reads notably more + * premium. Degrades to the arc where `corner-shape` is unsupported. @default 'rounded' + */ + shape?: ShapeFamily; /** Stretch to fill the container's inline-size. @default false */ block?: boolean; /** diff --git a/src/uix/eidos/components/card/card.svelte b/src/uix/eidos/components/card/card.svelte index 0e906c95e..6a019a46b 100644 --- a/src/uix/eidos/components/card/card.svelte +++ b/src/uix/eidos/components/card/card.svelte @@ -25,6 +25,7 @@ size = 'md', color = 'neutral', rounded = 'md', + shape, interactive = false, selected = false, disabled = false, @@ -74,6 +75,7 @@ data-color={resolvedColor} data-color-custom={customColor ? '' : undefined} data-rounded={resolvedRounded} + data-shape={shape} data-interactive={interactive ? '' : undefined} data-selected={selected ? '' : undefined} data-disabled={disabled ? '' : undefined} diff --git a/src/uix/eidos/components/card/types.ts b/src/uix/eidos/components/card/types.ts index 4b7e9a727..2de0ad40e 100644 --- a/src/uix/eidos/components/card/types.ts +++ b/src/uix/eidos/components/card/types.ts @@ -4,6 +4,7 @@ import type { ChipVariant, ColorRole, ResponsiveProp, + ShapeFamily, Size } from '$uix/eidos/lib/types'; import type { BoxProps } from '../box/types'; @@ -70,8 +71,16 @@ export type CardProps = Omit & { * string (hex / rgb / oklch / named). @default 'neutral' */ color?: CardColor; - /** Corner radius. @default 'md' */ + /** Corner radius (magnitude). @default 'md' */ rounded?: ResponsiveProp; + /** + * Corner shape family — `rounded` (arc) · `continuous` (squircle) · `cut` (bevel) · `scoop` + * (concave). Orthogonal to `rounded` (radius magnitude). Degrades to the arc where + * `corner-shape` is unsupported. For `cut`/`scoop` prefer the `soft`/`solid` variant — an + * `outline` border seams at concave/angular corners in current engines. + * @default 'rounded' + */ + shape?: ShapeFamily; /** * Make the card clickable. Promotes the Provider to `