@aircall/ds 0.10.0 → 0.11.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.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import { Accordion as Accordion$1 } from "@base-ui/react/accordion";
2
2
  import { clsx } from "clsx";
3
3
  import { extendTailwindMerge } from "tailwind-merge";
4
- import { ArrowDownToLine, ArrowLeft, ArrowRight, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, CircleAlert, CircleAlertIcon, CircleCheck, FLAGS, FlagUs, Info, Loader2Icon, MinusIcon, MoreHorizontalIcon, PanelLeftIcon, Search, Smile, TriangleAlertIcon, XIcon } from "@aircall/react-icons";
4
+ import { ArrowDownToLine, ArrowLeft, ArrowRight, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ChevronsUpDownIcon, CircleAlert, CircleAlertIcon, CircleCheck, FLAGS, FlagUs, Info, Loader2Icon, MinusIcon, MoreHorizontalIcon, PanelLeftIcon, Search, Smile, TriangleAlertIcon, XIcon } from "@aircall/react-icons";
5
5
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
6
  import * as React$1 from "react";
7
7
  import React, { createContext, useContext, useMemo } from "react";
8
- import { AlertDialog as AlertDialog$1 } from "@base-ui/react/alert-dialog";
9
8
  import { Button as Button$1 } from "@base-ui/react/button";
10
9
  import { cva } from "class-variance-authority";
10
+ import { AlertDialog as AlertDialog$1 } from "@base-ui/react/alert-dialog";
11
11
  import { Avatar as Avatar$1 } from "@base-ui/react/avatar";
12
12
  import { mergeProps } from "@base-ui/react/merge-props";
13
13
  import { useRender } from "@base-ui/react/use-render";
@@ -34,6 +34,7 @@ import { Select as Select$1 } from "@base-ui/react/select";
34
34
  import { Tooltip as Tooltip$1 } from "@base-ui/react/tooltip";
35
35
  import { Slider as Slider$1 } from "@base-ui/react/slider";
36
36
  import { Toaster as Toaster$1, toast } from "sonner";
37
+ import { useControllableState } from "@aircall/hooks";
37
38
  import { Switch as Switch$1 } from "@base-ui/react/switch";
38
39
  import { Tabs as Tabs$1 } from "@base-ui/react/tabs";
39
40
  import { Toggle as Toggle$1 } from "@base-ui/react/toggle";
@@ -157,7 +158,7 @@ const buttonVariants = cva("group/button inline-flex shrink-0 cursor-pointer ite
157
158
  default: "bg-primary text-primary-foreground hover:bg-primary/90",
158
159
  outline: "border-border bg-background hover:bg-muted hover:text-accent-foreground aria-expanded:bg-muted aria-expanded:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
159
160
  secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
160
- ghost: "hover:bg-muted hover:text-accent-foreground aria-expanded:bg-muted aria-expanded:text-accent-foreground dark:hover:bg-muted/50",
161
+ ghost: "hover:bg-muted hover:text-accent-foreground aria-expanded:bg-muted aria-expanded:text-accent-foreground dark:hover:bg-input/50",
161
162
  destructive: "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
162
163
  link: "text-primary underline underline-offset-4"
163
164
  },
@@ -194,6 +195,60 @@ const Button = React$1.forwardRef((componentProps, forwardRef) => {
194
195
  });
195
196
  Button.displayName = "Button";
196
197
 
198
+ //#endregion
199
+ //#region src/components/action-bar.tsx
200
+ /** Fixed height of the ActionBar (px). Single source of truth — the bar uses it
201
+ * for its own height and consumers (e.g. DataTable) reserve space with it. */
202
+ const ActionBarHeight = 48;
203
+ /**
204
+ * Lets a parent (e.g. `DataTable`) supply the selected `count` and an `onClear`
205
+ * handler so an `<ActionBar>` rendered inside it doesn't have to be passed them.
206
+ * Explicit `count`/`onClear` props on `ActionBar` always take precedence, so the
207
+ * component still works standalone. Mirrors React Spectrum's `ActionBarContext`.
208
+ */
209
+ const ActionBarContext = React$1.createContext(null);
210
+ const ActionBarButton = React$1.forwardRef(({ size = "default", ...props }, ref) => /* @__PURE__ */ jsx(Button, {
211
+ ref,
212
+ variant: "ghost",
213
+ size,
214
+ ...props
215
+ }));
216
+ ActionBarButton.displayName = "ActionBarButton";
217
+ const ActionBar = React$1.forwardRef(({ className, count, onClear, children, label, clearLabel = "Clear selection", style, ...props }, ref) => {
218
+ const ctx = React$1.useContext(ActionBarContext);
219
+ const resolvedCount = count ?? ctx?.count ?? 0;
220
+ const resolvedOnClear = onClear ?? ctx?.onClear;
221
+ return /* @__PURE__ */ jsxs("div", {
222
+ ref,
223
+ role: "toolbar",
224
+ "aria-label": "Selection actions",
225
+ "data-slot": "action-bar",
226
+ className: cn("relative flex w-full items-center gap-2 rounded-md border border-border bg-popover px-2 text-popover-foreground shadow-lg", className),
227
+ style: {
228
+ ...style,
229
+ height: ActionBarHeight
230
+ },
231
+ ...props,
232
+ children: [
233
+ resolvedOnClear ? /* @__PURE__ */ jsx(ActionBarButton, {
234
+ size: "icon",
235
+ onClick: resolvedOnClear,
236
+ "aria-label": clearLabel,
237
+ children: /* @__PURE__ */ jsx(XIcon, {})
238
+ }) : null,
239
+ /* @__PURE__ */ jsx("span", {
240
+ className: "flex-1 truncate text-sm",
241
+ children: label ? label(resolvedCount) : `${resolvedCount} items selected.`
242
+ }),
243
+ children ? /* @__PURE__ */ jsx("div", {
244
+ className: "flex shrink-0 items-center gap-2",
245
+ children
246
+ }) : null
247
+ ]
248
+ });
249
+ });
250
+ ActionBar.displayName = "ActionBar";
251
+
197
252
  //#endregion
