@idealyst/mcp-server 1.2.7 → 1.2.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.
@@ -12,45 +12,49 @@ npx @idealyst/cli init my-app
12
12
  cd my-app
13
13
  \`\`\`
14
14
 
15
- This creates a monorepo workspace with:
15
+ This single command creates a **complete monorepo workspace** with all 5 packages:
16
+ - \`packages/web/\` - React web app (Vite)
17
+ - \`packages/native/\` - React Native mobile app
18
+ - \`packages/api/\` - tRPC API server with GraphQL
19
+ - \`packages/database/\` - Prisma database layer
20
+ - \`packages/shared/\` - Shared utilities and tRPC client
21
+
22
+ Plus:
16
23
  - Yarn 3 workspace setup
17
24
  - TypeScript configuration
18
25
  - Jest testing setup
19
26
  - Git repository
20
27
  - Dev container configuration
21
28
 
22
- ### 2. Create Packages
29
+ ### 2. Start Development
23
30
 
24
- Create a web app:
25
31
  \`\`\`bash
26
- npx @idealyst/cli create web --type web --with-trpc
27
- \`\`\`
32
+ # Start web dev server
33
+ cd packages/web
34
+ yarn dev
28
35
 
29
- Create a native app:
30
- \`\`\`bash
31
- npx @idealyst/cli create mobile --type native --app-name "My App" --with-trpc
32
- \`\`\`
36
+ # Start native dev (in another terminal)
37
+ cd packages/native
38
+ yarn start
33
39
 
34
- Create an API server:
35
- \`\`\`bash
36
- npx @idealyst/cli create api --type api
40
+ # Start API server (in another terminal)
41
+ cd packages/api
42
+ yarn dev
37
43
  \`\`\`
38
44
 
39
- Create a database layer:
40
- \`\`\`bash
41
- npx @idealyst/cli create database --type database
42
- \`\`\`
45
+ ### 3. Configure Babel (Required for Styling)
43
46
 
44
- ### 3. Start Development
47
+ Add the Idealyst plugin to your babel.config.js:
45
48
 
46
- \`\`\`bash
47
- # Start web dev server
48
- cd packages/web
49
- yarn dev
50
-
51
- # Start native dev
52
- cd packages/mobile
53
- yarn dev
49
+ \`\`\`javascript
50
+ module.exports = {
51
+ presets: ['module:@react-native/babel-preset'],
52
+ plugins: [
53
+ ['@idealyst/theme/plugin', {
54
+ themePath: './src/theme/styles.ts', // Path to your theme file
55
+ }],
56
+ ],
57
+ };
54
58
  \`\`\`
55
59
 
56
60
  ## Project Structure
@@ -59,11 +63,12 @@ yarn dev
59
63
  my-app/
60
64
  ├── packages/
61
65
  │ ├── web/ # React web app (Vite)
62
- │ ├── mobile/ # React Native app
63
- │ ├── api/ # tRPC API server
66
+ │ ├── native/ # React Native app
67
+ │ ├── api/ # tRPC + GraphQL API server
64
68
  │ ├── database/ # Prisma database layer
65
- │ └── shared/ # Shared utilities
69
+ │ └── shared/ # Shared utilities & tRPC client
66
70
  ├── package.json
71
+ ├── tsconfig.json
67
72
  └── yarn.lock
68
73
  \`\`\`
69
74
 
@@ -74,14 +79,16 @@ my-app/
74
79
  - **Modern Tooling**: Vite, TypeScript, Jest, Prisma
75
80
  - **Monorepo Structure**: Share code across packages
76
81
  - **Theme System**: Consistent styling with react-native-unistyles
82
+ - **Style Extensions**: Customize component styles at build time
77
83
  - **Navigation**: Unified navigation for web and native
78
84
 
79
85
  ## Next Steps
80
86
 
81
87
  1. Explore the component library: \`@idealyst/components\`
82
- 2. Set up your database schema in \`packages/database\`
83
- 3. Define your API routes in \`packages/api\`
84
- 4. Build your UI in \`packages/web\` or \`packages/mobile\`
88
+ 2. Learn the style system: \`idealyst://framework/style-system\`
89
+ 3. Set up your database schema in \`packages/database\`
90
+ 4. Define your API routes in \`packages/api\`
91
+ 5. Build your UI using Idealyst components
85
92
  `,
86
93
  "idealyst://framework/components-overview": `# Idealyst Components Overview
87
94
 
@@ -186,188 +193,177 @@ import { Button, Card, Text, View } from '@idealyst/components';
186
193
  `,
