@caratlogic/design-system 0.1.20 → 0.1.21

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.esm.js CHANGED
@@ -21178,9 +21178,9 @@ function useSelectedComboboxOption(value, options) {
21178
21178
  }, [normalizedValue, options]);
21179
21179
  }
21180
21180
 
21181
- function CustomCombobox({ options, placeholder = 'Select option...', value, onChange, className, }) {
21181
+ function CustomCombobox({ options, placeholder = 'Select option...', value, onChange, className, emptyMessage = 'No option found.', }) {
21182
21182
  const selectedItem = useSelectedComboboxOption(value, options);
21183
- return (jsx(SearchableSelect, { selectedItem: selectedItem, onChange: (opt) => onChange(opt.label), getOptionKey: (o) => o.value, getOptionLabel: (o) => o.label, options: options, searchPlaceholder: placeholder, emptyMessage: "No option found.", className: className }));
21183
+ return (jsx(SearchableSelect, { selectedItem: selectedItem, onChange: (opt) => onChange(opt.label), getOptionKey: (o) => o.value, getOptionLabel: (o) => o.label, options: options, searchPlaceholder: placeholder, emptyMessage: emptyMessage, className: className }));
21184
21184
  }
21185
21185
 
21186
21186
  function useExpandableRows() {
@@ -21579,7 +21579,7 @@ function EditableCellContent({ col, row, value, isEditing, width, onEditValueCha
21579
21579
  return jsx(Fragment$2, { children: clipToWidth(stringValue, width) });
21580
21580
  }
21581
21581
 
21582
- function DataEditableTable({ data, columns, onRowClick, enableSelection = false, columnStyles = {}, onEditChange, onSaveRow, sortBy, setSortBy, sortOrder, setSortOrder, saving, selectedRows = [], onSelectionChange, isArchiveView = false, selectionInArchiveView = false, permissionKey = '', columnWidths, onColumnResize, pagination, fetchBusinessContacts, showGrid = true, }) {
21582
+ function DataEditableTable({ data, columns, onRowClick, enableSelection = false, columnStyles = {}, onEditChange, onSaveRow, sortBy, setSortBy, sortOrder, setSortOrder, saving, selectedRows = [], onSelectionChange, isArchiveView = false, selectionInArchiveView = false, permissionKey = '', columnWidths, onColumnResize, pagination, fetchBusinessContacts, showGrid = true, emptyState, }) {
21583
21583
  const showSelectionColumn = enableSelection && (!isArchiveView || selectionInArchiveView);
21584
21584
  const vBorder = showGrid ? 'border-r' : '';
21585
21585
  const { localWidths, draggingKey, tableRef, handleResizeMouseDown } = useColumnResize({
@@ -21603,77 +21603,73 @@ function DataEditableTable({ data, columns, onRowClick, enableSelection = false,
21603
21603
  setSortOrder('asc');
21604
21604
  }
21605
21605
  };
21606
- return (jsxs("div", { className: "w-full h-full rounded-lg border border-border bg-card flex flex-col overflow-hidden", children: [jsx("div", { className: "overflow-auto flex-1", children: jsxs("table", { ref: tableRef, className: "min-w-[70vh] w-full text-xs text-center border-separate", style: { borderSpacing: 0 }, children: [jsx("thead", { className: "sticky top-0 z-20 !bg-table-header border-b border-border text-secondary-foreground text-sm", children: jsxs("tr", { className: "h-[40px]", children: [!isArchiveView && (jsx("th", { className: cn('px-3 py-1.5 text-left font-semibold w-8 first:!pl-6 border-b border-solid !border-border', vBorder) })), showSelectionColumn && (jsx("th", { className: cn('px-3 py-1.5 text-center font-semibold first:!pl-6 border-b border-solid !border-border', vBorder), children: jsx(Checkbox, { checked: allSelected
21607
- ? true
21608
- : someSelected
21609
- ? 'indeterminate'
21610
- : false, onCheckedChange: toggleSelectAll }) })), columns.map((col) => {
21611
- const w = localWidths[col.key];
21612
- const isDragging = draggingKey === col.key;
21613
- const isPinnedRight = col.key === 'actions';
21614
- const thStyle = w || isDragging
21615
- ? {
21616
- width: `var(--col-w-${col.key})`,
21617
- minWidth: `var(--col-w-${col.key})`,
21618
- maxWidth: `var(--col-w-${col.key})`,
21619
- }
21620
- : isPinnedRight
21621
- ? { width: '72px', minWidth: '72px', maxWidth: '72px' }
21622
- : undefined;
21623
- return (jsxs("th", { className: cn('px-4 py-1.5 relative first:!pl-6 text-left whitespace-nowrap font-semibold text-sm border-b border-solid !border-border', vBorder, isArchiveView && !isPinnedRight && 'pl-1', col.sortable && '!cursor-pointer hover:bg-muted/60', isDragging && 'bg-primary/10', isPinnedRight && pinnedHeaderClass()), style: thStyle, onClick: () => handleColumnClick(col.key, col.sortable), children: [jsxs("div", { className: cn('gap-2', w && 'overflow-hidden', col.sortable && 'flex items-center !cursor-pointer', isPinnedRight && 'flex items-center justify-center'), children: [w && typeof col.header === 'string' ? (jsx("span", { className: "truncate", title: col.header, children: col.header })) : (col.header), col.sortable && (jsx(SortIcon, { active: sortBy === col.key, order: sortOrder }))] }), jsx("div", { className: cn('absolute right-0 top-0 h-full w-1.5 z-20 cursor-col-resize select-none transition-colors hover:bg-primary/40', isDragging && 'bg-primary/40'), onMouseDown: (e) => handleResizeMouseDown(e, col.key), onClick: (e) => e.stopPropagation() })] }, col.key.toString()));
21624
- })] }) }), jsx("tbody", { children: data.length === 0 ? (jsx("tr", { className: "h-12", children: jsx("td", { colSpan: columns.length +
21625
- (!isArchiveView ? 1 : 0) +
21626
- (showSelectionColumn ? 1 : 0), className: "text-center p-6 text-muted-foreground", children: "No data available" }) })) : (data.map((row, rowIndex) => {
21627
- const isEditing = editingRow === row.id && editingRow !== null;
21628
- const isSaving = savingRow === row.id;
21629
- const isSelected = selectedSet.has(row.id);
21630
- const bgClass = isEditing
21631
- ? 'bg-warning/10 hover:bg-warning/10'
21632
- : isSelected
21633
- ? 'bg-primary/10 hover:bg-primary/10'
21634
- : rowIndex % 2 === 0
21635
- ? 'bg-card hover:bg-secondary'
21636
- : 'bg-background hover:bg-secondary';
21637
- return (jsxs("tr", { className: cn('group/row h-[46px] transition-colors text-sm text-table-cell', bgClass, onRowClick && 'cursor-pointer'), onClick: () => onRowClick?.(row), children: [isArchiveView ? null : (jsx("td", { className: cn('px-3 py-1.5 text-center first:!pl-6 border-b border-solid !border-border', vBorder), children: jsx(Protected, { module: permissionKey, minLevel: PERMISSIONS.WRITE, children: jsx("button", { onClick: (e) => {
21638
- e.stopPropagation();
21639
- handleEditIconClick(row.id, row);
21640
- }, disabled: isSaving, className: cn('p-1 rounded hover:bg-primary/20 transition-colors !cursor-pointer', isEditing
21641
- ? 'text-success'
21642
- : 'text-muted-foreground'), children: isSaving ? (jsx(LoaderCircle, { size: 16, className: "animate-spin text-primary" })) : isEditing ? (jsx(Check, { size: 16 })) : (jsx(Pencil, { size: 16 })) }) }) })), showSelectionColumn && (jsx("td", { className: cn('px-3 py-1.5 first:!pl-6 border-b border-solid !border-border', vBorder), onClick: (e) => e.stopPropagation(), children: jsx(Checkbox, { checked: isSelected, onCheckedChange: () => toggleRow(row.id) }) })), columns.map((col) => {
21643
- const value = isEditing
21644
- ? editValues[col.key]
21645
- : row[col.key];
21606
+ return (jsxs("div", { className: "w-full h-full rounded-lg border border-border bg-card flex flex-col overflow-hidden", children: [jsxs("div", { className: "overflow-auto flex-1", children: [jsxs("table", { ref: tableRef, className: "min-w-[70vh] w-full text-xs text-center border-separate", style: { borderSpacing: 0 }, children: [jsx("thead", { className: "sticky top-0 z-20 !bg-table-header border-b border-border text-secondary-foreground text-sm", children: jsxs("tr", { className: "h-[40px]", children: [!isArchiveView && (jsx("th", { className: cn('px-3 py-1.5 text-left font-semibold w-8 first:!pl-6 border-b border-solid !border-border', vBorder) })), showSelectionColumn && (jsx("th", { className: cn('px-3 py-1.5 text-center font-semibold first:!pl-6 border-b border-solid !border-border', vBorder), children: jsx(Checkbox, { checked: allSelected
21607
+ ? true
21608
+ : someSelected
21609
+ ? 'indeterminate'
21610
+ : false, onCheckedChange: toggleSelectAll }) })), columns.map((col) => {
21646
21611
  const w = localWidths[col.key];
21612
+ const isDragging = draggingKey === col.key;
21647
21613
  const isPinnedRight = col.key === 'actions';
21648
- const tdStyle = w || draggingKey === col.key
21614
+ const thStyle = w || isDragging
21649
21615
  ? {
21650
21616
  width: `var(--col-w-${col.key})`,
21651
21617
  minWidth: `var(--col-w-${col.key})`,
21652
21618
  maxWidth: `var(--col-w-${col.key})`,
21653
21619
  }
21654
21620
  : isPinnedRight
21621
+ ? { width: '72px', minWidth: '72px', maxWidth: '72px' }
21622
+ : undefined;
21623
+ return (jsxs("th", { className: cn('px-4 py-1.5 relative first:!pl-6 text-left whitespace-nowrap font-semibold text-sm border-b border-solid !border-border', vBorder, isArchiveView && !isPinnedRight && 'pl-1', col.sortable && '!cursor-pointer hover:bg-muted/60', isDragging && 'bg-primary/10', isPinnedRight && pinnedHeaderClass()), style: thStyle, onClick: () => handleColumnClick(col.key, col.sortable), children: [jsxs("div", { className: cn('gap-2', w && 'overflow-hidden', col.sortable && 'flex items-center !cursor-pointer', isPinnedRight && 'flex items-center justify-center'), children: [w && typeof col.header === 'string' ? (jsx("span", { className: "truncate", title: col.header, children: col.header })) : (col.header), col.sortable && (jsx(SortIcon, { active: sortBy === col.key, order: sortOrder }))] }), jsx("div", { className: cn('absolute right-0 top-0 h-full w-1.5 z-20 cursor-col-resize select-none transition-colors hover:bg-primary/40', isDragging && 'bg-primary/40'), onMouseDown: (e) => handleResizeMouseDown(e, col.key), onClick: (e) => e.stopPropagation() })] }, col.key.toString()));
21624
+ })] }) }), jsx("tbody", { children: data.map((row, rowIndex) => {
21625
+ const isEditing = editingRow === row.id && editingRow !== null;
21626
+ const isSaving = savingRow === row.id;
21627
+ const isSelected = selectedSet.has(row.id);
21628
+ const bgClass = isEditing
21629
+ ? 'bg-warning/10 hover:bg-warning/10'
21630
+ : isSelected
21631
+ ? 'bg-primary/10 hover:bg-primary/10'
21632
+ : rowIndex % 2 === 0
21633
+ ? 'bg-card hover:bg-secondary'
21634
+ : 'bg-background hover:bg-secondary';
21635
+ return (jsxs("tr", { className: cn('group/row h-[46px] transition-colors text-sm text-table-cell', bgClass, onRowClick && 'cursor-pointer'), onClick: () => onRowClick?.(row), children: [isArchiveView ? null : (jsx("td", { className: cn('px-3 py-1.5 text-center first:!pl-6 border-b border-solid !border-border', vBorder), children: jsx(Protected, { module: permissionKey, minLevel: PERMISSIONS.WRITE, children: jsx("button", { onClick: (e) => {
21636
+ e.stopPropagation();
21637
+ handleEditIconClick(row.id, row);
21638
+ }, disabled: isSaving, className: cn('p-1 rounded hover:bg-primary/20 transition-colors !cursor-pointer', isEditing ? 'text-success' : 'text-muted-foreground'), children: isSaving ? (jsx(LoaderCircle, { size: 16, className: "animate-spin text-primary" })) : isEditing ? (jsx(Check, { size: 16 })) : (jsx(Pencil, { size: 16 })) }) }) })), showSelectionColumn && (jsx("td", { className: cn('px-3 py-1.5 first:!pl-6 border-b border-solid !border-border', vBorder), onClick: (e) => e.stopPropagation(), children: jsx(Checkbox, { checked: isSelected, onCheckedChange: () => toggleRow(row.id) }) })), columns.map((col) => {
21639
+ const value = isEditing
21640
+ ? editValues[col.key]
21641
+ : row[col.key];
21642
+ const w = localWidths[col.key];
21643
+ const isPinnedRight = col.key === 'actions';
21644
+ const tdStyle = w || draggingKey === col.key
21655
21645
  ? {
21656
- width: '72px',
21657
- minWidth: '72px',
21658
- maxWidth: '72px',
21646
+ width: `var(--col-w-${col.key})`,
21647
+ minWidth: `var(--col-w-${col.key})`,
21648
+ maxWidth: `var(--col-w-${col.key})`,
21659
21649
  }
21660
- : undefined;
21661
- // Pinned cells need an OPAQUE bg matching the row state so the
21662
- // scrolling content underneath doesn't bleed through — no alpha tints.
21663
- const pinnedBg = isPinnedRight
21664
- ? isEditing
21665
- ? 'bg-[#FEFCE8] dark:bg-[#422006]'
21666
- : isSelected
21667
- ? 'bg-[#EFF6FF] dark:bg-[#172554]'
21668
- : 'bg-card group-hover/row:bg-table-header'
21669
- : '';
21670
- return (jsx("td", { className: cn('px-4 py-1.5 first:!pl-6 border-b border-border whitespace-nowrap text-table-cell border-solid !border-border', vBorder, isPinnedRight || col.align === 'center'
21671
- ? 'text-center'
21672
- : typeof value === 'number'
21673
- ? 'text-right'
21674
- : 'text-left', isArchiveView && !isPinnedRight && 'pl-2', columnStyles?.[col.key.toString()] || '', draggingKey === col.key && 'bg-primary/5', isPinnedRight && pinnedCellClass(pinnedBg)), style: tdStyle, children: jsx(EditableCellContent, { col: col, row: row, value: value, isEditing: isEditing, width: w, onEditValueChange: handleEditValueChange, fetchBusinessContacts: fetchBusinessContacts }) }, col.key.toString()));
21675
- })] }, row.id));
21676
- })) })] }) }), pagination] }));
21650
+ : isPinnedRight
21651
+ ? {
21652
+ width: '72px',
21653
+ minWidth: '72px',
21654
+ maxWidth: '72px',
21655
+ }
21656
+ : undefined;
21657
+ // Pinned cells need an OPAQUE bg matching the row state so the
21658
+ // scrolling content underneath doesn't bleed through — no alpha tints.
21659
+ const pinnedBg = isPinnedRight
21660
+ ? isEditing
21661
+ ? 'bg-[#FEFCE8] dark:bg-[#422006]'
21662
+ : isSelected
21663
+ ? 'bg-[#EFF6FF] dark:bg-[#172554]'
21664
+ : 'bg-card group-hover/row:bg-table-header'
21665
+ : '';
21666
+ return (jsx("td", { className: cn('px-4 py-1.5 first:!pl-6 border-b border-border whitespace-nowrap text-table-cell border-solid !border-border', vBorder, isPinnedRight || col.align === 'center'
21667
+ ? 'text-center'
21668
+ : typeof value === 'number'
21669
+ ? 'text-right'
21670
+ : 'text-left', isArchiveView && !isPinnedRight && 'pl-2', columnStyles?.[col.key.toString()] || '', draggingKey === col.key && 'bg-primary/5', isPinnedRight && pinnedCellClass(pinnedBg)), style: tdStyle, children: jsx(EditableCellContent, { col: col, row: row, value: value, isEditing: isEditing, width: w, onEditValueChange: handleEditValueChange, fetchBusinessContacts: fetchBusinessContacts }) }, col.key.toString()));
21671
+ })] }, row.id));
21672
+ }) })] }), data.length === 0 && (jsx("div", { className: "sticky left-0 flex w-full items-center justify-center p-6 text-sm text-muted-foreground", children: emptyState ?? 'No data available' }))] }), pagination] }));
21677
21673
  }
21678
21674
 
21679
21675
  /**
@@ -37147,7 +37143,7 @@ function SelectTrigger({ className, size = 'default', children, ...props }) {
37147
37143
  return (jsxs(SelectPrimitive.Trigger, { "data-slot": "select-trigger", "data-size": size, className: cn("border-input-border cursor-pointer data-[placeholder]:!text-[var(--placeholder)] data-[placeholder]:!text-sm [&_[data-placeholder]]:!text-[var(--placeholder)] [&_[data-placeholder]]:!text-sm [&_span[data-placeholder]]:!text-[var(--placeholder)] [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-full items-center justify-between gap-2 rounded-md border bg-input-background px-3 py-2 text-sm whitespace-nowrap shadow-[0_1px_2px_0_rgba(0,0,0,0.05)] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:bg-muted/50 disabled:text-label data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className), ...props, children: [children, jsx(SelectPrimitive.Icon, { asChild: true, children: jsx(ChevronDown, { className: "size-4 text-gray-600" }) })] }));
37148
37144
  }
37149
37145
  function SelectContent({ className, children, position = 'popper', searchable = true, // default: all selects are searchable
37150
- searchPlaceholder = 'Search...', ...props }) {
37146
+ searchPlaceholder = 'Search...', emptyMessage = 'No options available', ...props }) {
37151
37147
  // Use the shared search context provided by Select root
37152
37148
  const searchCtx = useSelectSearchContext();
37153
37149
  const searchTerm = searchCtx?.searchTerm ?? '';
@@ -37159,7 +37155,9 @@ searchPlaceholder = 'Search...', ...props }) {
37159
37155
  return (jsx(SelectPrimitive.Portal, { children: jsxs(SelectPrimitive.Content, { "data-slot": "select-content", className: cn('bg-card cursor-pointer text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg border border-border shadow-[0_10px_15px_-3px_rgba(0,0,0,0.10),0_4px_6px_-4px_rgba(0,0,0,0.10)]', position === 'popper' &&
37160
37156
  'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1', className), position: position, ...props, children: [searchable && (jsx("div", { className: "p-2 pb-1", children: jsxs("div", { className: "flex h-9 w-full items-center gap-2 rounded-lg bg-secondary px-3", children: [jsx(Search, { className: "h-4 w-4 shrink-0 text-[#737373]", "aria-hidden": "true" }), jsx("input", { type: "search", className: "min-w-0 flex-1 bg-transparent text-sm text-foreground outline-none placeholder:text-placeholder", placeholder: searchPlaceholder, value: searchTerm, onChange: (e) => setSearchTerm?.(e.target.value),
37161
37157
  // prevent keys from interfering with Radix keyboard nav
37162
- onKeyDown: (e) => e.stopPropagation() })] }) })), jsx(SelectScrollUpButton, {}), jsx(SelectPrimitive.Viewport, { className: cn('p-1 max-h-[12.5rem] overflow-y-auto', position === 'popper' &&
37158
+ onKeyDown: (e) => e.stopPropagation() })] }) })), jsx(SelectScrollUpButton, {}), jsx(SelectPrimitive.Viewport, { "data-slot": "select-viewport", style: {
37159
+ '--select-empty-message': JSON.stringify(searchTerm ? 'No matching options' : emptyMessage),
37160
+ }, className: cn('p-1 max-h-[12.5rem] overflow-y-auto', 'empty:after:block empty:after:px-2 empty:after:py-4 empty:after:text-center empty:after:text-sm empty:after:text-muted-foreground empty:after:content-(--select-empty-message)', position === 'popper' &&
37163
37161
  'w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1'), children: children }), jsx(SelectScrollDownButton, {})] }) }));
37164
37162
  }
37165
37163
  // 👇 Add searchValue + withCheckbox props here