-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy paththeme.zod.ts
More file actions
282 lines (241 loc) · 12 KB
/
theme.zod.ts
File metadata and controls
282 lines (241 loc) · 12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
import { z } from 'zod';
import { SnakeCaseIdentifierSchema } from '../shared/identifiers.zod';
import { TouchTargetConfigSchema } from './touch.zod';
import { FocusManagementSchema } from './keyboard.zod';
/**
* Color Palette Schema
* Defines brand colors and their variants.
*/
export const ColorPaletteSchema = z.object({
primary: z.string().describe('Primary brand color (hex, rgb, or hsl)'),
secondary: z.string().optional().describe('Secondary brand color'),
accent: z.string().optional().describe('Accent color for highlights'),
success: z.string().optional().describe('Success state color (default: green)'),
warning: z.string().optional().describe('Warning state color (default: yellow)'),
error: z.string().optional().describe('Error state color (default: red)'),
info: z.string().optional().describe('Info state color (default: blue)'),
// Neutral colors
background: z.string().optional().describe('Background color'),
surface: z.string().optional().describe('Surface/card background color'),
text: z.string().optional().describe('Primary text color'),
textSecondary: z.string().optional().describe('Secondary text color'),
border: z.string().optional().describe('Border color'),
disabled: z.string().optional().describe('Disabled state color'),
// Color variants (shades)
primaryLight: z.string().optional().describe('Lighter shade of primary'),
primaryDark: z.string().optional().describe('Darker shade of primary'),
secondaryLight: z.string().optional().describe('Lighter shade of secondary'),
secondaryDark: z.string().optional().describe('Darker shade of secondary'),
});
/**
* Typography Settings Schema
* Font families, sizes, weights, and line heights.
*/
export const TypographySchema = z.object({
fontFamily: z.object({
base: z.string().optional().describe('Base font family (default: system fonts)'),
heading: z.string().optional().describe('Heading font family'),
mono: z.string().optional().describe('Monospace font family for code'),
}).optional(),
fontSize: z.object({
xs: z.string().optional().describe('Extra small font size (e.g., 0.75rem)'),
sm: z.string().optional().describe('Small font size (e.g., 0.875rem)'),
base: z.string().optional().describe('Base font size (e.g., 1rem)'),
lg: z.string().optional().describe('Large font size (e.g., 1.125rem)'),
xl: z.string().optional().describe('Extra large font size (e.g., 1.25rem)'),
'2xl': z.string().optional().describe('2X large font size (e.g., 1.5rem)'),
'3xl': z.string().optional().describe('3X large font size (e.g., 1.875rem)'),
'4xl': z.string().optional().describe('4X large font size (e.g., 2.25rem)'),
}).optional(),
fontWeight: z.object({
light: z.number().optional().describe('Light weight (default: 300)'),
normal: z.number().optional().describe('Normal weight (default: 400)'),
medium: z.number().optional().describe('Medium weight (default: 500)'),
semibold: z.number().optional().describe('Semibold weight (default: 600)'),
bold: z.number().optional().describe('Bold weight (default: 700)'),
}).optional(),
lineHeight: z.object({
tight: z.string().optional().describe('Tight line height (e.g., 1.25)'),
normal: z.string().optional().describe('Normal line height (e.g., 1.5)'),
relaxed: z.string().optional().describe('Relaxed line height (e.g., 1.75)'),
loose: z.string().optional().describe('Loose line height (e.g., 2)'),
}).optional(),
letterSpacing: z.object({
tighter: z.string().optional().describe('Tighter letter spacing (e.g., -0.05em)'),
tight: z.string().optional().describe('Tight letter spacing (e.g., -0.025em)'),
normal: z.string().optional().describe('Normal letter spacing (e.g., 0)'),
wide: z.string().optional().describe('Wide letter spacing (e.g., 0.025em)'),
wider: z.string().optional().describe('Wider letter spacing (e.g., 0.05em)'),
}).optional(),
});
/**
* Spacing Units Schema
* Defines spacing scale for margins, padding, gaps.
*/
export const SpacingSchema = z.object({
'0': z.string().optional().describe('0 spacing (0)'),
'1': z.string().optional().describe('Spacing unit 1 (e.g., 0.25rem)'),
'2': z.string().optional().describe('Spacing unit 2 (e.g., 0.5rem)'),
'3': z.string().optional().describe('Spacing unit 3 (e.g., 0.75rem)'),
'4': z.string().optional().describe('Spacing unit 4 (e.g., 1rem)'),
'5': z.string().optional().describe('Spacing unit 5 (e.g., 1.25rem)'),
'6': z.string().optional().describe('Spacing unit 6 (e.g., 1.5rem)'),
'8': z.string().optional().describe('Spacing unit 8 (e.g., 2rem)'),
'10': z.string().optional().describe('Spacing unit 10 (e.g., 2.5rem)'),
'12': z.string().optional().describe('Spacing unit 12 (e.g., 3rem)'),
'16': z.string().optional().describe('Spacing unit 16 (e.g., 4rem)'),
'20': z.string().optional().describe('Spacing unit 20 (e.g., 5rem)'),
'24': z.string().optional().describe('Spacing unit 24 (e.g., 6rem)'),
});
/**
* Border Radius Schema
* Rounded corners configuration.
*/
export const BorderRadiusSchema = z.object({
none: z.string().optional().describe('No border radius (0)'),
sm: z.string().optional().describe('Small border radius (e.g., 0.125rem)'),
base: z.string().optional().describe('Base border radius (e.g., 0.25rem)'),
md: z.string().optional().describe('Medium border radius (e.g., 0.375rem)'),
lg: z.string().optional().describe('Large border radius (e.g., 0.5rem)'),
xl: z.string().optional().describe('Extra large border radius (e.g., 0.75rem)'),
'2xl': z.string().optional().describe('2X large border radius (e.g., 1rem)'),
full: z.string().optional().describe('Full border radius (50%)'),
});
/**
* Shadow Schema
* Box shadow effects.
*/
export const ShadowSchema = z.object({
none: z.string().optional().describe('No shadow'),
sm: z.string().optional().describe('Small shadow'),
base: z.string().optional().describe('Base shadow'),
md: z.string().optional().describe('Medium shadow'),
lg: z.string().optional().describe('Large shadow'),
xl: z.string().optional().describe('Extra large shadow'),
'2xl': z.string().optional().describe('2X large shadow'),
inner: z.string().optional().describe('Inner shadow (inset)'),
});
/**
* Breakpoints Schema
* Responsive design breakpoints.
*/
export const BreakpointsSchema = z.object({
xs: z.string().optional().describe('Extra small breakpoint (e.g., 480px)'),
sm: z.string().optional().describe('Small breakpoint (e.g., 640px)'),
md: z.string().optional().describe('Medium breakpoint (e.g., 768px)'),
lg: z.string().optional().describe('Large breakpoint (e.g., 1024px)'),
xl: z.string().optional().describe('Extra large breakpoint (e.g., 1280px)'),
'2xl': z.string().optional().describe('2X large breakpoint (e.g., 1536px)'),
});
/**
* Animation Schema
* Animation timing and duration settings.
*/
export const AnimationSchema = z.object({
duration: z.object({
fast: z.string().optional().describe('Fast animation (e.g., 150ms)'),
base: z.string().optional().describe('Base animation (e.g., 300ms)'),
slow: z.string().optional().describe('Slow animation (e.g., 500ms)'),
}).optional(),
timing: z.object({
linear: z.string().optional().describe('Linear timing function'),
ease: z.string().optional().describe('Ease timing function'),
ease_in: z.string().optional().describe('Ease-in timing function'),
ease_out: z.string().optional().describe('Ease-out timing function'),
ease_in_out: z.string().optional().describe('Ease-in-out timing function'),
}).optional(),
});
/**
* Z-Index Scale Schema
* Layering and stacking order.
*/
export const ZIndexSchema = z.object({
base: z.number().optional().describe('Base z-index (e.g., 0)'),
dropdown: z.number().optional().describe('Dropdown z-index (e.g., 1000)'),
sticky: z.number().optional().describe('Sticky z-index (e.g., 1020)'),
fixed: z.number().optional().describe('Fixed z-index (e.g., 1030)'),
modalBackdrop: z.number().optional().describe('Modal backdrop z-index (e.g., 1040)'),
modal: z.number().optional().describe('Modal z-index (e.g., 1050)'),
popover: z.number().optional().describe('Popover z-index (e.g., 1060)'),
tooltip: z.number().optional().describe('Tooltip z-index (e.g., 1070)'),
});
/**
* Theme Mode Schema
*/
export const ThemeModeSchema = z.enum(['light', 'dark', 'auto']);
/** @deprecated Use ThemeModeSchema instead */
export const ThemeMode = ThemeModeSchema;
/**
* Density Mode Schema
* Controls spacing and sizing for different use cases.
*/
export const DensityModeSchema = z.enum(['compact', 'regular', 'spacious']);
/** @deprecated Use DensityModeSchema instead */
export const DensityMode = DensityModeSchema;
/**
* WCAG Contrast Level Schema
* Web Content Accessibility Guidelines color contrast requirements.
*/
export const WcagContrastLevelSchema = z.enum(['AA', 'AAA']);
/** @deprecated Use WcagContrastLevelSchema instead */
export const WcagContrastLevel = WcagContrastLevelSchema;
/**
* Theme Configuration Schema
* Complete theme definition for brand customization.
*/
export const ThemeSchema = z.object({
name: SnakeCaseIdentifierSchema.describe('Unique theme identifier (snake_case)'),
label: z.string().describe('Human-readable theme name'),
description: z.string().optional().describe('Theme description'),
/** Theme mode */
mode: ThemeModeSchema.default('light').describe('Theme mode (light, dark, or auto)'),
/** Color system */
colors: ColorPaletteSchema.describe('Color palette configuration'),
/** Typography */
typography: TypographySchema.optional().describe('Typography settings'),
/** Spacing */
spacing: SpacingSchema.optional().describe('Spacing scale'),
/** Border radius */
borderRadius: BorderRadiusSchema.optional().describe('Border radius scale'),
/** Shadows */
shadows: ShadowSchema.optional().describe('Box shadow effects'),
/** Breakpoints */
breakpoints: BreakpointsSchema.optional().describe('Responsive breakpoints'),
/** Animation */
animation: AnimationSchema.optional().describe('Animation settings'),
/** Z-Index */
zIndex: ZIndexSchema.optional().describe('Z-index scale for layering'),
/** Custom CSS variables */
customVars: z.record(z.string(), z.string()).optional().describe('Custom CSS variables (key-value pairs)'),
/** Logo */
logo: z.object({
light: z.string().optional().describe('Logo URL for light mode'),
dark: z.string().optional().describe('Logo URL for dark mode'),
favicon: z.string().optional().describe('Favicon URL'),
}).optional().describe('Logo assets'),
/** Extends another theme */
extends: z.string().optional().describe('Base theme to extend from'),
/** Display density mode */
density: DensityModeSchema.optional().describe('Display density: compact, regular, or spacious'),
/** WCAG contrast level requirement */
wcagContrast: WcagContrastLevelSchema.optional().describe('WCAG color contrast level (AA or AAA)'),
/** Right-to-left language support */
rtl: z.boolean().optional().describe('Enable right-to-left layout direction'),
/** Touch target accessibility configuration */
touchTarget: TouchTargetConfigSchema.optional().describe('Touch target sizing defaults'),
/** Keyboard navigation and focus management */
keyboardNavigation: FocusManagementSchema.optional().describe('Keyboard focus management settings'),
});
export type Theme = z.infer<typeof ThemeSchema>;
export type ColorPalette = z.infer<typeof ColorPaletteSchema>;
export type Typography = z.infer<typeof TypographySchema>;
export type Spacing = z.infer<typeof SpacingSchema>;
export type BorderRadius = z.infer<typeof BorderRadiusSchema>;
export type Shadow = z.infer<typeof ShadowSchema>;
export type Breakpoints = z.infer<typeof BreakpointsSchema>;
export type Animation = z.infer<typeof AnimationSchema>;
export type ZIndex = z.infer<typeof ZIndexSchema>;
export type ThemeMode = z.infer<typeof ThemeModeSchema>;
export type DensityMode = z.infer<typeof DensityModeSchema>;
export type WcagContrastLevel = z.infer<typeof WcagContrastLevelSchema>;