@optilogic/core 1.3.4 → 1.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -2374,6 +2374,7 @@ interface Theme {
2374
2374
  toggleTrack?: string;
2375
2375
  toggleTrackForeground?: string;
2376
2376
  inputHover?: string;
2377
+ hover?: string;
2377
2378
  /** Chart colors */
2378
2379
  chart1: string;
2379
2380
  chart2: string;
@@ -2435,6 +2436,7 @@ interface ThemeHSL extends Omit<Theme, keyof ThemeColorFields> {
2435
2436
  toggleTrack?: string;
2436
2437
  toggleTrackForeground?: string;
2437
2438
  inputHover?: string;
2439
+ hover?: string;
2438
2440
  chart1: string;
2439
2441
  chart2: string;
2440
2442
  chart3: string;
@@ -2479,6 +2481,7 @@ type ThemeColorFields = {
2479
2481
  toggleTrack?: string;
2480
2482
  toggleTrackForeground?: string;
2481
2483
  inputHover?: string;
2484
+ hover?: string;
2482
2485
  chart1: string;
2483
2486
  chart2: string;
2484
2487
  chart3: string;
package/dist/index.d.ts CHANGED
@@ -2374,6 +2374,7 @@ interface Theme {
2374
2374
  toggleTrack?: string;
2375
2375
  toggleTrackForeground?: string;
2376
2376
  inputHover?: string;
2377
+ hover?: string;
2377
2378
  /** Chart colors */
2378
2379
  chart1: string;
2379
2380
  chart2: string;
@@ -2435,6 +2436,7 @@ interface ThemeHSL extends Omit<Theme, keyof ThemeColorFields> {
2435
2436
  toggleTrack?: string;
2436
2437
  toggleTrackForeground?: string;
2437
2438
  inputHover?: string;
2439
+ hover?: string;
2438
2440
  chart1: string;
2439
2441
  chart2: string;
2440
2442
  chart3: string;
@@ -2479,6 +2481,7 @@ type ThemeColorFields = {
2479
2481
  toggleTrack?: string;
2480
2482
  toggleTrackForeground?: string;
2481
2483
  inputHover?: string;
2484
+ hover?: string;
2482
2485
  chart1: string;
2483
2486
  chart2: string;
2484
2487
  chart3: string;
package/dist/index.js CHANGED
@@ -34,12 +34,12 @@ var buttonVariants = cva(
34
34
  {
35
35
  variants: {
36
36
  variant: {
37
- default: "bg-muted text-foreground hover:bg-accent hover:text-accent-foreground disabled:opacity-50 disabled:text-muted-foreground",
37
+ default: "bg-muted text-foreground hover:bg-hover disabled:opacity-50 disabled:text-muted-foreground",
38
38
  primary: "bg-accent text-accent-foreground shadow hover:shadow-md disabled:opacity-50",
39
39
  destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90 hover:shadow-md disabled:opacity-50",
40
- outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground disabled:opacity-50 disabled:bg-muted/20 disabled:text-muted-foreground",
40
+ outline: "border border-input bg-background shadow-sm hover:bg-hover disabled:opacity-50 disabled:bg-muted/20 disabled:text-muted-foreground",
41
41
  secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80 disabled:opacity-50",
42
- ghost: "text-foreground hover:bg-accent hover:text-accent-foreground disabled:text-muted-foreground disabled:bg-muted/30 disabled:opacity-70",
42
+ ghost: "text-foreground hover:bg-hover disabled:text-muted-foreground disabled:bg-muted/30 disabled:opacity-70",
43
43
  link: "text-primary underline-offset-4 hover:underline disabled:opacity-50 disabled:text-muted-foreground"
44
44
  },
45
45
  size: {
@@ -351,7 +351,7 @@ 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-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",
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-hover data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
355
355
  className
356
356
  ),
357
357
  ...props,
@@ -505,10 +505,10 @@ var accordionTriggerVariants = cva(
505
505
  variants: {
506
506
  variant: {
507
507
  default: "hover:text-foreground/80",
508
- bordered: "px-4 hover:bg-muted/50",
509
- card: "px-4 hover:bg-muted/30",
510
- filled: "px-4 hover:bg-muted",
511
- ghost: "px-2 rounded-md hover:bg-muted/50"
508
+ bordered: "px-4 hover:bg-hover",
509
+ card: "px-4 hover:bg-hover",
510
+ filled: "px-4 hover:bg-hover",
511
+ ghost: "px-2 rounded-md hover:bg-hover"
512
512
  }
513
513
  },
514
514
  defaultVariants: {
@@ -685,7 +685,7 @@ var DropdownMenuSubTrigger = React20.forwardRef(({ className, inset, children, .
685
685
  ref,
686
686
  className: cn(
687
687
  "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none",
688
- "focus:bg-accent",
688
+ "focus:bg-hover",
689
689
  "data-[state=open]:bg-accent",
690
690
  inset && "pl-8",
691
691
  className
@@ -739,7 +739,7 @@ var DropdownMenuItem = React20.forwardRef(({ className, inset, destructive, ...p
739
739
  ref,
740
740
  className: cn(
741
741
  "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors",
742
- "focus:bg-accent focus:text-accent-foreground",
742
+ "focus:bg-hover",
743
743
  "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
744
744
  inset && "pl-8",
745
745
  destructive && "text-destructive focus:text-destructive",
@@ -755,7 +755,7 @@ var DropdownMenuCheckboxItem = React20.forwardRef(({ className, children, checke
755
755
  ref,
756
756
  className: cn(
757
757
  "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors",
758
- "focus:bg-accent focus:text-accent-foreground",
758
+ "focus:bg-hover",
759
759
  "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
760
760
  className
761
761
  ),
@@ -774,7 +774,7 @@ var DropdownMenuRadioItem = React20.forwardRef(({ className, children, ...props
774
774
  ref,
775
775
  className: cn(
776
776
  "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors",
777
- "focus:bg-accent focus:text-accent-foreground",
777
+ "focus:bg-hover",
778
778
  "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
779
779
  className
780
780
  ),
@@ -1526,7 +1526,7 @@ var TableRow = React20.forwardRef(
1526
1526
  {
1527
1527
  ref,
1528
1528
  className: cn(
1529
- "border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
1529
+ "border-b transition-colors hover:bg-hover data-[state=selected]:bg-muted",
1530
1530
  className
1531
1531
  ),
1532
1532
  ...props
@@ -2658,8 +2658,7 @@ function Chip({
2658
2658
  // Clickable state
2659
2659
  isClickable && [
2660
2660
  "cursor-pointer",
2661
- "hover:bg-accent hover:text-accent-foreground",
2662
- "hover:border-accent",
2661
+ "hover:bg-hover",
2663
2662
  "hover:shadow-md"
2664
2663
  ],
2665
2664
  // Non-clickable state
@@ -2819,7 +2818,7 @@ function Calendar({
2819
2818
  /* @__PURE__ */ jsx(
2820
2819
  SelectTrigger,
2821
2820
  {
2822
- className: "h-7 w-[110px] text-sm font-medium border-none shadow-none hover:bg-accent focus:ring-0 px-2",
2821
+ className: "h-7 w-[110px] text-sm font-medium border-none shadow-none hover:bg-hover focus:ring-0 px-2",
2823
2822
  "aria-label": "Select month",
2824
2823
  children: /* @__PURE__ */ jsx(SelectValue, { children: MONTHS[month] })
2825
2824
  }
@@ -2841,7 +2840,7 @@ function Calendar({
2841
2840
  /* @__PURE__ */ jsx(
2842
2841
  SelectTrigger,
2843
2842
  {
2844
- className: "h-7 w-[70px] text-sm font-medium border-none shadow-none hover:bg-accent focus:ring-0 px-2",
2843
+ className: "h-7 w-[70px] text-sm font-medium border-none shadow-none hover:bg-hover focus:ring-0 px-2",
2845
2844
  "aria-label": "Select year",
2846
2845
  children: /* @__PURE__ */ jsx(SelectValue, { children: year })
2847
2846
  }
@@ -3492,7 +3491,7 @@ function HeaderCell({
3492
3491
  "flex items-center gap-1 px-3 py-2 h-full",
3493
3492
  isResizable && "pr-6",
3494
3493
  // Extra padding to create space for resize handle
3495
- isSortable && "cursor-pointer hover:bg-accent/10",
3494
+ isSortable && "cursor-pointer hover:bg-hover",
3496
3495
  column.align === "center" && "justify-center",
3497
3496
  column.align === "right" && "justify-end"
3498
3497
  ),
@@ -3563,7 +3562,7 @@ function HeaderCell({
3563
3562
  className: cn(
3564
3563
  "absolute top-0 right-0 w-4 h-full cursor-col-resize z-10",
3565
3564
  "flex items-center justify-center",
3566
- "hover:bg-accent/50 transition-colors",
3565
+ "hover:bg-hover transition-colors",
3567
3566
  "group",
3568
3567
  isResizing && "bg-accent"
3569
3568
  ),
@@ -5193,7 +5192,7 @@ function DataGrid({
5193
5192
  "absolute top-0 left-0 transition-colors border-b border-border",
5194
5193
  onRowClick && "cursor-pointer",
5195
5194
  isSelected && "bg-accent/20",
5196
- !isSelected && "hover:bg-muted/50",
5195
+ !isSelected && "hover:bg-hover",
5197
5196
  rowClassName && rowClassName(row, virtualRow.index)
5198
5197
  ),
5199
5198
  style: {
@@ -5389,7 +5388,7 @@ function DataGrid({
5389
5388
  "flex border-b border-border transition-colors",
5390
5389
  onRowClick && "cursor-pointer",
5391
5390
  isSelected && "bg-accent/20",
5392
- !isSelected && "hover:bg-muted/50",
5391
+ !isSelected && "hover:bg-hover",
5393
5392
  rowClassName && rowClassName(row, rowIndex)
5394
5393
  ),
5395
5394
  style: { width: tableWidth ? `${tableWidth}px` : "100%" },
@@ -5638,8 +5637,8 @@ function Autocomplete({
5638
5637
  onClick: () => handleSelect(option.value),
5639
5638
  className: cn(
5640
5639
  "relative flex w-full cursor-pointer select-none items-start gap-2 rounded-sm px-2 py-1.5 text-sm outline-none",
5641
- "hover:bg-accent hover:text-accent-foreground",
5642
- "focus:bg-accent focus:text-accent-foreground",
5640
+ "hover:bg-hover",
5641
+ "focus:bg-hover",
5643
5642
  option.disabled && "pointer-events-none opacity-50",
5644
5643
  value === option.value && "bg-accent/50"
5645
5644
  ),
@@ -5679,7 +5678,7 @@ function Autocomplete({
5679
5678
  role: "button",
5680
5679
  tabIndex: -1,
5681
5680
  onClick: handleClear,
5682
- className: "rounded-sm hover:bg-muted p-0.5",
5681
+ className: "rounded-sm hover:bg-hover p-0.5",
5683
5682
  children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5 text-muted-foreground" })
5684
5683
  }
5685
5684
  ),
@@ -5713,7 +5712,7 @@ function Autocomplete({
5713
5712
  {
5714
5713
  type: "button",
5715
5714
  onClick: () => setSearch(""),
5716
- className: "p-1 hover:bg-muted rounded-sm",
5715
+ className: "p-1 hover:bg-hover rounded-sm",
5717
5716
  children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5 text-muted-foreground" })
5718
5717
  }
5719
5718
  )
@@ -5844,7 +5843,7 @@ function MultiSelect({
5844
5843
  onClick: () => handleToggle(option.value),
5845
5844
  className: cn(
5846
5845
  "relative flex w-full cursor-pointer select-none items-start gap-2 rounded-sm px-2 py-1.5 text-sm outline-none",
5847
- "hover:bg-accent hover:text-accent-foreground",
5846
+ "hover:bg-hover",
5848
5847
  option.disabled && "pointer-events-none opacity-50"
5849
5848
  ),
5850
5849
  children: [
@@ -5894,7 +5893,7 @@ function MultiSelect({
5894
5893
  role: "button",
5895
5894
  tabIndex: -1,
5896
5895
  onClick: (e) => handleRemove(safeValue[i], e),
5897
- className: "rounded-sm hover:bg-foreground/10 p-0.5",
5896
+ className: "rounded-sm hover:bg-hover p-0.5",
5898
5897
  children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
5899
5898
  }
5900
5899
  )
@@ -5914,7 +5913,7 @@ function MultiSelect({
5914
5913
  role: "button",
5915
5914
  tabIndex: -1,
5916
5915
  onClick: handleClearAll,
5917
- className: "rounded-sm hover:bg-muted p-0.5",
5916
+ className: "rounded-sm hover:bg-hover p-0.5",
5918
5917
  children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5 text-muted-foreground" })
5919
5918
  }
5920
5919
  ),
@@ -5948,7 +5947,7 @@ function MultiSelect({
5948
5947
  {
5949
5948
  type: "button",
5950
5949
  onClick: () => setSearch(""),
5951
- className: "p-1 hover:bg-muted rounded-sm",
5950
+ className: "p-1 hover:bg-hover rounded-sm",
5952
5951
  children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5 text-muted-foreground" })
5953
5952
  }
5954
5953
  )
@@ -5962,7 +5961,7 @@ function MultiSelect({
5962
5961
  onClick: handleSelectAll,
5963
5962
  className: cn(
5964
5963
  "relative flex w-full cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none",
5965
- "hover:bg-accent hover:text-accent-foreground"
5964
+ "hover:bg-hover"
5966
5965
  ),
5967
5966
  children: [
5968
5967
  /* @__PURE__ */ jsx(
@@ -6134,8 +6133,8 @@ function Combobox({
6134
6133
  onClick: () => handleSelect(option.value),
6135
6134
  className: cn(
6136
6135
  "relative flex w-full cursor-pointer select-none items-start gap-2 rounded-sm px-2 py-1.5 text-sm outline-none",
6137
- "hover:bg-accent hover:text-accent-foreground",
6138
- "focus:bg-accent focus:text-accent-foreground",
6136
+ "hover:bg-hover",
6137
+ "focus:bg-hover",
6139
6138
  option.disabled && "pointer-events-none opacity-50",
6140
6139
  value === option.value && "bg-accent/50"
6141
6140
  ),
@@ -6189,7 +6188,7 @@ function Combobox({
6189
6188
  tabIndex: -1,
6190
6189
  onMouseDown: (e) => e.preventDefault(),
6191
6190
  onClick: handleClear,
6192
- className: "rounded-sm hover:bg-muted p-0.5",
6191
+ className: "rounded-sm hover:bg-hover p-0.5",
6193
6192
  children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5 text-muted-foreground" })
6194
6193
  }
6195
6194
  ),
@@ -6242,41 +6241,41 @@ var iconButtonVariants = cva(
6242
6241
  variants: {
6243
6242
  variant: {
6244
6243
  /**
6245
- * Default - subtle background with accent on hover
6244
+ * Default - subtle hover tint
6246
6245
  */
6247
6246
  default: [
6248
6247
  "bg-transparent text-muted-foreground",
6249
- "hover:bg-accent hover:text-accent-foreground",
6248
+ "hover:bg-hover",
6250
6249
  "border border-transparent"
6251
6250
  ],
6252
6251
  /**
6253
- * Ghost - no background, accent on hover
6252
+ * Ghost - no background, subtle hover tint
6254
6253
  */
6255
6254
  ghost: [
6256
6255
  "bg-transparent text-muted-foreground",
6257
- "hover:bg-accent hover:text-accent-foreground"
6256
+ "hover:bg-hover"
6258
6257
  ],
6259
6258
  /**
6260
- * Outline - border with accent on hover
6259
+ * Outline - bordered, subtle hover tint
6261
6260
  */
6262
6261
  outline: [
6263
6262
  "bg-transparent text-muted-foreground",
6264
6263
  "border border-border",
6265
- "hover:bg-accent hover:text-accent-foreground hover:border-accent"
6264
+ "hover:bg-hover"
6266
6265
  ],
6267
6266
  /**
6268
- * Filled - accent background
6267
+ * Filled - accent background (branded; darkens on hover)
6269
6268
  */
6270
6269
  filled: [
6271
6270
  "bg-accent text-accent-foreground",
6272
6271
  "hover:bg-accent/90 hover:shadow-sm"
6273
6272
  ],
6274
6273
  /**
6275
- * Muted - muted background with accent on hover
6274
+ * Muted - muted background with subtle hover tint
6276
6275
  */
6277
6276
  muted: [
6278
6277
  "bg-muted text-muted-foreground",
6279
- "hover:bg-accent hover:text-accent-foreground"
6278
+ "hover:bg-hover"
6280
6279
  ]
6281
6280
  },
6282
6281
  size: {
@@ -6693,6 +6692,7 @@ function themeToHsl(theme) {
6693
6692
  toggleTrack: theme.toggleTrack ? hexToHsl(theme.toggleTrack) : void 0,
6694
6693
  toggleTrackForeground: theme.toggleTrackForeground ? hexToHsl(theme.toggleTrackForeground) : void 0,
6695
6694
  inputHover: theme.inputHover ? hexToHsl(theme.inputHover) : void 0,
6695
+ hover: theme.hover ? hexToHsl(theme.hover) : void 0,
6696
6696
  chart1: hexToHsl(theme.chart1),
6697
6697
  chart2: hexToHsl(theme.chart2),
6698
6698
  chart3: hexToHsl(theme.chart3),
@@ -6716,6 +6716,11 @@ function deriveInputHoverHsl(hslTheme) {
6716
6716
  }
6717
6717
  return hslTheme.foreground;
6718
6718
  }
6719
+ var HOVER_PRIMARY_MIN_CONTRAST = 2;
6720
+ function deriveHoverChannels(theme, hslTheme) {
6721
+ const primaryBgContrast = getContrastRatio(theme.primary, theme.background);
6722
+ return primaryBgContrast >= HOVER_PRIMARY_MIN_CONTRAST ? hslTheme.primary : hslTheme.foreground;
6723
+ }
6719
6724
  function applyTheme(theme, targetElement) {
6720
6725
  const element = targetElement || document.documentElement;
6721
6726
  const hslTheme = themeToHsl(theme);
@@ -6770,6 +6775,10 @@ function applyTheme(theme, targetElement) {
6770
6775
  "--input-hover",
6771
6776
  hslTheme.inputHover ?? deriveInputHoverHsl(hslTheme)
6772
6777
  );
6778
+ element.style.setProperty(
6779
+ "--hover",
6780
+ `${hslTheme.hover ?? deriveHoverChannels(theme, hslTheme)} / 0.12`
6781
+ );
6773
6782
  element.style.setProperty("--chart-1", hslTheme.chart1);
6774
6783
  element.style.setProperty("--chart-2", hslTheme.chart2);
6775
6784
  element.style.setProperty("--chart-3", hslTheme.chart3);
@@ -6887,6 +6896,7 @@ function areThemesEqual(theme1, theme2) {
6887
6896
  "toggleTrack",
6888
6897
  "toggleTrackForeground",
6889
6898
  "inputHover",
6899
+ "hover",
6890
6900
  "chart1",
6891
6901
  "chart2",
6892
6902
  "chart3",
@@ -6930,6 +6940,25 @@ function importTheme(jsonString) {
6930
6940
  };
6931
6941
  }
6932
6942
  }
6943
+ function hexToLinearRgb(hex) {
6944
+ hex = hex.replace(/^#/, "");
6945
+ const r = parseInt(hex.substring(0, 2), 16) / 255;
6946
+ const g = parseInt(hex.substring(2, 4), 16) / 255;
6947
+ const b = parseInt(hex.substring(4, 6), 16) / 255;
6948
+ const toLinear = (c) => c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
6949
+ return [toLinear(r), toLinear(g), toLinear(b)];
6950
+ }
6951
+ function getRelativeLuminance(hex) {
6952
+ const [r, g, b] = hexToLinearRgb(hex);
6953
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b;
6954
+ }
6955
+ function getContrastRatio(hex1, hex2) {
6956
+ const l1 = getRelativeLuminance(hex1);
6957
+ const l2 = getRelativeLuminance(hex2);
6958
+ const lighter = Math.max(l1, l2);
6959
+ const darker = Math.min(l1, l2);
6960
+ return (lighter + 0.05) / (darker + 0.05);
6961
+ }
6933
6962
  function ThemeSwatch({ theme, isSelected, onClick }) {
6934
6963
  return /* @__PURE__ */ jsx(
6935
6964
  Tooltip,
@@ -6947,7 +6976,7 @@ function ThemeSwatch({ theme, isSelected, onClick }) {
6947
6976
  onClick,
6948
6977
  className: cn(
6949
6978
  "relative flex flex-col items-center gap-1.5 p-2 rounded-lg transition-all",
6950
- "hover:bg-accent/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
6979
+ "hover:bg-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
6951
6980
  isSelected && "bg-accent ring-2 ring-primary"
6952
6981
  ),
6953
6982
  children: [
@@ -7182,8 +7211,8 @@ function MenuItem({ item, onClose, depth = 0 }) {
7182
7211
  className: cn(
7183
7212
  "w-full flex items-center gap-3 px-3 py-2 text-sm rounded-sm",
7184
7213
  "transition-colors text-left",
7185
- "focus:outline-none focus:bg-accent focus:text-accent-foreground",
7186
- item.disabled ? "opacity-50 cursor-not-allowed text-muted-foreground" : "hover:bg-accent hover:text-accent-foreground cursor-pointer",
7214
+ "focus:outline-none focus:bg-hover",
7215
+ item.disabled ? "opacity-50 cursor-not-allowed text-muted-foreground" : "hover:bg-hover cursor-pointer",
7187
7216
  item.destructive && !item.disabled && "text-destructive hover:text-destructive"
7188
7217
  ),
7189
7218
  children: [
@@ -8180,7 +8209,7 @@ function DefaultErrorState({ error }) {
8180
8209
  onClick: error.onRetry,
8181
8210
  className: cn(
8182
8211
  "rounded-md border border-border bg-background px-3 py-1.5 text-sm text-foreground",
8183
- "transition-colors hover:bg-muted"
8212
+ "transition-colors hover:bg-hover"
8184
8213
  ),
8185
8214
  children: "Retry"
8186
8215
  }