@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.
- package/dist/index.cjs +1115 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +326 -1
- package/dist/index.d.ts +326 -1
- package/dist/index.js +1097 -46
- package/dist/index.js.map +1 -1
- package/dist/styles.css +22 -0
- package/dist/tailwind-preset.cjs +17 -2
- package/dist/tailwind-preset.cjs.map +1 -1
- package/dist/tailwind-preset.js +17 -2
- package/dist/tailwind-preset.js.map +1 -1
- package/package.json +15 -1
- package/src/components/autocomplete.tsx +2 -1
- package/src/components/button.tsx +10 -8
- package/src/components/calendar.tsx +7 -7
- package/src/components/data-grid/DataGrid.tsx +6 -1
- package/src/components/data-grid/components/CellEditor.tsx +3 -3
- package/src/components/data-grid/hooks/useDataGridState.ts +18 -3
- package/src/components/data-grid/types.ts +4 -0
- package/src/components/data-grid/utils/dataProcessing.ts +40 -11
- package/src/components/date-picker.tsx +2 -1
- package/src/components/dropdown-menu.tsx +1 -1
- package/src/components/file-view/FileView.tsx +147 -0
- package/src/components/file-view/components/CodeRenderer.tsx +97 -0
- package/src/components/file-view/components/CsvRenderer.tsx +127 -0
- package/src/components/file-view/components/HtmlRenderer.tsx +24 -0
- package/src/components/file-view/components/ImageRenderer.tsx +67 -0
- package/src/components/file-view/components/MarkdownRenderer.tsx +304 -0
- package/src/components/file-view/components/PlainTextRenderer.tsx +27 -0
- package/src/components/file-view/components/index.ts +4 -0
- package/src/components/file-view/hooks/index.ts +5 -0
- package/src/components/file-view/hooks/useContentType.ts +34 -0
- package/src/components/file-view/hooks/useDarkMode.ts +62 -0
- package/src/components/file-view/hooks/useHighlightedTokens.ts +83 -0
- package/src/components/file-view/hooks/useShikiHighlighter.ts +69 -0
- package/src/components/file-view/index.ts +47 -0
- package/src/components/file-view/types.ts +180 -0
- package/src/components/file-view/utils/contentTypeDetection.ts +157 -0
- package/src/components/file-view/utils/index.ts +12 -0
- package/src/components/file-view/utils/languageMapping.ts +78 -0
- package/src/components/file-view/utils/rendererRegistry.ts +42 -0
- package/src/components/input.tsx +1 -1
- package/src/components/popover.tsx +1 -1
- package/src/components/select.tsx +1 -1
- package/src/components/switch.tsx +5 -3
- package/src/components/textarea.tsx +1 -1
- package/src/index.ts +39 -0
- package/src/styles.css +22 -0
- package/src/tailwind-preset.ts +17 -1
- package/src/theme/index.ts +5 -0
- package/src/theme/presets.ts +112 -2
- package/src/theme/types.ts +35 -0
- 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
|
|
package/dist/tailwind-preset.cjs
CHANGED
|
@@ -58,9 +58,17 @@ var optiUiPreset = {
|
|
|
58
58
|
},
|
|
59
59
|
// Border, input, ring
|
|
60
60
|
border: "hsl(var(--border))",
|
|
61
|
-
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,
|
|
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"]}
|
package/dist/tailwind-preset.js
CHANGED
|
@@ -54,9 +54,17 @@ var optiUiPreset = {
|
|
|
54
54
|
},
|
|
55
55
|
// Border, input, ring
|
|
56
56
|
border: "hsl(var(--border))",
|
|
57
|
-
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,
|
|
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
|
|
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
|
|
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-
|
|
18
|
-
primary:
|
|
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:
|
|
26
|
-
|
|
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-
|
|
129
|
-
month_caption: "flex justify-center pt-1
|
|
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-
|
|
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-
|
|
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: "
|
|
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-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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",
|