@optilogic/core 1.3.5 → 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/styles.css CHANGED
@@ -45,6 +45,7 @@
45
45
  --toggle-track: 0 0% 82%;
46
46
  --toggle-track-foreground: 0 0% 100%;
47
47
  --input-hover: 234 86% 67%;
48
+ --hover: 243 82% 20% / 0.12;
48
49
  --divider: 0 0% 82%;
49
50
  --chip: 227 88% 85%;
50
51
  --chip-foreground: 243 82% 20%;
@@ -93,6 +94,7 @@
93
94
  --toggle-track: 240 4% 26%;
94
95
  --toggle-track-foreground: 0 0% 98%;
95
96
  --input-hover: 217 91% 60%;
97
+ --hover: 217 91% 60% / 0.12;
96
98
  --divider: 240 4% 26%;
97
99
  --chip: 240 4% 16%;
98
100
  --chip-foreground: 240 5% 83%;
@@ -41,6 +41,11 @@ var optiUiPreset = {
41
41
  DEFAULT: "hsl(var(--accent))",
42
42
  foreground: "hsl(var(--accent-foreground))"
43
43
  },
44
+ // Universal theme-aware hover tint. The --hover variable holds HSL
45
+ // channels with alpha (e.g. "243 82% 20% / 0.12"), so themes can
46
+ // override both color and alpha. Defaults to primary @ 12% via inference
47
+ // in applyTheme, with foreground fallback when primary lacks contrast.
48
+ hover: "hsl(var(--hover))",
44
49
  // Destructive
45
50
  destructive: {
46
51
  DEFAULT: "hsl(var(--destructive))",
@@ -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,gBAAA,EAAkB,4BAAA;AAAA,QAClB,KAAA,EAAO;AAAA,UACL,OAAA,EAAS,mBAAA;AAAA,UACT,KAAA,EAAO;AAAA,SACT;AAAA,QACA,IAAA,EAAM,kBAAA;AAAA,QACN,OAAA,EAAS,qBAAA;AAAA;AAAA,QAGT,cAAA,EAAgB;AAAA,UACd,OAAA,EAAS,0BAAA;AAAA,UACT,UAAA,EAAY;AAAA,SACd;AAAA;AAAA,QAGA,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,qBAAA;AAAA,UACH,CAAA,EAAG,qBAAA;AAAA,UACH,CAAA,EAAG,qBAAA;AAAA,UACH,CAAA,EAAG,qBAAA;AAAA,UACH,CAAA,EAAG,qBAAA;AAAA,UACH,EAAA,EAAI,sBAAA;AAAA,UACJ,EAAA,EAAI,sBAAA;AAAA,UACJ,EAAA,EAAI;AAAA;AACN,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 \"popover-border\": \"hsl(var(--popover-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"]}
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 // Universal theme-aware hover tint. The --hover variable holds HSL\n // channels with alpha (e.g. \"243 82% 20% / 0.12\"), so themes can\n // override both color and alpha. Defaults to primary @ 12% via inference\n // in applyTheme, with foreground fallback when primary lacks contrast.\n hover: \"hsl(var(--hover))\",\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 \"popover-border\": \"hsl(var(--popover-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"]}
@@ -37,6 +37,11 @@ var optiUiPreset = {
37
37
  DEFAULT: "hsl(var(--accent))",
38
38
  foreground: "hsl(var(--accent-foreground))"
39
39
  },
40
+ // Universal theme-aware hover tint. The --hover variable holds HSL
41
+ // channels with alpha (e.g. "243 82% 20% / 0.12"), so themes can
42
+ // override both color and alpha. Defaults to primary @ 12% via inference
43
+ // in applyTheme, with foreground fallback when primary lacks contrast.
44
+ hover: "hsl(var(--hover))",
40
45
  // Destructive
