@animus-ui/core 0.1.1-fffe37d2.0 → 0.2.0-beta.2

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.
Files changed (49) hide show
  1. package/ANIMUS_ARCHITECTURE.md +173 -0
  2. package/CHANGELOG.md +80 -8
  3. package/CLAUDE.md +1240 -0
  4. package/dist/Animus.d.ts +77 -63
  5. package/dist/AnimusConfig.d.ts +8 -8
  6. package/dist/AnimusExtended.d.ts +76 -0
  7. package/dist/__fixtures__/testConfig.d.ts +153 -153
  8. package/dist/compatTheme.d.ts +28 -20
  9. package/dist/config.d.ts +2321 -2193
  10. package/dist/createAnimus.d.ts +2 -2
  11. package/dist/index.d.ts +1084 -1019
  12. package/dist/index.js +2006 -0
  13. package/dist/legacy/compose.d.ts +2 -2
  14. package/dist/legacy/config.d.ts +86 -85
  15. package/dist/legacy/core.d.ts +12 -12
  16. package/dist/legacy/create.d.ts +2 -2
  17. package/dist/legacy/createCss.d.ts +2 -2
  18. package/dist/legacy/createParser.d.ts +2 -9
  19. package/dist/legacy/createStates.d.ts +2 -2
  20. package/dist/legacy/createTransform.d.ts +2 -2
  21. package/dist/legacy/createVariant.d.ts +2 -2
  22. package/dist/legacy/responsive.d.ts +14 -14
  23. package/dist/properties/getStylePropNames.d.ts +1 -1
  24. package/dist/properties/orderPropNames.d.ts +6 -6
  25. package/dist/properties/styledOptions.d.ts +20 -20
  26. package/dist/scales/createScale.d.ts +6 -3
  27. package/dist/scales/lookupScaleValue.d.ts +3 -3
  28. package/dist/styles/createParser.d.ts +2 -9
  29. package/dist/styles/createPropertyStyle.d.ts +4 -3
  30. package/dist/styles/createStylist.d.ts +2 -2
  31. package/dist/styles/responsive.d.ts +14 -14
  32. package/dist/transforms/border.d.ts +1 -1
  33. package/dist/transforms/grid.d.ts +4 -4
  34. package/dist/transforms/index.d.ts +4 -4
  35. package/dist/transforms/size.d.ts +2 -2
  36. package/dist/transforms/utils.d.ts +2 -1
  37. package/dist/types/config.d.ts +50 -44
  38. package/dist/types/properties.d.ts +23 -26
  39. package/dist/types/props.d.ts +34 -43
  40. package/dist/types/scales.d.ts +2 -2
  41. package/dist/types/shared.d.ts +4 -4
  42. package/dist/types/theme.d.ts +17 -17
  43. package/dist/types/utils.d.ts +4 -4
  44. package/jest.config.js +1 -0
  45. package/package.json +11 -9
  46. package/rollup.config.js +2 -2
  47. package/tsconfig.json +4 -2
  48. package/dist/index.cjs.js +0 -1
  49. package/dist/index.esm.js +0 -1
