@optilogic/core 1.0.0-beta.9 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/index.cjs +1115 -45
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +326 -1
  4. package/dist/index.d.ts +326 -1
  5. package/dist/index.js +1097 -46
  6. package/dist/index.js.map +1 -1
  7. package/dist/styles.css +22 -0
  8. package/dist/tailwind-preset.cjs +17 -2
  9. package/dist/tailwind-preset.cjs.map +1 -1
  10. package/dist/tailwind-preset.js +17 -2
  11. package/dist/tailwind-preset.js.map +1 -1
  12. package/package.json +15 -1
  13. package/src/components/autocomplete.tsx +2 -1
  14. package/src/components/button.tsx +10 -8
  15. package/src/components/calendar.tsx +7 -7
  16. package/src/components/data-grid/DataGrid.tsx +6 -1
  17. package/src/components/data-grid/components/CellEditor.tsx +3 -3
  18. package/src/components/data-grid/hooks/useDataGridState.ts +18 -3
  19. package/src/components/data-grid/types.ts +4 -0
  20. package/src/components/data-grid/utils/dataProcessing.ts +40 -11
  21. package/src/components/date-picker.tsx +2 -1
  22. package/src/components/dropdown-menu.tsx +1 -1
  23. package/src/components/file-view/FileView.tsx +147 -0
  24. package/src/components/file-view/components/CodeRenderer.tsx +97 -0
  25. package/src/components/file-view/components/CsvRenderer.tsx +127 -0
  26. package/src/components/file-view/components/HtmlRenderer.tsx +24 -0
  27. package/src/components/file-view/components/ImageRenderer.tsx +67 -0
  28. package/src/components/file-view/components/MarkdownRenderer.tsx +304 -0
  29. package/src/components/file-view/components/PlainTextRenderer.tsx +27 -0
  30. package/src/components/file-view/components/index.ts +4 -0
  31. package/src/components/file-view/hooks/index.ts +5 -0
  32. package/src/components/file-view/hooks/useContentType.ts +34 -0
  33. package/src/components/file-view/hooks/useDarkMode.ts +62 -0
  34. package/src/components/file-view/hooks/useHighlightedTokens.ts +83 -0
  35. package/src/components/file-view/hooks/useShikiHighlighter.ts +69 -0
  36. package/src/components/file-view/index.ts +47 -0
  37. package/src/components/file-view/types.ts +180 -0
  38. package/src/components/file-view/utils/contentTypeDetection.ts +157 -0
  39. package/src/components/file-view/utils/index.ts +12 -0
  40. package/src/components/file-view/utils/languageMapping.ts +78 -0
  41. package/src/components/file-view/utils/rendererRegistry.ts +42 -0
  42. package/src/components/input.tsx +1 -1
  43. package/src/components/popover.tsx +1 -1
  44. package/src/components/select.tsx +1 -1
  45. package/src/components/switch.tsx +5 -3
  46. package/src/components/textarea.tsx +1 -1
  47. package/src/index.ts +39 -0
  48. package/src/styles.css +22 -0
  49. package/src/tailwind-preset.ts +17 -1
  50. package/src/theme/index.ts +5 -0
  51. package/src/theme/presets.ts +112 -2
  52. package/src/theme/types.ts +35 -0
  53. package/src/theme/utils.ts +231 -0
package/dist/styles.css CHANGED
@@ -40,15 +40,26 @@
40
40
  --border: 214.3 31.8% 91.4%;
41
41
  --input: 214.3 31.8% 91.4%;
42
42
  --ring: 222.2 84% 4.9%;
43
+ --toggle-track: var(--muted);
44
+ --toggle-track-foreground: var(--background);
45
+ --input-hover: var(--foreground);
43
46
  --divider: 214.3 31.8% 91.4%;
44
47
  --chip: 210 40% 96.1%;
45
48
  --chip-foreground: 222.2 47.4% 11.2%;
49
+ --disabled-opacity: 0.5;
46
50
  --radius: 0.5rem;
47
51
  --chart-1: 12 76% 61%;
48
52
  --chart-2: 173 58% 39%;
49
53
  --chart-3: 197 37% 24%;
50
54
  --chart-4: 43 74% 66%;
51
55
  --chart-5: 27 87% 67%;
56
+ --chart-6: 262 60% 55%;
57
+ --chart-7: 142 60% 45%;
58
+ --chart-8: 350 65% 55%;
59
+ --chart-9: 200 70% 50%;
60
+ --chart-10: 60 65% 50%;
61
+ --chart-11: 310 55% 50%;
62
+ --chart-12: 180 50% 45%;
52
63
  }
53
64
 
54
65
  .dark {
@@ -75,14 +86,25 @@
75
86
  --border: 217.2 32.6% 17.5%;
76
87
  --input: 217.2 32.6% 17.5%;
77
88
  --ring: 212.7 26.8% 83.9%;
89
+ --toggle-track: var(--muted);
90
+ --toggle-track-foreground: var(--background);
91
+ --input-hover: var(--foreground);
78
92
  --divider: 217.2 32.6% 17.5%;
79
93
  --chip: 217.2 32.6% 17.5%;
80
94
  --chip-foreground: 210 40% 98%;
95
+ --disabled-opacity: 0.5;
81
96
  --chart-1: 220 70% 50%;
82
97
  --chart-2: 160 60% 45%;
83
98
  --chart-3: 30 80% 55%;
84
99
  --chart-4: 280 65% 60%;
85
100
  --chart-5: 340 75% 55%;
101
+ --chart-6: 120 55% 50%;
102
+ --chart-7: 200 75% 55%;
103
+ --chart-8: 50 80% 55%;
104
+ --chart-9: 0 70% 55%;
105
+ --chart-10: 260 65% 60%;
106
+ --chart-11: 180 60% 50%;
107
+ --chart-12: 90 55% 55%;
86
108
  }
87
109
  }
88
110
 
@@ -58,9 +58,17 @@ var optiUiPreset = {
58
58
  },
59
59
  // Border, input, ring
60
60
  border: "hsl(var(--border))",
61
- input: "hsl(var(--input))",
61
+ input: {
62
+ DEFAULT: "hsl(var(--input))",
63
+ hover: "hsl(var(--input-hover))"
64
+ },
62
65
  ring: "hsl(var(--ring))",
