@ornikar/bumper 3.2.0 → 3.3.0

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 (28) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/docs/migration/Typography.md +484 -0
  3. package/package.json +5 -3
  4. package/src/Bumper.mdx +36 -0
  5. package/src/system/content/icon/Icon.mdx +31 -0
  6. package/src/system/content/icon/Icon.stories.tsx +0 -1
  7. package/src/system/content/typography/Typography.mdx +68 -0
  8. package/src/system/content/typography/Typography.stories.tsx +0 -1
  9. package/src/system/content/typography/TypographyIcon.mdx +50 -0
  10. package/src/system/content/typography/TypographyIcon.stories.tsx +0 -1
  11. package/src/system/content/typography/TypographyLink.mdx +49 -0
  12. package/src/system/content/typography/TypographyLink.stories.tsx +0 -1
  13. package/src/system/core/primitives/Center.mdx +31 -0
  14. package/src/system/core/primitives/Center.stories.tsx +0 -1
  15. package/src/system/core/primitives/Image/Image.mdx +15 -0
  16. package/src/system/core/primitives/Image/Image.stories.tsx +0 -1
  17. package/src/system/core/primitives/Pressable.mdx +37 -0
  18. package/src/system/core/primitives/Pressable.stories.tsx +0 -1
  19. package/src/system/core/primitives/ScrollView/ScrollView.mdx +36 -0
  20. package/src/system/core/primitives/ScrollView/ScrollView.stories.tsx +0 -1
  21. package/src/system/core/primitives/Stack.mdx +55 -0
  22. package/src/system/core/primitives/Stack.stories.tsx +0 -1
  23. package/src/system/core/primitives/View.mdx +86 -0
  24. package/src/system/core/primitives/View.stories.tsx +0 -1
  25. package/src/system/dataDisplays/Badge/Badge.mdx +32 -0
  26. package/src/system/dataDisplays/Badge/Badge.stories.tsx +0 -1
  27. package/src/system/loading/loader/Loader.mdx +26 -0
  28. package/src/system/loading/loader/Loader.stories.tsx +0 -1
