@doscientos/ui 0.1.14 → 0.1.16
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/README.md +17 -0
- package/dist/index.cjs +91 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +26 -5
- package/dist/index.d.ts +26 -5
- package/dist/index.js +91 -38
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -55,11 +55,28 @@ El combobox es composable: la aplicación controla datos, peticiones y caché; l
|
|
|
55
55
|
## Desarrollo
|
|
56
56
|
|
|
57
57
|
- `pnpm test`: pruebas unitarias y de renderizado.
|
|
58
|
+
- `pnpm test:storybook`: renderizado, accesibilidad e interacciones de todas las stories en Chromium.
|
|
58
59
|
- `pnpm typecheck`: contrato TypeScript.
|
|
59
60
|
- `pnpm build`: distribución JS, tipos y CSS Tailwind compilado.
|
|
60
61
|
- `pnpm storybook`: catálogo local en el puerto 6006.
|
|
61
62
|
- `pnpm build-storybook`: sitio estático en `storybook-static/`, listo para publicar en `ui.doscientos.es`.
|
|
62
63
|
|
|
64
|
+
Storybook genera documentación automática para todo el catálogo y ofrece temas
|
|
65
|
+
claro/oscuro y viewports móvil, tablet y escritorio. Chromatic captura cada
|
|
66
|
+
story en claro escritorio, oscuro escritorio y claro móvil. Para activar el job
|
|
67
|
+
visual de CI, configura `CHROMATIC_PROJECT_TOKEN` como secreto del repositorio;
|
|
68
|
+
el valor se consume mediante el entorno y nunca se pasa como argumento del CLI.
|
|
69
|
+
|
|
70
|
+
### Criterio de stories
|
|
71
|
+
|
|
72
|
+
Cada componente público debe tener una story propia. Cuando apliquen, incluye
|
|
73
|
+
estado por defecto, variantes, disabled o read-only, error, carga o vacío,
|
|
74
|
+
contenido largo y viewport estrecho. Los controles interactivos deben añadir
|
|
75
|
+
un flujo `play` que cubra su comportamiento principal con teclado y foco.
|
|
76
|
+
|
|
77
|
+
Las stories deben usar datos ficticios y permanecer independientes de rutas,
|
|
78
|
+
APIs, autenticación y estado de producto.
|
|
79
|
+
|
|
63
80
|
## Criterio de crecimiento
|
|
64
81
|
|
|
65
82
|
Un componente entra cuando ya resuelve dos contextos reales o una necesidad transversal de accesibilidad. No se incorporan entidades de negocio, consultas, rutas ni variaciones visuales exclusivas de un cliente.
|
package/dist/index.cjs
CHANGED
|
@@ -364,6 +364,7 @@ function getTextMatchParts(text, query) {
|
|
|
364
364
|
}
|
|
365
365
|
|
|
366
366
|
// src/ui/accordion/accordion.tsx
|
|
367
|
+
var React = require("react");
|
|
367
368
|
var import_lucide_react = require("lucide-react");
|
|
368
369
|
var import_react_aria_components = require("react-aria-components");
|
|
369
370
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -372,7 +373,7 @@ function Accordion({ className, ...props }) {
|
|
|
372
373
|
import_react_aria_components.DisclosureGroup,
|
|
373
374
|
{
|
|
374
375
|
"data-slot": "accordion",
|
|
375
|
-
className: cn("flex w-full flex-col", className),
|
|
376
|
+
className: cn("flex w-full flex-col text-foreground", className),
|
|
376
377
|
...props
|
|
377
378
|
}
|
|
378
379
|
);
|
|
@@ -398,7 +399,7 @@ function AccordionTrigger({
|
|
|
398
399
|
slot: "trigger",
|
|
399
400
|
"data-slot": "accordion-trigger",
|
|
400
401
|
className: cn(
|
|
401
|
-
"group/accordion-trigger relative flex flex-1 items-start justify-between rounded-lg border border-transparent py-2.5 text-left text-sm font-medium transition-
|
|
402
|
+
"group/accordion-trigger relative flex flex-1 items-start justify-between gap-3 rounded-lg border border-transparent px-2.5 py-2.5 text-left text-sm font-medium text-foreground transition-colors outline-none hover:bg-muted/50 aria-expanded:bg-muted/50 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground",
|
|
402
403
|
className
|
|
403
404
|
),
|
|
404
405
|
...props,
|
|
@@ -422,18 +423,22 @@ function AccordionTrigger({
|
|
|
422
423
|
}
|
|
423
424
|
) });
|
|
424
425
|
}
|
|
425
|
-
function AccordionContent({
|
|
426
|
+
function AccordionContent({
|
|
427
|
+
className,
|
|
428
|
+
children,
|
|
429
|
+
...props
|
|
430
|
+
}) {
|
|
426
431
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
427
432
|
import_react_aria_components.DisclosurePanel,
|
|
428
433
|
{
|
|
429
434
|
"data-slot": "accordion-content",
|
|
430
|
-
className: "h-(--disclosure-panel-height) overflow-clip text-sm transition-[height] data-open:animate-accordion-down data-closed:animate-accordion-up",
|
|
435
|
+
className: "h-(--disclosure-panel-height) overflow-clip text-sm text-muted-foreground transition-[height] data-open:animate-accordion-down data-closed:animate-accordion-up",
|
|
431
436
|
...props,
|
|
432
437
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
433
438
|
"div",
|
|
434
439
|
{
|
|
435
440
|
className: cn(
|
|
436
|
-
"pt-0 pb-
|
|
441
|
+
"px-2.5 pt-0 pb-3 [&_a]:text-foreground [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-primary [&_p:not(:last-child)]:mb-4",
|
|
437
442
|
className
|
|
438
443
|
),
|
|
439
444
|
children
|
|
@@ -1171,7 +1176,7 @@ function DrawerDescription({ className, ...props }) {
|
|
|
1171
1176
|
}
|
|
1172
1177
|
|
|
1173
1178
|
// src/ui/dropdown-menu/dropdown-menu.tsx
|
|
1174
|
-
var
|
|
1179
|
+
var React2 = require("react");
|
|
1175
1180
|
var import_class_variance_authority5 = require("class-variance-authority");
|
|
1176
1181
|
var import_lucide_react4 = require("lucide-react");
|
|
1177
1182
|
var import_react_aria_components11 = require("react-aria-components");
|
|
@@ -1674,7 +1679,7 @@ function FormRow({ label, htmlFor, required, hint, error, className, children })
|
|
|
1674
1679
|
var import_react_aria_components14 = require("react-aria-components");
|
|
1675
1680
|
|
|
1676
1681
|
// src/ui/tooltip/tooltip.tsx
|
|
1677
|
-
var
|
|
1682
|
+
var React3 = __toESM(require("react"), 1);
|
|
1678
1683
|
var import_react_aria_components13 = require("react-aria-components");
|
|
1679
1684
|
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
1680
1685
|
function TooltipTrigger({
|
|
@@ -1682,7 +1687,7 @@ function TooltipTrigger({
|
|
|
1682
1687
|
children,
|
|
1683
1688
|
...props
|
|
1684
1689
|
}) {
|
|
1685
|
-
const [trigger, tooltip] =
|
|
1690
|
+
const [trigger, tooltip] = React3.Children.toArray(children);
|
|
1686
1691
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
1687
1692
|
import_react_aria_components13.TooltipTrigger,
|
|
1688
1693
|
{
|
|
@@ -2586,59 +2591,108 @@ function SubmitButton({ pendingLabel = "Guardando\u2026", loading = false, child
|
|
|
2586
2591
|
}
|
|
2587
2592
|
|
|
2588
2593
|
// src/ui/switch/switch.tsx
|
|
2594
|
+
var import_react12 = require("react");
|
|
2589
2595
|
var import_react_aria_components25 = require("react-aria-components");
|
|
2590
2596
|
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
2591
|
-
var
|
|
2592
|
-
sm: {
|
|
2593
|
-
|
|
2597
|
+
var switchSizes = {
|
|
2598
|
+
sm: {
|
|
2599
|
+
control: "h-4 w-[1.875rem] p-0.5",
|
|
2600
|
+
thumb: "h-3 w-4",
|
|
2601
|
+
offset: "0.625rem"
|
|
2602
|
+
},
|
|
2603
|
+
md: {
|
|
2604
|
+
control: "h-5 w-9 p-0.5",
|
|
2605
|
+
thumb: "h-4 w-5",
|
|
2606
|
+
offset: "0.75rem"
|
|
2607
|
+
},
|
|
2608
|
+
lg: {
|
|
2609
|
+
control: "h-6 w-11 p-0.5",
|
|
2610
|
+
thumb: "h-5 w-6",
|
|
2611
|
+
offset: "1rem"
|
|
2612
|
+
}
|
|
2594
2613
|
};
|
|
2595
|
-
function Switch({
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2614
|
+
function Switch({
|
|
2615
|
+
className,
|
|
2616
|
+
children,
|
|
2617
|
+
description,
|
|
2618
|
+
icon,
|
|
2619
|
+
inputRef,
|
|
2620
|
+
isDisabled,
|
|
2621
|
+
isReadOnly,
|
|
2622
|
+
selectedIcon,
|
|
2623
|
+
size = "sm",
|
|
2624
|
+
...props
|
|
2625
|
+
}) {
|
|
2626
|
+
const styles = switchSizes[size];
|
|
2627
|
+
const fallbackInputRef = (0, import_react12.useRef)(null);
|
|
2628
|
+
const resolvedInputRef = inputRef ?? fallbackInputRef;
|
|
2629
|
+
(0, import_react12.useEffect)(() => {
|
|
2630
|
+
const input = resolvedInputRef.current;
|
|
2631
|
+
if (!input) return;
|
|
2632
|
+
const handleDirectionalKey = (event) => {
|
|
2633
|
+
if (event.target !== input || event.defaultPrevented || isDisabled || isReadOnly || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return;
|
|
2634
|
+
const nextSelected = event.key === "ArrowRight" ? true : event.key === "ArrowLeft" ? false : null;
|
|
2635
|
+
if (nextSelected === null) return;
|
|
2636
|
+
event.preventDefault();
|
|
2637
|
+
if (input.checked !== nextSelected) input.click();
|
|
2638
|
+
};
|
|
2639
|
+
const ownerDocument = input.ownerDocument;
|
|
2640
|
+
ownerDocument.addEventListener("keydown", handleDirectionalKey);
|
|
2641
|
+
return () => ownerDocument.removeEventListener("keydown", handleDirectionalKey);
|
|
2642
|
+
}, [isDisabled, isReadOnly, resolvedInputRef]);
|
|
2643
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2644
|
+
import_react_aria_components25.Switch,
|
|
2599
2645
|
{
|
|
2600
2646
|
"data-slot": "switch",
|
|
2601
2647
|
"data-size": size,
|
|
2602
|
-
|
|
2603
|
-
|
|
2648
|
+
inputRef: resolvedInputRef,
|
|
2649
|
+
isDisabled,
|
|
2650
|
+
isReadOnly,
|
|
2651
|
+
className: cn(
|
|
2652
|
+
"group/switch inline-flex cursor-pointer items-center gap-3 text-sm text-foreground outline-none select-none",
|
|
2604
2653
|
"data-disabled:cursor-not-allowed data-disabled:opacity-50",
|
|
2605
|
-
|
|
2654
|
+
className
|
|
2606
2655
|
),
|
|
2656
|
+
...props,
|
|
2607
2657
|
children: (state) => /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_jsx_runtime42.Fragment, { children: [
|
|
2608
2658
|
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2609
2659
|
"span",
|
|
2610
2660
|
{
|
|
2611
2661
|
"aria-hidden": "true",
|
|
2662
|
+
"data-slot": "switch-control",
|
|
2612
2663
|
className: cn(
|
|
2613
|
-
"relative inline-flex shrink-0 items-center rounded-full border border-
|
|
2614
|
-
"
|
|
2615
|
-
"
|
|
2616
|
-
"group-data-selected/switch:
|
|
2617
|
-
"group-data-selected/switch:group-data-hovered/switch:bg-primary/
|
|
2618
|
-
"group-data-focus-visible/switch:ring-3 group-data-focus-visible/switch:ring-ring/
|
|
2619
|
-
|
|
2620
|
-
"motion-reduce:transition-none",
|
|
2621
|
-
styles.track
|
|
2664
|
+
"relative inline-flex shrink-0 items-center overflow-hidden rounded-full border border-border bg-input shadow-inner",
|
|
2665
|
+
"transition-[background-color,border-color,box-shadow] duration-200 ease-out motion-reduce:transition-none",
|
|
2666
|
+
"group-data-hovered/switch:bg-muted-foreground/25",
|
|
2667
|
+
"group-data-selected/switch:border-primary group-data-selected/switch:bg-primary",
|
|
2668
|
+
"group-data-selected/switch:group-data-hovered/switch:bg-primary/85",
|
|
2669
|
+
"group-data-focus-visible/switch:ring-3 group-data-focus-visible/switch:ring-ring/50",
|
|
2670
|
+
styles.control
|
|
2622
2671
|
),
|
|
2623
2672
|
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
2624
2673
|
"span",
|
|
2625
2674
|
{
|
|
2675
|
+
"data-slot": "switch-thumb",
|
|
2676
|
+
style: { transform: state.isSelected ? `translate3d(${styles.offset}, 0, 0)` : "translate3d(0, 0, 0)" },
|
|
2626
2677
|
className: cn(
|
|
2627
|
-
"
|
|
2628
|
-
"transition-[transform,background-color,
|
|
2629
|
-
"group-data-selected/switch:
|
|
2630
|
-
"group-data-
|
|
2631
|
-
styles.travel,
|
|
2678
|
+
"grid shrink-0 place-items-center rounded-full border border-border/60 bg-background text-[0.625rem] text-muted-foreground shadow-sm",
|
|
2679
|
+
"will-change-transform transition-[transform,background-color,color,border-color] duration-[240ms] ease-[cubic-bezier(0.2,0.8,0.2,1)] motion-reduce:transition-none",
|
|
2680
|
+
"group-data-selected/switch:border-primary-foreground/20",
|
|
2681
|
+
"group-data-selected/switch:bg-primary-foreground group-data-selected/switch:text-primary",
|
|
2632
2682
|
styles.thumb
|
|
2633
|
-
)
|
|
2683
|
+
),
|
|
2684
|
+
children: state.isSelected ? selectedIcon ?? icon : icon
|
|
2634
2685
|
}
|
|
2635
2686
|
)
|
|
2636
2687
|
}
|
|
2637
2688
|
),
|
|
2638
|
-
children
|
|
2689
|
+
children || description ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { className: "grid gap-0.5 leading-tight", children: [
|
|
2690
|
+
children ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { "data-slot": "switch-label", className: "font-medium", children: typeof children === "function" ? children(state) : children }) : null,
|
|
2691
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { "data-slot": "switch-description", className: "text-xs font-normal text-muted-foreground", children: description }) : null
|
|
2692
|
+
] }) : null
|
|
2639
2693
|
] })
|
|
2640
2694
|
}
|
|
2641
|
-
)
|
|
2695
|
+
);
|
|
2642
2696
|
}
|
|
2643
2697
|
|
|
2644
2698
|
// src/ui/table/table.tsx
|
|
@@ -2743,7 +2797,7 @@ function TabsContent({ className, ...props }) {
|
|
|
2743
2797
|
}
|
|
2744
2798
|
|
|
2745
2799
|
// src/ui/toast/toast.tsx
|
|
2746
|
-
var
|
|
2800
|
+
var import_react13 = require("react");
|
|
2747
2801
|
var import_sileo = require("sileo");
|
|
2748
2802
|
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
2749
2803
|
function toSileoOptions({ title, description, duration, position, action }) {
|
|
@@ -2798,7 +2852,7 @@ function ToastViewport({ position, visiblePosition, className }) {
|
|
|
2798
2852
|
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Toaster, { position });
|
|
2799
2853
|
}
|
|
2800
2854
|
function Toast({ id, title, description, variant = "default", action, state = "open", duration = 0, position, onDismiss }) {
|
|
2801
|
-
(0,
|
|
2855
|
+
(0, import_react13.useEffect)(() => {
|
|
2802
2856
|
if (state !== "open") return;
|
|
2803
2857
|
const toastId = create({ title, description, variant, action, duration, position });
|
|
2804
2858
|
return () => {
|