@hilum/ui 0.1.1 → 0.1.3
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/README.md +23 -4
- package/dist/chunk-J2QQDUF4.js +204 -0
- package/dist/chunk-J2QQDUF4.js.map +1 -0
- package/dist/create-theme.d.ts +27 -0
- package/dist/create-theme.js +172 -0
- package/dist/create-theme.js.map +1 -0
- package/dist/index.d.ts +21 -8
- package/dist/index.js +393 -381
- package/dist/index.js.map +1 -1
- package/dist/tokens.css +59 -50
- package/dist/tokens.d.ts +46 -38
- package/dist/tokens.js +1 -191
- package/dist/tokens.js.map +1 -1
- package/llms.txt +1514 -0
- package/package.json +11 -7
- package/src/components/accordion.tsx +5 -5
- package/src/components/action-panel.tsx +6 -6
- package/src/components/activity-feed.tsx +4 -4
- package/src/components/alert-dialog.tsx +3 -3
- package/src/components/alert.tsx +4 -4
- package/src/components/avatar-stack.tsx +2 -2
- package/src/components/avatar.tsx +2 -2
- package/src/components/badge.tsx +6 -5
- package/src/components/breadcrumb.tsx +5 -5
- package/src/components/button-group.tsx +4 -4
- package/src/components/button.tsx +6 -5
- package/src/components/calendar.tsx +7 -7
- package/src/components/card-heading.tsx +3 -3
- package/src/components/card.tsx +3 -3
- package/src/components/chart.tsx +11 -11
- package/src/components/checkbox.tsx +1 -1
- package/src/components/color-input.tsx +7 -7
- package/src/components/color-picker.tsx +5 -5
- package/src/components/combobox.tsx +10 -10
- package/src/components/command-palette.tsx +11 -11
- package/src/components/command.tsx +13 -13
- package/src/components/context-menu.tsx +15 -16
- package/src/components/data-table.tsx +6 -6
- package/src/components/date-picker.tsx +9 -4
- package/src/components/description-list.tsx +8 -8
- package/src/components/dialog.tsx +3 -3
- package/src/components/drawer.tsx +5 -5
- package/src/components/dropdown-menu.tsx +15 -16
- package/src/components/empty-state.tsx +3 -3
- package/src/components/field.tsx +13 -6
- package/src/components/grid-list.tsx +12 -12
- package/src/components/hover-card.tsx +1 -1
- package/src/components/input-group.tsx +8 -8
- package/src/components/input-number.tsx +7 -7
- package/src/components/input-otp.tsx +3 -3
- package/src/components/input.tsx +5 -4
- package/src/components/kbd.tsx +1 -1
- package/src/components/label.tsx +1 -1
- package/src/components/menubar.tsx +21 -22
- package/src/components/native-select.tsx +4 -4
- package/src/components/navigation-menu.tsx +10 -10
- package/src/components/notification.tsx +10 -10
- package/src/components/page-heading.tsx +8 -8
- package/src/components/pagination.tsx +1 -1
- package/src/components/progress.tsx +1 -1
- package/src/components/property-row.tsx +1 -1
- package/src/components/radio-card.tsx +6 -6
- package/src/components/radio-group.tsx +3 -3
- package/src/components/resizable.tsx +3 -3
- package/src/components/scroll-area.tsx +1 -1
- package/src/components/section-heading.tsx +3 -3
- package/src/components/select.tsx +11 -11
- package/src/components/separator.tsx +1 -1
- package/src/components/sheet.tsx +3 -3
- package/src/components/sidebar.tsx +19 -19
- package/src/components/skeleton.tsx +1 -1
- package/src/components/slider.tsx +1 -1
- package/src/components/sonner.tsx +5 -5
- package/src/components/stacked-list.tsx +4 -4
- package/src/components/stat-card.tsx +6 -6
- package/src/components/steps.tsx +13 -12
- package/src/components/switch.tsx +1 -1
- package/src/components/table.tsx +9 -9
- package/src/components/tabs.tsx +2 -2
- package/src/components/textarea.tsx +4 -4
- package/src/components/toggle.tsx +8 -8
- package/src/components/tooltip.tsx +1 -1
- package/src/index.ts +3 -2
- package/src/tokens/tokens.ts +54 -40
- package/src/components/__tests__/data.test.tsx +0 -180
- package/src/components/__tests__/disclosure.test.tsx +0 -198
- package/src/components/__tests__/display.test.tsx +0 -262
- package/src/components/__tests__/feedback.test.tsx +0 -138
- package/src/components/__tests__/form.test.tsx +0 -297
- package/src/components/__tests__/layout.test.tsx +0 -388
- package/src/components/__tests__/overlay.test.tsx +0 -90
- package/src/components/__tests__/primitives.test.tsx +0 -248
package/README.md
CHANGED
|
@@ -15,11 +15,9 @@ In your app's `globals.css`:
|
|
|
15
15
|
```css
|
|
16
16
|
@import "tailwindcss";
|
|
17
17
|
@import "@hilum/ui/tokens.css";
|
|
18
|
-
|
|
19
|
-
@source "../../node_modules/@hilum/ui/src";
|
|
20
18
|
```
|
|
21
19
|
|
|
22
|
-
That's the whole setup — palette, typography, fonts,
|
|
20
|
+
That's the whole setup — palette, typography, fonts, light/dark theming, and Tailwind class scanning are all handled by those two lines.
|
|
23
21
|
|
|
24
22
|
## Usage
|
|
25
23
|
|
|
@@ -35,7 +33,28 @@ See the live catalog at [ui.hilum.dev](https://ui.hilum.dev) for component docs,
|
|
|
35
33
|
|
|
36
34
|
## Brand
|
|
37
35
|
|
|
38
|
-
Hilum UI ships a fully-fixed brand:
|
|
36
|
+
Hilum UI ships a fully-fixed brand: vivid purple `#C100F1` primary, pale lemon `#FFF5BF` secondary, lime `#CDEA19` success, taupe scale neutrals. No per-app overrides — apps pass through this identity unchanged. See `PLATFORM_PLAN.md` §2.1 D8.
|
|
37
|
+
|
|
38
|
+
## Design Tokens
|
|
39
|
+
|
|
40
|
+
Import JS tokens for runtime access:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { tokens } from "@hilum/ui/tokens"
|
|
44
|
+
|
|
45
|
+
tokens.brand.primary // "#C100F1"
|
|
46
|
+
tokens.brand.secondary // "#FFF5BF"
|
|
47
|
+
tokens.taupe[500] // "#7d6960"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Theming
|
|
51
|
+
|
|
52
|
+
Light/dark mode works automatically via `prefers-color-scheme`. Override explicitly:
|
|
53
|
+
|
|
54
|
+
```html
|
|
55
|
+
<html data-theme="dark"> <!-- force dark -->
|
|
56
|
+
<html data-theme="light"> <!-- force light -->
|
|
57
|
+
```
|
|
39
58
|
|
|
40
59
|
## Light / dark
|
|
41
60
|
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
// src/tokens/tokens.ts
|
|
2
|
+
var tokens = {
|
|
3
|
+
/* ============================================================== *
|
|
4
|
+
* PALETTE — concrete colors *
|
|
5
|
+
* ============================================================== */
|
|
6
|
+
ground: {
|
|
7
|
+
50: "#fafafa",
|
|
8
|
+
100: "#f5f5f5",
|
|
9
|
+
200: "#e5e5e5",
|
|
10
|
+
300: "#d4d4d4",
|
|
11
|
+
400: "#a3a3a3",
|
|
12
|
+
500: "#737373",
|
|
13
|
+
600: "#525252",
|
|
14
|
+
700: "#404040",
|
|
15
|
+
800: "#262626",
|
|
16
|
+
900: "#171717",
|
|
17
|
+
950: "#0a0a0a"
|
|
18
|
+
},
|
|
19
|
+
// Pale lemon — anchor: butter-200 = #FFF5BF
|
|
20
|
+
butter: {
|
|
21
|
+
50: "#ffffe8",
|
|
22
|
+
100: "#fffad0",
|
|
23
|
+
200: "#fff5bf",
|
|
24
|
+
300: "#fde870",
|
|
25
|
+
400: "#f6d42a",
|
|
26
|
+
500: "#dab010",
|
|
27
|
+
600: "#a88008",
|
|
28
|
+
700: "#7c5c04",
|
|
29
|
+
800: "#543e02",
|
|
30
|
+
900: "#382801",
|
|
31
|
+
950: "#221600"
|
|
32
|
+
},
|
|
33
|
+
// Vivid purple — anchor: purple-500 = #C100F1 (brand.primary)
|
|
34
|
+
purple: {
|
|
35
|
+
50: "#fdf0ff",
|
|
36
|
+
100: "#f5d6ff",
|
|
37
|
+
200: "#e8a8ff",
|
|
38
|
+
300: "#d870f9",
|
|
39
|
+
400: "#c840f6",
|
|
40
|
+
500: "#c100f1",
|
|
41
|
+
600: "#9c00c0",
|
|
42
|
+
700: "#740092",
|
|
43
|
+
800: "#4e0062",
|
|
44
|
+
900: "#330040",
|
|
45
|
+
950: "#200028"
|
|
46
|
+
},
|
|
47
|
+
// Legacy functional colors — used by components not yet migrated to the new palette.
|
|
48
|
+
brand: {
|
|
49
|
+
primary: "#C100F1",
|
|
50
|
+
// purple-500
|
|
51
|
+
secondary: "#FFF5BF"
|
|
52
|
+
// butter-200
|
|
53
|
+
},
|
|
54
|
+
destructive: "#dc2626",
|
|
55
|
+
// red-600
|
|
56
|
+
/* ============================================================== *
|
|
57
|
+
* SEMANTIC — what components reference *
|
|
58
|
+
* ============================================================== */
|
|
59
|
+
semantic: {
|
|
60
|
+
light: {
|
|
61
|
+
background: "#ffffff",
|
|
62
|
+
foreground: "#171717",
|
|
63
|
+
// ground-900
|
|
64
|
+
card: "#ffffff",
|
|
65
|
+
cardForeground: "#171717",
|
|
66
|
+
surface: "#fafafa",
|
|
67
|
+
// ground-50
|
|
68
|
+
surfaceForeground: "#262626",
|
|
69
|
+
// ground-800
|
|
70
|
+
border: "#f5f5f5",
|
|
71
|
+
// ground-100
|
|
72
|
+
input: "#f5f5f5",
|
|
73
|
+
muted: "#fafafa",
|
|
74
|
+
mutedForeground: "#737373",
|
|
75
|
+
// ground-500
|
|
76
|
+
accent: "#fdf0ff",
|
|
77
|
+
// purple-50
|
|
78
|
+
accentForeground: "#740092",
|
|
79
|
+
// purple-700
|
|
80
|
+
primary: "#c100f1",
|
|
81
|
+
// purple-500 = brand.primary
|
|
82
|
+
primaryForeground: "#ffffff",
|
|
83
|
+
secondary: "#fafafa",
|
|
84
|
+
// ground-50
|
|
85
|
+
secondaryForeground: "#404040",
|
|
86
|
+
// ground-700
|
|
87
|
+
destructive: "#dc2626",
|
|
88
|
+
destructiveForeground: "#ffffff",
|
|
89
|
+
success: "#CDEA19",
|
|
90
|
+
// lime — functional semantic only
|
|
91
|
+
successForeground: "#171717",
|
|
92
|
+
warning: "#fff5bf",
|
|
93
|
+
// butter-200 = brand.secondary
|
|
94
|
+
warningForeground: "#171717",
|
|
95
|
+
// ground-900
|
|
96
|
+
ring: "#c100f1"
|
|
97
|
+
// purple-500 = brand.primary
|
|
98
|
+
},
|
|
99
|
+
dark: {
|
|
100
|
+
background: "#0a0a0a",
|
|
101
|
+
// ground-950
|
|
102
|
+
foreground: "#fafafa",
|
|
103
|
+
// ground-50
|
|
104
|
+
card: "#171717",
|
|
105
|
+
// ground-900
|
|
106
|
+
cardForeground: "#fafafa",
|
|
107
|
+
surface: "#171717",
|
|
108
|
+
surfaceForeground: "#f5f5f5",
|
|
109
|
+
border: "#262626",
|
|
110
|
+
// ground-800
|
|
111
|
+
input: "#262626",
|
|
112
|
+
muted: "#171717",
|
|
113
|
+
mutedForeground: "#a3a3a3",
|
|
114
|
+
// ground-400
|
|
115
|
+
accent: "#330040",
|
|
116
|
+
// purple-900
|
|
117
|
+
accentForeground: "#f5d6ff",
|
|
118
|
+
// purple-100
|
|
119
|
+
primary: "#c100f1",
|
|
120
|
+
// purple-500 — brand stays consistent (D8)
|
|
121
|
+
primaryForeground: "#ffffff",
|
|
122
|
+
secondary: "#171717",
|
|
123
|
+
secondaryForeground: "#f5f5f5",
|
|
124
|
+
destructive: "#ef4444",
|
|
125
|
+
// red-500 (slightly lighter for dark)
|
|
126
|
+
destructiveForeground: "#ffffff",
|
|
127
|
+
success: "#CDEA19",
|
|
128
|
+
// lime — functional semantic only
|
|
129
|
+
successForeground: "#0a0a0a",
|
|
130
|
+
warning: "#221600",
|
|
131
|
+
// butter-950 surface
|
|
132
|
+
warningForeground: "#fffad0",
|
|
133
|
+
// butter-100
|
|
134
|
+
ring: "#c100f1"
|
|
135
|
+
// purple-500 = brand.primary
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
/* ============================================================== *
|
|
139
|
+
* TYPOGRAPHY *
|
|
140
|
+
* ============================================================== */
|
|
141
|
+
fontFamily: {
|
|
142
|
+
sans: 'Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
|
|
143
|
+
serif: '"Instrument Serif", ui-serif, Georgia, serif',
|
|
144
|
+
mono: 'ui-monospace, "SFMono-Regular", "Menlo", "Consolas", monospace'
|
|
145
|
+
},
|
|
146
|
+
/** Type scale utilities — emitted as Tailwind v4 `@utility` blocks. */
|
|
147
|
+
typeScale: {
|
|
148
|
+
"display-xl": { family: "serif", size: "3rem", weight: 400, lineHeight: "1.15" },
|
|
149
|
+
display: { family: "serif", size: "2.25rem", weight: 400, lineHeight: "1.15" },
|
|
150
|
+
"heading-xl": { family: "serif", size: "1.875rem", weight: 400, lineHeight: "1.2" },
|
|
151
|
+
heading: { family: "serif", size: "1.5rem", weight: 400, lineHeight: "1.2" },
|
|
152
|
+
subheading: { family: "serif", size: "1.25rem", weight: 400, lineHeight: "1.4" },
|
|
153
|
+
"body-lg": { family: "sans", size: "1rem", weight: 400, lineHeight: "1.625" },
|
|
154
|
+
body: { family: "sans", size: "0.875rem", weight: 400, lineHeight: "1.625" },
|
|
155
|
+
caption: { family: "sans", size: "0.75rem", weight: 400, lineHeight: "1.625" },
|
|
156
|
+
"caption-xs": { family: "sans", size: "0.625rem", weight: 400, lineHeight: "1.625" },
|
|
157
|
+
label: {
|
|
158
|
+
family: "sans",
|
|
159
|
+
size: "0.75rem",
|
|
160
|
+
weight: 600,
|
|
161
|
+
lineHeight: "1",
|
|
162
|
+
letterSpacing: "0.1em",
|
|
163
|
+
textTransform: "uppercase"
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
/* ============================================================== *
|
|
167
|
+
* GEOMETRY *
|
|
168
|
+
* ============================================================== */
|
|
169
|
+
radius: {
|
|
170
|
+
base: "0.5rem",
|
|
171
|
+
sm: "calc(0.5rem - 4px)",
|
|
172
|
+
md: "calc(0.5rem - 2px)",
|
|
173
|
+
lg: "calc(0.5rem + 2px)",
|
|
174
|
+
xl: "calc(0.5rem + 4px)",
|
|
175
|
+
full: "9999px"
|
|
176
|
+
},
|
|
177
|
+
/* ============================================================== *
|
|
178
|
+
* Z-INDEX — semantic layering scale *
|
|
179
|
+
* ============================================================== */
|
|
180
|
+
zIndex: {
|
|
181
|
+
dropdown: 40,
|
|
182
|
+
sticky: 50,
|
|
183
|
+
fixed: 60,
|
|
184
|
+
modal: 100,
|
|
185
|
+
popover: 110,
|
|
186
|
+
tooltip: 120
|
|
187
|
+
},
|
|
188
|
+
shadow: {
|
|
189
|
+
natural: "0 0px 0px 1px rgba(0, 0, 0, 0.06), 0 1px 1px -0.5px rgba(0, 0, 0, 0.06), 0 3px 3px -1.5px rgba(0, 0, 0, 0.06)",
|
|
190
|
+
elevated: "0 0px 0px 1px rgba(0, 0, 0, 0.06), 0 1px 1px -0.5px rgba(0, 0, 0, 0.06), 0 3px 3px -1.5px rgba(0, 0, 0, 0.06), 0 6px 6px -3px rgba(0, 0, 0, 0.06), 0 12px 12px -6px rgba(0, 0, 0, 0.04), 0 24px 24px -12px rgba(0, 0, 0, 0.04), 0 24px 24px 2px rgba(0, 0, 0, 0.1)"
|
|
191
|
+
},
|
|
192
|
+
/* ============================================================== *
|
|
193
|
+
* ANIMATION *
|
|
194
|
+
* ============================================================== */
|
|
195
|
+
animation: {
|
|
196
|
+
"accordion-down": "accordion-down 0.2s ease-out",
|
|
197
|
+
"accordion-up": "accordion-up 0.2s ease-out",
|
|
198
|
+
"caret-blink": "caret-blink 1.25s ease-out infinite"
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
export { tokens };
|
|
203
|
+
//# sourceMappingURL=chunk-J2QQDUF4.js.map
|
|
204
|
+
//# sourceMappingURL=chunk-J2QQDUF4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tokens/tokens.ts"],"names":[],"mappings":"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","file":"chunk-J2QQDUF4.js","sourcesContent":["// @hilum/ui/tokens — JS-first design tokens (D6).\n//\n// This module is the single source of truth for the Hilum visual identity.\n// A build step (scripts/build-tokens.mjs) reads the compiled output of this\n// file and emits dist/tokens.css for consumers to `@import`.\n//\n// Brand model: D8 — base palette is fixed here. Per-product overrides are\n// applied at runtime via createTheme() in @hilum/ui/create-theme.\n// Color modes: D7 — light + dark, both auto (`prefers-color-scheme`) and\n// explicit via `[data-theme]`.\n//\n// Core brand colors:\n// brand.primary #C100F1 — vivid purple — purple-500 on the scale below\n// brand.secondary #FFF5BF — pale lemon — butter-200 on the scale below\n//\n// ground — neutral spine for text, borders, and structure (values: Tailwind neutral)\n\nexport const tokens = {\n /* ============================================================== *\n * PALETTE — concrete colors *\n * ============================================================== */\n\n ground: {\n 50: \"#fafafa\",\n 100: \"#f5f5f5\",\n 200: \"#e5e5e5\",\n 300: \"#d4d4d4\",\n 400: \"#a3a3a3\",\n 500: \"#737373\",\n 600: \"#525252\",\n 700: \"#404040\",\n 800: \"#262626\",\n 900: \"#171717\",\n 950: \"#0a0a0a\",\n },\n\n // Pale lemon — anchor: butter-200 = #FFF5BF\n butter: {\n 50: \"#ffffe8\",\n 100: \"#fffad0\",\n 200: \"#fff5bf\",\n 300: \"#fde870\",\n 400: \"#f6d42a\",\n 500: \"#dab010\",\n 600: \"#a88008\",\n 700: \"#7c5c04\",\n 800: \"#543e02\",\n 900: \"#382801\",\n 950: \"#221600\",\n },\n\n // Vivid purple — anchor: purple-500 = #C100F1 (brand.primary)\n purple: {\n 50: \"#fdf0ff\",\n 100: \"#f5d6ff\",\n 200: \"#e8a8ff\",\n 300: \"#d870f9\",\n 400: \"#c840f6\",\n 500: \"#c100f1\",\n 600: \"#9c00c0\",\n 700: \"#740092\",\n 800: \"#4e0062\",\n 900: \"#330040\",\n 950: \"#200028\",\n },\n\n // Legacy functional colors — used by components not yet migrated to the new palette.\n brand: {\n primary: \"#C100F1\", // purple-500\n secondary: \"#FFF5BF\", // butter-200\n },\n\n destructive: \"#dc2626\", // red-600\n\n /* ============================================================== *\n * SEMANTIC — what components reference *\n * ============================================================== */\n\n semantic: {\n light: {\n background: \"#ffffff\",\n foreground: \"#171717\", // ground-900\n card: \"#ffffff\",\n cardForeground: \"#171717\",\n surface: \"#fafafa\", // ground-50\n surfaceForeground: \"#262626\", // ground-800\n border: \"#f5f5f5\", // ground-100\n input: \"#f5f5f5\",\n muted: \"#fafafa\",\n mutedForeground: \"#737373\", // ground-500\n accent: \"#fdf0ff\", // purple-50\n accentForeground: \"#740092\", // purple-700\n primary: \"#c100f1\", // purple-500 = brand.primary\n primaryForeground: \"#ffffff\",\n secondary: \"#fafafa\", // ground-50\n secondaryForeground: \"#404040\", // ground-700\n destructive: \"#dc2626\",\n destructiveForeground: \"#ffffff\",\n success: \"#CDEA19\", // lime — functional semantic only\n successForeground: \"#171717\",\n warning: \"#fff5bf\", // butter-200 = brand.secondary\n warningForeground: \"#171717\", // ground-900\n ring: \"#c100f1\", // purple-500 = brand.primary\n },\n dark: {\n background: \"#0a0a0a\", // ground-950\n foreground: \"#fafafa\", // ground-50\n card: \"#171717\", // ground-900\n cardForeground: \"#fafafa\",\n surface: \"#171717\",\n surfaceForeground: \"#f5f5f5\",\n border: \"#262626\", // ground-800\n input: \"#262626\",\n muted: \"#171717\",\n mutedForeground: \"#a3a3a3\", // ground-400\n accent: \"#330040\", // purple-900\n accentForeground: \"#f5d6ff\", // purple-100\n primary: \"#c100f1\", // purple-500 — brand stays consistent (D8)\n primaryForeground: \"#ffffff\",\n secondary: \"#171717\",\n secondaryForeground: \"#f5f5f5\",\n destructive: \"#ef4444\", // red-500 (slightly lighter for dark)\n destructiveForeground: \"#ffffff\",\n success: \"#CDEA19\", // lime — functional semantic only\n successForeground: \"#0a0a0a\",\n warning: \"#221600\", // butter-950 surface\n warningForeground: \"#fffad0\", // butter-100\n ring: \"#c100f1\", // purple-500 = brand.primary\n },\n },\n\n /* ============================================================== *\n * TYPOGRAPHY *\n * ============================================================== */\n\n fontFamily: {\n sans: 'Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\n serif: '\"Instrument Serif\", ui-serif, Georgia, serif',\n mono: 'ui-monospace, \"SFMono-Regular\", \"Menlo\", \"Consolas\", monospace',\n },\n\n /** Type scale utilities — emitted as Tailwind v4 `@utility` blocks. */\n typeScale: {\n \"display-xl\": { family: \"serif\", size: \"3rem\", weight: 400, lineHeight: \"1.15\" },\n display: { family: \"serif\", size: \"2.25rem\", weight: 400, lineHeight: \"1.15\" },\n \"heading-xl\": { family: \"serif\", size: \"1.875rem\", weight: 400, lineHeight: \"1.2\" },\n heading: { family: \"serif\", size: \"1.5rem\", weight: 400, lineHeight: \"1.2\" },\n subheading: { family: \"serif\", size: \"1.25rem\", weight: 400, lineHeight: \"1.4\" },\n \"body-lg\": { family: \"sans\", size: \"1rem\", weight: 400, lineHeight: \"1.625\" },\n body: { family: \"sans\", size: \"0.875rem\", weight: 400, lineHeight: \"1.625\" },\n caption: { family: \"sans\", size: \"0.75rem\", weight: 400, lineHeight: \"1.625\" },\n \"caption-xs\": { family: \"sans\", size: \"0.625rem\", weight: 400, lineHeight: \"1.625\" },\n label: {\n family: \"sans\",\n size: \"0.75rem\",\n weight: 600,\n lineHeight: \"1\",\n letterSpacing: \"0.1em\",\n textTransform: \"uppercase\" as const,\n },\n },\n\n /* ============================================================== *\n * GEOMETRY *\n * ============================================================== */\n\n radius: {\n base: \"0.5rem\",\n sm: \"calc(0.5rem - 4px)\",\n md: \"calc(0.5rem - 2px)\",\n lg: \"calc(0.5rem + 2px)\",\n xl: \"calc(0.5rem + 4px)\",\n full: \"9999px\",\n },\n\n /* ============================================================== *\n * Z-INDEX — semantic layering scale *\n * ============================================================== */\n\n zIndex: {\n dropdown: 40,\n sticky: 50,\n fixed: 60,\n modal: 100,\n popover: 110,\n tooltip: 120,\n },\n\n shadow: {\n natural:\n \"0 0px 0px 1px rgba(0, 0, 0, 0.06), 0 1px 1px -0.5px rgba(0, 0, 0, 0.06), 0 3px 3px -1.5px rgba(0, 0, 0, 0.06)\",\n elevated:\n \"0 0px 0px 1px rgba(0, 0, 0, 0.06), 0 1px 1px -0.5px rgba(0, 0, 0, 0.06), 0 3px 3px -1.5px rgba(0, 0, 0, 0.06), 0 6px 6px -3px rgba(0, 0, 0, 0.06), 0 12px 12px -6px rgba(0, 0, 0, 0.04), 0 24px 24px -12px rgba(0, 0, 0, 0.04), 0 24px 24px 2px rgba(0, 0, 0, 0.1)\",\n },\n\n /* ============================================================== *\n * ANIMATION *\n * ============================================================== */\n\n animation: {\n \"accordion-down\": \"accordion-down 0.2s ease-out\",\n \"accordion-up\": \"accordion-up 0.2s ease-out\",\n \"caret-blink\": \"caret-blink 1.25s ease-out infinite\",\n },\n} as const;\n\nexport type Tokens = typeof tokens;\nexport type SemanticTokens = typeof tokens.semantic.light;\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
interface ThemeConfig {
|
|
5
|
+
/** Hex color used as the 500-level anchor for the primary palette. */
|
|
6
|
+
primary: string;
|
|
7
|
+
/** Hex color used as the 500-level anchor for the secondary palette. */
|
|
8
|
+
secondary: string;
|
|
9
|
+
}
|
|
10
|
+
interface ThemeResult {
|
|
11
|
+
/** Complete CSS override string. Inject via <style> or write to a .css file. */
|
|
12
|
+
css: string;
|
|
13
|
+
/** Generated palette shades for programmatic access. */
|
|
14
|
+
palette: {
|
|
15
|
+
primary: Record<string, string>;
|
|
16
|
+
secondary: Record<string, string>;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
declare function createTheme(config: ThemeConfig): ThemeResult;
|
|
20
|
+
/** Injects the theme CSS into `document.head`. Returns a cleanup function. */
|
|
21
|
+
declare function applyTheme(config: ThemeConfig): () => void;
|
|
22
|
+
/** React component that applies the theme on mount and cleans up on unmount. */
|
|
23
|
+
declare function ThemeProvider({ primary, secondary, children, }: ThemeConfig & {
|
|
24
|
+
children: React.ReactNode;
|
|
25
|
+
}): react_jsx_runtime.JSX.Element;
|
|
26
|
+
|
|
27
|
+
export { type ThemeConfig, ThemeProvider, type ThemeResult, applyTheme, createTheme };
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
// src/tokens/create-theme.tsx
|
|
5
|
+
function toLinear(c) {
|
|
6
|
+
return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
|
|
7
|
+
}
|
|
8
|
+
function toGamma(c) {
|
|
9
|
+
return c <= 31308e-7 ? 12.92 * c : 1.055 * c ** (1 / 2.4) - 0.055;
|
|
10
|
+
}
|
|
11
|
+
function hexToOklch(hex) {
|
|
12
|
+
const r = toLinear(parseInt(hex.slice(1, 3), 16) / 255);
|
|
13
|
+
const g = toLinear(parseInt(hex.slice(3, 5), 16) / 255);
|
|
14
|
+
const b = toLinear(parseInt(hex.slice(5, 7), 16) / 255);
|
|
15
|
+
const X = 0.4124564 * r + 0.3575761 * g + 0.1804375 * b;
|
|
16
|
+
const Y = 0.2126729 * r + 0.7151522 * g + 0.072175 * b;
|
|
17
|
+
const Z = 0.0193339 * r + 0.119192 * g + 0.9503041 * b;
|
|
18
|
+
const l_ = Math.cbrt(0.8189330101 * X + 0.3618667424 * Y - 0.1288597137 * Z);
|
|
19
|
+
const m_ = Math.cbrt(0.0329845436 * X + 0.9293118715 * Y + 0.0361456387 * Z);
|
|
20
|
+
const s_ = Math.cbrt(0.0482003018 * X + 0.2643662691 * Y + 0.633851707 * Z);
|
|
21
|
+
const L = 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_;
|
|
22
|
+
const a = 1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_;
|
|
23
|
+
const bv = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_;
|
|
24
|
+
const C = Math.sqrt(a * a + bv * bv);
|
|
25
|
+
let H = Math.atan2(bv, a) * 180 / Math.PI;
|
|
26
|
+
if (H < 0) H += 360;
|
|
27
|
+
return [L, C, H];
|
|
28
|
+
}
|
|
29
|
+
function oklchToLinearRgb(L, C, H) {
|
|
30
|
+
const hRad = H * Math.PI / 180;
|
|
31
|
+
const a = C * Math.cos(hRad);
|
|
32
|
+
const bv = C * Math.sin(hRad);
|
|
33
|
+
const l_ = L + 0.3963377774 * a + 0.2158037573 * bv;
|
|
34
|
+
const m_ = L - 0.1055613458 * a - 0.0638541728 * bv;
|
|
35
|
+
const s_ = L - 0.0894841775 * a - 1.291485548 * bv;
|
|
36
|
+
const l = l_ * l_ * l_;
|
|
37
|
+
const m = m_ * m_ * m_;
|
|
38
|
+
const s = s_ * s_ * s_;
|
|
39
|
+
const r = 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s;
|
|
40
|
+
const g = -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s;
|
|
41
|
+
const b = -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s;
|
|
42
|
+
return [r, g, b];
|
|
43
|
+
}
|
|
44
|
+
function inSrgbGamut(r, g, b) {
|
|
45
|
+
return r >= -1e-6 && r <= 1 + 1e-6 && g >= -1e-6 && g <= 1 + 1e-6 && b >= -1e-6 && b <= 1 + 1e-6;
|
|
46
|
+
}
|
|
47
|
+
function oklchToHex(L, C, H) {
|
|
48
|
+
if (!inSrgbGamut(...oklchToLinearRgb(L, C, H))) {
|
|
49
|
+
let lo = 0;
|
|
50
|
+
let hi = C;
|
|
51
|
+
for (let i = 0; i < 20; i++) {
|
|
52
|
+
const mid = (lo + hi) / 2;
|
|
53
|
+
inSrgbGamut(...oklchToLinearRgb(L, mid, H)) ? lo = mid : hi = mid;
|
|
54
|
+
}
|
|
55
|
+
C = lo;
|
|
56
|
+
}
|
|
57
|
+
const [r, g, b] = oklchToLinearRgb(L, C, H);
|
|
58
|
+
const ch = (c) => Math.round(Math.max(0, Math.min(1, toGamma(c))) * 255).toString(16).padStart(2, "0");
|
|
59
|
+
return `#${ch(r)}${ch(g)}${ch(b)}`;
|
|
60
|
+
}
|
|
61
|
+
var SHADE_KEYS = ["50", "100", "200", "300", "400", "500", "600", "700", "800", "900", "950"];
|
|
62
|
+
function lerp(a, b, t) {
|
|
63
|
+
return a + (b - a) * t;
|
|
64
|
+
}
|
|
65
|
+
function generatePalette(hex) {
|
|
66
|
+
const [L0, C0, H] = hexToOklch(hex);
|
|
67
|
+
const palette = {};
|
|
68
|
+
SHADE_KEYS.forEach((key, i) => {
|
|
69
|
+
if (i === 5) {
|
|
70
|
+
palette[key] = hex.toLowerCase();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
let L, C;
|
|
74
|
+
if (i < 5) {
|
|
75
|
+
const t = (5 - i) / 5;
|
|
76
|
+
L = lerp(L0, 0.975, t);
|
|
77
|
+
C = C0 * (1 - t * 0.8);
|
|
78
|
+
} else {
|
|
79
|
+
const t = (i - 5) / 5;
|
|
80
|
+
L = lerp(L0, 0.145, t);
|
|
81
|
+
C = C0 * (1 - t * 0.4);
|
|
82
|
+
}
|
|
83
|
+
palette[key] = oklchToHex(L, C, H);
|
|
84
|
+
});
|
|
85
|
+
return palette;
|
|
86
|
+
}
|
|
87
|
+
var TAUPE_900 = "#26181a";
|
|
88
|
+
function relativeLuminance(hex) {
|
|
89
|
+
const r = toLinear(parseInt(hex.slice(1, 3), 16) / 255);
|
|
90
|
+
const g = toLinear(parseInt(hex.slice(3, 5), 16) / 255);
|
|
91
|
+
const b = toLinear(parseInt(hex.slice(5, 7), 16) / 255);
|
|
92
|
+
return 0.2126729 * r + 0.7151522 * g + 0.072175 * b;
|
|
93
|
+
}
|
|
94
|
+
function autoFg(hex) {
|
|
95
|
+
return relativeLuminance(hex) > 0.179 ? TAUPE_900 : "#ffffff";
|
|
96
|
+
}
|
|
97
|
+
function buildCss(p, s, primaryHex, secondaryHex) {
|
|
98
|
+
const pfg = autoFg(primaryHex);
|
|
99
|
+
const lightBlock = [
|
|
100
|
+
` --color-brand-primary: ${primaryHex};`,
|
|
101
|
+
` --color-brand-secondary: ${secondaryHex};`,
|
|
102
|
+
` --primary: ${primaryHex};`,
|
|
103
|
+
` --primary-foreground: ${pfg};`,
|
|
104
|
+
` --accent: ${p["50"]};`,
|
|
105
|
+
` --accent-foreground: ${p["700"]};`,
|
|
106
|
+
` --ring: ${primaryHex};`,
|
|
107
|
+
` --warning: ${s["200"]};`,
|
|
108
|
+
` --warning-foreground: ${TAUPE_900};`,
|
|
109
|
+
// Palette vars for product CSS use (not registered as Tailwind utilities)
|
|
110
|
+
...SHADE_KEYS.map((k) => ` --color-primary-${k}: ${p[k]};`),
|
|
111
|
+
...SHADE_KEYS.map((k) => ` --color-secondary-${k}: ${s[k]};`)
|
|
112
|
+
].join("\n");
|
|
113
|
+
const darkBlock = [
|
|
114
|
+
` --color-brand-primary: ${primaryHex};`,
|
|
115
|
+
` --color-brand-secondary: ${secondaryHex};`,
|
|
116
|
+
` --primary: ${primaryHex};`,
|
|
117
|
+
` --primary-foreground: #ffffff;`,
|
|
118
|
+
` --accent: ${p["900"]};`,
|
|
119
|
+
` --accent-foreground: ${p["100"]};`,
|
|
120
|
+
` --ring: ${primaryHex};`,
|
|
121
|
+
` --warning: ${s["900"]};`,
|
|
122
|
+
` --warning-foreground: ${s["100"]};`
|
|
123
|
+
].join("\n");
|
|
124
|
+
const darkMediaBlock = darkBlock.split("\n").map((l) => ` ${l}`).join("\n");
|
|
125
|
+
return `/* @hilum/ui theme override \u2014 generated by createTheme() */
|
|
126
|
+
:root {
|
|
127
|
+
${lightBlock}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
@media (prefers-color-scheme: dark) {
|
|
131
|
+
:root:not([data-theme="light"]) {
|
|
132
|
+
${darkMediaBlock}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
[data-theme="dark"] {
|
|
137
|
+
${darkBlock}
|
|
138
|
+
}
|
|
139
|
+
`;
|
|
140
|
+
}
|
|
141
|
+
function createTheme(config) {
|
|
142
|
+
const primary = config.primary.trim().toLowerCase();
|
|
143
|
+
const secondary = config.secondary.trim().toLowerCase();
|
|
144
|
+
const p = generatePalette(primary);
|
|
145
|
+
const s = generatePalette(secondary);
|
|
146
|
+
return { css: buildCss(p, s, primary, secondary), palette: { primary: p, secondary: s } };
|
|
147
|
+
}
|
|
148
|
+
function applyTheme(config) {
|
|
149
|
+
if (typeof document === "undefined") return () => {
|
|
150
|
+
};
|
|
151
|
+
document.querySelectorAll("style[data-hilum-theme]").forEach((el) => el.remove());
|
|
152
|
+
const { css } = createTheme(config);
|
|
153
|
+
const style = document.createElement("style");
|
|
154
|
+
style.dataset.hilumTheme = "";
|
|
155
|
+
style.textContent = css;
|
|
156
|
+
document.head.appendChild(style);
|
|
157
|
+
return () => {
|
|
158
|
+
if (style.parentNode) style.parentNode.removeChild(style);
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function ThemeProvider({
|
|
162
|
+
primary,
|
|
163
|
+
secondary,
|
|
164
|
+
children
|
|
165
|
+
}) {
|
|
166
|
+
React.useEffect(() => applyTheme({ primary, secondary }), [primary, secondary]);
|
|
167
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export { ThemeProvider, applyTheme, createTheme };
|
|
171
|
+
//# sourceMappingURL=create-theme.js.map
|
|
172
|
+
//# sourceMappingURL=create-theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tokens/create-theme.tsx"],"names":[],"mappings":"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","file":"create-theme.js","sourcesContent":["// @hilum/ui — createTheme: per-product color theming API.\n//\n// Generates a full 11-shade OKLCH palette from primary and secondary hex anchors,\n// then emits a CSS override string that products inject after tokens.css.\n//\n// No external dependencies — OKLCH math is inlined (~100 lines).\n// createTheme() is pure and works in Node (build scripts) and browser.\n// applyTheme() and ThemeProvider require a browser / Electron environment.\n\nimport * as React from \"react\";\n\nexport interface ThemeConfig {\n /** Hex color used as the 500-level anchor for the primary palette. */\n primary: string;\n /** Hex color used as the 500-level anchor for the secondary palette. */\n secondary: string;\n}\n\nexport interface ThemeResult {\n /** Complete CSS override string. Inject via <style> or write to a .css file. */\n css: string;\n /** Generated palette shades for programmatic access. */\n palette: {\n primary: Record<string, string>;\n secondary: Record<string, string>;\n };\n}\n\n/* ------------------------------------------------------------------ *\n * OKLCH math (Björn Ottosson — no external deps) *\n * ------------------------------------------------------------------ */\n\nfunction toLinear(c: number): number {\n return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;\n}\n\nfunction toGamma(c: number): number {\n return c <= 0.0031308 ? 12.92 * c : 1.055 * c ** (1 / 2.4) - 0.055;\n}\n\nfunction hexToOklch(hex: string): [number, number, number] {\n const r = toLinear(parseInt(hex.slice(1, 3), 16) / 255);\n const g = toLinear(parseInt(hex.slice(3, 5), 16) / 255);\n const b = toLinear(parseInt(hex.slice(5, 7), 16) / 255);\n\n // linear sRGB → XYZ D65\n const X = 0.4124564 * r + 0.3575761 * g + 0.1804375 * b;\n const Y = 0.2126729 * r + 0.7151522 * g + 0.0721750 * b;\n const Z = 0.0193339 * r + 0.1191920 * g + 0.9503041 * b;\n\n // XYZ → OKLab\n const l_ = Math.cbrt(0.8189330101 * X + 0.3618667424 * Y - 0.1288597137 * Z);\n const m_ = Math.cbrt(0.0329845436 * X + 0.9293118715 * Y + 0.0361456387 * Z);\n const s_ = Math.cbrt(0.0482003018 * X + 0.2643662691 * Y + 0.6338517070 * Z);\n\n const L = 0.2104542553 * l_ + 0.7936177850 * m_ - 0.0040720468 * s_;\n const a = 1.9779984951 * l_ - 2.4285922050 * m_ + 0.4505937099 * s_;\n const bv = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.8086757660 * s_;\n\n const C = Math.sqrt(a * a + bv * bv);\n let H = (Math.atan2(bv, a) * 180) / Math.PI;\n if (H < 0) H += 360;\n return [L, C, H];\n}\n\nfunction oklchToLinearRgb(L: number, C: number, H: number): [number, number, number] {\n const hRad = (H * Math.PI) / 180;\n const a = C * Math.cos(hRad);\n const bv = C * Math.sin(hRad);\n\n // OKLab → XYZ\n const l_ = L + 0.3963377774 * a + 0.2158037573 * bv;\n const m_ = L - 0.1055613458 * a - 0.0638541728 * bv;\n const s_ = L - 0.0894841775 * a - 1.2914855480 * bv;\n\n const l = l_ * l_ * l_;\n const m = m_ * m_ * m_;\n const s = s_ * s_ * s_;\n\n // XYZ → linear sRGB\n const r = +4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s;\n const g = -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s;\n const b = -0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s;\n return [r, g, b];\n}\n\nfunction inSrgbGamut(r: number, g: number, b: number): boolean {\n return r >= -1e-6 && r <= 1 + 1e-6 && g >= -1e-6 && g <= 1 + 1e-6 && b >= -1e-6 && b <= 1 + 1e-6;\n}\n\nfunction oklchToHex(L: number, C: number, H: number): string {\n // Reduce chroma via binary search until in sRGB gamut.\n if (!inSrgbGamut(...oklchToLinearRgb(L, C, H))) {\n let lo = 0;\n let hi = C;\n for (let i = 0; i < 20; i++) {\n const mid = (lo + hi) / 2;\n inSrgbGamut(...oklchToLinearRgb(L, mid, H)) ? (lo = mid) : (hi = mid);\n }\n C = lo;\n }\n const [r, g, b] = oklchToLinearRgb(L, C, H);\n const ch = (c: number) =>\n Math.round(Math.max(0, Math.min(1, toGamma(c))) * 255)\n .toString(16)\n .padStart(2, \"0\");\n return `#${ch(r)}${ch(g)}${ch(b)}`;\n}\n\n/* ------------------------------------------------------------------ *\n * Palette generation *\n * ------------------------------------------------------------------ */\n\nconst SHADE_KEYS = [\"50\", \"100\", \"200\", \"300\", \"400\", \"500\", \"600\", \"700\", \"800\", \"900\", \"950\"];\n\nfunction lerp(a: number, b: number, t: number): number {\n return a + (b - a) * t;\n}\n\nfunction generatePalette(hex: string): Record<string, string> {\n const [L0, C0, H] = hexToOklch(hex);\n const palette: Record<string, string> = {};\n\n SHADE_KEYS.forEach((key, i) => {\n if (i === 5) {\n palette[key] = hex.toLowerCase();\n return;\n }\n let L: number, C: number;\n if (i < 5) {\n // Lighter shades: interpolate toward 0.975, fade chroma\n const t = (5 - i) / 5;\n L = lerp(L0, 0.975, t);\n C = C0 * (1 - t * 0.8);\n } else {\n // Darker shades: interpolate toward 0.145, fade chroma slightly\n const t = (i - 5) / 5;\n L = lerp(L0, 0.145, t);\n C = C0 * (1 - t * 0.4);\n }\n palette[key] = oklchToHex(L, C, H);\n });\n\n return palette;\n}\n\n/* ------------------------------------------------------------------ *\n * Foreground auto-detection *\n * ------------------------------------------------------------------ */\n\nconst TAUPE_900 = \"#26181a\";\n\n// WCAG relative luminance Y (XYZ). Threshold ≈ 0.179 gives equal contrast\n// with black and white: use dark text above, white text at or below.\nfunction relativeLuminance(hex: string): number {\n const r = toLinear(parseInt(hex.slice(1, 3), 16) / 255);\n const g = toLinear(parseInt(hex.slice(3, 5), 16) / 255);\n const b = toLinear(parseInt(hex.slice(5, 7), 16) / 255);\n return 0.2126729 * r + 0.7151522 * g + 0.0721750 * b;\n}\n\nfunction autoFg(hex: string): string {\n return relativeLuminance(hex) > 0.179 ? TAUPE_900 : \"#ffffff\";\n}\n\n/* ------------------------------------------------------------------ *\n * CSS emission *\n * ------------------------------------------------------------------ */\n\nfunction buildCss(\n p: Record<string, string>,\n s: Record<string, string>,\n primaryHex: string,\n secondaryHex: string,\n): string {\n const pfg = autoFg(primaryHex);\n\n const lightBlock = [\n ` --color-brand-primary: ${primaryHex};`,\n ` --color-brand-secondary: ${secondaryHex};`,\n ` --primary: ${primaryHex};`,\n ` --primary-foreground: ${pfg};`,\n ` --accent: ${p[\"50\"]};`,\n ` --accent-foreground: ${p[\"700\"]};`,\n ` --ring: ${primaryHex};`,\n ` --warning: ${s[\"200\"]};`,\n ` --warning-foreground: ${TAUPE_900};`,\n // Palette vars for product CSS use (not registered as Tailwind utilities)\n ...SHADE_KEYS.map((k) => ` --color-primary-${k}: ${p[k]};`),\n ...SHADE_KEYS.map((k) => ` --color-secondary-${k}: ${s[k]};`),\n ].join(\"\\n\");\n\n const darkBlock = [\n ` --color-brand-primary: ${primaryHex};`,\n ` --color-brand-secondary: ${secondaryHex};`,\n ` --primary: ${primaryHex};`,\n ` --primary-foreground: #ffffff;`,\n ` --accent: ${p[\"900\"]};`,\n ` --accent-foreground: ${p[\"100\"]};`,\n ` --ring: ${primaryHex};`,\n ` --warning: ${s[\"900\"]};`,\n ` --warning-foreground: ${s[\"100\"]};`,\n ].join(\"\\n\");\n\n const darkMediaBlock = darkBlock\n .split(\"\\n\")\n .map((l) => ` ${l}`)\n .join(\"\\n\");\n\n return `/* @hilum/ui theme override — generated by createTheme() */\n:root {\n${lightBlock}\n}\n\n@media (prefers-color-scheme: dark) {\n :root:not([data-theme=\"light\"]) {\n${darkMediaBlock}\n }\n}\n\n[data-theme=\"dark\"] {\n${darkBlock}\n}\n`;\n}\n\n/* ------------------------------------------------------------------ *\n * Public API *\n * ------------------------------------------------------------------ */\n\nexport function createTheme(config: ThemeConfig): ThemeResult {\n const primary = config.primary.trim().toLowerCase();\n const secondary = config.secondary.trim().toLowerCase();\n const p = generatePalette(primary);\n const s = generatePalette(secondary);\n return { css: buildCss(p, s, primary, secondary), palette: { primary: p, secondary: s } };\n}\n\n/** Injects the theme CSS into `document.head`. Returns a cleanup function. */\nexport function applyTheme(config: ThemeConfig): () => void {\n if (typeof document === \"undefined\") return () => {};\n // Remove any stale theme override from a prior call.\n document.querySelectorAll(\"style[data-hilum-theme]\").forEach((el) => el.remove());\n const { css } = createTheme(config);\n const style = document.createElement(\"style\");\n style.dataset.hilumTheme = \"\";\n style.textContent = css;\n document.head.appendChild(style);\n return () => {\n if (style.parentNode) style.parentNode.removeChild(style);\n };\n}\n\n/** React component that applies the theme on mount and cleans up on unmount. */\nexport function ThemeProvider({\n primary,\n secondary,\n children,\n}: ThemeConfig & { children: React.ReactNode }) {\n React.useEffect(() => applyTheme({ primary, secondary }), [primary, secondary]);\n return <>{children}</>;\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -138,6 +138,9 @@ declare const badgeVariants: (props?: ({
|
|
|
138
138
|
interface BadgeProps extends React$1.ComponentProps<"span">, VariantProps<typeof badgeVariants> {
|
|
139
139
|
}
|
|
140
140
|
declare function Badge({ className, variant, ...props }: BadgeProps): react_jsx_runtime.JSX.Element;
|
|
141
|
+
declare namespace Badge {
|
|
142
|
+
var displayName: string;
|
|
143
|
+
}
|
|
141
144
|
|
|
142
145
|
declare const Breadcrumb: React$1.ForwardRefExoticComponent<Omit<React$1.ClassAttributes<HTMLElement> & React$1.HTMLAttributes<HTMLElement> & {
|
|
143
146
|
separator?: React$1.ReactNode;
|
|
@@ -173,6 +176,9 @@ interface ButtonProps extends React$1.ComponentProps<"button">, VariantProps<typ
|
|
|
173
176
|
asChild?: boolean;
|
|
174
177
|
}
|
|
175
178
|
declare function Button({ className, variant, size, asChild, ...props }: ButtonProps): react_jsx_runtime.JSX.Element;
|
|
179
|
+
declare namespace Button {
|
|
180
|
+
var displayName: string;
|
|
181
|
+
}
|
|
176
182
|
|
|
177
183
|
type CalendarProps = React$1.ComponentProps<typeof DayPicker>;
|
|
178
184
|
declare function Calendar({ className, classNames, showOutsideDays, ...props }: CalendarProps): react_jsx_runtime.JSX.Element;
|
|
@@ -225,12 +231,12 @@ declare function CarouselPrevious({ className, variant, size, ...props }: React$
|
|
|
225
231
|
declare function CarouselNext({ className, variant, size, ...props }: React$1.ComponentProps<typeof Button>): react_jsx_runtime.JSX.Element;
|
|
226
232
|
|
|
227
233
|
declare const CHART_COLORS: {
|
|
228
|
-
primary:
|
|
229
|
-
secondary:
|
|
230
|
-
tertiary:
|
|
231
|
-
muted:
|
|
232
|
-
subtle:
|
|
233
|
-
dark:
|
|
234
|
+
primary: "#C100F1";
|
|
235
|
+
secondary: "#CDEA19";
|
|
236
|
+
tertiary: "#FFF5BF";
|
|
237
|
+
muted: "#a3a3a3";
|
|
238
|
+
subtle: "#e5e5e5";
|
|
239
|
+
dark: "#171717";
|
|
234
240
|
};
|
|
235
241
|
interface ChartContainerProps {
|
|
236
242
|
children: React$1.ReactNode;
|
|
@@ -381,7 +387,7 @@ declare function DataTable<TData>({ columns, data, searchKey, searchPlaceholder,
|
|
|
381
387
|
|
|
382
388
|
declare const formatDate: (date: Date) => string;
|
|
383
389
|
interface DatePickerProps {
|
|
384
|
-
value?: Date;
|
|
390
|
+
value?: Date | undefined;
|
|
385
391
|
onChange?: (date: Date | undefined) => void;
|
|
386
392
|
placeholder?: string;
|
|
387
393
|
disabled?: boolean;
|
|
@@ -488,8 +494,12 @@ interface FieldProps {
|
|
|
488
494
|
cornerHint?: string;
|
|
489
495
|
className?: string;
|
|
490
496
|
children: React$1.ReactNode;
|
|
497
|
+
ref?: React$1.Ref<HTMLDivElement>;
|
|
498
|
+
}
|
|
499
|
+
declare function Field({ label, htmlFor, hint, error, required, cornerHint, className, children, ref, }: FieldProps): react_jsx_runtime.JSX.Element;
|
|
500
|
+
declare namespace Field {
|
|
501
|
+
var displayName: string;
|
|
491
502
|
}
|
|
492
|
-
declare function Field({ label, htmlFor, hint, error, required, cornerHint, className, children, }: FieldProps): react_jsx_runtime.JSX.Element;
|
|
493
503
|
|
|
494
504
|
interface GridListProps {
|
|
495
505
|
children: React$1.ReactNode;
|
|
@@ -588,6 +598,9 @@ declare const InputOTPSlot: React$1.ForwardRefExoticComponent<React$1.HTMLAttrib
|
|
|
588
598
|
declare const InputOTPSeparator: React$1.ForwardRefExoticComponent<React$1.HTMLAttributes<HTMLDivElement> & React$1.RefAttributes<HTMLDivElement>>;
|
|
589
599
|
|
|
590
600
|
declare function Input({ className, type, ...props }: React$1.ComponentProps<"input">): react_jsx_runtime.JSX.Element;
|
|
601
|
+
declare namespace Input {
|
|
602
|
+
var displayName: string;
|
|
603
|
+
}
|
|
591
604
|
|
|
592
605
|
declare const Kbd: React$1.ForwardRefExoticComponent<Omit<React$1.DetailedHTMLProps<React$1.HTMLAttributes<HTMLElement>, HTMLElement>, "ref"> & React$1.RefAttributes<HTMLElement>>;
|
|
593
606
|
|