187
194
  "idealyst://framework/theming": `# Theming Guide
188
195
 
189
- Idealyst uses react-native-unistyles for cross-platform theming with full TypeScript support.
190
-
191
- ## Theme Structure
196
+ Idealyst uses react-native-unistyles for cross-platform theming with full TypeScript support. Themes are created using a fluent builder pattern.
192
197
 
193
- Themes are defined with:
194
- - **Colors**: Text, surface, border, intent colors
195
- - **Typography**: Font families, sizes, weights
196
- - **Spacing**: Consistent spacing scale
197
- - **Border Radius**: Rounded corner sizes
198
- - **Breakpoints**: Responsive design breakpoints
198
+ ## Theme Builder API
199
199
 
200
- ## Default Theme
200
+ Create themes using the builder pattern:
201
201
 
202
202
  \`\`\`typescript
203
- {
204
- colors: {
205
- text: {
206
- primary: '#000000',
207
- secondary: '#666666',
208
- inverse: '#FFFFFF',
209
- disabled: '#999999',
210
- },
203
+ import { createTheme } from '@idealyst/theme';
204
+
205
+ export const myTheme = createTheme()
206
+ // Add semantic intents
207
+ .addIntent('primary', {
208
+ primary: '#3b82f6', // Main color
209
+ contrast: '#ffffff', // Text on primary background
210
+ light: '#bfdbfe', // Lighter variant
211
+ dark: '#1e40af', // Darker variant
212
+ })
213
+ .addIntent('success', {
214
+ primary: '#22c55e',
215
+ contrast: '#ffffff',
216
+ light: '#a7f3d0',
217
+ dark: '#165e29',
218
+ })
219
+ .addIntent('error', {
220
+ primary: '#ef4444',
221
+ contrast: '#ffffff',
222
+ light: '#fca5a1',
223
+ dark: '#9b2222',
224
+ })
225
+
226
+ // Add border radii
227
+ .addRadius('none', 0)
228
+ .addRadius('sm', 4)
229
+ .addRadius('md', 8)
230
+ .addRadius('lg', 12)
231
+
232
+ // Add shadows (cross-platform)
233
+ .addShadow('sm', {
234
+ elevation: 1,
235
+ shadowColor: '#000000',
236
+ shadowOffset: { width: 0, height: 1 },
237
+ shadowOpacity: 0.08,
238
+ shadowRadius: 1,
239
+ boxShadow: '0px 1px 2px rgba(0, 0, 0, 0.1)', // web-only
240
+ })
241
+
242
+ // Set colors
243
+ .setColors({
244
+ pallet: { /* color palette */ },
211
245
  surface: {
212
- primary: '#FFFFFF',
213
- secondary: '#F5F5F5',
214
- tertiary: '#EEEEEE',
246
+ screen: '#ffffff',
247
+ primary: '#ffffff',
248
+ secondary: '#f5f5f5',
215
249
  inverse: '#000000',
216
250
  },
217
- border: {
218
- primary: '#E0E0E0',
219
- secondary: '#CCCCCC',
220
- },
221
- },
222
- intents: {
223
- primary: {
224
- main: '#3B82F6',
225
- container: '#DBEAFE',
226
- onContainer: '#1E40AF',
227
- },
228
- success: {
229
- main: '#10B981',
230
- container: '#D1FAE5',
231
- onContainer: '#065F46',
232
- },
233
- error: {
234
- main: '#EF4444',
235
- container: '#FEE2E2',
236
- onContainer: '#991B1B',
237
- },
238
- warning: {
239
- main: '#F59E0B',
240
- container: '#FEF3C7',
241
- onContainer: '#92400E',
242
- },
243
- },
244
- spacing: {
245
- xs: 4,
246
- sm: 8,
247
- md: 16,
248
- lg: 24,
249
- xl: 32,
250
- xxl: 48,
251
- },
252
- borderRadius: {
253
- sm: 4,
254
- md: 8,
255
- lg: 12,
256
- xl: 16,
257
- },
258
- typography: {
259
- fontFamily: {
260
- sans: 'System',
261
- mono: 'Monospace',
251
+ text: {
252
+ primary: '#000000',
253
+ secondary: '#333333',
254
+ inverse: '#ffffff',
262
255
  },
263
- fontSize: {
264
- xs: 12,
265
- sm: 14,
266
- md: 16,
267
- lg: 18,
268
- xl: 20,
256
+ border: {
257
+ primary: '#e0e0e0',
258
+ disabled: '#f0f0f0',
269
259
  },
270
- fontWeight: {
271
- light: '300',
272
- normal: '400',
273
- medium: '500',
274
- semibold: '600',
275
- bold: '700',
260
+ })
261
+
262
+ // Set component sizes (xs, sm, md, lg, xl)
263
+ .setSizes({
264
+ button: {
265
+ xs: { paddingVertical: 4, paddingHorizontal: 8, minHeight: 24, fontSize: 12 },
266
+ sm: { paddingVertical: 6, paddingHorizontal: 12, minHeight: 32, fontSize: 14 },
267
+ md: { paddingVertical: 8, paddingHorizontal: 16, minHeight: 40, fontSize: 16 },
268
+ lg: { paddingVertical: 10, paddingHorizontal: 20, minHeight: 48, fontSize: 18 },
269
+ xl: { paddingVertical: 12, paddingHorizontal: 24, minHeight: 56, fontSize: 20 },
276
270
  },
277
- },
278
- }
279
- \`\`\`
271
+ // ... other components (chip, badge, icon, input, etc.)
272
+ })
280
273
 
281
- ## Custom Themes
274
+ // Set interaction styles
275
+ .setInteraction({
276
+ focusedBackground: 'rgba(59, 130, 246, 0.08)',
277
+ focusBorder: 'rgba(59, 130, 246, 0.3)',
278
+ opacity: { hover: 0.9, active: 0.75, disabled: 0.5 },
279
+ })
282
280
 
283
- Create custom themes in your app:
281
+ // Set responsive breakpoints
282
+ .setBreakpoints({
283
+ xs: 0, // Portrait phones
284
+ sm: 576, // Landscape phones
285
+ md: 768, // Tablets
286
+ lg: 992, // Desktops
287
+ xl: 1200, // Large desktops
288
+ })
284
289
 
285
- \`\`\`typescript
286
- // theme.ts
287
- export const customTheme = {
288
- colors: {
289
- // Override colors
290
- text: {
291
- primary: '#1A1A1A',
292
- // ...
293
- },
294
- },
295
- intents: {
296
- primary: {
297
- main: '#6366F1', // Custom brand color
298
- // ...
299
- },
300
- },
301
- // ... rest of theme
302
- };
290
+ .build();
303
291
  \`\`\`
304
292
 
305
- ## Using Themes
293
+ ## Intent Structure
306
294
 
307
- \`\`\`typescript
308
- import { UnistylesRegistry } from 'react-native-unistyles';
309
- import { lightTheme, darkTheme } from './themes';
295
+ Each intent defines four color values:
310
296
 
311
- UnistylesRegistry
312
- .addThemes({
313
- light: lightTheme,
314
- dark: darkTheme,
315
- })
316
- .addConfig({
317
- initialTheme: 'light',
318
- });
319
- \`\`\`
297
+ | Property | Purpose |
298
+ |------------|-----------------------------------|
299
+ | \`primary\` | Main color used for backgrounds |
300
+ | \`contrast\` | Text color on primary background |
301
+ | \`light\` | Lighter tint for subtle states |
302
+ | \`dark\` | Darker shade for pressed states |
320
303
 
321
- ## Dark Mode
304
+ ## Extending an Existing Theme
322
305
 
323
- Toggle between themes:
306
+ Use \`fromTheme()\` to extend a base theme:
324
307
 
325
308
  \`\`\`typescript
326
- import { useStyles } from 'react-native-unistyles';
309
+ import { fromTheme, lightTheme } from '@idealyst/theme';
310
+
311
+ export const brandTheme = fromTheme(lightTheme)
312
+ .addIntent('brand', {
313
+ primary: '#6366f1',
314
+ contrast: '#ffffff',
315
+ light: '#818cf8',
316
+ dark: '#4f46e5',
317
+ })
318
+ .build();
319
+ \`\`\`
327
320
 
328
- function ThemeToggle() {
329
- const { theme } = useStyles();
321
+ ## Registering Your Theme
330
322
 
331
- const toggleTheme = () => {
332
- theme.setTheme(theme.name === 'light' ? 'dark' : 'light');
333
- };
323
+ For full TypeScript inference:
334
324
 
335
- return <Button onPress={toggleTheme}>Toggle Theme</Button>;
325
+ \`\`\`typescript
326
+ // src/theme/styles.ts
327
+ export const myTheme = createTheme()
328
+ // ... builder chain
329
+ .build();
330
+
331
+ // Register the theme type
332
+ declare module '@idealyst/theme' {
333
+ interface RegisteredTheme {
334
+ theme: typeof myTheme;
335
+ }
336
336
  }
337
337
  \`\`\`
338
338
 
339
- ## Responsive Design
340
-
341
- Use breakpoints for responsive layouts:
339
+ ## Using Themes with Unistyles
342
340
 
343
341
  \`\`\`typescript
344
- const styles = StyleSheet.create(theme => ({
345
- container: {
346
- padding: theme.spacing.md,
342
+ import { UnistylesRegistry } from 'react-native-unistyles';
343
+ import { lightTheme, darkTheme } from '@idealyst/theme';
347
344
 
348
- variants: {
349
- breakpoint: {
350
- sm: { maxWidth: 640 },
351
- md: { maxWidth: 768 },
352
- lg: { maxWidth: 1024 },
353
- },
354
- },
355
- },
356
- }));
345
+ UnistylesRegistry
346
+ .addThemes({
347
+ light: lightTheme,
348
+ dark: darkTheme,
349
+ })
350
+ .addConfig({
351
+ initialTheme: 'light',
352
+ });
357
353
  \`\`\`
358
354
 
359
355
  ## Platform-Specific Styles
360
356
 
361
357
  \`\`\`typescript
362
- const styles = StyleSheet.create(theme => ({
358
+ const styles = StyleSheet.create((theme) => ({
363
359
  button: {
364
- padding: theme.spacing.md,
360
+ padding: 16,
365
361
 
366
362
  _web: {
367
363
  cursor: 'pointer',
368
- ':hover': {
369
- backgroundColor: theme.colors.surface.secondary,
370
- },
364
+ transition: 'all 0.1s ease',
365
+ _hover: { opacity: 0.9 },
366
+ _active: { opacity: 0.75 },
371
367
  },
372
368
 
373
369
  _native: {
@@ -376,6 +372,12 @@ const styles = StyleSheet.create(theme => ({
376
372
  },
377
373
  }));
378
374
  \`\`\`
375
+
376
+ ## See Also
377
+
378
+ - \`idealyst://framework/style-system\` - Style definition APIs (defineStyle, extendStyle)
379
+ - \`idealyst://framework/babel-plugin\` - Babel plugin configuration
380
+ - \`idealyst://framework/breakpoints\` - Responsive breakpoint system
379
381
  `,