198
253
  //#region src/components/alert-dialog.tsx
199
254
  function AlertDialog({ ...props }) {
@@ -1039,31 +1094,32 @@ function CalendarDayButton({ className: dayClassName, day, modifiers, locale, ..
1039
1094
 
1040
1095
  //#endregion
1041
1096
  //#region src/components/card.tsx
1042
- function Card({ className, ...props }) {
1097
+ function Card({ className, size = "default", ...props }) {
1043
1098
  return /* @__PURE__ */ jsx("div", {
1044
1099
  "data-slot": "card",
1045
- className: cn("bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm", className),
1100
+ "data-size": size,
1101
+ className: cn("group/card flex flex-col gap-4 overflow-hidden rounded-xl border bg-card py-4 text-sm text-card-foreground has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl", className),
1046
1102
  ...props
1047
1103
  });
1048
1104
  }
1049
1105
  function CardHeader({ className, ...props }) {
1050
1106
  return /* @__PURE__ */ jsx("div", {
1051
1107
  "data-slot": "card-header",
1052
- className: cn("@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6", className),
1108
+ className: cn("group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-4 group-data-[size=sm]/card:px-3 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3", className),
1053
1109
  ...props
1054
1110
  });
1055
1111
  }
1056
1112
  function CardTitle({ className, ...props }) {
1057
1113
  return /* @__PURE__ */ jsx("div", {
1058
1114
  "data-slot": "card-title",
1059
- className: cn("leading-none font-semibold", className),
1115
+ className: cn("text-base leading-snug font-medium group-data-[size=sm]/card:text-sm", className),
1060
1116
  ...props
1061
1117
  });
1062
1118
  }
1063
1119
  function CardDescription({ className, ...props }) {
1064
1120
  return /* @__PURE__ */ jsx("div", {
1065
1121
  "data-slot": "card-description",
1066
- className: cn("text-muted-foreground text-sm", className),
1122
+ className: cn("text-sm text-muted-foreground", className),
1067
1123
  ...props
1068
1124
  });
1069
1125
  }
@@ -1077,14 +1133,14 @@ function CardAction({ className, ...props }) {
1077
1133
  function CardContent({ className, ...props }) {
1078
1134
  return /* @__PURE__ */ jsx("div", {
1079
1135
  "data-slot": "card-content",
1080
- className: cn("px-6", className),
1136
+ className: cn("px-4 group-data-[size=sm]/card:px-3", className),
1081
1137
  ...props
1082
1138
  });
1083
1139
  }
1084
1140
  function CardFooter({ className, ...props }) {
1085
1141
  return /* @__PURE__ */ jsx("div", {
1086
1142
  "data-slot": "card-footer",
1087
- className: cn("flex items-center px-6 [.border-t]:pt-6", className),
1143
+ className: cn("flex items-center rounded-b-xl border-t bg-muted/50 p-4 group-data-[size=sm]/card:p-3", className),
1088
1144
  ...props
1089
1145
  });
1090
1146
  }
@@ -1187,7 +1243,7 @@ function CarouselPrevious({ className, variant = "outline", size = "sm", ...prop
1187
1243
  "data-slot": "carousel-previous",
1188
1244
  variant,
1189
1245
  size,
1190
- className: cn("absolute size-8 rounded-full", orientation === "horizontal" ? "top-1/2 -left-12 -translate-y-1/2" : "-top-12 left-1/2 -translate-x-1/2 rotate-90", className),
1246
+ className: cn("absolute size-8 touch-manipulation rounded-full", orientation === "horizontal" ? "top-1/2 -left-12 -translate-y-1/2" : "-top-12 left-1/2 -translate-x-1/2 rotate-90", className),
1191
1247
  disabled: !canScrollPrev,
1192
1248
  onClick: scrollPrev,
1193
1249
  ...props,
@@ -1203,7 +1259,7 @@ function CarouselNext({ className, variant = "outline", size = "sm", ...props })
1203
1259
  "data-slot": "carousel-next",
1204
1260
  variant,
1205
1261
  size,
1206
- className: cn("absolute size-8 rounded-full", orientation === "horizontal" ? "top-1/2 -right-12 -translate-y-1/2" : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90", className),
1262
+ className: cn("absolute size-8 touch-manipulation rounded-full", orientation === "horizontal" ? "top-1/2 -right-12 -translate-y-1/2" : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90", className),
1207
1263
  disabled: !canScrollNext,
1208
1264
  onClick: scrollNext,
1209
1265
  ...props,
@@ -1916,15 +1972,47 @@ const CountryFlag = ({ countryIsoCode, size = "xl", className, ...otherProps })
1916
1972
  });
1917
1973
  };
1918
1974
 
1975
+ //#endregion
1976
+ //#region src/components/skeleton.tsx
1977
+ function Skeleton({ className, ...props }) {
1978
+ return /* @__PURE__ */ jsx("div", {
1979
+ "data-slot": "skeleton",
1980
+ className: cn("animate-pulse rounded-md bg-muted", className),
1981
+ ...props
1982
+ });
1983
+ }
1984
+
1985
+ //#endregion
1986
+ //#region src/components/spinner.tsx
1987
+ const spinnerVariants = cva("animate-spin text-current", {
1988
+ variants: { size: {
1989
+ default: "size-4",
1990
+ sm: "size-3",
1991
+ lg: "size-5",
1992
+ xl: "size-6"
1993
+ } },
1994
+ defaultVariants: { size: "default" }
1995
+ });
1996
+ function Spinner({ className, size, ...props }) {
1997
+ return /* @__PURE__ */ jsx(Loader2Icon, {
1998
+ "data-slot": "spinner",
1999
+ role: "status",
2000
+ "aria-label": "Loading",
2001
+ className: cn(spinnerVariants({ size }), className),
2002
+ ...props
2003
+ });
2004
+ }
2005
+
1919
2006
  //#endregion
1920
2007
  //#region src/components/table.tsx
1921
- const Table = React$1.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", {
2008
+ const Table = React$1.forwardRef(({ className, containerClassName, containerStyle, ...props }, ref) => /* @__PURE__ */ jsx("div", {
1922
2009
  "data-slot": "table-container",
1923
- className: "relative w-full overflow-x-auto",
2010
+ style: containerStyle,
2011
+ className: cn("relative w-full overflow-x-auto rounded-lg border border-border", containerClassName),
1924
2012
  children: /* @__PURE__ */ jsx("table", {
1925
2013
  ref,
1926
2014
  "data-slot": "table",
1927
- className: cn("w-full caption-bottom text-sm", className),
2015
+ className: cn("w-full caption-bottom text-sm [&_tbody_tr:last-child]:border-b-0", className),
1928
2016
  ...props
1929
2017
  })
1930
2018
  }));
@@ -1932,7 +2020,7 @@ Table.displayName = "Table";
1932
2020
  const TableHeader = React$1.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("thead", {
1933
2021
  ref,
1934
2022
  "data-slot": "table-header",
1935
- className: cn("[&_tr]:border-b", className),
2023
+ className: cn("[&_tr]:border-b [&_tr]:hover:bg-transparent", className),
1936
2024
  ...props
1937
2025
  }));
1938
2026
  TableHeader.displayName = "TableHeader";
@@ -1946,14 +2034,14 @@ TableBody.displayName = "TableBody";
1946
2034
  const TableFooter = React$1.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("tfoot", {
1947
2035
  ref,
1948
2036
  "data-slot": "table-footer",
1949
- className: cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className),
2037
+ className: cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0 [&>tr]:hover:bg-transparent", className),
1950
2038
  ...props
1951
2039
  }));
1952
2040
  TableFooter.displayName = "TableFooter";
1953
2041
  const TableRow = React$1.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("tr", {
1954
2042
  ref,
1955
2043
  "data-slot": "table-row",
1956
- className: cn("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted", className),
2044
+ className: cn("border-b transition-colors hover:bg-accent/30 data-[state=selected]:bg-accent/50", className),
1957
2045
  ...props
1958
2046
  }));
1959
2047
  TableRow.displayName = "TableRow";
@@ -1971,31 +2059,248 @@ const TableCell = React$1.forwardRef(({ className, ...props }, ref) => /* @__PUR
1971
2059
  ...props
1972
2060
  }));
1973
2061
  TableCell.displayName = "TableCell";
1974
- const TableCaption = React$1.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("caption", {
1975
- ref,
1976
- "data-slot": "table-caption",
1977
- className: cn("mt-4 text-sm text-muted-foreground", className),
1978
- ...props
1979
- }));
1980
- TableCaption.displayName = "TableCaption";
1981
2062
 
1982
2063
  //#endregion
1983
2064
  //#region src/components/data-table.tsx
1984
- function DataTable({ columns, data, tableOptions, noResultsMessage = "No results." }) {
2065
+ const SELECT_COLUMN_ID = "__select";
2066
+ const DEFAULT_SKELETON_COUNT = 5;
2067
+ function DataTable({ columns, data, getRowId, loadingState = "idle", skeletonCount = DEFAULT_SKELETON_COUNT, emptyState, sorting, onSortingChange, enableRowSelection, rowSelection, onRowSelectionChange, actionBar, onFetchMore, hasMore = false, enableColumnResizing = false, fillHeight = false, onRowClick, className }) {
2068
+ const sortingEnabled = !!onSortingChange;
2069
+ const selectionEnabled = !!enableRowSelection;
2070
+ const finalColumns = React$1.useMemo(() => {
2071
+ if (!selectionEnabled) return columns;
2072
+ return [makeSelectColumn(), ...columns];
2073
+ }, [columns, selectionEnabled]);
1985
2074
  const table = useReactTable({
1986
2075
  data,
1987
- columns,
2076
+ columns: finalColumns,
1988
2077
  getCoreRowModel: getCoreRowModel(),
1989
- ...tableOptions
2078
+ getRowId,
2079
+ enableSorting: sortingEnabled,
2080
+ manualSorting: sortingEnabled,
2081
+ enableRowSelection,
2082
+ enableColumnResizing,
2083
+ columnResizeMode: "onChange",
2084
+ onSortingChange,
2085
+ onRowSelectionChange,
2086
+ state: {
2087
+ ...sorting !== void 0 && { sorting },
2088
+ ...rowSelection !== void 0 && { rowSelection }
2089
+ }
2090
+ });
2091
+ const rows = table.getRowModel().rows;
2092
+ const selectedCount = table.getSelectedRowModel().rows.length;
2093
+ const hasSelection = selectedCount > 0;
2094
+ const hasFooter = finalColumns.some((col) => col.footer != null);
2095
+ const isInitialLoading = loadingState === "loading";
2096
+ const isRefreshing = loadingState === "sorting" || loadingState === "filtering";
2097
+ const isLoadingMore = loadingState === "loadingMore";
2098
+ const showEmptyState = !isInitialLoading && rows.length === 0 && !!emptyState;
2099
+ const anySelected = hasSelection;
2100
+ const rowClickable = selectionEnabled || !!onRowClick;
2101
+ const handleRowActivate = (row) => {
2102
+ if (selectionEnabled && (anySelected || !onRowClick)) {
2103
+ if (row.getCanSelect()) row.toggleSelected();
2104
+ } else if (onRowClick) onRowClick(row.original);
2105
+ };
2106
+ const colWidth = (size) => enableColumnResizing ? { width: size } : void 0;
2107
+ const showActionBar = !!actionBar && hasSelection;
2108
+ const reservedBottom = showActionBar ? ActionBarHeight + 16 : void 0;
2109
+ const sentinelRef = useFetchMoreSentinel(onFetchMore, fillHeight, data.length);
2110
+ return /* @__PURE__ */ jsxs("div", {
2111
+ className: cn("relative w-full", fillHeight && "flex min-h-0 flex-1 flex-col", className),
2112
+ "aria-busy": isInitialLoading || isRefreshing || void 0,
2113
+ children: [
2114
+ /* @__PURE__ */ jsxs(Table, {
2115
+ className: cn(enableColumnResizing && "table-fixed", fillHeight && "[&_[data-slot=table-head]]:sticky [&_[data-slot=table-head]]:top-0 [&_[data-slot=table-head]]:z-10 [&_[data-slot=table-head]]:bg-background", fillHeight && showEmptyState && "h-full"),
2116
+ containerClassName: fillHeight ? "min-h-0 flex-1 overflow-y-auto" : void 0,
2117
+ containerStyle: reservedBottom ? {
2118
+ paddingBottom: reservedBottom,
2119
+ scrollPaddingBottom: reservedBottom
2120
+ } : void 0,
2121
+ style: enableColumnResizing ? { width: `max(100%, ${table.getTotalSize()}px)` } : void 0,
2122
+ children: [
2123
+ /* @__PURE__ */ jsx(TableHeader, { children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx(TableRow, {
2124
+ className: enableColumnResizing ? "group/header-row" : void 0,
2125
+ children: headerGroup.headers.map((header) => /* @__PURE__ */ jsxs(TableHead, {
2126
+ style: colWidth(header.getSize()),
2127
+ className: enableColumnResizing ? "relative" : void 0,
2128
+ children: [header.isPlaceholder ? null : header.column.getCanSort() ? /* @__PURE__ */ jsx(SortableHeader, { header }) : flexRender(header.column.columnDef.header, header.getContext()), enableColumnResizing && header.column.getCanResize() ? /* @__PURE__ */ jsx(ResizeHandle, { header }) : null]
2129
+ }, header.id))
2130
+ }, headerGroup.id)) }),
2131
+ /* @__PURE__ */ jsx(TableBody, { children: isInitialLoading ? /* @__PURE__ */ jsx(SkeletonRows, {
2132
+ columns: finalColumns,
2133
+ count: skeletonCount
2134
+ }) : rows.length ? /* @__PURE__ */ jsxs(Fragment, { children: [
2135
+ rows.map((row) => /* @__PURE__ */ jsx(TableRow, {
2136
+ "data-state": row.getIsSelected() ? "selected" : void 0,
2137
+ onClick: rowClickable ? () => handleRowActivate(row) : void 0,
2138
+ className: rowClickable ? "cursor-pointer" : void 0,
2139
+ children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx(TableCell, {
2140
+ style: colWidth(cell.column.getSize()),
2141
+ children: flexRender(cell.column.columnDef.cell, cell.getContext())
2142
+ }, cell.id))
2143
+ }, row.id)),
2144
+ isLoadingMore ? /* @__PURE__ */ jsx(TableRow, {
2145
+ className: "hover:bg-transparent",
2146
+ children: /* @__PURE__ */ jsx(TableCell, {
2147
+ colSpan: finalColumns.length,
2148
+ className: "py-3",
2149
+ children: /* @__PURE__ */ jsx("div", {
2150
+ className: "flex items-center justify-center text-muted-foreground",
2151
+ children: /* @__PURE__ */ jsx(Spinner, {})
2152
+ })
2153
+ })
2154
+ }) : null,
2155
+ onFetchMore && hasMore && !isLoadingMore ? /* @__PURE__ */ jsx("tr", {
2156
+ "aria-hidden": true,
2157
+ ref: sentinelRef,
2158
+ children: /* @__PURE__ */ jsx("td", {
2159
+ colSpan: finalColumns.length,
2160
+ className: "h-px"
2161
+ })
2162
+ }) : null
2163
+ ] }) : emptyState ? /* @__PURE__ */ jsx(TableRow, {
2164
+ className: "hover:bg-transparent",
2165
+ children: /* @__PURE__ */ jsx(TableCell, {
2166
+ colSpan: finalColumns.length,
2167
+ className: "h-full p-0",
2168
+ children: /* @__PURE__ */ jsx("div", {
2169
+ className: cn("flex h-full items-center justify-center", !fillHeight && "min-h-60"),
2170
+ children: emptyState
2171
+ })
2172
+ })
2173
+ }) : null }),
2174
+ hasFooter && !isInitialLoading ? /* @__PURE__ */ jsx(TableFooter, { children: table.getFooterGroups().map((footerGroup) => /* @__PURE__ */ jsx(TableRow, { children: footerGroup.headers.map((header) => /* @__PURE__ */ jsx(TableCell, {
2175
+ style: colWidth(header.getSize()),
2176
+ children: header.isPlaceholder ? null : flexRender(header.column.columnDef.footer, header.getContext())
2177
+ }, header.id)) }, footerGroup.id)) }) : null
2178
+ ]
2179
+ }),
2180
+ isRefreshing ? /* @__PURE__ */ jsx("div", {
2181
+ "data-slot": "table-loading-overlay",
2182
+ className: "bg-background/60 absolute inset-0 z-10 flex items-center justify-center",
2183
+ children: /* @__PURE__ */ jsx(Spinner, {
2184
+ size: "lg",
2185
+ className: "text-muted-foreground"
2186
+ })
2187
+ }) : null,
2188
+ showActionBar ? /* @__PURE__ */ jsx("div", {
2189
+ className: "pointer-events-none absolute inset-x-0 bottom-0 z-20 flex justify-center p-2",
2190
+ children: /* @__PURE__ */ jsx("div", {
2191
+ className: "animate-in fade-in slide-in-from-bottom-4 pointer-events-auto w-full duration-200 ease-out",
2192
+ children: /* @__PURE__ */ jsx(ActionBarContext.Provider, {
2193
+ value: {
2194
+ count: selectedCount,
2195
+ onClear: () => table.resetRowSelection()
2196
+ },
2197
+ children: actionBar
2198
+ })
2199
+ })
2200
+ }) : null
2201
+ ]
2202
+ });
2203
+ }
2204
+ function makeSelectColumn() {
2205
+ return {
2206
+ id: SELECT_COLUMN_ID,
2207
+ header: ({ table }) => {
2208
+ const allSelected = table.getIsAllRowsSelected();
2209
+ const someSelected = table.getIsSomeRowsSelected();
2210
+ return /* @__PURE__ */ jsx(Checkbox, {
2211
+ checked: allSelected,
2212
+ indeterminate: !allSelected && someSelected,
2213
+ onCheckedChange: (value) => table.toggleAllRowsSelected(value === true),
2214
+ "aria-label": "Select all rows"
2215
+ });
2216
+ },
2217
+ cell: ({ row }) => /* @__PURE__ */ jsx("span", {
2218
+ className: "contents",
2219
+ onClick: (e) => e.stopPropagation(),
2220
+ children: /* @__PURE__ */ jsx(Checkbox, {
2221
+ checked: row.getIsSelected(),
2222
+ disabled: !row.getCanSelect(),
2223
+ onCheckedChange: (value) => row.toggleSelected(value === true),
2224
+ "aria-label": "Select row"
2225
+ })
2226
+ }),
2227
+ enableSorting: false,
2228
+ enableHiding: false,
2229
+ enableResizing: false,
2230
+ size: 40
2231
+ };
2232
+ }
2233
+ function ResizeHandle({ header }) {
2234
+ const isResizing = header.column.getIsResizing();
2235
+ return /* @__PURE__ */ jsx("span", {
2236
+ "aria-hidden": true,
2237
+ onMouseDown: header.getResizeHandler(),
2238
+ onTouchStart: header.getResizeHandler(),
2239
+ onClick: (e) => e.stopPropagation(),
2240
+ className: cn("absolute top-0 right-0 z-10 h-full w-1 cursor-col-resize touch-none select-none bg-border opacity-0 transition-opacity group-hover/header-row:opacity-100 hover:opacity-100", isResizing && "bg-primary opacity-100")
2241
+ });
2242
+ }
2243
+ function SortableHeader({ header }) {
2244
+ const direction = header.column.getIsSorted();
2245
+ const Icon = direction === "asc" ? ChevronUpIcon : direction === "desc" ? ChevronDownIcon : ChevronsUpDownIcon;
2246
+ return /* @__PURE__ */ jsxs(Button, {
2247
+ variant: "ghost",
2248
+ size: "sm",
2249
+ className: "-ml-2 h-7 data-[icon=inline-end]:pr-2",
2250
+ onClick: header.column.getToggleSortingHandler(),
2251
+ children: [flexRender(header.column.columnDef.header, header.getContext()), /* @__PURE__ */ jsx(Icon, {
2252
+ "data-icon": "inline-end",
2253
+ className: cn("size-3.5", direction === false && "opacity-50")
2254
+ })]
1990
2255
  });
1991
- return /* @__PURE__ */ jsxs(Table, { children: [/* @__PURE__ */ jsx(TableHeader, { children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx(TableRow, { children: headerGroup.headers.map((header) => /* @__PURE__ */ jsx(TableHead, { children: header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext()) }, header.id)) }, headerGroup.id)) }), /* @__PURE__ */ jsx(TableBody, { children: table.getRowModel().rows.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsx(TableRow, {
1992
- "data-state": row.getIsSelected() && "selected",
1993
- children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx(TableCell, { children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id))
1994
- }, row.id)) : /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, {
1995
- colSpan: columns.length,
1996
- className: "h-24 text-center",
1997
- children: noResultsMessage
1998
- }) }) })] });
2256
+ }
2257
+ function SkeletonRows({ columns, count }) {
2258
+ return /* @__PURE__ */ jsx(Fragment, { children: Array.from({ length: count }, (_, i) => /* @__PURE__ */ jsx(TableRow, { children: columns.map((col, ci) => /* @__PURE__ */ jsx(TableCell, {
2259
+ "data-test": "loading-cell",
2260
+ children: /* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-full max-w-full" })
2261
+ }, col.id ?? `col-${ci}`)) }, `skeleton-${i}`)) });
2262
+ }
2263
+ /**
2264
+ * Returns a callback ref for the scroll sentinel. The observer is (re)attached
2265
+ * whenever the sentinel node mounts — so it works even if the sentinel only
2266
+ * appears after the first page loads (the sentinel's presence is the gate). It
2267
+ * fires `onFetchMore` once per mount and disconnects immediately, so a single
2268
+ * page never triggers duplicate fetches; the sentinel remounts for the next page.
2269
+ */
2270
+ function useFetchMoreSentinel(onFetchMore, fillHeight, resetKey) {
2271
+ const onFetchMoreRef = React$1.useRef(onFetchMore);
2272
+ onFetchMoreRef.current = onFetchMore;
2273
+ const observerRef = React$1.useRef(null);
2274
+ const nodeRef = React$1.useRef(null);
2275
+ const armedRef = React$1.useRef(true);
2276
+ const observe = React$1.useCallback(() => {
2277
+ observerRef.current?.disconnect();
2278
+ observerRef.current = null;
2279
+ const node = nodeRef.current;
2280
+ if (!node) return;
2281
+ const root = fillHeight ? node.closest("[data-slot=\"table-container\"]") : null;
2282
+ const observer = new IntersectionObserver((entries) => {
2283
+ if (entries[entries.length - 1]?.isIntersecting) {
2284
+ if (armedRef.current) {
2285
+ armedRef.current = false;
2286
+ onFetchMoreRef.current?.();
2287
+ }
2288
+ } else armedRef.current = true;
2289
+ }, {
2290
+ root,
2291
+ rootMargin: "200px"
2292
+ });
2293
+ observer.observe(node);
2294
+ observerRef.current = observer;
2295
+ }, [fillHeight]);
2296
+ React$1.useEffect(() => {
2297
+ armedRef.current = true;
2298
+ observe();
2299
+ }, [resetKey, observe]);
2300
+ return React$1.useCallback((node) => {
2301
+ nodeRef.current = node;
2302
+ observe();
2303
+ }, [observe]);
1999
2304
  }
2000
2305
 
2001
2306
  //#endregion
@@ -3602,16 +3907,6 @@ function SheetDescription({ className, ...props }) {
3602
3907
  });
3603
3908
  }
3604
3909
 
3605
- //#endregion
3606
- //#region src/components/skeleton.tsx
3607
- function Skeleton({ className, ...props }) {
3608
- return /* @__PURE__ */ jsx("div", {
3609
- "data-slot": "skeleton",
3610
- className: cn("animate-pulse rounded-md bg-muted", className),
3611
- ...props
3612
- });
3613
- }
3614
-
3615
3910
  //#endregion
3616
3911
  //#region src/components/tooltip.tsx
3617
3912
  function TooltipProvider({ delay = 0, ...props }) {
@@ -4122,38 +4417,115 @@ const Toaster = ({ ...props }) => {
4122
4417
  };
4123
4418
 
4124
4419
  //#endregion
4125
- //#region src/components/spinner.tsx
4126
- const spinnerVariants = cva("animate-spin text-current", {
4127
- variants: { size: {
4128
- default: "size-4",
4129
- sm: "size-3",
4130
- lg: "size-5",
4131
- xl: "size-6"
4132
- } },
4133
- defaultVariants: { size: "default" }
4420
+ //#region src/components/stepper.tsx
4421
+ const StepperContext = React$1.createContext(void 0);
4422
+ function useStepper() {
4423
+ const ctx = React$1.useContext(StepperContext);
4424
+ if (!ctx) throw new Error("useStepper must be used within a Stepper");
4425
+ return ctx;
4426
+ }
4427
+ const Stepper = React$1.forwardRef((componentProps, forwardRef) => {
4428
+ const { steps, defaultValue, className, children, value, onValueChange, ...props } = componentProps;
4429
+ const [activeId = "", setActiveId] = useControllableState({
4430
+ prop: value,
4431
+ defaultProp: defaultValue ?? steps[0]?.id,
4432
+ onChange: onValueChange
4433
+ });
4434
+ const goTo = React$1.useCallback((id) => setActiveId(id), [setActiveId]);
4435
+ const getIndex = React$1.useCallback((id) => steps.findIndex((s) => s.id === id), [steps]);
4436
+ const contextValue = React$1.useMemo(() => ({
4437
+ activeId,
4438
+ goTo,
4439
+ getIndex,
4440
+ steps
4441
+ }), [
4442
+ activeId,
4443
+ goTo,
4444
+ getIndex,
4445
+ steps
4446
+ ]);
4447
+ return /* @__PURE__ */ jsx(StepperContext.Provider, {
4448
+ value: contextValue,
4449
+ children: /* @__PURE__ */ jsx("div", {
4450
+ ref: forwardRef,
4451
+ "data-slot": "stepper",
4452
+ className: cn("w-full", className),
4453
+ ...props,
4454
+ children
4455
+ })
4456
+ });
4134
4457
  });
4135
- function Spinner({ className, size, ...props }) {
4136
- return /* @__PURE__ */ jsxs("svg", {
4137
- "data-slot": "spinner",
4138
- xmlns: "http://www.w3.org/2000/svg",
4139
- fill: "none",
4140
- viewBox: "0 0 24 24",
4141
- className: cn(spinnerVariants({ size }), className),
4458
+ Stepper.displayName = "Stepper";
4459
+ const StepperProgress = React$1.forwardRef((componentProps, forwardRef) => {
4460
+ const { steps: stepIds, className, ...props } = componentProps;
4461
+ const { activeId, getIndex, steps } = useStepper();
4462
+ const ids = stepIds ?? steps.map((s) => s.id);
4463
+ const currentIndex = getIndex(activeId);
4464
+ return /* @__PURE__ */ jsx("div", {
4465
+ ref: forwardRef,
4466
+ "data-slot": "stepper-progress",
4467
+ "aria-hidden": "true",
4468
+ className: cn("flex w-full items-center gap-1.5", className),
4142
4469
  ...props,
4143
- children: [/* @__PURE__ */ jsx("circle", {
4144
- className: "opacity-25",
4145
- cx: "12",
4146
- cy: "12",
4147
- r: "10",
4148
- stroke: "currentColor",
4149
- strokeWidth: "4"
4150
- }), /* @__PURE__ */ jsx("path", {
4151
- className: "opacity-75",
4152
- fill: "currentColor",
4153
- d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
4154
- })]
4470
+ children: ids.map((id) => {
4471
+ const idx = getIndex(id);
4472
+ const state = idx < currentIndex ? "completed" : idx === currentIndex ? "active" : "inactive";
4473
+ return /* @__PURE__ */ jsx("span", {
4474
+ "data-slot": "stepper-progress-segment",
4475
+ "data-state": state,
4476
+ className: "bg-muted h-1.5 flex-1 rounded-full transition-colors duration-300 data-[state=active]:bg-primary data-[state=completed]:bg-primary"
4477
+ }, id);
4478
+ })
4155
4479
  });
4156
- }
4480
+ });
4481
+ StepperProgress.displayName = "StepperProgress";
4482
+ const StepperCounter = React$1.forwardRef((componentProps, forwardRef) => {
4483
+ const { steps: stepIds, className, children, ...props } = componentProps;
4484
+ const { activeId, steps } = useStepper();
4485
+ const ids = stepIds ?? steps.map((s) => s.id);
4486
+ const pos = Math.max(0, ids.indexOf(activeId));
4487
+ return /* @__PURE__ */ jsxs("p", {
4488
+ ref: forwardRef,
4489
+ "data-slot": "stepper-counter",
4490
+ className: cn("text-muted-foreground text-xs", "[[data-slot=stepper-progress]+&]:pt-1", className),
4491
+ ...props,
4492
+ children: [
4493
+ "Step ",
4494
+ pos + 1,
4495
+ " of ",
4496
+ ids.length,
4497
+ children
4498
+ ]
4499
+ });
4500
+ });
4501
+ StepperCounter.displayName = "StepperCounter";
4502
+ const StepperPanel = React$1.forwardRef((componentProps, forwardRef) => {
4503
+ const { className, ...props } = componentProps;
4504
+ const { activeId } = useStepper();
4505
+ return /* @__PURE__ */ jsx("div", {
4506
+ ref: forwardRef,
4507
+ "data-slot": "stepper-panel",
4508
+ "data-state": activeId,
4509
+ className: cn("w-full", className),
4510
+ ...props
4511
+ });
4512
+ });
4513
+ StepperPanel.displayName = "StepperPanel";
4514
+ const StepperContent = React$1.forwardRef((componentProps, forwardRef) => {
4515
+ const { value, forceMount, className, ...props } = componentProps;
4516
+ const { activeId } = useStepper();
4517
+ const isActive = value === activeId;
4518
+ if (!forceMount && !isActive) return null;
4519
+ return /* @__PURE__ */ jsx("div", {
4520
+ ref: forwardRef,
4521
+ "data-slot": "stepper-content",
4522
+ "data-state": activeId,
4523
+ className: cn("w-full", className, !isActive && forceMount && "hidden"),
4524
+ hidden: !isActive && forceMount,
4525
+ ...props
4526
+ });
4527
+ });
4528
+ StepperContent.displayName = "StepperContent";
4157
4529
 
4158
4530
  //#endregion
4159
4531
  //#region src/components/switch.tsx
@@ -4355,4 +4727,4 @@ function useAudioGauge(options = {}) {
4355
4727
  }
4356
4728
 
4357
4729
  //#endregion
4358
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertAction, AlertAction as BannerAction, AlertDescription, AlertDescription as BannerDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AlertTitle as BannerTitle, Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage, Badge, BadgeGroup, BadgeGroupCount, Banner, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, Calendar, CalendarDayButton, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, Checkbox, Chip, ChipRemove, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, ComboboxChip, ComboboxChips, ComboboxChipsInput, ComboboxCollection, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxLabel, ComboboxList, ComboboxSeparator, ComboboxTrigger, ComboboxValue, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, CounterBadge, CountryFlag, DataTable, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerBackdrop, DrawerBar, DrawerClose, DrawerContent, DrawerCreateHandle, DrawerDescription, DrawerFooter, DrawerHeader, DrawerMenu, DrawerMenuCheckboxItem, DrawerMenuGroup, DrawerMenuGroupLabel, DrawerMenuItem, DrawerMenuRadioGroup, DrawerMenuRadioItem, DrawerMenuSeparator, DrawerMenuTrigger, DrawerPanel, DrawerPopup, DrawerPortal, DrawerPrimitive, DrawerSwipeArea, DrawerTitle, DrawerTrigger, DrawerViewport, DropdownMenu, DropdownMenuAddon, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Dropzone, DropzoneActions, DropzoneContent, DropzoneDescription, DropzoneIcon, DropzoneTitle, DropzoneTrigger, EmojiPicker, EmojiPickerCategories, EmojiPickerContent, EmojiPickerTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, FAB, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, Filter, FilterClearAllButton, FilterGroup, Gauge, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle, Label, List, ListCol, ListRow, NotificationQueueProvider, NotificationSlot, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger, Progress, ProgressIndicator, ProgressLabel, ProgressTrack, ProgressValue, RadioGroup, RadioGroupItem, ScrollArea, ScrollAreaPrimitive, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Slider, Spinner, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeProvider, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, alertVariants, bannerVariants, buttonGroupVariants, buttonVariants, cn, counterBadgeVariants, fabVariants, selectTriggerVariants, spinnerVariants, toast, toggleVariants, useAudioGauge, useComboboxAnchor, useNotification, useNotificationQueue, useSidebar, useTheme };
4730
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, ActionBar, ActionBarButton, ActionBarContext, ActionBarHeight, Alert, AlertAction, AlertAction as BannerAction, AlertDescription, AlertDescription as BannerDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AlertTitle as BannerTitle, Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage, Badge, BadgeGroup, BadgeGroupCount, Banner, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, Calendar, CalendarDayButton, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, Checkbox, Chip, ChipRemove, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, ComboboxChip, ComboboxChips, ComboboxChipsInput, ComboboxCollection, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxLabel, ComboboxList, ComboboxSeparator, ComboboxTrigger, ComboboxValue, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, CounterBadge, CountryFlag, DataTable, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerBackdrop, DrawerBar, DrawerClose, DrawerContent, DrawerCreateHandle, DrawerDescription, DrawerFooter, DrawerHeader, DrawerMenu, DrawerMenuCheckboxItem, DrawerMenuGroup, DrawerMenuGroupLabel, DrawerMenuItem, DrawerMenuRadioGroup, DrawerMenuRadioItem, DrawerMenuSeparator, DrawerMenuTrigger, DrawerPanel, DrawerPopup, DrawerPortal, DrawerPrimitive, DrawerSwipeArea, DrawerTitle, DrawerTrigger, DrawerViewport, DropdownMenu, DropdownMenuAddon, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Dropzone, DropzoneActions, DropzoneContent, DropzoneDescription, DropzoneIcon, DropzoneTitle, DropzoneTrigger, EmojiPicker, EmojiPickerCategories, EmojiPickerContent, EmojiPickerTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, FAB, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, Filter, FilterClearAllButton, FilterGroup, Gauge, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle, Label, List, ListCol, ListRow, NotificationQueueProvider, NotificationSlot, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, Popover, PopoverContent, PopoverDescription, PopoverHeader, PopoverTitle, PopoverTrigger, Progress, ProgressIndicator, ProgressLabel, ProgressTrack, ProgressValue, RadioGroup, RadioGroupItem, ScrollArea, ScrollAreaPrimitive, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Slider, Spinner, Stepper, StepperContent, StepperCounter, StepperPanel, StepperProgress, Switch, Table, TableBody, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeProvider, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, alertVariants, bannerVariants, buttonGroupVariants, buttonVariants, cn, counterBadgeVariants, fabVariants, selectTriggerVariants, spinnerVariants, toast, toggleVariants, useAudioGauge, useComboboxAnchor, useNotification, useNotificationQueue, useSidebar, useStepper, useTheme };