@open-kingdom/shared-frontend-ui-theme 0.0.2-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/README.md ADDED
@@ -0,0 +1,191 @@
1
+ # Shared UI Theme Library
2
+
3
+ This library provides a comprehensive theming system for the Nx workspace, including Tailwind CSS configuration, theme management, and dark/light mode support.
4
+
5
+ ## Features
6
+
7
+ - **Centralized Theme Configuration**: Single source of truth for design tokens
8
+ - **CSS Custom Properties**: Runtime theme changes via CSS variables
9
+ - **Dark/Light Mode Support**: Automatic theme switching with persistence
10
+ - **TypeScript Support**: Full type safety for theme objects
11
+ - **Tailwind Integration**: Seamless integration with Tailwind CSS
12
+ - **React Context**: Easy theme management with React hooks
13
+
14
+ ## Usage
15
+
16
+ ### Basic Setup
17
+
18
+ 1. **Import the ThemeProvider** in your app's root component:
19
+
20
+ ```tsx
21
+ import { ThemeProvider } from '@open-kingdom/shared-frontend-ui-theme';
22
+
23
+ export function App() {
24
+ return <ThemeProvider>{/* Your app content */}</ThemeProvider>;
25
+ }
26
+ ```
27
+
28
+ 2. **Use the theme hook** in your components:
29
+
30
+ ```tsx
31
+ import { useTheme } from '@open-kingdom/shared-frontend-ui-theme';
32
+
33
+ export function MyComponent() {
34
+ const { theme, mode, setMode } = useTheme();
35
+
36
+ return (
37
+ <div className="bg-primary-500 text-white">
38
+ <button onClick={() => setMode(mode === 'light' ? 'dark' : 'light')}>Toggle Theme</button>
39
+ </div>
40
+ );
41
+ }
42
+ ```
43
+
44
+ ### Tailwind Configuration
45
+
46
+ The library provides a base Tailwind configuration that can be extended by applications and other libraries:
47
+
48
+ ```javascript
49
+ // tailwind.config.js
50
+ const baseConfig = require('@open-kingdom/shared-frontend-ui-theme/src/tailwind.config.js');
51
+
52
+ module.exports = {
53
+ presets: [baseConfig],
54
+ content: ['./src/**/*.{ts,tsx}'],
55
+ theme: {
56
+ extend: {
57
+ // Your custom theme overrides
58
+ },
59
+ },
60
+ };
61
+ ```
62
+
63
+ ### Available Design Tokens
64
+
65
+ #### Colors
66
+
67
+ - `primary-50` to `primary-950`: Primary color palette
68
+ - `secondary-50` to `secondary-950`: Secondary color palette
69
+ - `neutral-50` to `neutral-950`: Neutral color palette
70
+ - `success-50` to `success-950`: Success color palette
71
+ - `warning-50` to `warning-950`: Warning color palette
72
+ - `error-50` to `error-950`: Error color palette
73
+
74
+ #### Typography
75
+
76
+ - Font families: `font-sans`, `font-serif`, `font-mono`
77
+ - Font sizes: `text-xs` to `text-6xl`
78
+ - Line heights: Automatically applied with font sizes
79
+
80
+ #### Spacing
81
+
82
+ - Custom spacing scale: `xs`, `sm`, `md`, `lg`, `xl`, `2xl`, `3xl`
83
+
84
+ #### Border Radius
85
+
86
+ - Custom radius scale: `none`, `sm`, `md`, `lg`, `xl`, `full`
87
+
88
+ #### Box Shadows
89
+
90
+ - Custom shadow scale: `sm`, `md`, `lg`, `xl`, `2xl`
91
+
92
+ ### Theme Customization
93
+
94
+ You can customize themes by passing them to the ThemeProvider:
95
+
96
+ ```tsx
97
+ import { ThemeProvider, defaultLightTheme } from '@open-kingdom/shared-frontend-ui-theme';
98
+
99
+ const customTheme = {
100
+ ...defaultLightTheme,
101
+ colors: {
102
+ ...defaultLightTheme.colors,
103
+ primary: {
104
+ // Your custom primary colors
105
+ },
106
+ },
107
+ };
108
+
109
+ <ThemeProvider initialTheme={customTheme}>{/* Your app */}</ThemeProvider>;
110
+ ```
111
+
112
+ ### CSS Variables
113
+
114
+ The theme system automatically generates CSS custom properties that can be used in your CSS:
115
+
116
+ ```css
117
+ .my-component {
118
+ background-color: var(--color-primary-500);
119
+ color: var(--color-neutral-900);
120
+ font-family: var(--font-family-sans);
121
+ font-size: var(--text-lg);
122
+ }
123
+ ```
124
+
125
+ ### Utilities
126
+
127
+ The library provides utility functions for theme management:
128
+
129
+ ```tsx
130
+ import { generateCSSVariables, applyThemeToDOM, mergeThemes, saveThemeMode, loadThemeMode } from '@open-kingdom/shared-frontend-ui-theme';
131
+
132
+ // Generate CSS variables from a theme
133
+ const variables = generateCSSVariables(theme);
134
+
135
+ // Apply theme to DOM
136
+ applyThemeToDOM(theme);
137
+
138
+ // Merge themes
139
+ const mergedTheme = mergeThemes(baseTheme, overrideTheme);
140
+
141
+ // Save/load theme mode
142
+ saveThemeMode('dark');
143
+ const mode = loadThemeMode();
144
+ ```
145
+
146
+ ## Architecture
147
+
148
+ ### File Structure
149
+
150
+ ```
151
+ src/
152
+ ├── index.ts # Main exports
153
+ ├── tailwind.config.js # Base Tailwind configuration
154
+ └── lib/
155
+ ├── theme.types.ts # TypeScript interfaces
156
+ ├── default-theme.ts # Default theme values
157
+ ├── theme-provider.tsx # React context and provider
158
+ └── theme-utils.ts # Utility functions
159
+ ```
160
+
161
+ ### Theme Flow
162
+
163
+ 1. **ThemeProvider** initializes with default theme
164
+ 2. **CSS Variables** are generated and applied to document root
165
+ 3. **Components** use Tailwind classes that reference CSS variables
166
+ 4. **Theme Changes** update CSS variables for immediate visual feedback
167
+ 5. **Persistence** saves theme mode to localStorage
168
+
169
+ ### Integration with Nx
170
+
171
+ - **Host Applications**: Extend the base Tailwind config
172
+ - **UI Libraries**: Use the base config as a preset
173
+ - **Peer Dependencies**: Tailwind CSS is a peer dependency
174
+ - **Type Safety**: Full TypeScript support across the workspace
175
+
176
+ ## Best Practices
177
+
178
+ 1. **Use Semantic Colors**: Always use semantic color tokens (e.g., `primary-500`) instead of hardcoded values
179
+ 2. **Dark Mode Support**: Include dark mode variants for all components
180
+ 3. **CSS Variables**: Leverage CSS variables for runtime customization
181
+ 4. **Type Safety**: Use the provided TypeScript interfaces for theme objects
182
+ 5. **Consistent Spacing**: Use the defined spacing scale for consistent layouts
183
+
184
+ ## Examples
185
+
186
+ See the demo-scaffold application for a complete example of the theme system in action, including:
187
+
188
+ - Theme provider setup
189
+ - Dark/light mode switching
190
+ - Component theming with Tailwind classes
191
+ - Color palette demonstrations
@@ -0,0 +1,5 @@
1
+ export * from './lib/theme.types';
2
+ export * from './lib/default-theme';
3
+ export * from './lib/theme-provider';
4
+ export * from './lib/theme-utils';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAC;AAGlC,cAAc,qBAAqB,CAAC;AAGpC,cAAc,sBAAsB,CAAC;AAGrC,cAAc,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,267 @@
1
+ import { jsx as g } from "react/jsx-runtime";
2
+ import { createContext as m, useContext as y, useState as p, useEffect as c } from "react";
3
+ const f = {
4
+ colors: {
5
+ primary: {
6
+ 50: "#eff6ff",
7
+ 100: "#dbeafe",
8
+ 200: "#bfdbfe",
9
+ 300: "#93c5fd",
10
+ 400: "#60a5fa",
11
+ 500: "#3b82f6",
12
+ 600: "#2563eb",
13
+ 700: "#1d4ed8",
14
+ 800: "#1e40af",
15
+ 900: "#1e3a8a",
16
+ 950: "#172554"
17
+ },
18
+ secondary: {
19
+ 50: "#f8fafc",
20
+ 100: "#f1f5f9",
21
+ 200: "#e2e8f0",
22
+ 300: "#cbd5e1",
23
+ 400: "#94a3b8",
24
+ 500: "#64748b",
25
+ 600: "#475569",
26
+ 700: "#334155",
27
+ 800: "#1e293b",
28
+ 900: "#0f172a",
29
+ 950: "#020617"
30
+ },
31
+ neutral: {
32
+ 50: "#fafafa",
33
+ 100: "#f5f5f5",
34
+ 200: "#e5e5e5",
35
+ 300: "#d4d4d4",
36
+ 400: "#a3a3a3",
37
+ 500: "#737373",
38
+ 600: "#525252",
39
+ 700: "#404040",
40
+ 800: "#262626",
41
+ 900: "#171717",
42
+ 950: "#0a0a0a"
43
+ },
44
+ success: {
45
+ 50: "#f0fdf4",
46
+ 100: "#dcfce7",
47
+ 200: "#bbf7d0",
48
+ 300: "#86efac",
49
+ 400: "#4ade80",
50
+ 500: "#22c55e",
51
+ 600: "#16a34a",
52
+ 700: "#15803d",
53
+ 800: "#166534",
54
+ 900: "#14532d",
55
+ 950: "#052e16"
56
+ },
57
+ warning: {
58
+ 50: "#fffbeb",
59
+ 100: "#fef3c7",
60
+ 200: "#fde68a",
61
+ 300: "#fcd34d",
62
+ 400: "#fbbf24",
63
+ 500: "#f59e0b",
64
+ 600: "#d97706",
65
+ 700: "#b45309",
66
+ 800: "#92400e",
67
+ 900: "#78350f",
68
+ 950: "#451a03"
69
+ },
70
+ error: {
71
+ 50: "#fef2f2",
72
+ 100: "#fee2e2",
73
+ 200: "#fecaca",
74
+ 300: "#fca5a5",
75
+ 400: "#f87171",
76
+ 500: "#ef4444",
77
+ 600: "#dc2626",
78
+ 700: "#b91c1c",
79
+ 800: "#991b1b",
80
+ 900: "#7f1d1d",
81
+ 950: "#450a0a"
82
+ }
83
+ },
84
+ typography: {
85
+ fontFamily: {
86
+ sans: ["Inter", "system-ui", "sans-serif"],
87
+ serif: ["Georgia", "serif"],
88
+ mono: ["JetBrains Mono", "ui-monospace", "monospace"]
89
+ },
90
+ fontSize: {
91
+ xs: "0.75rem",
92
+ sm: "0.875rem",
93
+ base: "1rem",
94
+ lg: "1.125rem",
95
+ xl: "1.25rem",
96
+ "2xl": "1.5rem",
97
+ "3xl": "1.875rem",
98
+ "4xl": "2.25rem",
99
+ "5xl": "3rem",
100
+ "6xl": "3.75rem"
101
+ }
102
+ },
103
+ spacing: {
104
+ xs: "0.25rem",
105
+ sm: "0.5rem",
106
+ md: "1rem",
107
+ lg: "1.5rem",
108
+ xl: "2rem",
109
+ "2xl": "3rem",
110
+ "3xl": "4rem"
111
+ },
112
+ borderRadius: {
113
+ none: "0",
114
+ sm: "0.125rem",
115
+ md: "0.375rem",
116
+ lg: "0.5rem",
117
+ xl: "0.75rem",
118
+ full: "9999px"
119
+ },
120
+ boxShadow: {
121
+ sm: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
122
+ md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
123
+ lg: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
124
+ xl: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)",
125
+ "2xl": "0 25px 50px -12px rgb(0 0 0 / 0.25)"
126
+ }
127
+ }, u = {
128
+ ...f,
129
+ colors: {
130
+ ...f.colors,
131
+ neutral: {
132
+ 50: "#0a0a0a",
133
+ 100: "#171717",
134
+ 200: "#262626",
135
+ 300: "#404040",
136
+ 400: "#525252",
137
+ 500: "#737373",
138
+ 600: "#a3a3a3",
139
+ 700: "#d4d4d4",
140
+ 800: "#e5e5e5",
141
+ 900: "#f5f5f5",
142
+ 950: "#fafafa"
143
+ }
144
+ }
145
+ }, b = (o) => {
146
+ const r = {};
147
+ return Object.entries(o.colors || {}).forEach(([t, e]) => {
148
+ Object.entries(e).forEach(([s, n]) => {
149
+ r[`--color-${t}-${s}`] = n;
150
+ });
151
+ }), Object.entries(o.typography?.fontFamily || {}).forEach(
152
+ ([t, e]) => {
153
+ r[`--font-family-${t}`] = e.join(", ");
154
+ }
155
+ ), Object.entries(o.typography?.fontSize || {}).forEach(([t, e]) => {
156
+ typeof e == "string" ? (r[`--text-${t}`] = e, r[`--leading-${t}`] = "1.5") : (r[`--text-${t}`] = e[0], r[`--leading-${t}`] = e[1].lineHeight);
157
+ }), Object.entries(o.spacing || {}).forEach(([t, e]) => {
158
+ r[`--spacing-${t}`] = e;
159
+ }), Object.entries(o.borderRadius || {}).forEach(([t, e]) => {
160
+ r[`--radius-${t}`] = e;
161
+ }), Object.entries(o.boxShadow || {}).forEach(([t, e]) => {
162
+ r[`--shadow-${t}`] = e;
163
+ }), r;
164
+ }, w = (o) => {
165
+ if (typeof document > "u") return;
166
+ const r = b(o), t = document.documentElement;
167
+ Object.entries(r).forEach(([e, s]) => {
168
+ t.style.setProperty(e, s);
169
+ });
170
+ }, h = (o, r) => ({
171
+ ...o,
172
+ ...r,
173
+ colors: {
174
+ primary: {
175
+ ...o?.colors?.primary,
176
+ ...r?.colors?.primary
177
+ },
178
+ secondary: {
179
+ ...o?.colors?.secondary,
180
+ ...r?.colors?.secondary
181
+ },
182
+ neutral: {
183
+ ...o?.colors?.neutral,
184
+ ...r?.colors?.neutral
185
+ },
186
+ success: {
187
+ ...o?.colors?.success,
188
+ ...r?.colors?.success
189
+ },
190
+ warning: {
191
+ ...o?.colors?.warning,
192
+ ...r?.colors?.warning
193
+ },
194
+ error: { ...o?.colors?.error, ...r?.colors?.error }
195
+ },
196
+ typography: {
197
+ ...o.typography,
198
+ ...r.typography,
199
+ fontFamily: {
200
+ ...o?.typography?.fontFamily,
201
+ ...r.typography?.fontFamily
202
+ },
203
+ fontSize: {
204
+ ...o?.typography?.fontSize,
205
+ ...r.typography?.fontSize
206
+ }
207
+ },
208
+ spacing: {
209
+ ...o.spacing,
210
+ ...r.spacing
211
+ },
212
+ borderRadius: {
213
+ ...o.borderRadius,
214
+ ...r.borderRadius
215
+ },
216
+ boxShadow: {
217
+ ...o.boxShadow,
218
+ ...r.boxShadow
219
+ }
220
+ }), S = (o) => {
221
+ typeof window < "u" && localStorage.setItem("theme-mode", o);
222
+ }, E = () => {
223
+ if (typeof window > "u") return null;
224
+ const o = localStorage.getItem("theme-mode");
225
+ return o && (o === "light" || o === "dark") ? o : null;
226
+ }, l = m(void 0), F = () => {
227
+ const o = y(l);
228
+ if (!o)
229
+ throw new Error("useTheme must be used within a ThemeProvider");
230
+ return o;
231
+ }, R = ({
232
+ children: o,
233
+ initialTheme: r = f,
234
+ initialMode: t = "light"
235
+ }) => {
236
+ const [e, s] = p(r), [n, d] = p(t);
237
+ c(() => {
238
+ w(e);
239
+ }, [e]), c(() => {
240
+ (!r || r === f) && s(n === "dark" ? u : f);
241
+ }, [n, r]), c(() => {
242
+ const a = E();
243
+ a && d(a);
244
+ }, []);
245
+ const i = {
246
+ theme: e,
247
+ mode: n,
248
+ setMode: (a) => {
249
+ d(a), S(a);
250
+ },
251
+ setTheme: (a) => {
252
+ s((x) => h(x, a));
253
+ }
254
+ };
255
+ return /* @__PURE__ */ g(l.Provider, { value: i, children: o });
256
+ };
257
+ export {
258
+ R as ThemeProvider,
259
+ w as applyThemeToDOM,
260
+ u as defaultDarkTheme,
261
+ f as defaultLightTheme,
262
+ b as generateCSSVariables,
263
+ E as loadThemeMode,
264
+ h as mergeThemes,
265
+ S as saveThemeMode,
266
+ F as useTheme
267
+ };
@@ -0,0 +1,4 @@
1
+ import { Theme } from './theme.types';
2
+ export declare const defaultLightTheme: Theme;
3
+ export declare const defaultDarkTheme: Theme;
4
+ //# sourceMappingURL=default-theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-theme.d.ts","sourceRoot":"","sources":["../../src/lib/default-theme.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEtC,eAAO,MAAM,iBAAiB,EAAE,KA4H/B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAkB9B,CAAC"}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=test-setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-setup.d.ts","sourceRoot":"","sources":["../../src/lib/test-setup.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,2BAA2B,CAAC"}
@@ -0,0 +1,159 @@
1
+ import { Theme, ColorPalette } from './theme.types';
2
+ /**
3
+ * Creates a minimal theme for testing purposes
4
+ */
5
+ export declare const createMockTheme: (overrides?: Partial<Theme>) => Theme;
6
+ /**
7
+ * Creates a custom color palette for testing
8
+ */
9
+ export declare const createMockColorPalette: (baseColor?: string) => ColorPalette;
10
+ /**
11
+ * Mock DOM utilities for testing
12
+ */
13
+ export declare const mockDocumentElement: () => {
14
+ setProperty: jest.Mock<any, any, any>;
15
+ getPropertyValue: jest.Mock<any, any, any>;
16
+ cleanup: () => void;
17
+ };
18
+ /**
19
+ * Mock localStorage utilities for testing
20
+ */
21
+ export declare const mockLocalStorage: () => {
22
+ getItem: jest.Mock<string | null, [key: string], any>;
23
+ setItem: jest.Mock<void, [key: string, value: string], any>;
24
+ removeItem: jest.Mock<void, [key: string], any>;
25
+ clear: jest.Mock<void, [], any>;
26
+ store: Record<string, string>;
27
+ cleanup: () => void;
28
+ };
29
+ /**
30
+ * Test helper to count CSS variable types
31
+ */
32
+ export declare const countCSSVariableTypes: (variables: Record<string, string>) => {
33
+ colors: number;
34
+ fontFamily: number;
35
+ fontSize: number;
36
+ lineHeight: number;
37
+ spacing: number;
38
+ borderRadius: number;
39
+ boxShadow: number;
40
+ total: number;
41
+ };
42
+ /**
43
+ * Assertion helpers for theme testing
44
+ */
45
+ export declare const themeAssertions: {
46
+ /**
47
+ * Assert that all expected CSS variables are present
48
+ */
49
+ hasAllCSSVariables: (variables: Record<string, string>) => void;
50
+ /**
51
+ * Assert that CSS variable follows naming convention
52
+ */
53
+ hasValidCSSVariableName: (name: string) => void;
54
+ /**
55
+ * Assert that theme has required structure
56
+ */
57
+ hasValidThemeStructure: (theme: Theme) => void;
58
+ };
59
+ /**
60
+ * Test scenarios for theme testing
61
+ */
62
+ export declare const testScenarios: {
63
+ /**
64
+ * Common theme override scenarios
65
+ */
66
+ themeOverrides: ({
67
+ name: string;
68
+ override: {
69
+ colors: {
70
+ primary: ColorPalette;
71
+ };
72
+ spacing?: undefined;
73
+ typography?: undefined;
74
+ borderRadius?: undefined;
75
+ };
76
+ } | {
77
+ name: string;
78
+ override: {
79
+ spacing: {
80
+ md: string;
81
+ lg: string;
82
+ };
83
+ colors?: undefined;
84
+ typography?: undefined;
85
+ borderRadius?: undefined;
86
+ };
87
+ } | {
88
+ name: string;
89
+ override: {
90
+ typography: {
91
+ fontFamily: {
92
+ sans: string[];
93
+ };
94
+ fontSize: {
95
+ base: string;
96
+ };
97
+ };
98
+ colors?: undefined;
99
+ spacing?: undefined;
100
+ borderRadius?: undefined;
101
+ };
102
+ } | {
103
+ name: string;
104
+ override: {
105
+ borderRadius: {
106
+ md: string;
107
+ lg: string;
108
+ };
109
+ colors?: undefined;
110
+ spacing?: undefined;
111
+ typography?: undefined;
112
+ };
113
+ })[];
114
+ /**
115
+ * Edge case scenarios
116
+ */
117
+ edgeCases: ({
118
+ name: string;
119
+ override: {
120
+ colors?: undefined;
121
+ spacing?: undefined;
122
+ };
123
+ } | {
124
+ name: string;
125
+ override: {
126
+ colors: {
127
+ primary: Partial<ColorPalette>;
128
+ };
129
+ spacing?: undefined;
130
+ };
131
+ } | {
132
+ name: string;
133
+ override: {
134
+ spacing: {
135
+ md: any;
136
+ };
137
+ colors?: undefined;
138
+ };
139
+ })[];
140
+ };
141
+ /**
142
+ * Performance testing utilities
143
+ */
144
+ export declare const performanceHelpers: {
145
+ /**
146
+ * Measure time for theme application
147
+ */
148
+ measureThemeApplicationTime: (fn: () => void) => Promise<number>;
149
+ /**
150
+ * Stress test theme switching
151
+ */
152
+ stressTestThemeSwitching: (switchFn: () => void, iterations?: number) => {
153
+ average: number;
154
+ min: number;
155
+ max: number;
156
+ total: number;
157
+ };
158
+ };
159
+ //# sourceMappingURL=test-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../src/lib/test-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAEpD;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,YAAW,OAAO,CAAC,KAAK,CAAM,KAAG,KAqGhE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,sBAAsB,GACjC,kBAAqB,KACpB,YAYD,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;CA4B/B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;;;CA2C5B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,GAAI,WAAW,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;;;;;;;;;CAyBtE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe;IAC1B;;OAEG;oCAC6B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAYtD;;OAEG;oCAC6B,MAAM;IAItC;;OAEG;oCAC6B,KAAK;CAiBtC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa;IACxB;;OAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA2CH;;OAEG;;;;;;;;;;;yBAYU,OAAO,CAAC,YAAY,CAAC;;;;;;;;oBAUd,GAAG;;;;;CAKxB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB;IAC7B;;OAEG;sCACqC,MAAM,IAAI,KAAG,OAAO,CAAC,MAAM,CAAC;IAOpE;;OAEG;yCACkC,MAAM,IAAI;;;;;;CAiBhD,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { default as React } from 'react';
2
+ import { Theme, ThemeContextValue, ThemeMode } from './theme.types';
3
+ export declare const useTheme: () => ThemeContextValue;
4
+ interface ThemeProviderProps {
5
+ children: React.ReactNode;
6
+ initialTheme?: Theme;
7
+ initialMode?: ThemeMode;
8
+ }
9
+ export declare const ThemeProvider: React.FC<ThemeProviderProps>;
10
+ export {};
11
+ //# sourceMappingURL=theme-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-provider.d.ts","sourceRoot":"","sources":["../../src/lib/theme-provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyD,MAAM,OAAO,CAAC;AAC9E,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAWpE,eAAO,MAAM,QAAQ,QAAO,iBAM3B,CAAC;AAEF,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA6CtD,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { Theme } from './theme.types';
2
+ export declare const generateCSSVariables: (theme: Theme) => Record<string, string>;
3
+ export declare const applyThemeToDOM: (theme: Theme) => void;
4
+ export declare const mergeThemes: (baseTheme: Theme, overrideTheme: Partial<Theme>) => Theme;
5
+ export declare const saveThemeMode: (mode: "light" | "dark") => void;
6
+ export declare const loadThemeMode: () => "light" | "dark" | null;
7
+ //# sourceMappingURL=theme-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-utils.d.ts","sourceRoot":"","sources":["../../src/lib/theme-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEtC,eAAO,MAAM,oBAAoB,GAAI,OAAO,KAAK,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CA2CxE,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,OAAO,KAAK,KAAG,IAS9C,CAAC;AAEF,eAAO,MAAM,WAAW,GACtB,WAAW,KAAK,EAChB,eAAe,OAAO,CAAC,KAAK,CAAC,KAC5B,KAoDF,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,MAAM,OAAO,GAAG,MAAM,KAAG,IAItD,CAAC;AAEF,eAAO,MAAM,aAAa,QAAO,OAAO,GAAG,MAAM,GAAG,IAOnD,CAAC"}
@@ -0,0 +1,100 @@
1
+ export interface ColorPalette {
2
+ 50?: string;
3
+ 100?: string;
4
+ 200?: string;
5
+ 300?: string;
6
+ 400?: string;
7
+ 500?: string;
8
+ 600?: string;
9
+ 700?: string;
10
+ 800?: string;
11
+ 900?: string;
12
+ 950?: string;
13
+ }
14
+ export interface TypographyScale {
15
+ xs?: string | [string, {
16
+ lineHeight: string;
17
+ }];
18
+ sm?: string | [string, {
19
+ lineHeight: string;
20
+ }];
21
+ base?: string | [string, {
22
+ lineHeight: string;
23
+ }];
24
+ lg?: string | [string, {
25
+ lineHeight: string;
26
+ }];
27
+ xl?: string | [string, {
28
+ lineHeight: string;
29
+ }];
30
+ '2xl'?: string | [string, {
31
+ lineHeight: string;
32
+ }];
33
+ '3xl'?: string | [string, {
34
+ lineHeight: string;
35
+ }];
36
+ '4xl'?: string | [string, {
37
+ lineHeight: string;
38
+ }];
39
+ '5xl'?: string | [string, {
40
+ lineHeight: string;
41
+ }];
42
+ '6xl'?: string | [string, {
43
+ lineHeight: string;
44
+ }];
45
+ }
46
+ export interface SpacingScale {
47
+ xs?: string;
48
+ sm?: string;
49
+ md?: string;
50
+ lg?: string;
51
+ xl?: string;
52
+ '2xl'?: string;
53
+ '3xl'?: string;
54
+ }
55
+ export interface BorderRadiusScale {
56
+ none?: string;
57
+ sm?: string;
58
+ md?: string;
59
+ lg?: string;
60
+ xl?: string;
61
+ full?: string;
62
+ }
63
+ export interface ShadowScale {
64
+ sm?: string;
65
+ md?: string;
66
+ lg?: string;
67
+ xl?: string;
68
+ '2xl'?: string;
69
+ }
70
+ export interface FontFamily {
71
+ sans?: string[];
72
+ serif?: string[];
73
+ mono?: string[];
74
+ }
75
+ export interface ThemeColors {
76
+ primary?: ColorPalette;
77
+ secondary?: ColorPalette;
78
+ neutral?: ColorPalette;
79
+ success?: ColorPalette;
80
+ warning?: ColorPalette;
81
+ error?: ColorPalette;
82
+ }
83
+ export interface Theme {
84
+ colors?: ThemeColors;
85
+ typography?: {
86
+ fontFamily?: FontFamily;
87
+ fontSize?: TypographyScale;
88
+ };
89
+ spacing?: SpacingScale;
90
+ borderRadius?: BorderRadiusScale;
91
+ boxShadow?: ShadowScale;
92
+ }
93
+ export type ThemeMode = 'light' | 'dark';
94
+ export interface ThemeContextValue {
95
+ theme: Theme;
96
+ mode: ThemeMode;
97
+ setMode: (mode: ThemeMode) => void;
98
+ setTheme: (theme: Partial<Theme>) => void;
99
+ }
100
+ //# sourceMappingURL=theme.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.types.d.ts","sourceRoot":"","sources":["../../src/lib/theme.types.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@open-kingdom/shared-frontend-ui-theme",
3
+ "version": "0.0.2-0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "development": "./src/index.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "./package.json": "./package.json"
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "!**/*.tsbuildinfo"
20
+ ],
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "nx": {
25
+ "name": "@open-kingdom/shared-frontend-ui-theme",
26
+ "tags": [
27
+ "scope:shared",
28
+ "type:ui",
29
+ "environment:frontend"
30
+ ]
31
+ },
32
+ "peerDependencies": {
33
+ "tailwindcss": "^3.4.0",
34
+ "react": "^19.0.0"
35
+ }
36
+ }