63
66
  divider: "hsl(var(--divider))",
67
+ // Toggle/switch track
68
+ "toggle-track": {
69
+ DEFAULT: "hsl(var(--toggle-track))",
70
+ foreground: "hsl(var(--toggle-track-foreground))"
71
+ },
64
72
  // Chip
65
73
  chip: {
66
74
  DEFAULT: "hsl(var(--chip))",
@@ -72,7 +80,14 @@ var optiUiPreset = {
72
80
  2: "hsl(var(--chart-2))",
73
81
  3: "hsl(var(--chart-3))",
74
82
  4: "hsl(var(--chart-4))",
75
- 5: "hsl(var(--chart-5))"
83
+ 5: "hsl(var(--chart-5))",
84
+ 6: "hsl(var(--chart-6))",
85
+ 7: "hsl(var(--chart-7))",
86
+ 8: "hsl(var(--chart-8))",
87
+ 9: "hsl(var(--chart-9))",
88
+ 10: "hsl(var(--chart-10))",
89
+ 11: "hsl(var(--chart-11))",
90
+ 12: "hsl(var(--chart-12))"
76
91
  }
77
92
  },
78
93
  borderRadius: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/tailwind-preset.ts"],"names":[],"mappings":";;;;;AAoBO,IAAM,YAAA,GAAgC;AAAA,EAC3C,QAAA,EAAU,CAAC,OAAO,CAAA;AAAA,EAClB,KAAA,EAAO;AAAA,IACL,MAAA,EAAQ;AAAA,MACN,MAAA,EAAQ;AAAA;AAAA,QAEN,UAAA,EAAY,wBAAA;AAAA,QACZ,UAAA,EAAY,wBAAA;AAAA;AAAA,QAGZ,IAAA,EAAM;AAAA,UACJ,OAAA,EAAS,kBAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,OAAA,EAAS;AAAA,UACP,OAAA,EAAS,qBAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,OAAA,EAAS;AAAA,UACP,OAAA,EAAS,qBAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,SAAA,EAAW;AAAA,UACT,OAAA,EAAS,uBAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,KAAA,EAAO;AAAA,UACL,OAAA,EAAS,mBAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,MAAA,EAAQ;AAAA,UACN,OAAA,EAAS,oBAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,WAAA,EAAa;AAAA,UACX,OAAA,EAAS,yBAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,OAAA,EAAS;AAAA,UACP,OAAA,EAAS,qBAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,OAAA,EAAS;AAAA,UACP,OAAA,EAAS,qBAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,MAAA,EAAQ,oBAAA;AAAA,QACR,KAAA,EAAO,mBAAA;AAAA,QACP,IAAA,EAAM,kBAAA;AAAA,QACN,OAAA,EAAS,qBAAA;AAAA;AAAA,QAGT,IAAA,EAAM;AAAA,UACJ,OAAA,EAAS,kBAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,KAAA,EAAO;AAAA,UACL,CAAA,EAAG,qBAAA;AAAA,UACH,CAAA,EAAG,qBAAA;AAAA,UACH,CAAA,EAAG,qBAAA;AAAA,UACH,CAAA,EAAG,qBAAA;AAAA,UACH,CAAA,EAAG;AAAA;AACL,OACF;AAAA,MACA,YAAA,EAAc;AAAA,QACZ,EAAA,EAAI,eAAA;AAAA,QACJ,EAAA,EAAI,2BAAA;AAAA,QACJ,EAAA,EAAI;AAAA,OACN;AAAA,MACA,SAAA,EAAW;AAAA,QACT,gBAAA,EAAkB;AAAA,UAChB,IAAA,EAAM,EAAE,MAAA,EAAQ,GAAA,EAAI;AAAA,UACpB,EAAA,EAAI,EAAE,MAAA,EAAQ,uCAAA;AAAwC,SACxD;AAAA,QACA,cAAA,EAAgB;AAAA,UACd,IAAA,EAAM,EAAE,MAAA,EAAQ,uCAAA,EAAwC;AAAA,UACxD,EAAA,EAAI,EAAE,MAAA,EAAQ,GAAA;AAAI;AACpB,OACF;AAAA,MACA,SAAA,EAAW;AAAA,QACT,gBAAA,EAAkB,8BAAA;AAAA,QAClB,cAAA,EAAgB;AAAA;AAClB;AACF,GACF;AAAA,EACA,SAAS;AACX;AAEA,IAAO,uBAAA,GAAQ","file":"tailwind-preset.cjs","sourcesContent":["import type { Config } from \"tailwindcss\";\n\n/**\n * opti-ui Tailwind CSS preset\n *\n * This preset provides the theme configuration required for opti-ui components.\n * Consumers should extend their Tailwind config with this preset.\n *\n * @example\n * // tailwind.config.js\n * import { optiUiPreset } from '@optilogic/core/tailwind-preset';\n *\n * export default {\n * presets: [optiUiPreset],\n * content: [\n * './src/**\\/*.{js,ts,jsx,tsx}',\n * './node_modules/@optilogic/core/dist/**\\/*.{js,mjs}'\n * ]\n * }\n */\nexport const optiUiPreset: Partial<Config> = {\n darkMode: [\"class\"],\n theme: {\n extend: {\n colors: {\n // Background colors\n background: \"hsl(var(--background))\",\n foreground: \"hsl(var(--foreground))\",\n\n // Card\n card: {\n DEFAULT: \"hsl(var(--card))\",\n foreground: \"hsl(var(--card-foreground))\",\n },\n\n // Popover\n popover: {\n DEFAULT: \"hsl(var(--popover))\",\n foreground: \"hsl(var(--popover-foreground))\",\n },\n\n // Primary\n primary: {\n DEFAULT: \"hsl(var(--primary))\",\n foreground: \"hsl(var(--primary-foreground))\",\n },\n\n // Secondary\n secondary: {\n DEFAULT: \"hsl(var(--secondary))\",\n foreground: \"hsl(var(--secondary-foreground))\",\n },\n\n // Muted\n muted: {\n DEFAULT: \"hsl(var(--muted))\",\n foreground: \"hsl(var(--muted-foreground))\",\n },\n\n // Accent\n accent: {\n DEFAULT: \"hsl(var(--accent))\",\n foreground: \"hsl(var(--accent-foreground))\",\n },\n\n // Destructive\n destructive: {\n DEFAULT: \"hsl(var(--destructive))\",\n foreground: \"hsl(var(--destructive-foreground))\",\n },\n\n // Success\n success: {\n DEFAULT: \"hsl(var(--success))\",\n foreground: \"hsl(var(--success-foreground))\",\n },\n\n // Warning\n warning: {\n DEFAULT: \"hsl(var(--warning))\",\n foreground: \"hsl(var(--warning-foreground))\",\n },\n\n // Border, input, ring\n border: \"hsl(var(--border))\",\n input: \"hsl(var(--input))\",\n ring: \"hsl(var(--ring))\",\n divider: \"hsl(var(--divider))\",\n\n // Chip\n chip: {\n DEFAULT: \"hsl(var(--chip))\",\n foreground: \"hsl(var(--chip-foreground))\",\n },\n\n // Chart colors\n chart: {\n 1: \"hsl(var(--chart-1))\",\n 2: \"hsl(var(--chart-2))\",\n 3: \"hsl(var(--chart-3))\",\n 4: \"hsl(var(--chart-4))\",\n 5: \"hsl(var(--chart-5))\",\n },\n },\n borderRadius: {\n lg: \"var(--radius)\",\n md: \"calc(var(--radius) - 2px)\",\n sm: \"calc(var(--radius) - 4px)\",\n },\n keyframes: {\n \"accordion-down\": {\n from: { height: \"0\" },\n to: { height: \"var(--radix-accordion-content-height)\" },\n },\n \"accordion-up\": {\n from: { height: \"var(--radix-accordion-content-height)\" },\n to: { height: \"0\" },\n },\n },\n animation: {\n \"accordion-down\": \"accordion-down 0.2s ease-out\",\n \"accordion-up\": \"accordion-up 0.2s ease-out\",\n },\n },\n },\n plugins: [],\n};\n\nexport default optiUiPreset;\n"]}
