@idealyst/theme 1.1.6 → 1.1.8

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.
@@ -0,0 +1,108 @@
1
+ /**
2
+ * StyleBuilder - Declarative styling system with extension support
3
+ *
4
+ * All transformations happen at BUILD TIME via Babel plugin.
5
+ * These functions are replaced with StyleSheet.create calls.
6
+ *
7
+ * For extensions to work, import your extension file BEFORE components:
8
+ *
9
+ * ```typescript
10
+ * // App.tsx
11
+ * import './style-extensions'; // FIRST
12
+ * import { Text } from '@idealyst/components'; // SECOND
13
+ * ```
14
+ */
15
+
16
+ import { StyleSheet } from 'react-native-unistyles';
17
+ import type { ComponentStyleRegistry, ExtendStyleDef, OverrideStyleDef } from './componentStyles';
18
+
19
+ export type ComponentName =
20
+ | 'Accordion'
21
+ | 'ActivityIndicator'
22
+ | 'Alert'
23
+ | 'Avatar'
24
+ | 'Badge'
25
+ | 'Breadcrumb'
26
+ | 'Button'
27
+ | 'Card'
28
+ | 'Checkbox'
29
+ | 'Chip'
30
+ | 'Dialog'
31
+ | 'Divider'
32
+ | 'Icon'
33
+ | 'Image'
34
+ | 'Input'
35
+ | 'Link'
36
+ | 'List'
37
+ | 'Menu'
38
+ | 'Popover'
39
+ | 'Pressable'
40
+ | 'Progress'
41
+ | 'RadioButton'
42
+ | 'Screen'
43
+ | 'Select'
44
+ | 'Skeleton'
45
+ | 'Slider'
46
+ | 'SVGImage'
47
+ | 'Switch'
48
+ | 'TabBar'
49
+ | 'Table'
50
+ | 'Text'
51
+ | 'TextArea'
52
+ | 'Tooltip'
53
+ | 'Video'
54
+ | 'View';
55
+
56
+ export type StyleCallback<TTheme, TStyles> = (theme: TTheme) => TStyles;
57
+
58
+ /**
59
+ * Define base styles for a component.
60
+ * Babel transforms this to StyleSheet.create with merged extensions.
61
+ */
62
+ export function defineStyle<TTheme, TStyles>(
63
+ _componentName: ComponentName,
64
+ styles: StyleCallback<TTheme, TStyles>
65
+ ): ReturnType<typeof StyleSheet.create> {
66
+ // Babel replaces this - runtime fallback for dev
67
+ return StyleSheet.create(styles as any);
68
+ }
69
+
70
+ /**
71
+ * Extend existing component styles (merged at build time).
72
+ * Import BEFORE components for extensions to apply.
73
+ */
74
+ export function extendStyle<K extends keyof ComponentStyleRegistry>(
75
+ componentName: K,
76
+ styles: (theme: any) => ExtendStyleDef<K>
77
+ ): void;
78
+ export function extendStyle<K extends string>(
79
+ componentName: K,
80
+ styles: (theme: any) => Record<string, any>
81
+ ): void;
82
+ export function extendStyle(
83
+ _componentName: string,
84
+ _styles: (theme: any) => any
85
+ ): void {
86
+ // Babel removes this call and merges into defineStyle
87
+ }
88
+
89
+ /**
90
+ * Override component styles completely (replaces base at build time).
91
+ * Import BEFORE components for overrides to apply.
92
+ */
93
+ export function overrideStyle<K extends keyof ComponentStyleRegistry>(
94
+ componentName: K,
95
+ styles: (theme: any) => OverrideStyleDef<K>
96
+ ): void;
97
+ export function overrideStyle<K extends string>(
98
+ componentName: K,
99
+ styles: (theme: any) => Record<string, any>
100
+ ): void;
101
+ export function overrideStyle(
102
+ _componentName: string,
103
+ _styles: (theme: any) => any
104
+ ): void {
105
+ // Babel removes this call and replaces defineStyle
106
+ }
107
+
108
+ export type { ThemeStyleWrapper } from './extensions';
@@ -1,15 +1,36 @@
1
- export type Pallet = 'red' | 'orange' | 'blue' | 'green' | 'yellow' | 'purple' | 'gray' | 'black' | 'white';
2
- export type Shade = 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;
3
- export type Color = `${Pallet}.${Shade}` | Pallet;
4
- export type ColorValue = string;
5
-
6
- export type Surface = 'primary' | 'secondary' | 'tertiary' | 'inverse' | 'inverse-secondary' | 'inverse-tertiary';
7
- export type Text = 'primary' | 'secondary' | 'tertiary' | 'inverse' | 'inverse-secondary' | 'inverse-tertiary';
8
- export type Border = 'primary' | 'secondary' | 'tertiary' | 'disabled';
9
-
10
- export type AllColorTypes = {
11
- surface: Record<Surface, ColorValue>;
12
- text: Record<Text, ColorValue>;
13
- border: Record<Border, ColorValue>;
14
- pallet: Record<Pallet, Record<Shade, ColorValue>>;
15
- }
1
+ import { RegisteredTheme } from './extensions';
2
+
3
+ /**
4
+ * All available palette color names.
5
+ * Derived from your registered theme's color pallet.
6
+ */
7
+ export type Pallet = keyof RegisteredTheme['theme']['colors']['pallet'] & string;
8
+
9
+ /**
10
+ * Color reference string. Either a palette.shade combination or just a palette name.
11
+ * @example 'blue.500', 'red.100', 'gray'
12
+ */
13
+ export type Color = `${Pallet}.${50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900}` | Pallet;
14
+
15
+ /**
16
+ * All available surface types.
17
+ * Derived from your registered theme's surfaces.
18
+ */
19
+ export type Surface = keyof RegisteredTheme['theme']['colors']['surface'];
20
+
21
+ /**
22
+ * All available text color types.
23
+ * Derived from your registered theme's text colors.
24
+ */
25
+ export type Text = keyof RegisteredTheme['theme']['colors']['text'];
26
+
27
+ /**
28
+ * All available border color types.
29
+ * Derived from your registered theme's borders.
30
+ */
31
+ export type Border = keyof RegisteredTheme['theme']['colors']['border'];
32
+
33
+ /**
34
+ * Complete color system structure.
35
+ */
36
+ export type AllColorTypes = RegisteredTheme['theme']['colors'];
@@ -0,0 +1,99 @@
1
+ /* eslint-disable @typescript-eslint/no-empty-object-type */
2
+
3
+ import type { IntentValue, ShadowValue, Shade, ColorValue, InteractionConfig, ButtonSizeValue, ChipSizeValue, BadgeSizeValue, IconSizeValue, InputSizeValue, RadioButtonSizeValue, SelectSizeValue, SliderSizeValue, SwitchSizeValue, TextAreaSizeValue, AvatarSizeValue, ProgressSizeValue, AccordionSizeValue, ActivityIndicatorSizeValue, BreadcrumbSizeValue, ListSizeValue, MenuSizeValue, TextSizeValue, TabBarSizeValue, TableSizeValue, TooltipSizeValue, ViewSizeValue, Typography, TypographyValue } from './structures';
4
+
5
+ /**
6
+ * Default fallback theme structure.
7
+ * Used when no custom theme is registered.
8
+ */
9
+ export interface DefaultTheme {
10
+ intents: Record<string, IntentValue>;
11
+ radii: Record<string, number>;
12
+ shadows: Record<string, ShadowValue>;
13
+ colors: {
14
+ pallet: Record<string, Record<Shade, ColorValue>>;
15
+ surface: Record<string, ColorValue>;
16
+ text: Record<string, ColorValue>;
17
+ border: Record<string, ColorValue>;
18
+ };
19
+ sizes: {
20
+ button: Record<string, ButtonSizeValue>;
21
+ chip: Record<string, ChipSizeValue>;
22
+ badge: Record<string, BadgeSizeValue>;
23
+ icon: Record<string, IconSizeValue>;
24
+ input: Record<string, InputSizeValue>;
25
+ radioButton: Record<string, RadioButtonSizeValue>;
26
+ select: Record<string, SelectSizeValue>;
27
+ slider: Record<string, SliderSizeValue>;
28
+ switch: Record<string, SwitchSizeValue>;
29
+ textarea: Record<string, TextAreaSizeValue>;
30
+ avatar: Record<string, AvatarSizeValue>;
31
+ progress: Record<string, ProgressSizeValue>;
32
+ accordion: Record<string, AccordionSizeValue>;
33
+ activityIndicator: Record<string, ActivityIndicatorSizeValue>;
34
+ breadcrumb: Record<string, BreadcrumbSizeValue>;
35
+ list: Record<string, ListSizeValue>;
36
+ menu: Record<string, MenuSizeValue>;
37
+ text: Record<string, TextSizeValue>;
38
+ tabBar: Record<string, TabBarSizeValue>;
39
+ table: Record<string, TableSizeValue>;
40
+ tooltip: Record<string, TooltipSizeValue>;
41
+ view: Record<string, ViewSizeValue>;
42
+ typography: Record<Typography, TypographyValue>;
43
+ };
44
+ interaction: InteractionConfig;
45
+ /**
46
+ * Component style extensions.
47
+ * Populated by the extension system when extendComponent is called.
48
+ * Used by the Babel plugin to merge extensions into component styles.
49
+ * @internal
50
+ */
51
+ __extensions?: Record<string, Record<string, any>>;
52
+ }
53
+
54
+ /**
55
+ * CustomThemeRegistry - Augment this interface to register your custom theme.
56
+ *
57
+ * All derived types (Intent, Radius, Size, etc.) come from this interface.
58
+ * Build your theme, then register it via module augmentation:
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * import { createTheme, fromTheme, lightTheme } from '@idealyst/theme';
63
+ *
64
+ * const myTheme = fromTheme(lightTheme)
65
+ * .addIntent('brand', { ... })
66
+ * .addRadius('2xl', 24)
67
+ * .build();
68
+ *
69
+ * // Register your theme to get type inference
70
+ * declare module '@idealyst/theme' {
71
+ * interface CustomThemeRegistry {
72
+ * theme: typeof myTheme;
73
+ * }
74
+ * }
75
+ *
76
+ * // Now all components get: Intent = 'primary' | 'brand' | ..., Radius = 'none' | ... | '2xl', etc.
77
+ * ```
78
+ */
79
+ export interface CustomThemeRegistry {
80
+ // Empty by default - users augment to add 'theme' property
81
+ }
82
+
83
+ /**
84
+ * Helper to extract theme type from registry, falling back to DefaultTheme.
85
+ */
86
+ type ResolveCustomTheme = CustomThemeRegistry extends { theme: infer T } ? T : DefaultTheme;
87
+
88
+ /**
89
+ * RegisteredTheme - Contains the resolved theme type.
90
+ * DO NOT augment this directly - augment CustomThemeRegistry instead.
91
+ */
92
+ export interface RegisteredTheme {
93
+ theme: ResolveCustomTheme;
94
+ }
95
+
96
+ /**
97
+ * Extend this interface to add custom properties to IntentValue.
98
+ */
99
+ export interface IntentValueExtensions {}
@@ -1,36 +1,50 @@
1
- import { AllColorTypes, Color, ColorValue } from "./color";
2
- import { Intent, IntentValue } from "./intent";
3
- import { AllComponentSizes, SizeValue } from "./size";
4
- import { AllShadowTypes } from "./shadow";
1
+ import { RegisteredTheme } from "./extensions";
5
2
 
