@retray-dev/ui-kit 6.1.0 → 7.0.1
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/COMPONENTS.md +447 -13
- package/EXAMPLES.md +248 -0
- package/README.md +11 -10
- package/dist/Accordion.d.mts +28 -0
- package/dist/Accordion.d.ts +28 -0
- package/dist/Accordion.js +340 -0
- package/dist/Accordion.mjs +6 -0
- package/dist/AlertBanner.d.mts +16 -0
- package/dist/AlertBanner.d.ts +16 -0
- package/dist/AlertBanner.js +247 -0
- package/dist/AlertBanner.mjs +5 -0
- package/dist/Avatar.d.mts +20 -0
- package/dist/Avatar.d.ts +20 -0
- package/dist/Avatar.js +234 -0
- package/dist/Avatar.mjs +3 -0
- package/dist/Badge.d.mts +26 -0
- package/dist/Badge.d.ts +26 -0
- package/dist/Badge.js +247 -0
- package/dist/Badge.mjs +4 -0
- package/dist/Button.d.mts +25 -0
- package/dist/Button.d.ts +25 -0
- package/dist/Button.js +414 -0
- package/dist/Button.mjs +8 -0
- package/dist/ButtonGroup.d.mts +26 -0
- package/dist/ButtonGroup.d.ts +26 -0
- package/dist/ButtonGroup.js +52 -0
- package/dist/ButtonGroup.mjs +2 -0
- package/dist/Card.d.mts +39 -0
- package/dist/Card.d.ts +39 -0
- package/dist/Card.js +329 -0
- package/dist/Card.mjs +7 -0
- package/dist/CategoryStrip.d.mts +26 -0
- package/dist/CategoryStrip.d.ts +26 -0
- package/dist/CategoryStrip.js +396 -0
- package/dist/CategoryStrip.mjs +9 -0
- package/dist/Checkbox.d.mts +14 -0
- package/dist/Checkbox.d.ts +14 -0
- package/dist/Checkbox.js +304 -0
- package/dist/Checkbox.mjs +7 -0
- package/dist/Chip.d.mts +31 -0
- package/dist/Chip.d.ts +31 -0
- package/dist/Chip.js +370 -0
- package/dist/Chip.mjs +8 -0
- package/dist/ConfirmDialog.d.mts +15 -0
- package/dist/ConfirmDialog.d.ts +15 -0
- package/dist/ConfirmDialog.js +530 -0
- package/dist/ConfirmDialog.mjs +9 -0
- package/dist/CurrencyDisplay.d.mts +24 -0
- package/dist/CurrencyDisplay.d.ts +24 -0
- package/dist/CurrencyDisplay.js +189 -0
- package/dist/CurrencyDisplay.mjs +3 -0
- package/dist/CurrencyInput.d.mts +26 -0
- package/dist/CurrencyInput.d.ts +26 -0
- package/dist/CurrencyInput.js +404 -0
- package/dist/CurrencyInput.mjs +7 -0
- package/dist/DetailRow.d.mts +32 -0
- package/dist/DetailRow.d.ts +32 -0
- package/dist/DetailRow.js +275 -0
- package/dist/DetailRow.mjs +4 -0
- package/dist/EmptyState.d.mts +27 -0
- package/dist/EmptyState.d.ts +27 -0
- package/dist/EmptyState.js +503 -0
- package/dist/EmptyState.mjs +9 -0
- package/dist/Form.d.mts +52 -0
- package/dist/Form.d.ts +52 -0
- package/dist/Form.js +204 -0
- package/dist/Form.mjs +3 -0
- package/dist/IconButton.d.mts +22 -0
- package/dist/IconButton.d.ts +22 -0
- package/dist/IconButton.js +383 -0
- package/dist/IconButton.mjs +7 -0
- package/dist/Input.d.mts +23 -0
- package/dist/Input.d.ts +23 -0
- package/dist/Input.js +351 -0
- package/dist/Input.mjs +6 -0
- package/dist/LabelValue.d.mts +16 -0
- package/dist/LabelValue.d.ts +16 -0
- package/dist/LabelValue.js +225 -0
- package/dist/LabelValue.mjs +4 -0
- package/dist/ListGroup.d.mts +34 -0
- package/dist/ListGroup.d.ts +34 -0
- package/dist/ListGroup.js +217 -0
- package/dist/ListGroup.mjs +4 -0
- package/dist/ListItem.d.mts +64 -0
- package/dist/ListItem.d.ts +64 -0
- package/dist/ListItem.js +430 -0
- package/dist/ListItem.mjs +8 -0
- package/dist/MediaCard.d.mts +39 -0
- package/dist/MediaCard.d.ts +39 -0
- package/dist/MediaCard.js +427 -0
- package/dist/MediaCard.mjs +8 -0
- package/dist/MenuGroup.d.mts +34 -0
- package/dist/MenuGroup.d.ts +34 -0
- package/dist/MenuGroup.js +217 -0
- package/dist/MenuGroup.mjs +4 -0
- package/dist/MenuItem.d.mts +48 -0
- package/dist/MenuItem.d.ts +48 -0
- package/dist/MenuItem.js +403 -0
- package/dist/MenuItem.mjs +8 -0
- package/dist/MonthPicker.d.mts +20 -0
- package/dist/MonthPicker.d.ts +20 -0
- package/dist/MonthPicker.js +234 -0
- package/dist/MonthPicker.mjs +4 -0
- package/dist/Pressable.d.mts +34 -0
- package/dist/Pressable.d.ts +34 -0
- package/dist/Pressable.js +132 -0
- package/dist/Pressable.mjs +4 -0
- package/dist/Progress.d.mts +14 -0
- package/dist/Progress.d.ts +14 -0
- package/dist/Progress.js +191 -0
- package/dist/Progress.mjs +4 -0
- package/dist/RadioGroup.d.mts +19 -0
- package/dist/RadioGroup.d.ts +19 -0
- package/dist/RadioGroup.js +341 -0
- package/dist/RadioGroup.mjs +7 -0
- package/dist/Select.d.mts +22 -0
- package/dist/Select.d.ts +22 -0
- package/dist/Select.js +441 -0
- package/dist/Select.mjs +6 -0
- package/dist/Separator.d.mts +10 -0
- package/dist/Separator.d.ts +10 -0
- package/dist/Separator.js +156 -0
- package/dist/Separator.mjs +2 -0
- package/dist/Sheet.d.mts +81 -0
- package/dist/Sheet.d.ts +81 -0
- package/dist/Sheet.js +340 -0
- package/dist/Sheet.mjs +4 -0
- package/dist/Skeleton.d.mts +17 -0
- package/dist/Skeleton.d.ts +17 -0
- package/dist/Skeleton.js +205 -0
- package/dist/Skeleton.mjs +4 -0
- package/dist/Slider.d.mts +20 -0
- package/dist/Slider.d.ts +20 -0
- package/dist/Slider.js +232 -0
- package/dist/Slider.mjs +4 -0
- package/dist/Spinner.d.mts +12 -0
- package/dist/Spinner.d.ts +12 -0
- package/dist/Spinner.js +172 -0
- package/dist/Spinner.mjs +3 -0
- package/dist/Switch.d.mts +13 -0
- package/dist/Switch.d.ts +13 -0
- package/dist/Switch.js +261 -0
- package/dist/Switch.mjs +5 -0
- package/dist/Tabs.d.mts +27 -0
- package/dist/Tabs.d.ts +27 -0
- package/dist/Tabs.js +389 -0
- package/dist/Tabs.mjs +6 -0
- package/dist/Text.d.mts +12 -0
- package/dist/Text.d.ts +12 -0
- package/dist/Text.js +311 -0
- package/dist/Text.mjs +4 -0
- package/dist/Textarea.d.mts +16 -0
- package/dist/Textarea.d.ts +16 -0
- package/dist/Textarea.js +333 -0
- package/dist/Textarea.mjs +6 -0
- package/dist/Toast.d.mts +47 -0
- package/dist/Toast.d.ts +47 -0
- package/dist/Toast.js +185 -0
- package/dist/Toast.mjs +3 -0
- package/dist/Toggle.d.mts +33 -0
- package/dist/Toggle.d.ts +33 -0
- package/dist/Toggle.js +397 -0
- package/dist/Toggle.mjs +8 -0
- package/dist/VirtualList.d.mts +19 -0
- package/dist/VirtualList.d.ts +19 -0
- package/dist/VirtualList.js +38 -0
- package/dist/VirtualList.mjs +1 -0
- package/dist/chunk-2CE3TQVY.mjs +11 -0
- package/dist/chunk-2UYENBLV.mjs +49 -0
- package/dist/chunk-3BBOZ3OQ.mjs +41 -0
- package/dist/chunk-5IKW3VNC.mjs +43 -0
- package/dist/chunk-63357L2X.mjs +51 -0
- package/dist/chunk-6LQYY7HC.mjs +127 -0
- package/dist/chunk-6Q64UFIA.mjs +71 -0
- package/dist/chunk-76PFOSM2.mjs +41 -0
- package/dist/chunk-7H2OR44A.mjs +14 -0
- package/dist/chunk-A4MDAP7G.mjs +42 -0
- package/dist/chunk-AU2VDY4P.mjs +190 -0
- package/dist/chunk-BRKYVJVV.mjs +60 -0
- package/dist/chunk-CRYBX2CM.mjs +146 -0
- package/dist/chunk-DITNP6PL.mjs +106 -0
- package/dist/chunk-FTLJOUOQ.mjs +97 -0
- package/dist/chunk-GCWOGZYL.mjs +104 -0
- package/dist/chunk-GNGLDL6Z.mjs +60 -0
- package/dist/chunk-GPOUINK5.mjs +148 -0
- package/dist/chunk-HSPSMN6U.mjs +115 -0
- package/dist/chunk-IRRY3CRZ.mjs +82 -0
- package/dist/chunk-JB67UOB5.mjs +92 -0
- package/dist/chunk-JBLL7U3U.mjs +64 -0
- package/dist/chunk-KWCPOM6W.mjs +136 -0
- package/dist/chunk-KZJRQOIU.mjs +64 -0
- package/dist/chunk-L7E7TVEZ.mjs +145 -0
- package/dist/chunk-LG4DO3DK.mjs +174 -0
- package/dist/chunk-LWG526VX.mjs +139 -0
- package/dist/chunk-MN7OG7IY.mjs +96 -0
- package/dist/chunk-MX6HRKMI.mjs +29 -0
- package/dist/chunk-NC5ZTR2Y.mjs +32 -0
- package/dist/chunk-NQGVLMWG.mjs +90 -0
- package/dist/chunk-QCNARS3X.mjs +46 -0
- package/dist/chunk-QXGYKWI7.mjs +134 -0
- package/dist/chunk-QY3X2UYR.mjs +191 -0
- package/dist/chunk-RKLHUDZS.mjs +92 -0
- package/dist/chunk-RMMK64W5.mjs +54 -0
- package/dist/chunk-RR2VQLKE.mjs +190 -0
- package/dist/chunk-RTC3CFXF.mjs +29 -0
- package/dist/chunk-SBZYEV4S.mjs +61 -0
- package/dist/chunk-SOA2Z4RB.mjs +82 -0
- package/dist/chunk-SOYNZDVY.mjs +151 -0
- package/dist/chunk-T7XZ7H7Y.mjs +57 -0
- package/dist/chunk-TAJ2PQ2O.mjs +163 -0
- package/dist/chunk-U4N7WF4Z.mjs +108 -0
- package/dist/chunk-URDE3EUU.mjs +132 -0
- package/dist/chunk-URLL5JBR.mjs +245 -0
- package/dist/chunk-XDMN67KV.mjs +59 -0
- package/dist/chunk-Y6MXOREN.mjs +120 -0
- package/dist/chunk-YZJAFS4P.mjs +131 -0
- package/dist/index.d.mts +94 -852
- package/dist/index.d.ts +94 -852
- package/dist/index.js +1387 -942
- package/dist/index.mjs +50 -3844
- package/package.json +23 -14
- package/src/assets/fonts/Sohne-Bold.otf +0 -0
- package/src/assets/fonts/Sohne-BoldItalic.otf +0 -0
- package/src/assets/fonts/Sohne-ExtraBold.otf +0 -0
- package/src/assets/fonts/Sohne-ExtraBoldItalic.otf +0 -0
- package/src/assets/fonts/Sohne-ExtraLight.otf +0 -0
- package/src/assets/fonts/Sohne-ExtraLightItalic.otf +0 -0
- package/src/assets/fonts/Sohne-Italic.otf +0 -0
- package/src/assets/fonts/Sohne-Light.otf +0 -0
- package/src/assets/fonts/Sohne-LightItalic.otf +0 -0
- package/src/assets/fonts/Sohne-Medium.otf +0 -0
- package/src/assets/fonts/Sohne-MediumItalic.otf +0 -0
- package/src/assets/fonts/Sohne-Regular.otf +0 -0
- package/src/assets/fonts/Sohne-SemiBold.otf +0 -0
- package/src/assets/fonts/Sohne-SemiBoldItalic.otf +0 -0
- package/src/assets/fonts/SohneMono-Bold.otf +0 -0
- package/src/assets/fonts/SohneMono-BoldItalic.otf +0 -0
- package/src/assets/fonts/SohneMono-ExtraBold.otf +0 -0
- package/src/assets/fonts/SohneMono-ExtraBoldItalic.otf +0 -0
- package/src/assets/fonts/SohneMono-ExtraLight.otf +0 -0
- package/src/assets/fonts/SohneMono-ExtraLightItalic.otf +0 -0
- package/src/assets/fonts/SohneMono-Italic.otf +0 -0
- package/src/assets/fonts/SohneMono-Light.otf +0 -0
- package/src/assets/fonts/SohneMono-LightItalic.otf +0 -0
- package/src/assets/fonts/SohneMono-Medium.otf +0 -0
- package/src/assets/fonts/SohneMono-MediumItalic.otf +0 -0
- package/src/assets/fonts/SohneMono-Regular.otf +0 -0
- package/src/assets/fonts/SohneMono-SemiBold.otf +0 -0
- package/src/assets/fonts/SohneMono-SemiBoldItalic.otf +0 -0
- package/src/components/Accordion/Accordion.tsx +13 -15
- package/src/components/AlertBanner/AlertBanner.tsx +33 -12
- package/src/components/Avatar/Avatar.tsx +4 -2
- package/src/components/Badge/Badge.tsx +4 -2
- package/src/components/Button/Button.tsx +30 -29
- package/src/components/ButtonGroup/ButtonGroup.tsx +13 -10
- package/src/components/Card/Card.tsx +36 -65
- package/src/components/CategoryStrip/CategoryStrip.tsx +68 -58
- package/src/components/Checkbox/Checkbox.tsx +41 -55
- package/src/components/Chip/Chip.tsx +49 -84
- package/src/components/ConfirmDialog/ConfirmDialog.tsx +2 -2
- package/src/components/CurrencyDisplay/CurrencyDisplay.tsx +4 -2
- package/src/components/CurrencyInput/CurrencyInput.tsx +2 -2
- package/src/components/DetailRow/DetailRow.tsx +9 -7
- package/src/components/EmptyState/EmptyState.tsx +2 -2
- package/src/components/Form/Form.tsx +149 -0
- package/src/components/Form/index.ts +1 -0
- package/src/components/IconButton/IconButton.tsx +24 -20
- package/src/components/Input/Input.tsx +63 -50
- package/src/components/LabelValue/LabelValue.tsx +6 -4
- package/src/components/ListGroup/ListGroup.tsx +145 -0
- package/src/components/ListGroup/index.ts +1 -0
- package/src/components/ListItem/ListItem.tsx +30 -43
- package/src/components/MediaCard/MediaCard.tsx +31 -29
- package/src/components/MenuGroup/MenuGroup.tsx +145 -0
- package/src/components/MenuGroup/index.ts +1 -0
- package/src/components/MenuItem/MenuItem.tsx +29 -40
- package/src/components/MonthPicker/MonthPicker.tsx +14 -4
- package/src/components/Pressable/Pressable.tsx +27 -46
- package/src/components/Progress/Progress.tsx +21 -12
- package/src/components/RadioGroup/RadioGroup.tsx +55 -32
- package/src/components/Select/Select.tsx +23 -21
- package/src/components/Separator/Separator.tsx +1 -3
- package/src/components/Sheet/Sheet.tsx +85 -18
- package/src/components/Skeleton/Skeleton.tsx +25 -14
- package/src/components/Slider/Slider.tsx +13 -3
- package/src/components/Spinner/Spinner.tsx +1 -1
- package/src/components/Switch/Switch.tsx +70 -52
- package/src/components/Tabs/Tabs.tsx +59 -47
- package/src/components/Text/Text.tsx +3 -1
- package/src/components/Textarea/Textarea.tsx +44 -23
- package/src/components/Toast/Toast.tsx +6 -6
- package/src/components/Toggle/Toggle.tsx +86 -68
- package/src/components/VirtualList/VirtualList.tsx +60 -0
- package/src/components/VirtualList/index.ts +1 -0
- package/src/fonts.ts +38 -20
- package/src/index.ts +5 -1
- package/src/theme/colors.ts +53 -39
- package/src/theme/types.ts +3 -0
- package/src/tokens.ts +49 -39
- package/src/utils/animations.ts +58 -0
- package/src/utils/icons.ts +47 -20
- package/src/utils/useColorTransition.ts +40 -0
- package/src/utils/usePressScale.ts +75 -0
- package/src/assets/fonts/Poppins-Black.ttf +0 -0
- package/src/assets/fonts/Poppins-BlackItalic.ttf +0 -0
- package/src/assets/fonts/Poppins-Bold.ttf +0 -0
- package/src/assets/fonts/Poppins-BoldItalic.ttf +0 -0
- package/src/assets/fonts/Poppins-ExtraBold.ttf +0 -0
- package/src/assets/fonts/Poppins-ExtraBoldItalic.ttf +0 -0
- package/src/assets/fonts/Poppins-ExtraLight.ttf +0 -0
- package/src/assets/fonts/Poppins-ExtraLightItalic.ttf +0 -0
- package/src/assets/fonts/Poppins-Italic.ttf +0 -0
- package/src/assets/fonts/Poppins-Light.ttf +0 -0
- package/src/assets/fonts/Poppins-LightItalic.ttf +0 -0
- package/src/assets/fonts/Poppins-Medium.ttf +0 -0
- package/src/assets/fonts/Poppins-MediumItalic.ttf +0 -0
- package/src/assets/fonts/Poppins-Regular.ttf +0 -0
- package/src/assets/fonts/Poppins-SemiBold.ttf +0 -0
- package/src/assets/fonts/Poppins-SemiBoldItalic.ttf +0 -0
- package/src/assets/fonts/Poppins-Thin.ttf +0 -0
- package/src/assets/fonts/Poppins-ThinItalic.ttf +0 -0
package/COMPONENTS.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @retray-dev/ui-kit — Component Reference (
|
|
1
|
+
# @retray-dev/ui-kit — Component Reference (v7.0.1)
|
|
2
2
|
|
|
3
3
|
This file is the AI reference for this package. It is shipped inside the npm package so consuming projects can import it into their `CLAUDE.md` with:
|
|
4
4
|
|
|
@@ -42,16 +42,16 @@ export default function App() {
|
|
|
42
42
|
- `BottomSheetModalProvider` must be inside `GestureHandlerRootView`
|
|
43
43
|
- `ToastProvider` wraps children and renders `Toaster` (from `sonner-native`) internally
|
|
44
44
|
|
|
45
|
-
## Typography —
|
|
45
|
+
## Typography — Sohne (Required)
|
|
46
46
|
|
|
47
|
-
All components use **
|
|
47
|
+
All components use **Sohne** as the font family. You **must** load it before rendering any UI kit component.
|
|
48
48
|
|
|
49
49
|
```tsx
|
|
50
50
|
import { useFonts } from 'expo-font'
|
|
51
|
-
import {
|
|
51
|
+
import { SohneFonts } from '@retray-dev/ui-kit/fonts'
|
|
52
52
|
|
|
53
53
|
export default function App() {
|
|
54
|
-
const [fontsLoaded] = useFonts(
|
|
54
|
+
const [fontsLoaded] = useFonts(SohneFonts)
|
|
55
55
|
if (!fontsLoaded) return null
|
|
56
56
|
return (
|
|
57
57
|
// ... your providers and app
|
|
@@ -60,16 +60,16 @@ export default function App() {
|
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
**How it works:**
|
|
63
|
-
1. Import `
|
|
63
|
+
1. Import `SohneFonts` from `@retray-dev/ui-kit/fonts` (separate export path)
|
|
64
64
|
2. Pass it to `expo-font`'s `useFonts()` hook at your app root
|
|
65
65
|
3. Metro resolves font files from `node_modules/@retray-dev/ui-kit/src/assets/fonts/` at bundle time
|
|
66
|
-
4. All library components reference fonts by family name (e.g., `fontFamily: '
|
|
66
|
+
4. All library components reference fonts by family name (e.g., `fontFamily: 'Sohne-SemiBold'`)
|
|
67
67
|
|
|
68
68
|
**Included weights:**
|
|
69
|
-
-
|
|
70
|
-
-
|
|
69
|
+
- Sohne: `Sohne-ExtraLight`, `Sohne-Light`, `Sohne-Regular`, `Sohne-Medium`, `Sohne-SemiBold`, `Sohne-Bold`, `Sohne-ExtraBold` + italic variants
|
|
70
|
+
- SohneMono: `SohneMono-ExtraLight`, `SohneMono-Light`, `SohneMono-Regular`, `SohneMono-Medium`, `SohneMono-SemiBold`, `SohneMono-Bold`, `SohneMono-ExtraBold` + italic variants
|
|
71
71
|
|
|
72
|
-
**Total:
|
|
72
|
+
**Total: 28 font files** exported from the package. Font `.otf` files ship as raw assets in `src/assets/fonts/` — NOT bundled into `dist/`. Metro resolves `require()` calls at build time.
|
|
73
73
|
|
|
74
74
|
Pair with `expo-splash-screen` in production:
|
|
75
75
|
```tsx
|
|
@@ -403,6 +403,57 @@ Access resolved values via `useTheme().colors.overlay`, `.accentResolved`, `.acc
|
|
|
403
403
|
|
|
404
404
|
---
|
|
405
405
|
|
|
406
|
+
## Migration Guide: v6 → v7
|
|
407
|
+
|
|
408
|
+
### Breaking Changes
|
|
409
|
+
|
|
410
|
+
**No prop API changes** — all component imports and props are identical. This is a breaking version bump due to visual behavior changes that affect rendered output.
|
|
411
|
+
|
|
412
|
+
**Typography scale corrected:**
|
|
413
|
+
|
|
414
|
+
| Token | v6 | v7 | Reason |
|
|
415
|
+
|-------|----|----|--------|
|
|
416
|
+
| `display-lg` | 22px / 500 | 24px / 600 | Removed weight inversion vs display-md |
|
|
417
|
+
| `display-md` | 21px / 700 | 20px / 600 | 4px gap preserved; weight normalised |
|
|
418
|
+
| `title-md` | 16px / 600 | 17px / 600 | Now visibly distinct from title-sm |
|
|
419
|
+
| `title-sm` | 16px / 500 | 15px / 500 | Was same px as title-md |
|
|
420
|
+
| `uppercase-tag` | 10px / 0.8 letterSpacing | 11px / 0.6 | Below Apple HIG 11pt minimum |
|
|
421
|
+
| `badge-text-md` | (missing) | 13px / 600 | New canonical token for Badge md |
|
|
422
|
+
|
|
423
|
+
**Default color values changed (WCAG AA fixes):**
|
|
424
|
+
|
|
425
|
+
| Token | v6 | v7 | WCAG impact |
|
|
426
|
+
|-------|----|----|-------------|
|
|
427
|
+
| `foregroundMuted` opacity | 0.38 (~#ababab) | 0.62 (~#767676) | 2.2:1 ❌ → 4.5:1 ✓ |
|
|
428
|
+
| `foregroundSubtle` opacity | 0.55 (~#858585) | 0.70 (~#646464) | 3.5:1 ❌ → 5.9:1 ✓ |
|
|
429
|
+
| `warning` (light) | `#e67e00` | `#9a5200` | 2.86:1 ❌ → 5.86:1 ✓ |
|
|
430
|
+
| `warningForeground` (dark) | `#ffffff` | `#0f0f0f` | Dark text on amber, 8.6:1 ✓ |
|
|
431
|
+
| `destructive` (light) | `#e53935` | `#c72828` | 4.22:1 ❌ → 5.59:1 ✓ |
|
|
432
|
+
| `accent` (light) | `= primary` | `#d4561d` | Explicit brand accent |
|
|
433
|
+
| `accent` (dark) | `= primary` | `#e87645` | Warm accent for dark surfaces |
|
|
434
|
+
|
|
435
|
+
**Component visual behavior changes:**
|
|
436
|
+
|
|
437
|
+
| Component | Change |
|
|
438
|
+
|-----------|--------|
|
|
439
|
+
| `AlertBanner` | Background now uses semantic tint per variant (was white card); 1px semantic border added |
|
|
440
|
+
| `Button` (text variant) | Label color: `foreground` → `accentResolved` — clearer CTA signal |
|
|
441
|
+
| `Card` (elevated variant) | `borderWidth: 0` — shadow is sole depth signal; border was redundant |
|
|
442
|
+
| `Chip` | `paddingVertical` doubled to hit 44pt WCAG 2.5.5 tap target |
|
|
443
|
+
| `Input` / `Textarea` | Border: 1px at rest → animates to 2px on focus (was always 2px) |
|
|
444
|
+
| `Switch` | Off-state now shows animated 1.5px border (invisible on white surfaces before) |
|
|
445
|
+
| `Tabs` | Labels always `Sohne-SemiBold`; active = color only — eliminates layout reflow on selection |
|
|
446
|
+
| `Checkbox` / `RadioGroup` | Disabled `opacity: 0.45` now on full row (was box only) |
|
|
447
|
+
| `Toast` | `richColors={true}` — semantic variants now visually distinct by color |
|
|
448
|
+
|
|
449
|
+
**If you customised any of these values** via `ThemeProvider` overrides, your overrides continue to take precedence — default palette changes only affect apps using the out-of-the-box defaults.
|
|
450
|
+
|
|
451
|
+
### New Compound Component Section
|
|
452
|
+
|
|
453
|
+
The example app now has a dedicated **Compound Components** section showcasing `Card`, `ButtonGroup`, `Form`, `ListGroup`, and `MenuGroup` with all sub-components and variants.
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
406
457
|
## Components
|
|
407
458
|
|
|
408
459
|
---
|
|
@@ -517,9 +568,9 @@ Access resolved values via `useTheme().colors.overlay`, `.accentResolved`, `.acc
|
|
|
517
568
|
|
|
518
569
|
**Shape:** `borderRadius: RADIUS.md = 14px` — Airbnb-aligned rounded rect on all variants. Exception: `IconButton` uses `RADIUS.full` (perfect circle).
|
|
519
570
|
|
|
520
|
-
**Animations:** Scale springs to 0.95 on `onPressIn`, back to 1.0 on `onPressOut`.
|
|
571
|
+
**Animations:** `usePressScale` hook — Reanimated v4, UI thread. Scale springs to 0.95 (`SPRINGS.pressIn`) on `onPressIn`, back to 1.0 (`SPRINGS.pressOut`) on `onPressOut`. Web: hover scale 1.02.
|
|
521
572
|
|
|
522
|
-
**Haptics:** `
|
|
573
|
+
**Haptics:** `impactMedium` on every press.
|
|
523
574
|
|
|
524
575
|
**Examples:**
|
|
525
576
|
```tsx
|
|
@@ -1247,6 +1298,74 @@ const [amount, setAmount] = useState(0)
|
|
|
1247
1298
|
|
|
1248
1299
|
---
|
|
1249
1300
|
|
|
1301
|
+
### VirtualList
|
|
1302
|
+
|
|
1303
|
+
**Import:** `import { VirtualList } from '@retray-dev/ui-kit'`
|
|
1304
|
+
|
|
1305
|
+
**When to use:** Large lists (100+ items) where you need efficient rendering. Thin wrapper over `FlatList` with sane defaults for stable keys and optional fixed-height fast path.
|
|
1306
|
+
|
|
1307
|
+
| Prop | Type | Default | Notes |
|
|
1308
|
+
|------|------|---------|-------|
|
|
1309
|
+
| data | `T[]` | — | Array of items to render |
|
|
1310
|
+
| renderItem | `ListRenderItem<T>` | — | Render function for each item |
|
|
1311
|
+
| itemHeight | `number` | — | Fixed row height in px. Enables `getItemLayout` for performance with large datasets |
|
|
1312
|
+
| keyExtractor | `(item: T, index: number) => string` | Auto | Defaults to `item.id` or index. Override for custom keys |
|
|
1313
|
+
| ...FlatListProps | — | — | All standard FlatList props pass through |
|
|
1314
|
+
|
|
1315
|
+
**Performance optimization:** When `itemHeight` is provided, `VirtualList` enables `getItemLayout` so FlatList skips async measurement. For 10k+ rows, combine with `React.memo`-wrapped `renderItem` so only on-screen rows mount and re-render.
|
|
1316
|
+
|
|
1317
|
+
**Default key extraction:** Uses `item.id` (converted to string) or falls back to index. Override with `keyExtractor` for custom logic.
|
|
1318
|
+
|
|
1319
|
+
**Example — simple list:**
|
|
1320
|
+
```tsx
|
|
1321
|
+
<VirtualList
|
|
1322
|
+
data={items}
|
|
1323
|
+
renderItem={({ item }) => (
|
|
1324
|
+
<ListItem
|
|
1325
|
+
title={item.title}
|
|
1326
|
+
subtitle={item.subtitle}
|
|
1327
|
+
onPress={() => handlePress(item.id)}
|
|
1328
|
+
/>
|
|
1329
|
+
)}
|
|
1330
|
+
itemHeight={56}
|
|
1331
|
+
/>
|
|
1332
|
+
```
|
|
1333
|
+
|
|
1334
|
+
**Example — large dataset with memoized render:**
|
|
1335
|
+
```tsx
|
|
1336
|
+
const renderItem = useCallback(({ item }) => (
|
|
1337
|
+
<ListItem
|
|
1338
|
+
title={item.title}
|
|
1339
|
+
subtitle={item.subtitle}
|
|
1340
|
+
leftIcon="circle"
|
|
1341
|
+
showSeparator
|
|
1342
|
+
onPress={() => navigate('detail', { id: item.id })}
|
|
1343
|
+
/>
|
|
1344
|
+
), [])
|
|
1345
|
+
|
|
1346
|
+
<VirtualList
|
|
1347
|
+
data={thousands}
|
|
1348
|
+
renderItem={renderItem}
|
|
1349
|
+
itemHeight={64}
|
|
1350
|
+
/>
|
|
1351
|
+
```
|
|
1352
|
+
|
|
1353
|
+
**Example — variable height rows (omit itemHeight):**
|
|
1354
|
+
```tsx
|
|
1355
|
+
<VirtualList
|
|
1356
|
+
data={posts}
|
|
1357
|
+
renderItem={({ item }) => (
|
|
1358
|
+
<Card style={{ margin: SPACING.sm }}>
|
|
1359
|
+
<CardContent>
|
|
1360
|
+
<Text>{item.content}</Text>
|
|
1361
|
+
</CardContent>
|
|
1362
|
+
</Card>
|
|
1363
|
+
)}
|
|
1364
|
+
/>
|
|
1365
|
+
```
|
|
1366
|
+
|
|
1367
|
+
---
|
|
1368
|
+
|
|
1250
1369
|
### Separator
|
|
1251
1370
|
|
|
1252
1371
|
**Import:** `import { Separator } from '@retray-dev/ui-kit'`
|
|
@@ -2058,6 +2177,195 @@ const [open, setOpen] = useState(false)
|
|
|
2058
2177
|
- Default `android_keyboardInputMode="adjustPan"` fixes the transparent gap that occurs with `adjustResize` when keyboard dismisses
|
|
2059
2178
|
- `enableBlurKeyboardOnGesture={true}` (default) dismisses keyboard when dragging sheet
|
|
2060
2179
|
|
|
2180
|
+
**Compound components:**
|
|
2181
|
+
|
|
2182
|
+
Sheet also supports compound components for custom layouts: `Sheet.Header`, `Sheet.Content`, `Sheet.Footer`.
|
|
2183
|
+
|
|
2184
|
+
**Sheet.Header Props:**
|
|
2185
|
+
| Prop | Type | Notes |
|
|
2186
|
+
|------|------|-------|
|
|
2187
|
+
| children | `ReactNode` | Custom header content — replaces title/subtitle/showCloseButton |
|
|
2188
|
+
| style | `ViewStyle` | — |
|
|
2189
|
+
|
|
2190
|
+
**Sheet.Content Props:**
|
|
2191
|
+
| Prop | Type | Notes |
|
|
2192
|
+
|------|------|-------|
|
|
2193
|
+
| children | `ReactNode` | Body content with automatic gap spacing |
|
|
2194
|
+
| style | `ViewStyle` | — |
|
|
2195
|
+
|
|
2196
|
+
**Sheet.Footer Props:**
|
|
2197
|
+
| Prop | Type | Notes |
|
|
2198
|
+
|------|------|-------|
|
|
2199
|
+
| children | `ReactNode` | Footer content (e.g., action buttons) |
|
|
2200
|
+
| style | `ViewStyle` | — |
|
|
2201
|
+
|
|
2202
|
+
**Compound component examples:**
|
|
2203
|
+
```tsx
|
|
2204
|
+
// Custom header with close button
|
|
2205
|
+
<Sheet open={open} onClose={() => setOpen(false)}>
|
|
2206
|
+
<Sheet.Header>
|
|
2207
|
+
<View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
|
|
2208
|
+
<Text variant="title-md">Custom Header</Text>
|
|
2209
|
+
<IconButton iconName="x" onPress={() => setOpen(false)} />
|
|
2210
|
+
</View>
|
|
2211
|
+
</Sheet.Header>
|
|
2212
|
+
<Sheet.Content>
|
|
2213
|
+
<Text>Content with auto spacing</Text>
|
|
2214
|
+
<Input placeholder="Name" />
|
|
2215
|
+
<Input placeholder="Email" />
|
|
2216
|
+
</Sheet.Content>
|
|
2217
|
+
<Sheet.Footer>
|
|
2218
|
+
<Button label="Cancel" variant="outline" onPress={() => setOpen(false)} />
|
|
2219
|
+
<Button label="Save" onPress={handleSave} />
|
|
2220
|
+
</Sheet.Footer>
|
|
2221
|
+
</Sheet>
|
|
2222
|
+
|
|
2223
|
+
// Mix compound components with props
|
|
2224
|
+
<Sheet open={open} onClose={() => setOpen(false)} title="Edit Profile">
|
|
2225
|
+
<Sheet.Content>
|
|
2226
|
+
<Input label="Name" value={name} onChangeText={setName} />
|
|
2227
|
+
<Input label="Email" value={email} onChangeText={setEmail} />
|
|
2228
|
+
</Sheet.Content>
|
|
2229
|
+
<Sheet.Footer>
|
|
2230
|
+
<Button label="Save" fullWidth onPress={handleSave} />
|
|
2231
|
+
</Sheet.Footer>
|
|
2232
|
+
</Sheet>
|
|
2233
|
+
```
|
|
2234
|
+
|
|
2235
|
+
When using compound components:
|
|
2236
|
+
- `Sheet.Header` replaces `title`, `subtitle`, and `showCloseButton` props
|
|
2237
|
+
- `Sheet.Content` automatically applies `gap: vs(16)` between children
|
|
2238
|
+
- `Sheet.Footer` renders sticky footer with automatic border, padding, and horizontal button layout
|
|
2239
|
+
|
|
2240
|
+
---
|
|
2241
|
+
|
|
2242
|
+
### Form
|
|
2243
|
+
|
|
2244
|
+
**Import:** `import { Form } from '@retray-dev/ui-kit'`
|
|
2245
|
+
|
|
2246
|
+
**When to use:** Standardize form layouts with consistent spacing, labels, and validation errors. Compound component pattern for wrapping Input, Select, Textarea, etc.
|
|
2247
|
+
|
|
2248
|
+
**Sub-components:**
|
|
2249
|
+
- `Form` — Root wrapper with consistent gap spacing between fields
|
|
2250
|
+
- `Form.Field` — Wraps a single input with optional label and error
|
|
2251
|
+
- `Form.Section` — Groups related fields with title and description
|
|
2252
|
+
- `Form.Footer` — Footer area for submit/cancel buttons
|
|
2253
|
+
|
|
2254
|
+
**Form Props:**
|
|
2255
|
+
| Prop | Type | Notes |
|
|
2256
|
+
|------|------|-------|
|
|
2257
|
+
| children | `ReactNode` | Form.Field, Form.Section, Form.Footer components |
|
|
2258
|
+
| style | `ViewStyle` | — |
|
|
2259
|
+
|
|
2260
|
+
**Form.Field Props:**
|
|
2261
|
+
| Prop | Type | Default | Notes |
|
|
2262
|
+
|------|------|---------|-------|
|
|
2263
|
+
| children | `ReactNode` | required | Input, Select, Textarea, etc. |
|
|
2264
|
+
| label | `string` | — | Label above input |
|
|
2265
|
+
| error | `string` | — | Error message below input |
|
|
2266
|
+
| required | `boolean` | `false` | Shows asterisk after label |
|
|
2267
|
+
| style | `ViewStyle` | — | — |
|
|
2268
|
+
| labelStyle | `TextStyle` | — | — |
|
|
2269
|
+
| errorStyle | `TextStyle` | — | — |
|
|
2270
|
+
|
|
2271
|
+
**Form.Section Props:**
|
|
2272
|
+
| Prop | Type | Notes |
|
|
2273
|
+
|------|------|-------|
|
|
2274
|
+
| children | `ReactNode` | Form.Field components |
|
|
2275
|
+
| title | `string` | Section heading |
|
|
2276
|
+
| description | `string` | Supporting text below title |
|
|
2277
|
+
| style | `ViewStyle` | — |
|
|
2278
|
+
|
|
2279
|
+
**Form.Footer Props:**
|
|
2280
|
+
| Prop | Type | Notes |
|
|
2281
|
+
|------|------|-------|
|
|
2282
|
+
| children | `ReactNode` | Button components |
|
|
2283
|
+
| style | `ViewStyle` | — |
|
|
2284
|
+
|
|
2285
|
+
**Features:**
|
|
2286
|
+
- **Automatic spacing:** `gap: vs(16)` between Form.Field components
|
|
2287
|
+
- **Required indicator:** Red asterisk (*) when `required={true}`
|
|
2288
|
+
- **Error styling:** Error text in destructive color below input
|
|
2289
|
+
- **Label hierarchy:** Sohne-Medium 14px for labels, 12px for errors
|
|
2290
|
+
- **Footer layout:** Horizontal row with `gap: s(12)` for button grouping
|
|
2291
|
+
|
|
2292
|
+
**Examples:**
|
|
2293
|
+
```tsx
|
|
2294
|
+
// Basic form
|
|
2295
|
+
<Form>
|
|
2296
|
+
<Form.Field label="Full Name" required>
|
|
2297
|
+
<Input value={name} onChangeText={setName} placeholder="John Doe" />
|
|
2298
|
+
</Form.Field>
|
|
2299
|
+
|
|
2300
|
+
<Form.Field label="Email" required error={emailError}>
|
|
2301
|
+
<Input
|
|
2302
|
+
value={email}
|
|
2303
|
+
onChangeText={setEmail}
|
|
2304
|
+
placeholder="john@example.com"
|
|
2305
|
+
keyboardType="email-address"
|
|
2306
|
+
/>
|
|
2307
|
+
</Form.Field>
|
|
2308
|
+
|
|
2309
|
+
<Form.Field label="Country">
|
|
2310
|
+
<Select
|
|
2311
|
+
value={country}
|
|
2312
|
+
onValueChange={setCountry}
|
|
2313
|
+
options={countries}
|
|
2314
|
+
/>
|
|
2315
|
+
</Form.Field>
|
|
2316
|
+
|
|
2317
|
+
<Form.Footer>
|
|
2318
|
+
<Button label="Cancel" variant="outline" onPress={onCancel} />
|
|
2319
|
+
<Button label="Submit" onPress={handleSubmit} />
|
|
2320
|
+
</Form.Footer>
|
|
2321
|
+
</Form>
|
|
2322
|
+
|
|
2323
|
+
// With sections
|
|
2324
|
+
<Form>
|
|
2325
|
+
<Form.Section title="Personal Information" description="Your basic profile details">
|
|
2326
|
+
<Form.Field label="Name" required>
|
|
2327
|
+
<Input value={name} onChangeText={setName} />
|
|
2328
|
+
</Form.Field>
|
|
2329
|
+
<Form.Field label="Email" required error={emailError}>
|
|
2330
|
+
<Input value={email} onChangeText={setEmail} />
|
|
2331
|
+
</Form.Field>
|
|
2332
|
+
</Form.Section>
|
|
2333
|
+
|
|
2334
|
+
<Form.Section title="Preferences">
|
|
2335
|
+
<Form.Field label="Language">
|
|
2336
|
+
<Select value={lang} onValueChange={setLang} options={languages} />
|
|
2337
|
+
</Form.Field>
|
|
2338
|
+
<Form.Field label="Timezone">
|
|
2339
|
+
<Select value={tz} onValueChange={setTz} options={timezones} />
|
|
2340
|
+
</Form.Field>
|
|
2341
|
+
</Form.Section>
|
|
2342
|
+
|
|
2343
|
+
<Form.Footer>
|
|
2344
|
+
<Button label="Save" fullWidth onPress={handleSave} />
|
|
2345
|
+
</Form.Footer>
|
|
2346
|
+
</Form>
|
|
2347
|
+
|
|
2348
|
+
// Inside Sheet
|
|
2349
|
+
<Sheet open={open} onClose={() => setOpen(false)} title="Edit Profile">
|
|
2350
|
+
<Form>
|
|
2351
|
+
<Form.Field label="Name" required>
|
|
2352
|
+
<SheetTextInput value={name} onChangeText={setName} />
|
|
2353
|
+
</Form.Field>
|
|
2354
|
+
<Form.Field label="Bio">
|
|
2355
|
+
<SheetTextInput
|
|
2356
|
+
value={bio}
|
|
2357
|
+
onChangeText={setBio}
|
|
2358
|
+
multiline
|
|
2359
|
+
style={{ minHeight: 80 }}
|
|
2360
|
+
/>
|
|
2361
|
+
</Form.Field>
|
|
2362
|
+
</Form>
|
|
2363
|
+
<View style={{ marginTop: 16 }}>
|
|
2364
|
+
<Button label="Save" fullWidth onPress={handleSave} />
|
|
2365
|
+
</View>
|
|
2366
|
+
</Sheet>
|
|
2367
|
+
```
|
|
2368
|
+
|
|
2061
2369
|
---
|
|
2062
2370
|
|
|
2063
2371
|
### Toast / useToast
|
|
@@ -2297,6 +2605,77 @@ dismiss(id)
|
|
|
2297
2605
|
|
|
2298
2606
|
---
|
|
2299
2607
|
|
|
2608
|
+
### ListGroup
|
|
2609
|
+
|
|
2610
|
+
**Import:** `import { ListGroup } from '@retray-dev/ui-kit'`
|
|
2611
|
+
|
|
2612
|
+
**When to use:** Wrap multiple `ListItem` components to standardize spacing, add automatic separators, and optionally apply a card surface. Identical pattern to `MenuGroup`.
|
|
2613
|
+
|
|
2614
|
+
| Prop | Type | Default | Notes |
|
|
2615
|
+
|------|------|---------|-------|
|
|
2616
|
+
| children | `ReactNode` | required | ListItem components + ListGroup.Header + ListGroup.Footer |
|
|
2617
|
+
| variant | `'plain' \| 'card'` | `'plain'` | `plain`: no background. `card`: card surface with border |
|
|
2618
|
+
| style | `ViewStyle` | — | — |
|
|
2619
|
+
|
|
2620
|
+
**Sub-components:**
|
|
2621
|
+
- `ListGroup.Header` — Header text or custom content
|
|
2622
|
+
- `ListGroup.Footer` — Footer text or custom content
|
|
2623
|
+
|
|
2624
|
+
**Features:**
|
|
2625
|
+
- **Auto-separators:** Automatically adds `showSeparator={true}` to all ListItem children except the last
|
|
2626
|
+
- **Individual override:** ListItem can override with `showSeparator={false}`
|
|
2627
|
+
- **Variant `card`:** Applies card surface (`RADIUS.md`, border, shadow)
|
|
2628
|
+
|
|
2629
|
+
**Examples:**
|
|
2630
|
+
```tsx
|
|
2631
|
+
// Transaction list with auto separators
|
|
2632
|
+
<ListGroup variant="card">
|
|
2633
|
+
<ListGroup.Header>Recent Transactions</ListGroup.Header>
|
|
2634
|
+
<ListItem
|
|
2635
|
+
leftIcon="coffee"
|
|
2636
|
+
title="Rappi"
|
|
2637
|
+
subtitle="Food · May 12"
|
|
2638
|
+
rightRender={<Text color={colors.destructive}>−$45.000</Text>}
|
|
2639
|
+
onPress={() => {}}
|
|
2640
|
+
/>
|
|
2641
|
+
<ListItem
|
|
2642
|
+
leftIcon="car"
|
|
2643
|
+
title="Uber"
|
|
2644
|
+
subtitle="Transport · May 11"
|
|
2645
|
+
rightRender={<Text color={colors.destructive}>−$18.200</Text>}
|
|
2646
|
+
onPress={() => {}}
|
|
2647
|
+
/>
|
|
2648
|
+
<ListItem
|
|
2649
|
+
leftIcon="briefcase"
|
|
2650
|
+
title="Salary"
|
|
2651
|
+
subtitle="Income · May 1"
|
|
2652
|
+
rightRender={<Text color={colors.success}>+$3.500.000</Text>}
|
|
2653
|
+
onPress={() => {}}
|
|
2654
|
+
/>
|
|
2655
|
+
<ListGroup.Footer>Last 7 days</ListGroup.Footer>
|
|
2656
|
+
</ListGroup>
|
|
2657
|
+
|
|
2658
|
+
// Plain variant (inside Card)
|
|
2659
|
+
<Card>
|
|
2660
|
+
<CardContent>
|
|
2661
|
+
<ListGroup variant="plain">
|
|
2662
|
+
{users.map((user) => (
|
|
2663
|
+
<ListItem
|
|
2664
|
+
key={user.id}
|
|
2665
|
+
leftRender={<Avatar src={user.avatar} fallback={user.name[0]} />}
|
|
2666
|
+
title={user.name}
|
|
2667
|
+
subtitle={user.role}
|
|
2668
|
+
rightRender={<Badge label={user.status} variant="success" />}
|
|
2669
|
+
onPress={() => navigate('user', { id: user.id })}
|
|
2670
|
+
/>
|
|
2671
|
+
))}
|
|
2672
|
+
</ListGroup>
|
|
2673
|
+
</CardContent>
|
|
2674
|
+
</Card>
|
|
2675
|
+
```
|
|
2676
|
+
|
|
2677
|
+
---
|
|
2678
|
+
|
|
2300
2679
|
### MenuItem
|
|
2301
2680
|
|
|
2302
2681
|
**Import:** `import { MenuItem } from '@retray-dev/ui-kit'`
|
|
@@ -2325,7 +2704,7 @@ dismiss(id)
|
|
|
2325
2704
|
- Height: 54dp — consistent settings row
|
|
2326
2705
|
- Chevron: shown by default (`showChevron={true}`). Can be replaced via `rightRender` prop
|
|
2327
2706
|
- `rightRender` — arbitrary right slot content (Switch, Checkbox, Badge, etc). When set, chevron is hidden
|
|
2328
|
-
- Press scale: 0.97
|
|
2707
|
+
- Press scale: 0.97 (`PRESS_SCALE.row`) via `usePressScale` with `SPRINGS.surfacePressIn/Out` — Reanimated v4, UI thread
|
|
2329
2708
|
- Haptics: `selectionAsync` on press
|
|
2330
2709
|
|
|
2331
2710
|
**Example:**
|
|
@@ -2376,6 +2755,61 @@ dismiss(id)
|
|
|
2376
2755
|
|
|
2377
2756
|
---
|
|
2378
2757
|
|
|
2758
|
+
### MenuGroup
|
|
2759
|
+
|
|
2760
|
+
**Import:** `import { MenuGroup } from '@retray-dev/ui-kit'`
|
|
2761
|
+
|
|
2762
|
+
**When to use:** Wrap multiple `MenuItem` components to standardize spacing, add automatic separators, and optionally apply a card surface. Compound component pattern like `Card`.
|
|
2763
|
+
|
|
2764
|
+
| Prop | Type | Default | Notes |
|
|
2765
|
+
|------|------|---------|-------|
|
|
2766
|
+
| children | `ReactNode` | required | MenuItem components + MenuGroup.Header + MenuGroup.Footer |
|
|
2767
|
+
| variant | `'plain' \| 'card'` | `'plain'` | `plain`: no background. `card`: card surface with border |
|
|
2768
|
+
| style | `ViewStyle` | — | — |
|
|
2769
|
+
|
|
2770
|
+
**Sub-components:**
|
|
2771
|
+
- `MenuGroup.Header` — Header text or custom content
|
|
2772
|
+
- `MenuGroup.Footer` — Footer text or custom content
|
|
2773
|
+
|
|
2774
|
+
**Features:**
|
|
2775
|
+
- **Auto-separators:** Automatically adds `showSeparator={true}` to all MenuItem children except the last
|
|
2776
|
+
- **Individual override:** MenuItem can override with `showSeparator={false}`
|
|
2777
|
+
- **Variant `card`:** Applies card surface (`RADIUS.md`, border, shadow) like standalone MenuItems with `variant="card"`
|
|
2778
|
+
|
|
2779
|
+
**Examples:**
|
|
2780
|
+
```tsx
|
|
2781
|
+
// Basic group with auto separators
|
|
2782
|
+
<MenuGroup variant="card">
|
|
2783
|
+
<MenuItem label="Personal Info" iconName="user" onPress={() => {}} />
|
|
2784
|
+
<MenuItem label="Security" iconName="shield" onPress={() => {}} />
|
|
2785
|
+
<MenuItem label="Privacy" iconName="lock" onPress={() => {}} />
|
|
2786
|
+
</MenuGroup>
|
|
2787
|
+
|
|
2788
|
+
// With header and footer
|
|
2789
|
+
<MenuGroup variant="card">
|
|
2790
|
+
<MenuGroup.Header>Account Settings</MenuGroup.Header>
|
|
2791
|
+
<MenuItem label="Personal Info" subtitle="Name, email, phone" iconName="user" onPress={() => {}} />
|
|
2792
|
+
<MenuItem label="Security" iconName="shield" onPress={() => {}} />
|
|
2793
|
+
<MenuItem label="Privacy" iconName="lock" onPress={() => {}} />
|
|
2794
|
+
<MenuGroup.Footer>Last updated today</MenuGroup.Footer>
|
|
2795
|
+
</MenuGroup>
|
|
2796
|
+
|
|
2797
|
+
// Plain variant (inside another container)
|
|
2798
|
+
<Card>
|
|
2799
|
+
<CardHeader>
|
|
2800
|
+
<CardTitle>Settings</CardTitle>
|
|
2801
|
+
</CardHeader>
|
|
2802
|
+
<CardContent>
|
|
2803
|
+
<MenuGroup variant="plain">
|
|
2804
|
+
<MenuItem label="Notifications" iconName="bell" rightRender={<Switch checked={notifs} onCheckedChange={setNotifs} />} />
|
|
2805
|
+
<MenuItem label="Dark Mode" iconName="moon" rightRender={<Switch checked={dark} onCheckedChange={setDark} />} />
|
|
2806
|
+
</MenuGroup>
|
|
2807
|
+
</CardContent>
|
|
2808
|
+
</Card>
|
|
2809
|
+
```
|
|
2810
|
+
|
|
2811
|
+
---
|
|
2812
|
+
|
|
2379
2813
|
### Chip / ChipGroup
|
|
2380
2814
|
|
|
2381
2815
|
**Import:** `import { Chip, ChipGroup } from '@retray-dev/ui-kit'`
|