@idealyst/theme 1.1.6 → 1.1.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idealyst/theme",
3
- "version": "1.1.6",
3
+ "version": "1.1.7",
4
4
  "description": "Theming system for Idealyst Framework",
5
5
  "readme": "README.md",
6
6
  "main": "src/index.ts",
package/src/builder.ts ADDED
@@ -0,0 +1,317 @@
1
+ import {
2
+ IntentValue,
3
+ ShadowValue,
4
+ InteractionConfig,
5
+ ColorValue,
6
+ Shade,
7
+ Typography,
8
+ TypographyValue,
9
+ ButtonSizeValue,
10
+ ChipSizeValue,
11
+ BadgeSizeValue,
12
+ IconSizeValue,
13
+ InputSizeValue,
14
+ RadioButtonSizeValue,
15
+ SelectSizeValue,
16
+ SliderSizeValue,
17
+ SwitchSizeValue,
18
+ TextAreaSizeValue,
19
+ AvatarSizeValue,
20
+ ProgressSizeValue,
21
+ AccordionSizeValue,
22
+ ActivityIndicatorSizeValue,
23
+ BreadcrumbSizeValue,
24
+ ListSizeValue,
25
+ MenuSizeValue,
26
+ TextSizeValue,
27
+ TabBarSizeValue,
28
+ TableSizeValue,
29
+ TooltipSizeValue,
30
+ ViewSizeValue,
31
+ } from './theme/structures';
32
+
33
+ /**
34
+ * Built theme structure - self-contained, no external type dependencies.
35
+ */
36
+ export type BuiltTheme<
37
+ TIntents extends string,
38
+ TRadii extends string,
39
+ TShadows extends string,
40
+ TPallet extends string,
41
+ TSurface extends string,
42
+ TText extends string,
43
+ TBorder extends string,
44
+ TSize extends string,
45
+ > = {
46
+ intents: Record<TIntents, IntentValue>;
47
+ radii: Record<TRadii, number>;
48
+ shadows: Record<TShadows, ShadowValue>;
49
+ colors: {
50
+ pallet: Record<TPallet, Record<Shade, ColorValue>>;
51
+ surface: Record<TSurface, ColorValue>;
52
+ text: Record<TText, ColorValue>;
53
+ border: Record<TBorder, ColorValue>;
54
+ };
55
+ sizes: {
56
+ button: Record<TSize, ButtonSizeValue>;
57
+ chip: Record<TSize, ChipSizeValue>;
58
+ badge: Record<TSize, BadgeSizeValue>;
59
+ icon: Record<TSize, IconSizeValue>;
60
+ input: Record<TSize, InputSizeValue>;
61
+ radioButton: Record<TSize, RadioButtonSizeValue>;
62
+ select: Record<TSize, SelectSizeValue>;
63
+ slider: Record<TSize, SliderSizeValue>;
64
+ switch: Record<TSize, SwitchSizeValue>;
65
+ textarea: Record<TSize, TextAreaSizeValue>;
66
+ avatar: Record<TSize, AvatarSizeValue>;
67
+ progress: Record<TSize, ProgressSizeValue>;
68
+ accordion: Record<TSize, AccordionSizeValue>;
69
+ activityIndicator: Record<TSize, ActivityIndicatorSizeValue>;
70
+ breadcrumb: Record<TSize, BreadcrumbSizeValue>;
71
+ list: Record<TSize, ListSizeValue>;
72
+ menu: Record<TSize, MenuSizeValue>;
73
+ text: Record<TSize, TextSizeValue>;
74
+ tabBar: Record<TSize, TabBarSizeValue>;
75
+ table: Record<TSize, TableSizeValue>;
76
+ tooltip: Record<TSize, TooltipSizeValue>;
77
+ view: Record<TSize, ViewSizeValue>;
78
+ typography: Record<Typography, TypographyValue>;
79
+ };
80
+ interaction: InteractionConfig;
81
+ };
82
+
83
+ /**
84
+ * Internal config type for building.
85
+ */
86
+ type ThemeConfig<
87
+ TIntents extends string,
88
+ TRadii extends string,
89
+ TShadows extends string,
90
+ TPallet extends string,
91
+ TSurface extends string,
92
+ TText extends string,
93
+ TBorder extends string,
94
+ TSize extends string,
95
+ > = BuiltTheme<TIntents, TRadii, TShadows, TPallet, TSurface, TText, TBorder, TSize>;
96
+
97
+ /**
98
+ * Fluent builder for creating themes with full TypeScript inference.
99
+ *
100
+ * Build a theme, then register it to get automatic type inference for all components:
101
+ *
102
+ * @example
103
+ * ```typescript
104
+ * const myTheme = createTheme()
105
+ * .addIntent('primary', { primary: '#3b82f6', contrast: '#fff', light: '#bfdbfe', dark: '#1e40af' })
106
+ * .addIntent('brand', { primary: '#6366f1', contrast: '#fff', light: '#818cf8', dark: '#4f46e5' })
107
+ * .addRadius('sm', 4)
108
+ * .addRadius('full', 9999)
109
+ * .build();
110
+ *
111
+ * // Register the theme type
112
+ * declare module '@idealyst/theme' {
113
+ * interface RegisteredTheme {
114
+ * theme: typeof myTheme;
115
+ * }
116
+ * }
117
+ *
118
+ * // Now Intent = 'primary' | 'brand', Radius = 'sm' | 'full', etc.
119
+ * ```
120
+ */
121
+ export class ThemeBuilder<
122
+ TIntents extends string = never,
123
+ TRadii extends string = never,
124
+ TShadows extends string = never,
125
+ TPallet extends string = never,
126
+ TSurface extends string = never,
127
+ TText extends string = never,
128
+ TBorder extends string = never,
129
+ TSize extends string = never,
130
+ > {
131
+ private config: ThemeConfig<TIntents, TRadii, TShadows, TPallet, TSurface, TText, TBorder, TSize>;
132
+
133
+ constructor() {
134
+ this.config = {
135
+ intents: {} as any,
136
+ radii: {} as any,
137
+ shadows: {} as any,
138
+ colors: {
139
+ pallet: {} as any,
140
+ surface: {} as any,
141
+ text: {} as any,
142
+ border: {} as any,
143
+ },
144
+ sizes: {} as any,
145
+ interaction: {} as any,
146
+ };
147
+ }
148
+
149
+ /**
150
+ * Add a custom intent to the theme.
151
+ */
152
+ addIntent<K extends string>(
153
+ name: K,
154
+ value: IntentValue
155
+ ): ThemeBuilder<TIntents | K, TRadii, TShadows, TPallet, TSurface, TText, TBorder, TSize> {
156
+ const newBuilder = new ThemeBuilder<TIntents | K, TRadii, TShadows, TPallet, TSurface, TText, TBorder, TSize>();
157
+ newBuilder.config = {
158
+ ...this.config,
159
+ intents: {
160
+ ...this.config.intents,
161
+ [name]: value,
162
+ } as any,
163
+ };
164
+ return newBuilder;
165
+ }
166
+
167
+ /**
168
+ * Add a custom border radius value.
169
+ */
170
+ addRadius<K extends string>(
171
+ name: K,
172
+ value: number
173
+ ): ThemeBuilder<TIntents, TRadii | K, TShadows, TPallet, TSurface, TText, TBorder, TSize> {
174
+ const newBuilder = new ThemeBuilder<TIntents, TRadii | K, TShadows, TPallet, TSurface, TText, TBorder, TSize>();
175
+ newBuilder.config = {
176
+ ...this.config,
177
+ radii: {
178
+ ...this.config.radii,
179
+ [name]: value,
180
+ } as any,
181
+ };
182
+ return newBuilder;
183
+ }
184
+
185
+ /**
186
+ * Add a custom shadow value.
187
+ */
188
+ addShadow<K extends string>(
189
+ name: K,
190
+ value: ShadowValue
191
+ ): ThemeBuilder<TIntents, TRadii, TShadows | K, TPallet, TSurface, TText, TBorder, TSize> {
192
+ const newBuilder = new ThemeBuilder<TIntents, TRadii, TShadows | K, TPallet, TSurface, TText, TBorder, TSize>();
193
+ newBuilder.config = {
194
+ ...this.config,
195
+ shadows: {
196
+ ...this.config.shadows,
197
+ [name]: value,
198
+ } as any,
199
+ };
200
+ return newBuilder;
201
+ }
202
+
203
+ /**
204
+ * Set the interaction configuration.
205
+ */
206
+ setInteraction(
207
+ interaction: InteractionConfig
208
+ ): ThemeBuilder<TIntents, TRadii, TShadows, TPallet, TSurface, TText, TBorder, TSize> {
209
+ const newBuilder = new ThemeBuilder<TIntents, TRadii, TShadows, TPallet, TSurface, TText, TBorder, TSize>();
210
+ newBuilder.config = {
211
+ ...this.config,
212
+ interaction,
213
+ };
214
+ return newBuilder;
215
+ }
216
+
217
+ /**
218
+ * Set the colors configuration.
219
+ */
220
+ setColors<
221
+ P extends string,
222
+ S extends string,
223
+ T extends string,
224
+ B extends string,
225
+ >(colors: {
226
+ pallet: Record<P, Record<Shade, ColorValue>>;
227
+ surface: Record<S, ColorValue>;
228
+ text: Record<T, ColorValue>;
229
+ border: Record<B, ColorValue>;
230
+ }): ThemeBuilder<TIntents, TRadii, TShadows, P, S, T, B, TSize> {
231
+ const newBuilder = new ThemeBuilder<TIntents, TRadii, TShadows, P, S, T, B, TSize>();
232
+ newBuilder.config = {
233
+ ...this.config,
234
+ colors,
235
+ } as any;
236
+ return newBuilder;
237
+ }
238
+
239
+ /**
240
+ * Set the sizes configuration.
241
+ */
242
+ setSizes<S extends string>(sizes: {
243
+ button: Record<S, ButtonSizeValue>;
244
+ chip: Record<S, ChipSizeValue>;
245
+ badge: Record<S, BadgeSizeValue>;
246
+ icon: Record<S, IconSizeValue>;
247
+ input: Record<S, InputSizeValue>;
248
+ radioButton: Record<S, RadioButtonSizeValue>;
249
+ select: Record<S, SelectSizeValue>;
250
+ slider: Record<S, SliderSizeValue>;
251
+ switch: Record<S, SwitchSizeValue>;
252
+ textarea: Record<S, TextAreaSizeValue>;
253
+ avatar: Record<S, AvatarSizeValue>;
254
+ progress: Record<S, ProgressSizeValue>;
255
+ accordion: Record<S, AccordionSizeValue>;
256
+ activityIndicator: Record<S, ActivityIndicatorSizeValue>;
257
+ breadcrumb: Record<S, BreadcrumbSizeValue>;
258
+ list: Record<S, ListSizeValue>;
259
+ menu: Record<S, MenuSizeValue>;
260
+ text: Record<S, TextSizeValue>;
261
+ tabBar: Record<S, TabBarSizeValue>;
262
+ table: Record<S, TableSizeValue>;
263
+ tooltip: Record<S, TooltipSizeValue>;
264
+ view: Record<S, ViewSizeValue>;
265
+ typography: Record<Typography, TypographyValue>;
266
+ }): ThemeBuilder<TIntents, TRadii, TShadows, TPallet, TSurface, TText, TBorder, S> {
267
+ const newBuilder = new ThemeBuilder<TIntents, TRadii, TShadows, TPallet, TSurface, TText, TBorder, S>();
268
+ newBuilder.config = {
269
+ ...this.config,
270
+ sizes,
271
+ } as any;
272
+ return newBuilder;
273
+ }
274
+
275
+ /**
276
+ * Build the final theme object.
277
+ */
278
+ build(): BuiltTheme<TIntents, TRadii, TShadows, TPallet, TSurface, TText, TBorder, TSize> {
279
+ return this.config;
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Create a new theme builder.
285
+ */
286
+ export function createTheme(): ThemeBuilder {
287
+ return new ThemeBuilder();
288
+ }
289
+
290
+ /**
291
+ * Create a builder from an existing theme to add more values.
292
+ */
293
+ export function fromTheme<T extends BuiltTheme<any, any, any, any, any, any, any, any>>(
294
+ base: T
295
+ ): ThemeBuilder<
296
+ keyof T['intents'] & string,
297
+ keyof T['radii'] & string,
298
+ keyof T['shadows'] & string,
299
+ keyof T['colors']['pallet'] & string,
300
+ keyof T['colors']['surface'] & string,
301
+ keyof T['colors']['text'] & string,
302
+ keyof T['colors']['border'] & string,
303
+ keyof T['sizes']['button'] & string
304
+ > {
305
+ const builder = new ThemeBuilder<
306
+ keyof T['intents'] & string,
307
+ keyof T['radii'] & string,
308
+ keyof T['shadows'] & string,
309
+ keyof T['colors']['pallet'] & string,
310
+ keyof T['colors']['surface'] & string,
311
+ keyof T['colors']['text'] & string,
312
+ keyof T['colors']['border'] & string,
313
+ keyof T['sizes']['button'] & string
314
+ >();
315
+ (builder as any).config = { ...base };
316
+ return builder;
317
+ }