@retray-dev/ui-kit 6.2.0 → 9.0.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.
- package/COMPONENTS.md +997 -20
- package/EXAMPLES.md +250 -2
- package/README.md +21 -14
- package/dist/Accordion.d.mts +28 -0
- package/dist/Accordion.d.ts +28 -0
- package/dist/Accordion.js +392 -0
- package/dist/Accordion.mjs +7 -0
- package/dist/AlertBanner.d.mts +16 -0
- package/dist/AlertBanner.d.ts +16 -0
- package/dist/AlertBanner.js +250 -0
- package/dist/AlertBanner.mjs +6 -0
- package/dist/AppHeader.d.mts +40 -0
- package/dist/AppHeader.d.ts +40 -0
- package/dist/AppHeader.js +515 -0
- package/dist/AppHeader.mjs +10 -0
- package/dist/Avatar.d.mts +20 -0
- package/dist/Avatar.d.ts +20 -0
- package/dist/Avatar.js +244 -0
- package/dist/Avatar.mjs +4 -0
- package/dist/Badge.d.mts +26 -0
- package/dist/Badge.d.ts +26 -0
- package/dist/Badge.js +257 -0
- package/dist/Badge.mjs +5 -0
- package/dist/Button.d.mts +30 -0
- package/dist/Button.d.ts +30 -0
- package/dist/Button.js +432 -0
- package/dist/Button.mjs +9 -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 +3 -0
- package/dist/Card.d.mts +39 -0
- package/dist/Card.d.ts +39 -0
- package/dist/Card.js +349 -0
- package/dist/Card.mjs +8 -0
- package/dist/CategoryStrip.d.mts +26 -0
- package/dist/CategoryStrip.d.ts +26 -0
- package/dist/CategoryStrip.js +453 -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 +336 -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 +403 -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 +560 -0
- package/dist/ConfirmDialog.mjs +10 -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 +4 -0
- package/dist/CurrencyInput.d.mts +26 -0
- package/dist/CurrencyInput.d.ts +26 -0
- package/dist/CurrencyInput.js +408 -0
- package/dist/CurrencyInput.mjs +8 -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 +5 -0
- package/dist/EmptyState.d.mts +27 -0
- package/dist/EmptyState.d.ts +27 -0
- package/dist/EmptyState.js +523 -0
- package/dist/EmptyState.mjs +10 -0
- package/dist/ErrorBoundary.d.mts +42 -0
- package/dist/ErrorBoundary.d.ts +42 -0
- package/dist/ErrorBoundary.js +351 -0
- package/dist/ErrorBoundary.mjs +7 -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 +4 -0
- package/dist/HolographicCard.d.mts +55 -0
- package/dist/HolographicCard.d.ts +55 -0
- package/dist/HolographicCard.js +316 -0
- package/dist/HolographicCard.mjs +191 -0
- package/dist/IconButton.d.mts +27 -0
- package/dist/IconButton.d.ts +27 -0
- package/dist/IconButton.js +400 -0
- package/dist/IconButton.mjs +8 -0
- package/dist/ImageViewer.d.mts +23 -0
- package/dist/ImageViewer.d.ts +23 -0
- package/dist/ImageViewer.js +582 -0
- package/dist/ImageViewer.mjs +8 -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 +7 -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 +5 -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 +5 -0
- package/dist/ListItem.d.mts +64 -0
- package/dist/ListItem.d.ts +64 -0
- package/dist/ListItem.js +444 -0
- package/dist/ListItem.mjs +9 -0
- package/dist/MediaCard.d.mts +39 -0
- package/dist/MediaCard.d.ts +39 -0
- package/dist/MediaCard.js +475 -0
- package/dist/MediaCard.mjs +9 -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 +5 -0
- package/dist/MenuItem.d.mts +48 -0
- package/dist/MenuItem.d.ts +48 -0
- package/dist/MenuItem.js +415 -0
- package/dist/MenuItem.mjs +9 -0
- package/dist/MonthPicker.d.mts +28 -0
- package/dist/MonthPicker.d.ts +28 -0
- package/dist/MonthPicker.js +297 -0
- package/dist/MonthPicker.mjs +5 -0
- package/dist/PagerDots.d.mts +35 -0
- package/dist/PagerDots.d.ts +35 -0
- package/dist/PagerDots.js +392 -0
- package/dist/PagerDots.mjs +7 -0
- package/dist/Pressable.d.mts +34 -0
- package/dist/Pressable.d.ts +34 -0
- package/dist/Pressable.js +143 -0
- package/dist/Pressable.mjs +5 -0
- package/dist/PricingCard.d.mts +50 -0
- package/dist/PricingCard.d.ts +50 -0
- package/dist/PricingCard.js +636 -0
- package/dist/PricingCard.mjs +11 -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 +5 -0
- package/dist/RadioGroup.d.mts +19 -0
- package/dist/RadioGroup.d.ts +19 -0
- package/dist/RadioGroup.js +392 -0
- package/dist/RadioGroup.mjs +7 -0
- package/dist/RetrayProvider.d.mts +2 -0
- package/dist/RetrayProvider.d.ts +2 -0
- package/dist/RetrayProvider.js +214 -0
- package/dist/RetrayProvider.mjs +5 -0
- package/dist/Select.d.mts +22 -0
- package/dist/Select.d.ts +22 -0
- package/dist/Select.js +488 -0
- package/dist/Select.mjs +7 -0
- package/dist/SelectableGrid.d.mts +44 -0
- package/dist/SelectableGrid.d.ts +44 -0
- package/dist/SelectableGrid.js +448 -0
- package/dist/SelectableGrid.mjs +9 -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 +3 -0
- package/dist/Sheet.d.mts +93 -0
- package/dist/Sheet.d.ts +93 -0
- package/dist/Sheet.js +450 -0
- package/dist/Sheet.mjs +6 -0
- package/dist/Skeleton.d.mts +67 -0
- package/dist/Skeleton.d.ts +67 -0
- package/dist/Skeleton.js +266 -0
- package/dist/Skeleton.mjs +6 -0
- package/dist/Slider.d.mts +20 -0
- package/dist/Slider.d.ts +20 -0
- package/dist/Slider.js +279 -0
- package/dist/Slider.mjs +5 -0
- package/dist/Spinner.d.mts +12 -0
- package/dist/Spinner.d.ts +12 -0
- package/dist/Spinner.js +193 -0
- package/dist/Spinner.mjs +4 -0
- package/dist/Switch.d.mts +13 -0
- package/dist/Switch.d.ts +13 -0
- package/dist/Switch.js +311 -0
- package/dist/Switch.mjs +6 -0
- package/dist/TabBar.d.mts +42 -0
- package/dist/TabBar.d.ts +42 -0
- package/dist/TabBar.js +361 -0
- package/dist/TabBar.mjs +6 -0
- package/dist/Tabs.d.mts +27 -0
- package/dist/Tabs.d.ts +27 -0
- package/dist/Tabs.js +419 -0
- package/dist/Tabs.mjs +7 -0
- package/dist/Text.d.mts +12 -0
- package/dist/Text.d.ts +12 -0
- package/dist/Text.js +327 -0
- package/dist/Text.mjs +5 -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 +7 -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 +4 -0
- package/dist/Toggle.d.mts +36 -0
- package/dist/Toggle.d.ts +36 -0
- package/dist/Toggle.js +412 -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 +2 -0
- package/dist/chunk-26BCI223.mjs +14 -0
- package/dist/chunk-2CE3TQVY.mjs +11 -0
- package/dist/chunk-2TFTAWVJ.mjs +131 -0
- package/dist/chunk-2UYENBLV.mjs +49 -0
- package/dist/chunk-3BBOZ3OQ.mjs +41 -0
- package/dist/chunk-3DKJ2GIC.mjs +30 -0
- package/dist/chunk-3U4SSNWP.mjs +120 -0
- package/dist/chunk-4I7D47FH.mjs +139 -0
- package/dist/chunk-4K625MVM.mjs +142 -0
- package/dist/chunk-6OAZJ577.mjs +98 -0
- package/dist/chunk-6Q64UFIA.mjs +71 -0
- package/dist/chunk-756RAKE4.mjs +145 -0
- package/dist/chunk-7QHVVCB3.mjs +115 -0
- package/dist/chunk-A3A6KNQN.mjs +245 -0
- package/dist/chunk-A4MDAP7G.mjs +42 -0
- package/dist/chunk-AJ7ZDNBT.mjs +120 -0
- package/dist/chunk-AV4EMIRH.mjs +94 -0
- package/dist/chunk-AZJF2BLK.mjs +115 -0
- package/dist/chunk-BNP626TY.mjs +159 -0
- package/dist/chunk-BRKYVJVV.mjs +60 -0
- package/dist/chunk-DVK4G2GT.mjs +59 -0
- package/dist/chunk-EH745HE5.mjs +127 -0
- package/dist/chunk-EJ7ZPXOH.mjs +163 -0
- package/dist/chunk-GD6KXMG5.mjs +106 -0
- package/dist/chunk-GQYFLP3D.mjs +187 -0
- package/dist/chunk-ID72TK46.mjs +111 -0
- package/dist/chunk-IRRY3CRZ.mjs +82 -0
- package/dist/chunk-JB67UOB5.mjs +92 -0
- package/dist/chunk-JMOZEC77.mjs +90 -0
- package/dist/chunk-JT7HKXRB.mjs +114 -0
- package/dist/chunk-KIHCWCWL.mjs +124 -0
- package/dist/chunk-LXJIIOYQ.mjs +104 -0
- package/dist/chunk-M6ZXVBTK.mjs +64 -0
- package/dist/chunk-MAC465BB.mjs +61 -0
- package/dist/chunk-MBMXYJJV.mjs +36 -0
- package/dist/chunk-MLF3EZFW.mjs +119 -0
- package/dist/chunk-MX6HRKMI.mjs +29 -0
- package/dist/chunk-NA7PARID.mjs +147 -0
- package/dist/chunk-NC5ZTR2Y.mjs +32 -0
- package/dist/chunk-O3HA6TYM.mjs +139 -0
- package/dist/chunk-OB4JUQ3O.mjs +51 -0
- package/dist/chunk-PFZTM6D5.mjs +238 -0
- package/dist/chunk-QKH5ZOD5.mjs +97 -0
- package/dist/chunk-QY3X2UYR.mjs +191 -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-TERDKCLE.mjs +74 -0
- package/dist/chunk-UREA2GYY.mjs +113 -0
- package/dist/chunk-VGTDN7SW.mjs +164 -0
- package/dist/chunk-VQ57HWPL.mjs +144 -0
- package/dist/chunk-WBOOUHSS.mjs +62 -0
- package/dist/chunk-WJLKJMKR.mjs +78 -0
- package/dist/chunk-X4G6APW6.mjs +134 -0
- package/dist/chunk-Y6FXYEAI.mjs +8 -0
- package/dist/chunk-YFZ3ELX5.mjs +16 -0
- package/dist/chunk-YNROWHQJ.mjs +46 -0
- package/dist/chunk-Z4BVUWW6.mjs +196 -0
- package/dist/chunk-ZJKGQMYH.mjs +131 -0
- package/dist/index-wt-orHUi.d.mts +85 -0
- package/dist/index-wt-orHUi.d.ts +85 -0
- package/dist/index.d.mts +149 -920
- package/dist/index.d.ts +149 -920
- package/dist/index.js +2560 -970
- package/dist/index.mjs +60 -3895
- package/package.json +55 -16
- 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 +15 -4
- package/src/components/AlertBanner/AlertBanner.tsx +38 -12
- package/src/components/AppHeader/AppHeader.tsx +172 -0
- package/src/components/AppHeader/index.ts +1 -0
- package/src/components/Avatar/Avatar.tsx +14 -4
- package/src/components/Badge/Badge.tsx +12 -3
- package/src/components/Button/Button.tsx +30 -38
- package/src/components/ButtonGroup/ButtonGroup.tsx +13 -10
- package/src/components/Card/Card.tsx +29 -57
- package/src/components/CategoryStrip/CategoryStrip.tsx +41 -42
- package/src/components/Checkbox/Checkbox.tsx +36 -45
- package/src/components/Chip/Chip.tsx +41 -48
- package/src/components/ConfirmDialog/ConfirmDialog.tsx +2 -2
- package/src/components/CurrencyDisplay/CurrencyDisplay.tsx +4 -2
- package/src/components/CurrencyInput/CurrencyInput.tsx +12 -10
- package/src/components/DetailRow/DetailRow.tsx +9 -7
- package/src/components/EmptyState/EmptyState.tsx +4 -3
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +153 -0
- package/src/components/ErrorBoundary/index.ts +1 -0
- package/src/components/Form/Form.tsx +149 -0
- package/src/components/Form/index.ts +1 -0
- package/src/components/HolographicCard/HolographicCard.tsx +315 -0
- package/src/components/HolographicCard/index.ts +1 -0
- package/src/components/IconButton/IconButton.tsx +23 -29
- package/src/components/ImageViewer/ImageViewer.tsx +290 -0
- package/src/components/ImageViewer/index.ts +1 -0
- package/src/components/Input/Input.tsx +27 -31
- 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 +78 -76
- package/src/components/MediaCard/MediaCard.tsx +15 -7
- package/src/components/MenuGroup/MenuGroup.tsx +145 -0
- package/src/components/MenuGroup/index.ts +1 -0
- package/src/components/MenuItem/MenuItem.tsx +16 -33
- package/src/components/MonthPicker/MonthPicker.tsx +41 -15
- package/src/components/MonthPicker/index.ts +1 -1
- package/src/components/PagerDots/PagerDots.tsx +200 -0
- package/src/components/PagerDots/index.ts +1 -0
- package/src/components/Pressable/Pressable.tsx +19 -35
- package/src/components/PricingCard/PricingCard.tsx +220 -0
- package/src/components/PricingCard/index.ts +1 -0
- package/src/components/RadioGroup/RadioGroup.tsx +23 -39
- package/src/components/RetrayProvider/RetrayProvider.tsx +59 -0
- package/src/components/RetrayProvider/index.ts +1 -0
- package/src/components/Select/Select.tsx +6 -6
- package/src/components/SelectableGrid/SelectableGrid.tsx +205 -0
- package/src/components/SelectableGrid/index.ts +1 -0
- package/src/components/Separator/Separator.tsx +1 -3
- package/src/components/Sheet/Sheet.tsx +146 -18
- package/src/components/Skeleton/Skeleton.tsx +143 -2
- package/src/components/Slider/Slider.tsx +2 -2
- package/src/components/Spinner/Spinner.tsx +18 -3
- package/src/components/Switch/Switch.tsx +44 -49
- package/src/components/TabBar/TabBar.tsx +169 -0
- package/src/components/TabBar/index.ts +1 -0
- package/src/components/Tabs/Tabs.tsx +45 -44
- package/src/components/Text/Text.tsx +5 -1
- package/src/components/Textarea/Textarea.tsx +18 -14
- package/src/components/Toast/Toast.tsx +6 -6
- package/src/components/Toggle/Toggle.tsx +80 -72
- package/src/components/VirtualList/VirtualList.tsx +60 -0
- package/src/components/VirtualList/index.ts +1 -0
- package/src/fonts.ts +41 -20
- package/src/index.ts +28 -3
- 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 +29 -1
- package/src/utils/fontGuard.ts +34 -0
- package/src/utils/haptics.ts +211 -9
- package/src/utils/icons.ts +47 -20
- package/src/utils/pressable.ts +66 -0
- package/src/utils/usePressScale.ts +2 -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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@retray-dev/ui-kit",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "9.0.0",
|
|
4
4
|
"description": "Personal UI Kit for React Native / Expo",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -11,7 +11,12 @@
|
|
|
11
11
|
"import": "./dist/index.mjs",
|
|
12
12
|
"require": "./dist/index.js"
|
|
13
13
|
},
|
|
14
|
-
"./fonts": "./src/fonts.ts"
|
|
14
|
+
"./fonts": "./src/fonts.ts",
|
|
15
|
+
"./*": {
|
|
16
|
+
"types": "./dist/*.d.ts",
|
|
17
|
+
"import": "./dist/*.mjs",
|
|
18
|
+
"require": "./dist/*.js"
|
|
19
|
+
}
|
|
15
20
|
},
|
|
16
21
|
"files": [
|
|
17
22
|
"dist",
|
|
@@ -23,12 +28,16 @@
|
|
|
23
28
|
"build": "tsup",
|
|
24
29
|
"dev": "tsup --watch",
|
|
25
30
|
"typecheck": "tsc --noEmit",
|
|
31
|
+
"test": "jest",
|
|
32
|
+
"test:watch": "jest --watch",
|
|
33
|
+
"test:coverage": "jest --coverage",
|
|
26
34
|
"lint": "eslint src",
|
|
27
35
|
"lint:fix": "eslint src --fix",
|
|
28
36
|
"format": "prettier --write src",
|
|
29
37
|
"format:check": "prettier --check src",
|
|
30
38
|
"lint:all": "pnpm lint && pnpm --filter retray-ui-kit-example lint",
|
|
31
39
|
"format:all": "pnpm format && pnpm --filter retray-ui-kit-example format",
|
|
40
|
+
"verify": "pnpm typecheck && pnpm lint && pnpm test && pnpm build",
|
|
32
41
|
"deploy": "pnpm typecheck && pnpm build && npm publish --access public"
|
|
33
42
|
},
|
|
34
43
|
"keywords": [
|
|
@@ -40,28 +49,48 @@
|
|
|
40
49
|
"license": "MIT",
|
|
41
50
|
"peerDependencies": {
|
|
42
51
|
"@expo/vector-icons": ">=14.0.0",
|
|
43
|
-
"@gorhom/bottom-sheet": ">=5.
|
|
52
|
+
"@gorhom/bottom-sheet": ">=5.2.0",
|
|
44
53
|
"@react-native-community/slider": ">=4.0.0",
|
|
45
54
|
"@react-native-picker/picker": ">=2.0.0",
|
|
55
|
+
"@shopify/react-native-skia": ">=1.0.0",
|
|
46
56
|
"expo-font": ">=14.0.0",
|
|
47
57
|
"expo-haptics": ">=14.0.0",
|
|
48
58
|
"expo-linear-gradient": ">=13.0.0",
|
|
59
|
+
"expo-sensors": ">=13.0.0",
|
|
60
|
+
"pressto": ">=0.6.0",
|
|
49
61
|
"react": ">=17",
|
|
50
|
-
"react-native": ">=0.
|
|
62
|
+
"react-native": ">=0.76",
|
|
63
|
+
"react-native-ease": ">=0.7.0",
|
|
51
64
|
"react-native-gesture-handler": ">=2.0.0",
|
|
65
|
+
"react-native-pulsar": ">=1.6.0",
|
|
52
66
|
"react-native-reanimated": ">=4.0.0",
|
|
53
67
|
"react-native-safe-area-context": ">=4.0.0",
|
|
68
|
+
"react-native-screens": ">=3.0.0",
|
|
54
69
|
"react-native-size-matters": ">=0.4.0",
|
|
55
|
-
"react-native-worklets": ">=0.5.0",
|
|
56
70
|
"react-native-svg": ">=15.0.0",
|
|
57
|
-
"react-native-
|
|
71
|
+
"react-native-worklets": ">=0.5.0",
|
|
72
|
+
"sonner-native": ">=0.20.0"
|
|
73
|
+
},
|
|
74
|
+
"peerDependenciesMeta": {
|
|
75
|
+
"@shopify/react-native-skia": {
|
|
76
|
+
"optional": true
|
|
77
|
+
},
|
|
78
|
+
"expo-sensors": {
|
|
79
|
+
"optional": true
|
|
80
|
+
},
|
|
81
|
+
"react-native-pulsar": {
|
|
82
|
+
"optional": true
|
|
83
|
+
}
|
|
58
84
|
},
|
|
59
85
|
"pnpm": {
|
|
60
86
|
"overrides": {
|
|
61
87
|
"fast-xml-parser": "^5.5.7",
|
|
62
88
|
"react": "19.1.0",
|
|
63
89
|
"react-native": "0.81.5",
|
|
64
|
-
"react-native-worklets": "0.5.1"
|
|
90
|
+
"react-native-worklets": "0.5.1",
|
|
91
|
+
"@types/react": "19.1.17",
|
|
92
|
+
"react-native-safe-area-context": "5.6.2",
|
|
93
|
+
"@gorhom/bottom-sheet": "5.2.8"
|
|
65
94
|
},
|
|
66
95
|
"onlyBuiltDependencies": [
|
|
67
96
|
"esbuild"
|
|
@@ -69,32 +98,42 @@
|
|
|
69
98
|
},
|
|
70
99
|
"devDependencies": {
|
|
71
100
|
"@eslint/js": "^9.0.0",
|
|
72
|
-
"react-native-size-matters": "^0.4.2",
|
|
73
101
|
"@expo/vector-icons": "^15.1.1",
|
|
74
|
-
"@gorhom/bottom-sheet": "
|
|
102
|
+
"@gorhom/bottom-sheet": "5.2.8",
|
|
75
103
|
"@react-native-community/slider": "5.0.1",
|
|
76
104
|
"@react-native-picker/picker": "2.11.1",
|
|
77
|
-
"@
|
|
105
|
+
"@shopify/react-native-skia": "2.2.12",
|
|
106
|
+
"@testing-library/react-native": "^14.0.0",
|
|
107
|
+
"@types/jest": "^30.0.0",
|
|
108
|
+
"@types/react": "19.1.17",
|
|
109
|
+
"babel-preset-expo": "~54.0.11",
|
|
78
110
|
"eslint": "^9.0.0",
|
|
79
111
|
"eslint-config-prettier": "^10.0.0",
|
|
80
112
|
"eslint-plugin-react": "^7.37.0",
|
|
81
|
-
"eslint-plugin-react-hooks": "^
|
|
113
|
+
"eslint-plugin-react-hooks": "^7.1.1",
|
|
82
114
|
"expo-font": "~14.0.11",
|
|
83
115
|
"expo-haptics": "~15.0.8",
|
|
84
116
|
"expo-linear-gradient": "~15.0.8",
|
|
85
|
-
"
|
|
117
|
+
"expo-sensors": "~15.0.7",
|
|
118
|
+
"jest-expo": "~54.0.17",
|
|
119
|
+
"pressto": "^0.6.1",
|
|
120
|
+
"prettier": "^3.8.3",
|
|
86
121
|
"react": "19.1.0",
|
|
87
122
|
"react-native": "0.81.5",
|
|
123
|
+
"react-native-ease": "^0.7.2",
|
|
88
124
|
"react-native-gesture-handler": "~2.28.0",
|
|
125
|
+
"react-native-pulsar": "^1.6.1",
|
|
89
126
|
"react-native-reanimated": "~4.1.1",
|
|
90
|
-
"react-native-safe-area-context": "
|
|
127
|
+
"react-native-safe-area-context": "5.6.2",
|
|
128
|
+
"react-native-screens": "4.16.0",
|
|
129
|
+
"react-native-size-matters": "^0.4.2",
|
|
130
|
+
"react-native-svg": "15.12.1",
|
|
91
131
|
"react-native-worklets": "~0.5.1",
|
|
92
132
|
"sonner-native": "0.23.1",
|
|
93
|
-
"
|
|
94
|
-
"react-native-screens": "4.16.0",
|
|
133
|
+
"test-renderer": "^1.2.0",
|
|
95
134
|
"tsup": "^8.0.0",
|
|
96
135
|
"typescript": "^5.4.0",
|
|
97
|
-
"typescript-eslint": "^8.
|
|
136
|
+
"typescript-eslint": "^8.60.0"
|
|
98
137
|
},
|
|
99
138
|
"packageManager": "pnpm@11.0.8+sha512.4c4097e1dd2d42372c4e7fa5a791ff28fc75a484c7ac192e64b1df0fdef17594ba982f9b4fed9adfb3c757846f565b799b2763fb3733d1de1bcb82cf46684912"
|
|
100
139
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -65,7 +65,7 @@ function AccordionItemComponent({
|
|
|
65
65
|
// Keep isExpanded in sync with the parent-driven isOpen prop
|
|
66
66
|
React.useEffect(() => {
|
|
67
67
|
isExpanded.value = isOpen
|
|
68
|
-
}, [isOpen])
|
|
68
|
+
}, [isOpen, isExpanded])
|
|
69
69
|
|
|
70
70
|
// Derived animated height — height * Number(isExpanded) gives 0 when closed and
|
|
71
71
|
// the measured height when open. `withTiming` wraps it so every change animates.
|
|
@@ -126,7 +126,13 @@ function AccordionItemComponent({
|
|
|
126
126
|
height.value = e.nativeEvent.layout.height
|
|
127
127
|
}}
|
|
128
128
|
>
|
|
129
|
-
{item.content
|
|
129
|
+
{typeof item.content === 'string' || typeof item.content === 'number' ? (
|
|
130
|
+
<Text style={[styles.contentText, { color: colors.foregroundMuted }]} allowFontScaling={true}>
|
|
131
|
+
{item.content}
|
|
132
|
+
</Text>
|
|
133
|
+
) : (
|
|
134
|
+
item.content
|
|
135
|
+
)}
|
|
130
136
|
</View>
|
|
131
137
|
</Animated.View>
|
|
132
138
|
</View>
|
|
@@ -190,7 +196,7 @@ const styles = StyleSheet.create({
|
|
|
190
196
|
justifyContent: 'center',
|
|
191
197
|
},
|
|
192
198
|
triggerText: {
|
|
193
|
-
fontFamily: '
|
|
199
|
+
fontFamily: 'Sohne-Medium',
|
|
194
200
|
fontSize: ms(14),
|
|
195
201
|
},
|
|
196
202
|
chevron: {
|
|
@@ -199,9 +205,14 @@ const styles = StyleSheet.create({
|
|
|
199
205
|
// position:'absolute' is the key — the inner View escapes the animated wrapper's
|
|
200
206
|
// clipped height so onLayout always reports the true content height.
|
|
201
207
|
content: {
|
|
202
|
-
paddingHorizontal: s(
|
|
208
|
+
paddingHorizontal: s(8),
|
|
203
209
|
paddingBottom: vs(12),
|
|
204
210
|
position: 'absolute',
|
|
205
211
|
width: '100%',
|
|
206
212
|
},
|
|
213
|
+
contentText: {
|
|
214
|
+
fontFamily: 'Sohne-Regular',
|
|
215
|
+
fontSize: ms(14),
|
|
216
|
+
lineHeight: ms(20),
|
|
217
|
+
},
|
|
207
218
|
})
|
|
@@ -19,13 +19,29 @@ export interface AlertBannerProps {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export function AlertBanner({ title, description, variant = 'default', icon, iconName, iconColor, style }: AlertBannerProps) {
|
|
22
|
-
const { colors } = useTheme()
|
|
22
|
+
const { colors, colorScheme } = useTheme()
|
|
23
|
+
|
|
24
|
+
// Match Toast richColors appearance — saturated semantic colors
|
|
25
|
+
const isDark = colorScheme === 'dark'
|
|
23
26
|
|
|
24
27
|
const accentColor =
|
|
25
28
|
variant === 'destructive' ? colors.destructive
|
|
26
29
|
: variant === 'success' ? colors.success
|
|
27
30
|
: variant === 'warning' ? colors.warning
|
|
28
|
-
: colors.
|
|
31
|
+
: colors.foreground
|
|
32
|
+
|
|
33
|
+
// Match sonner-native richColors backgrounds (more saturated than tint)
|
|
34
|
+
const bgColor =
|
|
35
|
+
variant === 'destructive' ? (isDark ? 'rgba(239, 83, 80, 0.15)' : 'rgba(199, 40, 40, 0.10)')
|
|
36
|
+
: variant === 'success' ? (isDark ? 'rgba(46, 125, 82, 0.15)' : 'rgba(26, 122, 69, 0.10)')
|
|
37
|
+
: variant === 'warning' ? (isDark ? 'rgba(245, 166, 35, 0.15)' : 'rgba(154, 82, 0, 0.10)')
|
|
38
|
+
: colors.surface
|
|
39
|
+
|
|
40
|
+
const borderColor =
|
|
41
|
+
variant === 'destructive' ? (isDark ? 'rgba(239, 83, 80, 0.30)' : 'rgba(199, 40, 40, 0.25)')
|
|
42
|
+
: variant === 'success' ? (isDark ? 'rgba(46, 125, 82, 0.30)' : 'rgba(26, 122, 69, 0.25)')
|
|
43
|
+
: variant === 'warning' ? (isDark ? 'rgba(245, 166, 35, 0.30)' : 'rgba(154, 82, 0, 0.25)')
|
|
44
|
+
: colors.border
|
|
29
45
|
|
|
30
46
|
const defaultIcon =
|
|
31
47
|
variant === 'success' ? (
|
|
@@ -35,6 +51,9 @@ export function AlertBanner({ title, description, variant = 'default', icon, ico
|
|
|
35
51
|
) : variant === 'warning' ? (
|
|
36
52
|
<MaterialIcons name="warning-amber" size={ms(17)} color={accentColor} />
|
|
37
53
|
) : (
|
|
54
|
+
// AUDIT FIX: default variant previously used colors.primary (near-black)
|
|
55
|
+
// as the info icon tint — ambiguous and heavy. accentResolved gives it
|
|
56
|
+
// a meaningful chromatic signal when an accent is defined.
|
|
38
57
|
<Entypo name="info-with-circle" size={ms(16)} color={accentColor} />
|
|
39
58
|
)
|
|
40
59
|
|
|
@@ -42,15 +61,24 @@ export function AlertBanner({ title, description, variant = 'default', icon, ico
|
|
|
42
61
|
? renderIcon(iconName, ms(16), iconColor ?? accentColor)
|
|
43
62
|
: icon ?? defaultIcon
|
|
44
63
|
|
|
64
|
+
// Accessibility: AlertBanner is a notification — "alert" role announces it.
|
|
65
|
+
const a11yLabel = description ? `${title}. ${description}` : title
|
|
66
|
+
|
|
45
67
|
return (
|
|
46
|
-
<View
|
|
47
|
-
{
|
|
68
|
+
<View
|
|
69
|
+
style={[
|
|
70
|
+
styles.container,
|
|
71
|
+
{ backgroundColor: bgColor, borderWidth: 1, borderColor },
|
|
72
|
+
style,
|
|
73
|
+
]}
|
|
74
|
+
accessibilityRole="alert"
|
|
75
|
+
accessibilityLabel={a11yLabel}
|
|
76
|
+
>
|
|
48
77
|
<View style={styles.iconSlot}>{effectiveIcon}</View>
|
|
49
|
-
{/* Text */}
|
|
50
78
|
<View style={styles.content}>
|
|
51
79
|
<Text style={[styles.title, { color: colors.foreground }]} allowFontScaling={true}>{title}</Text>
|
|
52
80
|
{description ? (
|
|
53
|
-
<Text style={[styles.description, { color: colors.
|
|
81
|
+
<Text style={[styles.description, { color: colors.foreground, opacity: 0.85 }]} allowFontScaling={true}>{description}</Text>
|
|
54
82
|
) : null}
|
|
55
83
|
</View>
|
|
56
84
|
</View>
|
|
@@ -63,8 +91,8 @@ const styles = StyleSheet.create({
|
|
|
63
91
|
alignItems: 'flex-start',
|
|
64
92
|
borderRadius: RADIUS.lg,
|
|
65
93
|
gap: s(8),
|
|
66
|
-
paddingVertical: vs(
|
|
67
|
-
paddingHorizontal: s(
|
|
94
|
+
paddingVertical: vs(10),
|
|
95
|
+
paddingHorizontal: s(12),
|
|
68
96
|
},
|
|
69
97
|
iconSlot: {
|
|
70
98
|
marginTop: vs(1),
|
|
@@ -74,13 +102,11 @@ const styles = StyleSheet.create({
|
|
|
74
102
|
gap: vs(2),
|
|
75
103
|
},
|
|
76
104
|
title: {
|
|
77
|
-
fontFamily: '
|
|
105
|
+
fontFamily: 'Sohne-Medium',
|
|
78
106
|
fontSize: ms(13),
|
|
79
|
-
lineHeight: ms(19),
|
|
80
107
|
},
|
|
81
108
|
description: {
|
|
82
|
-
fontFamily: '
|
|
109
|
+
fontFamily: 'Sohne-Regular',
|
|
83
110
|
fontSize: ms(12),
|
|
84
|
-
lineHeight: ms(17),
|
|
85
111
|
},
|
|
86
112
|
})
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { View, Text, StyleSheet, ViewStyle, useWindowDimensions } from 'react-native'
|
|
3
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
4
|
+
import { useTheme } from '../../theme'
|
|
5
|
+
import { IconButton } from '../IconButton'
|
|
6
|
+
import { s, vs, ms, mvs } from '../../utils/scaling'
|
|
7
|
+
import { BREAKPOINTS } from '../../tokens'
|
|
8
|
+
|
|
9
|
+
export interface AppHeaderProps {
|
|
10
|
+
/** Primary title. */
|
|
11
|
+
title?: string
|
|
12
|
+
/** Secondary text below the title. */
|
|
13
|
+
subtitle?: string
|
|
14
|
+
/** Show a back button on the left and call this when pressed. */
|
|
15
|
+
onBack?: () => void
|
|
16
|
+
/** Icon name for the back button. Defaults to `'chevron-left'`. */
|
|
17
|
+
backIconName?: string
|
|
18
|
+
/** Custom left content — overrides the back button. */
|
|
19
|
+
left?: React.ReactNode
|
|
20
|
+
/** Custom right content (actions). */
|
|
21
|
+
right?: React.ReactNode
|
|
22
|
+
/**
|
|
23
|
+
* Title alignment.
|
|
24
|
+
* - `'auto'` (default): left on narrow screens, centered when width ≥ `BREAKPOINTS.wide`.
|
|
25
|
+
* - `'left'` / `'center'`: force alignment.
|
|
26
|
+
*/
|
|
27
|
+
titleAlign?: 'auto' | 'left' | 'center'
|
|
28
|
+
/** Render a hairline border under the header. Defaults to true. */
|
|
29
|
+
bordered?: boolean
|
|
30
|
+
/** Apply the top safe-area inset as padding. Defaults to true. */
|
|
31
|
+
withSafeArea?: boolean
|
|
32
|
+
/** Background color. Defaults to theme `background`. */
|
|
33
|
+
backgroundColor?: string
|
|
34
|
+
style?: ViewStyle
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Top app bar / screen chrome — back button, title/subtitle, and a right action
|
|
39
|
+
* slot. Responsive: the title left-aligns on phones and centers on wide layouts.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* <AppHeader title="Settings" onBack={navigation.goBack} right={<IconButton iconName="more-horizontal" variant="text" />} />
|
|
43
|
+
*/
|
|
44
|
+
export function AppHeader({
|
|
45
|
+
title,
|
|
46
|
+
subtitle,
|
|
47
|
+
onBack,
|
|
48
|
+
backIconName = 'chevron-left',
|
|
49
|
+
left,
|
|
50
|
+
right,
|
|
51
|
+
titleAlign = 'auto',
|
|
52
|
+
bordered = true,
|
|
53
|
+
withSafeArea = true,
|
|
54
|
+
backgroundColor,
|
|
55
|
+
style,
|
|
56
|
+
}: AppHeaderProps) {
|
|
57
|
+
const { colors } = useTheme()
|
|
58
|
+
const insets = useSafeAreaInsets()
|
|
59
|
+
const { width } = useWindowDimensions()
|
|
60
|
+
|
|
61
|
+
const isWide = width >= BREAKPOINTS.wide
|
|
62
|
+
const centered = titleAlign === 'center' || (titleAlign === 'auto' && isWide)
|
|
63
|
+
|
|
64
|
+
const leftNode = left ?? (onBack ? (
|
|
65
|
+
<IconButton
|
|
66
|
+
iconName={backIconName}
|
|
67
|
+
variant="text"
|
|
68
|
+
size="md"
|
|
69
|
+
onPress={onBack}
|
|
70
|
+
accessibilityLabel="Go back"
|
|
71
|
+
/>
|
|
72
|
+
) : null)
|
|
73
|
+
|
|
74
|
+
const titleBlock = (
|
|
75
|
+
<View style={[styles.titleBlock, centered && styles.titleBlockCentered]} pointerEvents="none">
|
|
76
|
+
{title ? (
|
|
77
|
+
<Text
|
|
78
|
+
style={[styles.title, { color: colors.foreground }, centered && styles.textCentered]}
|
|
79
|
+
numberOfLines={1}
|
|
80
|
+
allowFontScaling={true}
|
|
81
|
+
accessibilityRole="header"
|
|
82
|
+
>
|
|
83
|
+
{title}
|
|
84
|
+
</Text>
|
|
85
|
+
) : null}
|
|
86
|
+
{subtitle ? (
|
|
87
|
+
<Text
|
|
88
|
+
style={[styles.subtitle, { color: colors.foregroundMuted }, centered && styles.textCentered]}
|
|
89
|
+
numberOfLines={1}
|
|
90
|
+
allowFontScaling={true}
|
|
91
|
+
>
|
|
92
|
+
{subtitle}
|
|
93
|
+
</Text>
|
|
94
|
+
) : null}
|
|
95
|
+
</View>
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
return (
|
|
99
|
+
<View
|
|
100
|
+
style={[
|
|
101
|
+
styles.container,
|
|
102
|
+
{
|
|
103
|
+
backgroundColor: backgroundColor ?? colors.background,
|
|
104
|
+
paddingTop: withSafeArea ? insets.top : 0,
|
|
105
|
+
borderBottomWidth: bordered ? StyleSheet.hairlineWidth : 0,
|
|
106
|
+
borderBottomColor: colors.border,
|
|
107
|
+
},
|
|
108
|
+
style,
|
|
109
|
+
]}
|
|
110
|
+
>
|
|
111
|
+
<View style={styles.bar}>
|
|
112
|
+
{/* Centered layout: absolutely-positioned title so it stays centered regardless of slot widths. */}
|
|
113
|
+
{centered ? (
|
|
114
|
+
<>
|
|
115
|
+
<View style={StyleSheet.absoluteFill}>{titleBlock}</View>
|
|
116
|
+
<View style={styles.side}>{leftNode}</View>
|
|
117
|
+
<View style={[styles.side, styles.sideRight]}>{right}</View>
|
|
118
|
+
</>
|
|
119
|
+
) : (
|
|
120
|
+
<>
|
|
121
|
+
<View style={styles.side}>{leftNode}</View>
|
|
122
|
+
{titleBlock}
|
|
123
|
+
<View style={[styles.side, styles.sideRight]}>{right}</View>
|
|
124
|
+
</>
|
|
125
|
+
)}
|
|
126
|
+
</View>
|
|
127
|
+
</View>
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const styles = StyleSheet.create({
|
|
132
|
+
container: {
|
|
133
|
+
width: '100%',
|
|
134
|
+
},
|
|
135
|
+
bar: {
|
|
136
|
+
minHeight: vs(48),
|
|
137
|
+
flexDirection: 'row',
|
|
138
|
+
alignItems: 'center',
|
|
139
|
+
paddingHorizontal: s(8),
|
|
140
|
+
},
|
|
141
|
+
side: {
|
|
142
|
+
minWidth: s(44),
|
|
143
|
+
flexDirection: 'row',
|
|
144
|
+
alignItems: 'center',
|
|
145
|
+
justifyContent: 'flex-start',
|
|
146
|
+
},
|
|
147
|
+
sideRight: {
|
|
148
|
+
justifyContent: 'flex-end',
|
|
149
|
+
},
|
|
150
|
+
titleBlock: {
|
|
151
|
+
flex: 1,
|
|
152
|
+
justifyContent: 'center',
|
|
153
|
+
paddingHorizontal: s(8),
|
|
154
|
+
gap: vs(1),
|
|
155
|
+
},
|
|
156
|
+
titleBlockCentered: {
|
|
157
|
+
alignItems: 'center',
|
|
158
|
+
},
|
|
159
|
+
title: {
|
|
160
|
+
fontFamily: 'Sohne-SemiBold',
|
|
161
|
+
fontSize: ms(18),
|
|
162
|
+
lineHeight: mvs(24),
|
|
163
|
+
},
|
|
164
|
+
subtitle: {
|
|
165
|
+
fontFamily: 'Sohne-Regular',
|
|
166
|
+
fontSize: ms(13),
|
|
167
|
+
lineHeight: mvs(16),
|
|
168
|
+
},
|
|
169
|
+
textCentered: {
|
|
170
|
+
textAlign: 'center',
|
|
171
|
+
},
|
|
172
|
+
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './AppHeader'
|
|
@@ -50,7 +50,7 @@ function getInitials(fallback?: string, fallbackText?: string): string {
|
|
|
50
50
|
return '?'
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
function AvatarBase({ src, fallback, fallbackText, size = 'md', status, style }: AvatarProps) {
|
|
54
54
|
const { colors } = useTheme()
|
|
55
55
|
const [imageError, setImageError] = useState(false)
|
|
56
56
|
const dimension = typeof size === 'number' ? size : sizeMap[size as AvatarSize]
|
|
@@ -59,8 +59,9 @@ export function Avatar({ src, fallback, fallbackText, size = 'md', status, style
|
|
|
59
59
|
|
|
60
60
|
const statusSize = typeof size === 'number' ? size * 0.25 : statusSizeMap[size as AvatarSize]
|
|
61
61
|
|
|
62
|
+
// AUDIT FIX: online was hardcoded '#22c55e' — now uses theme token.
|
|
62
63
|
const statusColor: Record<AvatarStatus, string> = {
|
|
63
|
-
online:
|
|
64
|
+
online: colors.success,
|
|
64
65
|
offline: 'transparent',
|
|
65
66
|
busy: colors.destructive,
|
|
66
67
|
away: colors.warning,
|
|
@@ -74,8 +75,15 @@ export function Avatar({ src, fallback, fallbackText, size = 'md', status, style
|
|
|
74
75
|
overflow: 'hidden',
|
|
75
76
|
}
|
|
76
77
|
|
|
78
|
+
// Compute accessible label: prefer explicit fallback text, then initials.
|
|
79
|
+
const a11yLabel = fallbackText || fallback || 'Avatar'
|
|
80
|
+
|
|
77
81
|
return (
|
|
78
|
-
<View
|
|
82
|
+
<View
|
|
83
|
+
style={[styles.wrapper, style]}
|
|
84
|
+
accessibilityRole="image"
|
|
85
|
+
accessibilityLabel={a11yLabel}
|
|
86
|
+
>
|
|
79
87
|
<View style={[styles.base, containerStyle]}>
|
|
80
88
|
{!showFallback ? (
|
|
81
89
|
<Image
|
|
@@ -111,6 +119,8 @@ export function Avatar({ src, fallback, fallbackText, size = 'md', status, style
|
|
|
111
119
|
)
|
|
112
120
|
}
|
|
113
121
|
|
|
122
|
+
export const Avatar = React.memo(AvatarBase)
|
|
123
|
+
|
|
114
124
|
const styles = StyleSheet.create({
|
|
115
125
|
wrapper: {
|
|
116
126
|
alignSelf: 'flex-start',
|
|
@@ -121,7 +131,7 @@ const styles = StyleSheet.create({
|
|
|
121
131
|
justifyContent: 'center',
|
|
122
132
|
},
|
|
123
133
|
fallback: {
|
|
124
|
-
fontFamily: '
|
|
134
|
+
fontFamily: 'Sohne-Medium',
|
|
125
135
|
},
|
|
126
136
|
statusDot: {
|
|
127
137
|
position: 'absolute',
|
|
@@ -45,7 +45,7 @@ const sizeIconGap: Record<BadgeSize, number> = {
|
|
|
45
45
|
|
|
46
46
|
const sizeIconSize: Record<BadgeSize, number> = { sm: 10, md: 12, lg: 14 }
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
function BadgeBase({ label, children, variant = 'default', size = 'md', icon, iconName, iconColor, style }: BadgeProps) {
|
|
49
49
|
const { colors } = useTheme()
|
|
50
50
|
|
|
51
51
|
const containerStyle: ViewStyle = {
|
|
@@ -78,8 +78,15 @@ export function Badge({ label, children, variant = 'default', size = 'md', icon,
|
|
|
78
78
|
|
|
79
79
|
const content = children ?? label
|
|
80
80
|
|
|
81
|
+
// Accessibility: badges are status indicators — role helps screen readers.
|
|
82
|
+
const a11yLabel = typeof content === 'string' ? content : label
|
|
83
|
+
|
|
81
84
|
return (
|
|
82
|
-
<View
|
|
85
|
+
<View
|
|
86
|
+
style={[styles.container, containerStyle, sizePadding[size], { gap: sizeIconGap[size] }, style]}
|
|
87
|
+
accessibilityRole="text"
|
|
88
|
+
accessibilityLabel={a11yLabel}
|
|
89
|
+
>
|
|
83
90
|
{effectiveIcon}
|
|
84
91
|
{typeof content === 'string' ? (
|
|
85
92
|
<Text style={[styles.label, { color: textColor }, sizeFontSize[size]]} allowFontScaling={true}>
|
|
@@ -92,6 +99,8 @@ export function Badge({ label, children, variant = 'default', size = 'md', icon,
|
|
|
92
99
|
)
|
|
93
100
|
}
|
|
94
101
|
|
|
102
|
+
export const Badge = React.memo(BadgeBase)
|
|
103
|
+
|
|
95
104
|
const styles = StyleSheet.create({
|
|
96
105
|
container: {
|
|
97
106
|
borderRadius: 9999,
|
|
@@ -100,6 +109,6 @@ const styles = StyleSheet.create({
|
|
|
100
109
|
alignItems: 'center',
|
|
101
110
|
},
|
|
102
111
|
label: {
|
|
103
|
-
fontFamily: '
|
|
112
|
+
fontFamily: 'Sohne-Medium',
|
|
104
113
|
},
|
|
105
114
|
})
|