41
46
  destructive: {
42
47
  DEFAULT: "hsl(var(--destructive))",
@@ -1 +1 @@
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 \"popover-border\": \"hsl(var(--popover-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"]}
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 // Universal theme-aware hover tint. The --hover variable holds HSL\n // channels with alpha (e.g. \"243 82% 20% / 0.12\"), so themes can\n // override both color and alpha. Defaults to primary @ 12% via inference\n // in applyTheme, with foreground fallback when primary lacks contrast.\n hover: \"hsl(var(--hover))\",\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 \"popover-border\": \"hsl(var(--popover-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.3.5",
3
+ "version": "1.3.6",
4
4
  "description": "Core UI components for Optilogic - A professional React component library",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -37,10 +37,10 @@ const accordionTriggerVariants = cva(
37
37
  variants: {
38
38
  variant: {
39
39
  default: "hover:text-foreground/80",
40
- bordered: "px-4 hover:bg-muted/50",
41
- card: "px-4 hover:bg-muted/30",
42
- filled: "px-4 hover:bg-muted",
43
- ghost: "px-2 rounded-md hover:bg-muted/50",
40
+ bordered: "px-4 hover:bg-hover",
41
+ card: "px-4 hover:bg-hover",
42
+ filled: "px-4 hover:bg-hover",
43
+ ghost: "px-2 rounded-md hover:bg-hover",
44
44
  },
45
45
  },
46
46
  defaultVariants: {
@@ -156,8 +156,8 @@ export function Autocomplete({
156
156
  onClick={() => handleSelect(option.value)}
157
157
  className={cn(
158
158
  "relative flex w-full cursor-pointer select-none items-start gap-2 rounded-sm px-2 py-1.5 text-sm outline-none",
159
- "hover:bg-accent hover:text-accent-foreground",
160
- "focus:bg-accent focus:text-accent-foreground",
159
+ "hover:bg-hover",
160
+ "focus:bg-hover",
161
161
  option.disabled && "pointer-events-none opacity-50",
162
162
  value === option.value && "bg-accent/50"
163
163
  )}
@@ -203,7 +203,7 @@ export function Autocomplete({
203
203
  role="button"
204
204
  tabIndex={-1}
205
205
  onClick={handleClear}
206
- className="rounded-sm hover:bg-muted p-0.5"
206
+ className="rounded-sm hover:bg-hover p-0.5"
207
207
  >
208
208
  <X className="h-3.5 w-3.5 text-muted-foreground" />
209
209
  </span>
@@ -232,7 +232,7 @@ export function Autocomplete({
232
232
  <button
233
233
  type="button"
234
234
  onClick={() => setSearch("")}
235
- className="p-1 hover:bg-muted rounded-sm"
235
+ className="p-1 hover:bg-hover rounded-sm"
236
236
  >
237
237
  <X className="h-3.5 w-3.5 text-muted-foreground" />
238
238
  </button>
@@ -14,17 +14,17 @@ const buttonVariants = cva(
14
14
  variants: {
15
15
  variant: {
16
16
  default:
17
- "bg-muted text-foreground hover:bg-accent hover:text-accent-foreground disabled:opacity-50 disabled:text-muted-foreground",
17
+ "bg-muted text-foreground hover:bg-hover disabled:opacity-50 disabled:text-muted-foreground",
18
18
  primary:
19
19
  "bg-accent text-accent-foreground shadow hover:shadow-md disabled:opacity-50",
20
20
  destructive:
21
21
  "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90 hover:shadow-md disabled:opacity-50",
22
22
  outline:
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
+ "border border-input bg-background shadow-sm hover:bg-hover disabled:opacity-50 disabled:bg-muted/20 disabled:text-muted-foreground",
24
24
  secondary:
25
25
  "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80 disabled:opacity-50",
26
26
  ghost:
27
- "text-foreground hover:bg-accent hover:text-accent-foreground disabled:text-muted-foreground disabled:bg-muted/30 disabled:opacity-70",
27
+ "text-foreground hover:bg-hover disabled:text-muted-foreground disabled:bg-muted/30 disabled:opacity-70",
28
28
  link: "text-primary underline-offset-4 hover:underline disabled:opacity-50 disabled:text-muted-foreground",
29
29
  },
30
30
  size: {
@@ -190,7 +190,7 @@ function Calendar({
190
190
  }}
191
191
  >
192
192
  <SelectTrigger
193
- className="h-7 w-[110px] text-sm font-medium border-none shadow-none hover:bg-accent focus:ring-0 px-2"
193
+ className="h-7 w-[110px] text-sm font-medium border-none shadow-none hover:bg-hover focus:ring-0 px-2"
194
194
  aria-label="Select month"
195
195
  >
196
196
  <SelectValue>{MONTHS[month]}</SelectValue>
@@ -213,7 +213,7 @@ function Calendar({
213
213
  }}
214
214
  >
215
215
  <SelectTrigger
216
- className="h-7 w-[70px] text-sm font-medium border-none shadow-none hover:bg-accent focus:ring-0 px-2"
216
+ className="h-7 w-[70px] text-sm font-medium border-none shadow-none hover:bg-hover focus:ring-0 px-2"
217
217
  aria-label="Select year"
218
218
  >
219
219
  <SelectValue>{year}</SelectValue>
@@ -59,8 +59,7 @@ export function Chip({
59
59
  // Clickable state
60
60
  isClickable && [
61
61
  "cursor-pointer",
62
- "hover:bg-accent hover:text-accent-foreground",
63
- "hover:border-accent",
62
+ "hover:bg-hover",
64
63
  "hover:shadow-md",
65
64
  ],
66
65
  // Non-clickable state
@@ -225,8 +225,8 @@ export function Combobox({
225
225
  onClick={() => handleSelect(option.value)}
226
226
  className={cn(
227
227
  "relative flex w-full cursor-pointer select-none items-start gap-2 rounded-sm px-2 py-1.5 text-sm outline-none",
228
- "hover:bg-accent hover:text-accent-foreground",
229
- "focus:bg-accent focus:text-accent-foreground",
228
+ "hover:bg-hover",
229
+ "focus:bg-hover",
230
230
  option.disabled && "pointer-events-none opacity-50",
231
231
  value === option.value && "bg-accent/50"
232
232
  )}
@@ -282,7 +282,7 @@ export function Combobox({
282
282
  tabIndex={-1}
283
283
  onMouseDown={(e) => e.preventDefault()}
284
284
  onClick={handleClear}
285
- className="rounded-sm hover:bg-muted p-0.5"
285
+ className="rounded-sm hover:bg-hover p-0.5"
286
286
  >
287
287
  <X className="h-3.5 w-3.5 text-muted-foreground" />
288
288
  </span>
@@ -183,10 +183,10 @@ function MenuItem({ item, onClose, depth = 0 }: MenuItemProps) {
183
183
  className={cn(
184
184
  "w-full flex items-center gap-3 px-3 py-2 text-sm rounded-sm",
185
185
  "transition-colors text-left",
186
- "focus:outline-none focus:bg-accent focus:text-accent-foreground",
186
+ "focus:outline-none focus:bg-hover",
187
187
  item.disabled
188
188
  ? "opacity-50 cursor-not-allowed text-muted-foreground"
189
- : "hover:bg-accent hover:text-accent-foreground cursor-pointer",
189
+ : "hover:bg-hover cursor-pointer",
190
190
  item.destructive &&
191
191
  !item.disabled &&
192
192
  "text-destructive hover:text-destructive"
@@ -671,7 +671,7 @@ export function DataGrid<T = Record<string, CellValue>>({
671
671
  "absolute top-0 left-0 transition-colors border-b border-border",
672
672
  onRowClick && "cursor-pointer",
673
673
  isSelected && "bg-accent/20",
674
- !isSelected && "hover:bg-muted/50",
674
+ !isSelected && "hover:bg-hover",
675
675
  rowClassName && rowClassName(row, virtualRow.index)
676
676
  )}
677
677
  style={{
@@ -899,7 +899,7 @@ export function DataGrid<T = Record<string, CellValue>>({
899
899
  "flex border-b border-border transition-colors",
900
900
  onRowClick && "cursor-pointer",
901
901
  isSelected && "bg-accent/20",
902
- !isSelected && "hover:bg-muted/50",
902
+ !isSelected && "hover:bg-hover",
903
903
  rowClassName && rowClassName(row, rowIndex)
904
904
  )}
905
905
  style={{ width: tableWidth ? `${tableWidth}px` : "100%" }}
@@ -115,7 +115,7 @@ export function HeaderCell<T = any>({
115
115
  className={cn(
116
116
  "flex items-center gap-1 px-3 py-2 h-full",
117
117
  isResizable && "pr-6", // Extra padding to create space for resize handle
118
- isSortable && "cursor-pointer hover:bg-accent/10",
118
+ isSortable && "cursor-pointer hover:bg-hover",
119
119
  column.align === "center" && "justify-center",
120
120
  column.align === "right" && "justify-end"
121
121
  )}
@@ -186,7 +186,7 @@ export function HeaderCell<T = any>({
186
186
  className={cn(
187
187
  "absolute top-0 right-0 w-4 h-full cursor-col-resize z-10",
188
188
  "flex items-center justify-center",
189
- "hover:bg-accent/50 transition-colors",
189
+ "hover:bg-hover transition-colors",
190
190
  "group",
191
191
  isResizing && "bg-accent"
192
192
  )}
@@ -29,7 +29,7 @@ const DropdownMenuSubTrigger = React.forwardRef<
29
29
  ref={ref}
30
30
  className={cn(
31
31
  "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none",
32
- "focus:bg-accent",
32
+ "focus:bg-hover",
33
33
  "data-[state=open]:bg-accent",
34
34
  inset && "pl-8",
35
35
  className
@@ -101,7 +101,7 @@ const DropdownMenuItem = React.forwardRef<
101
101
  ref={ref}
102
102
  className={cn(
103
103
  "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors",
104
- "focus:bg-accent focus:text-accent-foreground",
104
+ "focus:bg-hover",
105
105
  "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
106
106
  inset && "pl-8",
107
107
  destructive && "text-destructive focus:text-destructive",
@@ -120,7 +120,7 @@ const DropdownMenuCheckboxItem = React.forwardRef<
120
120
  ref={ref}
121
121
  className={cn(
122
122
  "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors",
123
- "focus:bg-accent focus:text-accent-foreground",
123
+ "focus:bg-hover",
124
124
  "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
125
125
  className
126
126
  )}
@@ -146,7 +146,7 @@ const DropdownMenuRadioItem = React.forwardRef<
146
146
  ref={ref}
147
147
  className={cn(
148
148
  "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors",
149
- "focus:bg-accent focus:text-accent-foreground",
149
+ "focus:bg-hover",
150
150
  "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
151
151
  className
152
152
  )}
@@ -33,7 +33,7 @@ function DefaultErrorState({ error }: { error: FileViewError }) {
33
33
  onClick={error.onRetry}
34
34
  className={cn(
35
35
  "rounded-md border border-border bg-background px-3 py-1.5 text-sm text-foreground",
36
- "transition-colors hover:bg-muted",
36
+ "transition-colors hover:bg-hover",
37
37
  )}
38
38
  >
39
39
  Retry
@@ -29,41 +29,41 @@ const iconButtonVariants = cva(
29
29
  variants: {
30
30
  variant: {
31
31
  /**
32
- * Default - subtle background with accent on hover
32
+ * Default - subtle hover tint
33
33
  */
34
34
  default: [
35
35
  "bg-transparent text-muted-foreground",
36
- "hover:bg-accent hover:text-accent-foreground",
36
+ "hover:bg-hover",
37
37
  "border border-transparent",
38
38
  ],
39
39
  /**
40
- * Ghost - no background, accent on hover
40
+ * Ghost - no background, subtle hover tint
41
41
  */
42
42
  ghost: [
43
43
  "bg-transparent text-muted-foreground",
44
- "hover:bg-accent hover:text-accent-foreground",
44
+ "hover:bg-hover",
45
45
  ],
46
46
  /**
47
- * Outline - border with accent on hover
47
+ * Outline - bordered, subtle hover tint
48
48
  */
49
49
  outline: [
50
50
  "bg-transparent text-muted-foreground",
51
51
  "border border-border",
52
- "hover:bg-accent hover:text-accent-foreground hover:border-accent",
52
+ "hover:bg-hover",
53
53
  ],
54
54
  /**
55
- * Filled - accent background
55
+ * Filled - accent background (branded; darkens on hover)
56
56
  */
57
57
  filled: [
58
58
  "bg-accent text-accent-foreground",
59
59
  "hover:bg-accent/90 hover:shadow-sm",
60
60
  ],
61
61
  /**
62
- * Muted - muted background with accent on hover
62
+ * Muted - muted background with subtle hover tint
63
63
  */
64
64
  muted: [
65
65
  "bg-muted text-muted-foreground",
66
- "hover:bg-accent hover:text-accent-foreground",
66
+ "hover:bg-hover",
67
67
  ],
68
68
  },
69
69
  size: {
@@ -203,7 +203,7 @@ export function MultiSelect({
203
203
  onClick={() => handleToggle(option.value)}
204
204
  className={cn(
205
205
  "relative flex w-full cursor-pointer select-none items-start gap-2 rounded-sm px-2 py-1.5 text-sm outline-none",
206
- "hover:bg-accent hover:text-accent-foreground",
206
+ "hover:bg-hover",
207
207
  option.disabled && "pointer-events-none opacity-50"
208
208
  )}
209
209
  >
@@ -255,7 +255,7 @@ export function MultiSelect({
255
255
  role="button"
256
256
  tabIndex={-1}
257
257
  onClick={(e) => handleRemove(safeValue[i]!, e)}
258
- className="rounded-sm hover:bg-foreground/10 p-0.5"
258
+ className="rounded-sm hover:bg-hover p-0.5"
259
259
  >
260
260
  <X className="h-3 w-3" />
261
261
  </span>
@@ -275,7 +275,7 @@ export function MultiSelect({
275
275
  role="button"
276
276
  tabIndex={-1}
277
277
  onClick={handleClearAll}
278
- className="rounded-sm hover:bg-muted p-0.5"
278
+ className="rounded-sm hover:bg-hover p-0.5"
279
279
  >
280
280
  <X className="h-3.5 w-3.5 text-muted-foreground" />
281
281
  </span>
@@ -304,7 +304,7 @@ export function MultiSelect({
304
304
  <button
305
305
  type="button"
306
306
  onClick={() => setSearch("")}
307
- className="p-1 hover:bg-muted rounded-sm"
307
+ className="p-1 hover:bg-hover rounded-sm"
308
308
  >
309
309
  <X className="h-3.5 w-3.5 text-muted-foreground" />
310
310
  </button>
@@ -321,7 +321,7 @@ export function MultiSelect({
321
321
  onClick={handleSelectAll}
322
322
  className={cn(
323
323
  "relative flex w-full cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none",
324
- "hover:bg-accent hover:text-accent-foreground"
324
+ "hover:bg-hover"
325
325
  )}
326
326
  >
327
327
  <Checkbox
@@ -119,7 +119,7 @@ const SelectItem = React.forwardRef<
119
119
  <SelectPrimitive.Item
120
120
  ref={ref}
121
121
  className={cn(
122
- "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",
122
+ "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",
123
123
  className
124
124
  )}
125
125
  {...props}
@@ -66,7 +66,7 @@ const TableRow = React.forwardRef<HTMLTableRowElement, TableRowProps>(
66
66
  <tr
67
67
  ref={ref}
68
68
  className={cn(
69
- "border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
69
+ "border-b transition-colors hover:bg-hover data-[state=selected]:bg-muted",
70
70
  className
71
71
  )}
72
72
  {...props}
@@ -68,7 +68,7 @@ function ThemeSwatch({ theme, isSelected, onClick }: ThemeSwatchProps) {
68
68
  onClick={onClick}
69
69
  className={cn(
70
70
  "relative flex flex-col items-center gap-1.5 p-2 rounded-lg transition-all",
71
- "hover:bg-accent/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
71
+ "hover:bg-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
72
72
  isSelected && "bg-accent ring-2 ring-primary"
73
73
  )}
74
74
  >
package/src/styles.css CHANGED
@@ -45,6 +45,7 @@
45
45
  --toggle-track: 0 0% 82%;
46
46
  --toggle-track-foreground: 0 0% 100%;
47
47
  --input-hover: 234 86% 67%;
48
+ --hover: 243 82% 20% / 0.12;
48
49
  --divider: 0 0% 82%;
49
50
  --chip: 227 88% 85%;
50
51
  --chip-foreground: 243 82% 20%;
@@ -93,6 +94,7 @@
93
94
  --toggle-track: 240 4% 26%;
94
95
  --toggle-track-foreground: 0 0% 98%;
95
96
  --input-hover: 217 91% 60%;
97
+ --hover: 217 91% 60% / 0.12;
96
98
  --divider: 240 4% 26%;
97
99
  --chip: 240 4% 16%;
98
100
  --chip-foreground: 240 5% 83%;
@@ -63,6 +63,12 @@ export const optiUiPreset: Partial<Config> = {
63
63
  foreground: "hsl(var(--accent-foreground))",
64
64
  },
65
65
 
66
+ // Universal theme-aware hover tint. The --hover variable holds HSL
67
+ // channels with alpha (e.g. "243 82% 20% / 0.12"), so themes can
68
+ // override both color and alpha. Defaults to primary @ 12% via inference
69
+ // in applyTheme, with foreground fallback when primary lacks contrast.
70
+ hover: "hsl(var(--hover))",
71
+
66
72
  // Destructive
67
73
  destructive: {
68
74
  DEFAULT: "hsl(var(--destructive))",
@@ -64,6 +64,7 @@ export interface Theme {
64
64
  toggleTrack?: string; // --toggle-track (switch track bg when off; fallback: muted)
65
65
  toggleTrackForeground?: string; // --toggle-track-foreground (switch thumb when off; fallback: background)
66
66
  inputHover?: string; // --input-hover (form control border on hover; fallback: derived)
67
+ hover?: string; // --hover (subtle hover-tint base color; applied at 12% alpha; fallback: inferred from primary/foreground vs background)
67
68
 
68
69
  /** Chart colors */
69
70
  chart1: string; // --chart-1
@@ -131,6 +132,7 @@ export interface ThemeHSL extends Omit<Theme, keyof ThemeColorFields> {
131
132
  toggleTrack?: string;
132
133
  toggleTrackForeground?: string;
133
134
  inputHover?: string;
135
+ hover?: string;
134
136
  chart1: string;
135
137
  chart2: string;
136
138
  chart3: string;
@@ -176,6 +178,7 @@ type ThemeColorFields = {
176
178
  toggleTrack?: string;
177
179
  toggleTrackForeground?: string;
178
180
  inputHover?: string;
181
+ hover?: string;
179
182
  chart1: string;
180
183
  chart2: string;
181
184
  chart3: string;
@@ -94,6 +94,7 @@ export function themeToHsl(theme: Theme): ThemeHSL {
94
94
  ? hexToHsl(theme.toggleTrackForeground)
95
95
  : undefined,
96
96
  inputHover: theme.inputHover ? hexToHsl(theme.inputHover) : undefined,
97
+ hover: theme.hover ? hexToHsl(theme.hover) : undefined,
97
98
  chart1: hexToHsl(theme.chart1),
98
99
  chart2: hexToHsl(theme.chart2),
99
100
  chart3: hexToHsl(theme.chart3),
@@ -123,6 +124,30 @@ function deriveInputHoverHsl(hslTheme: ThemeHSL): string {
123
124
  return hslTheme.foreground;
124
125
  }
125
126
 
127
+ /**
128
+ * Threshold below which a 12% tint of `primary` becomes too subtle to register
129
+ * as a hover state against the theme's background. Picked empirically: at ~2:1
130
+ * the tint is faintly visible; below that it disappears into the background.
131
+ */
132
+ const HOVER_PRIMARY_MIN_CONTRAST = 2;
133
+
134
+ /**
135
+ * Pick a base color (HSL channels, no alpha) for the --hover tint by inferring
136
+ * what will read as a visible hover state for this specific theme.
137
+ *
138
+ * Strategy: prefer `primary` so hovers feel branded. Fall back to `foreground`
139
+ * when primary is too close in luminance to background — foreground is
140
+ * guaranteed by WCAG to contrast with background (it has to, for text to be
141
+ * readable), so it always produces a visible tint. Alpha is applied
142
+ * downstream in applyTheme so themes can override the channels independently.
143
+ */
144
+ function deriveHoverChannels(theme: Theme, hslTheme: ThemeHSL): string {
145
+ const primaryBgContrast = getContrastRatio(theme.primary, theme.background);
146
+ return primaryBgContrast >= HOVER_PRIMARY_MIN_CONTRAST
147
+ ? hslTheme.primary
148
+ : hslTheme.foreground;
149
+ }
150
+
126
151
  /**
127
152
  * Apply a theme to the DOM
128
153
  *
@@ -189,6 +214,10 @@ export function applyTheme(theme: Theme, targetElement?: HTMLElement): void {
189
214
  "--input-hover",
190
215
  hslTheme.inputHover ?? deriveInputHoverHsl(hslTheme)
191
216
  );
217
+ element.style.setProperty(
218
+ "--hover",
219
+ `${hslTheme.hover ?? deriveHoverChannels(theme, hslTheme)} / 0.12`
220
+ );
192
221
 
193
222
  element.style.setProperty("--chart-1", hslTheme.chart1);
194
223
  element.style.setProperty("--chart-2", hslTheme.chart2);
@@ -332,6 +361,7 @@ export function areThemesEqual(theme1: Theme, theme2: Theme): boolean {
332
361
  "toggleTrack",
333
362
  "toggleTrackForeground",
334
363
  "inputHover",
364
+ "hover",
335
365
  "chart1",
336
366
  "chart2",
337
367
  "chart3",