@cronocode/react-box 3.1.6 → 3.1.8

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.
@@ -0,0 +1,825 @@
1
+ # @cronocode/react-box - AI Assistant Context
2
+
3
+ Reference document for AI assistants helping developers use this runtime CSS-in-JS library.
4
+
5
+ ---
6
+
7
+ ## CRITICAL RULES (Read First!)
8
+
9
+ ### Rule #1: NEVER Use Inline Styles
10
+
11
+ **WRONG** - Using `style` attribute:
12
+
13
+ ```tsx
14
+ // DO NOT DO THIS
15
+ <Box style={{ minHeight: "100vh", width: "100%" }} />
16
+ <Box style={{ pointerEvents: "none" }} />
17
+ <Box style={{ alignItems: "center" }} />
18
+ <Box style={{ maxWidth: "1200px" }} />
19
+ ```
20
+
21
+ **CORRECT** - Using Box props:
22
+
23
+ ```tsx
24
+ // DO THIS INSTEAD
25
+ <Box minHeight="fit-screen" width="fit" />
26
+ <Box pointerEvents="none" />
27
+ <Box ai="center" />
28
+ <Box maxWidth={300} />
29
+ ```
30
+
31
+ **If a prop doesn't exist for a CSS property**, create it using `Box.extend()` in your boxExtends.ts file. Never fall back to inline styles.
32
+
33
+ ### Common Style-to-Prop Conversions
34
+
35
+ | Inline Style (WRONG) | Box Prop (CORRECT) |
36
+ | --------------------------------------------- | ------------------------------------- |
37
+ | `style={{ width: "100%" }}` | `width="fit"` |
38
+ | `style={{ width: "100vw" }}` | `width="fit-screen"` |
39
+ | `style={{ height: "100%" }}` | `height="fit"` |
40
+ | `style={{ height: "100vh" }}` | `height="fit-screen"` |
41
+ | `style={{ minHeight: "100vh" }}` | `minHeight="fit-screen"` |
42
+ | `style={{ maxWidth: "1200px" }}` | `maxWidth={300}` (300/4=75rem=1200px) |
43
+ | `style={{ alignItems: "center" }}` | `ai="center"` |
44
+ | `style={{ justifyContent: "space-between" }}` | `jc="between"` |
45
+ | `style={{ flexDirection: "column" }}` | `d="column"` |
46
+ | `style={{ pointerEvents: "none" }}` | `pointerEvents="none"` |
47
+ | `style={{ cursor: "pointer" }}` | `cursor="pointer"` |
48
+ | `style={{ overflow: "hidden" }}` | `overflow="hidden"` |
49
+ | `style={{ position: "relative" }}` | `position="relative"` |
50
+ | `style={{ zIndex: 10 }}` | `zIndex={10}` |
51
+ | `style={{ opacity: 0.5 }}` | `opacity={0.5}` |
52
+
53
+ ### When a Prop Doesn't Exist
54
+
55
+ If you need a CSS property that doesn't have a Box prop, extend Box instead of using inline styles:
56
+
57
+ ```tsx
58
+ // boxExtends.ts - Create new props for missing CSS properties
59
+ import Box from '@cronocode/react-box';
60
+
61
+ export const { extendedProps, extendedPropTypes } = Box.extend(
62
+ {}, // CSS variables (if needed)
63
+ {
64
+ // Add new props
65
+ aspectRatio: [
66
+ {
67
+ values: ['auto', '1/1', '16/9', '4/3', '3/2'] as const,
68
+ styleName: 'aspect-ratio',
69
+ valueFormat: (value) => value,
70
+ },
71
+ ],
72
+ backdropBlur: [
73
+ {
74
+ values: ['none', 'sm', 'md', 'lg'] as const,
75
+ styleName: 'backdrop-filter',
76
+ valueFormat: (value) => {
77
+ const map = { none: 'none', sm: 'blur(4px)', md: 'blur(8px)', lg: 'blur(16px)' };
78
+ return map[value];
79
+ },
80
+ },
81
+ ],
82
+ },
83
+ {}, // Extended existing props (if needed)
84
+ );
85
+
86
+ // Now use the new props
87
+ <Box aspectRatio="16/9" backdropBlur="md" />;
88
+ ```
89
+
90
+ ### Rule #2: ALWAYS Use Component Shortcuts
91
+
92
+ **⚠️ NEVER use `<Box tag="...">` when a semantic component exists!**
93
+
94
+ The `tag` prop should ONLY be used for rare HTML elements that don't have a component shortcut (e.g., `<Box tag="datalist">`). For all common elements, use the corresponding component.
95
+
96
+ **WRONG** - Using `tag` prop for common elements:
97
+
98
+ ```tsx
99
+ // ❌ DO NOT DO THIS - These are WRONG even though they work
100
+ <Box tag="img" props={{ src: logo, alt: "Logo" }} /> // WRONG!
101
+ <Box tag="a" props={{ href: "#" }}>Link</Box> // WRONG!
102
+ <Box tag="button" onClick={...}>Click</Box> // WRONG!
103
+ <Box tag="nav">...</Box> // WRONG!
104
+ <Box tag="h1" fontSize={32}>Title</Box> // WRONG!
105
+ <Box tag="p">Text</Box> // WRONG!
106
+ <Box tag="span">Inline</Box> // WRONG!
107
+ <Box display="flex" gap={4}>...</Box> // WRONG!
108
+ <Box display="grid" gridCols={3}>...</Box> // WRONG!
109
+ ```
110
+
111
+ **CORRECT** - Using semantic components:
112
+
113
+ ```tsx
114
+ // DO THIS INSTEAD
115
+ import { Img, Link, H1, Nav } from '@cronocode/react-box/components/semantics';
116
+ import Button from '@cronocode/react-box/components/button';
117
+ import Flex from '@cronocode/react-box/components/flex';
118
+ import Grid from '@cronocode/react-box/components/grid';
119
+
120
+ <Img props={{ src: logo, alt: "Logo" }} />
121
+ <Link props={{ href: "#" }}>Link</Link>
122
+ <Button onClick={...}>Click</Button>
123
+ <Flex gap={4}>...</Flex>
124
+ <Grid gridCols={3}>...</Grid>
125
+ <Nav>...</Nav>
126
+ <H1 fontSize={32}>Title</H1>
127
+ ```
128
+
129
+ ### Component Shortcuts Reference
130
+
131
+ | Instead of... | Use... | Import from |
132
+ | ---------------------- | ------------ | ------------------------------------------- |
133
+ | `<Box display="flex">` | `<Flex>` | `@cronocode/react-box/components/flex` |
134
+ | `<Box display="grid">` | `<Grid>` | `@cronocode/react-box/components/grid` |
135
+ | `<Box tag="button">` | `<Button>` | `@cronocode/react-box/components/button` |
136
+ | `<Box tag="input">` | `<Textbox>` | `@cronocode/react-box/components/textbox` |
137
+ | `<Box tag="textarea">` | `<Textarea>` | `@cronocode/react-box/components/textarea` |
138
+ | `<Box tag="a">` | `<Link>` | `@cronocode/react-box/components/semantics` |
139
+ | `<Box tag="img">` | `<Img>` | `@cronocode/react-box/components/semantics` |
140
+ | `<Box tag="h1">` | `<H1>` | `@cronocode/react-box/components/semantics` |
141
+ | `<Box tag="h2">` | `<H2>` | `@cronocode/react-box/components/semantics` |
142
+ | `<Box tag="h3">` | `<H3>` | `@cronocode/react-box/components/semantics` |
143
+ | `<Box tag="p">` | `<P>` | `@cronocode/react-box/components/semantics` |
144
+ | `<Box tag="span">` | `<Span>` | `@cronocode/react-box/components/semantics` |
145
+ | `<Box tag="nav">` | `<Nav>` | `@cronocode/react-box/components/semantics` |
146
+ | `<Box tag="header">` | `<Header>` | `@cronocode/react-box/components/semantics` |
147
+ | `<Box tag="footer">` | `<Footer>` | `@cronocode/react-box/components/semantics` |
148
+ | `<Box tag="main">` | `<Main>` | `@cronocode/react-box/components/semantics` |
149
+ | `<Box tag="section">` | `<Section>` | `@cronocode/react-box/components/semantics` |
150
+ | `<Box tag="article">` | `<Article>` | `@cronocode/react-box/components/semantics` |
151
+ | `<Box tag="aside">` | `<Aside>` | `@cronocode/react-box/components/semantics` |
152
+ | `<Box tag="label">` | `<Label>` | `@cronocode/react-box/components/semantics` |
153
+
154
+ ---
155
+
156
+ ## Quick Overview
157
+
158
+ **What it is**: A React library that converts component props directly into CSS classes at runtime. No CSS files needed.
159
+
160
+ **Core component**: `Box` - a polymorphic component that accepts ~144 CSS props and renders any HTML element.
161
+
162
+ ```tsx
163
+ import Box from '@cronocode/react-box';
164
+
165
+ // Basic usage
166
+ <Box p={4} bgColor="blue-500" color="white">Content</Box>
167
+
168
+ // Renders as different elements
169
+ <Box tag="button" p={3}>Button</Box>
170
+ <Box tag="a" props={{ href: '/link' }}>Link</Box>
171
+
172
+ // Alias components (recommended)
173
+ import Button from '@cronocode/react-box/components/button';
174
+ <Button p={3}>Button</Button>
175
+ ```
176
+
177
+ ---
178
+
179
+ ## Critical: Numeric Value Formatters
180
+
181
+ **This is the #1 source of confusion.** Different props have different dividers:
182
+
183
+ | Prop Category | Divider | Formula | Example | CSS Output |
184
+ | ------------------------------------------------------- | ------- | ------------ | ------------------ | ------------------------ |
185
+ | Spacing (`p`, `m`, `gap`, `px`, `py`, `mx`, `my`, etc.) | 4 | value/4 rem | `p={4}` | `padding: 1rem` (16px) |
186
+ | Font size (`fontSize`) | **16** | value/16 rem | `fontSize={16}` | `font-size: 1rem` (16px) |
187
+ | Width/Height (numeric) | 4 | value/4 rem | `width={20}` | `width: 5rem` (80px) |
188
+ | Border width (`b`, `bx`, `by`, `bt`, `br`, `bb`, `bl`) | none | direct px | `b={1}` | `border-width: 1px` |
189
+ | Border radius (`borderRadius`) | none | direct px | `borderRadius={8}` | `border-radius: 8px` |
190
+
191
+ ### Common fontSize Values
192
+
193
+ ```tsx
194
+ fontSize={12} // → 0.75rem ≈ 12px (small)
195
+ fontSize={14} // → 0.875rem ≈ 14px (body)
196
+ fontSize={16} // → 1rem = 16px (default)
197
+ fontSize={18} // → 1.125rem ≈ 18px (large)
198
+ fontSize={24} // → 1.5rem = 24px (h2)
199
+ fontSize={32} // → 2rem = 32px (h1)
200
+ ```
201
+
202
+ ### Common Spacing Values (divider = 4)
203
+
204
+ ```tsx
205
+ p={1} // → 0.25rem = 4px
206
+ p={2} // → 0.5rem = 8px
207
+ p={3} // → 0.75rem = 12px
208
+ p={4} // → 1rem = 16px
209
+ p={6} // → 1.5rem = 24px
210
+ p={8} // → 2rem = 32px
211
+ ```
212
+
213
+ ---
214
+
215
+ ## Prop Reference
216
+
217
+ ### Spacing
218
+
219
+ | Prop | CSS Property |
220
+ | ---------------------- | ----------------------------- |
221
+ | `p` | padding |
222
+ | `px` | padding-left + padding-right |
223
+ | `py` | padding-top + padding-bottom |
224
+ | `pt`, `pr`, `pb`, `pl` | padding-top/right/bottom/left |
225
+ | `m` | margin |
226
+ | `mx`, `my` | margin horizontal/vertical |
227
+ | `mt`, `mr`, `mb`, `ml` | margin-top/right/bottom/left |
228
+ | `gap` | gap (flexbox/grid) |
229
+
230
+ ### Layout
231
+
232
+ | Prop | CSS Property | Values |
233
+ | --------- | --------------- | -------------------------------------------------------------------------- |
234
+ | `display` | display | `'flex'`, `'block'`, `'inline'`, `'grid'`, `'none'`, `'inline-flex'`, etc. |
235
+ | `d` | flex-direction | `'row'`, `'column'`, `'row-reverse'`, `'column-reverse'` |
236
+ | `wrap` | flex-wrap | `'wrap'`, `'nowrap'`, `'wrap-reverse'` |
237
+ | `ai` | align-items | `'center'`, `'start'`, `'end'`, `'stretch'`, `'baseline'` |
238
+ | `jc` | justify-content | `'center'`, `'start'`, `'end'`, `'between'`, `'around'`, `'evenly'` |
239
+ | `flex` | flex | number or string |
240
+ | `grow` | flex-grow | number |
241
+ | `shrink` | flex-shrink | number |
242
+
243
+ ### Sizing
244
+
245
+ | Prop | CSS Property | Accepts |
246
+ | ------------------------ | -------------- | ------------------------------------------------------------------- |
247
+ | `width` | width | number (rem/4), string (`'auto'`, `'1/2'`, `'fit'`, `'fit-screen'`) |
248
+ | `height` | height | number (rem/4), string (`'auto'`, `'fit'`, `'fit-screen'`) |
249
+ | `minWidth`, `maxWidth` | min/max-width | number or string |
250
+ | `minHeight`, `maxHeight` | min/max-height | number or string |
251
+
252
+ ### Colors (Tailwind-like palette)
253
+
254
+ | Prop | CSS Property |
255
+ | ------------- | ---------------- |
256
+ | `bgColor` | background-color |
257
+ | `color` | color |
258
+ | `borderColor` | border-color |
259
+
260
+ **Color values**: `'gray-50'` through `'gray-900'`, same for `red`, `orange`, `yellow`, `green`, `teal`, `blue`, `indigo`, `purple`, `pink`, `violet`.
261
+
262
+ Also: `'white'`, `'black'`, `'transparent'`, `'inherit'`, `'currentColor'`
263
+
264
+ ### Borders
265
+
266
+ | Prop | CSS Property |
267
+ | ---------------------- | ---------------------------------------------------------- |
268
+ | `b` | border-width (all sides) |
269
+ | `bx` | border-left-width + border-right-width |
270
+ | `by` | border-top-width + border-bottom-width |
271
+ | `bt`, `br`, `bb`, `bl` | individual sides |
272
+ | `borderRadius` | border-radius |
273
+ | `borderStyle` | border-style (`'solid'`, `'dashed'`, `'dotted'`, `'none'`) |
274
+
275
+ ### Typography
276
+
277
+ | Prop | CSS Property |
278
+ | ---------------- | ------------------------------------------------------------ |
279
+ | `fontSize` | font-size (divider: 16) |
280
+ | `fontWeight` | font-weight (`400`, `500`, `600`, `700`, etc.) |
281
+ | `lineHeight` | line-height (number = pixels, e.g. `lineHeight={24}` → 24px) |
282
+ | `textAlign` | text-align |
283
+ | `textDecoration` | text-decoration |
284
+ | `textTransform` | text-transform |
285
+ | `whiteSpace` | white-space |
286
+ | `overflow` | overflow |
287
+ | `textOverflow` | text-overflow |
288
+
289
+ ### Positioning
290
+
291
+ | Prop | CSS Property |
292
+ | -------------------------------- | ------------------------------------------------------------ |
293
+ | `position` | position (`'relative'`, `'absolute'`, `'fixed'`, `'sticky'`) |
294
+ | `top`, `right`, `bottom`, `left` | positioning offsets |
295
+ | `zIndex` | z-index |
296
+
297
+ ### Effects
298
+
299
+ | Prop | CSS Property |
300
+ | --------------- | --------------------------------------------------------------- |
301
+ | `shadow` | box-shadow (`'small'`, `'medium'`, `'large'`, `'xl'`, `'none'`) |
302
+ | `opacity` | opacity |
303
+ | `cursor` | cursor |
304
+ | `pointerEvents` | pointer-events |
305
+ | `transition` | transition |
306
+ | `transform` | transform |
307
+
308
+ ---
309
+
310
+ ## Pseudo-Classes
311
+
312
+ Apply styles on interaction states:
313
+
314
+ ```tsx
315
+ <Box
316
+ bgColor="blue-500"
317
+ hover={{ bgColor: 'blue-600' }}
318
+ focus={{ outline: 'none', ring: 2 }}
319
+ active={{ bgColor: 'blue-700' }}
320
+ disabled={{ opacity: 0.5, cursor: 'not-allowed' }}
321
+ />
322
+ ```
323
+
324
+ **Available pseudo-classes**: `hover`, `focus`, `active`, `disabled`, `checked`, `indeterminate`, `required`, `selected`, `focusWithin`, `focusVisible`, `first`, `last`, `even`, `odd`, `empty`
325
+
326
+ ---
327
+
328
+ ## Responsive Breakpoints
329
+
330
+ Mobile-first breakpoints using min-width media queries:
331
+
332
+ ```tsx
333
+ <Box
334
+ p={2} // Base (mobile)
335
+ sm={{ p: 3 }} // ≥640px
336
+ md={{ p: 4 }} // ≥768px
337
+ lg={{ p: 6 }} // ≥1024px
338
+ xl={{ p: 8 }} // ≥1280px
339
+ xxl={{ p: 10 }} // ≥1536px
340
+ />
341
+ ```
342
+
343
+ **Combine with pseudo-classes**:
344
+
345
+ ```tsx
346
+ <Box
347
+ bgColor="white"
348
+ hover={{ bgColor: 'gray-100' }}
349
+ md={{
350
+ bgColor: 'gray-50',
351
+ hover: { bgColor: 'gray-200' },
352
+ }}
353
+ />
354
+ ```
355
+
356
+ ---
357
+
358
+ ## Theme System
359
+
360
+ ### Setting Up Themes
361
+
362
+ The `Box.Theme` component provides theme management with automatic detection based on system preferences.
363
+
364
+ **Auto-detect theme** (recommended):
365
+
366
+ ```tsx
367
+ import Box from '@cronocode/react-box';
368
+
369
+ function App() {
370
+ return (
371
+ <Box.Theme>
372
+ {/* Theme auto-detects from prefers-color-scheme: 'light' or 'dark' */}
373
+ <YourApp />
374
+ </Box.Theme>
375
+ );
376
+ }
377
+ ```
378
+
379
+ **Explicit theme**:
380
+
381
+ ```tsx
382
+ <Box.Theme theme="dark">
383
+ <YourApp />
384
+ </Box.Theme>
385
+ ```
386
+
387
+ **Global vs Local theme**:
388
+
389
+ ```tsx
390
+ // Global: Adds theme class to document.documentElement (affects entire page)
391
+ <Box.Theme theme="dark" use="global">
392
+ <YourApp />
393
+ </Box.Theme>
394
+
395
+ // Local (default): Wraps children in a Box with theme class (scoped)
396
+ <Box.Theme theme="dark" use="local">
397
+ <Section>Content</Section>
398
+ </Box.Theme>
399
+ ```
400
+
401
+ ### Using the Theme Hook
402
+
403
+ ```tsx
404
+ import Box from '@cronocode/react-box';
405
+
406
+ function ThemeSwitcher() {
407
+ const [theme, setTheme] = Box.useTheme();
408
+
409
+ return <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>Current: {theme}</button>;
410
+ }
411
+
412
+ // Must be used within Box.Theme provider
413
+ function App() {
414
+ return (
415
+ <Box.Theme>
416
+ <ThemeSwitcher />
417
+ </Box.Theme>
418
+ );
419
+ }
420
+ ```
421
+
422
+ ### Theme-Aware Styles
423
+
424
+ Apply styles based on the active theme:
425
+
426
+ ```tsx
427
+ <Box
428
+ bgColor="white"
429
+ color="gray-900"
430
+ theme={{
431
+ dark: {
432
+ bgColor: 'gray-900',
433
+ color: 'gray-100',
434
+ },
435
+ }}
436
+ />
437
+ ```
438
+
439
+ ### Theme + Pseudo-Classes
440
+
441
+ Combine theme styles with pseudo-classes:
442
+
443
+ ```tsx
444
+ <Box
445
+ bgColor="white"
446
+ hover={{ bgColor: 'gray-100' }}
447
+ theme={{
448
+ dark: {
449
+ bgColor: 'gray-800',
450
+ hover: { bgColor: 'gray-700' },
451
+ },
452
+ }}
453
+ />
454
+ ```
455
+
456
+ ### Theme + Responsive Breakpoints
457
+
458
+ Combine all three systems:
459
+
460
+ ```tsx
461
+ <Box
462
+ p={4}
463
+ bgColor="white"
464
+ md={{
465
+ p: 6,
466
+ bgColor: 'gray-50',
467
+ }}
468
+ theme={{
469
+ dark: {
470
+ bgColor: 'gray-900',
471
+ md: {
472
+ bgColor: 'gray-800',
473
+ },
474
+ },
475
+ }}
476
+ />
477
+ ```
478
+
479
+ ---
480
+
481
+ ## Component System
482
+
483
+ ### Using Built-in Components
484
+
485
+ ```tsx
486
+ <Box component="button" variant="primary">Click me</Box>
487
+ <Box component="button.icon" />
488
+ ```
489
+
490
+ ### Pre-built Components
491
+
492
+ Import ready-to-use components:
493
+
494
+ ```tsx
495
+ // Form components
496
+ import Button from '@cronocode/react-box/components/button';
497
+ import Textbox from '@cronocode/react-box/components/textbox';
498
+ import Checkbox from '@cronocode/react-box/components/checkbox';
499
+ import RadioButton from '@cronocode/react-box/components/radioButton';
500
+ import Dropdown from '@cronocode/react-box/components/dropdown';
501
+ import Tooltip from '@cronocode/react-box/components/tooltip';
502
+
503
+ // Layout
504
+ import Flex from '@cronocode/react-box/components/flex'; // Box with display="flex" (supports inline prop)
505
+ import Grid from '@cronocode/react-box/components/grid'; // Box with display="grid" (supports inline prop)
506
+
507
+ <Button variant="primary">Submit</Button>
508
+ <Textbox placeholder="Enter text..." />
509
+ <Flex gap={4} ai="center">...</Flex>
510
+ <Flex inline gap={2}>Inline flex</Flex>
511
+ ```
512
+
513
+ ### Semantic HTML Components
514
+
515
+ Alias components for semantic HTML elements (from `components/semantics`):
516
+
517
+ ```tsx
518
+ import {
519
+ // Typography
520
+ P, H1, H2, H3, H4, H5, H6, Span, Mark,
521
+ // Structure
522
+ Header, Footer, Main, Nav, Section, Article, Aside,
523
+ // Other
524
+ Label, Link, Img, Figure, Figcaption, Details, Summary, Menu, Time,
525
+ } from '@cronocode/react-box/components/semantics';
526
+
527
+ // These are Box aliases with the correct HTML tag
528
+ <H1 fontSize={32} fontWeight={700}>Title</H1>
529
+ <P color="gray-600">Paragraph text</P>
530
+ <Link props={{ href: '/about' }} color="blue-500">About</Link>
531
+ <Flex tag="nav" gap={4}>...</Flex>
532
+ ```
533
+
534
+ ### Custom Components with Box.components()
535
+
536
+ ```tsx
537
+ // Define custom component styles
538
+ Box.components({
539
+ card: {
540
+ styles: {
541
+ display: 'flex',
542
+ d: 'column',
543
+ p: 4,
544
+ bgColor: 'white',
545
+ borderRadius: 8,
546
+ shadow: 'medium',
547
+ },
548
+ variants: {
549
+ bordered: { b: 1, borderColor: 'gray-200', shadow: 'none' },
550
+ elevated: { shadow: 'large' },
551
+ },
552
+ children: {
553
+ header: { styles: { fontSize: 18, fontWeight: 600, mb: 3 } },
554
+ body: { styles: { flex: 1 } },
555
+ },
556
+ },
557
+ });
558
+
559
+ // Use it
560
+ <Box component="card" variant="bordered">
561
+ <Box component="card.header">Title</Box>
562
+ <Box component="card.body">Content</Box>
563
+ </Box>;
564
+ ```
565
+
566
+ ---
567
+
568
+ ## Extension System
569
+
570
+ ### Adding Custom Colors/Variables
571
+
572
+ ```tsx
573
+ import Box from '@cronocode/react-box';
574
+
575
+ export const { extendedProps, extendedPropTypes } = Box.extend(
576
+ // Custom CSS variables
577
+ {
578
+ 'brand-primary': '#ff6600',
579
+ 'brand-secondary': '#0066ff',
580
+ },
581
+
582
+ // New props (optional)
583
+ {},
584
+
585
+ // Extend existing props with new values
586
+ {
587
+ bgColor: [
588
+ {
589
+ values: ['brand-primary', 'brand-secondary'] as const,
590
+ styleName: 'background-color',
591
+ valueFormat: (value, getVariable) => getVariable(value),
592
+ },
593
+ ],
594
+ color: [
595
+ {
596
+ values: ['brand-primary', 'brand-secondary'] as const,
597
+ styleName: 'color',
598
+ valueFormat: (value, getVariable) => getVariable(value),
599
+ },
600
+ ],
601
+ },
602
+ );
603
+
604
+ // Now use your custom colors
605
+ <Box bgColor="brand-primary" color="white">
606
+ Branded
607
+ </Box>;
608
+ ```
609
+
610
+ ### TypeScript Type Augmentation
611
+
612
+ **Manual approach** (simple cases):
613
+
614
+ ```typescript
615
+ // types.d.ts
616
+ import '@cronocode/react-box/types';
617
+
618
+ declare module '@cronocode/react-box/types' {
619
+ namespace Augmented {
620
+ interface BoxPropTypes {
621
+ bgColor: 'brand-primary' | 'brand-secondary';
622
+ }
623
+ interface ComponentsTypes {
624
+ card: 'bordered' | 'elevated';
625
+ }
626
+ }
627
+ }
628
+ ```
629
+
630
+ **Generic approach** (recommended - auto-extracts types from your definitions):
631
+
632
+ ```typescript
633
+ // types.d.ts
634
+ import { ExtractComponentsAndVariants, ExtractBoxStyles } from '@cronocode/react-box/types';
635
+ import { components } from './boxComponents';
636
+ import { extendedPropTypes, extendedProps } from './boxExtends';
637
+
638
+ declare module '@cronocode/react-box/types' {
639
+ namespace Augmented {
640
+ interface BoxProps extends ExtractBoxStyles<typeof extendedProps> {}
641
+ interface BoxPropTypes extends ExtractBoxStyles<typeof extendedPropTypes> {}
642
+ interface ComponentsTypes extends ExtractComponentsAndVariants<typeof components> {}
643
+ }
644
+ }
645
+ ```
646
+
647
+ ---
648
+
649
+ ## Common Patterns
650
+
651
+ ### Flex Container
652
+
653
+ ```tsx
654
+ import Flex from '@cronocode/react-box/components/flex';
655
+
656
+ <Flex d="column" gap={4} ai="center" jc="between">
657
+ {children}
658
+ </Flex>;
659
+ ```
660
+
661
+ ### Card
662
+
663
+ ```tsx
664
+ <Box p={4} bgColor="white" borderRadius={8} shadow="medium">
665
+ {content}
666
+ </Box>
667
+ ```
668
+
669
+ ### Button
670
+
671
+ ```tsx
672
+ import Button from '@cronocode/react-box/components/button';
673
+
674
+ <Button
675
+ px={4}
676
+ py={2}
677
+ bgColor="blue-500"
678
+ color="white"
679
+ borderRadius={6}
680
+ fontWeight={500}
681
+ hover={{ bgColor: 'blue-600' }}
682
+ disabled={{ opacity: 0.5, cursor: 'not-allowed' }}
683
+ >
684
+ Click me
685
+ </Button>;
686
+ ```
687
+
688
+ ### Input Field
689
+
690
+ ```tsx
691
+ import Textbox from '@cronocode/react-box/components/textbox';
692
+
693
+ <Textbox
694
+ placeholder="Enter text..."
695
+ width="fit"
696
+ px={3}
697
+ py={2}
698
+ b={1}
699
+ borderColor="gray-300"
700
+ borderRadius={6}
701
+ focus={{ borderColor: 'blue-500', outline: 'none' }}
702
+ />;
703
+ ```
704
+
705
+ ### Grid Layout
706
+
707
+ ```tsx
708
+ import Grid from '@cronocode/react-box/components/grid';
709
+
710
+ <Grid gridCols={3} gap={4}>
711
+ {items.map((item) => (
712
+ <Box key={item.id}>{item.content}</Box>
713
+ ))}
714
+ </Grid>;
715
+ ```
716
+
717
+ ### Responsive Stack
718
+
719
+ ```tsx
720
+ import Flex from '@cronocode/react-box/components/flex';
721
+
722
+ <Flex d="column" gap={2} md={{ d: 'row', gap: 4 }}>
723
+ {children}
724
+ </Flex>;
725
+ ```
726
+
727
+ ### Truncated Text
728
+
729
+ ```tsx
730
+ <Box overflow="hidden" textOverflow="ellipsis" whiteSpace="nowrap">
731
+ Long text that will be truncated...
732
+ </Box>
733
+ ```
734
+
735
+ ### Overlay/Modal Backdrop
736
+
737
+ ```tsx
738
+ <Box position="fixed" top={0} left={0} right={0} bottom={0} bgColor="black" opacity={0.5} zIndex={50} />
739
+ ```
740
+
741
+ **Note**: For tooltips, dropdowns, and popups that need to escape `overflow: hidden` containers, use the `Tooltip` component instead of manual `zIndex`. It uses React portals to render content outside the DOM hierarchy, avoiding z-index and overflow issues.
742
+
743
+ ```tsx
744
+ import Tooltip from '@cronocode/react-box/components/tooltip';
745
+
746
+ <Tooltip content="Tooltip text">
747
+ <Button>Hover me</Button>
748
+ </Tooltip>;
749
+ ```
750
+
751
+ ---
752
+
753
+ ## Group Hover (hoverGroup)
754
+
755
+ Style child elements when parent is hovered:
756
+
757
+ ```tsx
758
+ // Parent with a className
759
+ <Flex className="card-row" gap={2}>
760
+ {/* Child responds to parent hover */}
761
+ <Box opacity={0} hoverGroup={{ 'card-row': { opacity: 1 } }}>
762
+ Actions
763
+ </Box>
764
+ </Flex>
765
+ ```
766
+
767
+ ---
768
+
769
+ ## Server-Side Rendering (SSG/SSR)
770
+
771
+ ```tsx
772
+ import { getStyles, resetStyles } from '@cronocode/react-box/ssg';
773
+
774
+ // After rendering your app, get generated styles
775
+ const cssString = getStyles();
776
+
777
+ // Inject into your HTML
778
+ <style id="crono-box">{cssString}</style>;
779
+
780
+ // Reset for next request (in SSR)
781
+ resetStyles();
782
+ ```
783
+
784
+ ---
785
+
786
+ ## Key Reminders for AI Assistants
787
+
788
+ ### ⚠️ MOST IMPORTANT (Common AI Mistakes)
789
+
790
+ 1. **NEVER use `style={{ }}` attribute** - Always use Box props instead. If a prop doesn't exist, extend Box with `Box.extend()`
791
+ 2. **NEVER use `<Box tag="...">` for common elements** - Use semantic components instead:
792
+ - `<Box tag="a">` → `<Link>`
793
+ - `<Box tag="img">` → `<Img>`
794
+ - `<Box tag="button">` → `<Button>`
795
+ - `<Box tag="h1/h2/h3">` → `<H1>/<H2>/<H3>`
796
+ - `<Box tag="p">` → `<P>`
797
+ - `<Box tag="nav/header/footer>` → `<Nav>/<Header>/<Footer>`
798
+ 3. **NEVER use `<Box display="flex/grid">`** - Use `<Flex>` or `<Grid>` components instead
799
+
800
+ ### Value Formatting
801
+
802
+ 4. **fontSize uses divider 16**, not 4. `fontSize={14}` → 14px, NOT 3.5px
803
+ 5. **Spacing uses divider 4**. `p={4}` → 16px (1rem)
804
+ 6. **Border width is direct px**. `b={1}` → 1px
805
+ 7. **lineHeight is direct px**. `lineHeight={24}` → 24px
806
+
807
+ ### Syntax & Patterns
808
+
809
+ 8. **Colors are Tailwind-like**: `'gray-500'`, `'blue-600'`, etc.
810
+ 9. **Breakpoints are mobile-first**: base → sm → md → lg → xl → xxl
811
+ 10. **Theme styles nest**: `theme={{ dark: { hover: { ... } } }}`
812
+ 11. **HTML attributes go in `props`**: `<Link props={{ href: '/link' }}>` - NOT directly as Box props
813
+ 12. **Percentage widths**: Use strings like `width="1/2"` for 50%
814
+ 13. **Full size shortcuts**: `width="fit"` = 100%, `width="fit-screen"` = 100vw
815
+ 14. **Box is memoized** with `React.memo` - props comparison is efficient
816
+
817
+ ---
818
+
819
+ ## Debugging Tips
820
+
821
+ 1. **Inspect styles**: Look for `<style id="crono-box">` in document head
822
+ 2. **Check class names**: Elements get classes like `_b`, `_2a`, etc.
823
+ 3. **Verify variables**: CSS variables are in `:root` rules
824
+ 4. **Theme issues**: Ensure `<Box.Theme>` wraps your app
825
+ 5. **Portal theming**: Tooltips/dropdowns use `#crono-box` container