app-studio 0.7.11 → 0.7.13

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/docs/README.md CHANGED
@@ -80,7 +80,8 @@ Explore these guides to learn more about App-Studio:
80
80
 
81
81
  - [Components](Components.md) - Detailed documentation of all available components
82
82
  - [Hooks](Hooks.md) - Guide to the React hooks provided by App-Studio
83
- - [Theming](Theming.md) - How to customize the look and feel of your app
83
+ - [Theming](Theming.md) - How to customize colors and themes with theme colors and color palettes
84
+ - [Styling](Styling.md) - Advanced styling guide covering state modifiers, pseudo-elements, media queries, and the CSS system
84
85
  - [Animation](Animation.md) - Creating animations with App-Studio
85
86
  - [Responsive Design](Responsive.md) - Building responsive layouts
86
87
  - [Design System](Design.md) - Understanding the design system
@@ -560,7 +561,7 @@ Manages the application's theme, including color palettes, light/dark modes, and
560
561
 
561
562
  **Context Values (via `useTheme`)**
562
563
 
563
- * `getColor(colorName, mode?)`: Resolves a color string (e.g., `color-blue-500`, `theme-primary`) to its CSS value for the specified or current theme mode. You can also directly access specific theme mode colors using the `light-` or `dark-` prefix (e.g., `light-white` or `dark-red-200`), which will always use that specific theme mode's color regardless of the current theme setting.
564
+ * `getColor(colorName, mode?)`: Resolves a color string (e.g., `color-blue-500`, `theme-primary`) to its CSS value for the specified or current theme mode. You rarely need to call this — App-Studio components resolve color strings passed as props automatically. Use `getColor` only when passing a color to a non-App-Studio element or when you need the raw CSS value for a computed style. You can also directly access specific theme mode colors using the `light-` or `dark-` prefix (e.g., `light-white` or `dark-red-200`), which will always use that specific theme mode's color regardless of the current theme setting.
564
565
  * `theme`: The merged theme configuration object.
565
566
  * `themeMode`: The current mode ('light' or 'dark').
566
567
  * `setThemeMode(mode)`: Function to change the theme mode.
@@ -621,32 +622,31 @@ App-Studio exports utility objects and functions.
621
622
 
622
623
  ## Colors (`utils/colors.ts`)
623
624
 
624
- Defines the default color palettes (`defaultLightPalette`, `defaultDarkPalette`) and singleton colors (`defaultLightColors`, `defaultDarkColors`) used by `ThemeProvider`. You can import these if needed for custom theme configurations. Colors are accessed within components primarily via the `getColor` function from `useTheme`.
625
+ Defines the default color palettes (`defaultLightPalette`, `defaultDarkPalette`) and singleton colors (`defaultLightColors`, `defaultDarkColors`) used by `ThemeProvider`. You can import these if needed for custom theme configurations.
625
626
 
626
627
  **Accessing Colors:**
627
628
 