1
+ {"version":3,"sources":["../src/tailwind-preset.ts"],"names":[],"mappings":"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","file":"tailwind-preset.cjs","sourcesContent":["import type { Config } from \"tailwindcss\";\n\n/**\n * opti-ui Tailwind CSS preset\n *\n * This preset provides the theme configuration required for opti-ui components.\n * Consumers should extend their Tailwind config with this preset.\n *\n * @example\n * // tailwind.config.js\n * import { optiUiPreset } from '@optilogic/core/tailwind-preset';\n *\n * export default {\n * presets: [optiUiPreset],\n * content: [\n * './src/**\\/*.{js,ts,jsx,tsx}',\n * './node_modules/@optilogic/core/dist/**\\/*.{js,mjs}'\n * ]\n * }\n */\nexport const optiUiPreset: Partial<Config> = {\n darkMode: [\"class\"],\n theme: {\n extend: {\n colors: {\n // Background colors\n background: \"hsl(var(--background))\",\n foreground: \"hsl(var(--foreground))\",\n\n // Card\n card: {\n DEFAULT: \"hsl(var(--card))\",\n foreground: \"hsl(var(--card-foreground))\",\n },\n\n // Popover\n popover: {\n DEFAULT: \"hsl(var(--popover))\",\n foreground: \"hsl(var(--popover-foreground))\",\n },\n\n // Primary\n primary: {\n DEFAULT: \"hsl(var(--primary))\",\n foreground: \"hsl(var(--primary-foreground))\",\n },\n\n // Secondary\n secondary: {\n DEFAULT: \"hsl(var(--secondary))\",\n foreground: \"hsl(var(--secondary-foreground))\",\n },\n\n // Muted\n muted: {\n DEFAULT: \"hsl(var(--muted))\",\n foreground: \"hsl(var(--muted-foreground))\",\n },\n\n // Accent\n accent: {\n DEFAULT: \"hsl(var(--accent))\",\n foreground: \"hsl(var(--accent-foreground))\",\n },\n\n // Destructive\n destructive: {\n DEFAULT: \"hsl(var(--destructive))\",\n foreground: \"hsl(var(--destructive-foreground))\",\n },\n\n // Success\n success: {\n DEFAULT: \"hsl(var(--success))\",\n foreground: \"hsl(var(--success-foreground))\",\n },\n\n // Warning\n warning: {\n DEFAULT: \"hsl(var(--warning))\",\n foreground: \"hsl(var(--warning-foreground))\",\n },\n\n // Border, input, ring\n border: \"hsl(var(--border))\",\n input: {\n DEFAULT: \"hsl(var(--input))\",\n hover: \"hsl(var(--input-hover))\",\n },\n ring: \"hsl(var(--ring))\",\n divider: \"hsl(var(--divider))\",\n\n // Toggle/switch track\n \"toggle-track\": {\n DEFAULT: \"hsl(var(--toggle-track))\",\n foreground: \"hsl(var(--toggle-track-foreground))\",\n },\n\n // Chip\n chip: {\n DEFAULT: \"hsl(var(--chip))\",\n foreground: \"hsl(var(--chip-foreground))\",\n },\n\n // Chart colors\n chart: {\n 1: \"hsl(var(--chart-1))\",\n 2: \"hsl(var(--chart-2))\",\n 3: \"hsl(var(--chart-3))\",\n 4: \"hsl(var(--chart-4))\",\n 5: \"hsl(var(--chart-5))\",\n 6: \"hsl(var(--chart-6))\",\n 7: \"hsl(var(--chart-7))\",\n 8: \"hsl(var(--chart-8))\",\n 9: \"hsl(var(--chart-9))\",\n 10: \"hsl(var(--chart-10))\",\n 11: \"hsl(var(--chart-11))\",\n 12: \"hsl(var(--chart-12))\",\n },\n },\n borderRadius: {\n lg: \"var(--radius)\",\n md: \"calc(var(--radius) - 2px)\",\n sm: \"calc(var(--radius) - 4px)\",\n },\n keyframes: {\n \"accordion-down\": {\n from: { height: \"0\" },\n to: { height: \"var(--radix-accordion-content-height)\" },\n },\n \"accordion-up\": {\n from: { height: \"var(--radix-accordion-content-height)\" },\n to: { height: \"0\" },\n },\n },\n animation: {\n \"accordion-down\": \"accordion-down 0.2s ease-out\",\n \"accordion-up\": \"accordion-up 0.2s ease-out\",\n },\n },\n },\n plugins: [],\n};\n\nexport default optiUiPreset;\n"]}
@@ -54,9 +54,17 @@ var optiUiPreset = {
54
54
  },
