@animus-ui/core 0.2.0-beta.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.
package/CLAUDE.md CHANGED
@@ -173,6 +173,73 @@ const PrimaryButton = Button.extend()
173
173
  4. **Trace style cascade** - Follow execution through createStylist
174
174
  5. **Type errors** - Usually indicate incorrect method order or invalid configurations
175
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
+
176
243
  ## Practical Patterns & Examples
177
244
 
178
245
  This section provides answers to common implementation questions for AI agents.
@@ -210,7 +277,83 @@ const Box = animus.groups({ space: true }).asElement('div');
210
277
  ```
211
278
 
212
279
  ### Theming Integration
213
- *Documentation coming soon - design tokens, theme values, typing*
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
214
357
 
215
358
  ### Complex Selectors
216
359
  *Documentation coming soon - pseudo-selectors, nested selectors placement*
@@ -300,12 +443,158 @@ When extending a component using `.extend()` you can inject new styles to specif
300
443
 
301
444
 
302
445
  ### Animation Patterns
303
- *Documentation coming soon - where animations belong in the cascade*
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
304
592
 
305
593
  ### Compound Components
306
- *Documentation coming soon - Card.Header, Card.Body patterns*
307
594
 
308
- Compound composition is up to the user - a Compound component can befined as aliases of local components to indicate they are intended to be used together:
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
309
598
 
310
599
  ```tsx
311
600
  const Card = animus
@@ -336,17 +625,616 @@ Card.Body = CardBody;
336
625
  export default Card;
337
626
  ```
338
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
+
339
680
  ### Global Styles & Resets
340
681
  *Documentation coming soon - app-wide styles approach*
341
682
 
342
683
  ### Performance Considerations
343
- *Documentation coming soon - patterns to avoid, optimization tips*
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
344
852
 
345
853
  ### Complete Component Examples
346
854
  *Documentation coming soon - comprehensive examples with all features*
347
855
 
348
856
  ### Common UI Patterns
349
- *Documentation coming soon - modal, dropdown, form field implementations*
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
+ ```
350
1046
 
351
1047
  ### Design System Integration
352
- *Documentation coming soon - token integration, migration patterns*
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
+ };