@idealyst/theme 1.1.7 → 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.
- package/package.json +29 -1
- package/src/babel/index.ts +9 -0
- package/src/babel/plugin.js +871 -0
- package/src/babel/plugin.ts +187 -0
- package/src/babel/runtime.ts +94 -0
- package/src/babel/theme-analyzer.js +357 -0
- package/src/componentStyles.ts +93 -0
- package/src/config/cli.ts +95 -0
- package/src/config/generator.ts +817 -0
- package/src/config/index.ts +10 -0
- package/src/config/types.ts +112 -0
- package/src/darkTheme.ts +14 -14
- package/src/extensions.ts +110 -0
- package/src/index.ts +16 -4
- package/src/styleBuilder.ts +108 -0
- package/src/theme/extensions.ts +7 -0
- package/src/unistyles.ts +5 -15
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Idealyst Configuration Module
|
|
3
|
+
*
|
|
4
|
+
* Provides tools for defining theme configuration and generating
|
|
5
|
+
* flat, Unistyles-compatible style files.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export { defineConfig } from './types';
|
|
9
|
+
export { generateStyles } from './generator';
|
|
10
|
+
export type { IdealystConfig, ComponentExtensions, ComponentExtension } from './types';
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Idealyst Configuration Types
|
|
3
|
+
*
|
|
4
|
+
* This module defines the structure for idealyst.config.ts files.
|
|
5
|
+
* The config is used to generate flat, Unistyles-compatible style files.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { Theme } from '../theme';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Component extension definition.
|
|
12
|
+
* Can be either static styles or a function that receives the theme.
|
|
13
|
+
*/
|
|
14
|
+
export type ComponentExtension<T = Record<string, any>> =
|
|
15
|
+
| T
|
|
16
|
+
| ((theme: Theme) => T);
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Extension definitions for all components.
|
|
20
|
+
*/
|
|
21
|
+
export interface ComponentExtensions {
|
|
22
|
+
View?: ComponentExtension<{
|
|
23
|
+
view?: Record<string, any>;
|
|
24
|
+
}>;
|
|
25
|
+
Button?: ComponentExtension<{
|
|
26
|
+
button?: Record<string, any>;
|
|
27
|
+
text?: Record<string, any>;
|
|
28
|
+
icon?: Record<string, any>;
|
|
29
|
+
iconContainer?: Record<string, any>;
|
|
30
|
+
}>;
|
|
31
|
+
Text?: ComponentExtension<{
|
|
32
|
+
text?: Record<string, any>;
|
|
33
|
+
}>;
|
|
34
|
+
Card?: ComponentExtension<{
|
|
35
|
+
card?: Record<string, any>;
|
|
36
|
+
}>;
|
|
37
|
+
Input?: ComponentExtension<{
|
|
38
|
+
wrapper?: Record<string, any>;
|
|
39
|
+
input?: Record<string, any>;
|
|
40
|
+
label?: Record<string, any>;
|
|
41
|
+
hint?: Record<string, any>;
|
|
42
|
+
}>;
|
|
43
|
+
Screen?: ComponentExtension<{
|
|
44
|
+
screen?: Record<string, any>;
|
|
45
|
+
screenContent?: Record<string, any>;
|
|
46
|
+
}>;
|
|
47
|
+
// Add more components as needed...
|
|
48
|
+
[key: string]: ComponentExtension | undefined;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Theme definition in the config.
|
|
53
|
+
*/
|
|
54
|
+
export interface ThemeDefinition {
|
|
55
|
+
/**
|
|
56
|
+
* The built theme object.
|
|
57
|
+
* Created using createTheme() or fromTheme() builders.
|
|
58
|
+
*/
|
|
59
|
+
theme: Theme;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Optional name for this theme variant.
|
|
63
|
+
* Defaults to 'light' for the first theme, 'dark' for the second.
|
|
64
|
+
*/
|
|
65
|
+
name?: string;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Main Idealyst configuration structure.
|
|
70
|
+
*/
|
|
71
|
+
export interface IdealystConfig {
|
|
72
|
+
/**
|
|
73
|
+
* Theme definitions.
|
|
74
|
+
* At minimum, define light and dark themes.
|
|
75
|
+
*/
|
|
76
|
+
themes: {
|
|
77
|
+
light: Theme;
|
|
78
|
+
dark: Theme;
|
|
79
|
+
[key: string]: Theme;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Global component style extensions.
|
|
84
|
+
* These are merged with base component styles.
|
|
85
|
+
*/
|
|
86
|
+
extensions?: ComponentExtensions;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Output configuration.
|
|
90
|
+
*/
|
|
91
|
+
output?: {
|
|
92
|
+
/**
|
|
93
|
+
* Directory to output generated style files.
|
|
94
|
+
* Relative to config file location.
|
|
95
|
+
* @default './generated'
|
|
96
|
+
*/
|
|
97
|
+
dir?: string;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Whether to generate TypeScript or JavaScript.
|
|
101
|
+
* @default 'typescript'
|
|
102
|
+
*/
|
|
103
|
+
format?: 'typescript' | 'javascript';
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Helper to define a config with full type inference.
|
|
109
|
+
*/
|
|
110
|
+
export function defineConfig(config: IdealystConfig): IdealystConfig {
|
|
111
|
+
return config;
|
|
112
|
+
}
|
package/src/darkTheme.ts
CHANGED
|
@@ -85,30 +85,30 @@ export const darkTheme = createTheme()
|
|
|
85
85
|
shadowRadius: 16,
|
|
86
86
|
boxShadow: '0px 12px 32px rgba(0, 0, 0, 0.25)',
|
|
87
87
|
})
|
|
88
|
-
// Colors
|
|
88
|
+
// Colors (neutral grays, not blue-tinted)
|
|
89
89
|
.setColors({
|
|
90
90
|
pallet: generateDarkColorPallette(),
|
|
91
91
|
surface: {
|
|
92
|
-
primary: '#
|
|
93
|
-
secondary: '#
|
|
94
|
-
tertiary: '#
|
|
92
|
+
primary: '#121212',
|
|
93
|
+
secondary: '#1e1e1e',
|
|
94
|
+
tertiary: '#2a2a2a',
|
|
95
95
|
inverse: '#ffffff',
|
|
96
96
|
'inverse-secondary': 'rgba(255, 255, 255, 0.9)',
|
|
97
97
|
'inverse-tertiary': 'rgba(255, 255, 255, 0.7)',
|
|
98
98
|
},
|
|
99
99
|
text: {
|
|
100
|
-
primary: '#
|
|
101
|
-
secondary: '#
|
|
102
|
-
tertiary: '#
|
|
103
|
-
inverse: '#
|
|
104
|
-
'inverse-secondary': 'rgba(
|
|
105
|
-
'inverse-tertiary': 'rgba(
|
|
100
|
+
primary: '#f5f5f5',
|
|
101
|
+
secondary: '#a3a3a3',
|
|
102
|
+
tertiary: '#737373',
|
|
103
|
+
inverse: '#121212',
|
|
104
|
+
'inverse-secondary': 'rgba(18, 18, 18, 0.9)',
|
|
105
|
+
'inverse-tertiary': 'rgba(18, 18, 18, 0.7)',
|
|
106
106
|
},
|
|
107
107
|
border: {
|
|
108
|
-
primary: '#
|
|
109
|
-
secondary: '#
|
|
110
|
-
tertiary: '#
|
|
111
|
-
disabled: '#
|
|
108
|
+
primary: '#333333',
|
|
109
|
+
secondary: '#404040',
|
|
110
|
+
tertiary: '#525252',
|
|
111
|
+
disabled: '#1e1e1e',
|
|
112
112
|
},
|
|
113
113
|
})
|
|
114
114
|
// Sizes (reuse from light theme)
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extensions runtime for Idealyst theme.
|
|
3
|
+
*
|
|
4
|
+
* This module provides the runtime helper used by the Babel plugin
|
|
5
|
+
* to merge extensions into component styles.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export { __withExtension } from './babel/runtime';
|
|
9
|
+
|
|
10
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
11
|
+
import type { Theme } from './theme';
|
|
12
|
+
|
|
13
|
+
// =============================================================================
|
|
14
|
+
// ThemeStyleWrapper - Type utility for style definitions
|
|
15
|
+
// =============================================================================
|
|
16
|
+
|
|
17
|
+
// Check if T is an object we can iterate over (not array, not function, not primitive)
|
|
18
|
+
type IsIterableObject<T> = T extends object
|
|
19
|
+
? T extends any[]
|
|
20
|
+
? false
|
|
21
|
+
: T extends (...args: any[]) => any
|
|
22
|
+
? false
|
|
23
|
+
: true
|
|
24
|
+
: false;
|
|
25
|
+
|
|
26
|
+
// Get value type from an object - works for both Record and named-key objects
|
|
27
|
+
type ObjectValue<T> = T extends { [key: string]: infer V }
|
|
28
|
+
? V
|
|
29
|
+
: T[keyof T];
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Wraps a Theme type to add $iterator properties for any object types.
|
|
33
|
+
*
|
|
34
|
+
* For each property that is an object (dictionary-like), adds a sibling $propertyName
|
|
35
|
+
* that represents the value type. This enables Babel to expand iterations
|
|
36
|
+
* over theme values (like intents, typography sizes, etc.)
|
|
37
|
+
*
|
|
38
|
+
* Works with:
|
|
39
|
+
* - Record<string, V> types
|
|
40
|
+
* - Objects with named keys like { primary: V, success: V, ... }
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* import { ThemeStyleWrapper } from '@idealyst/theme/extensions';
|
|
45
|
+
* import type { Theme as BaseTheme } from '@idealyst/theme';
|
|
46
|
+
*
|
|
47
|
+
* type Theme = ThemeStyleWrapper<BaseTheme>;
|
|
48
|
+
*
|
|
49
|
+
* // Now you can use $iterator properties:
|
|
50
|
+
* // theme.$intents.primary -> Babel expands to all intent keys
|
|
51
|
+
* // theme.sizes.$typography.fontSize -> Babel expands to all typography keys
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export type ThemeStyleWrapper<T> = T extends object
|
|
55
|
+
? {
|
|
56
|
+
[K in keyof T]: ThemeStyleWrapper<T[K]>
|
|
57
|
+
} & {
|
|
58
|
+
[K in keyof T as IsIterableObject<T[K]> extends true ? `$${K & string}` : never]:
|
|
59
|
+
ThemeStyleWrapper<ObjectValue<T[K]>>
|
|
60
|
+
}
|
|
61
|
+
: T;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Theme type with $iterator properties for use in style definitions.
|
|
65
|
+
* Use this instead of the base Theme type when using $iterator syntax.
|
|
66
|
+
*/
|
|
67
|
+
export type IteratorTheme = ThemeStyleWrapper<Theme>;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Style callback type that accepts IteratorTheme.
|
|
71
|
+
* The variants structure is relaxed to accept $iterator patterns.
|
|
72
|
+
*/
|
|
73
|
+
export type IteratorStyleCallback<TStyles> = (theme: IteratorTheme) => TStyles;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Creates a stylesheet with $iterator expansion support.
|
|
77
|
+
*
|
|
78
|
+
* This is a typed wrapper around StyleSheet.create that:
|
|
79
|
+
* 1. Accepts the IteratorTheme type (with $intents, $sizes, etc.)
|
|
80
|
+
* 2. Allows relaxed variant structures for $iterator patterns
|
|
81
|
+
*
|
|
82
|
+
* The Babel plugin will expand $iterator patterns before Unistyles processes the styles.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* import { createIteratorStyles } from '@idealyst/theme';
|
|
87
|
+
*
|
|
88
|
+
* export const styles = createIteratorStyles((theme) => ({
|
|
89
|
+
* box: {
|
|
90
|
+
* borderRadius: theme.radii.md,
|
|
91
|
+
* variants: {
|
|
92
|
+
* intent: {
|
|
93
|
+
* backgroundColor: theme.$intents.light,
|
|
94
|
+
* borderColor: theme.$intents.primary,
|
|
95
|
+
* },
|
|
96
|
+
* size: {
|
|
97
|
+
* padding: theme.sizes.$button.paddingVertical,
|
|
98
|
+
* },
|
|
99
|
+
* },
|
|
100
|
+
* },
|
|
101
|
+
* }));
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
export function createIteratorStyles<TStyles extends Record<string, any>>(
|
|
105
|
+
callback: IteratorStyleCallback<TStyles>
|
|
106
|
+
): ReturnType<typeof StyleSheet.create> {
|
|
107
|
+
// This function is transformed by Babel - it sees StyleSheet.create and processes it
|
|
108
|
+
// The callback is passed through with $iterator patterns expanded
|
|
109
|
+
return StyleSheet.create(callback as any);
|
|
110
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
export * from './lightTheme';
|
|
3
|
-
export * from './darkTheme';
|
|
1
|
+
// Core types first (no dependencies)
|
|
4
2
|
export * from './theme';
|
|
5
3
|
export * from './variants';
|
|
6
4
|
export * from './components';
|
|
5
|
+
|
|
6
|
+
// Builder (depends on theme types)
|
|
7
|
+
export * from './builder';
|
|
8
|
+
|
|
9
|
+
// Themes (depend on builder)
|
|
10
|
+
export * from './lightTheme';
|
|
11
|
+
export * from './darkTheme';
|
|
12
|
+
|
|
13
|
+
// Unistyles declaration (depends on theme)
|
|
14
|
+
export * from './unistyles';
|
|
15
|
+
|
|
16
|
+
// Helpers and styles
|
|
7
17
|
export * from './styles';
|
|
8
18
|
export * from './helpers';
|
|
9
|
-
export * from './
|
|
19
|
+
export * from './styleBuilder';
|
|
20
|
+
export * from './extensions';
|
|
21
|
+
export * from './componentStyles';
|
|
@@ -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';
|
package/src/theme/extensions.ts
CHANGED
|
@@ -42,6 +42,13 @@ export interface DefaultTheme {
|
|
|
42
42
|
typography: Record<Typography, TypographyValue>;
|
|
43
43
|
};
|
|
44
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>>;
|
|
45
52
|
}
|
|
46
53
|
|
|
47
54
|
/**
|
package/src/unistyles.ts
CHANGED
|
@@ -1,25 +1,15 @@
|
|
|
1
|
-
import { StyleSheet } from 'react-native-unistyles';
|
|
2
|
-
import { darkTheme } from './darkTheme';
|
|
3
|
-
import { lightTheme } from './lightTheme';
|
|
4
1
|
import { Theme } from './theme';
|
|
5
2
|
|
|
6
3
|
// Unistyles v3 themes declaration
|
|
4
|
+
// Apps should configure their own themes via StyleSheet.configure()
|
|
7
5
|
declare module 'react-native-unistyles' {
|
|
8
6
|
export interface UnistylesThemes {
|
|
9
7
|
light: Theme;
|
|
10
8
|
dark: Theme;
|
|
9
|
+
// Apps can add more themes via module augmentation
|
|
10
|
+
[key: string]: Theme;
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
// Export
|
|
15
|
-
export const
|
|
16
|
-
|
|
17
|
-
StyleSheet.configure({
|
|
18
|
-
settings: {
|
|
19
|
-
initialTheme: 'light',
|
|
20
|
-
},
|
|
21
|
-
themes: {
|
|
22
|
-
light: lightTheme,
|
|
23
|
-
dark: darkTheme,
|
|
24
|
-
}
|
|
25
|
-
})
|
|
14
|
+
// Export for type checking
|
|
15
|
+
export const THEME_TYPES_DECLARED = true;
|