55
55
  // Border, input, ring
56
56
  border: "hsl(var(--border))",
57
- input: "hsl(var(--input))",
57
+ input: {
58
+ DEFAULT: "hsl(var(--input))",
59
+ hover: "hsl(var(--input-hover))"
60
+ },
58
61
  ring: "hsl(var(--ring))",
59
62
  divider: "hsl(var(--divider))",
63
+ // Toggle/switch track
64
+ "toggle-track": {
65
+ DEFAULT: "hsl(var(--toggle-track))",
66
+ foreground: "hsl(var(--toggle-track-foreground))"
67
+ },
60
68
  // Chip
61
69
  chip: {
62
70
  DEFAULT: "hsl(var(--chip))",
@@ -68,7 +76,14 @@ var optiUiPreset = {
68
76
  2: "hsl(var(--chart-2))",
69
77
  3: "hsl(var(--chart-3))",
70
78
  4: "hsl(var(--chart-4))",
71
- 5: "hsl(var(--chart-5))"
79
+ 5: "hsl(var(--chart-5))",
80
+ 6: "hsl(var(--chart-6))",
81
+ 7: "hsl(var(--chart-7))",
82
+ 8: "hsl(var(--chart-8))",
83
+ 9: "hsl(var(--chart-9))",
84
+ 10: "hsl(var(--chart-10))",
85
+ 11: "hsl(var(--chart-11))",
86
+ 12: "hsl(var(--chart-12))"
72
87
  }
73
88
  },
74
89
  borderRadius: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/tailwind-preset.ts"],"names":[],"mappings":";AAoBO,IAAM,YAAA,GAAgC;AAAA,EAC3C,QAAA,EAAU,CAAC,OAAO,CAAA;AAAA,EAClB,KAAA,EAAO;AAAA,IACL,MAAA,EAAQ;AAAA,MACN,MAAA,EAAQ;AAAA;AAAA,QAEN,UAAA,EAAY,wBAAA;AAAA,QACZ,UAAA,EAAY,wBAAA;AAAA;AAAA,QAGZ,IAAA,EAAM;AAAA,UACJ,OAAA,EAAS,kBAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,OAAA,EAAS;AAAA,UACP,OAAA,EAAS,qBAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,OAAA,EAAS;AAAA,UACP,OAAA,EAAS,qBAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,SAAA,EAAW;AAAA,UACT,OAAA,EAAS,uBAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,KAAA,EAAO;AAAA,UACL,OAAA,EAAS,mBAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,MAAA,EAAQ;AAAA,UACN,OAAA,EAAS,oBAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,WAAA,EAAa;AAAA,UACX,OAAA,EAAS,yBAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,OAAA,EAAS;AAAA,UACP,OAAA,EAAS,qBAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,OAAA,EAAS;AAAA,UACP,OAAA,EAAS,qBAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,MAAA,EAAQ,oBAAA;AAAA,QACR,KAAA,EAAO,mBAAA;AAAA,QACP,IAAA,EAAM,kBAAA;AAAA,QACN,OAAA,EAAS,qBAAA;AAAA;AAAA,QAGT,IAAA,EAAM;AAAA,UACJ,OAAA,EAAS,kBAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,KAAA,EAAO;AAAA,UACL,CAAA,EAAG,qBAAA;AAAA,UACH,CAAA,EAAG,qBAAA;AAAA,UACH,CAAA,EAAG,qBAAA;AAAA,UACH,CAAA,EAAG,qBAAA;AAAA,UACH,CAAA,EAAG;AAAA;AACL,OACF;AAAA,MACA,YAAA,EAAc;AAAA,QACZ,EAAA,EAAI,eAAA;AAAA,QACJ,EAAA,EAAI,2BAAA;AAAA,QACJ,EAAA,EAAI;AAAA,OACN;AAAA,MACA,SAAA,EAAW;AAAA,QACT,gBAAA,EAAkB;AAAA,UAChB,IAAA,EAAM,EAAE,MAAA,EAAQ,GAAA,EAAI;AAAA,UACpB,EAAA,EAAI,EAAE,MAAA,EAAQ,uCAAA;AAAwC,SACxD;AAAA,QACA,cAAA,EAAgB;AAAA,UACd,IAAA,EAAM,EAAE,MAAA,EAAQ,uCAAA,EAAwC;AAAA,UACxD,EAAA,EAAI,EAAE,MAAA,EAAQ,GAAA;AAAI;AACpB,OACF;AAAA,MACA,SAAA,EAAW;AAAA,QACT,gBAAA,EAAkB,8BAAA;AAAA,QAClB,cAAA,EAAgB;AAAA;AAClB;AACF,GACF;AAAA,EACA,SAAS;AACX;AAEA,IAAO,uBAAA,GAAQ","file":"tailwind-preset.js","sourcesContent":["import type { Config } from \"tailwindcss\";\n\n/**\n * opti-ui Tailwind CSS preset\n *\n * This preset provides the theme configuration required for opti-ui components.\n * Consumers should extend their Tailwind config with this preset.\n *\n * @example\n * // tailwind.config.js\n * import { optiUiPreset } from '@optilogic/core/tailwind-preset';\n *\n * export default {\n * presets: [optiUiPreset],\n * content: [\n * './src/**\\/*.{js,ts,jsx,tsx}',\n * './node_modules/@optilogic/core/dist/**\\/*.{js,mjs}'\n * ]\n * }\n */\nexport const optiUiPreset: Partial<Config> = {\n darkMode: [\"class\"],\n theme: {\n extend: {\n colors: {\n // Background colors\n background: \"hsl(var(--background))\",\n foreground: \"hsl(var(--foreground))\",\n\n // Card\n card: {\n DEFAULT: \"hsl(var(--card))\",\n foreground: \"hsl(var(--card-foreground))\",\n },\n\n // Popover\n popover: {\n DEFAULT: \"hsl(var(--popover))\",\n foreground: \"hsl(var(--popover-foreground))\",\n },\n\n // Primary\n primary: {\n DEFAULT: \"hsl(var(--primary))\",\n foreground: \"hsl(var(--primary-foreground))\",\n },\n\n // Secondary\n secondary: {\n DEFAULT: \"hsl(var(--secondary))\",\n foreground: \"hsl(var(--secondary-foreground))\",\n },\n\n // Muted\n muted: {\n DEFAULT: \"hsl(var(--muted))\",\n foreground: \"hsl(var(--muted-foreground))\",\n },\n\n // Accent\n accent: {\n DEFAULT: \"hsl(var(--accent))\",\n foreground: \"hsl(var(--accent-foreground))\",\n },\n\n // Destructive\n destructive: {\n DEFAULT: \"hsl(var(--destructive))\",\n foreground: \"hsl(var(--destructive-foreground))\",\n },\n\n // Success\n success: {\n DEFAULT: \"hsl(var(--success))\",\n foreground: \"hsl(var(--success-foreground))\",\n },\n\n // Warning\n warning: {\n DEFAULT: \"hsl(var(--warning))\",\n foreground: \"hsl(var(--warning-foreground))\",\n },\n\n // Border, input, ring\n border: \"hsl(var(--border))\",\n input: \"hsl(var(--input))\",\n ring: \"hsl(var(--ring))\",\n divider: \"hsl(var(--divider))\",\n\n // Chip\n chip: {\n DEFAULT: \"hsl(var(--chip))\",\n foreground: \"hsl(var(--chip-foreground))\",\n },\n\n // Chart colors\n chart: {\n 1: \"hsl(var(--chart-1))\",\n 2: \"hsl(var(--chart-2))\",\n 3: \"hsl(var(--chart-3))\",\n 4: \"hsl(var(--chart-4))\",\n 5: \"hsl(var(--chart-5))\",\n },\n },\n borderRadius: {\n lg: \"var(--radius)\",\n md: \"calc(var(--radius) - 2px)\",\n sm: \"calc(var(--radius) - 4px)\",\n },\n keyframes: {\n \"accordion-down\": {\n from: { height: \"0\" },\n to: { height: \"var(--radix-accordion-content-height)\" },\n },\n \"accordion-up\": {\n from: { height: \"var(--radix-accordion-content-height)\" },\n to: { height: \"0\" },\n },\n },\n animation: {\n \"accordion-down\": \"accordion-down 0.2s ease-out\",\n \"accordion-up\": \"accordion-up 0.2s ease-out\",\n },\n },\n },\n plugins: [],\n};\n\nexport default optiUiPreset;\n"]}
