@optilogic/core 1.2.2 → 1.2.3

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
@@ -351,17 +351,26 @@ var SelectItem = React20.forwardRef(({ className, children, ...props }, ref) =>
351
351
  {
352
352
  ref,
353
353
  className: cn(
354
- "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
354
+ "relative flex w-full cursor-default select-none items-start rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
355
355
  className
356
356
  ),
357
357
  ...props,
358
358
  children: [
359
- /* @__PURE__ */ jsx("span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) }) }),
359
+ /* @__PURE__ */ jsx("span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center mt-0.5", children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) }) }),
360
360
  /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })
361
361
  ]
362
362
  }
363
363
  ));
364
364
  SelectItem.displayName = SelectPrimitive.Item.displayName;
365
+ var SelectItemDescription = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
366
+ "span",
367
+ {
368
+ ref,
369
+ className: cn("text-xs text-muted-foreground", className),
370
+ ...props
371
+ }
372
+ ));
373
+ SelectItemDescription.displayName = "SelectItemDescription";
365
374
  var SelectSeparator = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
366
375
  SelectPrimitive.Separator,
367
376
  {
@@ -372,41 +381,85 @@ var SelectSeparator = React20.forwardRef(({ className, ...props }, ref) => /* @_
372
381
  ));
373
382
  SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
374
383
  var Tabs = TabsPrimitive.Root;
375
- var TabsList = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
384
+ var tabsListVariants = cva(
385
+ "inline-flex h-10 items-center justify-start bg-transparent",
386
+ {
387
+ variants: {
388
+ variant: {
389
+ default: "border-b border-border",
390
+ pill: "gap-1 rounded-lg bg-muted p-1",
391
+ unstyled: ""
392
+ }
393
+ },
394
+ defaultVariants: {
395
+ variant: "default"
396
+ }
397
+ }
398
+ );
399
+ var tabsTriggerVariants = cva(
400
+ [
401
+ "inline-flex items-center justify-center whitespace-nowrap",
402
+ "px-4 py-2.5 text-sm font-medium",
403
+ "transition-colors",
404
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
405
+ "disabled:pointer-events-none disabled:opacity-50"
406
+ ],
407
+ {
408
+ variants: {
409
+ variant: {
410
+ default: [
411
+ "-mb-px",
412
+ "border-transparent text-muted-foreground",
413
+ "hover:text-foreground hover:border-muted-foreground/50",
414
+ "data-[state=active]:border-foreground data-[state=active]:text-foreground"
415
+ ],
416
+ pill: [
417
+ "rounded-md",
418
+ "text-muted-foreground",
419
+ "hover:text-foreground",
420
+ "data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm"
421
+ ],
422
+ unstyled: [
423
+ "text-muted-foreground",
424
+ "hover:text-foreground",
425
+ "data-[state=active]:text-foreground"
426
+ ]
427
+ },
428
+ indicatorSize: {
429
+ sm: "border-b",
430
+ default: "border-b-2",
431
+ lg: "border-b-[3px]"
432
+ }
433
+ },
434
+ compoundVariants: [
435
+ { variant: "pill", indicatorSize: "sm", className: "border-b-0" },
436
+ { variant: "pill", indicatorSize: "default", className: "border-b-0" },
437
+ { variant: "pill", indicatorSize: "lg", className: "border-b-0" },
438
+ { variant: "unstyled", indicatorSize: "sm", className: "border-b-0" },
439
+ { variant: "unstyled", indicatorSize: "default", className: "border-b-0" },
440
+ { variant: "unstyled", indicatorSize: "lg", className: "border-b-0" }
441
+ ],
442
+ defaultVariants: {
443
+ variant: "default",
444
+ indicatorSize: "default"
445
+ }
446
+ }
447
+ );
448
+ var TabsList = React20.forwardRef(({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx(
376
449
  TabsPrimitive.List,
377
450
  {
378
451
  ref,
379
- className: cn(
380
- "inline-flex h-10 items-center justify-start",
381
- "border-b border-border",
382
- "bg-transparent",
383
- className
384
- ),
452
+ className: cn(tabsListVariants({ variant }), className),
385
453
  ...props
386
454
  }
387
455
  ));
388
456
  TabsList.displayName = TabsPrimitive.List.displayName;
389
- var TabsTrigger = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
457
+ var TabsTrigger = React20.forwardRef(({ className, variant, indicatorSize, ...props }, ref) => /* @__PURE__ */ jsx(
390
458
  TabsPrimitive.Trigger,
391
459
  {
392
460
  ref,
393
461
  className: cn(
394
- // Base styles
395
- "inline-flex items-center justify-center whitespace-nowrap",
396
- "px-4 py-2.5 text-sm font-medium",
397
- "transition-colors",
398
- // Border-bottom indicator style
399
- "border-b-2 -mb-px",
400
- // Default state
401
- "border-transparent text-muted-foreground",
402
- // Hover state
403
- "hover:text-foreground hover:border-muted-foreground/50",
404
- // Active/selected state
405
- "data-[state=active]:border-foreground data-[state=active]:text-foreground",
406
- // Focus styles
407
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
408
- // Disabled styles
409
- "disabled:pointer-events-none disabled:opacity-50",
462
+ tabsTriggerVariants({ variant, indicatorSize }),
410
463
  className
411
464
  ),
412
465
  ...props
@@ -419,7 +472,6 @@ var TabsContent = React20.forwardRef(({ className, ...props }, ref) => /* @__PUR
419
472
  ref,
420
473
  className: cn(
421
474
  "mt-2",
422
- // Focus styles
423
475
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
424
476
  className
425
477
  ),
@@ -3382,6 +3434,7 @@ function HeaderCell({
3382
3434
  sorting,
3383
3435
  filter,
3384
3436
  isResizable,
3437
+ fillWidth,
3385
3438
  onSort,
3386
3439
  onFilterChange,
3387
3440
  onResizeMouseDown,
@@ -3425,7 +3478,8 @@ function HeaderCell({
3425
3478
  "div",
3426
3479
  {
3427
3480
  className: cn(
3428
- "relative flex-shrink-0 border-r border-border last:border-r-0",
3481
+ "relative border-r border-border last:border-r-0",
3482
+ !fillWidth && "flex-shrink-0",
3429
3483
  "bg-muted select-none",
3430
3484
  isResizing && "bg-accent/20"
3431
3485
  ),
@@ -4365,11 +4419,15 @@ function useColumnResizeManager(options) {
4365
4419
  resizableColumns,
4366
4420
  onColumnResize,
4367
4421
  onColumnResizeStart,
4368
- onColumnResizeEnd
4422
+ onColumnResizeEnd,
4423
+ fillWidth,
4424
+ containerWidth,
4425
+ effectiveColumnWidths
4369
4426
  } = options;
4370
4427
  const [resizingColumn, setResizingColumn] = useState(null);
4371
4428
  const startXRef = useRef(0);
4372
4429
  const startWidthRef = useRef(0);
4430
+ const startEffectiveWidthsRef = useRef({});
4373
4431
  const getColumn = useCallback(
4374
4432
  (columnKey) => {
4375
4433
  return columns.find((c) => c.key === columnKey);
@@ -4393,9 +4451,20 @@ function useColumnResizeManager(options) {
4393
4451
  resizingColumn,
4394
4452
  startWidthRef.current + deltaX
4395
4453
  );
4454
+ if (fillWidth && containerWidth) {
4455
+ const otherCols = columns.filter((c) => c.key !== resizingColumn);
4456
+ const startEffective = startEffectiveWidthsRef.current;
4457
+ const otherTotal = otherCols.reduce((s, c) => s + (startEffective[c.key] || 0), 0);
4458
+ const remaining = containerWidth - newWidth;
4459
+ for (const col of otherCols) {
4460
+ const proportion = (startEffective[col.key] || 0) / otherTotal;
4461
+ const adjusted = clampWidth(col.key, Math.floor(remaining * proportion));
4462
+ onColumnResize(col.key, adjusted);
4463
+ }
4464
+ }
4396
4465
  onColumnResize(resizingColumn, newWidth);
4397
4466
  },
4398
- [resizingColumn, clampWidth, onColumnResize]
4467
+ [resizingColumn, clampWidth, onColumnResize, fillWidth, containerWidth, columns]
4399
4468
  );
4400
4469
  const handleMouseUp = useCallback(() => {
4401
4470
  if (!resizingColumn) return;
@@ -4429,6 +4498,9 @@ function useColumnResizeManager(options) {
4429
4498
  document.body.style.userSelect = "none";
4430
4499
  document.body.style.cursor = "col-resize";
4431
4500
  onColumnResizeStart?.(columnKey);
4501
+ if (fillWidth && effectiveColumnWidths) {
4502
+ startEffectiveWidthsRef.current = { ...effectiveColumnWidths };
4503
+ }
4432
4504
  };
4433
4505
  const handleDoubleClick = (event) => {
4434
4506
  if (!isResizable) return;
@@ -4454,7 +4526,9 @@ function useColumnResizeManager(options) {
4454
4526
  resizingColumn,
4455
4527
  onColumnResize,
4456
4528
  onColumnResizeStart,
4457
- onColumnResizeEnd
4529
+ onColumnResizeEnd,
4530
+ fillWidth,
4531
+ effectiveColumnWidths
4458
4532
  ]
4459
4533
  );
4460
4534
  return {
@@ -4679,6 +4753,7 @@ function DataGrid({
4679
4753
  tooltipMinLength = 30,
4680
4754
  enableKeyboardNavigation = true,
4681
4755
  showColumnBorders = true,
4756
+ fillWidth,
4682
4757
  enableInternalSorting = true,
4683
4758
  enableInternalFiltering = true,
4684
4759
  // Controlled sorting
@@ -4733,6 +4808,16 @@ function DataGrid({
4733
4808
  const headerRef = React20.useRef(null);
4734
4809
  const [headerHeight, setHeaderHeight] = React20.useState(40);
4735
4810
  const [hoveredCell, setHoveredCell] = React20.useState(null);
4811
+ const [containerWidth, setContainerWidth] = React20.useState(0);
4812
+ React20.useLayoutEffect(() => {
4813
+ if (!fillWidth || !parentRef.current) return;
4814
+ const observer = new ResizeObserver((entries) => {
4815
+ const w = entries[0]?.contentRect.width;
4816
+ if (w && w > 0) setContainerWidth(w);
4817
+ });
4818
+ observer.observe(parentRef.current);
4819
+ return () => observer.disconnect();
4820
+ }, [fillWidth]);
4736
4821
  const visibleColumns = React20.useMemo(
4737
4822
  () => columns.filter((col) => !col.hidden),
4738
4823
  [columns]
@@ -4786,14 +4871,6 @@ function DataGrid({
4786
4871
  visibleColumns
4787
4872
  ]);
4788
4873
  processedDataRef.current = processedData;
4789
- const { resizingColumn, getResizeProps } = useColumnResizeManager({
4790
- columns: visibleColumns,
4791
- columnWidths: state.columnWidths,
4792
- resizableColumns,
4793
- onColumnResize: actions.setColumnWidth,
4794
- onColumnResizeStart,
4795
- onColumnResizeEnd
4796
- });
4797
4874
  const shouldVirtualize = virtualized ?? processedData.length > 100;
4798
4875
  React20.useLayoutEffect(() => {
4799
4876
  if (headerRef.current && shouldVirtualize) {
@@ -4807,12 +4884,38 @@ function DataGrid({
4807
4884
  overscan: DEFAULT_OVERSCAN,
4808
4885
  enabled: shouldVirtualize
4809
4886
  });
4810
- const tableWidth = React20.useMemo(() => {
4811
- return visibleColumns.reduce((acc, col) => {
4812
- const width = state.columnWidths[col.key] || col.width || estimateColumnWidth(col);
4813
- return acc + width;
4814
- }, 0);
4815
- }, [visibleColumns, state.columnWidths]);
4887
+ const { tableWidth, effectiveColumnWidths } = React20.useMemo(() => {
4888
+ const rawWidths = {};
4889
+ let rawTotal = 0;
4890
+ for (const col of visibleColumns) {
4891
+ const w = state.columnWidths[col.key] || col.width || estimateColumnWidth(col);
4892
+ rawWidths[col.key] = w;
4893
+ rawTotal += w;
4894
+ }
4895
+ if (!fillWidth || !containerWidth || rawTotal >= containerWidth) {
4896
+ return { tableWidth: rawTotal, effectiveColumnWidths: rawWidths };
4897
+ }
4898
+ const scale = containerWidth / rawTotal;
4899
+ const scaled = {};
4900
+ for (const col of visibleColumns) {
4901
+ let w = Math.floor(rawWidths[col.key] * scale);
4902
+ if (col.minWidth) w = Math.max(w, col.minWidth);
4903
+ if (col.maxWidth) w = Math.min(w, col.maxWidth);
4904
+ scaled[col.key] = w;
4905
+ }
4906
+ return { tableWidth: containerWidth, effectiveColumnWidths: scaled };
4907
+ }, [visibleColumns, state.columnWidths, fillWidth, containerWidth]);
4908
+ const { resizingColumn, getResizeProps } = useColumnResizeManager({
4909
+ columns: visibleColumns,
4910
+ columnWidths: state.columnWidths,
4911
+ resizableColumns,
4912
+ onColumnResize: actions.setColumnWidth,
4913
+ onColumnResizeStart,
4914
+ onColumnResizeEnd,
4915
+ fillWidth,
4916
+ containerWidth,
4917
+ effectiveColumnWidths
4918
+ });
4816
4919
  const visibleRowCount = React20.useMemo(() => {
4817
4920
  if (!parentRef.current) return 10;
4818
4921
  return Math.floor(parentRef.current.clientHeight / DEFAULT_ROW_HEIGHT);
@@ -5044,7 +5147,7 @@ function DataGrid({
5044
5147
  },
5045
5148
  role: "row",
5046
5149
  children: visibleColumns.map((column, colIndex) => {
5047
- const width = state.columnWidths[column.key] || column.width || estimateColumnWidth(column);
5150
+ const width = effectiveColumnWidths[column.key];
5048
5151
  const resizeProps = getResizeProps(column.key);
5049
5152
  return /* @__PURE__ */ jsx(
5050
5153
  HeaderCell,
@@ -5055,6 +5158,7 @@ function DataGrid({
5055
5158
  sorting: getColumnSort(column.key),
5056
5159
  filter: getColumnFilter(column.key),
5057
5160
  isResizable: resizableColumns && column.resizable !== false,
5161
+ fillWidth,
5058
5162
  onSort: () => handleSort(column.key),
5059
5163
  onFilterChange: (filter) => handleFilterChange(column.key, filter),
5060
5164
  onResizeMouseDown: resizeProps.handleMouseDown,
@@ -5103,7 +5207,7 @@ function DataGrid({
5103
5207
  "aria-rowindex": virtualRow.index + 1,
5104
5208
  "aria-selected": isSelected,
5105
5209
  children: visibleColumns.map((column, colIndex) => {
5106
- const width = state.columnWidths[column.key] || column.width || estimateColumnWidth(column);
5210
+ const width = effectiveColumnWidths[column.key];
5107
5211
  const isEditingThisCell = state.editingCell?.rowIndex === virtualRow.index && state.editingCell?.columnKey === column.key;
5108
5212
  const isFocused = state.focusedCell?.rowIndex === virtualRow.index && state.focusedCell?.columnKey === column.key;
5109
5213
  const cellContent = renderCell(
@@ -5118,7 +5222,8 @@ function DataGrid({
5118
5222
  "div",
5119
5223
  {
5120
5224
  className: cn(
5121
- "flex-shrink-0 px-3 py-2 text-sm overflow-hidden",
5225
+ "px-3 py-2 text-sm overflow-hidden",
5226
+ !fillWidth && "flex-shrink-0",
5122
5227
  showColumnBorders && "border-r border-border last:border-r-0",
5123
5228
  isFocused && !isEditingThisCell && "ring-2 ring-inset ring-primary",
5124
5229
  isEditingThisCell && "ring-2 ring-inset ring-primary bg-background",
@@ -5230,7 +5335,7 @@ function DataGrid({
5230
5335
  }
5231
5336
  )
5232
5337
  ] }) }),
5233
- /* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-auto min-h-0", children: [
5338
+ /* @__PURE__ */ jsxs("div", { ref: parentRef, className: "flex-1 overflow-auto min-h-0", children: [
5234
5339
  /* @__PURE__ */ jsx(
5235
5340
  "div",
5236
5341
  {
@@ -5241,7 +5346,7 @@ function DataGrid({
5241
5346
  style: { width: tableWidth ? `${tableWidth}px` : "100%" },
5242
5347
  role: "row",
5243
5348
  children: visibleColumns.map((column, colIndex) => {
5244
- const width = state.columnWidths[column.key] || column.width || estimateColumnWidth(column);
5349
+ const width = effectiveColumnWidths[column.key];
5245
5350
  const resizeProps = getResizeProps(column.key);
5246
5351
  return /* @__PURE__ */ jsx(
5247
5352
  HeaderCell,
@@ -5252,6 +5357,7 @@ function DataGrid({
5252
5357
  sorting: getColumnSort(column.key),
5253
5358
  filter: getColumnFilter(column.key),
5254
5359
  isResizable: resizableColumns && column.resizable !== false,
5360
+ fillWidth,
5255
5361
  onSort: () => handleSort(column.key),
5256
5362
  onFilterChange: (filter) => handleFilterChange(column.key, filter),
5257
5363
  onResizeMouseDown: resizeProps.handleMouseDown,
@@ -5281,14 +5387,15 @@ function DataGrid({
5281
5387
  onDoubleClick: () => onRowDoubleClick?.(row, rowIndex),
5282
5388
  role: "row",
5283
5389
  children: visibleColumns.map((column) => {
5284
- const width = state.columnWidths[column.key] || column.width || estimateColumnWidth(column);
5390
+ const width = effectiveColumnWidths[column.key];
5285
5391
  const isEditingThisCell = state.editingCell?.rowIndex === rowIndex && state.editingCell?.columnKey === column.key;
5286
5392
  const isFocused = state.focusedCell?.rowIndex === rowIndex && state.focusedCell?.columnKey === column.key;
5287
5393
  return /* @__PURE__ */ jsx(
5288
5394
  "div",
5289
5395
  {
5290
5396
  className: cn(
5291
- "flex-shrink-0 px-3 py-2 text-sm overflow-hidden",
5397
+ "px-3 py-2 text-sm overflow-hidden",
5398
+ !fillWidth && "flex-shrink-0",
5292
5399
  showColumnBorders && "border-r border-border last:border-r-0",
5293
5400
  isFocused && !isEditingThisCell && "ring-2 ring-inset ring-primary",
5294
5401
  isEditingThisCell && "ring-2 ring-inset ring-primary bg-background",
@@ -5613,6 +5720,504 @@ function Autocomplete({
5613
5720
  )
5614
5721
  ] });
5615
5722
  }
5723
+ function MultiSelect({
5724
+ options,
5725
+ value,
5726
+ onChange,
5727
+ placeholder = "Select items...",
5728
+ searchPlaceholder = "Search...",
5729
+ emptyText = "No options found.",
5730
+ disabled = false,
5731
+ className,
5732
+ clearable = true,
5733
+ maxDisplayItems = 3,
5734
+ showSelectAll = false,
5735
+ selectAllLabel = "Select all"
5736
+ }) {
5737
+ const [open, setOpen] = React20.useState(false);
5738
+ const [search, setSearch] = React20.useState("");
5739
+ const inputRef = React20.useRef(null);
5740
+ const safeOptions = options ?? [];
5741
+ const safeValue = value ?? [];
5742
+ const selectedSet = React20.useMemo(() => new Set(safeValue), [safeValue]);
5743
+ const filteredOptions = React20.useMemo(() => {
5744
+ if (!search.trim()) return safeOptions;
5745
+ const searchLower = search.toLowerCase();
5746
+ return safeOptions.filter(
5747
+ (opt) => opt.label.toLowerCase().includes(searchLower) || opt.description?.toLowerCase().includes(searchLower)
5748
+ );
5749
+ }, [safeOptions, search]);
5750
+ const groupedOptions = React20.useMemo(() => {
5751
+ const groups = {};
5752
+ const ungrouped = [];
5753
+ filteredOptions.forEach((opt) => {
5754
+ if (opt.group) {
5755
+ if (!groups[opt.group]) groups[opt.group] = [];
5756
+ groups[opt.group].push(opt);
5757
+ } else {
5758
+ ungrouped.push(opt);
5759
+ }
5760
+ });
5761
+ return { groups, ungrouped };
5762
+ }, [filteredOptions]);
5763
+ const hasGroups = Object.keys(groupedOptions.groups).length > 0;
5764
+ const selectableFiltered = React20.useMemo(
5765
+ () => filteredOptions.filter((opt) => !opt.disabled),
5766
+ [filteredOptions]
5767
+ );
5768
+ const allFilteredSelected = React20.useMemo(
5769
+ () => selectableFiltered.length > 0 && selectableFiltered.every((opt) => selectedSet.has(opt.value)),
5770
+ [selectableFiltered, selectedSet]
5771
+ );
5772
+ const someFilteredSelected = React20.useMemo(
5773
+ () => !allFilteredSelected && selectableFiltered.some((opt) => selectedSet.has(opt.value)),
5774
+ [selectableFiltered, selectedSet, allFilteredSelected]
5775
+ );
5776
+ const handleToggle = React20.useCallback(
5777
+ (optionValue) => {
5778
+ const next = selectedSet.has(optionValue) ? safeValue.filter((v) => v !== optionValue) : [...safeValue, optionValue];
5779
+ onChange?.(next);
5780
+ },
5781
+ [onChange, safeValue, selectedSet]
5782
+ );
5783
+ const handleRemove = React20.useCallback(
5784
+ (optionValue, e) => {
5785
+ e.stopPropagation();
5786
+ onChange?.(safeValue.filter((v) => v !== optionValue));
5787
+ },
5788
+ [onChange, safeValue]
5789
+ );
5790
+ const handleClearAll = React20.useCallback(
5791
+ (e) => {
5792
+ e.stopPropagation();
5793
+ onChange?.([]);
5794
+ },
5795
+ [onChange]
5796
+ );
5797
+ const handleSelectAll = React20.useCallback(() => {
5798
+ if (allFilteredSelected) {
5799
+ const filteredValues = new Set(selectableFiltered.map((o) => o.value));
5800
+ onChange?.(safeValue.filter((v) => !filteredValues.has(v)));
5801
+ } else {
5802
+ const existing = new Set(safeValue);
5803
+ const next = [...safeValue];
5804
+ for (const opt of selectableFiltered) {
5805
+ if (!existing.has(opt.value)) {
5806
+ next.push(opt.value);
5807
+ }
5808
+ }
5809
+ onChange?.(next);
5810
+ }
5811
+ }, [allFilteredSelected, selectableFiltered, safeValue, onChange]);
5812
+ React20.useEffect(() => {
5813
+ if (open) {
5814
+ const timeout = setTimeout(() => inputRef.current?.focus(), 0);
5815
+ return () => clearTimeout(timeout);
5816
+ } else {
5817
+ setSearch("");
5818
+ }
5819
+ }, [open]);
5820
+ const handleKeyDown = React20.useCallback((e) => {
5821
+ if (e.key === "Escape") setOpen(false);
5822
+ }, []);
5823
+ const selectedLabels = React20.useMemo(
5824
+ () => safeValue.map((v) => safeOptions.find((o) => o.value === v)?.label ?? v).slice(0, maxDisplayItems),
5825
+ [safeValue, safeOptions, maxDisplayItems]
5826
+ );
5827
+ const overflow = safeValue.length - maxDisplayItems;
5828
+ const isSearching = search.trim().length > 0;
5829
+ const renderOption = (option) => /* @__PURE__ */ jsxs(
5830
+ "button",
5831
+ {
5832
+ type: "button",
5833
+ disabled: option.disabled,
5834
+ onClick: () => handleToggle(option.value),
5835
+ className: cn(
5836
+ "relative flex w-full cursor-pointer select-none items-start gap-2 rounded-sm px-2 py-1.5 text-sm outline-none",
5837
+ "hover:bg-accent hover:text-accent-foreground",
5838
+ option.disabled && "pointer-events-none opacity-50"
5839
+ ),
5840
+ children: [
5841
+ /* @__PURE__ */ jsx(
5842
+ Checkbox,
5843
+ {
5844
+ checked: selectedSet.has(option.value),
5845
+ tabIndex: -1,
5846
+ className: "mt-0.5 pointer-events-none"
5847
+ }
5848
+ ),
5849
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
5850
+ /* @__PURE__ */ jsx("div", { className: "truncate", children: option.label }),
5851
+ option.description && /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground truncate", children: option.description })
5852
+ ] })
5853
+ ]
5854
+ },
5855
+ option.value
5856
+ );
5857
+ return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
5858
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, disabled, children: /* @__PURE__ */ jsxs(
5859
+ "button",
5860
+ {
5861
+ type: "button",
5862
+ role: "combobox",
5863
+ "aria-expanded": open,
5864
+ "aria-haspopup": "listbox",
5865
+ disabled,
5866
+ className: cn(
5867
+ "flex min-h-9 w-full items-center justify-between gap-2 rounded-md border border-input bg-transparent px-3 py-1.5 text-sm shadow-sm ring-offset-background",
5868
+ "hover:border-input-hover",
5869
+ "focus:outline-none focus:ring-1 focus:ring-ring",
5870
+ "disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:border-input",
5871
+ className
5872
+ ),
5873
+ children: [
5874
+ /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-wrap gap-1 items-center min-w-0", children: safeValue.length === 0 ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: placeholder }) : /* @__PURE__ */ jsxs(Fragment, { children: [
5875
+ selectedLabels.map((label, i) => /* @__PURE__ */ jsxs(
5876
+ "span",
5877
+ {
5878
+ className: "inline-flex items-center gap-0.5 rounded-sm bg-accent px-1.5 py-0.5 text-xs font-medium text-accent-foreground",
5879
+ children: [
5880
+ /* @__PURE__ */ jsx("span", { className: "truncate max-w-[100px]", children: label }),
5881
+ /* @__PURE__ */ jsx(
5882
+ "span",
5883
+ {
5884
+ role: "button",
5885
+ tabIndex: -1,
5886
+ onClick: (e) => handleRemove(safeValue[i], e),
5887
+ className: "rounded-sm hover:bg-foreground/10 p-0.5",
5888
+ children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
5889
+ }
5890
+ )
5891
+ ]
5892
+ },
5893
+ safeValue[i]
5894
+ )),
5895
+ overflow > 0 && /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
5896
+ "+",
5897
+ overflow
5898
+ ] })
5899
+ ] }) }),
5900
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 flex-shrink-0", children: [
5901
+ clearable && safeValue.length > 0 && /* @__PURE__ */ jsx(
5902
+ "span",
5903
+ {
5904
+ role: "button",
5905
+ tabIndex: -1,
5906
+ onClick: handleClearAll,
5907
+ className: "rounded-sm hover:bg-muted p-0.5",
5908
+ children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5 text-muted-foreground" })
5909
+ }
5910
+ ),
5911
+ /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 opacity-50" })
5912
+ ] })
5913
+ ]
5914
+ }
5915
+ ) }),
5916
+ /* @__PURE__ */ jsxs(
5917
+ PopoverContent,
5918
+ {
5919
+ className: "w-[--radix-popover-trigger-width] p-0",
5920
+ align: "start",
5921
+ sideOffset: 4,
5922
+ onKeyDown: handleKeyDown,
5923
+ children: [
5924
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center border-b border-border px-3", children: [
5925
+ /* @__PURE__ */ jsx(
5926
+ "input",
5927
+ {
5928
+ ref: inputRef,
5929
+ type: "text",
5930
+ value: search,
5931
+ onChange: (e) => setSearch(e.target.value),
5932
+ placeholder: searchPlaceholder,
5933
+ className: "flex h-9 w-full bg-transparent py-2 text-sm outline-none placeholder:text-muted-foreground"
5934
+ }
5935
+ ),
5936
+ search && /* @__PURE__ */ jsx(
5937
+ "button",
5938
+ {
5939
+ type: "button",
5940
+ onClick: () => setSearch(""),
5941
+ className: "p-1 hover:bg-muted rounded-sm",
5942
+ children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5 text-muted-foreground" })
5943
+ }
5944
+ )
5945
+ ] }),
5946
+ /* @__PURE__ */ jsxs("div", { className: "max-h-[300px] overflow-y-auto p-1", children: [
5947
+ showSelectAll && selectableFiltered.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
5948
+ /* @__PURE__ */ jsxs(
5949
+ "button",
5950
+ {
5951
+ type: "button",
5952
+ onClick: handleSelectAll,
5953
+ className: cn(
5954
+ "relative flex w-full cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none",
5955
+ "hover:bg-accent hover:text-accent-foreground"
5956
+ ),
5957
+ children: [
5958
+ /* @__PURE__ */ jsx(
5959
+ Checkbox,
5960
+ {
5961
+ checked: allFilteredSelected ? true : someFilteredSelected ? "indeterminate" : false,
5962
+ tabIndex: -1,
5963
+ className: "pointer-events-none"
5964
+ }
5965
+ ),
5966
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: isSearching ? `${selectAllLabel} (filtered)` : selectAllLabel })
5967
+ ]
5968
+ }
5969
+ ),
5970
+ /* @__PURE__ */ jsx("div", { className: "-mx-1 my-1 h-px bg-border" })
5971
+ ] }),
5972
+ filteredOptions.length === 0 ? /* @__PURE__ */ jsx("div", { className: "py-6 text-center text-sm text-muted-foreground", children: emptyText }) : hasGroups ? /* @__PURE__ */ jsxs(Fragment, { children: [
5973
+ groupedOptions.ungrouped.map(renderOption),
5974
+ Object.entries(groupedOptions.groups).map(([group, opts]) => /* @__PURE__ */ jsxs("div", { children: [
5975
+ /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-xs font-semibold text-muted-foreground", children: group }),
5976
+ opts.map(renderOption)
5977
+ ] }, group))
5978
+ ] }) : filteredOptions.map(renderOption)
5979
+ ] })
5980
+ ]
5981
+ }
5982
+ )
5983
+ ] });
5984
+ }
5985
+ MultiSelect.displayName = "MultiSelect";
5986
+ function Combobox({
5987
+ options,
5988
+ value,
5989
+ onChange,
5990
+ onInputChange,
5991
+ placeholder = "Type or select...",
5992
+ emptyText = "No options found.",
5993
+ disabled = false,
5994
+ className,
5995
+ clearable = false,
5996
+ allowCustomValue = true
5997
+ }) {
5998
+ const [open, setOpen] = React20.useState(false);
5999
+ const [inputValue, setInputValue] = React20.useState("");
6000
+ const inputRef = React20.useRef(null);
6001
+ const wrapperRef = React20.useRef(null);
6002
+ const selectedOption = React20.useMemo(
6003
+ () => options.find((opt) => opt.value === value),
6004
+ [options, value]
6005
+ );
6006
+ React20.useEffect(() => {
6007
+ if (!open) {
6008
+ setInputValue(selectedOption?.label ?? value ?? "");
6009
+ }
6010
+ }, [value, selectedOption, open]);
6011
+ const filteredOptions = React20.useMemo(() => {
6012
+ if (!inputValue.trim()) return options;
6013
+ const searchLower = inputValue.toLowerCase();
6014
+ return options.filter(
6015
+ (opt) => opt.label.toLowerCase().includes(searchLower) || opt.description?.toLowerCase().includes(searchLower)
6016
+ );
6017
+ }, [options, inputValue]);
6018
+ const groupedOptions = React20.useMemo(() => {
6019
+ const groups = {};
6020
+ const ungrouped = [];
6021
+ filteredOptions.forEach((opt) => {
6022
+ if (opt.group) {
6023
+ if (!groups[opt.group]) groups[opt.group] = [];
6024
+ groups[opt.group].push(opt);
6025
+ } else {
6026
+ ungrouped.push(opt);
6027
+ }
6028
+ });
6029
+ return { groups, ungrouped };
6030
+ }, [filteredOptions]);
6031
+ const hasGroups = Object.keys(groupedOptions.groups).length > 0;
6032
+ const handleInputChange = React20.useCallback(
6033
+ (e) => {
6034
+ const newValue = e.target.value;
6035
+ setInputValue(newValue);
6036
+ onInputChange?.(newValue);
6037
+ if (!open) setOpen(true);
6038
+ },
6039
+ [onInputChange, open]
6040
+ );
6041
+ const handleSelect = React20.useCallback(
6042
+ (optionValue) => {
6043
+ const option = options.find((o) => o.value === optionValue);
6044
+ onChange?.(optionValue);
6045
+ setInputValue(option?.label ?? optionValue);
6046
+ setOpen(false);
6047
+ },
6048
+ [onChange, options]
6049
+ );
6050
+ const handleClear = React20.useCallback(
6051
+ (e) => {
6052
+ e.stopPropagation();
6053
+ e.preventDefault();
6054
+ onChange?.(void 0);
6055
+ setInputValue("");
6056
+ inputRef.current?.focus();
6057
+ },
6058
+ [onChange]
6059
+ );
6060
+ const handleFocus = React20.useCallback(() => {
6061
+ setOpen(true);
6062
+ inputRef.current?.select();
6063
+ }, []);
6064
+ const handleBlur = React20.useCallback(() => {
6065
+ setTimeout(() => {
6066
+ if (!wrapperRef.current?.contains(document.activeElement)) {
6067
+ setOpen(false);
6068
+ }
6069
+ if (allowCustomValue && inputValue.trim()) {
6070
+ const matchingOption = options.find(
6071
+ (opt) => opt.label.toLowerCase() === inputValue.toLowerCase()
6072
+ );
6073
+ if (matchingOption) {
6074
+ onChange?.(matchingOption.value);
6075
+ setInputValue(matchingOption.label);
6076
+ } else {
6077
+ onChange?.(inputValue.trim());
6078
+ }
6079
+ } else if (!allowCustomValue) {
6080
+ setInputValue(selectedOption?.label ?? "");
6081
+ }
6082
+ }, 200);
6083
+ }, [allowCustomValue, inputValue, options, onChange, selectedOption]);
6084
+ const handleKeyDown = React20.useCallback(
6085
+ (e) => {
6086
+ if (e.key === "Escape") {
6087
+ setOpen(false);
6088
+ setInputValue(selectedOption?.label ?? value ?? "");
6089
+ inputRef.current?.blur();
6090
+ } else if (e.key === "Enter" && open) {
6091
+ e.preventDefault();
6092
+ if (filteredOptions.length === 1) {
6093
+ handleSelect(filteredOptions[0].value);
6094
+ } else if (allowCustomValue && inputValue.trim()) {
6095
+ const exactMatch = filteredOptions.find(
6096
+ (opt) => opt.label.toLowerCase() === inputValue.toLowerCase()
6097
+ );
6098
+ if (exactMatch) {
6099
+ handleSelect(exactMatch.value);
6100
+ } else {
6101
+ onChange?.(inputValue.trim());
6102
+ setOpen(false);
6103
+ }
6104
+ }
6105
+ }
6106
+ },
6107
+ [
6108
+ open,
6109
+ filteredOptions,
6110
+ handleSelect,
6111
+ allowCustomValue,
6112
+ inputValue,
6113
+ onChange,
6114
+ selectedOption,
6115
+ value
6116
+ ]
6117
+ );
6118
+ const renderOption = (option) => /* @__PURE__ */ jsxs(
6119
+ "button",
6120
+ {
6121
+ type: "button",
6122
+ disabled: option.disabled,
6123
+ onMouseDown: (e) => e.preventDefault(),
6124
+ onClick: () => handleSelect(option.value),
6125
+ className: cn(
6126
+ "relative flex w-full cursor-pointer select-none items-start gap-2 rounded-sm px-2 py-1.5 text-sm outline-none",
6127
+ "hover:bg-accent hover:text-accent-foreground",
6128
+ "focus:bg-accent focus:text-accent-foreground",
6129
+ option.disabled && "pointer-events-none opacity-50",
6130
+ value === option.value && "bg-accent/50"
6131
+ ),
6132
+ children: [
6133
+ /* @__PURE__ */ jsx("span", { className: "flex h-4 w-4 items-center justify-center flex-shrink-0 mt-0.5", children: value === option.value && /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" }) }),
6134
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
6135
+ /* @__PURE__ */ jsx("div", { className: "truncate", children: option.label }),
6136
+ option.description && /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground truncate", children: option.description })
6137
+ ] })
6138
+ ]
6139
+ },
6140
+ option.value
6141
+ );
6142
+ return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
6143
+ /* @__PURE__ */ jsx(PopoverAnchor, { asChild: true, children: /* @__PURE__ */ jsxs(
6144
+ "div",
6145
+ {
6146
+ ref: wrapperRef,
6147
+ className: cn(
6148
+ "flex h-9 w-full items-center gap-2 rounded-md border border-input bg-transparent px-3 text-sm shadow-sm ring-offset-background",
6149
+ "hover:border-input-hover",
6150
+ "focus-within:outline-none focus-within:ring-1 focus-within:ring-ring",
6151
+ disabled && "cursor-not-allowed opacity-50 hover:border-input",
6152
+ className
6153
+ ),
6154
+ children: [
6155
+ /* @__PURE__ */ jsx(
6156
+ "input",
6157
+ {
6158
+ ref: inputRef,
6159
+ type: "text",
6160
+ value: inputValue,
6161
+ onChange: handleInputChange,
6162
+ onFocus: handleFocus,
6163
+ onBlur: handleBlur,
6164
+ onKeyDown: handleKeyDown,
6165
+ placeholder,
6166
+ disabled,
6167
+ className: "flex-1 min-w-0 bg-transparent py-2 outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed",
6168
+ role: "combobox",
6169
+ "aria-expanded": open,
6170
+ "aria-haspopup": "listbox",
6171
+ "aria-autocomplete": "list"
6172
+ }
6173
+ ),
6174
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 flex-shrink-0", children: [
6175
+ clearable && value && /* @__PURE__ */ jsx(
6176
+ "span",
6177
+ {
6178
+ role: "button",
6179
+ tabIndex: -1,
6180
+ onMouseDown: (e) => e.preventDefault(),
6181
+ onClick: handleClear,
6182
+ className: "rounded-sm hover:bg-muted p-0.5",
6183
+ children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5 text-muted-foreground" })
6184
+ }
6185
+ ),
6186
+ /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 opacity-50" })
6187
+ ] })
6188
+ ]
6189
+ }
6190
+ ) }),
6191
+ /* @__PURE__ */ jsx(
6192
+ PopoverContent,
6193
+ {
6194
+ className: "p-0",
6195
+ style: { width: wrapperRef.current?.offsetWidth },
6196
+ align: "start",
6197
+ sideOffset: 4,
6198
+ onOpenAutoFocus: (e) => e.preventDefault(),
6199
+ onFocusOutside: (e) => {
6200
+ if (wrapperRef.current?.contains(e.target)) {
6201
+ e.preventDefault();
6202
+ }
6203
+ },
6204
+ onInteractOutside: (e) => {
6205
+ if (wrapperRef.current?.contains(e.target)) {
6206
+ e.preventDefault();
6207
+ }
6208
+ },
6209
+ children: /* @__PURE__ */ jsx("div", { className: "max-h-[300px] overflow-y-auto p-1", children: filteredOptions.length === 0 ? /* @__PURE__ */ jsx("div", { className: "py-6 text-center text-sm text-muted-foreground", children: emptyText }) : hasGroups ? /* @__PURE__ */ jsxs(Fragment, { children: [
6210
+ groupedOptions.ungrouped.map(renderOption),
6211
+ Object.entries(groupedOptions.groups).map(([group, opts]) => /* @__PURE__ */ jsxs("div", { children: [
6212
+ /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-xs font-semibold text-muted-foreground", children: group }),
6213
+ opts.map(renderOption)
6214
+ ] }, group))
6215
+ ] }) : filteredOptions.map(renderOption) })
6216
+ }
6217
+ )
6218
+ ] });
6219
+ }
6220
+ Combobox.displayName = "Combobox";
5616
6221
  var iconButtonVariants = cva(
5617
6222
  // Base styles
5618
6223
  [
@@ -7889,6 +8494,6 @@ var DataStarIcon = forwardRef(
7889
8494
  );
7890
8495
  DataStarIcon.displayName = "DataStarIcon";
7891
8496
 
7892
- export { ALL_THEMES, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Autocomplete, Badge, Board, BoardContent, BoardHeader, Button, Calendar, Card, CardActions, CardContent, CardDescription, CardFooter, CardGrid, CardHeader, CardImage, CardList, CardTitle, CellEditor, Checkbox, Chip, CodeRenderer, ConfirmationModal, ContextMenu, CopyButton, CosmicFrogIcon, CsvRenderer, DARK_ELEGANT_THEME, DEFAULT_RENDERERS, DataGrid, DataStarIcon, DataTable, DatePicker, DatePickerInput, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, FileView, FilterPopover, HeaderCell, HtmlRenderer, IconButton, ImageRenderer, Input, Label, LoadingSpinner, MINIMALIST_LIGHT_THEME, MODERN_DARK_THEME, MODERN_LIGHT_THEME, MarkdownRenderer, Modal, ModalButton, OPTILOGIC_DARK_THEME, OPTILOGIC_LEGACY_THEME, OptilogicLogo, OptilogicLogoWithText, PRESET_THEMES, PlainTextRenderer, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, ResizablePanel, ResizeHandle, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SelectableCard, Separator, Skeleton, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemePicker, Toaster, Tooltip, TooltipArrow, TooltipContent, TooltipPortal, TooltipProvider, TooltipRoot, TooltipTrigger, accordionContentVariants, accordionItemVariants, accordionTriggerVariants, applyFilterOperator, applyFilters, applySorting, applyTheme, areThemesEqual, badgeVariants, boardVariants, buttonVariants, cardActionsVariants, cardGridVariants, cardImageVariants, cardListVariants, cardVariants, cloneTheme, cn, detectContentType, exportTheme, getCellValue, getCurrentTheme, getDefaultTheme, getFileExtension, getPresetTheme, hexToHsl, iconButtonVariants, importTheme, isPresetTheme, isTextContentType, isUrlContentType, labelVariants, loadingSpinnerVariants, mergeRenderers, resolveRenderer, themeToHsl, useColumnResize, useColumnResizeManager, useConfirmation, useContentType, useContextMenu, useDataGridState, useKeyboardNavigation, validateTheme };
8497
+ export { ALL_THEMES, Accordion, AccordionContent, AccordionItem, AccordionTrigger, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Autocomplete, Badge, Board, BoardContent, BoardHeader, Button, Calendar, Card, CardActions, CardContent, CardDescription, CardFooter, CardGrid, CardHeader, CardImage, CardList, CardTitle, CellEditor, Checkbox, Chip, CodeRenderer, Combobox, ConfirmationModal, ContextMenu, CopyButton, CosmicFrogIcon, CsvRenderer, DARK_ELEGANT_THEME, DEFAULT_RENDERERS, DataGrid, DataStarIcon, DataTable, DatePicker, DatePickerInput, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, FileView, FilterPopover, HeaderCell, HtmlRenderer, IconButton, ImageRenderer, Input, Label, LoadingSpinner, MINIMALIST_LIGHT_THEME, MODERN_DARK_THEME, MODERN_LIGHT_THEME, MarkdownRenderer, Modal, ModalButton, MultiSelect, OPTILOGIC_DARK_THEME, OPTILOGIC_LEGACY_THEME, OptilogicLogo, OptilogicLogoWithText, PRESET_THEMES, PlainTextRenderer, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, ResizablePanel, ResizeHandle, Select, SelectContent, SelectGroup, SelectItem, SelectItemDescription, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SelectableCard, Separator, Skeleton, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemePicker, Toaster, Tooltip, TooltipArrow, TooltipContent, TooltipPortal, TooltipProvider, TooltipRoot, TooltipTrigger, accordionContentVariants, accordionItemVariants, accordionTriggerVariants, applyFilterOperator, applyFilters, applySorting, applyTheme, areThemesEqual, badgeVariants, boardVariants, buttonVariants, cardActionsVariants, cardGridVariants, cardImageVariants, cardListVariants, cardVariants, cloneTheme, cn, detectContentType, exportTheme, getCellValue, getCurrentTheme, getDefaultTheme, getFileExtension, getPresetTheme, hexToHsl, iconButtonVariants, importTheme, isPresetTheme, isTextContentType, isUrlContentType, labelVariants, loadingSpinnerVariants, mergeRenderers, resolveRenderer, tabsListVariants, tabsTriggerVariants, themeToHsl, useColumnResize, useColumnResizeManager, useConfirmation, useContentType, useContextMenu, useDataGridState, useKeyboardNavigation, validateTheme };
7893
8498
  //# sourceMappingURL=index.js.map
7894
8499
  //# sourceMappingURL=index.js.map