@astra-kit/ui 1.0.0 → 1.2.1
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/CHANGELOG.md +32 -0
- package/README.md +14 -3
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/dist/components/button-link.d.ts +15 -0
- package/dist/components/button-link.js +70 -0
- package/dist/components/button-recipe.d.ts +27 -0
- package/dist/components/button-recipe.js +44 -0
- package/dist/components/button.d.ts +3 -5
- package/dist/components/button.js +1 -25
- package/dist/components/empty-state.d.ts +20 -0
- package/dist/components/empty-state.js +357 -0
- package/dist/components/metric-card.d.ts +22 -0
- package/dist/components/metric-card.js +378 -0
- package/dist/components/radio-group.d.ts +5 -3
- package/dist/components/radio-group.js +88 -85
- package/dist/components/stepper.d.ts +39 -0
- package/dist/components/stepper.js +693 -0
- package/dist/components/timeline.d.ts +51 -0
- package/dist/components/timeline.js +1013 -0
- package/dist/components/usage-meter.d.ts +39 -0
- package/dist/components/usage-meter.js +1093 -0
- package/dist/constants/empty-state.d.ts +12 -0
- package/dist/constants/empty-state.js +12 -0
- package/dist/constants/metric-card.d.ts +12 -0
- package/dist/constants/metric-card.js +12 -0
- package/dist/constants/stepper.d.ts +52 -0
- package/dist/constants/stepper.js +23 -0
- package/dist/constants/timeline.d.ts +62 -0
- package/dist/constants/timeline.js +31 -0
- package/dist/constants/usage-meter.d.ts +100 -0
- package/dist/constants/usage-meter.js +38 -0
- package/dist/hooks/use-has-entered-view.d.ts +9 -0
- package/dist/hooks/use-has-entered-view.js +46 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +8 -0
- package/dist/motion/arc-odometer.d.ts +53 -0
- package/dist/motion/arc-odometer.js +424 -0
- package/dist/motion/arc-text-swap.d.ts +22 -0
- package/dist/motion/arc-text-swap.js +142 -0
- package/dist/motion/arc-tokens.d.ts +1 -0
- package/dist/motion/arc-tokens.js +2 -1
- package/dist/styles.css +1 -1
- package/package.json +31 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,38 @@ Todos los cambios relevantes de `@astra-kit/ui` se documentan en este archivo co
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [1.2.1] - 2026-10-19
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- `EmptyState` ya no puede trabar la página en WebKit (Safari y navegadores basados en WebKit, sobre todo en Linux) mientras entra su ícono: la animación de entrada solo anima opacidad y escala, sin desenfoque.
|
|
12
|
+
- `UsageMeter` redondea cada segmento a la precisión de `decimals` antes de calcular todo, así la barra, la insignia, la leyenda y el resumen accesible coinciden (por ejemplo, 200,4 con límite 200 y sin decimales ya no dibuja un excedente que la insignia no muestra).
|
|
13
|
+
- `UsageMeter` acepta un segmento con `id="free"` sin confundirlo con el espacio libre de la leyenda.
|
|
14
|
+
- La leyenda de `UsageMeter` sigue alcanzable con Tab cuando se quitan segmentos después de mover el foco entre sus ítems.
|
|
15
|
+
- La insignia de estado de `UsageMeter` con un texto largo se recorta dentro del ancho del medidor en lugar de desbordarlo.
|
|
16
|
+
- `Stepper` muestra el contorno de foco del teclado en el paso actual al llegar con las flechas o End.
|
|
17
|
+
- `Timeline` etiqueta como "Ayer" el día calendario anterior en la zona horaria elegida, también en los cambios de horario de verano.
|
|
18
|
+
- `Timeline` vuelve a anunciar una actualización nueva aunque su resumen sea igual al anterior.
|
|
19
|
+
- `Timeline` ya no vuelve al principio del historial cuando solo cambia la preferencia de movimiento reducido; solo lo hace ante una actualización nueva.
|
|
20
|
+
- Los números de `MetricCard` y `UsageMeter` se detienen en su valor si se activa el movimiento reducido mientras ruedan.
|
|
21
|
+
|
|
22
|
+
## [1.2.0] - 2026-10-19
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- `UsageMeter`: barra segmentada de cupo (por ejemplo, códigos y avisos enviados hoy contra el límite diario) con total animado, insignia de estado (libre, casi lleno, excedido), leyenda navegable con teclado y anuncios para lectores de pantalla. Todo el copy viene en español y se reemplaza con `freeLabel`, `overLabel` y `messages`; los números usan `locale` (por defecto `es-AR`).
|
|
27
|
+
- `MetricCard`: tarjeta compacta para un número con contexto, con dígitos que ruedan al cambiar y un chip de variación (`change`) que se tiñe según el signo. Acepta `locale` (por defecto `es-AR`).
|
|
28
|
+
- `EmptyState`: estado vacío centrado con ícono, título, descripción y acción opcional; al cambiar el copy, el bloque se ajusta de alto sin saltos.
|
|
29
|
+
- `Timeline`: historial de eventos agrupado por día, del más reciente al más antiguo, con encabezados fijos, filas que se expanden en el lugar, tiempos relativos y anuncios de nuevas actualizaciones. Fechas en `es-AR` por defecto; el copy se reemplaza con `messages`.
|
|
30
|
+
- `Stepper`: indicador de pasos horizontal o vertical, con navegación opcional a pasos completados (`onStepSelect`), estado de error por paso y modo compacto automático en contenedores angostos. Textos de accesibilidad en español, reemplazables con `label`, `completeLabel` y `messages`.
|
|
31
|
+
|
|
32
|
+
## [1.1.0] - 2026-10-19
|
|
33
|
+
|
|
34
|
+
### Added
|
|
35
|
+
|
|
36
|
+
- `ButtonLink`: un link con el aspecto de `Button` (`variant` y `size`) que rutea con el adaptador del provider y sigue siendo un enlace, para navegar sin estilos propios en cada app. También se exporta `buttonClassName({ variant, size, className })`, con las mismas clases para otros elementos, como un `<label>` que abre un selector de archivos.
|
|
37
|
+
- `RadioGroup` acepta `hideLabel` (por defecto `false`), como `Select`: la leyenda sigue nombrando el grupo para lectores de pantalla pero no se ve ni ocupa espacio, para layouts que ya muestran su propio título. Ya no hace falta ocultarla con CSS propio.
|
|
38
|
+
|
|
7
39
|
## [1.0.0] - 2026-10-18
|
|
8
40
|
|
|
9
41
|
### Changed
|
package/README.md
CHANGED
|
@@ -47,7 +47,16 @@ import { Avatar, Button, Calendar, DataTable } from "@astra-kit/ui";
|
|
|
47
47
|
<Avatar name="Ana Núñez" src="/ana.jpg" />;
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
Los componentes adoptados de [Arc](https://uiarc.dev) usan la API pública de Arc: `Switch`, `Checkbox`, `RadioGroup`, `Badge`, `Avatar`, `AvatarGroup`, `Skeleton`, `Card`, `Alert`, `Tooltip`, `HoverCard`, `DropdownMenu`, `Select`, `Pagination`, `Calendar` y `Carousel` son componentes cerrados que se configuran por props (`items`, `options`, `members`, `content`, `title`); `Dialog` (`Dialog`, `DialogTrigger`, `DialogContent` con `title` y `description`, `DialogClose`), `Popover` y `Tabs` conservan las partes de Arc. Cada uno suma solo las extensiones que Arc no cubre, con copy en español por defecto, por ejemplo `getHref` en `Pagination`, `trigger` e ítems con `href` en `DropdownMenu`, `onOpenChange` en `HoverCard`, `footer` y el modo `alert` en `Dialog` (reemplaza a `AlertDialog`), `hideLabel` en `Select` y `onSettle` en `Carousel`. La tabla de migración desde `beez-ui` 2.x está en [`docs/history/beez-ui-changelog.md`](https://github.com/guidomodarelli/astra-ui/blob/main/docs/history/beez-ui-changelog.md).
|
|
50
|
+
Los componentes adoptados de [Arc](https://uiarc.dev) usan la API pública de Arc: `Switch`, `Checkbox`, `RadioGroup`, `Badge`, `Avatar`, `AvatarGroup`, `Skeleton`, `Card`, `Alert`, `Tooltip`, `HoverCard`, `DropdownMenu`, `Select`, `Pagination`, `Calendar` y `Carousel` son componentes cerrados que se configuran por props (`items`, `options`, `members`, `content`, `title`); `Dialog` (`Dialog`, `DialogTrigger`, `DialogContent` con `title` y `description`, `DialogClose`), `Popover` y `Tabs` conservan las partes de Arc. Cada uno suma solo las extensiones que Arc no cubre, con copy en español por defecto, por ejemplo `getHref` en `Pagination`, `trigger` e ítems con `href` en `DropdownMenu`, `onOpenChange` en `HoverCard`, `footer` y el modo `alert` en `Dialog` (reemplaza a `AlertDialog`), `hideLabel` en `Select` y `RadioGroup`, y `onSettle` en `Carousel`. Los displays de datos de Arc `UsageMeter`, `MetricCard`, `EmptyState`, `Timeline` y `Stepper` también son cerrados y se configuran por props; sus textos visibles y anunciados vienen en español y se reemplazan con `messages` (y con `freeLabel`/`overLabel`, `label` o `completeLabel` donde Arc ya los define), y `locale` formatea números y fechas (`es-AR` por defecto). La tabla de migración desde `beez-ui` 2.x está en [`docs/history/beez-ui-changelog.md`](https://github.com/guidomodarelli/astra-ui/blob/main/docs/history/beez-ui-changelog.md).
|
|
51
|
+
|
|
52
|
+
`Button` es para acciones y no tiene `asChild`. Una navegación con aspecto de botón es un `ButtonLink`: el `Link` del provider (rutea con el adaptador configurado y sigue siendo un enlace, que se puede abrir en otra pestaña o copiar) con la receta de `Button` y sus `variant` y `size`. Para otro elemento con aspecto de botón, como un `<label>` que abre un selector de archivos, `buttonClassName({ variant, size, className })` devuelve las mismas clases. Ninguno de los dos incluye la presión ni el spinner de `Button`.
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
import { ButtonLink, buttonClassName } from "@astra-kit/ui";
|
|
56
|
+
|
|
57
|
+
<ButtonLink href="/" variant="secondary">Volver al inicio</ButtonLink>;
|
|
58
|
+
<label className={buttonClassName({ variant: "ghost", size: "sm" })}>Adjuntar<input type="file" hidden /></label>;
|
|
59
|
+
```
|
|
51
60
|
|
|
52
61
|
Agrupar los imports de componentes desde la raíz. El paquete publica JavaScript ESM y declaraciones TypeScript en `dist`; el consumidor no necesita transpilar el código fuente de la librería. La gramática de filtros y los helpers de mes-año son independientes de React.
|
|
53
62
|
|
|
@@ -99,8 +108,10 @@ no tiemblan al pasar a `aria-invalid="true"`.
|
|
|
99
108
|
a 0.97 (un poco más los de solo ícono y menos los anchos) y vuelven con `snappy`; los
|
|
100
109
|
disparadores de menús, popovers y diálogos responden solo con color.
|
|
101
110
|
- `Checkbox`, `RadioGroup`, `Switch`, `Tabs`, `Calendar`, `Carousel`, `Card`, `Avatar`,
|
|
102
|
-
`AvatarGroup`, `Badge`, `Alert`, `ActionButton
|
|
103
|
-
componentes de Arc.
|
|
111
|
+
`AvatarGroup`, `Badge`, `Alert`, `ActionButton`, `SplitButton`, `UsageMeter`, `MetricCard`,
|
|
112
|
+
`EmptyState`, `Timeline` y `Stepper` usan el movimiento de sus componentes de Arc. Los
|
|
113
|
+
números de `UsageMeter` y `MetricCard` ruedan como un odómetro y sus segmentos o dígitos
|
|
114
|
+
entran la primera vez que el componente se ve; con movimiento reducido saltan al valor final.
|
|
104
115
|
- Una `Card` interactiva se eleva 2 px con el borde fuerte y la sombra `--shadow-raised` de
|
|
105
116
|
Arc al pasar un puntero fino.
|
|
106
117
|
- `Tooltip`, `Popover` y `HoverCard` se acercan desde su trigger con escala y fundido.
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## Arc
|
|
6
6
|
|
|
7
|
-
The theme tokens (`theme.css`, from Arc's `foundation.css`) and the `Button` API, styles and motion (`src/components/button.tsx`, `src/components/button-label.tsx`, `src/components/control-button.tsx`, `src/motion/arc-press.ts`, `src/motion/arc-tokens.ts`, `src/motion/use-morph-width.ts`), and the `ActionButton` and `SplitButton` components and their label morph (`src/components/action-button.tsx`, `src/components/split-button.tsx`, `src/components/morph-text.tsx`), the `Input` and `Textarea` fields with their animated helper and error rows (`src/components/input.tsx`, `src/components/textarea.tsx`, `src/components/field.tsx`), the `Switch`, `Checkbox` and `RadioGroup` controls (`src/components/switch.tsx`, `src/components/checkbox.tsx`, `src/components/radio-group.tsx`, `src/constants/switch.ts`, `src/constants/checkbox.ts`, `src/constants/radio-group.ts`), the `Badge`, `Avatar`, `AvatarGroup`, `Skeleton`, `Card` and `Alert` displays (`src/components/badge.tsx`, `src/components/avatar.tsx`, `src/components/skeleton.tsx`, `src/components/card.tsx`, `src/components/alert.tsx`, `src/constants/avatar.ts`, `src/constants/card.ts`, `src/constants/alert.ts`), the `Tooltip`, `Popover` and `HoverCard` overlays and their motion (`src/components/tooltip.tsx`, `src/components/popover.tsx`, `src/components/hover-card.tsx`, `src/motion/arc-floating-slot.tsx`, `src/motion/overlay-warmth.ts`, `src/constants/tooltip.ts`, `src/constants/popover.ts`, `src/constants/hover-card.ts`), the `DropdownMenu` and `Select` menus (`src/components/dropdown-menu.tsx`, `src/components/select.tsx`), the `Tabs` and `Pagination` navigation (`src/components/tabs.tsx`, `src/components/pagination.tsx`, `src/constants/tabs.ts`), the `Dialog` surface and its `alert` mode (`src/components/dialog.tsx`, `src/components/dialog-surface.tsx`, `src/constants/dialog.ts`), the `Calendar` and `Carousel` (`src/components/calendar.tsx`, `src/components/carousel.tsx`, `src/constants/calendar.ts`, `src/constants/carousel.ts`, `src/hooks/use-today.ts`), and the internal compositions those public components are built on (`src/components/primitives/`) are adapted from the free Arc library: https://uiarc.dev, https://github.com/kuratlielia/arc-library
|
|
7
|
+
The theme tokens (`theme.css`, from Arc's `foundation.css`) and the `Button` API, styles and motion (`src/components/button.tsx`, `src/components/button-label.tsx`, `src/components/control-button.tsx`, `src/motion/arc-press.ts`, `src/motion/arc-tokens.ts`, `src/motion/use-morph-width.ts`), and the `ActionButton` and `SplitButton` components and their label morph (`src/components/action-button.tsx`, `src/components/split-button.tsx`, `src/components/morph-text.tsx`), the `Input` and `Textarea` fields with their animated helper and error rows (`src/components/input.tsx`, `src/components/textarea.tsx`, `src/components/field.tsx`), the `Switch`, `Checkbox` and `RadioGroup` controls (`src/components/switch.tsx`, `src/components/checkbox.tsx`, `src/components/radio-group.tsx`, `src/constants/switch.ts`, `src/constants/checkbox.ts`, `src/constants/radio-group.ts`), the `Badge`, `Avatar`, `AvatarGroup`, `Skeleton`, `Card` and `Alert` displays (`src/components/badge.tsx`, `src/components/avatar.tsx`, `src/components/skeleton.tsx`, `src/components/card.tsx`, `src/components/alert.tsx`, `src/constants/avatar.ts`, `src/constants/card.ts`, `src/constants/alert.ts`), the `Tooltip`, `Popover` and `HoverCard` overlays and their motion (`src/components/tooltip.tsx`, `src/components/popover.tsx`, `src/components/hover-card.tsx`, `src/motion/arc-floating-slot.tsx`, `src/motion/overlay-warmth.ts`, `src/constants/tooltip.ts`, `src/constants/popover.ts`, `src/constants/hover-card.ts`), the `DropdownMenu` and `Select` menus (`src/components/dropdown-menu.tsx`, `src/components/select.tsx`), the `Tabs` and `Pagination` navigation (`src/components/tabs.tsx`, `src/components/pagination.tsx`, `src/constants/tabs.ts`), the `Dialog` surface and its `alert` mode (`src/components/dialog.tsx`, `src/components/dialog-surface.tsx`, `src/constants/dialog.ts`), the `Calendar` and `Carousel` (`src/components/calendar.tsx`, `src/components/carousel.tsx`, `src/constants/calendar.ts`, `src/constants/carousel.ts`, `src/hooks/use-today.ts`), the `EmptyState`, `MetricCard`, `UsageMeter`, `Timeline` and `Stepper` data displays and their shared text swap and rolling digits (`src/components/empty-state.tsx`, `src/components/metric-card.tsx`, `src/components/usage-meter.tsx`, `src/components/timeline.tsx`, `src/components/stepper.tsx`, `src/constants/empty-state.ts`, `src/constants/metric-card.ts`, `src/constants/usage-meter.ts`, `src/constants/timeline.ts`, `src/constants/stepper.ts`, `src/motion/arc-text-swap.tsx`, `src/motion/arc-odometer.tsx`), and the internal compositions those public components are built on (`src/components/primitives/`) are adapted from the free Arc library: https://uiarc.dev, https://github.com/kuratlielia/arc-library
|
|
8
8
|
|
|
9
9
|
```
|
|
10
10
|
MIT License
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ButtonSize, type ButtonVariant } from "./button-recipe.js";
|
|
2
|
+
import { type LinkProps } from "./link.js";
|
|
3
|
+
export type ButtonLinkProps = LinkProps & {
|
|
4
|
+
/** Visual weight, as in `Button`. Defaults to `primary`. */
|
|
5
|
+
variant?: ButtonVariant;
|
|
6
|
+
/** Height and padding, as in `Button`. Defaults to `md`. */
|
|
7
|
+
size?: ButtonSize;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* A link styled as a button, such as "Volver al inicio" on an error page.
|
|
11
|
+
* @param props - Variant, size and every `Link` prop, including `href`, `prefetch` and `component`.
|
|
12
|
+
* @returns The link.
|
|
13
|
+
*/
|
|
14
|
+
declare function ButtonLink({ variant, size, className, ...props }: ButtonLinkProps): import("react").JSX.Element;
|
|
15
|
+
export { ButtonLink };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { c as _c } from "react/compiler-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Navigation that looks like Arc's Button (https://uiarc.dev, MIT License, see THIRD_PARTY_NOTICES.md): the
|
|
5
|
+
* provider's `Link`, so it routes through the configured adapter, with the button recipe. A link stays a link for
|
|
6
|
+
* assistive technology and the browser (it opens in a new tab, it can be copied), which a `Button` cannot.
|
|
7
|
+
*/
|
|
8
|
+
import { cn } from "../lib/utils.js";
|
|
9
|
+
import { buttonClassName } from "./button-recipe.js";
|
|
10
|
+
import { Link } from "./link.js";
|
|
11
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
|
+
/**
|
|
13
|
+
* A link styled as a button, such as "Volver al inicio" on an error page.
|
|
14
|
+
* @param props - Variant, size and every `Link` prop, including `href`, `prefetch` and `component`.
|
|
15
|
+
* @returns The link.
|
|
16
|
+
*/
|
|
17
|
+
function ButtonLink(t0) {
|
|
18
|
+
const $ = _c(14);
|
|
19
|
+
let className;
|
|
20
|
+
let props;
|
|
21
|
+
let t1;
|
|
22
|
+
let t2;
|
|
23
|
+
if ($[0] !== t0) {
|
|
24
|
+
({variant: t1, size: t2, className, ...props} = t0);
|
|
25
|
+
$[0] = t0;
|
|
26
|
+
$[1] = className;
|
|
27
|
+
$[2] = props;
|
|
28
|
+
$[3] = t1;
|
|
29
|
+
$[4] = t2;
|
|
30
|
+
} else {
|
|
31
|
+
className = $[1];
|
|
32
|
+
props = $[2];
|
|
33
|
+
t1 = $[3];
|
|
34
|
+
t2 = $[4];
|
|
35
|
+
}
|
|
36
|
+
const variant = t1 === undefined ? "primary" : t1;
|
|
37
|
+
const size = t2 === undefined ? "md" : t2;
|
|
38
|
+
let t3;
|
|
39
|
+
if ($[5] !== className || $[6] !== size || $[7] !== variant) {
|
|
40
|
+
t3 = cn(buttonClassName({
|
|
41
|
+
variant,
|
|
42
|
+
size
|
|
43
|
+
}), className);
|
|
44
|
+
$[5] = className;
|
|
45
|
+
$[6] = size;
|
|
46
|
+
$[7] = variant;
|
|
47
|
+
$[8] = t3;
|
|
48
|
+
} else {
|
|
49
|
+
t3 = $[8];
|
|
50
|
+
}
|
|
51
|
+
let t4;
|
|
52
|
+
if ($[9] !== props || $[10] !== size || $[11] !== t3 || $[12] !== variant) {
|
|
53
|
+
t4 = /* @__PURE__ */ _jsx(Link, {
|
|
54
|
+
"data-slot": "button-link",
|
|
55
|
+
"data-variant": variant,
|
|
56
|
+
"data-size": size,
|
|
57
|
+
...props,
|
|
58
|
+
className: t3
|
|
59
|
+
});
|
|
60
|
+
$[9] = props;
|
|
61
|
+
$[10] = size;
|
|
62
|
+
$[11] = t3;
|
|
63
|
+
$[12] = variant;
|
|
64
|
+
$[13] = t4;
|
|
65
|
+
} else {
|
|
66
|
+
t4 = $[13];
|
|
67
|
+
}
|
|
68
|
+
return t4;
|
|
69
|
+
}
|
|
70
|
+
export { ButtonLink };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Visual weight, as in Arc: one primary action per surface. */
|
|
2
|
+
export type ButtonVariant = "primary" | "secondary" | "ghost" | "danger";
|
|
3
|
+
/** Height and padding, from Arc's control heights. */
|
|
4
|
+
export type ButtonSize = "sm" | "md" | "lg";
|
|
5
|
+
/**
|
|
6
|
+
* Arc's button recipe on its tokens. Press scale is driven by Motion alone, so `transform` never gets a CSS
|
|
7
|
+
* transition, and anchors of floating layers never scale because Radix measures them on pointerdown. Keyboard focus
|
|
8
|
+
* uses the foundation's shared outline; pointer focus draws no ring.
|
|
9
|
+
*/
|
|
10
|
+
export declare const buttonVariants: (props?: ({
|
|
11
|
+
variant?: "danger" | "ghost" | "primary" | "secondary" | null | undefined;
|
|
12
|
+
size?: "lg" | "md" | "sm" | null | undefined;
|
|
13
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
14
|
+
/** Options of {@link buttonClassName}. */
|
|
15
|
+
export type ButtonClassNameOptions = {
|
|
16
|
+
variant?: ButtonVariant;
|
|
17
|
+
size?: ButtonSize;
|
|
18
|
+
/** Extra classes merged after the recipe, so they win on conflicts. */
|
|
19
|
+
className?: string;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Arc's button classes for an element that is not a `Button`, such as a `<label>` that opens a file picker. Links
|
|
23
|
+
* use {@link ButtonLink} instead. The press scale and the loading label are effects of `Button` and are not included.
|
|
24
|
+
* @param options - Variant, size and extra classes. Defaults to `primary` and `md`.
|
|
25
|
+
* @returns The class list.
|
|
26
|
+
*/
|
|
27
|
+
export declare function buttonClassName({ variant, size, className }?: ButtonClassNameOptions): string;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Arc's Button recipe (https://uiarc.dev, MIT License, see THIRD_PARTY_NOTICES.md): variants, sizes and the helper
|
|
3
|
+
* that applies them. It has no client directive, so `buttonClassName` also runs in React Server Components; the
|
|
4
|
+
* `Button` and `ButtonLink` components import it from here.
|
|
5
|
+
*/
|
|
6
|
+
import { cva } from "class-variance-authority";
|
|
7
|
+
import { cn } from "../lib/utils.js";
|
|
8
|
+
/**
|
|
9
|
+
* Arc's button recipe on its tokens. Press scale is driven by Motion alone, so `transform` never gets a CSS
|
|
10
|
+
* transition, and anchors of floating layers never scale because Radix measures them on pointerdown. Keyboard focus
|
|
11
|
+
* uses the foundation's shared outline; pointer focus draws no ring.
|
|
12
|
+
*/
|
|
13
|
+
export const buttonVariants = cva("relative inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 rounded-(--radius-control) border border-transparent px-4 font-sans text-sm leading-(--leading-body) font-medium whitespace-nowrap select-none [-webkit-tap-highlight-color:transparent] transition-[color,background-color,border-color,opacity,box-shadow] duration-(--duration-fast) ease-(--ease-standard) disabled:cursor-not-allowed disabled:opacity-[.52] aria-busy:cursor-progress motion-reduce:transition-none [&:is([aria-haspopup]:not([aria-haspopup=false]),[data-state],[role=combobox])]:transform-none! [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
|
|
14
|
+
variants: {
|
|
15
|
+
variant: {
|
|
16
|
+
primary: "border-foreground bg-foreground text-background hover-fine:not-disabled:opacity-[.91] hover-fine:not-disabled:shadow-(--shadow-resting) active:not-disabled:opacity-[.84]",
|
|
17
|
+
secondary: "border-border bg-surface text-foreground hover-fine:not-disabled:bg-surface-muted hover-fine:not-disabled:shadow-(--shadow-resting) active:not-disabled:bg-surface-muted disabled:bg-surface-muted disabled:text-text-muted disabled:opacity-100",
|
|
18
|
+
ghost: "bg-transparent text-text-secondary hover-fine:not-disabled:bg-surface-muted hover-fine:not-disabled:text-foreground active:not-disabled:bg-surface-muted active:not-disabled:text-foreground disabled:text-text-muted disabled:opacity-100",
|
|
19
|
+
danger: "border-border bg-surface text-danger hover-fine:not-disabled:border-danger hover-fine:not-disabled:bg-surface-muted active:not-disabled:border-danger active:not-disabled:bg-surface-muted disabled:bg-surface-muted disabled:text-[color-mix(in_oklab,var(--danger)_55%,var(--surface-muted))] disabled:opacity-100"
|
|
20
|
+
},
|
|
21
|
+
size: {
|
|
22
|
+
sm: "min-h-(--control-height-sm) px-3",
|
|
23
|
+
md: "min-h-(--control-height-md)",
|
|
24
|
+
lg: "min-h-(--control-height-lg) px-5"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
defaultVariants: {
|
|
28
|
+
variant: "primary",
|
|
29
|
+
size: "md"
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
/**
|
|
33
|
+
* Arc's button classes for an element that is not a `Button`, such as a `<label>` that opens a file picker. Links
|
|
34
|
+
* use {@link ButtonLink} instead. The press scale and the loading label are effects of `Button` and are not included.
|
|
35
|
+
* @param options - Variant, size and extra classes. Defaults to `primary` and `md`.
|
|
36
|
+
* @returns The class list.
|
|
37
|
+
*/
|
|
38
|
+
export function buttonClassName({ variant = "primary", size = "md", className } = {}) {
|
|
39
|
+
return cn(buttonVariants({
|
|
40
|
+
variant,
|
|
41
|
+
size,
|
|
42
|
+
className
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Arc's Button (https://uiarc.dev, MIT License, see THIRD_PARTY_NOTICES.md): its variants, sizes, tokens and motion,
|
|
3
3
|
* with width-aware press feedback, a label that springs to its new width and a loading spinner. It renders a native
|
|
4
|
-
* button
|
|
4
|
+
* button: navigation that looks like a button is a `ButtonLink`, and other elements take `buttonClassName`. Composite components that need icon sizes use the internal `ControlButton`.
|
|
5
5
|
*/
|
|
6
6
|
import type { ComponentProps } from "react";
|
|
7
|
-
|
|
8
|
-
export type ButtonVariant = "primary" | "secondary" | "ghost" | "danger";
|
|
9
|
-
/** Height and padding, from Arc's control heights. */
|
|
10
|
-
export type ButtonSize = "sm" | "md" | "lg";
|
|
7
|
+
import { type ButtonSize, type ButtonVariant } from "./button-recipe.js";
|
|
11
8
|
export type ButtonProps = ComponentProps<"button"> & {
|
|
12
9
|
variant?: ButtonVariant;
|
|
13
10
|
size?: ButtonSize;
|
|
@@ -21,3 +18,4 @@ export type ButtonProps = ComponentProps<"button"> & {
|
|
|
21
18
|
*/
|
|
22
19
|
declare function Button({ className, variant, size, loading, type, children, ref, ...props }: ButtonProps): import("react").JSX.Element;
|
|
23
20
|
export { Button };
|
|
21
|
+
export type { ButtonSize, ButtonVariant } from "./button-recipe.js";
|
|
@@ -1,39 +1,15 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { c as _c } from "react/compiler-runtime";
|
|
3
|
-
import { cva } from "class-variance-authority";
|
|
4
3
|
import { useIsPresent } from "motion/react";
|
|
5
4
|
import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
|
|
6
5
|
import { cn } from "../lib/utils.js";
|
|
6
|
+
import { buttonVariants } from "./button-recipe.js";
|
|
7
7
|
import { useArcPress } from "../motion/arc-press.js";
|
|
8
8
|
import { useAttachedElement } from "../motion/use-attached-element.js";
|
|
9
9
|
import { ButtonLabel } from "./button-label.js";
|
|
10
10
|
import { LEAVING_ATTRIBUTES, LOADING_INERT_HANDLERS } from "./button-interaction.js";
|
|
11
11
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
12
|
/**
|
|
13
|
-
* Arc's button recipe on its tokens. Press scale is driven by Motion alone, so `transform` never gets a CSS
|
|
14
|
-
* transition, and anchors of floating layers never scale because Radix measures them on pointerdown. Keyboard focus
|
|
15
|
-
* uses the foundation's shared outline; pointer focus draws no ring.
|
|
16
|
-
*/
|
|
17
|
-
const buttonVariants = cva("relative inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 rounded-(--radius-control) border border-transparent px-4 font-sans text-sm leading-(--leading-body) font-medium whitespace-nowrap select-none [-webkit-tap-highlight-color:transparent] transition-[color,background-color,border-color,opacity,box-shadow] duration-(--duration-fast) ease-(--ease-standard) disabled:cursor-not-allowed disabled:opacity-[.52] aria-busy:cursor-progress motion-reduce:transition-none [&:is([aria-haspopup]:not([aria-haspopup=false]),[data-state],[role=combobox])]:transform-none! [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
|
|
18
|
-
variants: {
|
|
19
|
-
variant: {
|
|
20
|
-
primary: "border-foreground bg-foreground text-background hover-fine:not-disabled:opacity-[.91] hover-fine:not-disabled:shadow-(--shadow-resting) active:not-disabled:opacity-[.84]",
|
|
21
|
-
secondary: "border-border bg-surface text-foreground hover-fine:not-disabled:bg-surface-muted hover-fine:not-disabled:shadow-(--shadow-resting) active:not-disabled:bg-surface-muted disabled:bg-surface-muted disabled:text-text-muted disabled:opacity-100",
|
|
22
|
-
ghost: "bg-transparent text-text-secondary hover-fine:not-disabled:bg-surface-muted hover-fine:not-disabled:text-foreground active:not-disabled:bg-surface-muted active:not-disabled:text-foreground disabled:text-text-muted disabled:opacity-100",
|
|
23
|
-
danger: "border-border bg-surface text-danger hover-fine:not-disabled:border-danger hover-fine:not-disabled:bg-surface-muted active:not-disabled:border-danger active:not-disabled:bg-surface-muted disabled:bg-surface-muted disabled:text-[color-mix(in_oklab,var(--danger)_55%,var(--surface-muted))] disabled:opacity-100"
|
|
24
|
-
},
|
|
25
|
-
size: {
|
|
26
|
-
sm: "min-h-(--control-height-sm) px-3",
|
|
27
|
-
md: "min-h-(--control-height-md)",
|
|
28
|
-
lg: "min-h-(--control-height-lg) px-5"
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
defaultVariants: {
|
|
32
|
-
variant: "primary",
|
|
33
|
-
size: "md"
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
/**
|
|
37
13
|
* A single action on a page, form or dialog. Defaults to `type="button"`, so it only submits a form when asked to.
|
|
38
14
|
* @param props - Variant, size, loading state and native button attributes, including `ref`.
|
|
39
15
|
* @returns The native button.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ComponentProps, ReactNode } from "react";
|
|
2
|
+
export type EmptyStateProps = Omit<ComponentProps<"section">, "title" | "children"> & {
|
|
3
|
+
/** Headline. A new title rises in while the old one leaves. */
|
|
4
|
+
title: string;
|
|
5
|
+
/** One or two sentences on why it is empty and what to do. */
|
|
6
|
+
description: string;
|
|
7
|
+
/** Call to action, usually a button. */
|
|
8
|
+
action?: ReactNode;
|
|
9
|
+
/** Leading icon; defaults to a folder. A different icon component crossfades in. */
|
|
10
|
+
icon?: ReactNode;
|
|
11
|
+
/** Accessible name of the section region. */
|
|
12
|
+
label?: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* A centered placeholder for empty views with an icon, a title, a description and an optional action.
|
|
16
|
+
* @param props - Copy, icon, action, accessible name and native section attributes.
|
|
17
|
+
* @returns The empty state section.
|
|
18
|
+
*/
|
|
19
|
+
declare function EmptyState({ title, description, action, icon, label, className, ...props }: EmptyStateProps): import("react").JSX.Element;
|
|
20
|
+
export { EmptyState };
|