6
3
  /**
7
- * Interaction state configuration for hover, focus, active states
4
+ * All available border radius values.
5
+ * Derived from your registered theme's radii.
8
6
  */
9
- export type InteractionConfig = {
10
- /** Background color for focused/highlighted items (e.g., list items, select options) */
11
- focusedBackground: string;
12
- /** Border/outline color for focused elements */
13
- focusBorder: string;
14
- /** Opacity values for various interaction states */
15
- opacity: {
16
- /** Opacity for hovered elements */
17
- hover: number;
18
- /** Opacity for active/pressed elements */
19
- active: number;
20
- /** Opacity for disabled elements */
21
- disabled: number;
22
- };
23
- };
7
+ export type Radius = keyof RegisteredTheme['theme']['radii'];
24
8
 
25
- export type Theme = {
26
- intents: Record<Intent, IntentValue>;
27
- colors: AllColorTypes;
28
- sizes: AllComponentSizes;
29
- shadows: AllShadowTypes;
30
- interaction: InteractionConfig;
31
- };
9
+ /**
10
+ * Theme type - derived from RegisteredTheme.
11
+ */
12
+ export type Theme = RegisteredTheme['theme'];
32
13
 
14
+ export * from "./extensions";
33
15
  export * from "./intent";
34
16
  export * from "./size";
