@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.
@@ -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: '#0f172a',
93
- secondary: '#1e293b',
94
- tertiary: '#334155',
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: '#f1f5f9',
101
- secondary: '#cbd5e1',
102
- tertiary: '#94a3b8',
103
- inverse: '#0f172a',
104
- 'inverse-secondary': 'rgba(15, 23, 42, 0.9)',
105
- 'inverse-tertiary': 'rgba(15, 23, 42, 0.7)',
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: '#334155',
109
- secondary: '#475569',
110
- tertiary: '#64748b',
111
- disabled: '#1e293b',
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
- export * from './unistyles';
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 './builder';
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';
@@ -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 something to ensure this module is included in compilation
15
- export const unistylesConfigured = true;
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;