@idealyst/mcp-server 1.2.24 → 1.2.26
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/dist/index.cjs +22366 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +0 -2
- package/dist/index.js +22186 -1034
- package/dist/index.js.map +1 -1
- package/package.json +17 -7
- package/dist/data/cli-commands.d.ts +0 -2
- package/dist/data/cli-commands.d.ts.map +0 -1
- package/dist/data/cli-commands.js +0 -100
- package/dist/data/cli-commands.js.map +0 -1
- package/dist/data/components/Accordion.d.ts +0 -15
- package/dist/data/components/Accordion.d.ts.map +0 -1
- package/dist/data/components/Accordion.js +0 -113
- package/dist/data/components/Accordion.js.map +0 -1
- package/dist/data/components/ActivityIndicator.d.ts +0 -15
- package/dist/data/components/ActivityIndicator.d.ts.map +0 -1
- package/dist/data/components/ActivityIndicator.js +0 -80
- package/dist/data/components/ActivityIndicator.js.map +0 -1
- package/dist/data/components/Alert.d.ts +0 -15
- package/dist/data/components/Alert.d.ts.map +0 -1
- package/dist/data/components/Alert.js +0 -130
- package/dist/data/components/Alert.js.map +0 -1
- package/dist/data/components/Avatar.d.ts +0 -15
- package/dist/data/components/Avatar.d.ts.map +0 -1
- package/dist/data/components/Avatar.js +0 -91
- package/dist/data/components/Avatar.js.map +0 -1
- package/dist/data/components/Badge.d.ts +0 -15
- package/dist/data/components/Badge.d.ts.map +0 -1
- package/dist/data/components/Badge.js +0 -64
- package/dist/data/components/Badge.js.map +0 -1
- package/dist/data/components/Breadcrumb.d.ts +0 -15
- package/dist/data/components/Breadcrumb.d.ts.map +0 -1
- package/dist/data/components/Breadcrumb.js +0 -92
- package/dist/data/components/Breadcrumb.js.map +0 -1
- package/dist/data/components/Button.d.ts +0 -16
- package/dist/data/components/Button.d.ts.map +0 -1
- package/dist/data/components/Button.js +0 -118
- package/dist/data/components/Button.js.map +0 -1
- package/dist/data/components/Card.d.ts +0 -15
- package/dist/data/components/Card.d.ts.map +0 -1
- package/dist/data/components/Card.js +0 -75
- package/dist/data/components/Card.js.map +0 -1
- package/dist/data/components/Checkbox.d.ts +0 -15
- package/dist/data/components/Checkbox.d.ts.map +0 -1
- package/dist/data/components/Checkbox.js +0 -118
- package/dist/data/components/Checkbox.js.map +0 -1
- package/dist/data/components/Chip.d.ts +0 -15
- package/dist/data/components/Chip.d.ts.map +0 -1
- package/dist/data/components/Chip.js +0 -94
- package/dist/data/components/Chip.js.map +0 -1
- package/dist/data/components/Dialog.d.ts +0 -15
- package/dist/data/components/Dialog.d.ts.map +0 -1
- package/dist/data/components/Dialog.js +0 -137
- package/dist/data/components/Dialog.js.map +0 -1
- package/dist/data/components/Divider.d.ts +0 -15
- package/dist/data/components/Divider.d.ts.map +0 -1
- package/dist/data/components/Divider.js +0 -68
- package/dist/data/components/Divider.js.map +0 -1
- package/dist/data/components/Icon.d.ts +0 -15
- package/dist/data/components/Icon.d.ts.map +0 -1
- package/dist/data/components/Icon.js +0 -68
- package/dist/data/components/Icon.js.map +0 -1
- package/dist/data/components/Image.d.ts +0 -15
- package/dist/data/components/Image.d.ts.map +0 -1
- package/dist/data/components/Image.js +0 -119
- package/dist/data/components/Image.js.map +0 -1
- package/dist/data/components/Input.d.ts +0 -15
- package/dist/data/components/Input.d.ts.map +0 -1
- package/dist/data/components/Input.js +0 -155
- package/dist/data/components/Input.js.map +0 -1
- package/dist/data/components/Link.d.ts +0 -15
- package/dist/data/components/Link.d.ts.map +0 -1
- package/dist/data/components/Link.js +0 -142
- package/dist/data/components/Link.js.map +0 -1
- package/dist/data/components/List.d.ts +0 -15
- package/dist/data/components/List.d.ts.map +0 -1
- package/dist/data/components/List.js +0 -113
- package/dist/data/components/List.js.map +0 -1
- package/dist/data/components/Menu.d.ts +0 -15
- package/dist/data/components/Menu.d.ts.map +0 -1
- package/dist/data/components/Menu.js +0 -123
- package/dist/data/components/Menu.js.map +0 -1
- package/dist/data/components/Popover.d.ts +0 -15
- package/dist/data/components/Popover.d.ts.map +0 -1
- package/dist/data/components/Popover.js +0 -157
- package/dist/data/components/Popover.js.map +0 -1
- package/dist/data/components/Pressable.d.ts +0 -15
- package/dist/data/components/Pressable.d.ts.map +0 -1
- package/dist/data/components/Pressable.js +0 -125
- package/dist/data/components/Pressable.js.map +0 -1
- package/dist/data/components/Progress.d.ts +0 -15
- package/dist/data/components/Progress.d.ts.map +0 -1
- package/dist/data/components/Progress.js +0 -93
- package/dist/data/components/Progress.js.map +0 -1
- package/dist/data/components/RadioButton.d.ts +0 -15
- package/dist/data/components/RadioButton.d.ts.map +0 -1
- package/dist/data/components/RadioButton.js +0 -131
- package/dist/data/components/RadioButton.js.map +0 -1
- package/dist/data/components/SVGImage.d.ts +0 -15
- package/dist/data/components/SVGImage.d.ts.map +0 -1
- package/dist/data/components/SVGImage.js +0 -112
- package/dist/data/components/SVGImage.js.map +0 -1
- package/dist/data/components/Screen.d.ts +0 -15
- package/dist/data/components/Screen.d.ts.map +0 -1
- package/dist/data/components/Screen.js +0 -109
- package/dist/data/components/Screen.js.map +0 -1
- package/dist/data/components/Select.d.ts +0 -15
- package/dist/data/components/Select.d.ts.map +0 -1
- package/dist/data/components/Select.js +0 -141
- package/dist/data/components/Select.js.map +0 -1
- package/dist/data/components/Skeleton.d.ts +0 -15
- package/dist/data/components/Skeleton.d.ts.map +0 -1
- package/dist/data/components/Skeleton.js +0 -100
- package/dist/data/components/Skeleton.js.map +0 -1
- package/dist/data/components/Slider.d.ts +0 -15
- package/dist/data/components/Slider.d.ts.map +0 -1
- package/dist/data/components/Slider.js +0 -151
- package/dist/data/components/Slider.js.map +0 -1
- package/dist/data/components/Switch.d.ts +0 -15
- package/dist/data/components/Switch.d.ts.map +0 -1
- package/dist/data/components/Switch.js +0 -128
- package/dist/data/components/Switch.js.map +0 -1
- package/dist/data/components/TabBar.d.ts +0 -17
- package/dist/data/components/TabBar.d.ts.map +0 -1
- package/dist/data/components/TabBar.js +0 -244
- package/dist/data/components/TabBar.js.map +0 -1
- package/dist/data/components/Table.d.ts +0 -15
- package/dist/data/components/Table.d.ts.map +0 -1
- package/dist/data/components/Table.js +0 -159
- package/dist/data/components/Table.js.map +0 -1
- package/dist/data/components/Tabs.d.ts +0 -15
- package/dist/data/components/Tabs.d.ts.map +0 -1
- package/dist/data/components/Tabs.js +0 -150
- package/dist/data/components/Tabs.js.map +0 -1
- package/dist/data/components/Text.d.ts +0 -15
- package/dist/data/components/Text.d.ts.map +0 -1
- package/dist/data/components/Text.js +0 -97
- package/dist/data/components/Text.js.map +0 -1
- package/dist/data/components/TextArea.d.ts +0 -15
- package/dist/data/components/TextArea.d.ts.map +0 -1
- package/dist/data/components/TextArea.js +0 -156
- package/dist/data/components/TextArea.js.map +0 -1
- package/dist/data/components/Tooltip.d.ts +0 -15
- package/dist/data/components/Tooltip.d.ts.map +0 -1
- package/dist/data/components/Tooltip.js +0 -103
- package/dist/data/components/Tooltip.js.map +0 -1
- package/dist/data/components/Video.d.ts +0 -15
- package/dist/data/components/Video.d.ts.map +0 -1
- package/dist/data/components/Video.js +0 -166
- package/dist/data/components/Video.js.map +0 -1
- package/dist/data/components/View.d.ts +0 -15
- package/dist/data/components/View.d.ts.map +0 -1
- package/dist/data/components/View.js +0 -127
- package/dist/data/components/View.js.map +0 -1
- package/dist/data/components/index.d.ts +0 -38
- package/dist/data/components/index.d.ts.map +0 -1
- package/dist/data/components/index.js +0 -113
- package/dist/data/components/index.js.map +0 -1
- package/dist/data/framework-guides.d.ts +0 -2
- package/dist/data/framework-guides.d.ts.map +0 -1
- package/dist/data/framework-guides.js +0 -1730
- package/dist/data/framework-guides.js.map +0 -1
- package/dist/data/icon-guide.d.ts +0 -2
- package/dist/data/icon-guide.d.ts.map +0 -1
- package/dist/data/icon-guide.js +0 -285
- package/dist/data/icon-guide.js.map +0 -1
- package/dist/data/icons.json +0 -7452
- package/dist/data/navigation-guides.d.ts +0 -2
- package/dist/data/navigation-guides.d.ts.map +0 -1
- package/dist/data/navigation-guides.js +0 -2144
- package/dist/data/navigation-guides.js.map +0 -1
- package/dist/data/packages.d.ts +0 -39
- package/dist/data/packages.d.ts.map +0 -1
- package/dist/data/packages.js +0 -550
- package/dist/data/packages.js.map +0 -1
- package/dist/data/recipes.d.ts +0 -36
- package/dist/data/recipes.d.ts.map +0 -1
- package/dist/data/recipes.js +0 -2945
- package/dist/data/recipes.js.map +0 -1
- package/dist/data/storage-guides.d.ts +0 -2
- package/dist/data/storage-guides.d.ts.map +0 -1
- package/dist/data/storage-guides.js +0 -418
- package/dist/data/storage-guides.js.map +0 -1
- package/dist/data/translate-guides.d.ts +0 -2
- package/dist/data/translate-guides.d.ts.map +0 -1
- package/dist/data/translate-guides.js +0 -1030
- package/dist/data/translate-guides.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/tools/get-types.d.ts +0 -37
- package/dist/tools/get-types.d.ts.map +0 -1
- package/dist/tools/get-types.js +0 -148
- package/dist/tools/get-types.js.map +0 -1
|
@@ -1,1730 +0,0 @@
|
|
|
1
|
-
export const frameworkGuides = {
|
|
2
|
-
"idealyst://framework/getting-started": `# Getting Started with Idealyst
|
|
3
|
-
|
|
4
|
-
Idealyst is a modern, cross-platform framework for building React and React Native applications with a powerful component library, type-safe APIs, and monorepo tooling.
|
|
5
|
-
|
|
6
|
-
## Quick Start
|
|
7
|
-
|
|
8
|
-
### 1. Create a New Workspace
|
|
9
|
-
|
|
10
|
-
\`\`\`bash
|
|
11
|
-
npx @idealyst/cli init my-app
|
|
12
|
-
cd my-app
|
|
13
|
-
\`\`\`
|
|
14
|
-
|
|
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:
|
|
23
|
-
- Yarn 3 workspace setup
|
|
24
|
-
- TypeScript configuration
|
|
25
|
-
- Jest testing setup
|
|
26
|
-
- Git repository
|
|
27
|
-
- Dev container configuration
|
|
28
|
-
|
|
29
|
-
### 2. Start Development
|
|
30
|
-
|
|
31
|
-
\`\`\`bash
|
|
32
|
-
# Start web dev server
|
|
33
|
-
cd packages/web
|
|
34
|
-
yarn dev
|
|
35
|
-
|
|
36
|
-
# Start native dev (in another terminal)
|
|
37
|
-
cd packages/native
|
|
38
|
-
yarn start
|
|
39
|
-
|
|
40
|
-
# Start API server (in another terminal)
|
|
41
|
-
cd packages/api
|
|
42
|
-
yarn dev
|
|
43
|
-
\`\`\`
|
|
44
|
-
|
|
45
|
-
### 3. Configure Babel (Required for Styling)
|
|
46
|
-
|
|
47
|
-
Add the Idealyst plugin to your babel.config.js:
|
|
48
|
-
|
|
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
|
-
};
|
|
58
|
-
\`\`\`
|
|
59
|
-
|
|
60
|
-
## Project Structure
|
|
61
|
-
|
|
62
|
-
\`\`\`
|
|
63
|
-
my-app/
|
|
64
|
-
├── packages/
|
|
65
|
-
│ ├── web/ # React web app (Vite)
|
|
66
|
-
│ ├── native/ # React Native app
|
|
67
|
-
│ ├── api/ # tRPC + GraphQL API server
|
|
68
|
-
│ ├── database/ # Prisma database layer
|
|
69
|
-
│ └── shared/ # Shared utilities & tRPC client
|
|
70
|
-
├── package.json
|
|
71
|
-
├── tsconfig.json
|
|
72
|
-
└── yarn.lock
|
|
73
|
-
\`\`\`
|
|
74
|
-
|
|
75
|
-
## Key Features
|
|
76
|
-
|
|
77
|
-
- **Cross-Platform Components**: Use the same components for web and native
|
|
78
|
-
- **Type-Safe APIs**: End-to-end type safety with tRPC
|
|
79
|
-
- **Modern Tooling**: Vite, TypeScript, Jest, Prisma
|
|
80
|
-
- **Monorepo Structure**: Share code across packages
|
|
81
|
-
- **Theme System**: Consistent styling with react-native-unistyles
|
|
82
|
-
- **Style Extensions**: Customize component styles at build time
|
|
83
|
-
- **Navigation**: Unified navigation for web and native
|
|
84
|
-
|
|
85
|
-
## Next Steps
|
|
86
|
-
|
|
87
|
-
1. Explore the component library: \`@idealyst/components\`
|
|
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
|
|
92
|
-
`,
|
|
93
|
-
"idealyst://framework/components-overview": `# Idealyst Components Overview
|
|
94
|
-
|
|
95
|
-
Idealyst provides a comprehensive library of cross-platform React components organized into categories.
|
|
96
|
-
|
|
97
|
-
## Component Categories
|
|
98
|
-
|
|
99
|
-
### Layout Components
|
|
100
|
-
- **View**: Flex container with spacing system
|
|
101
|
-
- **Screen**: Full-screen container with safe area handling
|
|
102
|
-
- **Divider**: Visual separator with orientation options
|
|
103
|
-
|
|
104
|
-
### Form Components
|
|
105
|
-
- **Button**: Interactive button with variants, intents, and icons
|
|
106
|
-
- **Input**: Text input with label, validation, and helper text
|
|
107
|
-
- **Checkbox**: Form checkbox with label support
|
|
108
|
-
- **Select**: Dropdown selection component
|
|
109
|
-
- **Switch**: Toggle switch component
|
|
110
|
-
- **RadioButton**: Radio button group
|
|
111
|
-
- **Slider**: Range slider component
|
|
112
|
-
- **TextArea**: Multi-line text input
|
|
113
|
-
|
|
114
|
-
### Display Components
|
|
115
|
-
- **Text**: Styled text with sizes and weights
|
|
116
|
-
- **Card**: Content container with variants
|
|
117
|
-
- **Badge**: Status indicator
|
|
118
|
-
- **Chip**: Compact element for tags and filters
|
|
119
|
-
- **Avatar**: User profile image
|
|
120
|
-
- **Icon**: MDI icon with theming
|
|
121
|
-
- **Skeleton**: Loading placeholder
|
|
122
|
-
- **Alert**: Notification message
|
|
123
|
-
- **Accordion**: Collapsible content sections
|
|
124
|
-
- **Image**: Cross-platform image component
|
|
125
|
-
- **SVGImage**: SVG image renderer
|
|
126
|
-
- **Video**: Video player component
|
|
127
|
-
|
|
128
|
-
### Navigation Components
|
|
129
|
-
- **Tabs**: Tab navigation
|
|
130
|
-
- **TabBar**: Bottom tab bar
|
|
131
|
-
- **Breadcrumb**: Breadcrumb navigation
|
|
132
|
-
- **Menu**: Dropdown menu
|
|
133
|
-
- **MenuItem**: Individual menu item
|
|
134
|
-
- **List**: Vertical list with sections
|
|
135
|
-
- **ListItem**: Individual list item
|
|
136
|
-
- **Link**: Navigation link component
|
|
137
|
-
|
|
138
|
-
### Overlay Components
|
|
139
|
-
- **Dialog**: Modal dialog
|
|
140
|
-
- **Popover**: Contextual overlay
|
|
141
|
-
- **Tooltip**: Hover tooltip
|
|
142
|
-
|
|
143
|
-
### Feedback Components
|
|
144
|
-
- **Progress**: Progress indicator (linear/circular)
|
|
145
|
-
- **ActivityIndicator**: Loading spinner
|
|
146
|
-
|
|
147
|
-
### Data Components
|
|
148
|
-
- **Table**: Data table with sorting and filtering
|
|
149
|
-
- **DataGrid**: Advanced data grid
|
|
150
|
-
- **DatePicker**: Date selection component
|
|
151
|
-
- **TimePicker**: Time selection component
|
|
152
|
-
- **DateTimePicker**: Combined date and time picker
|
|
153
|
-
|
|
154
|
-
## Common Props
|
|
155
|
-
|
|
156
|
-
Most components share common props:
|
|
157
|
-
- \`style\`: Custom styles
|
|
158
|
-
- \`testID\`: Test identifier
|
|
159
|
-
- \`disabled\`: Disable interaction
|
|
160
|
-
|
|
161
|
-
### Intent Colors
|
|
162
|
-
Components support intent-based colors:
|
|
163
|
-
- \`primary\`: Main brand actions
|
|
164
|
-
- \`neutral\`: Secondary actions
|
|
165
|
-
- \`success\`: Positive actions
|
|
166
|
-
- \`error\`: Destructive actions
|
|
167
|
-
- \`warning\`: Caution actions
|
|
168
|
-
|
|
169
|
-
### Type/Variant Props
|
|
170
|
-
Many components offer visual type or variant options:
|
|
171
|
-
- Button \`type\`: \`contained\`, \`outlined\`, \`text\`
|
|
172
|
-
- Card \`type\`: \`default\`, \`outlined\`, \`elevated\`, \`filled\`
|
|
173
|
-
- Chip \`type\`: \`filled\`, \`outlined\`, \`soft\`
|
|
174
|
-
- Progress \`variant\`: \`linear\`, \`circular\`
|
|
175
|
-
|
|
176
|
-
### Sizes
|
|
177
|
-
Most components support size variants:
|
|
178
|
-
- \`sm\`, \`md\`, \`lg\`
|
|
179
|
-
- Sometimes 'xs' and 'xl', but varies by component
|
|
180
|
-
|
|
181
|
-
## Icon Support
|
|
182
|
-
|
|
183
|
-
Components with icon support accept:
|
|
184
|
-
- **String icon names**: Material Design Icons
|
|
185
|
-
- **React elements**: Custom icon components
|
|
186
|
-
|
|
187
|
-
Example:
|
|
188
|
-
\`\`\`tsx
|
|
189
|
-
<Button leftIcon="check">Save</Button>
|
|
190
|
-
<Button leftIcon={<CustomIcon />}>Save</Button>
|
|
191
|
-
<Button rightIcon="arrow-right">Next</Button>
|
|
192
|
-
\`\`\`
|
|
193
|
-
|
|
194
|
-
## Theming
|
|
195
|
-
|
|
196
|
-
All components use the Unistyles theming system:
|
|
197
|
-
- Light and dark mode support
|
|
198
|
-
- Customizable color palettes
|
|
199
|
-
- Responsive breakpoints
|
|
200
|
-
- Platform-specific styles
|
|
201
|
-
|
|
202
|
-
## Import Pattern
|
|
203
|
-
|
|
204
|
-
\`\`\`tsx
|
|
205
|
-
import { Button, Card, Text, View } from '@idealyst/components';
|
|
206
|
-
\`\`\`
|
|
207
|
-
`,
|
|
208
|
-
"idealyst://framework/theming": `# Theming Guide
|
|
209
|
-
|
|
210
|
-
Idealyst uses react-native-unistyles for cross-platform theming with full TypeScript support. Themes are created using a fluent builder pattern.
|
|
211
|
-
|
|
212
|
-
## Theme Builder API
|
|
213
|
-
|
|
214
|
-
Create themes using the builder pattern:
|
|
215
|
-
|
|
216
|
-
\`\`\`typescript
|
|
217
|
-
import { createTheme } from '@idealyst/theme';
|
|
218
|
-
|
|
219
|
-
export const myTheme = createTheme()
|
|
220
|
-
// Add semantic intents
|
|
221
|
-
.addIntent('primary', {
|
|
222
|
-
primary: '#3b82f6', // Main color
|
|
223
|
-
contrast: '#ffffff', // Text on primary background
|
|
224
|
-
light: '#bfdbfe', // Lighter variant
|
|
225
|
-
dark: '#1e40af', // Darker variant
|
|
226
|
-
})
|
|
227
|
-
.addIntent('success', {
|
|
228
|
-
primary: '#22c55e',
|
|
229
|
-
contrast: '#ffffff',
|
|
230
|
-
light: '#a7f3d0',
|
|
231
|
-
dark: '#165e29',
|
|
232
|
-
})
|
|
233
|
-
.addIntent('error', {
|
|
234
|
-
primary: '#ef4444',
|
|
235
|
-
contrast: '#ffffff',
|
|
236
|
-
light: '#fca5a1',
|
|
237
|
-
dark: '#9b2222',
|
|
238
|
-
})
|
|
239
|
-
|
|
240
|
-
// Add border radii
|
|
241
|
-
.addRadius('none', 0)
|
|
242
|
-
.addRadius('sm', 4)
|
|
243
|
-
.addRadius('md', 8)
|
|
244
|
-
.addRadius('lg', 12)
|
|
245
|
-
|
|
246
|
-
// Add shadows (cross-platform)
|
|
247
|
-
.addShadow('sm', {
|
|
248
|
-
elevation: 1,
|
|
249
|
-
shadowColor: '#000000',
|
|
250
|
-
shadowOffset: { width: 0, height: 1 },
|
|
251
|
-
shadowOpacity: 0.08,
|
|
252
|
-
shadowRadius: 1,
|
|
253
|
-
boxShadow: '0px 1px 2px rgba(0, 0, 0, 0.1)', // web-only
|
|
254
|
-
})
|
|
255
|
-
|
|
256
|
-
// Set colors
|
|
257
|
-
.setColors({
|
|
258
|
-
pallet: { /* color palette */ },
|
|
259
|
-
surface: {
|
|
260
|
-
screen: '#ffffff',
|
|
261
|
-
primary: '#ffffff',
|
|
262
|
-
secondary: '#f5f5f5',
|
|
263
|
-
inverse: '#000000',
|
|
264
|
-
},
|
|
265
|
-
text: {
|
|
266
|
-
primary: '#000000',
|
|
267
|
-
secondary: '#333333',
|
|
268
|
-
inverse: '#ffffff',
|
|
269
|
-
},
|
|
270
|
-
border: {
|
|
271
|
-
primary: '#e0e0e0',
|
|
272
|
-
disabled: '#f0f0f0',
|
|
273
|
-
},
|
|
274
|
-
})
|
|
275
|
-
|
|
276
|
-
// Set component sizes (xs, sm, md, lg, xl)
|
|
277
|
-
.setSizes({
|
|
278
|
-
button: {
|
|
279
|
-
xs: { paddingVertical: 4, paddingHorizontal: 8, minHeight: 24, fontSize: 12 },
|
|
280
|
-
sm: { paddingVertical: 6, paddingHorizontal: 12, minHeight: 32, fontSize: 14 },
|
|
281
|
-
md: { paddingVertical: 8, paddingHorizontal: 16, minHeight: 40, fontSize: 16 },
|
|
282
|
-
lg: { paddingVertical: 10, paddingHorizontal: 20, minHeight: 48, fontSize: 18 },
|
|
283
|
-
xl: { paddingVertical: 12, paddingHorizontal: 24, minHeight: 56, fontSize: 20 },
|
|
284
|
-
},
|
|
285
|
-
// ... other components (chip, badge, icon, input, etc.)
|
|
286
|
-
})
|
|
287
|
-
|
|
288
|
-
// Set interaction styles
|
|
289
|
-
.setInteraction({
|
|
290
|
-
focusedBackground: 'rgba(59, 130, 246, 0.08)',
|
|
291
|
-
focusBorder: 'rgba(59, 130, 246, 0.3)',
|
|
292
|
-
opacity: { hover: 0.9, active: 0.75, disabled: 0.5 },
|
|
293
|
-
})
|
|
294
|
-
|
|
295
|
-
// Set responsive breakpoints
|
|
296
|
-
.setBreakpoints({
|
|
297
|
-
xs: 0, // Portrait phones
|
|
298
|
-
sm: 576, // Landscape phones
|
|
299
|
-
md: 768, // Tablets
|
|
300
|
-
lg: 992, // Desktops
|
|
301
|
-
xl: 1200, // Large desktops
|
|
302
|
-
})
|
|
303
|
-
|
|
304
|
-
.build();
|
|
305
|
-
\`\`\`
|
|
306
|
-
|
|
307
|
-
## Intent Structure
|
|
308
|
-
|
|
309
|
-
Each intent defines four color values:
|
|
310
|
-
|
|
311
|
-
| Property | Purpose |
|
|
312
|
-
|------------|-----------------------------------|
|
|
313
|
-
| \`primary\` | Main color used for backgrounds |
|
|
314
|
-
| \`contrast\` | Text color on primary background |
|
|
315
|
-
| \`light\` | Lighter tint for subtle states |
|
|
316
|
-
| \`dark\` | Darker shade for pressed states |
|
|
317
|
-
|
|
318
|
-
## Extending an Existing Theme
|
|
319
|
-
|
|
320
|
-
Use \`fromTheme()\` to extend a base theme:
|
|
321
|
-
|
|
322
|
-
\`\`\`typescript
|
|
323
|
-
import { fromTheme, lightTheme } from '@idealyst/theme';
|
|
324
|
-
|
|
325
|
-
export const brandTheme = fromTheme(lightTheme)
|
|
326
|
-
.addIntent('brand', {
|
|
327
|
-
primary: '#6366f1',
|
|
328
|
-
contrast: '#ffffff',
|
|
329
|
-
light: '#818cf8',
|
|
330
|
-
dark: '#4f46e5',
|
|
331
|
-
})
|
|
332
|
-
.build();
|
|
333
|
-
\`\`\`
|
|
334
|
-
|
|
335
|
-
## Registering Your Theme
|
|
336
|
-
|
|
337
|
-
For full TypeScript inference:
|
|
338
|
-
|
|
339
|
-
\`\`\`typescript
|
|
340
|
-
// src/theme/styles.ts
|
|
341
|
-
export const myTheme = createTheme()
|
|
342
|
-
// ... builder chain
|
|
343
|
-
.build();
|
|
344
|
-
|
|
345
|
-
// Register the theme type
|
|
346
|
-
declare module '@idealyst/theme' {
|
|
347
|
-
interface RegisteredTheme {
|
|
348
|
-
theme: typeof myTheme;
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
\`\`\`
|
|
352
|
-
|
|
353
|
-
## Using Themes with Unistyles
|
|
354
|
-
|
|
355
|
-
\`\`\`typescript
|
|
356
|
-
import { UnistylesRegistry } from 'react-native-unistyles';
|
|
357
|
-
import { lightTheme, darkTheme } from '@idealyst/theme';
|
|
358
|
-
|
|
359
|
-
UnistylesRegistry
|
|
360
|
-
.addThemes({
|
|
361
|
-
light: lightTheme,
|
|
362
|
-
dark: darkTheme,
|
|
363
|
-
})
|
|
364
|
-
.addConfig({
|
|
365
|
-
initialTheme: 'light',
|
|
366
|
-
});
|
|
367
|
-
\`\`\`
|
|
368
|
-
|
|
369
|
-
## Platform-Specific Styles
|
|
370
|
-
|
|
371
|
-
\`\`\`typescript
|
|
372
|
-
const styles = StyleSheet.create((theme) => ({
|
|
373
|
-
button: {
|
|
374
|
-
padding: 16,
|
|
375
|
-
|
|
376
|
-
_web: {
|
|
377
|
-
cursor: 'pointer',
|
|
378
|
-
transition: 'all 0.1s ease',
|
|
379
|
-
_hover: { opacity: 0.9 },
|
|
380
|
-
_active: { opacity: 0.75 },
|
|
381
|
-
},
|
|
382
|
-
|
|
383
|
-
_native: {
|
|
384
|
-
elevation: 2,
|
|
385
|
-
},
|
|
386
|
-
},
|
|
387
|
-
}));
|
|
388
|
-
\`\`\`
|
|
389
|
-
|
|
390
|
-
## See Also
|
|
391
|
-
|
|
392
|
-
- \`idealyst://framework/style-system\` - Style definition APIs (defineStyle, extendStyle)
|
|
393
|
-
- \`idealyst://framework/babel-plugin\` - Babel plugin configuration
|
|
394
|
-
- \`idealyst://framework/breakpoints\` - Responsive breakpoint system
|
|
395
|
-
`,
|
|
396
|
-
"idealyst://framework/cli": `# Idealyst CLI Reference
|
|
397
|
-
|
|
398
|
-
The Idealyst CLI provides commands for creating and managing Idealyst projects.
|
|
399
|
-
|
|
400
|
-
## Installation
|
|
401
|
-
|
|
402
|
-
\`\`\`bash
|
|
403
|
-
npm install -g @idealyst/cli
|
|
404
|
-
# or
|
|
405
|
-
npx @idealyst/cli <command>
|
|
406
|
-
\`\`\`
|
|
407
|
-
|
|
408
|
-
## Commands
|
|
409
|
-
|
|
410
|
-
### init
|
|
411
|
-
|
|
412
|
-
Initialize a new Idealyst workspace.
|
|
413
|
-
|
|
414
|
-
\`\`\`bash
|
|
415
|
-
idealyst init <workspace-name> [options]
|
|
416
|
-
\`\`\`
|
|
417
|
-
|
|
418
|
-
**Arguments:**
|
|
419
|
-
- \`workspace-name\`: Name for the workspace directory
|
|
420
|
-
|
|
421
|
-
**Options:**
|
|
422
|
-
- \`--git\`: Initialize git repository (default: true)
|
|
423
|
-
- \`--no-git\`: Skip git initialization
|
|
424
|
-
- \`--install\`: Install dependencies (default: true)
|
|
425
|
-
- \`--no-install\`: Skip dependency installation
|
|
426
|
-
|
|
427
|
-
**Examples:**
|
|
428
|
-
\`\`\`bash
|
|
429
|
-
idealyst init my-app
|
|
430
|
-
idealyst init my-company-app --no-git
|
|
431
|
-
\`\`\`
|
|
432
|
-
|
|
433
|
-
**Creates:**
|
|
434
|
-
- Monorepo workspace structure
|
|
435
|
-
- package.json with workspaces
|
|
436
|
-
- TypeScript configuration
|
|
437
|
-
- Jest setup
|
|
438
|
-
- Git repository (optional)
|
|
439
|
-
- Dev container configuration
|
|
440
|
-
|
|
441
|
-
### create
|
|
442
|
-
|
|
443
|
-
Create a new package in the workspace.
|
|
444
|
-
|
|
445
|
-
\`\`\`bash
|
|
446
|
-
idealyst create <name> --type <type> [options]
|
|
447
|
-
\`\`\`
|
|
448
|
-
|
|
449
|
-
**Arguments:**
|
|
450
|
-
- \`name\`: Package name
|
|
451
|
-
|
|
452
|
-
**Options:**
|
|
453
|
-
- \`--type <type>\`: Package type (required)
|
|
454
|
-
- \`web\`: React web app with Vite
|
|
455
|
-
- \`mobile\`: React Native mobile app
|
|
456
|
-
- \`api\`: tRPC API server
|
|
457
|
-
- \`shared\`: Shared utilities library
|
|
458
|
-
- \`--app-name <name>\`: Display name for mobile apps (required for mobile)
|
|
459
|
-
- \`--with-trpc\`: Include tRPC setup (web/mobile)
|
|
460
|
-
- \`--no-trpc\`: Exclude tRPC setup (web/mobile)
|
|
461
|
-
|
|
462
|
-
**Examples:**
|
|
463
|
-
\`\`\`bash
|
|
464
|
-
# Web app
|
|
465
|
-
idealyst create web --type web --with-trpc
|
|
466
|
-
|
|
467
|
-
# Mobile app
|
|
468
|
-
idealyst create mobile --type mobile --app-name "My App" --with-trpc
|
|
469
|
-
|
|
470
|
-
# API server
|
|
471
|
-
idealyst create api --type api
|
|
472
|
-
|
|
473
|
-
# Shared library
|
|
474
|
-
idealyst create shared --type shared
|
|
475
|
-
\`\`\`
|
|
476
|
-
|
|
477
|
-
**Note:** The database package is automatically created during workspace initialization. Use the \`init\` command to create a new workspace with all packages including database.
|
|
478
|
-
|
|
479
|
-
## Package Types
|
|
480
|
-
|
|
481
|
-
### Web Package
|
|
482
|
-
- Vite + React 19
|
|
483
|
-
- TypeScript
|
|
484
|
-
- React Router
|
|
485
|
-
- Optional tRPC client
|
|
486
|
-
- @idealyst/components
|
|
487
|
-
- @idealyst/theme
|
|
488
|
-
|
|
489
|
-
### Mobile Package
|
|
490
|
-
- React Native 0.80
|
|
491
|
-
- TypeScript
|
|
492
|
-
- React Navigation
|
|
493
|
-
- Optional tRPC client
|
|
494
|
-
- @idealyst/components
|
|
495
|
-
- @idealyst/navigation
|
|
496
|
-
|
|
497
|
-
### API Package
|
|
498
|
-
- tRPC server
|
|
499
|
-
- Express
|
|
500
|
-
- TypeScript
|
|
501
|
-
- CORS enabled
|
|
502
|
-
- WebSocket support
|
|
503
|
-
|
|
504
|
-
### Database Package
|
|
505
|
-
- Prisma ORM
|
|
506
|
-
- TypeScript
|
|
507
|
-
- Schema definition
|
|
508
|
-
- Migration support
|
|
509
|
-
- Multiple database support
|
|
510
|
-
|
|
511
|
-
### Shared Package
|
|
512
|
-
- TypeScript library
|
|
513
|
-
- Utility functions
|
|
514
|
-
- Type definitions
|
|
515
|
-
- Shared between packages
|
|
516
|
-
|
|
517
|
-
## Workspace Commands
|
|
518
|
-
|
|
519
|
-
Run these from workspace root:
|
|
520
|
-
|
|
521
|
-
\`\`\`bash
|
|
522
|
-
# Install all dependencies
|
|
523
|
-
yarn install
|
|
524
|
-
|
|
525
|
-
# Run tests
|
|
526
|
-
yarn test
|
|
527
|
-
yarn test:watch
|
|
528
|
-
yarn test:coverage
|
|
529
|
-
|
|
530
|
-
# Build all packages
|
|
531
|
-
yarn workspaces foreach run build
|
|
532
|
-
|
|
533
|
-
# Version management
|
|
534
|
-
yarn version:patch # Bump patch version
|
|
535
|
-
yarn version:minor # Bump minor version
|
|
536
|
-
yarn version:major # Bump major version
|
|
537
|
-
|
|
538
|
-
# Publish
|
|
539
|
-
yarn publish:all
|
|
540
|
-
\`\`\`
|
|
541
|
-
|
|
542
|
-
## Package Commands
|
|
543
|
-
|
|
544
|
-
Run these from package directory:
|
|
545
|
-
|
|
546
|
-
\`\`\`bash
|
|
547
|
-
# Development
|
|
548
|
-
yarn dev
|
|
549
|
-
|
|
550
|
-
# Build
|
|
551
|
-
yarn build
|
|
552
|
-
|
|
553
|
-
# Test
|
|
554
|
-
yarn test
|
|
555
|
-
|
|
556
|
-
# Type check
|
|
557
|
-
yarn type-check
|
|
558
|
-
|
|
559
|
-
# Lint
|
|
560
|
-
yarn lint
|
|
561
|
-
\`\`\`
|
|
562
|
-
|
|
563
|
-
## Project Structure
|
|
564
|
-
|
|
565
|
-
\`\`\`
|
|
566
|
-
workspace/
|
|
567
|
-
├── packages/
|
|
568
|
-
│ ├── web/
|
|
569
|
-
│ │ ├── src/
|
|
570
|
-
│ │ ├── public/
|
|
571
|
-
│ │ ├── package.json
|
|
572
|
-
│ │ └── vite.config.ts
|
|
573
|
-
│ ├── mobile/
|
|
574
|
-
│ │ ├── src/
|
|
575
|
-
│ │ ├── android/
|
|
576
|
-
│ │ ├── ios/
|
|
577
|
-
│ │ └── package.json
|
|
578
|
-
│ ├── api/
|
|
579
|
-
│ │ ├── src/
|
|
580
|
-
│ │ ├── trpc/
|
|
581
|
-
│ │ └── package.json
|
|
582
|
-
│ ├── database/
|
|
583
|
-
│ │ ├── prisma/
|
|
584
|
-
│ │ └── package.json
|
|
585
|
-
│ └── shared/
|
|
586
|
-
│ ├── src/
|
|
587
|
-
│ └── package.json
|
|
588
|
-
├── package.json
|
|
589
|
-
├── tsconfig.json
|
|
590
|
-
└── jest.config.js
|
|
591
|
-
\`\`\`
|
|
592
|
-
|
|
593
|
-
## Best Practices
|
|
594
|
-
|
|
595
|
-
1. **Use workspaces**: Keep related packages in the same workspace
|
|
596
|
-
2. **Share code**: Use the shared package for utilities
|
|
597
|
-
3. **Type safety**: Enable strict TypeScript
|
|
598
|
-
4. **Testing**: Write tests for critical functionality
|
|
599
|
-
5. **Versioning**: Keep package versions synchronized
|
|
600
|
-
6. **Documentation**: Add README files to packages
|
|
601
|
-
7. **Git**: Use conventional commits
|
|
602
|
-
8. **Dependencies**: Share dependencies across packages when possible
|
|
603
|
-
`,
|
|
604
|
-
"idealyst://framework/spacing-system": `# Spacing System
|
|
605
|
-
|
|
606
|
-
Idealyst components use a variant-based spacing system for consistent layouts. Instead of specifying numeric values, you use Size variants (xs, sm, md, lg, xl) that map to theme-defined values.
|
|
607
|
-
|
|
608
|
-
## Spacing Prop Interfaces
|
|
609
|
-
|
|
610
|
-
Different component types receive different spacing props based on their use case:
|
|
611
|
-
|
|
612
|
-
### ContainerStyleProps (Layout Containers)
|
|
613
|
-
**Components**: View, Card, Screen, List, Accordion, Table, TabBar
|
|
614
|
-
|
|
615
|
-
\`\`\`typescript
|
|
616
|
-
interface ContainerStyleProps {
|
|
617
|
-
gap?: Size; // Space between children
|
|
618
|
-
padding?: Size; // Padding on all sides
|
|
619
|
-
paddingVertical?: Size; // Top and bottom padding
|
|
620
|
-
paddingHorizontal?: Size; // Left and right padding
|
|
621
|
-
margin?: Size; // Margin on all sides
|
|
622
|
-
marginVertical?: Size; // Top and bottom margin
|
|
623
|
-
marginHorizontal?: Size; // Left and right margin
|
|
624
|
-
}
|
|
625
|
-
\`\`\`
|
|
626
|
-
|
|
627
|
-
### TextSpacingStyleProps (Text Components)
|
|
628
|
-
**Components**: Text
|
|
629
|
-
|
|
630
|
-
\`\`\`typescript
|
|
631
|
-
interface TextSpacingStyleProps {
|
|
632
|
-
gap?: Size; // Space between nested elements
|
|
633
|
-
padding?: Size; // Padding on all sides
|
|
634
|
-
paddingVertical?: Size; // Top and bottom padding
|
|
635
|
-
paddingHorizontal?: Size; // Left and right padding
|
|
636
|
-
}
|
|
637
|
-
\`\`\`
|
|
638
|
-
|
|
639
|
-
### PressableSpacingStyleProps (Interactive Elements)
|
|
640
|
-
**Components**: Pressable
|
|
641
|
-
|
|
642
|
-
\`\`\`typescript
|
|
643
|
-
interface PressableSpacingStyleProps {
|
|
644
|
-
padding?: Size; // Padding on all sides
|
|
645
|
-
paddingVertical?: Size; // Top and bottom padding
|
|
646
|
-
paddingHorizontal?: Size; // Left and right padding
|
|
647
|
-
}
|
|
648
|
-
\`\`\`
|
|
649
|
-
|
|
650
|
-
### FormInputStyleProps (Form Inputs)
|
|
651
|
-
**Components**: Input, Select, TextArea, Checkbox, RadioButton, Switch, Slider
|
|
652
|
-
|
|
653
|
-
\`\`\`typescript
|
|
654
|
-
interface FormInputStyleProps {
|
|
655
|
-
margin?: Size; // Margin on all sides
|
|
656
|
-
marginVertical?: Size; // Top and bottom margin
|
|
657
|
-
marginHorizontal?: Size; // Left and right margin
|
|
658
|
-
}
|
|
659
|
-
\`\`\`
|
|
660
|
-
|
|
661
|
-
## Size Values
|
|
662
|
-
|
|
663
|
-
Size variants map to theme values:
|
|
664
|
-
|
|
665
|
-
| Size | Padding | Spacing (Gap) |
|
|
666
|
-
|------|---------|---------------|
|
|
667
|
-
| xs | 4px | 4px |
|
|
668
|
-
| sm | 8px | 8px |
|
|
669
|
-
| md | 16px | 16px |
|
|
670
|
-
| lg | 24px | 24px |
|
|
671
|
-
| xl | 32px | 32px |
|
|
672
|
-
|
|
673
|
-
## Usage Examples
|
|
674
|
-
|
|
675
|
-
### Container Spacing
|
|
676
|
-
|
|
677
|
-
\`\`\`tsx
|
|
678
|
-
import { View, Card, Text } from '@idealyst/components';
|
|
679
|
-
|
|
680
|
-
// Gap between children
|
|
681
|
-
<View gap="md">
|
|
682
|
-
<Text>Item 1</Text>
|
|
683
|
-
<Text>Item 2</Text>
|
|
684
|
-
</View>
|
|
685
|
-
|
|
686
|
-
// Padding inside container
|
|
687
|
-
<Card padding="lg" gap="sm">
|
|
688
|
-
<Text weight="bold">Card Title</Text>
|
|
689
|
-
<Text>Card content</Text>
|
|
690
|
-
</Card>
|
|
691
|
-
|
|
692
|
-
// Directional padding
|
|
693
|
-
<View paddingVertical="md" paddingHorizontal="lg">
|
|
694
|
-
<Text>Content with different vertical/horizontal padding</Text>
|
|
695
|
-
</View>
|
|
696
|
-
|
|
697
|
-
// Margin for spacing between containers
|
|
698
|
-
<Card margin="md" padding="lg">
|
|
699
|
-
<Text>Card with margin</Text>
|
|
700
|
-
</Card>
|
|
701
|
-
\`\`\`
|
|
702
|
-
|
|
703
|
-
### Form Input Spacing
|
|
704
|
-
|
|
705
|
-
\`\`\`tsx
|
|
706
|
-
import { Input, Checkbox, View } from '@idealyst/components';
|
|
707
|
-
|
|
708
|
-
// Use margin to space form fields
|
|
709
|
-
<View>
|
|
710
|
-
<Input placeholder="Email" marginVertical="sm" />
|
|
711
|
-
<Input placeholder="Password" marginVertical="sm" />
|
|
712
|
-
<Checkbox label="Remember me" marginVertical="md" />
|
|
713
|
-
</View>
|
|
714
|
-
\`\`\`
|
|
715
|
-
|
|
716
|
-
### Combining with Style Prop
|
|
717
|
-
|
|
718
|
-
The spacing props work alongside the style prop:
|
|
719
|
-
|
|
720
|
-
\`\`\`tsx
|
|
721
|
-
<View
|
|
722
|
-
gap="md"
|
|
723
|
-
padding="lg"
|
|
724
|
-
style={{ backgroundColor: '#f5f5f5', borderRadius: 8 }}
|
|
725
|
-
>
|
|
726
|
-
<Text>Content</Text>
|
|
727
|
-
</View>
|
|
728
|
-
\`\`\`
|
|
729
|
-
|
|
730
|
-
## Custom Components
|
|
731
|
-
|
|
732
|
-
You can use the exported builder functions to add spacing variants to custom components:
|
|
733
|
-
|
|
734
|
-
\`\`\`typescript
|
|
735
|
-
import { StyleSheet } from 'react-native-unistyles';
|
|
736
|
-
import { Theme } from '@idealyst/theme';
|
|
737
|
-
import {
|
|
738
|
-
buildGapVariants,
|
|
739
|
-
buildPaddingVariants,
|
|
740
|
-
buildMarginVariants,
|
|
741
|
-
} from '@idealyst/components';
|
|
742
|
-
|
|
743
|
-
export const customStyles = StyleSheet.create((theme: Theme) => ({
|
|
744
|
-
container: {
|
|
745
|
-
variants: {
|
|
746
|
-
gap: buildGapVariants(theme),
|
|
747
|
-
padding: buildPaddingVariants(theme),
|
|
748
|
-
margin: buildMarginVariants(theme),
|
|
749
|
-
},
|
|
750
|
-
},
|
|
751
|
-
}));
|
|
752
|
-
\`\`\`
|
|
753
|
-
|
|
754
|
-
## Best Practices
|
|
755
|
-
|
|
756
|
-
1. **Use variants for consistency**: Prefer Size variants over numeric values for consistent spacing across your app
|
|
757
|
-
2. **Gap over margins for children**: Use \`gap\` to space children instead of margins on individual items
|
|
758
|
-
3. **Directional props for precision**: Use paddingVertical/paddingHorizontal when you need different spacing
|
|
759
|
-
4. **Form spacing with margin**: Use marginVertical on form inputs to create consistent form layouts
|
|
760
|
-
5. **Combine with theme values**: The variant values come from the theme, ensuring consistency
|
|
761
|
-
`,
|
|
762
|
-
"idealyst://framework/api-overview": `# API Architecture Overview
|
|
763
|
-
|
|
764
|
-
Idealyst provides a dual API architecture with both tRPC and GraphQL, giving you flexibility for different use cases.
|
|
765
|
-
|
|
766
|
-
## When to Use Each
|
|
767
|
-
|
|
768
|
-
### tRPC (Type-Safe RPC)
|
|
769
|
-
- **Best for**: Internal clients, same-team consumption
|
|
770
|
-
- **Benefits**: End-to-end type safety, no code generation, fast development
|
|
771
|
-
- **Use when**: Your frontend and backend are TypeScript
|
|
772
|
-
|
|
773
|
-
### GraphQL
|
|
774
|
-
- **Best for**: Public APIs, third-party integrations, mobile apps
|
|
775
|
-
- **Benefits**: Flexible queries, schema documentation, wide ecosystem
|
|
776
|
-
- **Use when**: You need schema introspection or have non-TypeScript clients
|
|
777
|
-
|
|
778
|
-
## Architecture
|
|
779
|
-
|
|
780
|
-
Both APIs run on the same Express server:
|
|
781
|
-
|
|
782
|
-
\`\`\`
|
|
783
|
-
Server (port 3000)
|
|
784
|
-
├── /trpc/* → tRPC handlers
|
|
785
|
-
├── /graphql → GraphQL Yoga endpoint
|
|
786
|
-
└── Shared context (database, auth)
|
|
787
|
-
\`\`\`
|
|
788
|
-
|
|
789
|
-
## File Structure
|
|
790
|
-
|
|
791
|
-
\`\`\`
|
|
792
|
-
packages/api/src/
|
|
793
|
-
├── routers/ # tRPC routers
|
|
794
|
-
│ ├── index.ts # Root router
|
|
795
|
-
│ └── test.ts # Example router
|
|
796
|
-
├── graphql/ # GraphQL setup
|
|
797
|
-
│ ├── builder.ts # Pothos schema builder
|
|
798
|
-
│ ├── index.ts # Yoga server setup
|
|
799
|
-
│ └── types/ # GraphQL type definitions
|
|
800
|
-
│ └── test.ts # Example types
|
|
801
|
-
├── context.ts # Shared context
|
|
802
|
-
├── server.ts # Express server
|
|
803
|
-
└── index.ts # Entry point
|
|
804
|
-
\`\`\`
|
|
805
|
-
|
|
806
|
-
## Shared Context
|
|
807
|
-
|
|
808
|
-
Both APIs share the same context:
|
|
809
|
-
|
|
810
|
-
\`\`\`typescript
|
|
811
|
-
// context.ts
|
|
812
|
-
export interface Context {
|
|
813
|
-
db: PrismaClient;
|
|
814
|
-
// Add auth, session, etc.
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
export async function createContext(): Promise<Context> {
|
|
818
|
-
return {
|
|
819
|
-
db: prisma,
|
|
820
|
-
};
|
|
821
|
-
}
|
|
822
|
-
\`\`\`
|
|
823
|
-
|
|
824
|
-
## Client Setup
|
|
825
|
-
|
|
826
|
-
The shared package provides clients for both:
|
|
827
|
-
|
|
828
|
-
\`\`\`typescript
|
|
829
|
-
// In your App component
|
|
830
|
-
import { createTRPCClient, createGraphQLClient } from '@your-app/shared';
|
|
831
|
-
|
|
832
|
-
// tRPC - automatic type inference
|
|
833
|
-
const trpcClient = createTRPCClient({ apiUrl: 'http://localhost:3000/trpc' });
|
|
834
|
-
|
|
835
|
-
// GraphQL - manual queries with graphql-request
|
|
836
|
-
createGraphQLClient({ apiUrl: 'http://localhost:3000/graphql' });
|
|
837
|
-
\`\`\`
|
|
838
|
-
|
|
839
|
-
## Migration Path
|
|
840
|
-
|
|
841
|
-
Start with tRPC for rapid development, add GraphQL when you need:
|
|
842
|
-
- Public API documentation
|
|
843
|
-
- Third-party integrations
|
|
844
|
-
- Schema-first development
|
|
845
|
-
- Non-TypeScript clients
|
|
846
|
-
`,
|
|
847
|
-
"idealyst://framework/graphql-setup": `# GraphQL Setup Guide
|
|
848
|
-
|
|
849
|
-
Idealyst uses Pothos (code-first schema) with GraphQL Yoga server, integrated with Prisma.
|
|
850
|
-
|
|
851
|
-
## Server Setup
|
|
852
|
-
|
|
853
|
-
### 1. Schema Builder (builder.ts)
|
|
854
|
-
|
|
855
|
-
\`\`\`typescript
|
|
856
|
-
import SchemaBuilder from '@pothos/core';
|
|
857
|
-
import PrismaPlugin from '@pothos/plugin-prisma';
|
|
858
|
-
import type PrismaTypes from './generated';
|
|
859
|
-
import { prisma } from '@your-app/database';
|
|
860
|
-
|
|
861
|
-
export const builder = new SchemaBuilder<{
|
|
862
|
-
PrismaTypes: PrismaTypes;
|
|
863
|
-
Context: { db: typeof prisma };
|
|
864
|
-
}>({
|
|
865
|
-
plugins: [PrismaPlugin],
|
|
866
|
-
prisma: {
|
|
867
|
-
client: prisma,
|
|
868
|
-
},
|
|
869
|
-
});
|
|
870
|
-
|
|
871
|
-
// Initialize Query and Mutation types
|
|
872
|
-
builder.queryType({});
|
|
873
|
-
builder.mutationType({});
|
|
874
|
-
\`\`\`
|
|
875
|
-
|
|
876
|
-
### 2. Generate Prisma Types
|
|
877
|
-
|
|
878
|
-
\`\`\`bash
|
|
879
|
-
# In packages/api
|
|
880
|
-
npx prisma generate --generator pothos
|
|
881
|
-
\`\`\`
|
|
882
|
-
|
|
883
|
-
Add to your prisma schema:
|
|
884
|
-
|
|
885
|
-
\`\`\`prisma
|
|
886
|
-
generator pothos {
|
|
887
|
-
provider = "prisma-pothos-types"
|
|
888
|
-
output = "../src/graphql/generated.ts"
|
|
889
|
-
}
|
|
890
|
-
\`\`\`
|
|
891
|
-
|
|
892
|
-
### 3. Define Types (types/example.ts)
|
|
893
|
-
|
|
894
|
-
\`\`\`typescript
|
|
895
|
-
import { builder } from '../builder';
|
|
896
|
-
|
|
897
|
-
// Object type from Prisma model
|
|
898
|
-
builder.prismaObject('Test', {
|
|
899
|
-
fields: (t) => ({
|
|
900
|
-
id: t.exposeID('id'),
|
|
901
|
-
name: t.exposeString('name'),
|
|
902
|
-
message: t.exposeString('message'),
|
|
903
|
-
status: t.exposeString('status'),
|
|
904
|
-
createdAt: t.expose('createdAt', { type: 'DateTime' }),
|
|
905
|
-
}),
|
|
906
|
-
});
|
|
907
|
-
|
|
908
|
-
// Input type for mutations
|
|
909
|
-
const CreateTestInput = builder.inputType('CreateTestInput', {
|
|
910
|
-
fields: (t) => ({
|
|
911
|
-
name: t.string({ required: true }),
|
|
912
|
-
message: t.string({ required: true }),
|
|
913
|
-
status: t.string({ required: true }),
|
|
914
|
-
}),
|
|
915
|
-
});
|
|
916
|
-
|
|
917
|
-
// Query
|
|
918
|
-
builder.queryField('tests', (t) =>
|
|
919
|
-
t.prismaField({
|
|
920
|
-
type: ['Test'],
|
|
921
|
-
args: {
|
|
922
|
-
take: t.arg.int(),
|
|
923
|
-
skip: t.arg.int(),
|
|
924
|
-
},
|
|
925
|
-
resolve: async (query, _root, args, ctx) =>
|
|
926
|
-
ctx.db.test.findMany({
|
|
927
|
-
...query,
|
|
928
|
-
take: args.take ?? 10,
|
|
929
|
-
skip: args.skip ?? 0,
|
|
930
|
-
orderBy: { createdAt: 'desc' },
|
|
931
|
-
}),
|
|
932
|
-
})
|
|
933
|
-
);
|
|
934
|
-
|
|
935
|
-
// Mutation
|
|
936
|
-
builder.mutationField('createTest', (t) =>
|
|
937
|
-
t.prismaField({
|
|
938
|
-
type: 'Test',
|
|
939
|
-
args: {
|
|
940
|
-
input: t.arg({ type: CreateTestInput, required: true }),
|
|
941
|
-
},
|
|
942
|
-
resolve: async (query, _root, args, ctx) =>
|
|
943
|
-
ctx.db.test.create({
|
|
944
|
-
...query,
|
|
945
|
-
data: args.input,
|
|
946
|
-
}),
|
|
947
|
-
})
|
|
948
|
-
);
|
|
949
|
-
\`\`\`
|
|
950
|
-
|
|
951
|
-
### 4. Yoga Server (index.ts)
|
|
952
|
-
|
|
953
|
-
\`\`\`typescript
|
|
954
|
-
import { createYoga } from 'graphql-yoga';
|
|
955
|
-
import { builder } from './builder';
|
|
956
|
-
import './types/test'; // Import all type definitions
|
|
957
|
-
|
|
958
|
-
export const yoga = createYoga({
|
|
959
|
-
schema: builder.toSchema(),
|
|
960
|
-
graphqlEndpoint: '/graphql',
|
|
961
|
-
});
|
|
962
|
-
\`\`\`
|
|
963
|
-
|
|
964
|
-
### 5. Mount in Express (server.ts)
|
|
965
|
-
|
|
966
|
-
\`\`\`typescript
|
|
967
|
-
import express from 'express';
|
|
968
|
-
import { yoga } from './graphql';
|
|
969
|
-
|
|
970
|
-
const app = express();
|
|
971
|
-
|
|
972
|
-
// GraphQL endpoint
|
|
973
|
-
app.use('/graphql', yoga);
|
|
974
|
-
|
|
975
|
-
// tRPC endpoint
|
|
976
|
-
app.use('/trpc', trpcMiddleware);
|
|
977
|
-
\`\`\`
|
|
978
|
-
|
|
979
|
-
## Client Setup
|
|
980
|
-
|
|
981
|
-
### 1. GraphQL Client (shared/src/graphql/client.ts)
|
|
982
|
-
|
|
983
|
-
\`\`\`typescript
|
|
984
|
-
import { GraphQLClient } from 'graphql-request';
|
|
985
|
-
|
|
986
|
-
let client: GraphQLClient | null = null;
|
|
987
|
-
|
|
988
|
-
export function createGraphQLClient(config: { apiUrl: string }) {
|
|
989
|
-
client = new GraphQLClient(config.apiUrl);
|
|
990
|
-
return client;
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
export function getGraphQLClient(): GraphQLClient {
|
|
994
|
-
if (!client) throw new Error('GraphQL client not initialized');
|
|
995
|
-
return client;
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
export { gql } from 'graphql-request';
|
|
999
|
-
\`\`\`
|
|
1000
|
-
|
|
1001
|
-
### 2. Using with React Query
|
|
1002
|
-
|
|
1003
|
-
\`\`\`typescript
|
|
1004
|
-
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
1005
|
-
import { getGraphQLClient, gql } from '../graphql/client';
|
|
1006
|
-
|
|
1007
|
-
const TESTS_QUERY = gql\`
|
|
1008
|
-
query GetTests($take: Int) {
|
|
1009
|
-
tests(take: $take) {
|
|
1010
|
-
id
|
|
1011
|
-
name
|
|
1012
|
-
message
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
\`;
|
|
1016
|
-
|
|
1017
|
-
const CREATE_TEST = gql\`
|
|
1018
|
-
mutation CreateTest($input: CreateTestInput!) {
|
|
1019
|
-
createTest(input: $input) {
|
|
1020
|
-
id
|
|
1021
|
-
name
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1024
|
-
\`;
|
|
1025
|
-
|
|
1026
|
-
// Query hook
|
|
1027
|
-
const { data, isLoading } = useQuery({
|
|
1028
|
-
queryKey: ['graphql', 'tests'],
|
|
1029
|
-
queryFn: () => getGraphQLClient().request(TESTS_QUERY, { take: 10 }),
|
|
1030
|
-
});
|
|
1031
|
-
|
|
1032
|
-
// Mutation hook
|
|
1033
|
-
const queryClient = useQueryClient();
|
|
1034
|
-
const mutation = useMutation({
|
|
1035
|
-
mutationFn: (input) => getGraphQLClient().request(CREATE_TEST, { input }),
|
|
1036
|
-
onSuccess: () => {
|
|
1037
|
-
queryClient.invalidateQueries({ queryKey: ['graphql', 'tests'] });
|
|
1038
|
-
},
|
|
1039
|
-
});
|
|
1040
|
-
\`\`\`
|
|
1041
|
-
|
|
1042
|
-
## GraphQL Playground
|
|
1043
|
-
|
|
1044
|
-
Access the GraphQL playground at:
|
|
1045
|
-
\`\`\`
|
|
1046
|
-
http://localhost:3000/graphql
|
|
1047
|
-
\`\`\`
|
|
1048
|
-
|
|
1049
|
-
Features:
|
|
1050
|
-
- Schema explorer
|
|
1051
|
-
- Query autocompletion
|
|
1052
|
-
- Documentation browser
|
|
1053
|
-
- Query history
|
|
1054
|
-
|
|
1055
|
-
## Best Practices
|
|
1056
|
-
|
|
1057
|
-
1. **Use Input Types**: Always use input types for mutations
|
|
1058
|
-
2. **Pagination**: Implement cursor-based pagination for lists
|
|
1059
|
-
3. **Error Handling**: Use Pothos error types
|
|
1060
|
-
4. **Authorization**: Add auth checks in resolvers
|
|
1061
|
-
5. **N+1 Prevention**: Use Prisma's query optimization
|
|
1062
|
-
`,
|
|
1063
|
-
"idealyst://framework/style-system": `# Style Definition System
|
|
1064
|
-
|
|
1065
|
-
Idealyst provides a powerful style definition system with build-time transformations via Babel plugin.
|
|
1066
|
-
|
|
1067
|
-
## Overview
|
|
1068
|
-
|
|
1069
|
-
The style system provides:
|
|
1070
|
-
- **defineStyle()**: Define base styles for components
|
|
1071
|
-
- **extendStyle()**: Merge additional styles with base styles
|
|
1072
|
-
- **overrideStyle()**: Completely replace component styles
|
|
1073
|
-
- **$iterator pattern**: Expand styles for all theme keys
|
|
1074
|
-
|
|
1075
|
-
## defineStyle()
|
|
1076
|
-
|
|
1077
|
-
Define base styles for a component:
|
|
1078
|
-
|
|
1079
|
-
\`\`\`typescript
|
|
1080
|
-
import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
|
|
1081
|
-
import type { Theme as BaseTheme } from '@idealyst/theme';
|
|
1082
|
-
|
|
1083
|
-
// Wrap theme for $iterator support
|
|
1084
|
-
type Theme = ThemeStyleWrapper<BaseTheme>;
|
|
1085
|
-
|
|
1086
|
-
export const buttonStyles = defineStyle('Button', (theme: Theme) => ({
|
|
1087
|
-
button: {
|
|
1088
|
-
borderRadius: theme.radii.md,
|
|
1089
|
-
backgroundColor: theme.intents.primary.primary,
|
|
1090
|
-
|
|
1091
|
-
variants: {
|
|
1092
|
-
size: {
|
|
1093
|
-
// $iterator expands to all size keys (xs, sm, md, lg, xl)
|
|
1094
|
-
paddingVertical: theme.sizes.$button.paddingVertical,
|
|
1095
|
-
paddingHorizontal: theme.sizes.$button.paddingHorizontal,
|
|
1096
|
-
},
|
|
1097
|
-
disabled: {
|
|
1098
|
-
true: { opacity: 0.5 },
|
|
1099
|
-
false: { opacity: 1 },
|
|
1100
|
-
},
|
|
1101
|
-
},
|
|
1102
|
-
},
|
|
1103
|
-
text: {
|
|
1104
|
-
color: theme.intents.primary.contrast,
|
|
1105
|
-
variants: {
|
|
1106
|
-
size: {
|
|
1107
|
-
fontSize: theme.sizes.$button.fontSize,
|
|
1108
|
-
},
|
|
1109
|
-
},
|
|
1110
|
-
},
|
|
1111
|
-
}));
|
|
1112
|
-
\`\`\`
|
|
1113
|
-
|
|
1114
|
-
## Dynamic Style Functions
|
|
1115
|
-
|
|
1116
|
-
For styles depending on runtime props:
|
|
1117
|
-
|
|
1118
|
-
\`\`\`typescript
|
|
1119
|
-
export const buttonStyles = defineStyle('Button', (theme: Theme) => ({
|
|
1120
|
-
button: ({ intent = 'primary', type = 'contained' }: ButtonDynamicProps) => ({
|
|
1121
|
-
backgroundColor: type === 'contained'
|
|
1122
|
-
? theme.intents[intent].primary
|
|
1123
|
-
: 'transparent',
|
|
1124
|
-
borderColor: type === 'outlined'
|
|
1125
|
-
? theme.intents[intent].primary
|
|
1126
|
-
: 'transparent',
|
|
1127
|
-
}),
|
|
1128
|
-
}));
|
|
1129
|
-
\`\`\`
|
|
1130
|
-
|
|
1131
|
-
## Using Styles in Components
|
|
1132
|
-
|
|
1133
|
-
\`\`\`typescript
|
|
1134
|
-
import { buttonStyles } from './Button.styles';
|
|
1135
|
-
|
|
1136
|
-
const Button = ({ size = 'md', disabled = false, intent, type }) => {
|
|
1137
|
-
// Apply variants
|
|
1138
|
-
buttonStyles.useVariants({ size, disabled });
|
|
1139
|
-
|
|
1140
|
-
// Static styles - no function call
|
|
1141
|
-
const staticStyle = buttonStyles.button;
|
|
1142
|
-
|
|
1143
|
-
// Dynamic styles - function call with props
|
|
1144
|
-
const dynamicStyle = (buttonStyles.button as any)({ intent, type });
|
|
1145
|
-
|
|
1146
|
-
return (
|
|
1147
|
-
<TouchableOpacity style={dynamicStyle}>
|
|
1148
|
-
<Text style={buttonStyles.text}>Click me</Text>
|
|
1149
|
-
</TouchableOpacity>
|
|
1150
|
-
);
|
|
1151
|
-
};
|
|
1152
|
-
\`\`\`
|
|
1153
|
-
|
|
1154
|
-
## extendStyle()
|
|
1155
|
-
|
|
1156
|
-
Merge additional styles with base component styles:
|
|
1157
|
-
|
|
1158
|
-
\`\`\`typescript
|
|
1159
|
-
// style-extensions.ts
|
|
1160
|
-
import { extendStyle } from '@idealyst/theme';
|
|
1161
|
-
|
|
1162
|
-
extendStyle('Button', (theme) => ({
|
|
1163
|
-
button: {
|
|
1164
|
-
borderRadius: 9999, // Make all buttons pill-shaped
|
|
1165
|
-
},
|
|
1166
|
-
text: {
|
|
1167
|
-
fontFamily: 'CustomFont',
|
|
1168
|
-
},
|
|
1169
|
-
}));
|
|
1170
|
-
\`\`\`
|
|
1171
|
-
|
|
1172
|
-
## overrideStyle()
|
|
1173
|
-
|
|
1174
|
-
Completely replace component styles:
|
|
1175
|
-
|
|
1176
|
-
\`\`\`typescript
|
|
1177
|
-
import { overrideStyle } from '@idealyst/theme';
|
|
1178
|
-
|
|
1179
|
-
overrideStyle('Button', (theme) => ({
|
|
1180
|
-
button: {
|
|
1181
|
-
backgroundColor: theme.colors.surface.primary,
|
|
1182
|
-
borderWidth: 2,
|
|
1183
|
-
borderColor: theme.intents.primary.primary,
|
|
1184
|
-
},
|
|
1185
|
-
text: {
|
|
1186
|
-
color: theme.intents.primary.primary,
|
|
1187
|
-
},
|
|
1188
|
-
}));
|
|
1189
|
-
\`\`\`
|
|
1190
|
-
|
|
1191
|
-
## Import Order Matters
|
|
1192
|
-
|
|
1193
|
-
Extensions must be imported **before** components:
|
|
1194
|
-
|
|
1195
|
-
\`\`\`typescript
|
|
1196
|
-
// App.tsx
|
|
1197
|
-
import './style-extensions'; // FIRST - registers extensions
|
|
1198
|
-
import { Button } from '@idealyst/components'; // SECOND - uses extensions
|
|
1199
|
-
\`\`\`
|
|
1200
|
-
|
|
1201
|
-
## When to Use Each
|
|
1202
|
-
|
|
1203
|
-
| API | Use When |
|
|
1204
|
-
|-----|----------|
|
|
1205
|
-
| \`defineStyle()\` | Creating component library styles |
|
|
1206
|
-
| \`extendStyle()\` | Adding/modifying specific properties |
|
|
1207
|
-
| \`overrideStyle()\` | Completely custom styling |
|
|
1208
|
-
|
|
1209
|
-
## See Also
|
|
1210
|
-
|
|
1211
|
-
- \`idealyst://framework/theming\` - Theme builder API
|
|
1212
|
-
- \`idealyst://framework/babel-plugin\` - Plugin configuration
|
|
1213
|
-
- \`idealyst://framework/iterator-pattern\` - $iterator expansion
|
|
1214
|
-
`,
|
|
1215
|
-
"idealyst://framework/babel-plugin": `# Idealyst Babel Plugin
|
|
1216
|
-
|
|
1217
|
-
The Idealyst Babel plugin transforms style definitions at build time.
|
|
1218
|
-
|
|
1219
|
-
## Installation
|
|
1220
|
-
|
|
1221
|
-
The plugin is included with \`@idealyst/theme\`.
|
|
1222
|
-
|
|
1223
|
-
## Configuration
|
|
1224
|
-
|
|
1225
|
-
\`\`\`javascript
|
|
1226
|
-
// babel.config.js
|
|
1227
|
-
module.exports = {
|
|
1228
|
-
presets: ['module:@react-native/babel-preset'],
|
|
1229
|
-
plugins: [
|
|
1230
|
-
['@idealyst/theme/plugin', {
|
|
1231
|
-
// REQUIRED: Path to your theme file
|
|
1232
|
-
themePath: './src/theme/styles.ts',
|
|
1233
|
-
|
|
1234
|
-
// Optional: Enable debug logging
|
|
1235
|
-
debug: false,
|
|
1236
|
-
verbose: false,
|
|
1237
|
-
|
|
1238
|
-
// Optional: Paths to auto-process
|
|
1239
|
-
autoProcessPaths: [
|
|
1240
|
-
'@idealyst/components',
|
|
1241
|
-
'@idealyst/datepicker',
|
|
1242
|
-
'src/',
|
|
1243
|
-
],
|
|
1244
|
-
}],
|
|
1245
|
-
],
|
|
1246
|
-
};
|
|
1247
|
-
\`\`\`
|
|
1248
|
-
|
|
1249
|
-
## What the Plugin Does
|
|
1250
|
-
|
|
1251
|
-
### 1. Transforms defineStyle() to StyleSheet.create()
|
|
1252
|
-
|
|
1253
|
-
**Input:**
|
|
1254
|
-
\`\`\`typescript
|
|
1255
|
-
defineStyle('Button', (theme) => ({
|
|
1256
|
-
button: { backgroundColor: theme.intents.primary.primary }
|
|
1257
|
-
}));
|
|
1258
|
-
\`\`\`
|
|
1259
|
-
|
|
1260
|
-
**Output:**
|
|
1261
|
-
\`\`\`typescript
|
|
1262
|
-
StyleSheet.create((theme) => ({
|
|
1263
|
-
button: { backgroundColor: theme.intents.primary.primary }
|
|
1264
|
-
}));
|
|
1265
|
-
\`\`\`
|
|
1266
|
-
|
|
1267
|
-
### 2. Expands $iterator Patterns
|
|
1268
|
-
|
|
1269
|
-
**Input:**
|
|
1270
|
-
\`\`\`typescript
|
|
1271
|
-
defineStyle('Button', (theme) => ({
|
|
1272
|
-
button: {
|
|
1273
|
-
variants: {
|
|
1274
|
-
size: {
|
|
1275
|
-
paddingVertical: theme.sizes.$button.paddingVertical,
|
|
1276
|
-
},
|
|
1277
|
-
},
|
|
1278
|
-
},
|
|
1279
|
-
}));
|
|
1280
|
-
\`\`\`
|
|
1281
|
-
|
|
1282
|
-
**Output:**
|
|
1283
|
-
\`\`\`typescript
|
|
1284
|
-
StyleSheet.create((theme) => ({
|
|
1285
|
-
button: {
|
|
1286
|
-
variants: {
|
|
1287
|
-
size: {
|
|
1288
|
-
xs: { paddingVertical: theme.sizes.button.xs.paddingVertical },
|
|
1289
|
-
sm: { paddingVertical: theme.sizes.button.sm.paddingVertical },
|
|
1290
|
-
md: { paddingVertical: theme.sizes.button.md.paddingVertical },
|
|
1291
|
-
lg: { paddingVertical: theme.sizes.button.lg.paddingVertical },
|
|
1292
|
-
xl: { paddingVertical: theme.sizes.button.xl.paddingVertical },
|
|
1293
|
-
},
|
|
1294
|
-
},
|
|
1295
|
-
},
|
|
1296
|
-
}));
|
|
1297
|
-
\`\`\`
|
|
1298
|
-
|
|
1299
|
-
### 3. Merges Extensions at Build Time
|
|
1300
|
-
|
|
1301
|
-
\`\`\`typescript
|
|
1302
|
-
// Extension (processed first)
|
|
1303
|
-
extendStyle('Button', (theme) => ({
|
|
1304
|
-
button: { borderRadius: 9999 },
|
|
1305
|
-
}));
|
|
1306
|
-
|
|
1307
|
-
// Base (merges with extension)
|
|
1308
|
-
defineStyle('Button', (theme) => ({
|
|
1309
|
-
button: { padding: 16 },
|
|
1310
|
-
}));
|
|
1311
|
-
|
|
1312
|
-
// Result: { padding: 16, borderRadius: 9999 }
|
|
1313
|
-
\`\`\`
|
|
1314
|
-
|
|
1315
|
-
### 4. Removes extendStyle/overrideStyle Calls
|
|
1316
|
-
|
|
1317
|
-
After capturing extension definitions, the plugin removes the calls from the output since all merging happens at build time.
|
|
1318
|
-
|
|
1319
|
-
## Theme Analysis
|
|
1320
|
-
|
|
1321
|
-
The plugin statically analyzes your theme file to extract:
|
|
1322
|
-
- Intent names (primary, success, error, etc.)
|
|
1323
|
-
- Size keys (xs, sm, md, lg, xl)
|
|
1324
|
-
- Radius names (none, sm, md, lg)
|
|
1325
|
-
- Shadow names (none, sm, md, lg, xl)
|
|
1326
|
-
|
|
1327
|
-
This enables $iterator expansion without runtime overhead.
|
|
1328
|
-
|
|
1329
|
-
## Troubleshooting
|
|
1330
|
-
|
|
1331
|
-
### Styles Not Applying
|
|
1332
|
-
|
|
1333
|
-
1. Verify \`themePath\` points to your theme file
|
|
1334
|
-
2. Clear bundler cache: \`yarn start --reset-cache\`
|
|
1335
|
-
3. Check \`void StyleSheet;\` marker exists in style files
|
|
1336
|
-
|
|
1337
|
-
### Theme Changes Not Detected
|
|
1338
|
-
|
|
1339
|
-
1. Restart Metro bundler (theme is analyzed once)
|
|
1340
|
-
2. Verify theme exports correctly
|
|
1341
|
-
|
|
1342
|
-
### Debug Mode
|
|
1343
|
-
|
|
1344
|
-
Enable verbose logging:
|
|
1345
|
-
|
|
1346
|
-
\`\`\`javascript
|
|
1347
|
-
['@idealyst/theme/plugin', {
|
|
1348
|
-
themePath: './src/theme/styles.ts',
|
|
1349
|
-
verbose: true,
|
|
1350
|
-
}],
|
|
1351
|
-
\`\`\`
|
|
1352
|
-
`,
|
|
1353
|
-
"idealyst://framework/breakpoints": `# Responsive Breakpoints
|
|
1354
|
-
|
|
1355
|
-
Idealyst provides a responsive breakpoint system built on Unistyles v3, enabling width-based responsive styling across web and native platforms.
|
|
1356
|
-
|
|
1357
|
-
## Default Breakpoints
|
|
1358
|
-
|
|
1359
|
-
The default themes include 5 breakpoints:
|
|
1360
|
-
|
|
1361
|
-
| Breakpoint | Min Width | Target Devices |
|
|
1362
|
-
|------------|-----------|----------------|
|
|
1363
|
-
| \`xs\` | 0px | Portrait phones |
|
|
1364
|
-
| \`sm\` | 576px | Landscape phones |
|
|
1365
|
-
| \`md\` | 768px | Tablets |
|
|
1366
|
-
| \`lg\` | 992px | Desktops |
|
|
1367
|
-
| \`xl\` | 1200px | Large desktops |
|
|
1368
|
-
|
|
1369
|
-
## Defining Breakpoints
|
|
1370
|
-
|
|
1371
|
-
### Using setBreakpoints()
|
|
1372
|
-
|
|
1373
|
-
Set all breakpoints at once:
|
|
1374
|
-
|
|
1375
|
-
\`\`\`typescript
|
|
1376
|
-
import { createTheme } from '@idealyst/theme';
|
|
1377
|
-
|
|
1378
|
-
const theme = createTheme()
|
|
1379
|
-
// ... other theme config
|
|
1380
|
-
.setBreakpoints({
|
|
1381
|
-
xs: 0, // Must have one breakpoint at 0
|
|
1382
|
-
sm: 576,
|
|
1383
|
-
md: 768,
|
|
1384
|
-
lg: 992,
|
|
1385
|
-
xl: 1200,
|
|
1386
|
-
})
|
|
1387
|
-
.build();
|
|
1388
|
-
\`\`\`
|
|
1389
|
-
|
|
1390
|
-
### Using addBreakpoint()
|
|
1391
|
-
|
|
1392
|
-
Add breakpoints individually:
|
|
1393
|
-
|
|
1394
|
-
\`\`\`typescript
|
|
1395
|
-
import { fromTheme, lightTheme } from '@idealyst/theme';
|
|
1396
|
-
|
|
1397
|
-
const theme = fromTheme(lightTheme)
|
|
1398
|
-
.addBreakpoint('xxl', 1400) // Add extra large breakpoint
|
|
1399
|
-
.addBreakpoint('xxxl', 1800) // Add even larger
|
|
1400
|
-
.build();
|
|
1401
|
-
\`\`\`
|
|
1402
|
-
|
|
1403
|
-
## Using Breakpoints in Styles
|
|
1404
|
-
|
|
1405
|
-
### In StyleSheet.create()
|
|
1406
|
-
|
|
1407
|
-
Use object notation for responsive values:
|
|
1408
|
-
|
|
1409
|
-
\`\`\`typescript
|
|
1410
|
-
import { StyleSheet } from 'react-native-unistyles';
|
|
1411
|
-
|
|
1412
|
-
const styles = StyleSheet.create((theme) => ({
|
|
1413
|
-
container: {
|
|
1414
|
-
// Responsive padding
|
|
1415
|
-
padding: {
|
|
1416
|
-
xs: 8,
|
|
1417
|
-
md: 16,
|
|
1418
|
-
xl: 24,
|
|
1419
|
-
},
|
|
1420
|
-
|
|
1421
|
-
// Responsive flex direction
|
|
1422
|
-
flexDirection: {
|
|
1423
|
-
xs: 'column',
|
|
1424
|
-
md: 'row',
|
|
1425
|
-
},
|
|
1426
|
-
|
|
1427
|
-
// Responsive gap
|
|
1428
|
-
gap: {
|
|
1429
|
-
xs: 8,
|
|
1430
|
-
sm: 12,
|
|
1431
|
-
lg: 16,
|
|
1432
|
-
},
|
|
1433
|
-
},
|
|
1434
|
-
|
|
1435
|
-
text: {
|
|
1436
|
-
fontSize: {
|
|
1437
|
-
xs: 14,
|
|
1438
|
-
md: 16,
|
|
1439
|
-
lg: 18,
|
|
1440
|
-
},
|
|
1441
|
-
},
|
|
1442
|
-
}));
|
|
1443
|
-
\`\`\`
|
|
1444
|
-
|
|
1445
|
-
### Cascading Behavior
|
|
1446
|
-
|
|
1447
|
-
Values cascade up - if a breakpoint isn't defined, it uses the nearest smaller one:
|
|
1448
|
-
|
|
1449
|
-
\`\`\`typescript
|
|
1450
|
-
padding: {
|
|
1451
|
-
xs: 8, // Used for xs, sm (no sm defined)
|
|
1452
|
-
md: 16, // Used for md, lg (no lg defined)
|
|
1453
|
-
xl: 24, // Used for xl
|
|
1454
|
-
}
|
|
1455
|
-
\`\`\`
|
|
1456
|
-
|
|
1457
|
-
## Runtime Utilities
|
|
1458
|
-
|
|
1459
|
-
### getCurrentBreakpoint()
|
|
1460
|
-
|
|
1461
|
-
Get the current active breakpoint:
|
|
1462
|
-
|
|
1463
|
-
\`\`\`typescript
|
|
1464
|
-
import { getCurrentBreakpoint } from '@idealyst/theme';
|
|
1465
|
-
|
|
1466
|
-
const current = getCurrentBreakpoint();
|
|
1467
|
-
console.log(current); // 'md'
|
|
1468
|
-
\`\`\`
|
|
1469
|
-
|
|
1470
|
-
### getBreakpoints()
|
|
1471
|
-
|
|
1472
|
-
Get all registered breakpoints:
|
|
1473
|
-
|
|
1474
|
-
\`\`\`typescript
|
|
1475
|
-
import { getBreakpoints } from '@idealyst/theme';
|
|
1476
|
-
|
|
1477
|
-
const breakpoints = getBreakpoints();
|
|
1478
|
-
// { xs: 0, sm: 576, md: 768, lg: 992, xl: 1200 }
|
|
1479
|
-
\`\`\`
|
|
1480
|
-
|
|
1481
|
-
### isBreakpointUp() / isBreakpointDown()
|
|
1482
|
-
|
|
1483
|
-
Check viewport against breakpoints:
|
|
1484
|
-
|
|
1485
|
-
\`\`\`typescript
|
|
1486
|
-
import { isBreakpointUp, isBreakpointDown } from '@idealyst/theme';
|
|
1487
|
-
|
|
1488
|
-
if (isBreakpointUp('md')) {
|
|
1489
|
-
// Tablet or larger
|
|
1490
|
-
}
|
|
1491
|
-
|
|
1492
|
-
if (isBreakpointDown('md')) {
|
|
1493
|
-
// Mobile only (below tablet)
|
|
1494
|
-
}
|
|
1495
|
-
\`\`\`
|
|
1496
|
-
|
|
1497
|
-
### resolveResponsive()
|
|
1498
|
-
|
|
1499
|
-
Resolve a responsive value for the current breakpoint:
|
|
1500
|
-
|
|
1501
|
-
\`\`\`typescript
|
|
1502
|
-
import { resolveResponsive } from '@idealyst/theme';
|
|
1503
|
-
|
|
1504
|
-
const padding = resolveResponsive({ xs: 8, md: 16, xl: 24 });
|
|
1505
|
-
// Returns 8 on mobile, 16 on tablet, 24 on desktop
|
|
1506
|
-
\`\`\`
|
|
1507
|
-
|
|
1508
|
-
## Responsive Type
|
|
1509
|
-
|
|
1510
|
-
The \`Responsive<T>\` type makes any value responsive:
|
|
1511
|
-
|
|
1512
|
-
\`\`\`typescript
|
|
1513
|
-
import { Responsive, Size } from '@idealyst/theme';
|
|
1514
|
-
|
|
1515
|
-
// Can be either a direct value or breakpoint map
|
|
1516
|
-
type Props = {
|
|
1517
|
-
size: Responsive<Size>;
|
|
1518
|
-
};
|
|
1519
|
-
|
|
1520
|
-
// Both are valid:
|
|
1521
|
-
<Component size="md" />
|
|
1522
|
-
<Component size={{ xs: 'sm', md: 'lg' }} />
|
|
1523
|
-
\`\`\`
|
|
1524
|
-
|
|
1525
|
-
### Type Guard
|
|
1526
|
-
|
|
1527
|
-
Check if a value is responsive:
|
|
1528
|
-
|
|
1529
|
-
\`\`\`typescript
|
|
1530
|
-
import { isResponsiveValue, Responsive, Size } from '@idealyst/theme';
|
|
1531
|
-
|
|
1532
|
-
function handleSize(size: Responsive<Size>) {
|
|
1533
|
-
if (isResponsiveValue(size)) {
|
|
1534
|
-
// size is Partial<Record<Breakpoint, Size>>
|
|
1535
|
-
console.log(size.xs, size.md);
|
|
1536
|
-
} else {
|
|
1537
|
-
// size is Size
|
|
1538
|
-
console.log(size);
|
|
1539
|
-
}
|
|
1540
|
-
}
|
|
1541
|
-
\`\`\`
|
|
1542
|
-
|
|
1543
|
-
## TypeScript Support
|
|
1544
|
-
|
|
1545
|
-
Custom breakpoints are fully typed:
|
|
1546
|
-
|
|
1547
|
-
\`\`\`typescript
|
|
1548
|
-
const theme = createTheme()
|
|
1549
|
-
.setBreakpoints({
|
|
1550
|
-
mobile: 0,
|
|
1551
|
-
tablet: 768,
|
|
1552
|
-
desktop: 1024,
|
|
1553
|
-
})
|
|
1554
|
-
.build();
|
|
1555
|
-
|
|
1556
|
-
// Register for type inference
|
|
1557
|
-
declare module '@idealyst/theme' {
|
|
1558
|
-
interface CustomThemeRegistry {
|
|
1559
|
-
theme: typeof theme;
|
|
1560
|
-
}
|
|
1561
|
-
}
|
|
1562
|
-
|
|
1563
|
-
// Now Breakpoint = 'mobile' | 'tablet' | 'desktop'
|
|
1564
|
-
import { Breakpoint } from '@idealyst/theme';
|
|
1565
|
-
\`\`\`
|
|
1566
|
-
|
|
1567
|
-
## Unistyles Integration
|
|
1568
|
-
|
|
1569
|
-
Breakpoints are automatically registered with Unistyles:
|
|
1570
|
-
|
|
1571
|
-
\`\`\`typescript
|
|
1572
|
-
import { UnistylesRegistry } from 'react-native-unistyles';
|
|
1573
|
-
import { lightTheme, darkTheme } from '@idealyst/theme';
|
|
1574
|
-
|
|
1575
|
-
UnistylesRegistry
|
|
1576
|
-
.addThemes({ light: lightTheme, dark: darkTheme })
|
|
1577
|
-
.addBreakpoints(lightTheme.breakpoints) // Register breakpoints
|
|
1578
|
-
.addConfig({ initialTheme: 'light' });
|
|
1579
|
-
\`\`\`
|
|
1580
|
-
|
|
1581
|
-
## Cross-Platform Behavior
|
|
1582
|
-
|
|
1583
|
-
- **Web**: Breakpoints convert to CSS media queries automatically
|
|
1584
|
-
- **Native**: Uses device screen width (works with tablets, phones, etc.)
|
|
1585
|
-
- **Same API**: Write once, works everywhere
|
|
1586
|
-
|
|
1587
|
-
## Best Practices
|
|
1588
|
-
|
|
1589
|
-
1. **Mobile-first**: Start with \`xs\` and add larger breakpoints as needed
|
|
1590
|
-
2. **Use cascading**: Don't define every breakpoint - let values cascade
|
|
1591
|
-
3. **Consistent breakpoints**: Use the same breakpoints across themes
|
|
1592
|
-
4. **Test on devices**: Verify layouts on actual device widths
|
|
1593
|
-
5. **Avoid over-responsiveness**: Not everything needs to change per breakpoint
|
|
1594
|
-
`,
|
|
1595
|
-
"idealyst://framework/iterator-pattern": `# The $iterator Pattern
|
|
1596
|
-
|
|
1597
|
-
The \`$iterator\` pattern allows defining styles once that expand to all keys of a theme object.
|
|
1598
|
-
|
|
1599
|
-
## ThemeStyleWrapper
|
|
1600
|
-
|
|
1601
|
-
Wrap your theme type to enable $iterator properties:
|
|
1602
|
-
|
|
1603
|
-
\`\`\`typescript
|
|
1604
|
-
import { ThemeStyleWrapper } from '@idealyst/theme';
|
|
1605
|
-
import type { Theme as BaseTheme } from '@idealyst/theme';
|
|
1606
|
-
|
|
1607
|
-
type Theme = ThemeStyleWrapper<BaseTheme>;
|
|
1608
|
-
\`\`\`
|
|
1609
|
-
|
|
1610
|
-
This adds \`$property\` versions of iterable theme properties:
|
|
1611
|
-
|
|
1612
|
-
| Original Path | $iterator Path |
|
|
1613
|
-
|--------------------------|---------------------------|
|
|
1614
|
-
| \`theme.intents.primary\` | \`theme.$intents.primary\` |
|
|
1615
|
-
| \`theme.sizes.button.md\` | \`theme.sizes.$button.md\` |
|
|
1616
|
-
|
|
1617
|
-
## Usage Examples
|
|
1618
|
-
|
|
1619
|
-
### Expand Intents
|
|
1620
|
-
|
|
1621
|
-
\`\`\`typescript
|
|
1622
|
-
// Single definition
|
|
1623
|
-
variants: {
|
|
1624
|
-
intent: {
|
|
1625
|
-
backgroundColor: theme.$intents.light,
|
|
1626
|
-
borderColor: theme.$intents.primary,
|
|
1627
|
-
},
|
|
1628
|
-
}
|
|
1629
|
-
|
|
1630
|
-
// Expands to all intent keys (primary, success, error, warning, etc.)
|
|
1631
|
-
// Result:
|
|
1632
|
-
// intent: {
|
|
1633
|
-
// primary: { backgroundColor: theme.intents.primary.light, borderColor: theme.intents.primary.primary },
|
|
1634
|
-
// success: { backgroundColor: theme.intents.success.light, borderColor: theme.intents.success.primary },
|
|
1635
|
-
// error: { ... },
|
|
1636
|
-
// ...
|
|
1637
|
-
// }
|
|
1638
|
-
\`\`\`
|
|
1639
|
-
|
|
1640
|
-
### Expand Sizes
|
|
1641
|
-
|
|
1642
|
-
\`\`\`typescript
|
|
1643
|
-
// Single definition
|
|
1644
|
-
variants: {
|
|
1645
|
-
size: {
|
|
1646
|
-
paddingVertical: theme.sizes.$button.paddingVertical,
|
|
1647
|
-
fontSize: theme.sizes.$button.fontSize,
|
|
1648
|
-
},
|
|
1649
|
-
}
|
|
1650
|
-
|
|
1651
|
-
// Expands to all size keys (xs, sm, md, lg, xl)
|
|
1652
|
-
// Result:
|
|
1653
|
-
// size: {
|
|
1654
|
-
// xs: { paddingVertical: theme.sizes.button.xs.paddingVertical, fontSize: theme.sizes.button.xs.fontSize },
|
|
1655
|
-
// sm: { paddingVertical: theme.sizes.button.sm.paddingVertical, fontSize: theme.sizes.button.sm.fontSize },
|
|
1656
|
-
// md: { ... },
|
|
1657
|
-
// ...
|
|
1658
|
-
// }
|
|
1659
|
-
\`\`\`
|
|
1660
|
-
|
|
1661
|
-
## Complete Example
|
|
1662
|
-
|
|
1663
|
-
\`\`\`typescript
|
|
1664
|
-
import { defineStyle, ThemeStyleWrapper } from '@idealyst/theme';
|
|
1665
|
-
import type { Theme as BaseTheme } from '@idealyst/theme';
|
|
1666
|
-
|
|
1667
|
-
type Theme = ThemeStyleWrapper<BaseTheme>;
|
|
1668
|
-
|
|
1669
|
-
export const chipStyles = defineStyle('Chip', (theme: Theme) => ({
|
|
1670
|
-
chip: {
|
|
1671
|
-
borderRadius: 999,
|
|
1672
|
-
|
|
1673
|
-
variants: {
|
|
1674
|
-
// Expand for all sizes
|
|
1675
|
-
size: {
|
|
1676
|
-
paddingVertical: theme.sizes.$chip.paddingVertical,
|
|
1677
|
-
paddingHorizontal: theme.sizes.$chip.paddingHorizontal,
|
|
1678
|
-
minHeight: theme.sizes.$chip.minHeight,
|
|
1679
|
-
},
|
|
1680
|
-
|
|
1681
|
-
// Expand for all intents
|
|
1682
|
-
intent: {
|
|
1683
|
-
backgroundColor: theme.$intents.light,
|
|
1684
|
-
borderColor: theme.$intents.primary,
|
|
1685
|
-
},
|
|
1686
|
-
},
|
|
1687
|
-
},
|
|
1688
|
-
|
|
1689
|
-
text: {
|
|
1690
|
-
variants: {
|
|
1691
|
-
size: {
|
|
1692
|
-
fontSize: theme.sizes.$chip.fontSize,
|
|
1693
|
-
lineHeight: theme.sizes.$chip.lineHeight,
|
|
1694
|
-
},
|
|
1695
|
-
|
|
1696
|
-
intent: {
|
|
1697
|
-
color: theme.$intents.dark,
|
|
1698
|
-
},
|
|
1699
|
-
},
|
|
1700
|
-
},
|
|
1701
|
-
}));
|
|
1702
|
-
\`\`\`
|
|
1703
|
-
|
|
1704
|
-
## createIteratorStyles()
|
|
1705
|
-
|
|
1706
|
-
Alternative to defineStyle for custom components:
|
|
1707
|
-
|
|
1708
|
-
\`\`\`typescript
|
|
1709
|
-
import { createIteratorStyles } from '@idealyst/theme';
|
|
1710
|
-
|
|
1711
|
-
export const styles = createIteratorStyles((theme) => ({
|
|
1712
|
-
box: {
|
|
1713
|
-
variants: {
|
|
1714
|
-
intent: {
|
|
1715
|
-
backgroundColor: theme.$intents.light,
|
|
1716
|
-
},
|
|
1717
|
-
},
|
|
1718
|
-
},
|
|
1719
|
-
}));
|
|
1720
|
-
\`\`\`
|
|
1721
|
-
|
|
1722
|
-
## Benefits
|
|
1723
|
-
|
|
1724
|
-
1. **DRY Code**: Define once, expand to many
|
|
1725
|
-
2. **Type Safety**: TypeScript validates iterator properties
|
|
1726
|
-
3. **Maintainable**: Adding new sizes/intents to theme auto-expands
|
|
1727
|
-
4. **Zero Runtime Cost**: Expansion happens at build time
|
|
1728
|
-
`,
|
|
1729
|
-
};
|
|
1730
|
-
//# sourceMappingURL=framework-guides.js.map
|