@hex-core/components 0.2.0 → 1.0.0
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/dist/index.d.ts +69 -16
- package/dist/index.js +140 -51
- package/dist/index.js.map +1 -1
- package/package.json +99 -99
package/dist/index.d.ts
CHANGED
|
@@ -125,11 +125,21 @@ declare const RadioGroup: React$1.ForwardRefExoticComponent<Omit<RadioGroupPrimi
|
|
|
125
125
|
/** A single radio option within a RadioGroup. */
|
|
126
126
|
declare const RadioGroupItem: React$1.ForwardRefExoticComponent<Omit<RadioGroupPrimitive.RadioGroupItemProps & React$1.RefAttributes<HTMLButtonElement>, "ref"> & React$1.RefAttributes<HTMLButtonElement>>;
|
|
127
127
|
|
|
128
|
+
interface SliderProps extends React$1.ComponentPropsWithoutRef<typeof SliderPrimitive.Root> {
|
|
129
|
+
/**
|
|
130
|
+
* Per-thumb accessible labels. When the slider has multiple thumbs, pass
|
|
131
|
+
* one entry per thumb (e.g. ["Minimum", "Maximum"]). For a single-thumb
|
|
132
|
+
* slider, the Root's `aria-label` / `aria-labelledby` is mirrored onto
|
|
133
|
+
* the thumb automatically — pass `thumbLabels` only when those defaults
|
|
134
|
+
* are insufficient.
|
|
135
|
+
*/
|
|
136
|
+
thumbLabels?: string[];
|
|
137
|
+
}
|
|
128
138
|
/**
|
|
129
139
|
* A range input with one or more draggable thumbs.
|
|
130
140
|
* Built on Radix UI Slider with keyboard controls (arrows, Home, End, PageUp/Down).
|
|
131
141
|
*/
|
|
132
|
-
declare const Slider: React$1.ForwardRefExoticComponent<
|
|
142
|
+
declare const Slider: React$1.ForwardRefExoticComponent<SliderProps & React$1.RefAttributes<HTMLSpanElement>>;
|
|
133
143
|
|
|
134
144
|
declare const toggleVariants: (props?: ({
|
|
135
145
|
variant?: "default" | "outline" | null | undefined;
|
|
@@ -175,8 +185,17 @@ declare function Skeleton({ className, ...props }: React$1.HTMLAttributes<HTMLDi
|
|
|
175
185
|
*/
|
|
176
186
|
declare const Progress: React$1.ForwardRefExoticComponent<Omit<ProgressPrimitive.ProgressProps & React$1.RefAttributes<HTMLDivElement>, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
|
|
177
187
|
|
|
188
|
+
interface ScrollAreaProps extends React$1.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root> {
|
|
189
|
+
/**
|
|
190
|
+
* tabIndex applied to the scroll viewport so keyboard users can scroll
|
|
191
|
+
* without a pointer. Defaults to `0` (focusable) — pass `-1` to skip the
|
|
192
|
+
* viewport in the tab order when ScrollArea wraps purely decorative or
|
|
193
|
+
* already-keyboard-reachable content.
|
|
194
|
+
*/
|
|
195
|
+
viewportTabIndex?: number;
|
|
196
|
+
}
|
|
178
197
|
/** A scrollable area with custom-styled scrollbars. Content must be explicitly sized. */
|
|
179
|
-
declare const ScrollArea: React$1.ForwardRefExoticComponent<
|
|
198
|
+
declare const ScrollArea: React$1.ForwardRefExoticComponent<ScrollAreaProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
180
199
|
/** Styled scrollbar track + thumb. Rendered inside ScrollArea automatically. */
|
|
181
200
|
declare const ScrollBar: React$1.ForwardRefExoticComponent<Omit<ScrollAreaPrimitive.ScrollAreaScrollbarProps & React$1.RefAttributes<HTMLDivElement>, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
|
|
182
201
|
|
|
@@ -224,8 +243,22 @@ declare const DialogPortal: React$1.FC<DialogPrimitive.DialogPortalProps>;
|
|
|
224
243
|
declare const DialogClose: React$1.ForwardRefExoticComponent<DialogPrimitive.DialogCloseProps & React$1.RefAttributes<HTMLButtonElement>>;
|
|
225
244
|
/** Dimmed backdrop rendered behind the dialog content. */
|
|
226
245
|
declare const DialogOverlay: React$1.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogOverlayProps & React$1.RefAttributes<HTMLDivElement>, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
|
|
246
|
+
interface DialogContentProps extends React$1.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {
|
|
247
|
+
/**
|
|
248
|
+
* When `true` (the default), DialogContent caps its height at viewport-2rem
|
|
249
|
+
* and renders children inside a padded inner scroll container. The Close
|
|
250
|
+
* button stays anchored to the (non-scrolling) outer panel so it remains
|
|
251
|
+
* visible even when the user scrolls long content.
|
|
252
|
+
*
|
|
253
|
+
* Pass `scrollable={false}` to opt out — useful when the consumer manages
|
|
254
|
+
* its own scroll surface (e.g. CommandDialog defers scroll to cmdk's
|
|
255
|
+
* internal CommandList).
|
|
256
|
+
*/
|
|
257
|
+
scrollable?: boolean;
|
|
258
|
+
}
|
|
227
259
|
/** The dialog content panel, centered on the overlay. Includes a close button by default. */
|
|
228
|
-
declare const DialogContent: React$1.ForwardRefExoticComponent<
|
|
260
|
+
declare const DialogContent: React$1.ForwardRefExoticComponent<DialogContentProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
261
|
+
|
|
229
262
|
/**
|
|
230
263
|
* Header container inside DialogContent; stacks title and description.
|
|
231
264
|
* @returns A div wrapping title/description with vertical rhythm
|
|
@@ -511,7 +544,11 @@ declare const TableRow: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes
|
|
|
511
544
|
declare const TableHead: React$1.ForwardRefExoticComponent<React$1.ThHTMLAttributes<HTMLTableCellElement> & React$1.RefAttributes<HTMLTableCellElement>>;
|
|
512
545
|
/** `<td>` with consistent padding. */
|
|
513
546
|
declare const TableCell: React$1.ForwardRefExoticComponent<React$1.TdHTMLAttributes<HTMLTableCellElement> & React$1.RefAttributes<HTMLTableCellElement>>;
|
|
514
|
-
/**
|
|
547
|
+
/**
|
|
548
|
+
* Visible `<caption>` rendered below the table. The parent `<Table>` sets
|
|
549
|
+
* `caption-bottom`, so the caption is announced first by screen readers when
|
|
550
|
+
* entering the table, then visually placed below the rows.
|
|
551
|
+
*/
|
|
515
552
|
declare const TableCaption: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLTableCaptionElement> & React$1.RefAttributes<HTMLTableCaptionElement>>;
|
|
516
553
|
|
|
517
554
|
/**
|
|
@@ -523,13 +560,24 @@ declare const TableCaption: React$1.ForwardRefExoticComponent<React$1.HTMLAttrib
|
|
|
523
560
|
interface DataTableProps<TData> {
|
|
524
561
|
columns: ColumnDef<TData, unknown>[];
|
|
525
562
|
data: TData[];
|
|
563
|
+
/**
|
|
564
|
+
* Visible caption rendered below the table. Announced by screen readers
|
|
565
|
+
* when the user enters the table. Provide either `caption` or `aria-label`.
|
|
566
|
+
*/
|
|
567
|
+
caption?: React$1.ReactNode;
|
|
568
|
+
/**
|
|
569
|
+
* Accessible label for the table when no visible caption is shown.
|
|
570
|
+
* Forwarded as `aria-label` on the underlying `<table>` element. Kebab-case
|
|
571
|
+
* to match the canonical ARIA prop convention used elsewhere in Hex UI.
|
|
572
|
+
*/
|
|
573
|
+
"aria-label"?: string;
|
|
526
574
|
}
|
|
527
575
|
/**
|
|
528
576
|
* Render a data-driven table from TanStack column definitions.
|
|
529
|
-
* @param props - Columns and
|
|
577
|
+
* @param props - Columns, data, and optional accessible labelling (`caption` or `aria-label`)
|
|
530
578
|
* @returns A styled Table rendered from the TanStack row model
|
|
531
579
|
*/
|
|
532
|
-
declare function DataTable<TData>({ columns, data }: DataTableProps<TData>): react_jsx_runtime.JSX.Element;
|
|
580
|
+
declare function DataTable<TData>({ columns, data, caption, "aria-label": ariaLabel, }: DataTableProps<TData>): react_jsx_runtime.JSX.Element;
|
|
533
581
|
|
|
534
582
|
/**
|
|
535
583
|
* Root nav landmark for pagination controls.
|
|
@@ -690,14 +738,17 @@ declare const CommandGroup: React$1.ForwardRefExoticComponent<Omit<{
|
|
|
690
738
|
value?: string;
|
|
691
739
|
forceMount?: boolean;
|
|
692
740
|
} & React$1.RefAttributes<HTMLDivElement>, "ref"> & React$1.RefAttributes<HTMLDivElement>>;
|
|
693
|
-
/**
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
741
|
+
/**
|
|
742
|
+
* Horizontal rule between groups. Renders as a presentational `<div>` (no role)
|
|
743
|
+
* so it can sit inside CommandList (role=listbox) without violating ARIA's
|
|
744
|
+
* required-children rule for listbox. The line is purely decorative — cmdk's
|
|
745
|
+
* built-in Separator hardcodes `role="separator"`, which axe rejects in this
|
|
746
|
+
* context, so we render the divider directly.
|
|
747
|
+
*
|
|
748
|
+
* The `data-cmdk-separator` attribute is preserved so existing CSS / test
|
|
749
|
+
* selectors that target cmdk's separator continue to match.
|
|
750
|
+
*/
|
|
751
|
+
declare const CommandSeparator: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & React$1.RefAttributes<HTMLDivElement>>;
|
|
701
752
|
/** Selectable item. onSelect fires on Enter or click. */
|
|
702
753
|
declare const CommandItem: React$1.ForwardRefExoticComponent<Omit<{
|
|
703
754
|
children?: React$1.ReactNode;
|
|
@@ -746,8 +797,10 @@ interface ComboboxProps {
|
|
|
746
797
|
disabled?: boolean;
|
|
747
798
|
/** Extra class names on the trigger button. */
|
|
748
799
|
className?: string;
|
|
749
|
-
/** Accessible label for the trigger (required when no adjacent visible
|
|
800
|
+
/** Accessible label for the trigger (required when no adjacent visible label). */
|
|
750
801
|
"aria-label"?: string;
|
|
802
|
+
/** Id of an external visible label that names this combobox. */
|
|
803
|
+
"aria-labelledby"?: string;
|
|
751
804
|
}
|
|
752
805
|
/**
|
|
753
806
|
* Searchable select input built on Command + Popover.
|
|
@@ -756,7 +809,7 @@ interface ComboboxProps {
|
|
|
756
809
|
* the trigger; the popover contains a CommandInput and filtered CommandList.
|
|
757
810
|
* @returns A trigger button that opens a filtered option list.
|
|
758
811
|
*/
|
|
759
|
-
declare function Combobox({ options, value, onChange, placeholder, searchPlaceholder, emptyText, disabled, className, "aria-label": ariaLabel, }: ComboboxProps): react_jsx_runtime.JSX.Element;
|
|
812
|
+
declare function Combobox({ options, value, onChange, placeholder, searchPlaceholder, emptyText, disabled, className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, }: ComboboxProps): react_jsx_runtime.JSX.Element;
|
|
760
813
|
declare namespace Combobox {
|
|
761
814
|
var displayName: string;
|
|
762
815
|
}
|
package/dist/index.js
CHANGED
|
@@ -488,30 +488,46 @@ RadioGroupItem.displayName = "RadioGroupItem";
|
|
|
488
488
|
import * as SliderPrimitive from "@radix-ui/react-slider";
|
|
489
489
|
import * as React10 from "react";
|
|
490
490
|
import { jsx as jsx11, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
491
|
-
var Slider = React10.forwardRef(({ className, ...props }, ref) =>
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
(props.value ?? props.defaultValue ?? [0]).map((_, i) => /* @__PURE__ */ jsx11(
|
|
500
|
-
SliderPrimitive.Thumb,
|
|
501
|
-
{
|
|
502
|
-
className: cn(
|
|
503
|
-
"block h-5 w-5 rounded-full border-2 border-primary bg-background",
|
|
504
|
-
"transition-all duration-[var(--duration-normal,200ms)] ease-out shadow-md",
|
|
505
|
-
"hover:shadow-lg hover:scale-110",
|
|
506
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
507
|
-
"disabled:pointer-events-none disabled:opacity-50"
|
|
508
|
-
)
|
|
509
|
-
},
|
|
510
|
-
i
|
|
511
|
-
))
|
|
512
|
-
]
|
|
491
|
+
var Slider = React10.forwardRef(({ className, thumbLabels, ...props }, ref) => {
|
|
492
|
+
const values = props.value ?? props.defaultValue ?? [0];
|
|
493
|
+
const rootLabel = props["aria-label"];
|
|
494
|
+
const rootLabelledBy = props["aria-labelledby"];
|
|
495
|
+
if (typeof process !== "undefined" && process.env?.NODE_ENV !== "production" && thumbLabels && thumbLabels.length !== values.length) {
|
|
496
|
+
console.warn(
|
|
497
|
+
`Slider: thumbLabels.length (${thumbLabels.length}) does not match value.length (${values.length}). Missing labels fall back to indexed names; extra labels are ignored.`
|
|
498
|
+
);
|
|
513
499
|
}
|
|
514
|
-
|
|
500
|
+
return /* @__PURE__ */ jsxs4(
|
|
501
|
+
SliderPrimitive.Root,
|
|
502
|
+
{
|
|
503
|
+
ref,
|
|
504
|
+
className: cn("relative flex w-full touch-none select-none items-center", className),
|
|
505
|
+
...props,
|
|
506
|
+
children: [
|
|
507
|
+
/* @__PURE__ */ jsx11(SliderPrimitive.Track, { className: "relative h-2 w-full grow overflow-hidden rounded-full bg-secondary", children: /* @__PURE__ */ jsx11(SliderPrimitive.Range, { className: "absolute h-full bg-primary" }) }),
|
|
508
|
+
values.map((_, i) => {
|
|
509
|
+
const explicit = thumbLabels?.[i];
|
|
510
|
+
const fallback = values.length === 1 ? rootLabel : rootLabel ? `${rootLabel} (${i + 1} of ${values.length})` : void 0;
|
|
511
|
+
return /* @__PURE__ */ jsx11(
|
|
512
|
+
SliderPrimitive.Thumb,
|
|
513
|
+
{
|
|
514
|
+
"aria-label": explicit ?? fallback,
|
|
515
|
+
"aria-labelledby": explicit || fallback ? void 0 : rootLabelledBy,
|
|
516
|
+
className: cn(
|
|
517
|
+
"block h-5 w-5 rounded-full border-2 border-primary bg-background",
|
|
518
|
+
"transition-all duration-[var(--duration-normal,200ms)] ease-out shadow-md",
|
|
519
|
+
"hover:shadow-lg hover:scale-110",
|
|
520
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
521
|
+
"disabled:pointer-events-none disabled:opacity-50"
|
|
522
|
+
)
|
|
523
|
+
},
|
|
524
|
+
i
|
|
525
|
+
);
|
|
526
|
+
})
|
|
527
|
+
]
|
|
528
|
+
}
|
|
529
|
+
);
|
|
530
|
+
});
|
|
515
531
|
Slider.displayName = "Slider";
|
|
516
532
|
|
|
517
533
|
// src/primitives/toggle/toggle.tsx
|
|
@@ -666,14 +682,24 @@ Progress.displayName = "Progress";
|
|
|
666
682
|
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
|
667
683
|
import * as React15 from "react";
|
|
668
684
|
import { jsx as jsx17, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
669
|
-
var ScrollArea = React15.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs5(
|
|
685
|
+
var ScrollArea = React15.forwardRef(({ className, children, viewportTabIndex = 0, ...props }, ref) => /* @__PURE__ */ jsxs5(
|
|
670
686
|
ScrollAreaPrimitive.Root,
|
|
671
687
|
{
|
|
672
688
|
ref,
|
|
673
689
|
className: cn("relative overflow-hidden", className),
|
|
674
690
|
...props,
|
|
675
691
|
children: [
|
|
676
|
-
/* @__PURE__ */ jsx17(
|
|
692
|
+
/* @__PURE__ */ jsx17(
|
|
693
|
+
ScrollAreaPrimitive.Viewport,
|
|
694
|
+
{
|
|
695
|
+
tabIndex: viewportTabIndex,
|
|
696
|
+
className: cn(
|
|
697
|
+
"h-full w-full rounded-[inherit]",
|
|
698
|
+
viewportTabIndex >= 0 && "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
|
|
699
|
+
),
|
|
700
|
+
children
|
|
701
|
+
}
|
|
702
|
+
),
|
|
677
703
|
/* @__PURE__ */ jsx17(ScrollBar, { orientation: "vertical" }),
|
|
678
704
|
/* @__PURE__ */ jsx17(ScrollBar, { orientation: "horizontal" }),
|
|
679
705
|
/* @__PURE__ */ jsx17(ScrollAreaPrimitive.Corner, {})
|
|
@@ -884,15 +910,15 @@ var DialogOverlay = React19.forwardRef(({ className, ...props }, ref) => /* @__P
|
|
|
884
910
|
}
|
|
885
911
|
));
|
|
886
912
|
DialogOverlay.displayName = "DialogOverlay";
|
|
887
|
-
var DialogContent = React19.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs7(DialogPortal, { children: [
|
|
913
|
+
var DialogContent = React19.forwardRef(({ className, children, scrollable = true, ...props }, ref) => /* @__PURE__ */ jsxs7(DialogPortal, { children: [
|
|
888
914
|
/* @__PURE__ */ jsx21(DialogOverlay, {}),
|
|
889
915
|
/* @__PURE__ */ jsxs7(
|
|
890
916
|
DialogPrimitive.Content,
|
|
891
917
|
{
|
|
892
918
|
ref,
|
|
893
919
|
className: cn(
|
|
894
|
-
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%]
|
|
895
|
-
"border bg-background p-[var(--space-6,1.5rem)] shadow-lg rounded-lg",
|
|
920
|
+
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%]",
|
|
921
|
+
scrollable ? "max-h-[calc(100vh-2rem)] border bg-background shadow-lg rounded-lg" : "gap-[var(--gap-md,1rem)] border bg-background p-[var(--space-6,1.5rem)] shadow-lg rounded-lg",
|
|
896
922
|
"duration-[var(--duration-normal,200ms)] data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
897
923
|
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
898
924
|
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
@@ -900,12 +926,12 @@ var DialogContent = React19.forwardRef(({ className, children, ...props }, ref)
|
|
|
900
926
|
),
|
|
901
927
|
...props,
|
|
902
928
|
children: [
|
|
903
|
-
children,
|
|
929
|
+
scrollable ? /* @__PURE__ */ jsx21("div", { className: "grid gap-[var(--gap-md,1rem)] overflow-y-auto p-[var(--space-6,1.5rem)]", children }) : children,
|
|
904
930
|
/* @__PURE__ */ jsxs7(
|
|
905
931
|
DialogPrimitive.Close,
|
|
906
932
|
{
|
|
907
933
|
className: cn(
|
|
908
|
-
"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background",
|
|
934
|
+
"absolute right-4 top-4 z-10 rounded-sm opacity-70 ring-offset-background bg-background/80 backdrop-blur-sm",
|
|
909
935
|
"transition-all duration-[var(--duration-normal,200ms)] ease-out hover:opacity-100",
|
|
910
936
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
911
937
|
"disabled:pointer-events-none"
|
|
@@ -1962,7 +1988,10 @@ var TableCaption = React31.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
1962
1988
|
"caption",
|
|
1963
1989
|
{
|
|
1964
1990
|
ref,
|
|
1965
|
-
className: cn(
|
|
1991
|
+
className: cn(
|
|
1992
|
+
"caption-bottom mt-[var(--space-4,1rem)] text-sm text-muted-foreground",
|
|
1993
|
+
className
|
|
1994
|
+
),
|
|
1966
1995
|
...props
|
|
1967
1996
|
}
|
|
1968
1997
|
));
|
|
@@ -1975,13 +2004,19 @@ import {
|
|
|
1975
2004
|
useReactTable
|
|
1976
2005
|
} from "@tanstack/react-table";
|
|
1977
2006
|
import { jsx as jsx35, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1978
|
-
function DataTable({
|
|
2007
|
+
function DataTable({
|
|
2008
|
+
columns,
|
|
2009
|
+
data,
|
|
2010
|
+
caption,
|
|
2011
|
+
"aria-label": ariaLabel
|
|
2012
|
+
}) {
|
|
1979
2013
|
const table = useReactTable({
|
|
1980
2014
|
data,
|
|
1981
2015
|
columns,
|
|
1982
2016
|
getCoreRowModel: getCoreRowModel()
|
|
1983
2017
|
});
|
|
1984
|
-
return /* @__PURE__ */ jsx35("div", { className: "rounded-md border", children: /* @__PURE__ */ jsxs13(Table, { children: [
|
|
2018
|
+
return /* @__PURE__ */ jsx35("div", { className: "rounded-md border", children: /* @__PURE__ */ jsxs13(Table, { "aria-label": ariaLabel, children: [
|
|
2019
|
+
caption ? /* @__PURE__ */ jsx35(TableCaption, { children: caption }) : null,
|
|
1985
2020
|
/* @__PURE__ */ jsx35(TableHeader, { children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx35(TableRow, { children: headerGroup.headers.map((header) => /* @__PURE__ */ jsx35(TableHead, { children: header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext()) }, header.id)) }, headerGroup.id)) }),
|
|
1986
2021
|
/* @__PURE__ */ jsx35(TableBody, { children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx35(TableRow, { "data-state": row.getIsSelected() && "selected", children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx35(TableCell, { children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id)) }, row.id)) : /* @__PURE__ */ jsx35(TableRow, { children: /* @__PURE__ */ jsx35(TableCell, { colSpan: columns.length, className: "h-24 text-center", children: "No results." }) }) })
|
|
1987
2022
|
] }) });
|
|
@@ -2350,7 +2385,7 @@ function CommandDialog({
|
|
|
2350
2385
|
/* @__PURE__ */ jsx40(DialogTitle, { children: title }),
|
|
2351
2386
|
/* @__PURE__ */ jsx40(DialogDescription, { children: description })
|
|
2352
2387
|
] }),
|
|
2353
|
-
/* @__PURE__ */ jsx40(DialogContent, { className: "overflow-hidden p-0", children: /* @__PURE__ */ jsx40(Command, { className: "[&_[cmdk-group-heading]]:px-[var(--space-2,0.5rem)] [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-[var(--space-2,0.5rem)] [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-[var(--space-2,0.5rem)] [&_[cmdk-item]]:py-[var(--space-3,0.75rem)] [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5", children }) })
|
|
2388
|
+
/* @__PURE__ */ jsx40(DialogContent, { className: "overflow-hidden p-0", scrollable: false, children: /* @__PURE__ */ jsx40(Command, { className: "[&_[cmdk-group-heading]]:px-[var(--space-2,0.5rem)] [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-[var(--space-2,0.5rem)] [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-[var(--space-2,0.5rem)] [&_[cmdk-item]]:py-[var(--space-3,0.75rem)] [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5", children }) })
|
|
2354
2389
|
] });
|
|
2355
2390
|
}
|
|
2356
2391
|
var CommandInput = React35.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs17("div", { className: "flex items-center border-b px-[var(--space-3,0.75rem)]", "cmdk-input-wrapper": "", children: [
|
|
@@ -2409,9 +2444,11 @@ var CommandGroup = React35.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
2409
2444
|
));
|
|
2410
2445
|
CommandGroup.displayName = "CommandGroup";
|
|
2411
2446
|
var CommandSeparator = React35.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx40(
|
|
2412
|
-
|
|
2447
|
+
"div",
|
|
2413
2448
|
{
|
|
2414
2449
|
ref,
|
|
2450
|
+
role: "none",
|
|
2451
|
+
"data-cmdk-separator": "",
|
|
2415
2452
|
className: cn("-mx-[var(--space-1,0.25rem)] h-px bg-border", className),
|
|
2416
2453
|
...props
|
|
2417
2454
|
}
|
|
@@ -2458,9 +2495,11 @@ function Combobox({
|
|
|
2458
2495
|
emptyText = "No results found.",
|
|
2459
2496
|
disabled,
|
|
2460
2497
|
className,
|
|
2461
|
-
"aria-label": ariaLabel
|
|
2498
|
+
"aria-label": ariaLabel,
|
|
2499
|
+
"aria-labelledby": ariaLabelledBy
|
|
2462
2500
|
}) {
|
|
2463
2501
|
const [open, setOpen] = React36.useState(false);
|
|
2502
|
+
const listboxId = React36.useId();
|
|
2464
2503
|
const selected = options.find((o) => o.value === value);
|
|
2465
2504
|
return /* @__PURE__ */ jsxs18(Popover, { open, onOpenChange: setOpen, children: [
|
|
2466
2505
|
/* @__PURE__ */ jsx41(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs18(
|
|
@@ -2470,7 +2509,9 @@ function Combobox({
|
|
|
2470
2509
|
role: "combobox",
|
|
2471
2510
|
"aria-expanded": open,
|
|
2472
2511
|
"aria-haspopup": "listbox",
|
|
2512
|
+
"aria-controls": open ? listboxId : void 0,
|
|
2473
2513
|
"aria-label": ariaLabel,
|
|
2514
|
+
"aria-labelledby": ariaLabelledBy,
|
|
2474
2515
|
disabled,
|
|
2475
2516
|
className: cn(
|
|
2476
2517
|
"inline-flex h-[var(--control-height-md,2.5rem)] w-[240px] items-center justify-between gap-[var(--gap-sm,0.5rem)] rounded-md border border-input bg-background px-[var(--space-3,0.75rem)] py-[var(--space-2,0.5rem)] text-sm font-normal transition-all duration-[var(--duration-normal,200ms)] ease-out",
|
|
@@ -2502,7 +2543,7 @@ function Combobox({
|
|
|
2502
2543
|
) }),
|
|
2503
2544
|
/* @__PURE__ */ jsx41(PopoverContent, { className: "w-[240px] p-0", align: "start", children: /* @__PURE__ */ jsxs18(Command, { children: [
|
|
2504
2545
|
/* @__PURE__ */ jsx41(CommandInput, { placeholder: searchPlaceholder }),
|
|
2505
|
-
/* @__PURE__ */ jsxs18(CommandList, { children: [
|
|
2546
|
+
/* @__PURE__ */ jsxs18(CommandList, { id: listboxId, children: [
|
|
2506
2547
|
/* @__PURE__ */ jsx41(CommandEmpty, { children: emptyText }),
|
|
2507
2548
|
/* @__PURE__ */ jsx41(CommandGroup, { children: options.map((option) => /* @__PURE__ */ jsxs18(
|
|
2508
2549
|
CommandItem,
|
|
@@ -3706,7 +3747,7 @@ var dialogSchema = {
|
|
|
3706
3747
|
"Putting too many primary actions in DialogFooter"
|
|
3707
3748
|
],
|
|
3708
3749
|
relatedComponents: ["alert-dialog", "popover", "sheet"],
|
|
3709
|
-
accessibilityNotes: "Radix traps focus, handles Escape to close, and wires aria-labelledby/describedby to DialogTitle/DialogDescription. Always include a DialogTitle.",
|
|
3750
|
+
accessibilityNotes: "Radix traps focus, handles Escape to close, and wires aria-labelledby/describedby to DialogTitle/DialogDescription. Always include a DialogTitle. DialogContent is constrained to `max-h-[calc(100vh-2rem)]` and scrolls internally so long content stays inside the focus trap.",
|
|
3710
3751
|
tokenBudget: 600
|
|
3711
3752
|
},
|
|
3712
3753
|
tags: ["dialog", "modal", "overlay", "popup", "form"]
|
|
@@ -4224,6 +4265,24 @@ var sliderSchema = {
|
|
|
4224
4265
|
default: "horizontal",
|
|
4225
4266
|
description: "Slider direction",
|
|
4226
4267
|
enumValues: ["horizontal", "vertical"]
|
|
4268
|
+
},
|
|
4269
|
+
{
|
|
4270
|
+
name: "aria-label",
|
|
4271
|
+
type: "string",
|
|
4272
|
+
required: false,
|
|
4273
|
+
description: "Accessible label for the slider as a whole. Mirrored onto a single thumb automatically; for range sliders prefer thumbLabels."
|
|
4274
|
+
},
|
|
4275
|
+
{
|
|
4276
|
+
name: "aria-labelledby",
|
|
4277
|
+
type: "string",
|
|
4278
|
+
required: false,
|
|
4279
|
+
description: "Id of an external visible label that names the slider."
|
|
4280
|
+
},
|
|
4281
|
+
{
|
|
4282
|
+
name: "thumbLabels",
|
|
4283
|
+
type: "object",
|
|
4284
|
+
required: false,
|
|
4285
|
+
description: "Per-thumb accessible labels (string[]). Required for range sliders so each thumb has a meaningful name (e.g. ['Minimum price', 'Maximum price']). For a single-thumb slider, the Root's aria-label is mirrored onto the thumb automatically and thumbLabels is only needed when overriding that default."
|
|
4227
4286
|
}
|
|
4228
4287
|
],
|
|
4229
4288
|
variants: [],
|
|
@@ -4253,10 +4312,12 @@ var sliderSchema = {
|
|
|
4253
4312
|
"Using Slider for exact values without showing the number",
|
|
4254
4313
|
"Missing min/max bounds",
|
|
4255
4314
|
"Using step=1 for fractional values (set step=0.01)",
|
|
4256
|
-
"Not providing aria-label when there's no visible label"
|
|
4315
|
+
"Not providing aria-label / aria-labelledby when there's no visible label",
|
|
4316
|
+
"Range slider with only Root aria-label and no thumbLabels \u2014 both thumbs fall back to '(N of 2)' indexed names instead of meaningful per-thumb labels",
|
|
4317
|
+
"thumbLabels.length !== value.length \u2014 extra labels are ignored, missing labels fall back to indexed names (dev-mode warning)"
|
|
4257
4318
|
],
|
|
4258
4319
|
relatedComponents: ["input"],
|
|
4259
|
-
accessibilityNotes: "Arrow keys step by step, Home/End jump to min/max, PageUp/PageDown step larger. Radix handles aria-valuemin/max/now. Add aria-label
|
|
4320
|
+
accessibilityNotes: "Arrow keys step by step, Home/End jump to min/max, PageUp/PageDown step larger. Radix handles aria-valuemin/max/now. Each thumb has its own accessible name: explicit via thumbLabels[i], else mirrored from the Root's aria-label (single thumb) or indexed '(i of N)' fallback (range). Add aria-label / aria-labelledby on the Root when there's no visible label.",
|
|
4260
4321
|
tokenBudget: 450
|
|
4261
4322
|
},
|
|
4262
4323
|
tags: ["slider", "range", "form", "numeric", "input"]
|
|
@@ -4683,7 +4744,14 @@ var scrollAreaSchema = {
|
|
|
4683
4744
|
description: "When scrollbars are visible",
|
|
4684
4745
|
enumValues: ["auto", "always", "scroll", "hover"]
|
|
4685
4746
|
},
|
|
4686
|
-
{ name: "className", type: "string", required: false, description: "Set dimensions via Tailwind (e.g. h-72 w-48)" }
|
|
4747
|
+
{ name: "className", type: "string", required: false, description: "Set dimensions via Tailwind (e.g. h-72 w-48)" },
|
|
4748
|
+
{
|
|
4749
|
+
name: "viewportTabIndex",
|
|
4750
|
+
type: "number",
|
|
4751
|
+
required: false,
|
|
4752
|
+
default: 0,
|
|
4753
|
+
description: "tabIndex applied to the scroll viewport. Defaults to 0 so keyboard users can scroll without a pointer; pass -1 to skip the viewport in the tab order when wrapping decorative or already-keyboard-reachable content."
|
|
4754
|
+
}
|
|
4687
4755
|
],
|
|
4688
4756
|
variants: [],
|
|
4689
4757
|
slots: [
|
|
@@ -4713,10 +4781,11 @@ var scrollAreaSchema = {
|
|
|
4713
4781
|
commonMistakes: [
|
|
4714
4782
|
"Forgetting to set height/width \u2014 scrollbars don't appear",
|
|
4715
4783
|
"Using for the whole page",
|
|
4716
|
-
"Nesting ScrollAreas (confusing UX)"
|
|
4784
|
+
"Nesting ScrollAreas (confusing UX)",
|
|
4785
|
+
"Wrapping decorative or already-keyboard-reachable content without setting viewportTabIndex={-1} \u2014 adds an unnecessary tab stop"
|
|
4717
4786
|
],
|
|
4718
4787
|
relatedComponents: [],
|
|
4719
|
-
accessibilityNotes: "
|
|
4788
|
+
accessibilityNotes: "The viewport is keyboard-focusable by default (viewportTabIndex=0) so users can scroll long content via arrow keys / PgUp / PgDn / Home / End without a pointer. Pass viewportTabIndex={-1} when the contents are already in the tab order or purely decorative. For very long lists, consider pagination or virtualization.",
|
|
4720
4789
|
tokenBudget: 350
|
|
4721
4790
|
},
|
|
4722
4791
|
tags: ["scroll-area", "scroll", "overflow", "scrollbar", "layout"]
|
|
@@ -5250,7 +5319,19 @@ var dataTableSchema = {
|
|
|
5250
5319
|
subcategory: "data",
|
|
5251
5320
|
props: [
|
|
5252
5321
|
{ name: "columns", type: "object", required: true, description: "ColumnDef<TData, TValue>[] from @tanstack/react-table" },
|
|
5253
|
-
{ name: "data", type: "object", required: true, description: "Array of row data" }
|
|
5322
|
+
{ name: "data", type: "object", required: true, description: "Array of row data" },
|
|
5323
|
+
{
|
|
5324
|
+
name: "caption",
|
|
5325
|
+
type: "ReactNode",
|
|
5326
|
+
required: false,
|
|
5327
|
+
description: "Visible caption rendered below the table; announced by screen readers when entering the table"
|
|
5328
|
+
},
|
|
5329
|
+
{
|
|
5330
|
+
name: "aria-label",
|
|
5331
|
+
type: "string",
|
|
5332
|
+
required: false,
|
|
5333
|
+
description: "Accessible label forwarded as aria-label on the underlying <table>; use when no visible caption is shown"
|
|
5334
|
+
}
|
|
5254
5335
|
],
|
|
5255
5336
|
variants: [],
|
|
5256
5337
|
slots: [],
|
|
@@ -5274,10 +5355,11 @@ var dataTableSchema = {
|
|
|
5274
5355
|
"Forgetting getCoreRowModel() (table renders nothing)",
|
|
5275
5356
|
"Recreating columns array on every render (breaks memoization \u2014 wrap in useMemo or define outside the component)",
|
|
5276
5357
|
"Using accessorKey with nested paths without accessorFn",
|
|
5277
|
-
"Not adding filter/sort row models when those features are needed"
|
|
5358
|
+
"Not adding filter/sort row models when those features are needed",
|
|
5359
|
+
"Shipping a table without `caption` or `aria-label` \u2014 the table is unlabelled to assistive tech"
|
|
5278
5360
|
],
|
|
5279
5361
|
relatedComponents: ["table", "pagination"],
|
|
5280
|
-
accessibilityNotes: "
|
|
5362
|
+
accessibilityNotes: "Pass either `caption` (visible) or `aria-label` so screen readers announce the table when the user enters it. Add aria-sort to sortable column headers. Announce filter/sort changes via aria-live for dynamic updates.",
|
|
5281
5363
|
tokenBudget: 900
|
|
5282
5364
|
},
|
|
5283
5365
|
tags: ["data-table", "tanstack", "sortable", "filterable", "paginated"]
|
|
@@ -5691,10 +5773,11 @@ var commandSchema = {
|
|
|
5691
5773
|
"Forgetting CommandList \u2014 items won't be scrollable or grouped properly",
|
|
5692
5774
|
"Giving CommandItem non-unique values (breaks filtering and controlled state)",
|
|
5693
5775
|
"Overriding CommandInput className to remove the border/padding \u2014 breaks the \u2318K icon layout",
|
|
5694
|
-
"Not rendering CommandEmpty \u2014 the list looks broken when a search has no matches"
|
|
5776
|
+
"Not rendering CommandEmpty \u2014 the list looks broken when a search has no matches",
|
|
5777
|
+
"Querying CommandSeparator via cmdk's internal Separator state \u2014 Hex UI renders it as a presentational div with role='none' (and the `data-cmdk-separator` attribute preserved for selector compatibility) so it can sit inside CommandList's role=listbox without violating ARIA"
|
|
5695
5778
|
],
|
|
5696
5779
|
relatedComponents: ["combobox", "dialog", "dropdown-menu"],
|
|
5697
|
-
accessibilityNotes: "cmdk wires role=listbox/option and aria-activedescendant. Use the `label` prop on Command for a screen-reader-only name when no visible heading exists.",
|
|
5780
|
+
accessibilityNotes: "cmdk wires role=listbox/option and aria-activedescendant. Use the `label` prop on Command for a screen-reader-only name when no visible heading exists. CommandSeparator renders with role='none' (still selectable via `[data-cmdk-separator]`) so listbox-children rules are satisfied.",
|
|
5698
5781
|
tokenBudget: 900
|
|
5699
5782
|
},
|
|
5700
5783
|
tags: ["command", "cmdk", "palette", "search", "launcher"]
|
|
@@ -5758,7 +5841,13 @@ var comboboxSchema = {
|
|
|
5758
5841
|
name: "aria-label",
|
|
5759
5842
|
type: "string",
|
|
5760
5843
|
required: false,
|
|
5761
|
-
description: "Accessible label \u2014 required when no adjacent visible
|
|
5844
|
+
description: "Accessible label \u2014 required when no adjacent visible label is used"
|
|
5845
|
+
},
|
|
5846
|
+
{
|
|
5847
|
+
name: "aria-labelledby",
|
|
5848
|
+
type: "string",
|
|
5849
|
+
required: false,
|
|
5850
|
+
description: "Id of an external visible label that names the combobox"
|
|
5762
5851
|
}
|
|
5763
5852
|
],
|
|
5764
5853
|
variants: [],
|
|
@@ -5789,10 +5878,10 @@ var comboboxSchema = {
|
|
|
5789
5878
|
"Using the label as the value \u2014 fine if stable, but prefer a short stable `value` string",
|
|
5790
5879
|
"Forgetting to bind value + onChange \u2014 uncontrolled mode doesn't exist on this wrapper",
|
|
5791
5880
|
"Mixing translated labels without keying on value \u2014 label changes won't update selection",
|
|
5792
|
-
"Missing aria-label
|
|
5881
|
+
"Missing aria-label / aria-labelledby \u2014 role='combobox' does not allow name from contents, so without one of these the trigger has no accessible name"
|
|
5793
5882
|
],
|
|
5794
5883
|
relatedComponents: ["command", "popover", "select"],
|
|
5795
|
-
accessibilityNotes: "Trigger has role='combobox' + aria-expanded.
|
|
5884
|
+
accessibilityNotes: "Trigger has role='combobox' + aria-expanded + aria-haspopup='listbox'. aria-controls points at the inner CommandList (a useId-stabilized listbox). Pass aria-label or aria-labelledby \u2014 combobox does not derive its name from contents.",
|
|
5796
5885
|
tokenBudget: 900
|
|
5797
5886
|
},
|
|
5798
5887
|
tags: ["combobox", "select", "search", "cmdk", "input"]
|