35
17
  export * from "./color";
36
18
  export * from "./shadow";
19
+
20
+ // Re-export structures except IntentValue and ShadowValue (those are re-exported with extensions from intent.ts and shadow.ts)
21
+ export type {
22
+ InteractionConfig,
23
+ ColorValue,
24
+ Shade,
25
+ SizeValue,
26
+ Typography,
27
+ TypographyValue,
28
+ ButtonSizeValue,
29
+ ChipSizeValue,
30
+ BadgeSizeValue,
31
+ IconSizeValue,
32
+ InputSizeValue,
33
+ RadioButtonSizeValue,
34
+ SelectSizeValue,
35
+ SliderSizeValue,
36
+ SwitchSizeValue,
37
+ TextAreaSizeValue,
38
+ AvatarSizeValue,
39
+ ProgressSizeValue,
40
+ AccordionSizeValue,
41
+ ActivityIndicatorSizeValue,
42
+ BreadcrumbSizeValue,
43
+ ListSizeValue,
44
+ MenuSizeValue,
45
+ TextSizeValue,
46
+ TabBarSizeValue,
47
+ TableSizeValue,
48
+ TooltipSizeValue,
49
+ ViewSizeValue,
50
+ } from "./structures";
@@ -1,8 +1,13 @@
1
- export type Intent = 'primary' | 'success' | 'error' | 'warning' | 'neutral' | 'info';
1
+ import { RegisteredTheme, IntentValueExtensions } from './extensions';
2
+ import { IntentValue as BaseIntentValue } from './structures';
2
3
 