package/CHANGELOG.md CHANGED
@@ -3,6 +3,15 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [3.3.0](https://github.com/ornikar/kitt/compare/@ornikar/bumper@3.2.0...@ornikar/bumper@3.3.0) (2026-03-10)
7
+
8
+
9
+ ### Features
10
+
11
+ * **bumper:** create typography migration process [no issue] ([#2914](https://github.com/ornikar/kitt/issues/2914)) ([61d576a](https://github.com/ornikar/kitt/commit/61d576ada6c95fc8bdb8bf5aa1a3ca63a1da9327))
12
+
13
+
14
+
6
15
  ## [3.2.0](https://github.com/ornikar/kitt/compare/@ornikar/bumper@3.1.0...@ornikar/bumper@3.2.0) (2026-03-09)
7
16
 
8
17
 
@@ -0,0 +1,484 @@
1
+ # Typography → Typography Migration Guide
2
+
3
+ > Source: `@ornikar/kitt-universal/Typography`
4
+ > Target: `@ornikar/bumper/Typography`
5
+ > Generated: 2026-03-05
6
+
7
+ ## Import Change
8
+
9
+ ```tsx
10
+ // Before
11
+ import { Typography } from '@ornikar/kitt-universal';
12
+ import { TypographyLink } from '@ornikar/kitt-universal';
13
+ import { TypographyIcon } from '@ornikar/kitt-universal';
14
+ import { TypographyEmoji } from '@ornikar/kitt-universal';
15
+
16
+ // After
17
+ import { Typography } from '@ornikar/bumper';
18
+ // TypographyLink → Typography.Link (compound component)
19
+ // TypographyIcon → Typography.Icon (compound component)
20
+ // TypographyEmoji has NO equivalent in bumper (requires manual review)
21
+ ```
22
+
23
+ ## Props Mapping
24
+
25
+ ### Typography.Text / Typography.Header\*
26
+
27
+ | Source Prop | Target Prop | Transform | Notes |
28
+ | --------------------------------------------- | ---------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------ |
29
+ | `base="body-m"` | `variant="body-m"` | Rename prop `base` → `variant` | When used as the only size prop (non-responsive) |
30
+ | `base` + `medium` + `large` etc. | `variant` + `$md` + `$lg` etc. | See [Responsive Typography](#responsive-typography) | Legacy breakpoint props become Tamagui media props |
31
+ | `type={{ base: "body-m", medium: "body-l" }}` | `variant="body-m" $md={{ variant: "body-l" }}` | Destructure `type` object into `variant` + media props | See [Responsive Typography](#responsive-typography) |
32
+ | `variant="regular"` | `weight="regular"` | Rename prop `variant` → `weight` | Only applies to body variants |
33
+ | `variant="bold"` | `weight="bold"` | Rename prop `variant` → `weight` | Only applies to body variants |
34
+ | `variant="semibold"` | Remove | Remove prop | Headings/labels are always semibold by default; body variants don't support semibold |
35
+ | `color="black"` | `color="$content.base.hi"` | Map color value | See [Color Mapping](#color-mapping) |
36
+ | `accessibilityRole` | Remove | Remove prop | Sub-components handle roles automatically |
37
+ | `textAlign` | `textAlign` | Keep as-is | Same API |
38
+ | `textTransform` | `textTransform` | Keep as-is | content-caps auto-applies uppercase in both |
39
+ | `underline` | `textDecorationLine="underline"` | Convert boolean to style prop | — |
40
+ | `strikeThrough` | `textDecorationLine="line-through"` | Convert boolean to style prop | — |
41
+ | `_web={{ ... }}` | `$platform-web={{ ... }}` | Rename platform prop | Tamagui media query syntax |
42
+ | `_ios={{ ... }}` | `$platform-native={{ ... }}` | Rename platform prop | No iOS-specific prop; use platform-native |
43
+ | `_android={{ ... }}` | `$platform-native={{ ... }}` | Rename platform prop | No Android-specific prop; use platform-native |
44
+
45
+ ### TypographyLink → Typography.Link
46
+
47
+ | Source Prop | Target Prop | Transform | Notes |
48
+ | ------------------- | ------------------ | -------------------------------- | ------------------------------------------------------ |
49
+ | `variant="bold"` | `weight="bold"` | Rename prop `variant` → `weight` | Required in source, same in target |
50
+ | `variant="regular"` | `weight="regular"` | Rename prop `variant` → `weight` | — |
51
+ | `href` | Remove | Remove prop | `href` is handled by the parent `ExternalLink` wrapper |
52
+ | `hrefAttrs` | Remove | Remove prop | Handled by parent wrapper |
53
+ | `disabled` | `disabled` | Keep as-is | Same API |
54
+ | `noUnderline` | `noUnderline` | Keep as-is | Same API |
55
+ | `onPress` | `onPress` | Keep as-is | Same API |
56
+ | `base="body-s"` | `variant="body-s"` | Rename prop `base` → `variant` | Same as Typography.Text |
57
+ | `color` | `color` | Map color value | See [Color Mapping](#color-mapping) |
58
+
59
+ ### TypographyIcon → Typography.Icon
60
+
61
+ | Source Prop | Target Prop | Transform | Notes |
62
+ | ----------- | ----------- | --------------- | ------------------------------------------------------------------------------------- |
63
+ | `icon` | `icon` | Keep as-is | Same API |
64
+ | `color` | `color` | Map color value | See [Color Mapping](#color-mapping); `"inherit"` value removed — omit prop to inherit |
65
+ | `size` | `size` | Map to token | Numeric values → `$icon.s` (16) / `$icon.m` (20) / `$icon.l` (24) |
66
+
67
+ ## Value Mappings
68
+
69
+ ### Variant (Type/Size) Mapping
70
+
71
+ Most body variants are identical. Key renames:
72
+
73
+ ```
74
+ heading-xxs → heading-2xs
75
+ heading-xs → heading-xs (unchanged)
76
+ heading-s → heading-s (unchanged)
77
+ heading-m → heading-m (unchanged)
78
+ heading-l → heading-l (unchanged)
79
+ heading-xl → heading-xl (unchanged)
80
+ heading-xxl → heading-2xl
81
+
82
+ body-xs → body-xs (unchanged)
83
+ body-s → body-s (unchanged)
84
+ body-m → body-m (unchanged)
85
+ body-l → body-l (unchanged)
86
+ body-xl → body-xl (unchanged)
87
+
88
+ label-small → label-s
89
+ label-medium → label-m
90
+ label-large → label-l
91
+
92
+ content-caps-xs → content-caps-xs (unchanged)
93
+ content-caps-s → content-caps-s (unchanged)
94
+ content-caps-m → content-caps-m (unchanged)
95
+ content-caps-l → content-caps-l (unchanged)
96
+ content-caps-xl → content-caps-xl (unchanged)
97
+ content-caps-xxl → content-caps-2xl
98
+ content-caps-xxxl → content-caps-3xl
99
+ ```
100
+
101
+ ### Weight Mapping
102
+
103
+ Source `variant` prop → Target `weight` prop:
104
+
105
+ ```
106
+ "regular" → "regular" (body only)
107
+ "semibold" → remove prop (headings/labels enforce semibold automatically)
108
+ "bold" → "bold" (body only)
109
+ ```
110
+
111
+ **Important**: In bumper, `weight` is only meaningful for body variants. Heading, label, and content-caps variants have fixed weights. If the source has `variant="semibold"` on a heading, simply remove the prop.
112
+
113
+ ### Color Mapping
114
+
115
+ #### Predefined Color Names (kitt-universal → bumper tokens)
116
+
117
+ ```
118
+ "black" → "$content.base.hi"
119
+ "black-anthracite" → "$content.base.hi"
120
+ "black-disabled" → "$content.disabled"
121
+ "black-light" → "$content.base.mid"
122
+ "white" → "$content.base.onContrasted.hi"
123
+ "white-light" → "$content.base.onContrasted.mid"
124
+ "primary" → "$content.accent"
125
+ "primary-light" → "$content.accent"
126
+ "accent" → "$content.accent"
127
+ "success" → "$content.success"
128
+ "danger" → "$content.danger"
129
+ "warning" → "$content.warning"
130
+ ```
131
+
132
+ #### Bumper Design Token Colors (already used in learner-apps)
133
+
134
+ These are the most common colors found in the codebase. They need the `kitt.bumper.` prefix stripped and `$` prefix added:
135
+
136
+ ```
137
+ "kitt.bumper.content.base.mid" → "$content.base.mid"
138
+ "kitt.bumper.content.base.low" → "$content.base.low"
139
+ "kitt.bumper.content.base.onContrasted.hi" → "$content.base.onContrasted.hi"
140
+ "kitt.bumper.content.base.hi" → "$content.base.hi"
141
+ "kitt.bumper.content.accent" → "$content.accent"
142
+ "kitt.bumper.content.disabled" → "$content.disabled"
143
+ "kitt.bumper.content.success" → "$content.success"
144
+ "kitt.bumper.content.danger" → "$content.danger"
145
+ ```
146
+
147
+ **Rule**: If the color starts with `"kitt.bumper."`, strip the `"kitt.bumper."` prefix and prepend `"$"`.
148
+
149
+ ### Icon Size Mapping
150
+
151
+ ```
152
+ 16 → "$icon.s"
153
+ 20 → "$icon.m"
154
+ 24 → "$icon.l"
155
+ ```
156
+
157
+ ## Sub-Component Mapping
158
+
159
+ | Source | Target | Notes |
160
+ | ---------------------------- | -------------------- | --------------------------------------------------------------------------------------------- |
161
+ | `Typography.Text` | `Typography.Text` | Same name, props differ (see mapping) |
162
+ | `Typography.Paragraph` | `Typography.Text` | **Removed** — use `Typography.Text` (add `role="paragraph"` manually if semantic role needed) |
163
+ | `Typography.Header1` | `Typography.Header1` | Same name, props differ |
164
+ | `Typography.Header2` | `Typography.Header2` | Same name, props differ |
165
+ | `Typography.Header3` | `Typography.Header3` | Same name, props differ |
166
+ | `Typography.Header4` | `Typography.Header4` | Same name, props differ |
167
+ | `Typography.Header5` | `Typography.Header5` | Same name, props differ |
168
+ | `Typography.Header6` | `Typography.Header6` | Same name, props differ |
169
+ | `Typography.SetDefaultColor` | **None** | **Removed** — no equivalent. Apply color directly to each child. |
170
+ | `TypographyLink` | `Typography.Link` | Standalone import → compound component |
171
+ | `TypographyIcon` | `Typography.Icon` | Standalone import → compound component |
172
+ | `TypographyEmoji` | **None** | **Removed** — no equivalent in bumper. Requires manual review. |
173
+
174
+ ## Responsive Typography
175
+
176
+ Source uses legacy breakpoint props or a `type` object. Target uses Tamagui media props.
177
+
178
+ ### Breakpoint Prop Mapping
179
+
180
+ ```
181
+ base → variant (the base/default value)
182
+ small → $sm={{ variant: "..." }}
183
+ medium → $md={{ variant: "..." }}
184
+ large → $lg={{ variant: "..." }}
185
+ wide → $xl={{ variant: "..." }}
186
+ ```
187
+
188
+ ### Examples
189
+
190
+ ```tsx
191
+ // Before — legacy shorthand props
192
+ <Typography.Text base="body-s" medium="body-l">
193
+ Responsive text
194
+ </Typography.Text>
195
+
196
+ // After
197
+ <Typography.Text variant="body-s" $md={{ variant: "body-l" }}>
198
+ Responsive text
199
+ </Typography.Text>
200
+ ```
201
+
202
+ ```tsx
203
+ // Before — type object
204
+ <Typography.Text type={{ base: "body-s", medium: "body-m", large: "body-l" }}>
205
+ Responsive text
206
+ </Typography.Text>
207
+
208
+ // After
209
+ <Typography.Text variant="body-s" $md={{ variant: "body-m" }} $lg={{ variant: "body-l" }}>
210
+ Responsive text
211
+ </Typography.Text>
212
+ ```
213
+
214
+ ## Children & Composition
215
+
216
+ Children patterns are largely identical between source and target. Both accept:
217
+
218
+ - String/number children
219
+ - Nested Typography components
220
+ - Link, Icon components as children
221
+
222
+ Key differences:
223
+
224
+ - `TypographyEmoji` cannot be nested in bumper Typography (no equivalent)
225
+ - `Typography.Paragraph` children should be moved to `Typography.Text`
226
+
227
+ ### Before/After: Bold Emphasis Pattern
228
+
229
+ ```tsx
230
+ // Before
231
+ <Typography.Text>
232
+ <FormattedMessage
233
+ defaultMessage="Text with <bold>emphasis</bold>"
234
+ values={{
235
+ bold: (chunks) => <Typography.Text variant="bold">{chunks}</Typography.Text>,
236
+ }}
237
+ />
238
+ </Typography.Text>
239
+
240
+ // After
241
+ <Typography.Text>
242
+ <FormattedMessage
243
+ defaultMessage="Text with <bold>emphasis</bold>"
244
+ values={{
245
+ bold: (chunks) => <Typography.Text weight="bold">{chunks}</Typography.Text>,
246
+ }}
247
+ />
248
+ </Typography.Text>
249
+ ```
250
+
251
+ ### Before/After: Link in FormattedMessage
252
+
253
+ ```tsx
254
+ // Before
255
+ <Typography.Text>
256
+ <FormattedMessage
257
+ defaultMessage="Click <link>here</link>"
258
+ values={{
259
+ link: (chunks) => (
260
+ <ExternalLink as={TypographyLink} variant="bold" href={url}>
261
+ {chunks}
262
+ </ExternalLink>
263
+ ),
264
+ }}
265
+ />
266
+ </Typography.Text>
267
+
268
+ // After
269
+ <Typography.Text>
270
+ <FormattedMessage
271
+ defaultMessage="Click <link>here</link>"
272
+ values={{
273
+ link: (chunks) => (
274
+ <ExternalLink as={Typography.Link} weight="bold" href={url}>
275
+ {chunks}
276
+ </ExternalLink>
277
+ ),
278
+ }}
279
+ />
280
+ </Typography.Text>
281
+ ```
282
+
283
+ ## Behavioral Differences
284
+
285
+ 1. **Default color changed**: Source defaults to `"black"`. Target defaults to `"$content.base.hi"` (equivalent, but token-based).
286
+ 2. **Weight prop name**: Source uses `variant` for weight. Target uses `weight`.
287
+ 3. **Size prop name**: Source uses `base`/`type` for size. Target uses `variant`.
288
+ 4. **No Typography.Paragraph**: Target has no Paragraph sub-component. Use Typography.Text.
289
+ 5. **No SetDefaultColor**: Target has no context provider for default colors. Colors must be set on each component individually.
290
+ 6. **No TypographyEmoji**: Target has no emoji sub-component.
291
+ 7. **Platform props syntax**: `_web`/`_ios`/`_android` → `$platform-web`/`$platform-native`.
292
+ 8. **Color inheritance**: Both support color inheritance via context, but the context APIs differ internally. Behavior is equivalent.
293
+ 9. **Responsive API**: Source uses breakpoint props (`base`, `medium`, `large`) or `type` object. Target uses Tamagui media props (`$sm`, `$md`, `$lg`).
294
+ 10. **TypographyLink/TypographyIcon**: Source exports as standalone components. Target uses compound component pattern (`Typography.Link`, `Typography.Icon`).
295
+ 11. **Icon color="inherit"**: Source supports `color="inherit"`. Target does not — simply omit the color prop to inherit from parent.
296
+
297
+ ## Edge Cases
298
+
299
+ ### Conditional props
300
+
301
+ ```tsx
302
+ // Before — conditional variant (weight)
303
+ <Typography.Text variant={isImportant ? "bold" : "regular"}>text</Typography.Text>
304
+
305
+ // After — rename prop, keep expression
306
+ <Typography.Text weight={isImportant ? "bold" : "regular"}>text</Typography.Text>
307
+ ```
308
+
309
+ ```tsx
310
+ // Before — conditional base (size)
311
+ <Typography.Text base={isLarge ? "body-l" : "body-s"}>text</Typography.Text>
312
+
313
+ // After — rename prop, keep expression
314
+ <Typography.Text variant={isLarge ? "body-l" : "body-s"}>text</Typography.Text>
315
+ ```
316
+
317
+ ### Spread props
318
+
319
+ ```tsx
320
+ // Before
321
+ <Typography.Text {...typographyProps} />;
322
+
323
+ // After — rename spread keys
324
+ const { base, variant, type, _web, _ios, _android, accessibilityRole, underline, strikeThrough, ...rest } =
325
+ typographyProps;
326
+ <Typography.Text
327
+ variant={base}
328
+ weight={variant}
329
+ {...(underline && { textDecorationLine: 'underline' })}
330
+ {...(strikeThrough && { textDecorationLine: 'line-through' })}
331
+ {...(_web && { '$platform-web': _web })}
332
+ {...rest}
333
+ />;
334
+ ```
335
+
336
+ **Note**: Spread props require manual review as the prop names are ambiguous without runtime context.
337
+
338
+ ### Typography.Paragraph migration
339
+
340
+ ```tsx
341
+ // Before
342
+ <Typography.Paragraph base="body-m">
343
+ Paragraph content
344
+ </Typography.Paragraph>
345
+
346
+ // After — no semantic paragraph in bumper
347
+ <Typography.Text variant="body-m">
348
+ Paragraph content
349
+ </Typography.Text>
350
+ ```
351
+
352
+ If semantic `<p>` element is required, add `tag="p"` if supported by Tamagui, or wrap in a `<p>` element.
353
+
354
+ ### Typography.SetDefaultColor migration
355
+
356
+ ```tsx
357
+ // Before
358
+ <Typography.SetDefaultColor value="primary">
359
+ <Typography.Text base="body-m">Inherits primary</Typography.Text>
360
+ <Typography.Text base="body-s">Also inherits primary</Typography.Text>
361
+ </Typography.SetDefaultColor>
362
+
363
+ // After — apply color to each child
364
+ <Typography.Text variant="body-m" color="$content.accent">Explicit color</Typography.Text>
365
+ <Typography.Text variant="body-s" color="$content.accent">Explicit color</Typography.Text>
366
+ ```
367
+
368
+ ### TypographyEmoji migration
369
+
370
+ ```tsx
371
+ // Before
372
+ <Typography.Text base="body-m">
373
+ Text with <TypographyEmoji emoji="💸" base="heading-m" /> emoji
374
+ </Typography.Text>
375
+
376
+ // After — NO equivalent in bumper. Use inline text emoji or custom component.
377
+ <Typography.Text variant="body-m">
378
+ Text with 💸 emoji
379
+ </Typography.Text>
380
+ ```
381
+
382
+ **Requires manual review** — TypographyEmoji provides consistent cross-platform rendering via Twemoji. A plain emoji character may render differently across platforms.
383
+
384
+ ### Wrapper / re-export migration
385
+
386
+ #### InternalTypographyLink
387
+
388
+ ```tsx
389
+ // Before — wrapper imports TypographyLink
390
+ import { TypographyLink } from '@ornikar/kitt-universal';
391
+
392
+ // After — wrapper should import Typography.Link
393
+ import { Typography } from '@ornikar/bumper';
394
+ // Use Typography.Link instead of TypographyLink
395
+ ```
396
+
397
+ The `InternalTypographyLink` wrapper in `learner-apps-shared` must be updated to use `Typography.Link` from bumper. Its internal `variant` prop should be renamed to `weight`.
398
+
399
+ #### Price component
400
+
401
+ The `Price` component wraps `Typography.Text` and uses `TypographyTextProps`. Update:
402
+
403
+ - Import source: `@ornikar/kitt-universal` → `@ornikar/bumper`
404
+ - Prop type references to match bumper's types
405
+ - Internal `base` → `variant`, `variant` → `weight` mappings
406
+
407
+ #### getTypographyColor helper
408
+
409
+ This helper maps semantic states to Typography colors. Update returned color values from kitt-universal predefined colors to bumper `$content.*` tokens.
410
+
411
+ ### Styled / extended components
412
+
413
+ Source components extended via NativeBase `styled()` should be migrated to Tamagui's `styled()`:
414
+
415
+ ```tsx
416
+ // Before
417
+ import { styled } from 'native-base';
418
+ const StyledText = styled(Typography.Text, { ... });
419
+
420
+ // After
421
+ import { styled } from 'tamagui';
422
+ const StyledText = styled(Typography.Text, { ... });
423
+ ```
424
+
425
+ Props passed to styled components must follow the same prop mapping rules.
426
+
427
+ ### Dynamic color from helper functions
428
+
429
+ ```tsx
430
+ // Before
431
+ const color = getTypographyColor(state); // returns 'primary', 'danger', etc.
432
+ <Typography.Text color={color}>text</Typography.Text>;
433
+
434
+ // After — update the helper to return bumper tokens
435
+ const color = getTypographyColor(state); // should return '$content.accent', '$content.danger', etc.
436
+ <Typography.Text color={color}>text</Typography.Text>;
437
+ ```
438
+
439
+ ### TypographyIcon with color="inherit"
440
+
441
+ ```tsx
442
+ // Before
443
+ <TypographyIcon color="inherit" icon={<CheckIcon />} />
444
+
445
+ // After — omit color prop to inherit
446
+ <Typography.Icon icon={<CheckIcon />} />
447
+ ```
448
+
449
+ ## Migration Rules (machine-readable)
450
+
451
+ 1. **Update import**: Replace `import { Typography } from '@ornikar/kitt-universal'` with `import { Typography } from '@ornikar/bumper'`
452
+ 2. **Update import**: Replace `import { TypographyLink } from '@ornikar/kitt-universal'` — use `Typography.Link` from `@ornikar/bumper` instead
453
+ 3. **Update import**: Replace `import { TypographyIcon } from '@ornikar/kitt-universal'` — use `Typography.Icon` from `@ornikar/bumper` instead
454
+ 4. **Update import**: Replace `import { TypographyEmoji } from '@ornikar/kitt-universal'` — flag for manual review (no bumper equivalent)
455
+ 5. **Rename component**: `TypographyLink` → `Typography.Link`
456
+ 6. **Rename component**: `TypographyIcon` → `Typography.Icon`
457
+ 7. **Rename component**: `Typography.Paragraph` → `Typography.Text`
458
+ 8. **Remove component**: `Typography.SetDefaultColor` — apply color directly to each child
459
+ 9. **Rename prop**: `base` → `variant` (when used as size/type)
460
+ 10. **Rename prop**: `variant` → `weight` (when used as font weight)
461
+ 11. **Remove prop**: `accessibilityRole` (sub-components handle this)
462
+ 12. **Convert boolean**: `underline` → `textDecorationLine="underline"`
463
+ 13. **Convert boolean**: `strikeThrough` → `textDecorationLine="line-through"`
464
+ 14. **Rename platform prop**: `_web={{ ... }}` → `$platform-web={{ ... }}`
465
+ 15. **Rename platform prop**: `_ios={{ ... }}` → `$platform-native={{ ... }}`
466
+ 16. **Rename platform prop**: `_android={{ ... }}` → `$platform-native={{ ... }}`
467
+ 17. **Convert responsive**: `type={{ base: X, small: Y, medium: Z, large: W, wide: V }}` → `variant={X} $sm={{ variant: Y }} $md={{ variant: Z }} $lg={{ variant: W }} $xl={{ variant: V }}`
468
+ 18. **Convert responsive shorthand**: `small="X"` → `$sm={{ variant: "X" }}`; `medium="X"` → `$md={{ variant: "X" }}`; `large="X"` → `$lg={{ variant: "X" }}`; `wide="X"` → `$xl={{ variant: "X" }}`
469
+ 19. **Map variant values**: Apply value mapping table (e.g. `heading-xxs` → `heading-2xs`, `label-small` → `label-s`)
470
+ 20. **Map color values**: Apply color mapping table (e.g. `"black"` → `"$content.base.hi"`, `"kitt.bumper.X"` → `"$X"`)
471
+ 21. **Remove weight on headings/labels**: If target `variant` is a heading or label type, remove the `weight` prop (it's fixed)
472
+ 22. **Icon color="inherit"**: Remove `color="inherit"` prop (omitting color achieves inheritance)
473
+ 23. **Icon size**: Map numeric sizes to tokens (`16` → `"$icon.s"`, `20` → `"$icon.m"`, `24` → `"$icon.l"`)
474
+
475
+ ## Not Migratable (requires human review)
476
+
477
+ - **TypographyEmoji usage** — No bumper equivalent. ~low frequency but renders differently as plain emoji vs Twemoji.
478
+ - **Typography.SetDefaultColor with many children** — Each child needs explicit color. Large trees may need careful review to ensure no child is missed.
479
+ - **Spread props (`{...typographyProps}`)** — Prop names change (`base` → `variant`, `variant` → `weight`), cannot be renamed in spread without runtime knowledge of the shape.
480
+ - **Dynamic type/variant expressions** — `base={someVariable}` where the variable may contain values that need renaming (e.g. `heading-xxs` → `heading-2xs`). Requires runtime mapping function or audit of variable sources.
481
+ - **Custom color strings (hex/rgb)** — Source accepts arbitrary CSS color strings. Target uses Tamagui ColorTokens. Arbitrary hex values should be mapped to the nearest token.
482
+ - **NativeBase styled() extensions** — Must be migrated to Tamagui `styled()` with updated prop names.
483
+ - **Type imports** — `TypographyTextProps`, `TypographyHeadingProps`, `TypographyColor`, `ExtendedTypographyColor` type imports must be updated to bumper equivalents.
484
+ - **Platform-specific overrides merging** — Source has separate `_ios` and `_android` props. Target only has `$platform-native`. If different iOS/Android overrides were used, they need reconciliation.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ornikar/bumper",
3
- "version": "3.2.0",
3
+ "version": "3.3.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "directory": "@ornikar/bumper",
@@ -24,7 +24,8 @@
24
24
  "storybook"
25
25
  ],
26
26
  "extraEntries": [
27
- "./src/tamagui.config.ts"
27
+ "./src/tamagui.config.ts",
28
+ "./docs/**/*.md"
28
29
  ]
29
30
  },
30
31
  "dependencies": {
@@ -118,7 +119,8 @@
118
119
  }
119
120
  },
120
121
  "./package.json": "./package.json",
121
- "./src/tamagui.config.ts": "./src/tamagui.config.ts"
122
+ "./src/tamagui.config.ts": "./src/tamagui.config.ts",
123
+ "./docs/**/*.md": "./docs/**/*.md"
122
124
  },
123
125
  "browser": {
124
126
  ".": "./dist/index.es",
package/src/Bumper.mdx ADDED
@@ -0,0 +1,36 @@
1
+ import { Meta } from '@storybook/blocks';
2
+
3
+ <Meta title="Bumper/Overview" />
4
+
5
+ # Bumper
6
+
7
+ Next-generation Ornikar design system built on Tamagui. Semantic token system for
8
+ spacing, color, radius, and typography.
9
+
10
+ [Back to Introduction](?path=/docs/docs-introduction--docs)
11
+
12
+ ## Core
13
+
14
+ ### Primitives
15
+
16
+ - [View](?path=/docs/bumper-core-primitives-view--docs) — Base layout box. Backgrounds, borders, spacing, flex.
17
+ - [Pressable](?path=/docs/bumper-core-primitives-pressable--docs) — Polymorphic interactive primitive with hover/press styles.
18
+ - [Stack](?path=/docs/bumper-core-primitives-stack--docs) — Flex container. Includes HStack and VStack presets.
19
+ - [Center](?path=/docs/bumper-core-primitives-center--docs) — View with centered content.
20
+ - [Image](?path=/docs/bumper-core-primitives-image--docs) — Image component from Tamagui.
21
+ - [ScrollView](?path=/docs/bumper-core-primitives-scrollview--docs) — Scrollable container.
22
+
23
+ ## Content
24
+
25
+ - [Typography](?path=/docs/bumper-content-typography--docs) — Foundational text component. All typographic variants.
26
+ - [TypographyIcon](?path=/docs/bumper-content-typographyicon--docs) — Inline icon within Typography context. Inherits color.
27
+ - [TypographyLink](?path=/docs/bumper-content-typographylink--docs) — Interactive link with underline and disabled states.
28
+ - [Icon](?path=/docs/bumper-content-icon--docs) — Standalone icon wrapper. Color and size via tokens.
29
+
30
+ ## Data Displays
31
+
32
+ - [Badge](?path=/docs/bumper-data-displays-badge--docs) — Numeric count or dot indicator.
33
+
34
+ ## Loading
35
+
36
+ - [Loader](?path=/docs/bumper-loading-loader--docs) — Animated circular spinner.
@@ -0,0 +1,31 @@
1
+ import { Meta, Title, Subtitle, Primary, Controls, Canvas } from '@storybook/blocks';
2
+ import * as IconStories from './Icon.stories';
3
+ import * as IconFeatures from './Icon.features.stories';
4
+
5
+ <Meta of={IconStories} />
6
+ <Title />
7
+ <Subtitle />
8
+
9
+ <Primary />
10
+ <Controls />
11
+
12
+ ## Overview
13
+
14
+ `Icon` is a standalone icon wrapper that applies color and size to an icon element. Pass any icon from `@ornikar/kitt-icons/ornicons` via the `icon` prop. Defaults to `$icon.m` (20px) and `$content.base.hi` color. For icons inside `Typography.Text`, use `Typography.Icon` instead — it inherits color from the typography context.
15
+
16
+ ## Sizes
17
+
18
+ Use `size` to control the icon dimensions: `$icon.s` (16px), `$icon.m` (20px), or `$icon.l` (24px).
19
+
20
+ <Canvas of={IconFeatures.Sizes} />
21
+
22
+ ## Colors
23
+
24
+ Use `color` with semantic `$content.*` tokens. The icon element receives the resolved color via `cloneElement`.
25
+
26
+ <Canvas of={IconFeatures.Colors} />
27
+
28
+ ## Related
29
+
30
+ - [TypographyIcon](?path=/docs/bumper-content-typographyicon--docs)
31
+ - [Typography](?path=/docs/bumper-content-typography--docs)
@@ -6,7 +6,6 @@ import { Icon } from './Icon';
6
6
  const meta: Meta<typeof Icon> = {
7
7
  title: 'Bumper/Content/Icon',
8
8
  component: Icon,
9
- tags: ['autodocs'],
10
9
  argTypes: {
11
10
  size: {
12
11
  control: 'select',
@@ -0,0 +1,68 @@
1
+ import { Meta, Title, Subtitle, Primary, Controls, Canvas } from '@storybook/blocks';
2
+ import * as TypographyStories from './Typography.stories';
3
+ import * as TypographyFeatures from './Typography.features.stories';
4
+
5
+ <Meta of={TypographyStories} />
6
+ <Title />
7
+ <Subtitle />
8
+
9
+ <Primary />
10
+ <Controls />
11
+
12
+ ## Overview
13
+
14
+ `Typography.Text` is the foundational text component in Bumper. It supports four variant families — heading, body, label, and content-caps — each with a fixed font weight. Defaults to `body-m` / `regular`. Use `color` with `$content.*` tokens and `variant` to control size and style.
15
+
16
+ ## Default values
17
+
18
+ When no props are specified, `Typography.Text` renders as `body-m` with `regular` weight and `$content.base.hi` color.
19
+
20
+ <Canvas of={TypographyFeatures.DefaultValues} />
21
+
22
+ ## Heading variants
23
+
24
+ Heading variants range from `heading-2xl` down to `heading-2xs`. All headings use `semibold` weight. Use these for titles and section headers.
25
+
26
+ <Canvas of={TypographyFeatures.HeadingVariants} />
27
+
28
+ ## Body variants
29
+
30
+ Body variants range from `body-xl` to `body-xs`. They support both `regular` and `bold` weights. Use `body-m` as the default for paragraph text.
31
+
32
+ <Canvas of={TypographyFeatures.BodyVariants} />
33
+
34
+ ### Bold body
35
+
36
+ Set `weight="bold"` on body variants to emphasize important text within paragraphs.
37
+
38
+ <Canvas of={TypographyFeatures.BodyVariantsBold} />
39
+
40
+ ## Label variants
41
+
42
+ Label variants (`label-l`, `label-m`, `label-s`) use `semibold` weight. Use them for form labels, button text, and short UI copy that needs emphasis.
43
+
44
+ <Canvas of={TypographyFeatures.LabelVariants} />
45
+
46
+ ## Content caps variants
47
+
48
+ Content caps variants (`content-caps-3xl` to `content-caps-xs`) use the GTStandardNarrow font with automatic `uppercase` transformation and `bold` weight. Use them for tags, badges, and short categorical labels.
49
+
50
+ <Canvas of={TypographyFeatures.ContentCapsVariants} />
51
+
52
+ ## Semantic header components
53
+
54
+ Use `Typography.Header1` through `Typography.Header6` for semantically correct headings. These render with the `heading` ARIA role and the appropriate `aria-level`.
55
+
56
+ <Canvas of={TypographyFeatures.HeaderComponents} />
57
+
58
+ ## Context inheritance
59
+
60
+ Nested `Typography.Text` components inherit `variant`, `weight`, and `color` from their parent. Child components can override any inherited value by setting the prop explicitly.
61
+
62
+ <Canvas of={TypographyFeatures.ContextInheritance} />
63
+
64
+ ## Related
65
+
66
+ - [TypographyIcon](?path=/docs/bumper-content-typographyicon--docs)
67
+ - [TypographyLink](?path=/docs/bumper-content-typographylink--docs)
68
+ - [Icon](?path=/docs/bumper-content-icon--docs)
@@ -6,7 +6,6 @@ import { Typography } from '.';
6
6
  const meta: Meta<Extract<TypographyTextProps, BodyProps>> = {
7
7
  title: 'Bumper/Content/Typography',
8
8
  component: Typography.Text,
9
- tags: ['autodocs'],
10
9
  argTypes: {
11
10
  variant: {
12
11
  control: 'select',
@@ -0,0 +1,50 @@
1
+ import { Meta, Title, Subtitle, Primary, Controls, Canvas } from '@storybook/blocks';
2
+ import * as TypographyIconStories from './TypographyIcon.stories';
3
+ import * as TypographyIconFeatures from './TypographyIcon.features.stories';
4
+
5
+ <Meta of={TypographyIconStories} />
6
+ <Title />
7
+ <Subtitle />
8
+
9
+ <Primary />
10
+ <Controls />
11
+
12
+ ## Overview
13
+
14
+ `Typography.Icon` renders an icon inline within a `Typography.Text` block. It automatically inherits the parent's `color` from the typography context. Use it when placing icons alongside text — it ensures the icon stays color-consistent with surrounding copy.
15
+
16
+ ## Explicit color
17
+
18
+ Pass `color` directly to override the inherited value. Use semantic `$content.*` tokens to convey meaning — `$content.accent`, `$content.success`, `$content.warning`, `$content.danger`.
19
+
20
+ <Canvas of={TypographyIconFeatures.WithExplicitColor} />
21
+
22
+ ## Color inheritance from Typography
23
+
24
+ When `color` is omitted, `Typography.Icon` reads the nearest parent `Typography.Text` color from context. This keeps icon and text colors in sync automatically.
25
+
26
+ <Canvas of={TypographyIconFeatures.InheritFromTypography} />
27
+
28
+ ## Overriding inherited color
29
+
30
+ Set `color` explicitly on `Typography.Icon` to break from the parent's color — useful when an icon should convey a different status than its surrounding text.
31
+
32
+ <Canvas of={TypographyIconFeatures.OverrideInheritedColor} />
33
+
34
+ ## Sizes
35
+
36
+ Use `size` to match the icon to its typographic context: `$icon.s` (16px) for small text, `$icon.m` (20px) for body text, `$icon.l` (24px) for headings.
37
+
38
+ <Canvas of={TypographyIconFeatures.DifferentSizes} />
39
+
40
+ ## Nested inheritance
41
+
42
+ In deeply nested `Typography.Text` trees, icons inherit color from their closest ancestor. A child `Typography.Text` that overrides color will also change the color of its nested icons.
43
+
44
+ <Canvas of={TypographyIconFeatures.NestedTypographyInheritance} />
45
+
46
+ ## Related
47
+
48
+ - [Typography](?path=/docs/bumper-content-typography--docs)
49
+ - [Icon](?path=/docs/bumper-content-icon--docs)
50
+ - [TypographyLink](?path=/docs/bumper-content-typographylink--docs)
@@ -6,7 +6,6 @@ import { TypographyIcon } from './TypographyIcon';
6
6
  const meta: Meta<typeof TypographyIcon> = {
7
7
  title: 'Bumper/Content/TypographyIcon',
8
8
  component: TypographyIcon,
9
- tags: ['autodocs'],
10
9
  argTypes: {
11
10
  icon: {
12
11
  control: false,
@@ -0,0 +1,49 @@
1
+ import { Meta, Title, Subtitle, Primary, Controls, Canvas } from '@storybook/blocks';
2
+ import * as TypographyLinkStories from './TypographyLink.stories';
3
+ import * as TypographyLinkFeatures from './TypographyLink.features.stories';
4
+
5
+ <Meta of={TypographyLinkStories} />
6
+ <Title />
7
+ <Subtitle />
8
+
9
+ <Primary />
10
+ <Controls />
11
+
12
+ ## Overview
13
+
14
+ `Typography.Link` is an interactive text component with `role="link"`. It renders underlined by default and removes the underline on hover. It inherits all typography props (`variant`, `weight`, `color`) from `Typography.Text`. Use it for inline navigational links within text blocks.
15
+
16
+ ## Enabled state
17
+
18
+ By default, `disabled` is `false` — the link shows a pointer cursor and responds to `onPress`.
19
+
20
+ <Canvas of={TypographyLinkFeatures.DisabledFalse} />
21
+
22
+ ## Disabled state
23
+
24
+ Set `disabled` to disable the link. The cursor changes to `not-allowed`, `onPress` is removed, and the text color switches to `$content.disabled`.
25
+
26
+ <Canvas of={TypographyLinkFeatures.DisabledTrue} />
27
+
28
+ ## With underline (default)
29
+
30
+ By default, `noUnderline` is `false` — the link renders with an underline that disappears on hover.
31
+
32
+ <Canvas of={TypographyLinkFeatures.NoUnderlineFalse} />
33
+
34
+ ## Without underline
35
+
36
+ Set `noUnderline` to remove the underline entirely. Use this for links where the context already makes the interactive nature obvious.
37
+
38
+ <Canvas of={TypographyLinkFeatures.NoUnderlineTrue} />
39
+
40
+ ## Hover state
41
+
42
+ On hover, the underline is removed. When `noUnderline` is already set or the link is `disabled`, hover has no visible effect.
43
+
44
+ <Canvas of={TypographyLinkFeatures.StateHover} />
45
+
46
+ ## Related
47
+
48
+ - [Typography](?path=/docs/bumper-content-typography--docs)
49
+ - [TypographyIcon](?path=/docs/bumper-content-typographyicon--docs)
@@ -8,7 +8,6 @@ import { TypographyLink } from './TypographyLink';
8
8
  const meta: Meta<Extract<TypographyLinkProps, BodyProps>> = {
9
9
  title: 'Bumper/Content/TypographyLink',
10
10
  component: TypographyLink,
11
- tags: ['autodocs'],
12
11
  argTypes: {
13
12
  variant: {
14
13
  control: 'select',
@@ -0,0 +1,31 @@
1
+ import { Meta, Title, Subtitle, Primary, Controls, Canvas } from '@storybook/blocks';
2
+ import * as CenterStories from './Center.stories';
3
+ import * as CenterFeatures from './Center.features.stories';
4
+
5
+ <Meta of={CenterStories} />
6
+ <Title />
7
+ <Subtitle />
8
+
9
+ <Primary />
10
+ <Controls />
11
+
12
+ ## Overview
13
+
14
+ `Center` is a styled `View` with `justifyContent: center` and `alignItems: center` baked in. Use it whenever you need to center content within a fixed-size container — icons, avatars, placeholder blocks, or any content that should sit in the middle of its parent.
15
+
16
+ ## Centering text
17
+
18
+ Give `Center` explicit `width` and `height` to create a fixed container. Text and other children are automatically centered both horizontally and vertically.
19
+
20
+ <Canvas of={CenterFeatures.CenteringText} />
21
+
22
+ ## Circular centering
23
+
24
+ Combine `Center` with `borderRadius="$radius.circle"` and equal `width`/`height` to create circular containers — useful for avatars, step indicators, or numbered badges.
25
+
26
+ <Canvas of={CenterFeatures.CircularCentering} />
27
+
28
+ ## Related
29
+
30
+ - [View](?path=/docs/bumper-core-primitives-view--docs)
31
+ - [Stack](?path=/docs/bumper-core-primitives-stack--docs)
@@ -6,7 +6,6 @@ import { Center } from './Center';
6
6
  const meta: Meta<typeof Center> = {
7
7
  title: 'Bumper/Core/Primitives/Center',
8
8
  component: Center,
9
- tags: ['autodocs'],
10
9
  argTypes: {
11
10
  backgroundColor: backgroundColorArgType,
12
11
  padding: spaceArgType,
@@ -0,0 +1,15 @@
1
+ import { Meta, Title, Subtitle, Primary, Controls } from '@storybook/blocks';
2
+ import * as ImageStories from './Image.stories';
3
+
4
+ <Meta of={ImageStories} />
5
+ <Title />
6
+ <Subtitle />
7
+
8
+ <Primary />
9
+ <Controls />
10
+
11
+ ## Overview
12
+
13
+ `Image` is Tamagui's image primitive, re-exported from `@tamagui/image`. Use it to display images with Bumper's `$size.*` tokens for `width` and `height`. Set `resizeMode` to control how the image fills its container: `"contain"` preserves aspect ratio within bounds, `"cover"` fills the container and crops, `"stretch"` distorts to fit, and `"center"` keeps the original size.
14
+
15
+ Pass the image source via the `source` prop as `{ uri: string }` for remote images or a require call for local assets.
@@ -5,7 +5,6 @@ import { Image } from './Image';
5
5
  const meta: Meta<typeof Image> = {
6
6
  title: 'Bumper/Core/Primitives/Image',
7
7
  component: Image,
8
- tags: ['autodocs'],
9
8
  argTypes: {
10
9
  source: {
11
10
  table: { disable: true },
@@ -0,0 +1,37 @@
1
+ import { Meta, Title, Subtitle, Primary, Controls, Canvas } from '@storybook/blocks';
2
+ import * as PressableStories from './Pressable.stories';
3
+ import * as PressableFeatures from './Pressable.features.stories';
4
+
5
+ <Meta of={PressableStories} />
6
+ <Title />
7
+ <Subtitle />
8
+
9
+ <Primary />
10
+ <Controls />
11
+
12
+ ## Overview
13
+
14
+ `Pressable` is a polymorphic interactive primitive that renders as a button with `cursor: pointer` and `role="button"`. Use it to make any layout element tappable — it wraps a Tamagui component (defaults to `View`) and adds press/hover interaction styles.
15
+
16
+ ## Hover effects
17
+
18
+ Use `hoverStyle` to apply visual feedback on hover. Common patterns include changing `backgroundColor`, scaling up with `scale`, or reducing `opacity`.
19
+
20
+ <Canvas of={PressableFeatures.HoverEffects} />
21
+
22
+ ## Press effects
23
+
24
+ Use `pressStyle` to give immediate tactile feedback on press. Combine `scale`, `backgroundColor`, `opacity`, and `rotateZ` for richer interactions.
25
+
26
+ <Canvas of={PressableFeatures.PressEffects} />
27
+
28
+ ## Polymorphic rendering
29
+
30
+ Pass the `as` prop to render `Pressable` as a different Tamagui component. Use `as={HStack}` or `as={VStack}` when you need a pressable flex container with a specific direction.
31
+
32
+ <Canvas of={PressableFeatures.PolymorphicAs} />
33
+
34
+ ## Related
35
+
36
+ - [View](?path=/docs/bumper-core-primitives-view--docs)
37
+ - [Stack](?path=/docs/bumper-core-primitives-stack--docs)
@@ -7,7 +7,6 @@ import { Pressable } from './Pressable';
7
7
  const meta: Meta<typeof Pressable> = {
8
8
  title: 'Bumper/Core/Primitives/Pressable',
9
9
  component: Pressable,
10
- tags: ['autodocs'],
11
10
  argTypes: {
12
11
  backgroundColor: backgroundColorArgType,
13
12
  padding: spaceArgType,
@@ -0,0 +1,36 @@
1
+ import { Meta, Title, Subtitle, Primary, Controls, Canvas } from '@storybook/blocks';
2
+ import * as ScrollViewStories from './ScrollView.stories';
3
+ import * as ScrollViewFeatures from './ScrollView.features.stories';
4
+
5
+ <Meta of={ScrollViewStories} />
6
+ <Title />
7
+ <Subtitle />
8
+
9
+ <Primary />
10
+ <Controls />
11
+
12
+ ## Overview
13
+
14
+ `ScrollView` is Tamagui's scrollable container, re-exported from `@tamagui/scroll-view`. Use it when content exceeds the available space and needs to be scrollable. Give it a fixed `height` (and optionally `width`) so the scroll area has clear bounds.
15
+
16
+ ## Horizontal scrolling
17
+
18
+ Set `horizontal` to arrange and scroll content on the horizontal axis. Useful for carousels, tag lists, or any horizontally overflowing content.
19
+
20
+ <Canvas of={ScrollViewFeatures.HorizontalScroll} />
21
+
22
+ ## Hidden scroll indicators
23
+
24
+ Set `showsVerticalScrollIndicator={false}` or `showsHorizontalScrollIndicator={false}` to hide native scrollbars. Use this for cleaner UIs where the scroll affordance is implicit.
25
+
26
+ <Canvas of={ScrollViewFeatures.HiddenIndicators} />
27
+
28
+ ## Disabled scrolling
29
+
30
+ Set `scrollEnabled={false}` to prevent scrolling entirely. Use this when content should be visible but not interactable — for example, in a preview or locked state.
31
+
32
+ <Canvas of={ScrollViewFeatures.ScrollDisabled} />
33
+
34
+ ## Related
35
+
36
+ - [View](?path=/docs/bumper-core-primitives-view--docs)
@@ -7,7 +7,6 @@ import { ScrollView } from './ScrollView';
7
7
  const meta: Meta<typeof ScrollView> = {
8
8
  title: 'Bumper/Core/Primitives/ScrollView',
9
9
  component: ScrollView,
10
- tags: ['autodocs'],
11
10
  argTypes: {
12
11
  horizontal: {
13
12
  control: 'boolean',
@@ -0,0 +1,55 @@
1
+ import { Meta, Title, Subtitle, Primary, Controls, Canvas } from '@storybook/blocks';
2
+ import * as StackStories from './Stack.stories';
3
+ import * as StackFeatures from './Stack.features.stories';
4
+
5
+ <Meta of={StackStories} />
6
+ <Title />
7
+ <Subtitle />
8
+
9
+ <Primary />
10
+ <Controls />
11
+
12
+ ## Overview
13
+
14
+ `Stack` is the base flex container from Tamagui. Bumper also exports `HStack` (row direction) and `VStack` (column direction) as convenient presets. Use these instead of setting `flexDirection` manually on `View` when building layouts.
15
+
16
+ ## VStack
17
+
18
+ Use `VStack` to arrange children vertically. Set `gap` with `$space.*` tokens to control spacing between items.
19
+
20
+ <Canvas of={StackFeatures.VStackBasic} />
21
+
22
+ ## HStack
23
+
24
+ Use `HStack` to arrange children horizontally. Same API as `VStack` but with `flexDirection: row`.
25
+
26
+ <Canvas of={StackFeatures.HStackBasic} />
27
+
28
+ ## Wrapping
29
+
30
+ Set `flexWrap="wrap"` on `HStack` with a constrained `maxWidth` to create flowing layouts where items wrap to the next line.
31
+
32
+ <Canvas of={StackFeatures.FlexWrap} />
33
+
34
+ ## Nested stacks
35
+
36
+ Combine `VStack` and `HStack` to build complex layouts. Nest stacks to create sections with mixed directions.
37
+
38
+ <Canvas of={StackFeatures.NestedStacks} />
39
+
40
+ ## Flex grow
41
+
42
+ Use `flexGrow` on children to distribute available space. Fixed-width children sit alongside flexible ones.
43
+
44
+ <Canvas of={StackFeatures.FlexGrowExample} />
45
+
46
+ ## Grid-like layout
47
+
48
+ Combine nested `HStack` rows inside a `VStack` with `flexGrow={1}` on each cell to build uniform grid layouts.
49
+
50
+ <Canvas of={StackFeatures.GridLikeLayout} />
51
+
52
+ ## Related
53
+
54
+ - [View](?path=/docs/bumper-core-primitives-view--docs)
55
+ - [Center](?path=/docs/bumper-core-primitives-center--docs)
@@ -7,7 +7,6 @@ import { View } from './View';
7
7
  const meta: Meta<typeof Stack> = {
8
8
  title: 'Bumper/Core/Primitives/Stack',
9
9
  component: Stack,
10
- tags: ['autodocs'],
11
10
  argTypes: {
12
11
  flexDirection: {
13
12
  control: 'select',
@@ -0,0 +1,86 @@
1
+ import { Meta, Title, Subtitle, Primary, Controls, Canvas } from '@storybook/blocks';
2
+ import * as ViewStories from './View.stories';
3
+ import * as ViewFeatures from './View.features.stories';
4
+
5
+ <Meta of={ViewStories} />
6
+ <Title />
7
+ <Subtitle />
8
+
9
+ <Primary />
10
+ <Controls />
11
+
12
+ ## Overview
13
+
14
+ `View` is the foundational layout primitive in Bumper, re-exported from Tamagui's `View`. Use it as the base building block for backgrounds, borders, spacing, and flex layouts. All spacing and color values should use Bumper's semantic tokens (`$bg.*`, `$space.*`, `$radius.*`, `$border.*`).
15
+
16
+ ## Background colors
17
+
18
+ Use `backgroundColor` with semantic `$bg.*` tokens to apply surface colors. Choose `$bg.base.low.default` for subtle backgrounds, `$bg.base.mid.default` for standard surfaces, and `$bg.accent.default` or `$bg.promo.hi.default` for high-emphasis areas that require contrasted text.
19
+
20
+ <Canvas of={ViewFeatures.BackgroundColors} />
21
+
22
+ ## Borders and radius
23
+
24
+ Combine `borderWidth`, `borderColor`, and `borderRadius` to define the shape and outline of a `View`. Radius tokens range from `$radius.none` (sharp corners) to `$radius.circle` (fully round). Use `$radius.m` as the default for cards and containers.
25
+
26
+ <Canvas of={ViewFeatures.BordersAndRadius} />
27
+
28
+ ### Border colors
29
+
30
+ Border color tokens follow the same semantic naming as backgrounds. Use `$border.base.mid` for standard outlines and semantic tokens like `$border.info`, `$border.success`, `$border.warning`, or `$border.danger` to convey status.
31
+
32
+ <Canvas of={ViewFeatures.BorderColors} />
33
+
34
+ ## Padding
35
+
36
+ Use `padding` with `$space.*` tokens to control inner spacing. Available values range from `$space.none` (0) to `$space.32`.
37
+
38
+ <Canvas of={ViewFeatures.PaddingVariants} />
39
+
40
+ ### Directional padding
41
+
42
+ Use `paddingTop`, `paddingBottom`, `paddingLeft`, `paddingRight`, `paddingHorizontal`, and `paddingVertical` when you need asymmetric inner spacing.
43
+
44
+ <Canvas of={ViewFeatures.DirectionalPadding} />
45
+
46
+ ## Margin
47
+
48
+ Use `margin` with `$space.*` tokens to control outer spacing between elements.
49
+
50
+ <Canvas of={ViewFeatures.MarginVariants} />
51
+
52
+ ### Directional margin
53
+
54
+ Use directional margin props (`marginTop`, `marginBottom`, `marginHorizontal`, `marginVertical`) for asymmetric outer spacing.
55
+
56
+ <Canvas of={ViewFeatures.DirectionalMargin} />
57
+
58
+ ## Flex layout
59
+
60
+ `View` supports all flexbox properties. Use `flexDirection="row"` for horizontal layouts and `flexGrow` to distribute available space between children.
61
+
62
+ <Canvas of={ViewFeatures.FlexLayout} />
63
+
64
+ ### Alignment
65
+
66
+ Combine `alignItems` and `justifyContent` to position children within the container. Use `stretch` with `space-between` when children should fill the cross axis and be evenly distributed.
67
+
68
+ <Canvas of={ViewFeatures.FlexAlignment} />
69
+
70
+ ### Wrapping
71
+
72
+ Set `flexWrap="wrap"` with `gap` to create grid-like layouts where items flow to the next line when the container runs out of horizontal space.
73
+
74
+ <Canvas of={ViewFeatures.FlexWrap} />
75
+
76
+ ## Overflow behavior
77
+
78
+ Use `overflow="hidden"` to clip content that exceeds the container's dimensions, or `overflow="scroll"` to make it scrollable.
79
+
80
+ <Canvas of={ViewFeatures.OverflowBehavior} />
81
+
82
+ ## Related
83
+
84
+ - [Stack](?path=/docs/bumper-core-primitives-stack--docs)
85
+ - [Center](?path=/docs/bumper-core-primitives-center--docs)
86
+ - [Pressable](?path=/docs/bumper-core-primitives-pressable--docs)
@@ -5,7 +5,6 @@ import { View } from './View';
5
5
  const meta: Meta<typeof View> = {
6
6
  title: 'Bumper/Core/Primitives/View',
7
7
  component: View,
8
- tags: ['autodocs'],
9
8
  argTypes: {
10
9
  backgroundColor: backgroundColorArgType,
11
10
  padding: spaceArgType,
@@ -0,0 +1,32 @@
1
+ import { Meta, Title, Subtitle, Primary, Controls, Canvas } from '@storybook/blocks';
2
+ import * as BadgeStories from './Badge.stories';
3
+ import * as BadgeFeatures from './Badge.features.stories';
4
+
5
+ <Meta of={BadgeStories} />
6
+ <Title />
7
+ <Subtitle />
8
+
9
+ <Primary />
10
+ <Controls />
11
+
12
+ ## Overview
13
+
14
+ `Badge` displays a numeric count or a simple dot indicator. Use it to flag unread items, notifications, or new content. It renders as a circular red pill (`$bg.danger.hi`) with white text. When `count` exceeds `maxCount` (default: 9), it displays `"{max}+"`.
15
+
16
+ ## Dot (no count)
17
+
18
+ Omit `count` entirely to render the badge as an 8px dot. Use this when you want to flag new or unread content without surfacing an exact number.
19
+
20
+ <Canvas of={BadgeFeatures.WithoutCount} />
21
+
22
+ ## Count values
23
+
24
+ Pass `count` to display a numeric value. The badge auto-sizes its width to fit the number. A count of `0` is rendered literally.
25
+
26
+ <Canvas of={BadgeFeatures.WithCount} />
27
+
28
+ ## Maximum count
29
+
30
+ When `count` exceeds `maxCount`, the badge displays `"{maxCount}+"`. The default `maxCount` is `9`. Set a custom `maxCount` for higher thresholds like `99` or `999`.
31
+
32
+ <Canvas of={BadgeFeatures.WithMaximumCount} />
@@ -4,7 +4,6 @@ import { Badge } from './Badge';
4
4
  const meta: Meta<typeof Badge> = {
5
5
  title: 'Bumper/Data Displays/Badge',
6
6
  component: Badge,
7
- tags: ['autodocs'],
8
7
  argTypes: {
9
8
  count: {
10
9
  control: 'number',
@@ -0,0 +1,26 @@
1
+ import { Meta, Title, Subtitle, Primary, Controls, Canvas } from '@storybook/blocks';
2
+ import * as LoaderStories from './Loader.stories';
3
+ import * as LoaderFeatures from './Loader.features.stories';
4
+
5
+ <Meta of={LoaderStories} />
6
+ <Title />
7
+ <Subtitle />
8
+
9
+ <Primary />
10
+ <Controls />
11
+
12
+ ## Overview
13
+
14
+ `Loader` is an animated circular spinner built with `react-native-reanimated`. It loops continuously and comes in two sizes. Defaults to `size="page"` (48px) with an accent-colored foreground. Use `size="icon"` (20px) for inline loading indicators next to text or buttons.
15
+
16
+ ## Sizes
17
+
18
+ Use `size="icon"` (20px) for compact inline loaders and `size="page"` (48px) for full-page or section-level loading states.
19
+
20
+ <Canvas of={LoaderFeatures.Sizes} />
21
+
22
+ ## On contrasted backgrounds
23
+
24
+ Set `isOnContrasted` when the loader sits on a dark or accent background. This switches the foreground color from `$content.accent` to `$border.base.onContrasted.hi` for proper contrast.
25
+
26
+ <Canvas of={LoaderFeatures.OnContrasted} />
@@ -4,7 +4,6 @@ import { Loader } from './Loader';
4
4
  const meta: Meta<typeof Loader> = {
5
5
  title: 'Bumper/Loading/Loader',
6
6
  component: Loader,
7
- tags: ['autodocs'],
8
7
  argTypes: {
9
8
  size: {
10
9
  control: 'select',