629
+ App-Studio components resolve color strings automatically — just pass them as props. You don't need `getColor` for this:
630
+
628
631
  ```jsx
629
- import { useTheme } from 'app-studio';
630
- import { View, Text } from './components/Components';
632
+ import { View, Text } from 'app-studio';
631
633
 
632
634
  function ThemedComponent() {
633
- const { getColor } = useTheme();
634
-
635
635
  return (
636
636
  <View
637
- backgroundColor={getColor('theme-primary')} // Get theme color
638
- color={getColor('color-white')} // Get singleton color
637
+ backgroundColor="theme-primary" // Theme color
638
+ color="color-white" // Singleton color
639
639
  borderRadius={8}
640
640
  padding={10}
641
641
  >
642
642
  <Text>My Themed Content</Text>
643
643
 
644
- {/* Direct access to specific theme mode colors */}
644
+ {/* Mode-locked colors work the same way */}
645
645
  <View
646
646
  marginTop={10}
647
647
  padding={8}
648
- backgroundColor={getColor('light-blue-200')} // Always light mode blue
649
- borderColor={getColor('dark-red-500')} // Always dark mode red
648
+ backgroundColor="light-blue-200" // Always light mode blue
649
+ borderColor="dark-red-500" // Always dark mode red
650
650
  borderWidth={2}
651
651
  borderStyle="solid"
652
652
  borderRadius={4}
@@ -654,7 +654,6 @@ function ThemedComponent() {
654
654
  <Text>Mixed theme mode colors</Text>
655
655
  </View>
656
656
 
657
- {/* Direct usage in component props without getColor */}
658
657
  <View marginTop={10} padding={8}>
659
658
  <Text color="light-white">Always light mode white text</Text>
660
659
  <Text color="dark-blue-700" marginTop={4}>Always dark mode blue text</Text>
@@ -0,0 +1,572 @@
1
+ # Comprehensive Styling Guide for App-Studio
2
+
3
+ This guide covers advanced styling techniques in App-Studio, including state modifiers, pseudo-elements, media queries, and the underlying CSS system.
4
+
5
+ ## Table of Contents
6
+
7
+ 1. [State Modifiers](#state-modifiers)
8
+ 2. [Pseudo-Elements](#pseudo-elements)
9
+ 3. [Media Queries](#media-queries)
10
+ 4. [CSS System Architecture](#css-system-architecture)
11
+ 5. [Performance Optimization](#performance-optimization)
12
+ 6. [Advanced Patterns](#advanced-patterns)
13
+
14
+ ## State Modifiers
15
+
16
+ State modifiers allow you to define styles that apply based on user interactions or element states. They use underscore-prefixed props for a clean, declarative syntax.
17
+
18
+ ### Basic State Modifiers
19
+
20
+ ```javascript
21
+ import { Element } from 'app-studio';
22
+
23
+ <Element
24
+ as="button"
25
+ // Base styles
26
+ padding={12}
27
+ backgroundColor="color-blue-500"
28
+ color="color-white"
29
+
30
+ // Interaction states
31
+ _hover={{ backgroundColor: "color-blue-600" }}
32
+ _active={{ backgroundColor: "color-blue-700" }}
33
+ _focus={{ outline: "2px solid color-blue-400" }}
34
+ _disabled={{ opacity: 0.5, cursor: "not-allowed" }}
35
+ />
36
+ ```
37
+
38
+ ### Form States
39
+
40
+ ```javascript
41
+ // Input with validation states
42
+ <Element
43
+ as="input"
44
+ borderColor="color-gray-300"
45
+ _focus={{ borderColor: "color-blue-500" }}
46
+ _valid={{ borderColor: "color-green-500" }}
47
+ _invalid={{ borderColor: "color-red-500" }}
48
+ />
49
+
50
+ // Checkbox states
51
+ <Element
52
+ as="input"
53
+ type="checkbox"
54
+ _checked={{ accentColor: "color-blue-500" }}
55
+ _disabled={{ accentColor: "color-gray-400" }}
56
+ />
57
+ ```
58
+
59
+ ### Child & Element Relationship States
60
+
61
+ ```javascript
62
+ // First/last child
63
+ <View>
64
+ <Element
65
+ _firstChild={{ marginTop: 0 }}
66
+ _lastChild={{ marginBottom: 0 }}
67
+ marginTop={12}
68
+ marginBottom={12}
69
+ >
70
+ List item
71
+ </Element>
72
+ </View>
73
+
74
+ // Group hover - child reacts to parent hover
75
+ <View className="group" _hover={{ backgroundColor: "color-gray-100" }}>
76
+ <Element
77
+ color="color-gray-600"
78
+ _groupHover={{ color: "color-blue-500" }}
79
+ >
80
+ Text changes when group hovers
81
+ </Element>
82
+ </View>
83
+
84
+ // Peer modifiers - sibling relationships
85
+ <View>
86
+ <input className="peer" />
87
+ <Element
88
+ color="color-gray-400"
89
+ _peerFocus={{ color: "color-blue-500" }}
90
+ >
91
+ Label
92
+ </Element>
93
+ </View>
94
+ ```
95
+
96
+ ## Pseudo-Elements
97
+
98
+ Pseudo-elements like `::before`, `::after`, `::first-letter`, etc., can be styled with the underscore prefix:
99
+
100
+ ### Common Pseudo-Elements
101
+
102
+ ```javascript
103
+ import { Element } from 'app-studio';
104
+
105
+ function ButtonWithUnderline() {
106
+ return (
107
+ <Element
108
+ as="button"
109
+ position="relative"
110
+
111
+ // ::before pseudo-element
112
+ _before={{
113
+ content: '""',
114
+ position: 'absolute',
115
+ top: 0,
116
+ left: 0,
117
+ width: '100%',
118
+ height: '2px',
119
+ backgroundColor: 'color-blue-500',
120
+ }}
121
+
122
+ // ::after pseudo-element
123
+ _after={{
124
+ content: '""',
125
+ position: 'absolute',
126
+ bottom: 0,
127
+ left: 0,
128
+ width: 0,
129
+ height: '2px',
130
+ backgroundColor: 'color-blue-500',
131
+ transition: 'width 300ms ease',
132
+ }}
133
+
134
+ _hover={{
135
+ _after: {
136
+ width: '100%',
137
+ },
138
+ }}
139
+ >
140
+ Hover me
141
+ </Element>
142
+ );
143
+ }
144
+ ```
145
+
146
+ ### Text Pseudo-Elements
147
+
148
+ ```javascript
149
+ // Style first letter
150
+ <Element
151
+ as="p"
152
+ _firstLetter={{
153
+ fontSize: 24,
154
+ fontWeight: 'bold',
155
+ color: 'color-blue-500',
156
+ }}
157
+ >
158
+ Lorem ipsum dolor sit amet...
159
+ </Element>
160
+
161
+ // Style first line
162
+ <Element
163
+ as="p"
164
+ _firstLine={{
165
+ fontWeight: 'bold',
166
+ color: 'color-gray-800',
167
+ }}
168
+ >
169
+ First line will be bold
170
+ </Element>
171
+
172
+ // Style selected text
173
+ <Element
174
+ _selection={{
175
+ backgroundColor: 'color-blue-300',
176
+ color: 'color-white',
177
+ }}
178
+ >
179
+ Try selecting this text
180
+ </Element>
181
+ ```
182
+
183
+ ## Media Queries
184
+
185
+ Define responsive styles using the `media` prop:
186
+
187
+ ### Basic Responsive Styles
188
+
189
+ ```javascript
190
+ import { View, Text } from 'app-studio';
191
+
192
+ function ResponsiveComponent() {
193
+ return (
194
+ <View
195
+ // Mobile first
196
+ padding={8}
197
+ fontSize={14}
198
+
199
+ // Tablet and up
200
+ media={{
201
+ tablet: {
202
+ padding: 16,
203
+ fontSize: 16,
204
+ },
205
+ // Desktop and up
206
+ desktop: {
207
+ padding: 24,
208
+ fontSize: 18,
209
+ },
210
+ }}
211
+ >
212
+ <Text>Responsive content</Text>
213
+ </View>
214
+ );
215
+ }
216
+ ```
217
+
218
+ ### Color Changes Across Breakpoints
219
+
220
+ ```javascript
221
+ <View
222
+ backgroundColor="color-white"
223
+ color="color-gray-900"
224
+
225
+ media={{
226
+ tablet: {
227
+ backgroundColor: "color-gray-50",
228
+ },
229
+ desktop: {
230
+ backgroundColor: "color-white",
231
+ color: "color-gray-950",
232
+ },
233
+ }}
234
+ />
235
+ ```
236
+
237
+ ### Hide/Show Based on Breakpoint
238
+
239
+ ```javascript
240
+ <View
241
+ display="none"
242
+ media={{
243
+ tablet: { display: "block" },
244
+ }}
245
+ >
246
+ Only visible on tablet and larger
247
+ </View>
248
+ ```
249
+
250
+ ## CSS System Architecture
251
+
252
+ ### How App-Studio's CSS System Works
253
+
254
+ App-Studio uses a sophisticated utility-class generation system based on CSS variables and atomic CSS principles.
255
+
256
+ #### Style Processing Pipeline
257
+
258
+ ```
259
+ User Props
260
+
261
+ Color Resolution (theme-aware)
262
+
263
+ CSS Property Normalization
264
+
265
+ Utility Class Generation
266
+
267
+ LRU Cache (10,000 entries)
268
+
269
+ CSS Injection (contextual)
270
+
271
+ DOM Rendering
272
+ ```
273
+
274
+ #### Contexts for CSS Injection
275
+
276
+ Styles are injected into different contexts for proper specificity management:
277
+
278
+ 1. **Base**: Standard styles (lowest specificity)
279
+ 2. **Pseudo**: Pseudo-class/element styles (`:hover`, `::before`, etc.)
280
+ 3. **Media**: Media query styles
281
+ 4. **Modifier**: Complex modifiers (group/peer)
282
+ 5. **Override**: Highest specificity for `css` prop
283
+
284
+ ### CSS Variables System
285
+
286
+ All theme colors are exposed as CSS variables:
287
+
288
+ ```css
289
+ /* Color palettes */
290
+ --color-blue-500: #3b82f6;
291
+ --color-blue-600: #2563eb;
292
+ --color-rose-200: #fecdd3;
293
+
294
+ /* Theme colors */
295
+ --theme-primary: var(--color-blue-600);
296
+ --theme-secondary: var(--color-purple-500);
297
+
298
+ /* Light mode colors */
299
+ --light-white: #ffffff;
300
+ --dark-white: #000000;
301
+ ```
302
+
303
+ Access them directly in CSS:
304
+
305
+ ```javascript
306
+ <View
307
+ css={{
308
+ background: 'linear-gradient(90deg, var(--color-blue-500), var(--color-purple-500))',
309
+ }}
310
+ />
311
+ ```
312
+
313
+ ### Color Processing
314
+
315
+ Colors are processed through multiple stages:
316
+
317
+ 1. **Token Recognition**: Identify color tokens (e.g., `color-blue-500`)
318
+ 2. **Theme Resolution**: Resolve theme colors to actual values
319
+ 3. **Alpha Application**: Apply transparency using `color-mix()`
320
+ 4. **Mode Awareness**: Switch between light/dark mode colors
321
+
322
+ ## Performance Optimization
323
+
324
+ ### 1. LRU Caching
325
+
326
+ The utility class manager uses an LRU (Least Recently Used) cache with 10,000 entries:
327
+
328
+ ```javascript
329
+ // Every computed class is cached
330
+ // Subsequent renders reuse the cached class
331
+ // Old entries are evicted to maintain memory
332
+ ```
333
+
334
+ ### 2. CSS Variable Reuse
335
+
336
+ Avoid redundant property-value combinations:
337
+
338
+ ```javascript
339
+ // Good - reuses computed values
340
+ <View backgroundColor="color-blue-500" />
341
+ <View backgroundColor="color-blue-500" />
342
+
343
+ // Less efficient - different instances
344
+ <View backgroundColor="rgb(59, 130, 246)" />
345
+ <View backgroundColor="rgb(59, 130, 246)" />
346
+ ```
347
+
348
+ ### 3. Batch Style Updates
349
+
350
+ Group related style changes:
351
+
352
+ ```javascript
353
+ // Good - batches all changes
354
+ <View
355
+ padding={16}
356
+ gap={8}
357
+ flexDirection="column"
358
+ />
359
+
360
+ // Less efficient - multiple renders
361
+ const [padding, setPadding] = useState(0);
362
+ const [gap, setGap] = useState(0);
363
+ ```
364
+
365
+ ### 4. Media Query Optimization
366
+
367
+ Define media queries once:
368
+
369
+ ```javascript
370
+ // Define at component level
371
+ const responsiveStyles = {
372
+ mobile: { padding: 8 },
373
+ tablet: { padding: 16 },
374
+ desktop: { padding: 24 },
375
+ };
376
+
377
+ // Reuse across multiple elements
378
+ <View media={responsiveStyles} />
379
+ <View media={responsiveStyles} />
380
+ ```
381
+
382
+ ## Advanced Patterns
383
+
384
+ ### Compound States
385
+
386
+ Combine multiple state modifiers:
387
+
388
+ ```javascript
389
+ <Element
390
+ as="button"
391
+ backgroundColor="color-blue-500"
392
+
393
+ _hover={{
394
+ backgroundColor: "color-blue-600",
395
+
396
+ // Nested state: hover + focus
397
+ _focus: {
398
+ boxShadow: "0 0 0 3px rgba(59, 130, 246, 0.1)",
399
+ },
400
+ }}
401
+
402
+ _active={{
403
+ backgroundColor: "color-blue-700",
404
+ transform: "scale(0.98)",
405
+ }}
406
+ />
407
+ ```
408
+
409
+ ### Dynamic Theming
410
+
411
+ App-Studio components resolve theme color strings automatically. Pass the color name directly — no need for `getColor`:
412
+
413
+ ```javascript
414
+ import { View } from 'app-studio';
415
+
416
+ function DynamicThemedComponent() {
417
+ return (
418
+ <View
419
+ backgroundColor="theme-primary"
420
+ borderColor="theme-secondary"
421
+ />
422
+ );
423
+ }
424
+ ```
425
+
426
+ `getColor` from `useTheme` is only needed when passing a resolved CSS color to a non-App-Studio element (e.g., a third-party chart library) or to a computed value outside the prop system.
427
+
428
+ ### CSS-in-JS Patterns
429
+
430
+ Use the `css` prop for complex styles:
431
+
432
+ ```javascript
433
+ <View
434
+ css={{
435
+ // Standard CSS
436
+ 'background': 'linear-gradient(135deg, var(--color-blue-500) 0%, var(--color-purple-500) 100%)',
437
+ 'clip-path': 'polygon(0 0, 85% 0, 100% 50%, 85% 100%, 0 100%)',
438
+ 'position': 'relative',
439
+
440
+ // Vendor prefixes
441
+ 'WebkitMaskImage': 'linear-gradient(to bottom, black 0%, transparent 100%)',
442
+ }}
443
+ padding={20}
444
+ />
445
+ ```
446
+
447
+ ### Animation with Colors
448
+
449
+ ```javascript
450
+ import { View, Animation } from 'app-studio';
451
+
452
+ <View
453
+ fontSize={48}
454
+ fontWeight="bold"
455
+ css={{
456
+ 'background': 'linear-gradient(90deg, var(--color-blue-500), var(--color-purple-500))',
457
+ 'background-clip': 'text',
458
+ 'color': 'transparent',
459
+ 'WebkitBackgroundClip': 'text',
460
+ 'WebkitTextFillColor': 'transparent',
461
+ }}
462
+ animate={Animation.scroll()}
463
+ />
464
+ ```
465
+
466
+ ### Responsive Grid Layouts
467
+
468
+ ```javascript
469
+ <View
470
+ display="grid"
471
+ gridTemplateColumns="1fr"
472
+ gap={16}
473
+
474
+ media={{
475
+ tablet: {
476
+ gridTemplateColumns: "1fr 1fr",
477
+ gap: 24,
478
+ },
479
+ desktop: {
480
+ gridTemplateColumns: "repeat(3, 1fr)",
481
+ gap: 32,
482
+ },
483
+ }}
484
+ >
485
+ {/* Grid items */}
486
+ </View>
487
+ ```
488
+
489
+ ### Accessibility Patterns
490
+
491
+ ```javascript
492
+ import { Element } from 'app-studio';
493
+
494
+ function AccessibleButton() {
495
+ return (
496
+ <Element
497
+ as="button"
498
+ aria-label="Close dialog"
499
+ backgroundColor="color-gray-100"
500
+
501
+ // High contrast on focus
502
+ _focusVisible={{
503
+ outline: "3px solid color-blue-600",
504
+ outlineOffset: "2px",
505
+ }}
506
+
507
+ // Disabled state indication
508
+ _disabled={{
509
+ backgroundColor: "color-gray-300",
510
+ color: "color-gray-600",
511
+ cursor: "not-allowed",
512
+ }}
513
+
514
+ // Reduce motion preference
515
+ media={{
516
+ 'prefers-reduced-motion': {
517
+ transition: "none",
518
+ },
519
+ }}
520
+ >
521
+ Close
522
+ </Element>
523
+ );
524
+ }
525
+ ```
526
+
527
+ ## Best Practices
528
+
529
+ 1. **Use semantic color names** - `theme-primary`, `theme-error`, not arbitrary colors
530
+ 2. **Leverage CSS variables** - Reference `var(--color-*)` for better performance
531
+ 3. **Compose state modifiers** - Build complex states from simple ones
532
+ 4. **Mobile-first responsive design** - Define mobile styles first, then enhance
533
+ 5. **Cache computed styles** - Reuse style objects across components
534
+ 6. **Avoid inline computations** - Pre-define color combinations in theme
535
+ 7. **Use pseudo-elements sparingly** - They can complicate debugging
536
+ 8. **Test state combinations** - Ensure all interactive states work properly
537
+
538
+ ## Debugging
539
+
540
+ ### Chrome DevTools Tips
541
+
542
+ 1. **Inspect Utility Classes** - Look for `.{property}-{value}` class names
543
+ 2. **Check CSS Variables** - Use DevTools to see all `--color-*` variables
544
+ 3. **Monitor Cache** - Check if classes are being reused (cache hits)
545
+
546
+ ### Browser Console
547
+
548
+ ```javascript
549
+ // Check if a color is available
550
+ getComputedStyle(document.documentElement).getPropertyValue('--color-blue-500');
551
+
552
+ // Find all theme variables
553
+ Array.from(document.documentElement.style)
554
+ .filter(prop => prop.startsWith('--'))
555
+ ```
556
+
557
+ ## Summary
558
+
559
+ App-Studio's styling system provides:
560
+
561
+ - ✅ Declarative state management with underscore-prefixed props
562
+ - ✅ Pseudo-element styling with full CSS support
563
+ - ✅ Responsive design with media queries
564
+ - ✅ Theme-aware colors with CSS variables
565
+ - ✅ High-performance caching and optimization
566
+ - ✅ Type-safe styling with TypeScript support
567
+ - ✅ Server-side rendering compatibility
568
+
569
+ For more information, see:
570
+ - [Theming Guide](./Theming.md)
571
+ - [Animation Guide](./Animation.md)
572
+ - [Responsive Design](./Responsive.md)