380
382
  "idealyst://framework/cli": `# Idealyst CLI Reference
381
383
 
@@ -1045,6 +1047,672 @@ Features:
1045
1047
  3. **Error Handling**: Use Pothos error types
1046
1048
  4. **Authorization**: Add auth checks in resolvers
1047
1049
  5. **N+1 Prevention**: Use Prisma's query optimization
1050
+ `,
1051
+ "idealyst://framework/style-system": `# Style Definition System
1052
+
1053
+ Idealyst provides a powerful style definition system with build-time transformations via Babel plugin.
1054
+
1055
+ ## Overview
1056
+
1057
+ The style system provides:
1058
+ - **defineStyle()**: Define base styles for components
1059
+ - **extendStyle()**: Merge additional styles with base styles
1060
+ - **overrideStyle()**: Completely replace component styles
1061
+ - **$iterator pattern**: Expand styles for all theme keys
1062
+
1063
+ ## defineStyle()
1064
+
1065
+ Define base styles for a component:
1066
+
1067
+ \`\`\`typescript
1068
+ import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
1069
+ import type { Theme as BaseTheme } from '@idealyst/theme';
1070
+
1071
+ // Wrap theme for $iterator support
1072
+ type Theme = ThemeStyleWrapper<BaseTheme>;
1073
+
1074
+ export const buttonStyles = defineStyle('Button', (theme: Theme) => ({
1075
+ button: {
1076
+ borderRadius: theme.radii.md,
1077
+ backgroundColor: theme.intents.primary.primary,
1078
+
1079
+ variants: {
1080
+ size: {
1081
+ // $iterator expands to all size keys (xs, sm, md, lg, xl)
1082
+ paddingVertical: theme.sizes.$button.paddingVertical,
1083
+ paddingHorizontal: theme.sizes.$button.paddingHorizontal,
1084
+ },
1085
+ disabled: {
1086
+ true: { opacity: 0.5 },
1087
+ false: { opacity: 1 },
1088
+ },
1089
+ },
1090
+ },
1091
+ text: {
1092
+ color: theme.intents.primary.contrast,
1093
+ variants: {
1094
+ size: {
1095
+ fontSize: theme.sizes.$button.fontSize,
1096
+ },
1097
+ },
1098
+ },
1099
+ }));
1100
+ \`\`\`
1101
+
1102
+ ## Dynamic Style Functions
1103
+
1104
+ For styles depending on runtime props:
1105
+
1106
+ \`\`\`typescript
1107
+ export const buttonStyles = defineStyle('Button', (theme: Theme) => ({
1108
+ button: ({ intent = 'primary', type = 'contained' }: ButtonDynamicProps) => ({
1109
+ backgroundColor: type === 'contained'
1110
+ ? theme.intents[intent].primary
1111
+ : 'transparent',
1112
+ borderColor: type === 'outlined'
1113
+ ? theme.intents[intent].primary
1114
+ : 'transparent',
1115
+ }),
1116
+ }));
1117
+ \`\`\`
1118
+
1119
+ ## Using Styles in Components
1120
+
1121
+ \`\`\`typescript
1122
+ import { buttonStyles } from './Button.styles';
1123
+
1124
+ const Button = ({ size = 'md', disabled = false, intent, type }) => {
1125
+ // Apply variants
1126
+ buttonStyles.useVariants({ size, disabled });
1127
+
1128
+ // Static styles - no function call
1129
+ const staticStyle = buttonStyles.button;
1130
+
1131
+ // Dynamic styles - function call with props
1132
+ const dynamicStyle = (buttonStyles.button as any)({ intent, type });
1133
+
1134
+ return (
1135
+ <TouchableOpacity style={dynamicStyle}>
1136
+ <Text style={buttonStyles.text}>Click me</Text>
1137
+ </TouchableOpacity>
1138
+ );
1139
+ };
1140
+ \`\`\`
1141
+
1142
+ ## extendStyle()
1143
+
1144
+ Merge additional styles with base component styles:
1145
+
1146
+ \`\`\`typescript
1147
+ // style-extensions.ts
1148
+ import { extendStyle } from '@idealyst/theme';
1149
+
1150
+ extendStyle('Button', (theme) => ({
1151
+ button: {
1152
+ borderRadius: 9999, // Make all buttons pill-shaped
1153
+ },
1154
+ text: {
1155
+ fontFamily: 'CustomFont',
1156
+ },
1157
+ }));
1158
+ \`\`\`
1159
+
1160
+ ## overrideStyle()
1161
+
1162
+ Completely replace component styles:
1163
+
1164
+ \`\`\`typescript
1165
+ import { overrideStyle } from '@idealyst/theme';
1166
+
1167
+ overrideStyle('Button', (theme) => ({
1168
+ button: {
1169
+ backgroundColor: theme.colors.surface.primary,
1170
+ borderWidth: 2,
1171
+ borderColor: theme.intents.primary.primary,
1172
+ },
1173
+ text: {
1174
+ color: theme.intents.primary.primary,
1175
+ },
1176
+ }));
1177
+ \`\`\`
1178
+
1179
+ ## Import Order Matters
1180
+
1181
+ Extensions must be imported **before** components:
1182
+
1183
+ \`\`\`typescript
1184
+ // App.tsx
1185
+ import './style-extensions'; // FIRST - registers extensions
1186
+ import { Button } from '@idealyst/components'; // SECOND - uses extensions
1187
+ \`\`\`
1188
+
1189
+ ## When to Use Each
1190
+
1191
+ | API | Use When |
1192
+ |-----|----------|
1193
+ | \`defineStyle()\` | Creating component library styles |
1194
+ | \`extendStyle()\` | Adding/modifying specific properties |
1195
+ | \`overrideStyle()\` | Completely custom styling |
1196
+
1197
+ ## See Also
1198
+
1199
+ - \`idealyst://framework/theming\` - Theme builder API
1200
+ - \`idealyst://framework/babel-plugin\` - Plugin configuration
1201
+ - \`idealyst://framework/iterator-pattern\` - $iterator expansion
1202
+ `,
1203
+ "idealyst://framework/babel-plugin": `# Idealyst Babel Plugin
1204
+
1205
+ The Idealyst Babel plugin transforms style definitions at build time.
1206
+
1207
+ ## Installation
1208
+
1209
+ The plugin is included with \`@idealyst/theme\`.
1210
+
1211
+ ## Configuration
1212
+
1213
+ \`\`\`javascript
1214
+ // babel.config.js
1215
+ module.exports = {
1216
+ presets: ['module:@react-native/babel-preset'],
1217
+ plugins: [
1218
+ ['@idealyst/theme/plugin', {
1219
+ // REQUIRED: Path to your theme file
1220
+ themePath: './src/theme/styles.ts',
1221
+
1222
+ // Optional: Enable debug logging
1223
+ debug: false,
1224
+ verbose: false,
1225
+
1226
+ // Optional: Paths to auto-process
1227
+ autoProcessPaths: [
1228
+ '@idealyst/components',
1229
+ '@idealyst/datepicker',
1230
+ 'src/',
1231
+ ],
1232
+ }],
1233
+ ],
1234
+ };
1235
+ \`\`\`
1236
+
1237
+ ## What the Plugin Does
1238
+
1239
+ ### 1. Transforms defineStyle() to StyleSheet.create()
1240
+
1241
+ **Input:**
1242
+ \`\`\`typescript
1243
+ defineStyle('Button', (theme) => ({
1244
+ button: { backgroundColor: theme.intents.primary.primary }
1245
+ }));
1246
+ \`\`\`
1247
+
1248
+ **Output:**
1249
+ \`\`\`typescript
1250
+ StyleSheet.create((theme) => ({
1251
+ button: { backgroundColor: theme.intents.primary.primary }
1252
+ }));
1253
+ \`\`\`
1254
+
1255
+ ### 2. Expands $iterator Patterns
1256
+
1257
+ **Input:**
1258
+ \`\`\`typescript
1259
+ defineStyle('Button', (theme) => ({
1260
+ button: {
1261
+ variants: {
1262
+ size: {
1263
+ paddingVertical: theme.sizes.$button.paddingVertical,
1264
+ },
1265
+ },
1266
+ },
1267
+ }));
1268
+ \`\`\`
1269
+
1270
+ **Output:**
1271
+ \`\`\`typescript
1272
+ StyleSheet.create((theme) => ({
1273
+ button: {
1274
+ variants: {
1275
+ size: {
1276
+ xs: { paddingVertical: theme.sizes.button.xs.paddingVertical },
1277
+ sm: { paddingVertical: theme.sizes.button.sm.paddingVertical },
1278
+ md: { paddingVertical: theme.sizes.button.md.paddingVertical },
1279
+ lg: { paddingVertical: theme.sizes.button.lg.paddingVertical },
1280
+ xl: { paddingVertical: theme.sizes.button.xl.paddingVertical },
1281
+ },
1282
+ },
1283
+ },
1284
+ }));
1285
+ \`\`\`
1286
+
1287
+ ### 3. Merges Extensions at Build Time
1288
+
1289
+ \`\`\`typescript
1290
+ // Extension (processed first)
1291
+ extendStyle('Button', (theme) => ({
1292
+ button: { borderRadius: 9999 },
1293
+ }));
1294
+
1295
+ // Base (merges with extension)
1296
+ defineStyle('Button', (theme) => ({
1297
+ button: { padding: 16 },
1298
+ }));
1299
+
1300
+ // Result: { padding: 16, borderRadius: 9999 }
1301
+ \`\`\`
1302
+
1303
+ ### 4. Removes extendStyle/overrideStyle Calls
1304
+
1305
+ After capturing extension definitions, the plugin removes the calls from the output since all merging happens at build time.
1306
+
1307
+ ## Theme Analysis
1308
+
1309
+ The plugin statically analyzes your theme file to extract:
1310
+ - Intent names (primary, success, error, etc.)
1311
+ - Size keys (xs, sm, md, lg, xl)
1312
+ - Radius names (none, sm, md, lg)
1313
+ - Shadow names (none, sm, md, lg, xl)
1314
+
1315
+ This enables $iterator expansion without runtime overhead.
1316
+
1317
+ ## Troubleshooting
1318
+
1319
+ ### Styles Not Applying
1320
+
1321
+ 1. Verify \`themePath\` points to your theme file
1322
+ 2. Clear bundler cache: \`yarn start --reset-cache\`
1323
+ 3. Check \`void StyleSheet;\` marker exists in style files
1324
+
1325
+ ### Theme Changes Not Detected
1326
+
1327
+ 1. Restart Metro bundler (theme is analyzed once)
1328
+ 2. Verify theme exports correctly
1329
+
1330
+ ### Debug Mode
1331
+
1332
+ Enable verbose logging:
1333
+
1334
+ \`\`\`javascript
1335
+ ['@idealyst/theme/plugin', {
1336
+ themePath: './src/theme/styles.ts',
1337
+ verbose: true,
1338
+ }],
1339
+ \`\`\`
1340
+ `,
1341
+ "idealyst://framework/breakpoints": `# Responsive Breakpoints
1342
+
1343
+ Idealyst provides a responsive breakpoint system built on Unistyles v3, enabling width-based responsive styling across web and native platforms.
1344
+
1345
+ ## Default Breakpoints
1346
+
1347
+ The default themes include 5 breakpoints:
1348
+
1349
+ | Breakpoint | Min Width | Target Devices |
1350
+ |------------|-----------|----------------|
1351
+ | \`xs\` | 0px | Portrait phones |
1352
+ | \`sm\` | 576px | Landscape phones |
1353
+ | \`md\` | 768px | Tablets |
1354
+ | \`lg\` | 992px | Desktops |
1355
+ | \`xl\` | 1200px | Large desktops |
1356
+
1357
+ ## Defining Breakpoints
1358
+
1359
+ ### Using setBreakpoints()
1360
+
1361
+ Set all breakpoints at once:
1362
+
1363
+ \`\`\`typescript
1364
+ import { createTheme } from '@idealyst/theme';
1365
+
1366
+ const theme = createTheme()
1367
+ // ... other theme config
1368
+ .setBreakpoints({
1369
+ xs: 0, // Must have one breakpoint at 0
1370
+ sm: 576,
1371
+ md: 768,
1372
+ lg: 992,
1373
+ xl: 1200,
1374
+ })
1375
+ .build();
1376
+ \`\`\`
1377
+
1378
+ ### Using addBreakpoint()
1379
+
1380
+ Add breakpoints individually:
1381
+
1382
+ \`\`\`typescript
1383
+ import { fromTheme, lightTheme } from '@idealyst/theme';
1384
+
1385
+ const theme = fromTheme(lightTheme)
1386
+ .addBreakpoint('xxl', 1400) // Add extra large breakpoint
1387
+ .addBreakpoint('xxxl', 1800) // Add even larger
1388
+ .build();
1389
+ \`\`\`
1390
+
1391
+ ## Using Breakpoints in Styles
1392
+
1393
+ ### In StyleSheet.create()
1394
+
1395
+ Use object notation for responsive values:
1396
+
1397
+ \`\`\`typescript
1398
+ import { StyleSheet } from 'react-native-unistyles';
1399
+
1400
+ const styles = StyleSheet.create((theme) => ({
1401
+ container: {
1402
+ // Responsive padding
1403
+ padding: {
1404
+ xs: 8,
1405
+ md: 16,
1406
+ xl: 24,
1407
+ },
1408
+
1409
+ // Responsive flex direction
1410
+ flexDirection: {
1411
+ xs: 'column',
1412
+ md: 'row',
1413
+ },
1414
+
1415
+ // Responsive gap
1416
+ gap: {
1417
+ xs: 8,
1418
+ sm: 12,
1419
+ lg: 16,
1420
+ },
1421
+ },
1422
+
1423
+ text: {
1424
+ fontSize: {
1425
+ xs: 14,
1426
+ md: 16,
1427
+ lg: 18,
1428
+ },
1429
+ },
1430
+ }));
1431
+ \`\`\`
1432
+
1433
+ ### Cascading Behavior
1434
+
1435
+ Values cascade up - if a breakpoint isn't defined, it uses the nearest smaller one:
1436
+
1437
+ \`\`\`typescript
1438
+ padding: {
1439
+ xs: 8, // Used for xs, sm (no sm defined)
1440
+ md: 16, // Used for md, lg (no lg defined)
1441
+ xl: 24, // Used for xl
1442
+ }
1443
+ \`\`\`
1444
+
1445
+ ## Runtime Utilities
1446
+
1447
+ ### getCurrentBreakpoint()
1448
+
1449
+ Get the current active breakpoint:
1450
+
1451
+ \`\`\`typescript
1452
+ import { getCurrentBreakpoint } from '@idealyst/theme';
1453
+
1454
+ const current = getCurrentBreakpoint();
1455
+ console.log(current); // 'md'
1456
+ \`\`\`
1457
+
1458
+ ### getBreakpoints()
1459
+
1460
+ Get all registered breakpoints:
1461
+
1462
+ \`\`\`typescript
1463
+ import { getBreakpoints } from '@idealyst/theme';
1464
+
1465
+ const breakpoints = getBreakpoints();
1466
+ // { xs: 0, sm: 576, md: 768, lg: 992, xl: 1200 }
1467
+ \`\`\`
1468
+
1469
+ ### isBreakpointUp() / isBreakpointDown()
1470
+
1471
+ Check viewport against breakpoints:
1472
+
1473
+ \`\`\`typescript
1474
+ import { isBreakpointUp, isBreakpointDown } from '@idealyst/theme';
1475
+
1476
+ if (isBreakpointUp('md')) {
1477
+ // Tablet or larger
1478
+ }
1479
+
1480
+ if (isBreakpointDown('md')) {
1481
+ // Mobile only (below tablet)
1482
+ }
1483
+ \`\`\`
1484
+
1485
+ ### resolveResponsive()
1486
+
1487
+ Resolve a responsive value for the current breakpoint:
1488
+
1489
+ \`\`\`typescript
1490
+ import { resolveResponsive } from '@idealyst/theme';
1491
+
1492
+ const padding = resolveResponsive({ xs: 8, md: 16, xl: 24 });
1493
+ // Returns 8 on mobile, 16 on tablet, 24 on desktop
1494
+ \`\`\`
1495
+
1496
+ ## Responsive Type
1497
+
1498
+ The \`Responsive<T>\` type makes any value responsive:
1499
+
1500
+ \`\`\`typescript
1501
+ import { Responsive, Size } from '@idealyst/theme';
1502
+
1503
+ // Can be either a direct value or breakpoint map
1504
+ type Props = {
1505
+ size: Responsive<Size>;
1506
+ };
1507
+
1508
+ // Both are valid:
1509
+ <Component size="md" />
1510
+ <Component size={{ xs: 'sm', md: 'lg' }} />
1511
+ \`\`\`
1512
+
1513
+ ### Type Guard
1514
+
1515
+ Check if a value is responsive:
1516
+
1517
+ \`\`\`typescript
1518
+ import { isResponsiveValue, Responsive, Size } from '@idealyst/theme';
1519
+
1520
+ function handleSize(size: Responsive<Size>) {
1521
+ if (isResponsiveValue(size)) {
1522
+ // size is Partial<Record<Breakpoint, Size>>
1523
+ console.log(size.xs, size.md);
1524
+ } else {
1525
+ // size is Size
1526
+ console.log(size);
1527
+ }
1528
+ }
1529
+ \`\`\`
1530
+
1531
+ ## TypeScript Support
1532
+
1533
+ Custom breakpoints are fully typed:
1534
+
1535
+ \`\`\`typescript
1536
+ const theme = createTheme()
1537
+ .setBreakpoints({
1538
+ mobile: 0,
1539
+ tablet: 768,
1540
+ desktop: 1024,
1541
+ })
1542
+ .build();
1543
+
1544
+ // Register for type inference
1545
+ declare module '@idealyst/theme' {
1546
+ interface CustomThemeRegistry {
1547
+ theme: typeof theme;
1548
+ }
1549
+ }
1550
+
1551
+ // Now Breakpoint = 'mobile' | 'tablet' | 'desktop'
1552
+ import { Breakpoint } from '@idealyst/theme';
1553
+ \`\`\`
1554
+
1555
+ ## Unistyles Integration
1556
+
1557
+ Breakpoints are automatically registered with Unistyles:
1558
+
1559
+ \`\`\`typescript
1560
+ import { UnistylesRegistry } from 'react-native-unistyles';
1561
+ import { lightTheme, darkTheme } from '@idealyst/theme';
1562
+
1563
+ UnistylesRegistry
1564
+ .addThemes({ light: lightTheme, dark: darkTheme })
1565
+ .addBreakpoints(lightTheme.breakpoints) // Register breakpoints
1566
+ .addConfig({ initialTheme: 'light' });
1567
+ \`\`\`
1568
+
1569
+ ## Cross-Platform Behavior
1570
+
1571
+ - **Web**: Breakpoints convert to CSS media queries automatically
1572
+ - **Native**: Uses device screen width (works with tablets, phones, etc.)
1573
+ - **Same API**: Write once, works everywhere
1574
+
1575
+ ## Best Practices
1576
+
1577
+ 1. **Mobile-first**: Start with \`xs\` and add larger breakpoints as needed
1578
+ 2. **Use cascading**: Don't define every breakpoint - let values cascade
1579
+ 3. **Consistent breakpoints**: Use the same breakpoints across themes
1580
+ 4. **Test on devices**: Verify layouts on actual device widths
1581
+ 5. **Avoid over-responsiveness**: Not everything needs to change per breakpoint
1582
+ `,
1583
+ "idealyst://framework/iterator-pattern": `# The $iterator Pattern
1584
+
1585
+ The \`$iterator\` pattern allows defining styles once that expand to all keys of a theme object.
1586
+
1587
+ ## ThemeStyleWrapper
1588
+
1589
+ Wrap your theme type to enable $iterator properties:
1590
+
1591
+ \`\`\`typescript
1592
+ import { ThemeStyleWrapper } from '@idealyst/theme';
1593
+ import type { Theme as BaseTheme } from '@idealyst/theme';
1594
+
1595
+ type Theme = ThemeStyleWrapper<BaseTheme>;
1596
+ \`\`\`
1597
+
1598
+ This adds \`$property\` versions of iterable theme properties:
1599
+
1600
+ | Original Path | $iterator Path |
1601
+ |--------------------------|---------------------------|
1602
+ | \`theme.intents.primary\` | \`theme.$intents.primary\` |
1603
+ | \`theme.sizes.button.md\` | \`theme.sizes.$button.md\` |
1604
+
1605
+ ## Usage Examples
1606
+
1607
+ ### Expand Intents
1608
+
1609
+ \`\`\`typescript
1610
+ // Single definition
1611
+ variants: {
1612
+ intent: {
1613
+ backgroundColor: theme.$intents.light,
1614
+ borderColor: theme.$intents.primary,
1615
+ },
1616
+ }
1617
+
1618
+ // Expands to all intent keys (primary, success, error, warning, etc.)
1619
+ // Result:
1620
+ // intent: {
1621
+ // primary: { backgroundColor: theme.intents.primary.light, borderColor: theme.intents.primary.primary },
1622
+ // success: { backgroundColor: theme.intents.success.light, borderColor: theme.intents.success.primary },
1623
+ // error: { ... },
1624
+ // ...
1625
+ // }
1626
+ \`\`\`
1627
+
1628
+ ### Expand Sizes
1629
+
1630
+ \`\`\`typescript
1631
+ // Single definition
1632
+ variants: {
1633
+ size: {
1634
+ paddingVertical: theme.sizes.$button.paddingVertical,
1635
+ fontSize: theme.sizes.$button.fontSize,
1636
+ },
1637
+ }
1638
+
1639
+ // Expands to all size keys (xs, sm, md, lg, xl)
1640
+ // Result:
1641
+ // size: {
1642
+ // xs: { paddingVertical: theme.sizes.button.xs.paddingVertical, fontSize: theme.sizes.button.xs.fontSize },
1643
+ // sm: { paddingVertical: theme.sizes.button.sm.paddingVertical, fontSize: theme.sizes.button.sm.fontSize },
1644
+ // md: { ... },
1645
+ // ...
1646
+ // }
1647
+ \`\`\`
1648
+
1649
+ ## Complete Example
1650
+
1651
+ \`\`\`typescript
1652
+ import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
1653
+ import type { Theme as BaseTheme } from '@idealyst/theme';
1654
+
1655
+ type Theme = ThemeStyleWrapper<BaseTheme>;
1656
+
1657
+ export const chipStyles = defineStyle('Chip', (theme: Theme) => ({
1658
+ chip: {
1659
+ borderRadius: 999,
1660
+
1661
+ variants: {
1662
+ // Expand for all sizes
1663
+ size: {
1664
+ paddingVertical: theme.sizes.$chip.paddingVertical,
1665
+ paddingHorizontal: theme.sizes.$chip.paddingHorizontal,
1666
+ minHeight: theme.sizes.$chip.minHeight,
1667
+ },
1668
+
1669
+ // Expand for all intents
1670
+ intent: {
1671
+ backgroundColor: theme.$intents.light,
1672
+ borderColor: theme.$intents.primary,
1673
+ },
1674
+ },
1675
+ },
1676
+
1677
+ text: {
1678
+ variants: {
1679
+ size: {
1680
+ fontSize: theme.sizes.$chip.fontSize,
1681
+ lineHeight: theme.sizes.$chip.lineHeight,
1682
+ },
1683
+
1684
+ intent: {
1685
+ color: theme.$intents.dark,
1686
+ },
1687
+ },
1688
+ },
1689
+ }));
1690
+ \`\`\`
1691
+
1692
+ ## createIteratorStyles()
1693
+
1694
+ Alternative to defineStyle for custom components:
1695
+
1696
+ \`\`\`typescript
1697
+ import { createIteratorStyles } from '@idealyst/theme';
1698
+
1699
+ export const styles = createIteratorStyles((theme) => ({
1700
+ box: {
1701
+ variants: {
1702
+ intent: {
1703
+ backgroundColor: theme.$intents.light,
1704
+ },
1705
+ },
1706
+ },
1707
+ }));
1708
+ \`\`\`
1709
+
1710
+ ## Benefits
1711
+
1712
+ 1. **DRY Code**: Define once, expand to many
1713
+ 2. **Type Safety**: TypeScript validates iterator properties
1714
+ 3. **Maintainable**: Adding new sizes/intents to theme auto-expands
1715
+ 4. **Zero Runtime Cost**: Expansion happens at build time
1048
1716
  `,
1049
1717
  };
1050
1718
  //# sourceMappingURL=framework-guides.js.map