3
- export type IntentValue = {
4
- primary: string;
5
- contrast: string;
6
- light: string;
7
- dark: string;
8
- }
4
+ /**
5
+ * All available intent types.
6
+ * Derived from your registered theme's intents.
7
+ */
8
+ export type Intent = keyof RegisteredTheme['theme']['intents'];
9
+
10
+ /**
11
+ * Intent value structure with any extensions.
12
+ */
13
+ export type IntentValue = BaseIntentValue & IntentValueExtensions;
@@ -1,18 +1,14 @@
1
- export type ShadowVariant = 'none' | 'sm' | 'md' | 'lg' | 'xl';
1
+ import { RegisteredTheme } from './extensions';
2
+ import type { ShadowValue } from './structures';
3
+ export type { ShadowValue };
2
4
 
3
- export type ShadowValue = {
4
- // Android: elevation value
5
- elevation: number;
5
+ /**
6
+ * All available shadow variant names.
7
+ * Derived from your registered theme's shadows.
8
+ */
9
+ export type ShadowVariant = keyof RegisteredTheme['theme']['shadows'];
6
10
 
7
- // iOS: shadow properties
8
- shadowColor: string;
9
- shadowOffset: {
10
- width: number;
11
- height: number;
12
- };
13
- shadowOpacity: number;
14
- shadowRadius: number;
15
- boxShadow?: string;
16
- } | {}
17
-
18
- export type AllShadowTypes = Record<ShadowVariant, ShadowValue>;
11
+ /**
12
+ * Complete shadow system structure.
13
+ */
14
+ export type AllShadowTypes = RegisteredTheme['theme']['shadows'];
package/src/theme/size.ts CHANGED
@@ -1,208 +1,12 @@
1
- export type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
2
- export type SizeValue = number | string
1
+ import { RegisteredTheme } from './extensions';
3
2
 
