@idealyst/components 1.0.23 → 1.0.25
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/README.md +567 -567
- package/package.json +2 -6
- package/plugin/web.js +319 -185
- package/src/Avatar/Avatar.native.tsx +43 -43
- package/src/Avatar/Avatar.styles.tsx +66 -66
- package/src/Avatar/Avatar.web.tsx +50 -50
- package/src/Avatar/index.native.ts +1 -1
- package/src/Avatar/index.ts +1 -1
- package/src/Avatar/index.web.ts +1 -1
- package/src/Avatar/types.ts +42 -42
- package/src/Badge/Badge.native.tsx +42 -42
- package/src/Badge/Badge.styles.tsx +153 -153
- package/src/Badge/Badge.web.tsx +44 -44
- package/src/Badge/index.native.ts +1 -1
- package/src/Badge/index.ts +1 -1
- package/src/Badge/index.web.ts +1 -1
- package/src/Badge/types.ts +33 -33
- package/src/Button/Button.native.tsx +38 -38
- package/src/Button/Button.styles.tsx +214 -214
- package/src/Button/Button.types.ts +11 -11
- package/src/Button/Button.web.tsx +55 -55
- package/src/Button/index.native.ts +2 -2
- package/src/Button/index.ts +4 -4
- package/src/Button/index.web.ts +2 -2
- package/src/Button/types.ts +48 -48
- package/src/Card/Card.native.tsx +51 -51
- package/src/Card/Card.styles.tsx +239 -239
- package/src/Card/Card.web.tsx +61 -61
- package/src/Card/index.native.ts +2 -2
- package/src/Card/index.ts +4 -4
- package/src/Card/index.web.ts +2 -2
- package/src/Card/types.ts +58 -58
- package/src/Checkbox/Checkbox.native.tsx +98 -98
- package/src/Checkbox/Checkbox.styles.tsx +291 -291
- package/src/Checkbox/Checkbox.web.tsx +130 -130
- package/src/Checkbox/index.native.ts +2 -2
- package/src/Checkbox/index.ts +4 -4
- package/src/Checkbox/index.web.ts +2 -2
- package/src/Checkbox/types.ts +78 -78
- package/src/Divider/Divider.native.tsx +144 -144
- package/src/Divider/Divider.styles.tsx +601 -601
- package/src/Divider/Divider.web.tsx +72 -72
- package/src/Divider/index.native.ts +2 -2
- package/src/Divider/index.ts +4 -4
- package/src/Divider/index.web.ts +2 -2
- package/src/Divider/types.ts +53 -53
- package/src/Icon/Icon.native.tsx +38 -38
- package/src/Icon/Icon.styles.tsx +49 -49
- package/src/Icon/Icon.web.tsx +46 -46
- package/src/Icon/icon-types.ts +7452 -7452
- package/src/Icon/index.native.ts +2 -2
- package/src/Icon/index.ts +4 -4
- package/src/Icon/index.web.ts +2 -2
- package/src/Icon/types.ts +35 -35
- package/src/Input/Input.native.tsx +74 -74
- package/src/Input/Input.styles.tsx +176 -176
- package/src/Input/Input.web.tsx +70 -70
- package/src/Input/index.native.ts +2 -2
- package/src/Input/index.ts +4 -4
- package/src/Input/index.web.ts +2 -2
- package/src/Input/types.ts +68 -68
- package/src/Screen/Screen.native.tsx +40 -40
- package/src/Screen/Screen.styles.tsx +59 -59
- package/src/Screen/Screen.web.tsx +32 -32
- package/src/Screen/index.native.ts +1 -1
- package/src/Screen/index.ts +1 -1
- package/src/Screen/index.web.ts +1 -1
- package/src/Screen/types.ts +37 -37
- package/src/Text/Text.native.tsx +35 -35
- package/src/Text/Text.styles.tsx +66 -66
- package/src/Text/Text.web.tsx +40 -40
- package/src/Text/index.native.ts +2 -2
- package/src/Text/index.ts +4 -4
- package/src/Text/index.web.ts +2 -2
- package/src/Text/types.ts +38 -38
- package/src/View/View.native.tsx +55 -55
- package/src/View/View.styles.tsx +102 -102
- package/src/View/View.web.tsx +59 -59
- package/src/View/index.native.ts +2 -2
- package/src/View/index.ts +4 -4
- package/src/View/index.web.ts +2 -2
- package/src/View/types.ts +72 -72
- package/src/examples/AllExamples.tsx +71 -71
- package/src/examples/AvatarExamples.tsx +96 -96
- package/src/examples/BadgeExamples.tsx +199 -199
- package/src/examples/ButtonExamples.tsx +149 -149
- package/src/examples/CardExamples.tsx +175 -175
- package/src/examples/CheckboxExamples.tsx +216 -216
- package/src/examples/DividerExamples.tsx +217 -217
- package/src/examples/IconExamples.tsx +341 -341
- package/src/examples/InputExamples.tsx +133 -133
- package/src/examples/README.md +135 -135
- package/src/examples/ScreenExamples.tsx +153 -153
- package/src/examples/TextExamples.tsx +88 -88
- package/src/examples/ThemeExtensionExamples.tsx +90 -90
- package/src/examples/ValidationExamples.tsx +94 -94
- package/src/examples/ViewExamples.tsx +128 -128
- package/src/examples/extendedTheme.ts +328 -328
- package/src/examples/index.ts +14 -14
- package/src/index.native.ts +48 -48
- package/src/index.ts +47 -47
- package/src/theme/breakpoints.ts +8 -8
- package/src/theme/colorResolver.ts +217 -217
- package/src/theme/colors.ts +314 -314
- package/src/theme/defaultThemes.ts +325 -325
- package/src/theme/index.ts +187 -187
- package/src/theme/themeBuilder.ts +601 -601
- package/src/theme/unistyles.d.ts +5 -5
- package/src/theme/variantHelpers.ts +583 -583
- package/src/theme/variants.ts +55 -55
package/README.md
CHANGED
|
@@ -1,568 +1,568 @@
|
|
|
1
|
-
# @idealyst/components
|
|
2
|
-
|
|
3
|
-
A comprehensive, cross-platform component library for React and React Native applications. Built with TypeScript and powered by [react-native-unistyles](https://github.com/jpudysz/react-native-unistyles) for consistent styling across platforms.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- 🌐 **Cross-Platform**: Works seamlessly in React and React Native
|
|
8
|
-
- 🎨 **Design System**: Comprehensive theming with light/dark mode support
|
|
9
|
-
- 📱 **Responsive**: Adaptive components that work on all screen sizes
|
|
10
|
-
- ♿ **Accessible**: Built with accessibility best practices
|
|
11
|
-
- 🔧 **TypeScript**: Full TypeScript support with comprehensive type definitions
|
|
12
|
-
- 🎯 **Intent-Based**: Semantic color system for consistent UX
|
|
13
|
-
- 🚀 **Production Ready**: Optimized for performance and developer experience
|
|
14
|
-
|
|
15
|
-
## Installation
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
# Using Yarn (recommended)
|
|
19
|
-
yarn add @idealyst/components
|
|
20
|
-
|
|
21
|
-
# Using npm
|
|
22
|
-
npm install @idealyst/components
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
### Peer Dependencies
|
|
26
|
-
|
|
27
|
-
This library requires the following peer dependencies:
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
# Core dependencies
|
|
31
|
-
yarn add react react-native-unistyles
|
|
32
|
-
|
|
33
|
-
# For React Native projects
|
|
34
|
-
yarn add react-native @react-native/normalize-colors react-native-edge-to-edge react-native-nitro-modules
|
|
35
|
-
|
|
36
|
-
# For React/Web projects
|
|
37
|
-
yarn add react
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Quick Start
|
|
41
|
-
|
|
42
|
-
```tsx
|
|
43
|
-
import React from 'react';
|
|
44
|
-
import { Screen, View, Text, Button } from '@idealyst/components';
|
|
45
|
-
|
|
46
|
-
export default function App() {
|
|
47
|
-
return (
|
|
48
|
-
<Screen background="primary">
|
|
49
|
-
<View spacing="lg" style={{ flex: 1, justifyContent: 'center' }}>
|
|
50
|
-
<Text size="large" weight="bold" align="center">
|
|
51
|
-
Welcome to Idealyst Components
|
|
52
|
-
</Text>
|
|
53
|
-
<Button
|
|
54
|
-
variant="contained"
|
|
55
|
-
intent="primary"
|
|
56
|
-
onPress={() => console.log('Button pressed!')}
|
|
57
|
-
>
|
|
58
|
-
Get Started
|
|
59
|
-
</Button>
|
|
60
|
-
</View>
|
|
61
|
-
</Screen>
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## Available Components
|
|
67
|
-
|
|
68
|
-
### Layout Components
|
|
69
|
-
|
|
70
|
-
#### View
|
|
71
|
-
A flexible container component with built-in spacing and styling options.
|
|
72
|
-
|
|
73
|
-
```tsx
|
|
74
|
-
import { View } from '@idealyst/components';
|
|
75
|
-
|
|
76
|
-
<View spacing="md" style={{ padding: 16 }}>
|
|
77
|
-
{/* Content */}
|
|
78
|
-
</View>
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
**Props:**
|
|
82
|
-
- `spacing`: `"xs" | "sm" | "md" | "lg" | "xl" | "xxl"`
|
|
83
|
-
- Standard View props (style, children, etc.)
|
|
84
|
-
|
|
85
|
-
#### Screen
|
|
86
|
-
A full-screen container component that grows to fit the parent completely with theme-based backgrounds and padding.
|
|
87
|
-
|
|
88
|
-
```tsx
|
|
89
|
-
import { Screen } from '@idealyst/components';
|
|
90
|
-
|
|
91
|
-
<Screen background="primary" padding="lg" safeArea={true}>
|
|
92
|
-
{/* Your app content */}
|
|
93
|
-
</Screen>
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
**Props:**
|
|
97
|
-
- `background`: `"primary" | "secondary" | "tertiary" | "inverse"` - Background color variant
|
|
98
|
-
- `padding`: `"none" | "sm" | "md" | "lg" | "xl"` - Screen padding (default: "md")
|
|
99
|
-
- `safeArea`: `boolean` - Enable safe area padding for mobile devices (default: false)
|
|
100
|
-
- `style`: Additional styles
|
|
101
|
-
- `testID`: Test identifier
|
|
102
|
-
|
|
103
|
-
#### Divider
|
|
104
|
-
A separator component with customizable styling and spacing.
|
|
105
|
-
|
|
106
|
-
```tsx
|
|
107
|
-
import { Divider } from '@idealyst/components';
|
|
108
|
-
|
|
109
|
-
<Divider spacing="medium" intent="primary">
|
|
110
|
-
<Text>Section Title</Text>
|
|
111
|
-
</Divider>
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
**Props:**
|
|
115
|
-
- `spacing`: `"small" | "medium" | "large"`
|
|
116
|
-
- `intent`: `"primary" | "secondary" | "neutral"`
|
|
117
|
-
- `children`: Optional content to display in the divider
|
|
118
|
-
|
|
119
|
-
### Typography
|
|
120
|
-
|
|
121
|
-
#### Text
|
|
122
|
-
A versatile text component with comprehensive styling options.
|
|
123
|
-
|
|
124
|
-
```tsx
|
|
125
|
-
import { Text } from '@idealyst/components';
|
|
126
|
-
|
|
127
|
-
<Text
|
|
128
|
-
size="large"
|
|
129
|
-
weight="bold"
|
|
130
|
-
color="primary"
|
|
131
|
-
align="center"
|
|
132
|
-
>
|
|
133
|
-
Hello World
|
|
134
|
-
</Text>
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
**Props:**
|
|
138
|
-
- `size`: `"small" | "medium" | "large" | "xlarge"`
|
|
139
|
-
- `weight`: `"light" | "normal" | "medium" | "semibold" | "bold"`
|
|
140
|
-
- `color`: `"primary" | "secondary" | "success" | "warning" | "error"`
|
|
141
|
-
- `align`: `"left" | "center" | "right"`
|
|
142
|
-
|
|
143
|
-
### Form Components
|
|
144
|
-
|
|
145
|
-
#### Button
|
|
146
|
-
A customizable button component with multiple variants and intents.
|
|
147
|
-
|
|
148
|
-
```tsx
|
|
149
|
-
import { Button } from '@idealyst/components';
|
|
150
|
-
|
|
151
|
-
<Button
|
|
152
|
-
variant="contained"
|
|
153
|
-
intent="primary"
|
|
154
|
-
size="medium"
|
|
155
|
-
onPress={() => console.log('Pressed!')}
|
|
156
|
-
>
|
|
157
|
-
Click Me
|
|
158
|
-
</Button>
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
**Props:**
|
|
162
|
-
- `variant`: `"contained" | "outlined" | "text"`
|
|
163
|
-
- `intent`: `"primary" | "neutral" | "success" | "error" | "warning"`
|
|
164
|
-
- `size`: `"small" | "medium" | "large"`
|
|
165
|
-
- `disabled`: `boolean`
|
|
166
|
-
- `onPress`: `() => void`
|
|
167
|
-
|
|
168
|
-
#### Input
|
|
169
|
-
A text input component with consistent styling.
|
|
170
|
-
|
|
171
|
-
```tsx
|
|
172
|
-
import { Input } from '@idealyst/components';
|
|
173
|
-
|
|
174
|
-
<Input
|
|
175
|
-
placeholder="Enter your name"
|
|
176
|
-
value={value}
|
|
177
|
-
onChangeText={setValue}
|
|
178
|
-
/>
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
#### Checkbox
|
|
182
|
-
A checkbox component with customizable styling.
|
|
183
|
-
|
|
184
|
-
```tsx
|
|
185
|
-
import { Checkbox } from '@idealyst/components';
|
|
186
|
-
|
|
187
|
-
<Checkbox
|
|
188
|
-
checked={isChecked}
|
|
189
|
-
onPress={() => setIsChecked(!isChecked)}
|
|
190
|
-
label="Agree to terms"
|
|
191
|
-
/>
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
### Display Components
|
|
195
|
-
|
|
196
|
-
#### Card
|
|
197
|
-
A container component for displaying content in a card format.
|
|
198
|
-
|
|
199
|
-
```tsx
|
|
200
|
-
import { Card } from '@idealyst/components';
|
|
201
|
-
|
|
202
|
-
<Card>
|
|
203
|
-
<Text size="large" weight="bold">Card Title</Text>
|
|
204
|
-
<Text>Card content goes here</Text>
|
|
205
|
-
</Card>
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
#### Badge
|
|
209
|
-
A small component for displaying status or count information.
|
|
210
|
-
|
|
211
|
-
```tsx
|
|
212
|
-
import { Badge } from '@idealyst/components';
|
|
213
|
-
|
|
214
|
-
<Badge count={5} intent="error">
|
|
215
|
-
<Text>Notifications</Text>
|
|
216
|
-
</Badge>
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
#### Avatar
|
|
220
|
-
A component for displaying user avatars or profile pictures.
|
|
221
|
-
|
|
222
|
-
```tsx
|
|
223
|
-
import { Avatar } from '@idealyst/components';
|
|
224
|
-
|
|
225
|
-
<Avatar
|
|
226
|
-
source={{ uri: 'https://example.com/avatar.jpg' }}
|
|
227
|
-
size="medium"
|
|
228
|
-
fallback="JD"
|
|
229
|
-
/>
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
**Props:**
|
|
233
|
-
- `source`: Image source object
|
|
234
|
-
- `size`: `"small" | "medium" | "large"`
|
|
235
|
-
- `fallback`: Text to display when image fails to load
|
|
236
|
-
|
|
237
|
-
## Theme System
|
|
238
|
-
|
|
239
|
-
The library includes a comprehensive theme system with light and dark mode support.
|
|
240
|
-
|
|
241
|
-
### Default Themes
|
|
242
|
-
|
|
243
|
-
```tsx
|
|
244
|
-
import { appThemes } from '@idealyst/components';
|
|
245
|
-
|
|
246
|
-
// Access theme colors and properties
|
|
247
|
-
const { colors, spacing, typography } = appThemes.light;
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
### Intent System
|
|
251
|
-
|
|
252
|
-
Components use an intent-based color system for consistent UX:
|
|
253
|
-
|
|
254
|
-
- **Primary**: Main brand actions
|
|
255
|
-
- **Neutral**: Secondary actions
|
|
256
|
-
- **Success**: Positive actions (save, confirm)
|
|
257
|
-
- **Error**: Destructive actions (delete, cancel)
|
|
258
|
-
- **Warning**: Caution actions
|
|
259
|
-
|
|
260
|
-
### Color Palettes
|
|
261
|
-
|
|
262
|
-
The theme includes 8 comprehensive color palettes:
|
|
263
|
-
- Blue (Primary)
|
|
264
|
-
- Green (Success)
|
|
265
|
-
- Red (Error)
|
|
266
|
-
- Amber (Warning)
|
|
267
|
-
- Gray (Neutral)
|
|
268
|
-
- Cyan (Info)
|
|
269
|
-
- Purple (Accent)
|
|
270
|
-
- Pink (Accent)
|
|
271
|
-
|
|
272
|
-
Each palette includes 10 shades (50-900) optimized for both light and dark themes.
|
|
273
|
-
|
|
274
|
-
### Custom Styling
|
|
275
|
-
|
|
276
|
-
Use the theme in your custom components:
|
|
277
|
-
|
|
278
|
-
```tsx
|
|
279
|
-
import { StyleSheet } from 'react-native';
|
|
280
|
-
import { createStyleSheet } from 'react-native-unistyles';
|
|
281
|
-
|
|
282
|
-
const styles = createStyleSheet((theme) => ({
|
|
283
|
-
container: {
|
|
284
|
-
backgroundColor: theme.colors.surface.primary,
|
|
285
|
-
padding: theme.spacing.md,
|
|
286
|
-
borderRadius: theme.borderRadius.lg,
|
|
287
|
-
},
|
|
288
|
-
text: {
|
|
289
|
-
color: theme.colors.text.primary,
|
|
290
|
-
fontSize: theme.typography.fontSize.md,
|
|
291
|
-
},
|
|
292
|
-
}));
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
## Platform-Specific Usage
|
|
296
|
-
|
|
297
|
-
### React Native
|
|
298
|
-
|
|
299
|
-
```tsx
|
|
300
|
-
import React from 'react';
|
|
301
|
-
import { Screen, View, Text, Button } from '@idealyst/components';
|
|
302
|
-
|
|
303
|
-
export default function App() {
|
|
304
|
-
return (
|
|
305
|
-
<Screen background="primary">
|
|
306
|
-
<View spacing="lg" style={{ flex: 1 }}>
|
|
307
|
-
<Text size="large" weight="bold">
|
|
308
|
-
React Native App
|
|
309
|
-
</Text>
|
|
310
|
-
<Button variant="contained" intent="primary">
|
|
311
|
-
Native Button
|
|
312
|
-
</Button>
|
|
313
|
-
</View>
|
|
314
|
-
</Screen>
|
|
315
|
-
);
|
|
316
|
-
}
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
### React Web
|
|
320
|
-
|
|
321
|
-
```tsx
|
|
322
|
-
import React from 'react';
|
|
323
|
-
import { Screen, View, Text, Button } from '@idealyst/components';
|
|
324
|
-
|
|
325
|
-
export default function App() {
|
|
326
|
-
return (
|
|
327
|
-
<Screen background="primary">
|
|
328
|
-
<View spacing="lg">
|
|
329
|
-
<Text size="large" weight="bold">
|
|
330
|
-
Web App
|
|
331
|
-
</Text>
|
|
332
|
-
<Button variant="contained" intent="primary">
|
|
333
|
-
Web Button
|
|
334
|
-
</Button>
|
|
335
|
-
</View>
|
|
336
|
-
</Screen>
|
|
337
|
-
);
|
|
338
|
-
}
|
|
339
|
-
```
|
|
340
|
-
|
|
341
|
-
## Examples
|
|
342
|
-
|
|
343
|
-
Import pre-built examples to see components in action:
|
|
344
|
-
|
|
345
|
-
```tsx
|
|
346
|
-
import { ButtonExamples, TextExamples, ScreenExamples, AllExamples } from '@idealyst/components/examples';
|
|
347
|
-
|
|
348
|
-
// Show all components
|
|
349
|
-
<AllExamples />
|
|
350
|
-
|
|
351
|
-
// Show specific component examples
|
|
352
|
-
<ButtonExamples />
|
|
353
|
-
<TextExamples />
|
|
354
|
-
<ScreenExamples />
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
## TypeScript Support
|
|
358
|
-
|
|
359
|
-
All components are fully typed with comprehensive TypeScript definitions:
|
|
360
|
-
|
|
361
|
-
```tsx
|
|
362
|
-
import { ButtonProps, TextProps, ViewProps, ScreenProps } from '@idealyst/components';
|
|
363
|
-
|
|
364
|
-
// Use component prop types in your own components
|
|
365
|
-
interface MyButtonProps extends ButtonProps {
|
|
366
|
-
customProp: string;
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
interface MyScreenProps extends ScreenProps {
|
|
370
|
-
customLayout: boolean;
|
|
371
|
-
}
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
## Styling Guidelines
|
|
375
|
-
|
|
376
|
-
### Component Styling Architecture
|
|
377
|
-
|
|
378
|
-
This library follows a consistent approach to component styling using [react-native-unistyles](https://github.com/jpudysz/react-native-unistyles) with a variant-based system.
|
|
379
|
-
|
|
380
|
-
#### 1. Style Precedence
|
|
381
|
-
|
|
382
|
-
When both stylesheet variants and manual style props are provided, **manual styles take precedence**:
|
|
383
|
-
|
|
384
|
-
```tsx
|
|
385
|
-
// The backgroundColor in style will override the background variant
|
|
386
|
-
<View
|
|
387
|
-
background="primary" // Sets background via variant
|
|
388
|
-
style={{ backgroundColor: 'red' }} // This takes precedence
|
|
389
|
-
>
|
|
390
|
-
Content
|
|
391
|
-
</View>
|
|
392
|
-
```
|
|
393
|
-
|
|
394
|
-
This allows for flexible overrides while maintaining the design system defaults.
|
|
395
|
-
|
|
396
|
-
#### 2. Variants Over Manual Styles
|
|
397
|
-
|
|
398
|
-
**All style-related props should be implemented as variants** in the stylesheet rather than direct style modifications. This ensures consistency, theme integration, and maintainability.
|
|
399
|
-
|
|
400
|
-
✅ **Good - Using Variants:**
|
|
401
|
-
```tsx
|
|
402
|
-
// Component prop
|
|
403
|
-
<Text color="primary" size="large" weight="bold">
|
|
404
|
-
Hello World
|
|
405
|
-
</Text>
|
|
406
|
-
|
|
407
|
-
// Stylesheet implementation
|
|
408
|
-
const textStyles = StyleSheet.create((theme) => ({
|
|
409
|
-
text: {
|
|
410
|
-
variants: {
|
|
411
|
-
color: {
|
|
412
|
-
primary: { color: theme.colors.text.primary },
|
|
413
|
-
secondary: { color: theme.colors.text.secondary },
|
|
414
|
-
error: { color: theme.intents.error.main },
|
|
415
|
-
},
|
|
416
|
-
size: {
|
|
417
|
-
small: { fontSize: theme.typography.fontSize.sm },
|
|
418
|
-
large: { fontSize: theme.typography.fontSize.lg },
|
|
419
|
-
},
|
|
420
|
-
weight: {
|
|
421
|
-
bold: { fontWeight: theme.typography.fontWeight.bold },
|
|
422
|
-
normal: { fontWeight: theme.typography.fontWeight.regular },
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
}));
|
|
427
|
-
```
|
|
428
|
-
|
|
429
|
-
❌ **Avoid - Direct Style Manipulation:**
|
|
430
|
-
```tsx
|
|
431
|
-
// Don't do this
|
|
432
|
-
const Text = ({ color, size, style }) => {
|
|
433
|
-
const dynamicStyles = {
|
|
434
|
-
color: color === 'primary' ? '#007AFF' : '#666',
|
|
435
|
-
fontSize: size === 'large' ? 18 : 14,
|
|
436
|
-
};
|
|
437
|
-
|
|
438
|
-
return <RNText style={[dynamicStyles, style]} />;
|
|
439
|
-
};
|
|
440
|
-
```
|
|
441
|
-
|
|
442
|
-
#### 3. Benefits of the Variant System
|
|
443
|
-
|
|
444
|
-
- **Theme Integration**: Variants automatically use theme values
|
|
445
|
-
- **Type Safety**: TypeScript can enforce valid variant values
|
|
446
|
-
- **Performance**: Styles are computed once, not on every render
|
|
447
|
-
- **Consistency**: All components follow the same patterns
|
|
448
|
-
- **Dark Mode**: Automatic theme switching without component changes
|
|
449
|
-
|
|
450
|
-
#### 4. Style Override Pattern
|
|
451
|
-
|
|
452
|
-
The recommended pattern for all components:
|
|
453
|
-
|
|
454
|
-
```tsx
|
|
455
|
-
const Component = ({ variant1, variant2, style, ...props }) => {
|
|
456
|
-
componentStyles.useVariants({
|
|
457
|
-
variant1,
|
|
458
|
-
variant2,
|
|
459
|
-
});
|
|
460
|
-
|
|
461
|
-
const styleArray = [
|
|
462
|
-
componentStyles.component, // Base styles + variants
|
|
463
|
-
style, // Manual overrides (highest precedence)
|
|
464
|
-
];
|
|
465
|
-
|
|
466
|
-
return <BaseComponent style={styleArray} {...props} />;
|
|
467
|
-
};
|
|
468
|
-
```
|
|
469
|
-
|
|
470
|
-
#### 5. Creating New Variants
|
|
471
|
-
|
|
472
|
-
When adding new style options to components:
|
|
473
|
-
|
|
474
|
-
1. **Define the prop type** with specific allowed values
|
|
475
|
-
2. **Add the variant** to the stylesheet
|
|
476
|
-
3. **Use theme values** where possible
|
|
477
|
-
4. **Document the new prop** in the component's props section
|
|
478
|
-
|
|
479
|
-
```tsx
|
|
480
|
-
// 1. Type definition
|
|
481
|
-
interface ButtonProps {
|
|
482
|
-
radius?: 'none' | 'sm' | 'md' | 'lg' | 'full';
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
// 2. Stylesheet variant
|
|
486
|
-
const buttonStyles = StyleSheet.create((theme) => ({
|
|
487
|
-
button: {
|
|
488
|
-
variants: {
|
|
489
|
-
radius: {
|
|
490
|
-
none: { borderRadius: 0 },
|
|
491
|
-
sm: { borderRadius: theme.borderRadius.sm },
|
|
492
|
-
md: { borderRadius: theme.borderRadius.md },
|
|
493
|
-
lg: { borderRadius: theme.borderRadius.lg },
|
|
494
|
-
full: { borderRadius: theme.borderRadius.full },
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
}));
|
|
499
|
-
|
|
500
|
-
// 3. Component implementation
|
|
501
|
-
const Button = ({ radius = 'md', style, ...props }) => {
|
|
502
|
-
buttonStyles.useVariants({ radius });
|
|
503
|
-
return <Pressable style={[buttonStyles.button, style]} {...props} />;
|
|
504
|
-
};
|
|
505
|
-
```
|
|
506
|
-
|
|
507
|
-
## Development
|
|
508
|
-
|
|
509
|
-
### Building
|
|
510
|
-
|
|
511
|
-
```bash
|
|
512
|
-
# Build the library
|
|
513
|
-
yarn build
|
|
514
|
-
|
|
515
|
-
# Watch for changes during development
|
|
516
|
-
yarn dev
|
|
517
|
-
```
|
|
518
|
-
|
|
519
|
-
### Project Structure
|
|
520
|
-
|
|
521
|
-
```
|
|
522
|
-
packages/components/
|
|
523
|
-
├── src/
|
|
524
|
-
│ ├── Avatar/ # Avatar component
|
|
525
|
-
│ ├── Badge/ # Badge component
|
|
526
|
-
│ ├── Button/ # Button component
|
|
527
|
-
│ ├── Card/ # Card component
|
|
528
|
-
│ ├── Checkbox/ # Checkbox component
|
|
529
|
-
│ ├── Divider/ # Divider component
|
|
530
|
-
│ ├── Input/ # Input component
|
|
531
|
-
│ ├── Text/ # Text component
|
|
532
|
-
│ ├── View/ # View component
|
|
533
|
-
│ ├── examples/ # Component examples
|
|
534
|
-
│ ├── theme/ # Theme system
|
|
535
|
-
│ └── index.ts # Main exports
|
|
536
|
-
├── package.json
|
|
537
|
-
└── README.md
|
|
538
|
-
```
|
|
539
|
-
|
|
540
|
-
## Contributing
|
|
541
|
-
|
|
542
|
-
1. Fork the repository
|
|
543
|
-
2. Create a feature branch
|
|
544
|
-
3. Add your component following the existing patterns
|
|
545
|
-
4. Include examples and TypeScript definitions
|
|
546
|
-
5. Submit a pull request
|
|
547
|
-
|
|
548
|
-
### Component Structure
|
|
549
|
-
|
|
550
|
-
Each component follows this structure:
|
|
551
|
-
```
|
|
552
|
-
ComponentName/
|
|
553
|
-
├── ComponentName.web.tsx # Web implementation
|
|
554
|
-
├── ComponentName.native.tsx # React Native implementation
|
|
555
|
-
├── ComponentName.styles.tsx # Shared styles
|
|
556
|
-
├── types.ts # TypeScript definitions
|
|
557
|
-
├── index.ts # Web export
|
|
558
|
-
├── index.native.ts # Native export
|
|
559
|
-
└── index.web.ts # Web export
|
|
560
|
-
```
|
|
561
|
-
|
|
562
|
-
## License
|
|
563
|
-
|
|
564
|
-
MIT License - see LICENSE file for details.
|
|
565
|
-
|
|
566
|
-
## Support
|
|
567
|
-
|
|
1
|
+
# @idealyst/components
|
|
2
|
+
|
|
3
|
+
A comprehensive, cross-platform component library for React and React Native applications. Built with TypeScript and powered by [react-native-unistyles](https://github.com/jpudysz/react-native-unistyles) for consistent styling across platforms.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🌐 **Cross-Platform**: Works seamlessly in React and React Native
|
|
8
|
+
- 🎨 **Design System**: Comprehensive theming with light/dark mode support
|
|
9
|
+
- 📱 **Responsive**: Adaptive components that work on all screen sizes
|
|
10
|
+
- ♿ **Accessible**: Built with accessibility best practices
|
|
11
|
+
- 🔧 **TypeScript**: Full TypeScript support with comprehensive type definitions
|
|
12
|
+
- 🎯 **Intent-Based**: Semantic color system for consistent UX
|
|
13
|
+
- 🚀 **Production Ready**: Optimized for performance and developer experience
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Using Yarn (recommended)
|
|
19
|
+
yarn add @idealyst/components
|
|
20
|
+
|
|
21
|
+
# Using npm
|
|
22
|
+
npm install @idealyst/components
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Peer Dependencies
|
|
26
|
+
|
|
27
|
+
This library requires the following peer dependencies:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Core dependencies
|
|
31
|
+
yarn add react react-native-unistyles
|
|
32
|
+
|
|
33
|
+
# For React Native projects
|
|
34
|
+
yarn add react-native @react-native/normalize-colors react-native-edge-to-edge react-native-nitro-modules
|
|
35
|
+
|
|
36
|
+
# For React/Web projects
|
|
37
|
+
yarn add react
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import React from 'react';
|
|
44
|
+
import { Screen, View, Text, Button } from '@idealyst/components';
|
|
45
|
+
|
|
46
|
+
export default function App() {
|
|
47
|
+
return (
|
|
48
|
+
<Screen background="primary">
|
|
49
|
+
<View spacing="lg" style={{ flex: 1, justifyContent: 'center' }}>
|
|
50
|
+
<Text size="large" weight="bold" align="center">
|
|
51
|
+
Welcome to Idealyst Components
|
|
52
|
+
</Text>
|
|
53
|
+
<Button
|
|
54
|
+
variant="contained"
|
|
55
|
+
intent="primary"
|
|
56
|
+
onPress={() => console.log('Button pressed!')}
|
|
57
|
+
>
|
|
58
|
+
Get Started
|
|
59
|
+
</Button>
|
|
60
|
+
</View>
|
|
61
|
+
</Screen>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Available Components
|
|
67
|
+
|
|
68
|
+
### Layout Components
|
|
69
|
+
|
|
70
|
+
#### View
|
|
71
|
+
A flexible container component with built-in spacing and styling options.
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
import { View } from '@idealyst/components';
|
|
75
|
+
|
|
76
|
+
<View spacing="md" style={{ padding: 16 }}>
|
|
77
|
+
{/* Content */}
|
|
78
|
+
</View>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Props:**
|
|
82
|
+
- `spacing`: `"xs" | "sm" | "md" | "lg" | "xl" | "xxl"`
|
|
83
|
+
- Standard View props (style, children, etc.)
|
|
84
|
+
|
|
85
|
+
#### Screen
|
|
86
|
+
A full-screen container component that grows to fit the parent completely with theme-based backgrounds and padding.
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
import { Screen } from '@idealyst/components';
|
|
90
|
+
|
|
91
|
+
<Screen background="primary" padding="lg" safeArea={true}>
|
|
92
|
+
{/* Your app content */}
|
|
93
|
+
</Screen>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Props:**
|
|
97
|
+
- `background`: `"primary" | "secondary" | "tertiary" | "inverse"` - Background color variant
|
|
98
|
+
- `padding`: `"none" | "sm" | "md" | "lg" | "xl"` - Screen padding (default: "md")
|
|
99
|
+
- `safeArea`: `boolean` - Enable safe area padding for mobile devices (default: false)
|
|
100
|
+
- `style`: Additional styles
|
|
101
|
+
- `testID`: Test identifier
|
|
102
|
+
|
|
103
|
+
#### Divider
|
|
104
|
+
A separator component with customizable styling and spacing.
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
import { Divider } from '@idealyst/components';
|
|
108
|
+
|
|
109
|
+
<Divider spacing="medium" intent="primary">
|
|
110
|
+
<Text>Section Title</Text>
|
|
111
|
+
</Divider>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Props:**
|
|
115
|
+
- `spacing`: `"small" | "medium" | "large"`
|
|
116
|
+
- `intent`: `"primary" | "secondary" | "neutral"`
|
|
117
|
+
- `children`: Optional content to display in the divider
|
|
118
|
+
|
|
119
|
+
### Typography
|
|
120
|
+
|
|
121
|
+
#### Text
|
|
122
|
+
A versatile text component with comprehensive styling options.
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
import { Text } from '@idealyst/components';
|
|
126
|
+
|
|
127
|
+
<Text
|
|
128
|
+
size="large"
|
|
129
|
+
weight="bold"
|
|
130
|
+
color="primary"
|
|
131
|
+
align="center"
|
|
132
|
+
>
|
|
133
|
+
Hello World
|
|
134
|
+
</Text>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Props:**
|
|
138
|
+
- `size`: `"small" | "medium" | "large" | "xlarge"`
|
|
139
|
+
- `weight`: `"light" | "normal" | "medium" | "semibold" | "bold"`
|
|
140
|
+
- `color`: `"primary" | "secondary" | "success" | "warning" | "error"`
|
|
141
|
+
- `align`: `"left" | "center" | "right"`
|
|
142
|
+
|
|
143
|
+
### Form Components
|
|
144
|
+
|
|
145
|
+
#### Button
|
|
146
|
+
A customizable button component with multiple variants and intents.
|
|
147
|
+
|
|
148
|
+
```tsx
|
|
149
|
+
import { Button } from '@idealyst/components';
|
|
150
|
+
|
|
151
|
+
<Button
|
|
152
|
+
variant="contained"
|
|
153
|
+
intent="primary"
|
|
154
|
+
size="medium"
|
|
155
|
+
onPress={() => console.log('Pressed!')}
|
|
156
|
+
>
|
|
157
|
+
Click Me
|
|
158
|
+
</Button>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Props:**
|
|
162
|
+
- `variant`: `"contained" | "outlined" | "text"`
|
|
163
|
+
- `intent`: `"primary" | "neutral" | "success" | "error" | "warning"`
|
|
164
|
+
- `size`: `"small" | "medium" | "large"`
|
|
165
|
+
- `disabled`: `boolean`
|
|
166
|
+
- `onPress`: `() => void`
|
|
167
|
+
|
|
168
|
+
#### Input
|
|
169
|
+
A text input component with consistent styling.
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
import { Input } from '@idealyst/components';
|
|
173
|
+
|
|
174
|
+
<Input
|
|
175
|
+
placeholder="Enter your name"
|
|
176
|
+
value={value}
|
|
177
|
+
onChangeText={setValue}
|
|
178
|
+
/>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
#### Checkbox
|
|
182
|
+
A checkbox component with customizable styling.
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
import { Checkbox } from '@idealyst/components';
|
|
186
|
+
|
|
187
|
+
<Checkbox
|
|
188
|
+
checked={isChecked}
|
|
189
|
+
onPress={() => setIsChecked(!isChecked)}
|
|
190
|
+
label="Agree to terms"
|
|
191
|
+
/>
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Display Components
|
|
195
|
+
|
|
196
|
+
#### Card
|
|
197
|
+
A container component for displaying content in a card format.
|
|
198
|
+
|
|
199
|
+
```tsx
|
|
200
|
+
import { Card } from '@idealyst/components';
|
|
201
|
+
|
|
202
|
+
<Card>
|
|
203
|
+
<Text size="large" weight="bold">Card Title</Text>
|
|
204
|
+
<Text>Card content goes here</Text>
|
|
205
|
+
</Card>
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
#### Badge
|
|
209
|
+
A small component for displaying status or count information.
|
|
210
|
+
|
|
211
|
+
```tsx
|
|
212
|
+
import { Badge } from '@idealyst/components';
|
|
213
|
+
|
|
214
|
+
<Badge count={5} intent="error">
|
|
215
|
+
<Text>Notifications</Text>
|
|
216
|
+
</Badge>
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
#### Avatar
|
|
220
|
+
A component for displaying user avatars or profile pictures.
|
|
221
|
+
|
|
222
|
+
```tsx
|
|
223
|
+
import { Avatar } from '@idealyst/components';
|
|
224
|
+
|
|
225
|
+
<Avatar
|
|
226
|
+
source={{ uri: 'https://example.com/avatar.jpg' }}
|
|
227
|
+
size="medium"
|
|
228
|
+
fallback="JD"
|
|
229
|
+
/>
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**Props:**
|
|
233
|
+
- `source`: Image source object
|
|
234
|
+
- `size`: `"small" | "medium" | "large"`
|
|
235
|
+
- `fallback`: Text to display when image fails to load
|
|
236
|
+
|
|
237
|
+
## Theme System
|
|
238
|
+
|
|
239
|
+
The library includes a comprehensive theme system with light and dark mode support.
|
|
240
|
+
|
|
241
|
+
### Default Themes
|
|
242
|
+
|
|
243
|
+
```tsx
|
|
244
|
+
import { appThemes } from '@idealyst/components';
|
|
245
|
+
|
|
246
|
+
// Access theme colors and properties
|
|
247
|
+
const { colors, spacing, typography } = appThemes.light;
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Intent System
|
|
251
|
+
|
|
252
|
+
Components use an intent-based color system for consistent UX:
|
|
253
|
+
|
|
254
|
+
- **Primary**: Main brand actions
|
|
255
|
+
- **Neutral**: Secondary actions
|
|
256
|
+
- **Success**: Positive actions (save, confirm)
|
|
257
|
+
- **Error**: Destructive actions (delete, cancel)
|
|
258
|
+
- **Warning**: Caution actions
|
|
259
|
+
|
|
260
|
+
### Color Palettes
|
|
261
|
+
|
|
262
|
+
The theme includes 8 comprehensive color palettes:
|
|
263
|
+
- Blue (Primary)
|
|
264
|
+
- Green (Success)
|
|
265
|
+
- Red (Error)
|
|
266
|
+
- Amber (Warning)
|
|
267
|
+
- Gray (Neutral)
|
|
268
|
+
- Cyan (Info)
|
|
269
|
+
- Purple (Accent)
|
|
270
|
+
- Pink (Accent)
|
|
271
|
+
|
|
272
|
+
Each palette includes 10 shades (50-900) optimized for both light and dark themes.
|
|
273
|
+
|
|
274
|
+
### Custom Styling
|
|
275
|
+
|
|
276
|
+
Use the theme in your custom components:
|
|
277
|
+
|
|
278
|
+
```tsx
|
|
279
|
+
import { StyleSheet } from 'react-native';
|
|
280
|
+
import { createStyleSheet } from 'react-native-unistyles';
|
|
281
|
+
|
|
282
|
+
const styles = createStyleSheet((theme) => ({
|
|
283
|
+
container: {
|
|
284
|
+
backgroundColor: theme.colors.surface.primary,
|
|
285
|
+
padding: theme.spacing.md,
|
|
286
|
+
borderRadius: theme.borderRadius.lg,
|
|
287
|
+
},
|
|
288
|
+
text: {
|
|
289
|
+
color: theme.colors.text.primary,
|
|
290
|
+
fontSize: theme.typography.fontSize.md,
|
|
291
|
+
},
|
|
292
|
+
}));
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## Platform-Specific Usage
|
|
296
|
+
|
|
297
|
+
### React Native
|
|
298
|
+
|
|
299
|
+
```tsx
|
|
300
|
+
import React from 'react';
|
|
301
|
+
import { Screen, View, Text, Button } from '@idealyst/components';
|
|
302
|
+
|
|
303
|
+
export default function App() {
|
|
304
|
+
return (
|
|
305
|
+
<Screen background="primary">
|
|
306
|
+
<View spacing="lg" style={{ flex: 1 }}>
|
|
307
|
+
<Text size="large" weight="bold">
|
|
308
|
+
React Native App
|
|
309
|
+
</Text>
|
|
310
|
+
<Button variant="contained" intent="primary">
|
|
311
|
+
Native Button
|
|
312
|
+
</Button>
|
|
313
|
+
</View>
|
|
314
|
+
</Screen>
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### React Web
|
|
320
|
+
|
|
321
|
+
```tsx
|
|
322
|
+
import React from 'react';
|
|
323
|
+
import { Screen, View, Text, Button } from '@idealyst/components';
|
|
324
|
+
|
|
325
|
+
export default function App() {
|
|
326
|
+
return (
|
|
327
|
+
<Screen background="primary">
|
|
328
|
+
<View spacing="lg">
|
|
329
|
+
<Text size="large" weight="bold">
|
|
330
|
+
Web App
|
|
331
|
+
</Text>
|
|
332
|
+
<Button variant="contained" intent="primary">
|
|
333
|
+
Web Button
|
|
334
|
+
</Button>
|
|
335
|
+
</View>
|
|
336
|
+
</Screen>
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
## Examples
|
|
342
|
+
|
|
343
|
+
Import pre-built examples to see components in action:
|
|
344
|
+
|
|
345
|
+
```tsx
|
|
346
|
+
import { ButtonExamples, TextExamples, ScreenExamples, AllExamples } from '@idealyst/components/examples';
|
|
347
|
+
|
|
348
|
+
// Show all components
|
|
349
|
+
<AllExamples />
|
|
350
|
+
|
|
351
|
+
// Show specific component examples
|
|
352
|
+
<ButtonExamples />
|
|
353
|
+
<TextExamples />
|
|
354
|
+
<ScreenExamples />
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## TypeScript Support
|
|
358
|
+
|
|
359
|
+
All components are fully typed with comprehensive TypeScript definitions:
|
|
360
|
+
|
|
361
|
+
```tsx
|
|
362
|
+
import { ButtonProps, TextProps, ViewProps, ScreenProps } from '@idealyst/components';
|
|
363
|
+
|
|
364
|
+
// Use component prop types in your own components
|
|
365
|
+
interface MyButtonProps extends ButtonProps {
|
|
366
|
+
customProp: string;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
interface MyScreenProps extends ScreenProps {
|
|
370
|
+
customLayout: boolean;
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
## Styling Guidelines
|
|
375
|
+
|
|
376
|
+
### Component Styling Architecture
|
|
377
|
+
|
|
378
|
+
This library follows a consistent approach to component styling using [react-native-unistyles](https://github.com/jpudysz/react-native-unistyles) with a variant-based system.
|
|
379
|
+
|
|
380
|
+
#### 1. Style Precedence
|
|
381
|
+
|
|
382
|
+
When both stylesheet variants and manual style props are provided, **manual styles take precedence**:
|
|
383
|
+
|
|
384
|
+
```tsx
|
|
385
|
+
// The backgroundColor in style will override the background variant
|
|
386
|
+
<View
|
|
387
|
+
background="primary" // Sets background via variant
|
|
388
|
+
style={{ backgroundColor: 'red' }} // This takes precedence
|
|
389
|
+
>
|
|
390
|
+
Content
|
|
391
|
+
</View>
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
This allows for flexible overrides while maintaining the design system defaults.
|
|
395
|
+
|
|
396
|
+
#### 2. Variants Over Manual Styles
|
|
397
|
+
|
|
398
|
+
**All style-related props should be implemented as variants** in the stylesheet rather than direct style modifications. This ensures consistency, theme integration, and maintainability.
|
|
399
|
+
|
|
400
|
+
✅ **Good - Using Variants:**
|
|
401
|
+
```tsx
|
|
402
|
+
// Component prop
|
|
403
|
+
<Text color="primary" size="large" weight="bold">
|
|
404
|
+
Hello World
|
|
405
|
+
</Text>
|
|
406
|
+
|
|
407
|
+
// Stylesheet implementation
|
|
408
|
+
const textStyles = StyleSheet.create((theme) => ({
|
|
409
|
+
text: {
|
|
410
|
+
variants: {
|
|
411
|
+
color: {
|
|
412
|
+
primary: { color: theme.colors.text.primary },
|
|
413
|
+
secondary: { color: theme.colors.text.secondary },
|
|
414
|
+
error: { color: theme.intents.error.main },
|
|
415
|
+
},
|
|
416
|
+
size: {
|
|
417
|
+
small: { fontSize: theme.typography.fontSize.sm },
|
|
418
|
+
large: { fontSize: theme.typography.fontSize.lg },
|
|
419
|
+
},
|
|
420
|
+
weight: {
|
|
421
|
+
bold: { fontWeight: theme.typography.fontWeight.bold },
|
|
422
|
+
normal: { fontWeight: theme.typography.fontWeight.regular },
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}));
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
❌ **Avoid - Direct Style Manipulation:**
|
|
430
|
+
```tsx
|
|
431
|
+
// Don't do this
|
|
432
|
+
const Text = ({ color, size, style }) => {
|
|
433
|
+
const dynamicStyles = {
|
|
434
|
+
color: color === 'primary' ? '#007AFF' : '#666',
|
|
435
|
+
fontSize: size === 'large' ? 18 : 14,
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
return <RNText style={[dynamicStyles, style]} />;
|
|
439
|
+
};
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
#### 3. Benefits of the Variant System
|
|
443
|
+
|
|
444
|
+
- **Theme Integration**: Variants automatically use theme values
|
|
445
|
+
- **Type Safety**: TypeScript can enforce valid variant values
|
|
446
|
+
- **Performance**: Styles are computed once, not on every render
|
|
447
|
+
- **Consistency**: All components follow the same patterns
|
|
448
|
+
- **Dark Mode**: Automatic theme switching without component changes
|
|
449
|
+
|
|
450
|
+
#### 4. Style Override Pattern
|
|
451
|
+
|
|
452
|
+
The recommended pattern for all components:
|
|
453
|
+
|
|
454
|
+
```tsx
|
|
455
|
+
const Component = ({ variant1, variant2, style, ...props }) => {
|
|
456
|
+
componentStyles.useVariants({
|
|
457
|
+
variant1,
|
|
458
|
+
variant2,
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
const styleArray = [
|
|
462
|
+
componentStyles.component, // Base styles + variants
|
|
463
|
+
style, // Manual overrides (highest precedence)
|
|
464
|
+
];
|
|
465
|
+
|
|
466
|
+
return <BaseComponent style={styleArray} {...props} />;
|
|
467
|
+
};
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
#### 5. Creating New Variants
|
|
471
|
+
|
|
472
|
+
When adding new style options to components:
|
|
473
|
+
|
|
474
|
+
1. **Define the prop type** with specific allowed values
|
|
475
|
+
2. **Add the variant** to the stylesheet
|
|
476
|
+
3. **Use theme values** where possible
|
|
477
|
+
4. **Document the new prop** in the component's props section
|
|
478
|
+
|
|
479
|
+
```tsx
|
|
480
|
+
// 1. Type definition
|
|
481
|
+
interface ButtonProps {
|
|
482
|
+
radius?: 'none' | 'sm' | 'md' | 'lg' | 'full';
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// 2. Stylesheet variant
|
|
486
|
+
const buttonStyles = StyleSheet.create((theme) => ({
|
|
487
|
+
button: {
|
|
488
|
+
variants: {
|
|
489
|
+
radius: {
|
|
490
|
+
none: { borderRadius: 0 },
|
|
491
|
+
sm: { borderRadius: theme.borderRadius.sm },
|
|
492
|
+
md: { borderRadius: theme.borderRadius.md },
|
|
493
|
+
lg: { borderRadius: theme.borderRadius.lg },
|
|
494
|
+
full: { borderRadius: theme.borderRadius.full },
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}));
|
|
499
|
+
|
|
500
|
+
// 3. Component implementation
|
|
501
|
+
const Button = ({ radius = 'md', style, ...props }) => {
|
|
502
|
+
buttonStyles.useVariants({ radius });
|
|
503
|
+
return <Pressable style={[buttonStyles.button, style]} {...props} />;
|
|
504
|
+
};
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
## Development
|
|
508
|
+
|
|
509
|
+
### Building
|
|
510
|
+
|
|
511
|
+
```bash
|
|
512
|
+
# Build the library
|
|
513
|
+
yarn build
|
|
514
|
+
|
|
515
|
+
# Watch for changes during development
|
|
516
|
+
yarn dev
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
### Project Structure
|
|
520
|
+
|
|
521
|
+
```
|
|
522
|
+
packages/components/
|
|
523
|
+
├── src/
|
|
524
|
+
│ ├── Avatar/ # Avatar component
|
|
525
|
+
│ ├── Badge/ # Badge component
|
|
526
|
+
│ ├── Button/ # Button component
|
|
527
|
+
│ ├── Card/ # Card component
|
|
528
|
+
│ ├── Checkbox/ # Checkbox component
|
|
529
|
+
│ ├── Divider/ # Divider component
|
|
530
|
+
│ ├── Input/ # Input component
|
|
531
|
+
│ ├── Text/ # Text component
|
|
532
|
+
│ ├── View/ # View component
|
|
533
|
+
│ ├── examples/ # Component examples
|
|
534
|
+
│ ├── theme/ # Theme system
|
|
535
|
+
│ └── index.ts # Main exports
|
|
536
|
+
├── package.json
|
|
537
|
+
└── README.md
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
## Contributing
|
|
541
|
+
|
|
542
|
+
1. Fork the repository
|
|
543
|
+
2. Create a feature branch
|
|
544
|
+
3. Add your component following the existing patterns
|
|
545
|
+
4. Include examples and TypeScript definitions
|
|
546
|
+
5. Submit a pull request
|
|
547
|
+
|
|
548
|
+
### Component Structure
|
|
549
|
+
|
|
550
|
+
Each component follows this structure:
|
|
551
|
+
```
|
|
552
|
+
ComponentName/
|
|
553
|
+
├── ComponentName.web.tsx # Web implementation
|
|
554
|
+
├── ComponentName.native.tsx # React Native implementation
|
|
555
|
+
├── ComponentName.styles.tsx # Shared styles
|
|
556
|
+
├── types.ts # TypeScript definitions
|
|
557
|
+
├── index.ts # Web export
|
|
558
|
+
├── index.native.ts # Native export
|
|
559
|
+
└── index.web.ts # Web export
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
## License
|
|
563
|
+
|
|
564
|
+
MIT License - see LICENSE file for details.
|
|
565
|
+
|
|
566
|
+
## Support
|
|
567
|
+
|
|
568
568
|
For issues, questions, or contributions, please visit our [GitHub repository](https://github.com/your-org/idealyst-framework).
|