package/CLAUDE.md ADDED
@@ -0,0 +1,1240 @@
1
+ # CLAUDE.md - Animus Core Package
2
+
3
+ This file provides detailed guidance for working with the Animus core builder implementation.
4
+
5
+ ## Quick Philosophy Reminder for AI Agents
6
+
7
+ **This is optimal for us because:**
8
+ - Method order = semantic intent (styles=base, variants=choices, states=interactions, props=dynamics)
9
+ - Constraints guide us to correct patterns, not limit capabilities
10
+ - `extend()` provides full flexibility when needed
11
+ - One canonical path eliminates ambiguity
12
+
13
+ **Key Insight**: We're not limited in WHAT we can style, only guided in HOW we express styling intent. This transforms CSS from an open-ended problem to a solvable pattern-matching exercise.
14
+
15
+ ## Architecture Overview
16
+
17
+ The Animus builder implements a sophisticated type-safe fluent API pattern using TypeScript's class inheritance and type narrowing. The architecture enforces a specific method call order to mirror CSS cascade principles.
18
+
19
+ ## Builder Chain Architecture
20
+
21
+ ### Class Hierarchy
22
+ ```
23
+ AnimusConfig → Animus → AnimusWithBase → AnimusWithVariants → AnimusWithStates → AnimusWithSystem → AnimusWithAll
24
+ ```
25
+
26
+ Each class progressively narrows available methods:
27
+ - **AnimusConfig**: Entry point with `addGroup()` and `build()`
28
+ - **Animus**: Adds `styles()` method
29
+ - **AnimusWithBase**: Adds `variant()` method
30
+ - **AnimusWithVariants**: Adds `states()` and `variant()` methods
31
+ - **AnimusWithStates**: Adds `groups()` method
32
+ - **AnimusWithSystem**: Adds `props()` method
33
+ - **AnimusWithAll**: Terminal class with `asElement()`, `asComponent()`, `build()`, and `extend()`
34
+
35
+ ### Method Chain Enforcement
36
+
37
+ The builder enforces this cascade order:
38
+ 1. `.styles()` - Base styles (foundation layer)
39
+ 2. `.variant()` - Variant-based styles (can be called multiple times)
40
+ 3. `.states()` - Boolean state styles
41
+ 4. `.groups()` - Enable prop groups
42
+ 5. `.props()` - Custom props with scales
43
+ 6. `.asElement()` or `.asComponent()` - Terminal methods
44
+
45
+ This order mirrors CSS cascade specificity where later rules override earlier ones.
46
+
47
+ ### Extension Pattern
48
+
49
+ The `extend()` method is special - it returns an `AnimusExtended` instance that:
50
+ - Preserves all configuration from the parent
51
+ - Allows any builder method to be called in any order
52
+ - Merges configurations using lodash `merge()` to combine nested objects
53
+ - Maintains proper style execution order despite flexible API
54
+
55
+ ## Key Components
56
+
57
+ ### AnimusConfig (Entry Point)
58
+ Located in `AnimusConfig.ts`:
59
+ - Manages prop registry and group definitions
60
+ - `addGroup()`: Registers named groups of props
61
+ - `build()`: Creates the initial Animus instance
62
+
63
+ ### Animus Classes (Builder Chain)
64
+ Located in `Animus.ts`:
65
+ - Each class extends the previous, adding specific methods
66
+ - Uses TypeScript generics to track configuration state
67
+ - Methods return new instances of the next class in chain
68
+
69
+ ### AnimusExtended (Extension Handler)
70
+ Located in `AnimusExtended.ts`:
71
+ - Handles component extension with full method access
72
+ - Merges parent and child configurations
73
+ - Preserves cascade order during style execution
74
+
75
+ ### Style Processing
76
+
77
+ #### createStylist (Style Compiler)
78
+ Located in `styles/createStylist.ts`:
79
+ - Compiles all style layers into a single function
80
+ - Handles selector generation for variants and states
81
+ - Manages responsive breakpoint extraction
82
+ - Applies styles in correct cascade order:
83
+ 1. Base styles
84
+ 2. Variant styles (when active)
85
+ 3. State styles (when active)
86
+ 4. System props (from parser)
87
+ 5. Custom props
88
+
89
+ #### createParser (Prop Parser)
90
+ Located in `styles/createParser.ts`:
91
+ - Converts prop values to CSS using scale lookups
92
+ - Handles responsive prop arrays
93
+ - Manages prop-to-CSS property mapping
94
+
95
+ ## Type System
96
+
97
+ The builder uses extensive TypeScript generics to track:
98
+ - **PropRegistry**: All registered props and their types
99
+ - **GroupRegistry**: Named groups and their constituent props
100
+ - **BaseParser**: Parser configuration for system props
101
+ - **BaseStyles**: Base CSS styles
102
+ - **Variants**: Variant configurations with their options
103
+ - **States**: Boolean state configurations
104
+ - **ActiveGroups**: Currently enabled prop groups
105
+ - **CustomProps**: User-defined custom props
106
+
107
+ ## Style Execution Order
108
+
109
+ When a component renders, styles are applied in this order:
110
+ 1. CSS variables (from `vars` prop)
111
+ 2. Base styles from `.styles()`
112
+ 3. Active variant styles
113
+ 4. Active state styles
114
+ 5. System props (parsed from component props)
115
+ 6. Inline style overrides
116
+
117
+ ## Prop Forwarding
118
+
119
+ The builder automatically filters props:
120
+ - System props (in PropRegistry) are consumed and not forwarded
121
+ - Valid HTML attributes are forwarded (using @emotion/is-prop-valid)
122
+ - Custom props are consumed based on configuration
123
+
124
+ ## Best Practices
125
+
126
+ 1. **Define base styles first** - Use `.styles()` for foundational styles
127
+ 2. **Use variants for design options** - Color schemes, sizes, etc.
128
+ 3. **Use states for interactive states** - Hover, focus, disabled, etc.
129
+ 4. **Group related props** - Use `.groups()` to enable sets of props
130
+ 5. **Extend for variations** - Use `.extend()` to create component variants
131
+
132
+ ## Common Patterns
133
+
134
+ ### Basic Component
135
+ ```typescript
136
+ const Button = animus
137
+ .styles({
138
+ padding: '8px 16px',
139
+ borderRadius: '4px'
140
+ })
141
+ .asElement('button');
142
+ ```
143
+
144
+ ### Component with Variants
145
+ ```typescript
146
+ const Button = animus
147
+ .styles({ base: '...' })
148
+ .variant({
149
+ prop: 'size',
150
+ variants: {
151
+ small: { padding: '4px 8px' },
152
+ large: { padding: '12px 24px' }
153
+ }
154
+ })
155
+ .asElement('button');
156
+ ```
157
+
158
+ ### Extended Component
159
+ ```typescript
160
+ const PrimaryButton = Button.extend()
161
+ .styles({
162
+ backgroundColor: 'blue',
163
+ color: 'white'
164
+ })
165
+ .asElement('button');
166
+ ```
167
+
168
+ ## Debugging Tips
169
+
170
+ 1. **Check method order** - Ensure builder methods are called in correct sequence
171
+ 2. **Inspect built styles** - Use `.build()` to see the compiled style function
172
+ 3. **Verify prop filtering** - Check `shouldForwardProp` logic
173
+ 4. **Trace style cascade** - Follow execution through createStylist
174
+ 5. **Type errors** - Usually indicate incorrect method order or invalid configurations
175
+
176
+ ## New Insights from Real-World Usage
177
+
178
+ Based on analyzing actual implementations across the codebase:
179
+
180
+ ### 1. Gradient Token System
181
+ The codebase uses semantic gradient tokens like `gradient: 'flowX'` that map to complex gradient definitions. This suggests a sophisticated token system beyond simple color values.
182
+
183
+ ### 2. Grid Area Shorthand
184
+ Components use `area: 'sidebar'` as shorthand for `gridArea: 'sidebar'`, indicating custom CSS property mappings in the prop system.
185
+
186
+ ### 3. Layered Component Architecture
187
+ Complex components like Button separate visual layers (container vs foreground) rather than combining all styles in one component. This pattern enables:
188
+ - Independent animation of layers
189
+ - Better performance (transforms on specific layers)
190
+ - Cleaner separation of concerns
191
+
192
+ ### 4. Responsive Grid Templates
193
+ The Layout component shows responsive grid template areas:
194
+ ```tsx
195
+ gridTemplateAreas: {
196
+ _: '"header header" "content content"',
197
+ sm: '"header header" "sidebar content"',
198
+ }
199
+ ```
200
+
201
+ ### 5. CSS Custom Scrollbar Hiding
202
+ Components use webkit-specific scrollbar hiding:
203
+ ```tsx
204
+ '::-webkit-scrollbar': {
205
+ display: 'none',
206
+ }
207
+ ```
208
+
209
+ ### 6. Position-Based Responsive Patterns
210
+ Components change positioning strategy based on viewport:
211
+ ```tsx
212
+ position: {
213
+ _: 'absolute',
214
+ sm: 'static',
215
+ }
216
+ ```
217
+
218
+ ### 7. Size Shorthands
219
+ The codebase uses numeric shorthands like `width: 1` (likely 100%), `size: 1`, `inset: 0`, suggesting a normalized prop value system.
220
+
221
+ ## Open Questions from Analysis
222
+
223
+ 1. **Gradient Token Architecture**: How are gradient tokens like 'flowX' defined and resolved? Are they CSS variables or JS objects?
224
+
225
+ 2. **Numeric Value System**: What's the complete mapping for numeric values (0, 1, 0.5)? How do they translate to CSS?
226
+
227
+ 3. **Custom Prop Mappings**: Beyond 'area' for 'gridArea', what other CSS property shorthands exist?
228
+
229
+ 4. **Animation Integration**: How does the `import { flow } from '../animations/flow'` pattern work with Emotion keyframes?
230
+
231
+ 5. **Theme Token Categories**: What are all the semantic token categories (text-shadow: 'flush', 'link-raised')?
232
+
233
+ 6. **Performance of Pseudo-Elements**: Given heavy use of :before/:after for effects, are there performance benchmarks?
234
+
235
+ 7. **TypeScript Compound Pattern**: Is the Layout compound component TypeScript pattern the recommended approach?
236
+
237
+ 8. **Group Selection Strategy**: What determines which groups to enable for each component type?
238
+
239
+ 9. **Variant vs State Decision**: When should something be a variant vs a state? The pattern isn't always clear.
240
+
241
+ 10. **Build Tool Integration**: How do production builds optimize these complex styled components?
242
+
243
+ ## Practical Patterns & Examples
244
+
245
+ This section provides answers to common implementation questions for AI agents.
246
+
247
+ ### Responsive Design
248
+ *Documentation coming soon - how arrays work, breakpoint system*
249
+ Array responsive syntax works for specificing values mobile first, from no breakpoint to the highest breakpoint configured in the theme. Omitted sequential values in the array are ignored (only if undefined).
250
+
251
+ The object syntax is equivalent but uses named keys for the sequence. Please see the example:
252
+
253
+ ```tsx
254
+ // Object syntax
255
+ animus.styles({ width: { _: '100px', xs: '200px', md: '300px' }})
256
+ // Equivalent Array Syntax
257
+ animus.styles({ width: ['100px', '200px', , '300px' ]});
258
+ ```
259
+
260
+ Responsive syntax is available definitionally in `.styles()`, `.variant()` and `.states()` for example:
261
+ ```tsx
262
+ animus
263
+ .variant({
264
+ prop: 'size',
265
+ variants: {
266
+ large: { padding: ['1rem', '2rem'] } // Is this valid?
267
+ }
268
+ })
269
+ ```
270
+
271
+ And for `groups()` and custom `props()` they are available in the final prop API as valid syntax E.G:
272
+
273
+ ```tsx
274
+ const Box = animus.groups({ space: true }).asElement('div');
275
+
276
+ <Box p={['1rem', '2rem', '3rem']} />
277
+ ```
278
+
279
+ ### Theming Integration
280
+
281
+ The Animus builder integrates seamlessly with themes provided via Emotion's ThemeProvider. When using ThemeBuilder from `@animus-ui/theming`, the integration works as follows:
282
+
283
+ #### Theme Value Resolution
284
+
285
+ Props can reference theme scales using the `scale` property in prop definitions:
286
+
287
+ ```typescript
288
+ animus
289
+ .props({
290
+ bg: {
291
+ property: 'backgroundColor',
292
+ scale: 'colors' // References theme.colors scale
293
+ }
294
+ })
295
+ .asElement('div');
296
+
297
+ // Usage: <Box bg="primary" /> resolves to theme.colors.primary
298
+ ```
299
+
300
+ #### Design Token Flow
301
+
302
+ 1. **ThemeBuilder creates CSS variables**:
303
+ ```typescript
304
+ const theme = createTheme(baseTheme)
305
+ .addColors({ primary: '#007bff' })
306
+ .build();
307
+ // Creates: theme.colors.primary = 'var(--colors-primary)'
308
+ ```
309
+
310
+ 2. **Animus resolves theme values**:
311
+ ```typescript
312
+ // When bg="primary" is used:
313
+ // lookupScaleValue('primary', 'colors', theme) → 'var(--colors-primary)'
314
+ ```
315
+
316
+ 3. **CSS variables must be injected**:
317
+ ```typescript
318
+ import { Global } from '@emotion/react';
319
+
320
+ const GlobalStyles = () => {
321
+ const theme = useTheme();
322
+ return (
323
+ <Global styles={{
324
+ ':root': theme._variables.root
325
+ }} />
326
+ );
327
+ };
328
+ ```
329
+
330
+ #### Type Safety with Themes
331
+
332
+ For proper TypeScript support, extend Emotion's theme interface:
333
+
334
+ ```typescript
335
+ declare module '@emotion/react' {
336
+ export interface Theme extends MyThemeType {}
337
+ }
338
+ ```
339
+
340
+ #### Theme Scales Available
341
+
342
+ Common scales that work with Animus props:
343
+ - `colors` - Color values
344
+ - `space` - Spacing/margin/padding values
345
+ - `fontSizes` - Typography sizes
346
+ - `fonts` - Font families
347
+ - `lineHeights` - Line height values
348
+ - `letterSpacings` - Letter spacing values
349
+ - `sizes` - Width/height values
350
+ - `borders` - Border styles
351
+ - `borderWidths` - Border width values
352
+ - `borderStyles` - Border style values
353
+ - `radii` - Border radius values
354
+ - `shadows` - Box shadow values
355
+ - `zIndices` - Z-index values
356
+ - `transitions` - Transition values
357
+
358
+ ### Complex Selectors
359
+ *Documentation coming soon - pseudo-selectors, nested selectors placement*
360
+ Pseudo selectors and nested selectors are available for `.styles()`, `.variant()` and `.states()` as they all represent a set of CSS rules rather than indivdiual utilities.
361
+
362
+ ```tsx
363
+ const HoverableItem = animus
364
+ .styles({
365
+ backgroundColor: 'white',
366
+ '&:hover': {
367
+ backgroundColor: 'grey',
368
+ }
369
+ })
370
+ .variant({
371
+ prop: 'intent',
372
+ variants: {
373
+ primary: {
374
+ backgroundColor: 'blue',
375
+ color: 'white',
376
+ '&:hover': {
377
+ backgroundColor: 'darkblue',
378
+ }
379
+ },
380
+ danger: {
381
+ backgroundColor: 'red',
382
+ color: 'white',
383
+ '&:hover': {
384
+ backgroundColor: 'darkred',
385
+ }
386
+ },
387
+ }
388
+ })
389
+ .states({
390
+ disabled: {
391
+ backgroundColor: 'grey',
392
+ opacity: 0.8,
393
+ '&:hover': {
394
+ cursor: 'not-allowed',
395
+ backgroundColor: 'grey',
396
+ }
397
+ }
398
+ })
399
+ ```
400
+
401
+ This also applies to complex or multiple selectors and or pseudo elements like - however may not include escaping the current context with `.parent + &`:
402
+ ```tsx
403
+ const ComplexThing = animus
404
+ .styles({
405
+ '&:before': {
406
+ content: '""',
407
+ position: 'absolute',
408
+ borderRadius: 4,
409
+ gradient: 'flowX',
410
+ backgroundSize: '300px 100px',
411
+ backgroundPosition: '0px 0%',
412
+ transition: 'bg',
413
+ inset: 0,
414
+ bg: 'background-current',
415
+ zIndex: 0,
416
+ },
417
+ '&:after': {
418
+ content: '""',
419
+ inset: 2,
420
+ borderRadius: 2,
421
+ bg: 'background-current',
422
+ zIndex: 0,
423
+ position: 'absolute',
424
+ },
425
+ '&:hover:before': {
426
+ backgroundPosition: '-100px 0%',
427
+ },
428
+ '&:active:hover:before': {
429
+ backgroundPosition: '-400px 0%',
430
+ },
431
+ });
432
+ ```
433
+
434
+ Chain definition order reflects the order of evaluation:
435
+ 1. `styles`
436
+ 2. `variant` preserving the order in which variants are registered if this is called multiple times.
437
+ 3. `states`
438
+ 4. `groups`
439
+ 5. `props`
440
+
441
+ When extending a component using `.extend()` you can inject new styles to specific layers without effecting the prop cascade!
442
+
443
+
444
+
445
+ ### Animation Patterns
446
+
447
+ Animations in Animus follow the same cascade principles as other styles. Here's where each type of animation belongs:
448
+
449
+ #### Base Animations (in `.styles()`)
450
+
451
+ For animations that are fundamental to the component:
452
+
453
+ ```typescript
454
+ const FadeIn = animus
455
+ .styles({
456
+ animation: 'fadeIn 0.3s ease-in-out',
457
+ '@keyframes fadeIn': {
458
+ from: { opacity: 0 },
459
+ to: { opacity: 1 }
460
+ }
461
+ })
462
+ .asElement('div');
463
+ ```
464
+
465
+ #### Variant-Based Animations (in `.variant()`)
466
+
467
+ For animations that change based on component variations:
468
+
469
+ ```typescript
470
+ const Alert = animus
471
+ .styles({
472
+ padding: '1rem',
473
+ borderRadius: '4px'
474
+ })
475
+ .variant({
476
+ prop: 'type',
477
+ variants: {
478
+ success: {
479
+ backgroundColor: 'green.100',
480
+ animation: 'slideInLeft 0.3s ease-out'
481
+ },
482
+ error: {
483
+ backgroundColor: 'red.100',
484
+ animation: 'shake 0.5s ease-in-out'
485
+ }
486
+ }
487
+ })
488
+ .asElement('div');
489
+ ```
490
+
491
+ #### State-Based Animations (in `.states()`)
492
+
493
+ For animations triggered by interactive states:
494
+
495
+ ```typescript
496
+ const Button = animus
497
+ .styles({
498
+ transition: 'all 0.2s ease'
499
+ })
500
+ .states({
501
+ loading: {
502
+ position: 'relative',
503
+ color: 'transparent',
504
+ '&::after': {
505
+ content: '""',
506
+ position: 'absolute',
507
+ width: '16px',
508
+ height: '16px',
509
+ top: '50%',
510
+ left: '50%',
511
+ margin: '-8px 0 0 -8px',
512
+ border: '2px solid',
513
+ borderColor: 'currentColor',
514
+ borderRadius: '50%',
515
+ borderTopColor: 'transparent',
516
+ animation: 'spin 0.6s linear infinite'
517
+ }
518
+ }
519
+ })
520
+ .asElement('button');
521
+ ```
522
+
523
+ #### CSS Transition Integration
524
+
525
+ For smooth property transitions, define them in base styles:
526
+
527
+ ```typescript
528
+ const Card = animus
529
+ .styles({
530
+ backgroundColor: 'white',
531
+ transform: 'translateY(0)',
532
+ transition: 'transform 0.2s ease, box-shadow 0.2s ease',
533
+ '&:hover': {
534
+ transform: 'translateY(-4px)',
535
+ boxShadow: 'lg'
536
+ }
537
+ })
538
+ .asElement('div');
539
+ ```
540
+
541
+ #### Complex Animation Sequences
542
+
543
+ For multi-step animations, use keyframes in the appropriate layer:
544
+
545
+ ```typescript
546
+ const LoadingDots = animus
547
+ .styles({
548
+ display: 'inline-flex',
549
+ gap: '4px',
550
+ '& span': {
551
+ width: '8px',
552
+ height: '8px',
553
+ borderRadius: '50%',
554
+ backgroundColor: 'currentColor',
555
+ animation: 'bounce 1.4s ease-in-out infinite both'
556
+ },
557
+ '& span:nth-of-type(1)': {
558
+ animationDelay: '-0.32s'
559
+ },
560
+ '& span:nth-of-type(2)': {
561
+ animationDelay: '-0.16s'
562
+ },
563
+ '@keyframes bounce': {
564
+ '0%, 80%, 100%': {
565
+ transform: 'scale(0)'
566
+ },
567
+ '40%': {
568
+ transform: 'scale(1)'
569
+ }
570
+ }
571
+ })
572
+ .asElement('div');
573
+ ```
574
+
575
+ #### Animation Best Practices
576
+
577
+ 1. **Performance**: Use `transform` and `opacity` for best performance
578
+ 2. **Accessibility**: Respect `prefers-reduced-motion`:
579
+ ```typescript
580
+ .styles({
581
+ '@media (prefers-reduced-motion: reduce)': {
582
+ animation: 'none',
583
+ transition: 'none'
584
+ }
585
+ })
586
+ ```
587
+ 3. **Duration**: Keep animations short (200-400ms for micro-interactions)
588
+ 4. **Easing**: Use appropriate easing functions:
589
+ - `ease-out` for enter animations
590
+ - `ease-in` for exit animations
591
+ - `ease-in-out` for state changes
592
+
593
+ ### Compound Components
594
+
595
+ Compound components are a powerful pattern for creating related components that work together. Here's the recommended approach based on real-world usage:
596
+
597
+ #### Basic Pattern
598
+
599
+ ```tsx
600
+ const Card = animus
601
+ .styles({
602
+ padding: '1rem',
603
+ backgroundColor: 'grey',
604
+ border: 1,
605
+ })
606
+ .asElement('div');
607
+
608
+ const CardHeader = animus
609
+ .styles({
610
+ fontSize: 18,
611
+ fontWeight: 500
612
+ })
613
+ .asElement('h2');
614
+
615
+ const CardBody = animus
616
+ .styles({
617
+ padding: '1rem',
618
+ fontSize: 14,
619
+ })
620
+ .asElement('div');
621
+
622
+ Card.Header = CardHeader;
623
+ Card.Body = CardBody;
624
+
625
+ export default Card;
626
+ ```
627
+
628
+ #### Advanced Pattern with TypeScript (from Layout.tsx)
629
+
630
+ ```tsx
631
+ // Define individual components
632
+ const LayoutContainer = animus
633
+ .styles({
634
+ display: 'grid',
635
+ gridTemplateAreas: '"header header" "sidebar content"',
636
+ })
637
+ .states({
638
+ sidebar: {
639
+ gridTemplateAreas: {
640
+ _: '"header header" "content content"',
641
+ sm: '"header header" "sidebar content"',
642
+ }
643
+ }
644
+ })
645
+ .asElement('div');
646
+
647
+ const HeaderContainer = animus
648
+ .styles({ area: 'header' })
649
+ .asElement('div');
650
+
651
+ const SidebarContainer = animus
652
+ .styles({ area: 'sidebar' })
653
+ .asElement('div');
654
+
655
+ // Create compound type
656
+ type LayoutContainer = typeof LayoutContainer;
657
+
658
+ export interface Layout extends LayoutContainer {
659
+ Header: typeof HeaderContainer;
660
+ Sidebar: typeof SidebarContainer;
661
+ }
662
+
663
+ // Export with sub-components attached
664
+ export const Layout = LayoutContainer as Layout;
665
+ Layout.Header = HeaderContainer;
666
+ Layout.Sidebar = SidebarContainer;
667
+
668
+ // Usage
669
+ <Layout sidebar>
670
+ <Layout.Header>...</Layout.Header>
671
+ <Layout.Sidebar>...</Layout.Sidebar>
672
+ </Layout>
673
+ ```
674
+
675
+ This pattern provides:
676
+ - Type-safe compound components
677
+ - Clear parent-child relationships
678
+ - Cohesive API for related components
679
+
680
+ ### Global Styles & Resets
681
+ *Documentation coming soon - app-wide styles approach*
682
+
683
+ ### Performance Considerations
684
+
685
+ Based on real-world usage patterns, here are key performance optimizations:
686
+
687
+ #### 1. Avoid Excessive Pseudo-Elements
688
+
689
+ While powerful, overuse of `:before` and `:after` can impact performance:
690
+
691
+ ```tsx
692
+ // ❌ Avoid: Multiple layers of pseudo-elements
693
+ .styles({
694
+ '&:before': { /* gradient layer */ },
695
+ '&:after': { /* shadow layer */ },
696
+ '& > div:before': { /* more effects */ },
697
+ '& > div:after': { /* even more */ }
698
+ })
699
+
700
+ // ✅ Better: Use actual elements when needed
701
+ const Container = animus.styles({...}).asElement('div');
702
+ const GradientLayer = animus.styles({...}).asElement('div');
703
+ const ContentLayer = animus.styles({...}).asElement('div');
704
+ ```
705
+
706
+ #### 2. Optimize Gradient Animations
707
+
708
+ Gradient animations can be expensive. Use transform instead:
709
+
710
+ ```tsx
711
+ // ❌ Avoid: Animating background-position continuously
712
+ .styles({
713
+ animation: 'flow 5s linear infinite',
714
+ '@keyframes flow': {
715
+ '0%': { backgroundPosition: '0% 0%' },
716
+ '100%': { backgroundPosition: '100% 0%' }
717
+ }
718
+ })
719
+
720
+ // ✅ Better: Use transform for smoother performance
721
+ .styles({
722
+ '&:before': {
723
+ content: '""',
724
+ position: 'absolute',
725
+ inset: 0,
726
+ background: 'gradient',
727
+ transform: 'translateX(0)',
728
+ transition: 'transform 0.3s ease',
729
+ },
730
+ '&:hover:before': {
731
+ transform: 'translateX(-100px)',
732
+ }
733
+ })
734
+ ```
735
+
736
+ #### 3. Group-Based Code Splitting
737
+
738
+ Enable only the groups you need to reduce bundle size:
739
+
740
+ ```tsx
741
+ // ❌ Avoid: Enabling all groups
742
+ .groups({
743
+ layout: true,
744
+ space: true,
745
+ color: true,
746
+ typography: true,
747
+ borders: true,
748
+ shadows: true,
749
+ positioning: true,
750
+ background: true,
751
+ flex: true,
752
+ grid: true
753
+ })
754
+
755
+ // ✅ Better: Enable only what's needed
756
+ .groups({
757
+ layout: true,
758
+ space: true,
759
+ color: true
760
+ })
761
+ ```
762
+
763
+ #### 4. Responsive Value Optimization
764
+
765
+ Use responsive values judiciously:
766
+
767
+ ```tsx
768
+ // ❌ Avoid: Responsive values for every property
769
+ .styles({
770
+ padding: { _: 8, xs: 12, sm: 16, md: 20, lg: 24, xl: 32 },
771
+ margin: { _: 4, xs: 6, sm: 8, md: 10, lg: 12, xl: 16 },
772
+ fontSize: { _: 14, xs: 15, sm: 16, md: 17, lg: 18, xl: 20 },
773
+ })
774
+
775
+ // ✅ Better: Use responsive values for key breakpoints
776
+ .styles({
777
+ padding: { _: 8, sm: 16, lg: 24 },
778
+ margin: 8,
779
+ fontSize: { _: 14, sm: 16 }
780
+ })
781
+ ```
782
+
783
+ #### 5. Component Composition vs. Complex Styles
784
+
785
+ Break complex components into simpler pieces:
786
+
787
+ ```tsx
788
+ // ❌ Avoid: One component with many variants and states
789
+ const Button = animus
790
+ .styles({ /* 50+ lines of base styles */ })
791
+ .variant({ /* 10 variants */ })
792
+ .states({ /* 8 states */ })
793
+ .asElement('button');
794
+
795
+ // ✅ Better: Compose from simpler components
796
+ const BaseButton = animus.styles({...}).asElement('button');
797
+ const IconButton = BaseButton.extend().styles({...}).asElement('button');
798
+ const LoadingButton = BaseButton.extend().states({...}).asElement('button');
799
+ ```
800
+
801
+ #### 6. Memoize Complex Components
802
+
803
+ For components with expensive render logic:
804
+
805
+ ```tsx
806
+ import { memo } from 'react';
807
+
808
+ const ExpensiveComponent = memo(
809
+ animus
810
+ .styles({ /* complex styles */ })
811
+ .asComponent(({ children, ...props }) => {
812
+ // Complex render logic
813
+ return <div {...props}>{children}</div>;
814
+ })
815
+ );
816
+ ```
817
+
818
+ #### 7. CSS Variable Performance
819
+
820
+ When using ThemeBuilder, minimize CSS variable lookups:
821
+
822
+ ```tsx
823
+ // ❌ Avoid: Many individual variable references
824
+ .styles({
825
+ color: 'var(--colors-text)',
826
+ backgroundColor: 'var(--colors-background)',
827
+ borderColor: 'var(--colors-border)',
828
+ // ... many more
829
+ })
830
+
831
+ // ✅ Better: Use semantic tokens that group related values
832
+ .styles({
833
+ color: 'text',
834
+ bg: 'background',
835
+ borderColor: 'border',
836
+ })
837
+ ```
838
+
839
+ #### 8. Build-Time Optimizations
840
+
841
+ - Use production builds to eliminate development warnings
842
+ - Enable CSS extraction in your bundler when possible
843
+ - Consider using `babel-plugin-emotion` for build-time optimizations
844
+ - Tree-shake unused Animus groups and features
845
+
846
+ #### Key Metrics to Monitor
847
+
848
+ 1. **Bundle Size**: Track the size of your styled components
849
+ 2. **Runtime Performance**: Monitor style recalculation in DevTools
850
+ 3. **Memory Usage**: Watch for memory leaks from dynamic styles
851
+ 4. **Initial Load**: Measure time to first meaningful paint
852
+
853
+ ### Complete Component Examples
854
+ *Documentation coming soon - comprehensive examples with all features*
855
+
856
+ ### Common UI Patterns
857
+
858
+ Based on real-world usage analysis, here are common patterns for building UI components with Animus:
859
+
860
+ #### Layered Visual Effects (Button Pattern)
861
+
862
+ Create rich visual effects by separating container and content:
863
+
864
+ ```tsx
865
+ // Container handles background effects
866
+ const ButtonContainer = animus
867
+ .styles({
868
+ position: 'relative',
869
+ overflow: 'hidden',
870
+ })
871
+ .variant({
872
+ prop: 'variant',
873
+ variants: {
874
+ fill: {
875
+ '&:before': {
876
+ content: '""',
877
+ position: 'absolute',
878
+ inset: 0,
879
+ gradient: 'flowX',
880
+ backgroundSize: '300px 100%',
881
+ transition: 'background-position 0.3s ease',
882
+ },
883
+ '&:hover:before': {
884
+ backgroundPosition: '-100px 0%',
885
+ }
886
+ },
887
+ stroke: {
888
+ '&:before': {
889
+ content: '""',
890
+ position: 'absolute',
891
+ inset: 0,
892
+ gradient: 'flowX',
893
+ zIndex: 0,
894
+ },
895
+ '&:after': {
896
+ content: '""',
897
+ position: 'absolute',
898
+ inset: 2,
899
+ bg: 'background-current',
900
+ zIndex: 0,
901
+ }
902
+ }
903
+ }
904
+ })
905
+ .asElement('button');
906
+
907
+ // Foreground handles text/content
908
+ const ButtonForeground = animus
909
+ .styles({
910
+ position: 'relative',
911
+ zIndex: 1,
912
+ })
913
+ .variant({
914
+ prop: 'size',
915
+ variants: {
916
+ sm: { px: 12, py: 6, fontSize: 14 },
917
+ md: { px: 16, py: 8, fontSize: 16 },
918
+ lg: { px: 20, py: 10, fontSize: 18 }
919
+ }
920
+ })
921
+ .asElement('span');
922
+ ```
923
+
924
+ #### Grid Layout with Named Areas
925
+
926
+ Use CSS Grid with named template areas for complex layouts:
927
+
928
+ ```tsx
929
+ const Layout = animus
930
+ .styles({
931
+ display: 'grid',
932
+ gridTemplateAreas: '"header header" "sidebar content"',
933
+ gridTemplateColumns: '15rem 1fr',
934
+ gridTemplateRows: 'auto 1fr',
935
+ })
936
+ .states({
937
+ collapsed: {
938
+ gridTemplateAreas: '"header" "content"',
939
+ gridTemplateColumns: '1fr',
940
+ }
941
+ })
942
+ .asElement('div');
943
+
944
+ // Child components reference grid areas
945
+ const Sidebar = animus
946
+ .styles({
947
+ gridArea: 'sidebar',
948
+ // or using Animus shorthand:
949
+ area: 'sidebar'
950
+ })
951
+ .asElement('aside');
952
+ ```
953
+
954
+ #### Gradient Text Effects
955
+
956
+ Create gradient text using background clip:
957
+
958
+ ```tsx
959
+ const GradientText = animus
960
+ .styles({
961
+ gradient: 'primary',
962
+ backgroundClip: 'text',
963
+ WebkitBackgroundClip: 'text',
964
+ WebkitTextFillColor: 'transparent',
965
+ })
966
+ .asElement('span');
967
+ ```
968
+
969
+ #### Responsive Sticky Positioning
970
+
971
+ Combine responsive values with position states:
972
+
973
+ ```tsx
974
+ const Navigation = animus
975
+ .styles({
976
+ position: {
977
+ _: 'fixed',
978
+ sm: 'sticky'
979
+ },
980
+ top: 0,
981
+ zIndex: 10,
982
+ })
983
+ .asElement('nav');
984
+ ```
985
+
986
+ #### State-Based Component Switching
987
+
988
+ Use states for component behavior changes:
989
+
990
+ ```tsx
991
+ const Modal = animus
992
+ .styles({
993
+ position: 'fixed',
994
+ inset: 0,
995
+ display: 'flex',
996
+ alignItems: 'center',
997
+ justifyContent: 'center',
998
+ opacity: 0,
999
+ pointerEvents: 'none',
1000
+ transition: 'opacity 0.2s ease',
1001
+ })
1002
+ .states({
1003
+ open: {
1004
+ opacity: 1,
1005
+ pointerEvents: 'auto',
1006
+ }
1007
+ })
1008
+ .asElement('div');
1009
+ ```
1010
+
1011
+ #### Polymorphic Components
1012
+
1013
+ Use variants with 'as' prop for semantic flexibility:
1014
+
1015
+ ```tsx
1016
+ const Text = animus
1017
+ .variant({
1018
+ prop: 'as',
1019
+ variants: {
1020
+ h1: { fontSize: 32, lineHeight: 1.2, fontWeight: 700 },
1021
+ h2: { fontSize: 24, lineHeight: 1.3, fontWeight: 600 },
1022
+ p: { fontSize: 16, lineHeight: 1.5, fontWeight: 400 },
1023
+ small: { fontSize: 14, lineHeight: 1.4, fontWeight: 400 },
1024
+ }
1025
+ })
1026
+ .asElement('p');
1027
+
1028
+ // Usage: <Text as="h1">Heading</Text>
1029
+ ```
1030
+
1031
+ #### Minimal Wrapper Pattern
1032
+
1033
+ Sometimes it's better to wrap existing components than create new ones:
1034
+
1035
+ ```tsx
1036
+ export const Code = (props: ComponentProps<typeof Box>) => (
1037
+ <Box
1038
+ as="code"
1039
+ color="primary"
1040
+ fontFamily="mono"
1041
+ fontSize={14}
1042
+ {...props}
1043
+ />
1044
+ );
1045
+ ```
1046
+
1047
+ ### Design System Integration
1048
+
1049
+ #### Token Integration with ThemeBuilder
1050
+
1051
+ When building a design system with Animus and ThemeBuilder, follow this pattern:
1052
+
1053
+ 1. **Define Design Tokens**:
1054
+ ```typescript
1055
+ // tokens.ts
1056
+ export const tokens = {
1057
+ colors: {
1058
+ brand: {
1059
+ primary: '#007bff',
1060
+ secondary: '#6c757d'
1061
+ },
1062
+ semantic: {
1063
+ success: '#28a745',
1064
+ danger: '#dc3545'
1065
+ }
1066
+ },
1067
+ space: {
1068
+ xs: '0.25rem',
1069
+ sm: '0.5rem',
1070
+ md: '1rem',
1071
+ lg: '2rem',
1072
+ xl: '4rem'
1073
+ }
1074
+ };
1075
+ ```
1076
+
1077
+ 2. **Build Theme with CSS Variables**:
1078
+ ```typescript
1079
+ // theme.ts
1080
+ import { createTheme } from '@animus-ui/theming';
1081
+
1082
+ export const theme = createTheme(baseTheme)
1083
+ .addColors(tokens.colors)
1084
+ .createScaleVariables('space')
1085
+ .addColorModes('light', {
1086
+ light: {
1087
+ bg: 'white',
1088
+ text: 'brand.primary'
1089
+ },
1090
+ dark: {
1091
+ bg: 'brand.primary',
1092
+ text: 'white'
1093
+ }
1094
+ })
1095
+ .build();
1096
+ ```
1097
+
1098
+ 3. **Create Design System Components**:
1099
+ ```typescript
1100
+ // Button.ts
1101
+ export const Button = animus
1102
+ .styles({
1103
+ cursor: 'pointer',
1104
+ fontFamily: 'body',
1105
+ transition: 'all 0.2s'
1106
+ })
1107
+ .variant({
1108
+ prop: 'variant',
1109
+ variants: {
1110
+ primary: {
1111
+ bg: 'brand.primary',
1112
+ color: 'white',
1113
+ '&:hover': {
1114
+ bg: 'brand.secondary'
1115
+ }
1116
+ },
1117
+ outline: {
1118
+ bg: 'transparent',
1119
+ borderWidth: '2px',
1120
+ borderStyle: 'solid',
1121
+ borderColor: 'brand.primary',
1122
+ color: 'brand.primary'
1123
+ }
1124
+ }
1125
+ })
1126
+ .variant({
1127
+ prop: 'size',
1128
+ variants: {
1129
+ sm: { px: 'sm', py: 'xs', fontSize: 'sm' },
1130
+ md: { px: 'md', py: 'sm', fontSize: 'base' },
1131
+ lg: { px: 'lg', py: 'md', fontSize: 'lg' }
1132
+ }
1133
+ })
1134
+ .states({
1135
+ disabled: {
1136
+ opacity: 0.6,
1137
+ cursor: 'not-allowed'
1138
+ }
1139
+ })
1140
+ .groups({ space: true })
1141
+ .asElement('button');
1142
+ ```
1143
+
1144
+ #### Migration Patterns
1145
+
1146
+ ##### From CSS/SCSS to Animus
1147
+
1148
+ ```scss
1149
+ // Before (SCSS)
1150
+ .button {
1151
+ padding: 8px 16px;
1152
+ border-radius: 4px;
1153
+
1154
+ &--primary {
1155
+ background: blue;
1156
+ color: white;
1157
+ }
1158
+
1159
+ &:disabled {
1160
+ opacity: 0.6;
1161
+ }
1162
+ }
1163
+ ```
1164
+
1165
+ ```typescript
1166
+ // After (Animus)
1167
+ const Button = animus
1168
+ .styles({
1169
+ padding: '8px 16px',
1170
+ borderRadius: '4px'
1171
+ })
1172
+ .variant({
1173
+ prop: 'variant',
1174
+ variants: {
1175
+ primary: {
1176
+ background: 'blue',
1177
+ color: 'white'
1178
+ }
1179
+ }
1180
+ })
1181
+ .states({
1182
+ disabled: {
1183
+ opacity: 0.6
1184
+ }
1185
+ })
1186
+ .asElement('button');
1187
+ ```
1188
+
1189
+ ##### From Styled Components to Animus
1190
+
1191
+ ```typescript
1192
+ // Before (styled-components)
1193
+ const Button = styled.button<{ variant?: 'primary' | 'secondary' }>`
1194
+ padding: ${props => props.theme.space[2]} ${props => props.theme.space[4]};
1195
+ background: ${props => props.variant === 'primary' ? props.theme.colors.primary : props.theme.colors.secondary};
1196
+ `;
1197
+ ```
1198
+
1199
+ ```typescript
1200
+ // After (Animus)
1201
+ const Button = animus
1202
+ .styles({
1203
+ px: 4, // Uses theme.space scale
1204
+ py: 2
1205
+ })
1206
+ .variant({
1207
+ prop: 'variant',
1208
+ variants: {
1209
+ primary: { bg: 'primary' },
1210
+ secondary: { bg: 'secondary' }
1211
+ }
1212
+ })
1213
+ .asElement('button');
1214
+ ```
1215
+
1216
+ #### Best Practices for Design Systems
1217
+
1218
+ 1. **Use Semantic Token Names**: Instead of `blue-500`, use `brand.primary`
1219
+ 2. **Leverage Color Modes**: Define semantic aliases that change with modes
1220
+ 3. **Component Composition**: Build complex components from simple ones
1221
+ 4. **Consistent Prop APIs**: Use the same variant names across components
1222
+ 5. **Document Token Usage**: Create a token reference guide for designers
1223
+
1224
+ #### Token Reference Architecture
1225
+
1226
+ ```typescript
1227
+ // Create a centralized token reference
1228
+ export const designSystem = {
1229
+ components: {
1230
+ Button,
1231
+ Card,
1232
+ Input
1233
+ },
1234
+ tokens: theme._tokens, // Original token values
1235
+ scales: {
1236
+ colors: theme.colors,
1237
+ space: theme.space,
1238
+ // ... other scales
1239
+ }
1240
+ };