4
3
  /**
5
- * Typography variants for semantic text styling
4
+ * All available size variants.
5
+ * Derived from your registered theme's sizes.
6
6
  */
7
- export type Typography =
8
- | 'h1'
9
- | 'h2'
10
- | 'h3'
11
- | 'h4'
12
- | 'h5'
13
- | 'h6'
14
- | 'subtitle1'
15
- | 'subtitle2'
16
- | 'body1'
17
- | 'body2'
18
- | 'caption'
7
+ export type Size = keyof RegisteredTheme['theme']['sizes']['button'];
19
8
 
20
9
  /**
21
- * Typography style values
10
+ * Complete component sizes structure.
22
11
  */
23
- export type TypographyValue = {
24
- fontSize: SizeValue;
25
- lineHeight: SizeValue;
26
- fontWeight: '300' | '400' | '500' | '600' | '700';
27
- }
28
-
29
- // Size alone is not very useful, as sizes are contextual based on the component
30
- export type AllComponentSizes = {
31
- button: Record<Size, ButtonSizeValue>;
32
- chip: Record<Size, ChipSizeValue>;
33
- badge: Record<Size, BadgeSizeValue>;
34
- icon: Record<Size, IconSizeValue>;
35
- input: Record<Size, InputSizeValue>;
36
- radioButton: Record<Size, RadioButtonSizeValue>;
37
- select: Record<Size, SelectSizeValue>;
38
- slider: Record<Size, SliderSizeValue>;
39
- switch: Record<Size, SwitchSizeValue>;
40
- textarea: Record<Size, TextAreaSizeValue>;
41
- avatar: Record<Size, AvatarSizeValue>;
42
- progress: Record<Size, ProgressSizeValue>;
43
- accordion: Record<Size, AccordionSizeValue>;
44
- activityIndicator: Record<Size, ActivityIndicatorSizeValue>;
45
- breadcrumb: Record<Size, BreadcrumbSizeValue>;
46
- list: Record<Size, ListSizeValue>;
47
- menu: Record<Size, MenuSizeValue>;
48
- text: Record<Size, TextSizeValue>;
49
- tabBar: Record<Size, TabBarSizeValue>;
50
- table: Record<Size, TableSizeValue>;
51
- tooltip: Record<Size, TooltipSizeValue>;
52
- view: Record<Size, ViewSizeValue>;
53
- typography: Record<Typography, TypographyValue>;
54
- }
55
-
56
-
57
- // Derivative size values based on context
58
- export type ButtonSizeValue = {
59
- paddingVertical: SizeValue;
60
- paddingHorizontal: SizeValue;
61
- minHeight: SizeValue;
62
- fontSize: SizeValue;
63
- iconSize: SizeValue;
64
- }
65
-
66
- export type ChipSizeValue = {
67
- paddingVertical: SizeValue;
68
- paddingHorizontal: SizeValue;
69
- minHeight: SizeValue;
70
- borderRadius: SizeValue;
71
- fontSize: SizeValue;
72
- lineHeight: SizeValue;
73
- iconSize: SizeValue;
74
- }
75
-
76
- export type BadgeSizeValue = {
77
- minWidth: SizeValue;
78
- height: SizeValue;
79
- paddingHorizontal: SizeValue;
80
- fontSize: SizeValue;
81
- lineHeight: SizeValue;
82
- iconSize: SizeValue;
83
- }
84
-
85
- export type IconSizeValue = {
86
- width: SizeValue;
87
- height: SizeValue;
88
- fontSize: SizeValue;
89
- }
90
-
91
- export type InputSizeValue = {
92
- height: SizeValue;
93
- paddingHorizontal: SizeValue;
94
- fontSize: SizeValue;
95
- iconSize: SizeValue;
96
- iconMargin: SizeValue;
97
- }
98
-
99
- export type RadioButtonSizeValue = {
100
- radioSize: SizeValue;
101
- radioDotSize: SizeValue;
102
- fontSize: SizeValue;
103
- gap: SizeValue;
104
- }
105
-
106
- export type SelectSizeValue = {
107
- paddingHorizontal: SizeValue;
108
- minHeight: SizeValue;
109
- fontSize: SizeValue;
110
- iconSize: SizeValue;
111
- }
112
-
113
- export type SliderSizeValue = {
114
- trackHeight: SizeValue;
115
- thumbSize: SizeValue;
116
- thumbIconSize: SizeValue;
117
- markHeight: SizeValue;
118
- labelFontSize: SizeValue;
119
- }
120
-
121
- export type SwitchSizeValue = {
122
- trackWidth: SizeValue;
123
- trackHeight: SizeValue;
124
- thumbSize: SizeValue;
125
- thumbIconSize: SizeValue;
126
- translateX: SizeValue;
127
- }
128
-
129
- export type TextAreaSizeValue = {
130
- fontSize: SizeValue;
131
- padding: SizeValue;
132
- lineHeight: SizeValue;
133
- minHeight: SizeValue;
134
- }
135
-
136
- export type AvatarSizeValue = {
137
- width: SizeValue;
138
- height: SizeValue;
139
- fontSize: SizeValue;
140
- }
141
-
142
- export type ProgressSizeValue = {
143
- linearHeight: SizeValue;
144
- circularSize: SizeValue;
145
- labelFontSize: SizeValue;
146
- circularLabelFontSize: SizeValue;
147
- }
148
-
149
- export type AccordionSizeValue = {
150
- headerPadding: SizeValue;
151
- headerFontSize: SizeValue;
152
- iconSize: SizeValue;
153
- contentPadding: SizeValue;
154
- }
155
-
156
- export type ActivityIndicatorSizeValue = {
157
- size: SizeValue;
158
- borderWidth: SizeValue;
159
- }
160
-
161
- export type BreadcrumbSizeValue = {
162
- fontSize: SizeValue;
163
- lineHeight: SizeValue;
164
- iconSize: SizeValue;
165
- }
166
-
167
- export type ListSizeValue = {
168
- paddingVertical: SizeValue;
169
- paddingHorizontal: SizeValue;
170
- minHeight: SizeValue;
171
- iconSize: SizeValue;
172
- labelFontSize: SizeValue;
173
- labelLineHeight: SizeValue;
174
- }
175
-
176
- export type MenuSizeValue = {
177
- paddingVertical: SizeValue;
178
- paddingHorizontal: SizeValue;
179
- iconSize: SizeValue;
180
- labelFontSize: SizeValue;
181
- }
182
-
183
- export type TextSizeValue = {
184
- fontSize: SizeValue;
185
- lineHeight: SizeValue;
186
- }
187
-
188
- export type TabBarSizeValue = {
189
- fontSize: SizeValue;
190
- lineHeight: SizeValue;
191
- padding: SizeValue;
192
- }
193
-
194
- export type TableSizeValue = {
195
- padding: SizeValue;
196
- fontSize: SizeValue;
197
- lineHeight: SizeValue;
198
- }
199
-
200
- export type TooltipSizeValue = {
201
- fontSize: SizeValue;
202
- padding: SizeValue;
203
- }
204
-
205
- export type ViewSizeValue = {
206
- padding: SizeValue;
207
- spacing: SizeValue;
208
- }
12
+ export type AllComponentSizes = RegisteredTheme['theme']['sizes'];