1
+ {"version":3,"sources":["../src/tailwind-preset.ts"],"names":[],"mappings":"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","file":"tailwind-preset.js","sourcesContent":["import type { Config } from \"tailwindcss\";\n\n/**\n * opti-ui Tailwind CSS preset\n *\n * This preset provides the theme configuration required for opti-ui components.\n * Consumers should extend their Tailwind config with this preset.\n *\n * @example\n * // tailwind.config.js\n * import { optiUiPreset } from '@optilogic/core/tailwind-preset';\n *\n * export default {\n * presets: [optiUiPreset],\n * content: [\n * './src/**\\/*.{js,ts,jsx,tsx}',\n * './node_modules/@optilogic/core/dist/**\\/*.{js,mjs}'\n * ]\n * }\n */\nexport const optiUiPreset: Partial<Config> = {\n darkMode: [\"class\"],\n theme: {\n extend: {\n colors: {\n // Background colors\n background: \"hsl(var(--background))\",\n foreground: \"hsl(var(--foreground))\",\n\n // Card\n card: {\n DEFAULT: \"hsl(var(--card))\",\n foreground: \"hsl(var(--card-foreground))\",\n },\n\n // Popover\n popover: {\n DEFAULT: \"hsl(var(--popover))\",\n foreground: \"hsl(var(--popover-foreground))\",\n },\n\n // Primary\n primary: {\n DEFAULT: \"hsl(var(--primary))\",\n foreground: \"hsl(var(--primary-foreground))\",\n },\n\n // Secondary\n secondary: {\n DEFAULT: \"hsl(var(--secondary))\",\n foreground: \"hsl(var(--secondary-foreground))\",\n },\n\n // Muted\n muted: {\n DEFAULT: \"hsl(var(--muted))\",\n foreground: \"hsl(var(--muted-foreground))\",\n },\n\n // Accent\n accent: {\n DEFAULT: \"hsl(var(--accent))\",\n foreground: \"hsl(var(--accent-foreground))\",\n },\n\n // Destructive\n destructive: {\n DEFAULT: \"hsl(var(--destructive))\",\n foreground: \"hsl(var(--destructive-foreground))\",\n },\n\n // Success\n success: {\n DEFAULT: \"hsl(var(--success))\",\n foreground: \"hsl(var(--success-foreground))\",\n },\n\n // Warning\n warning: {\n DEFAULT: \"hsl(var(--warning))\",\n foreground: \"hsl(var(--warning-foreground))\",\n },\n\n // Border, input, ring\n border: \"hsl(var(--border))\",\n input: {\n DEFAULT: \"hsl(var(--input))\",\n hover: \"hsl(var(--input-hover))\",\n },\n ring: \"hsl(var(--ring))\",\n divider: \"hsl(var(--divider))\",\n\n // Toggle/switch track\n \"toggle-track\": {\n DEFAULT: \"hsl(var(--toggle-track))\",\n foreground: \"hsl(var(--toggle-track-foreground))\",\n },\n\n // Chip\n chip: {\n DEFAULT: \"hsl(var(--chip))\",\n foreground: \"hsl(var(--chip-foreground))\",\n },\n\n // Chart colors\n chart: {\n 1: \"hsl(var(--chart-1))\",\n 2: \"hsl(var(--chart-2))\",\n 3: \"hsl(var(--chart-3))\",\n 4: \"hsl(var(--chart-4))\",\n 5: \"hsl(var(--chart-5))\",\n 6: \"hsl(var(--chart-6))\",\n 7: \"hsl(var(--chart-7))\",\n 8: \"hsl(var(--chart-8))\",\n 9: \"hsl(var(--chart-9))\",\n 10: \"hsl(var(--chart-10))\",\n 11: \"hsl(var(--chart-11))\",\n 12: \"hsl(var(--chart-12))\",\n },\n },\n borderRadius: {\n lg: \"var(--radius)\",\n md: \"calc(var(--radius) - 2px)\",\n sm: \"calc(var(--radius) - 4px)\",\n },\n keyframes: {\n \"accordion-down\": {\n from: { height: \"0\" },\n to: { height: \"var(--radix-accordion-content-height)\" },\n },\n \"accordion-up\": {\n from: { height: \"var(--radix-accordion-content-height)\" },\n to: { height: \"0\" },\n },\n },\n animation: {\n \"accordion-down\": \"accordion-down 0.2s ease-out\",\n \"accordion-up\": \"accordion-up 0.2s ease-out\",\n },\n },\n },\n plugins: [],\n};\n\nexport default optiUiPreset;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optilogic/core",
3
- "version": "1.0.0-beta.9",
3
+ "version": "1.0.0",
4
4
  "description": "Core UI components for Optilogic - A professional React component library",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -63,6 +63,9 @@
63
63
  "react-day-picker": "^9.0.0",
64
64
  "react-dom": "^18.0.0 || ^19.0.0",
65
65
  "sonner": "^2.0.0",
66
+ "react-markdown": "^9.0.0",
67
+ "remark-gfm": "^4.0.0",
68
+ "shiki": "^3.0.0",
66
69
  "tailwindcss": "^3.4.0"
67
70
  },
68
71
  "peerDependenciesMeta": {
@@ -75,6 +78,15 @@
75
78
  "react-day-picker": {
76
79
  "optional": true
77
80
  },
81
+ "react-markdown": {
82
+ "optional": true
83
+ },
84
+ "remark-gfm": {
85
+ "optional": true
86
+ },
87
+ "shiki": {
88
+ "optional": true
89
+ },
78
90
  "sonner": {
79
91
  "optional": true
80
92
  }
@@ -88,6 +100,8 @@
88
100
  "react": "^19.0.0",
89
101
  "react-day-picker": "^9.13.0",
90
102
  "react-dom": "^19.0.0",
103
+ "react-markdown": "^9.0.0",
104
+ "remark-gfm": "^4.0.0",
91
105
  "tailwindcss": "^3.4.19",
92
106
  "tsup": "^8.3.5",
93
107
  "typescript": "^5.7.2"
@@ -187,8 +187,9 @@ export function Autocomplete({
187
187
  disabled={disabled}
188
188
  className={cn(
189
189
  "flex h-9 w-full items-center justify-between gap-2 whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background",
190
+ "hover:border-input-hover",
190
191
  "focus:outline-none focus:ring-1 focus:ring-ring",
191
- "disabled:cursor-not-allowed disabled:opacity-50",
192
+ "disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:border-input",
192
193
  !selectedOption && "text-muted-foreground",
193
194
  className
194
195
  )}
@@ -9,21 +9,23 @@ import { cn } from "../utils/cn";
9
9
  * Provides consistent button styling across the application.
10
10
  */
11
11
  const buttonVariants = cva(
12
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
12
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
13
13
  {
14
14
  variants: {
15
15
  variant: {
16
16
  default:
17
- "bg-muted text-muted-foreground hover:bg-accent hover:text-accent-foreground",
18
- primary: "bg-accent text-accent-foreground shadow hover:shadow-md",
17
+ "bg-muted text-foreground hover:bg-accent hover:text-accent-foreground disabled:opacity-50 disabled:text-muted-foreground",
18
+ primary:
19
+ "bg-accent text-accent-foreground shadow hover:shadow-md disabled:opacity-50",
19
20
  destructive:
20
- "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90 hover:shadow-md",
21
+ "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90 hover:shadow-md disabled:opacity-50",
21
22
  outline:
22
- "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
23
+ "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",
23
24
  secondary:
24
- "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
25
- ghost: "hover:bg-accent hover:text-accent-foreground",
26
- link: "text-primary underline-offset-4 hover:underline",
25
+ "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80 disabled:opacity-50",
26
+ ghost:
27
+ "text-foreground hover:bg-accent hover:text-accent-foreground disabled:text-muted-foreground disabled:bg-muted/30 disabled:opacity-70",
28
+ link: "text-primary underline-offset-4 hover:underline disabled:opacity-50 disabled:text-muted-foreground",
27
29
  },
28
30
  size: {
29
31
  default: "h-9 px-4 py-2",
@@ -125,19 +125,19 @@ function Calendar({
125
125
  className={cn("p-3", className)}
126
126
  classNames={{
127
127
  months: "flex flex-col sm:flex-row gap-4",
128
- month: "flex flex-col gap-4",
129
- month_caption: "flex justify-center pt-1 relative items-center h-7 px-10",
128
+ month: "flex flex-col gap-2 relative px-8",
129
+ month_caption: "flex justify-center pt-1 items-center h-7",
130
130
  caption_label: "text-sm font-medium hidden",
131
131
  nav: "flex items-center gap-1",
132
132
  button_previous: cn(
133
133
  buttonVariants({ variant: "outline" }),
134
- "absolute left-1 h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 z-10"
134
+ "absolute left-1 top-1/2 -translate-y-1/2 h-6 w-6 bg-transparent p-0 opacity-50 hover:opacity-100 z-10"
135
135
  ),
136
136
  button_next: cn(
137
137
  buttonVariants({ variant: "outline" }),
138
- "absolute right-1 h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100 z-10"
138
+ "absolute right-1 top-1/2 -translate-y-1/2 h-6 w-6 bg-transparent p-0 opacity-50 hover:opacity-100 z-10"
139
139
  ),
140
- month_grid: "w-full border-collapse px-1",
140
+ month_grid: "border-collapse mx-auto",
141
141
  weekdays: "flex",
142
142
  weekday:
143
143
  "text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
@@ -168,14 +168,14 @@ function Calendar({
168
168
  components={{
169
169
  Chevron: ({ orientation }) => {
170
170
  const Icon = orientation === "left" ? ChevronLeft : ChevronRight;
171
- return <Icon className="h-4 w-4" />;
171
+ return <Icon className="h-3.5 w-3.5" />;
172
172
  },
173
173
  MonthCaption: ({ calendarMonth }) => {
174
174
  const month = calendarMonth.date.getMonth();
175
175
  const year = calendarMonth.date.getFullYear();
176
176
 
177
177
  return (
178
- <div className="flex items-center justify-center gap-1 px-10">
178
+ <div className="flex items-center justify-center gap-1">
179
179
  <Select
180
180
  value={month.toString()}
181
181
  onValueChange={(value) => {
@@ -182,7 +182,7 @@ export function DataGrid<T = Record<string, CellValue>>({
182
182
  );
183
183
 
184
184
  // Use data grid state hook
185
- const { state, actions, isControlled } = useDataGridState({
185
+ const { state, actions, processedDataRef, isControlled } = useDataGridState({
186
186
  sorting: controlledSorting,
187
187
  filters: controlledFilters,
188
188
  columnWidths: controlledColumnWidths,
@@ -229,6 +229,9 @@ export function DataGrid<T = Record<string, CellValue>>({
229
229
  visibleColumns,
230
230
  ]);
231
231
 
232
+ // Keep the state hook's ref in sync so editing resolves the correct row
233
+ processedDataRef.current = processedData;
234
+
232
235
  // Use column resize manager
233
236
  const { resizingColumn, getResizeProps } = useColumnResizeManager({
234
237
  columns: visibleColumns,
@@ -671,6 +674,7 @@ export function DataGrid<T = Record<string, CellValue>>({
671
674
  "flex-shrink-0 px-3 py-2 text-sm overflow-hidden",
672
675
  showColumnBorders && "border-r border-border last:border-r-0",
673
676
  isFocused && !isEditingThisCell && "ring-2 ring-inset ring-primary",
677
+ isEditingThisCell && "ring-2 ring-inset ring-primary bg-background",
674
678
  column.align === "center" && "text-center",
675
679
  column.align === "right" && "text-right"
676
680
  )}
@@ -864,6 +868,7 @@ export function DataGrid<T = Record<string, CellValue>>({
864
868
  "flex-shrink-0 px-3 py-2 text-sm overflow-hidden",
865
869
  showColumnBorders && "border-r border-border last:border-r-0",
866
870
  isFocused && !isEditingThisCell && "ring-2 ring-inset ring-primary",
871
+ isEditingThisCell && "ring-2 ring-inset ring-primary bg-background",
867
872
  column.align === "center" && "text-center",
868
873
  column.align === "right" && "text-right"
869
874
  )}
@@ -147,7 +147,7 @@ export function CellEditor<T = Record<string, CellValue>>({
147
147
  onKeyDown={handleKeyDown}
148
148
  onBlur={handleBlur}
149
149
  className={cn(
150
- "h-full w-full border-0 rounded-none focus:ring-2 focus:ring-primary text-sm px-2",
150
+ "h-full w-full border-0 rounded-none bg-background focus:ring-0 text-sm px-2",
151
151
  validationError && "ring-2 ring-destructive focus:ring-destructive",
152
152
  className
153
153
  )}
@@ -165,7 +165,7 @@ export function CellEditor<T = Record<string, CellValue>>({
165
165
  onKeyDown={handleKeyDown}
166
166
  onBlur={handleBlur}
167
167
  className={cn(
168
- "h-full w-full border-0 rounded-none focus:ring-2 focus:ring-primary text-sm px-2",
168
+ "h-full w-full border-0 rounded-none bg-background focus:ring-0 text-sm px-2",
169
169
  validationError && "ring-2 ring-destructive focus:ring-destructive",
170
170
  className
171
171
  )}
@@ -234,7 +234,7 @@ export function CellEditor<T = Record<string, CellValue>>({
234
234
  <SelectTrigger
235
235
  ref={selectRef}
236
236
  className={cn(
237
- "h-full w-full border-0 rounded-none focus:ring-2 focus:ring-primary text-sm",
237
+ "h-full w-full border-0 rounded-none bg-background focus:ring-0 text-sm",
238
238
  validationError && "ring-2 ring-destructive focus:ring-destructive",
239
239
  className
240
240
  )}
@@ -6,7 +6,7 @@
6
6
  * cell focus, and cell editing.
7
7
  */
8
8
 
9
- import { useState, useCallback, useMemo, useRef, useEffect } from "react";
9
+ import { useState, useCallback, useMemo, useRef, useEffect, type MutableRefObject } from "react";
10
10
  import type {
11
11
  SortConfig,
12
12
  FilterConfig,
@@ -64,6 +64,8 @@ export interface UseDataGridStateReturn {
64
64
  commitEdit: (value?: CellValue) => void;
65
65
  cancelEdit: () => void;
66
66
  };
67
+ /** Ref that DataGrid should populate with the current processedData array */
68
+ processedDataRef: MutableRefObject<unknown[]>;
67
69
  isControlled: {
68
70
  sorting: boolean;
69
71
  filters: boolean;
@@ -126,6 +128,10 @@ export function useDataGridState<T = Record<string, CellValue>>(
126
128
  useState<CellPosition | null>(null);
127
129
  const [editingCell, setEditingCell] = useState<EditingCell | null>(null);
128
130
 
131
+ // Ref populated by DataGrid with the current sorted/filtered data.
132
+ // Editing callbacks read from this so they resolve the correct row after sort/filter.
133
+ const processedDataRef = useRef<unknown[]>([]);
134
+
129
135
  const sorting = isControlled.sorting ? controlledSorting! : internalSorting;
130
136
  const filters = isControlled.filters ? controlledFilters! : internalFilters;
131
137
  const focusedCell = isControlled.focusedCell
@@ -276,7 +282,12 @@ export function useDataGridState<T = Record<string, CellValue>>(
276
282
  const column = columns.find((c) => c.key === columnKey);
277
283
  if (!column || !column.editable) return;
278
284
 
279
- const row = data[rowIndex];
285
+ // Use processedData (sorted/filtered) so the rowIndex maps to the
286
+ // correct visual row, falling back to the raw data array.
287
+ const resolvedData = processedDataRef.current.length > 0
288
+ ? processedDataRef.current
289
+ : data;
290
+ const row = resolvedData[rowIndex] as T | undefined;
280
291
  if (!row) return;
281
292
 
282
293
  const value = getCellValue(row, column);
@@ -305,7 +316,10 @@ export function useDataGridState<T = Record<string, CellValue>>(
305
316
 
306
317
  const column = columns.find((c) => c.key === columnKey);
307
318
  if (column?.validator) {
308
- const row = data[rowIndex];
319
+ const resolvedData = processedDataRef.current.length > 0
320
+ ? processedDataRef.current
321
+ : data;
322
+ const row = resolvedData[rowIndex] as T;
309
323
  const validationResult = column.validator(value, row);
310
324
  if (validationResult !== true && typeof validationResult === "string") {
311
325
  return;
@@ -341,6 +355,7 @@ export function useDataGridState<T = Record<string, CellValue>>(
341
355
  commitEdit,
342
356
  cancelEdit,
343
357
  },
358
+ processedDataRef,
344
359
  isControlled,
345
360
  };
346
361
  }
@@ -137,6 +137,10 @@ export interface ColumnDef<T = Record<string, CellValue>> {
137
137
  /** Accessor function to get cell value (defaults to row[key]) */
138
138
  accessor?: (row: T) => CellValue;
139
139
 
140
+ // Data type
141
+ /** Data type hint for sorting/comparison (auto-detected from values if omitted) */
142
+ dataType?: "string" | "number" | "date" | "boolean";
143
+
140
144
  // Sorting
141
145
  /** Whether this column is sortable */
142
146
  sortable?: boolean;
@@ -59,20 +59,49 @@ export function applySorting<T>(
59
59
  if (aVal == null) return sort.direction === "asc" ? 1 : -1;
60
60
  if (bVal == null) return sort.direction === "asc" ? -1 : 1;
61
61
 
62
- // Compare based on type
63
62
  let comparison = 0;
64
63
 
65
- if (typeof aVal === "string" && typeof bVal === "string") {
66
- comparison = aVal.localeCompare(bVal);
67
- } else if (typeof aVal === "number" && typeof bVal === "number") {
68
- comparison = aVal - bVal;
69
- } else if (aVal instanceof Date && bVal instanceof Date) {
70
- comparison = aVal.getTime() - bVal.getTime();
71
- } else if (typeof aVal === "boolean" && typeof bVal === "boolean") {
72
- comparison = aVal === bVal ? 0 : aVal ? 1 : -1;
73
- } else {
74
- // Fallback: convert to string
64
+ // If column specifies a dataType, coerce values accordingly
65
+ if (column.dataType === "number") {
66
+ const aNum = Number(aVal);
67
+ const bNum = Number(bVal);
68
+ if (!isNaN(aNum) && !isNaN(bNum)) {
69
+ comparison = aNum - bNum;
70
+ } else {
71
+ comparison = String(aVal).localeCompare(String(bVal));
72
+ }
73
+ } else if (column.dataType === "date") {
74
+ const aDate = aVal instanceof Date ? aVal : new Date(aVal as string | number);
75
+ const bDate = bVal instanceof Date ? bVal : new Date(bVal as string | number);
76
+ const aTime = isNaN(aDate.getTime()) ? 0 : aDate.getTime();
77
+ const bTime = isNaN(bDate.getTime()) ? 0 : bDate.getTime();
78
+ comparison = aTime - bTime;
79
+ } else if (column.dataType === "boolean") {
80
+ const aBool = aVal === true || aVal === "true" || aVal === 1;
81
+ const bBool = bVal === true || bVal === "true" || bVal === 1;
82
+ comparison = aBool === bBool ? 0 : aBool ? 1 : -1;
83
+ } else if (column.dataType === "string") {
75
84
  comparison = String(aVal).localeCompare(String(bVal));
85
+ } else {
86
+ // No dataType specified -- auto-detect from runtime types
87
+ if (typeof aVal === "number" && typeof bVal === "number") {
88
+ comparison = aVal - bVal;
89
+ } else if (aVal instanceof Date && bVal instanceof Date) {
90
+ comparison = aVal.getTime() - bVal.getTime();
91
+ } else if (typeof aVal === "boolean" && typeof bVal === "boolean") {
92
+ comparison = aVal === bVal ? 0 : aVal ? 1 : -1;
93
+ } else {
94
+ // Try numeric parse (handles string-encoded numbers from SQL results etc.)
95
+ const aStr = String(aVal);
96
+ const bStr = String(bVal);
97
+ const aNum = Number(aStr);
98
+ const bNum = Number(bStr);
99
+ if (!isNaN(aNum) && !isNaN(bNum) && aStr !== "" && bStr !== "") {
100
+ comparison = aNum - bNum;
101
+ } else {
102
+ comparison = aStr.localeCompare(bStr);
103
+ }
104
+ }
76
105
  }
77
106
 
78
107
  return sort.direction === "asc" ? comparison : -comparison;
@@ -304,8 +304,9 @@ function DatePickerInput({
304
304
  <div
305
305
  className={cn(
306
306
  "flex items-center rounded-md border border-input bg-background ring-offset-background",
307
+ "hover:border-input-hover",
307
308
  "focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2",
308
- disabled && "opacity-50 cursor-not-allowed",
309
+ disabled && "opacity-50 cursor-not-allowed hover:border-input",
309
310
  sizeClasses[size]
310
311
  )}
311
312
  >
@@ -73,7 +73,7 @@ const DropdownMenuContent = React.forwardRef<
73
73
  ref={ref}
74
74
  sideOffset={sideOffset}
75
75
  className={cn(
76
- "z-50 min-w-[8rem] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md",
76
+ "z-50 min-w-[8rem] max-w-[90vw] overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md",
77
77
  "data-[state=open]:animate-in data-[state=closed]:animate-out",
78
78
  "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
79
79
  "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",