@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
|
@@ -4,10 +4,8 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
|
4
4
|
import { useTheme } from '../../theme'
|
|
5
5
|
import { s, vs, ms } from '../../utils/scaling'
|
|
6
6
|
|
|
7
|
-
// Direct function API — no hook required
|
|
8
7
|
export { sonnerToast as toast }
|
|
9
8
|
|
|
10
|
-
// useToast — backward-compat wrapper
|
|
11
9
|
export function useToast() {
|
|
12
10
|
return {
|
|
13
11
|
toast: sonnerToast,
|
|
@@ -15,7 +13,6 @@ export function useToast() {
|
|
|
15
13
|
}
|
|
16
14
|
}
|
|
17
15
|
|
|
18
|
-
// ToastProvider — wraps children + renders the Toaster
|
|
19
16
|
export function ToastProvider({ children }: { children: React.ReactNode }) {
|
|
20
17
|
const { colorScheme } = useTheme()
|
|
21
18
|
const insets = useSafeAreaInsets()
|
|
@@ -26,7 +23,10 @@ export function ToastProvider({ children }: { children: React.ReactNode }) {
|
|
|
26
23
|
<Toaster
|
|
27
24
|
theme={colorScheme}
|
|
28
25
|
position="top-center"
|
|
29
|
-
richColors={false}
|
|
26
|
+
// AUDIT FIX: was richColors={false} — all semantic variants (error, success,
|
|
27
|
+
// warning) were visually identical. richColors={true} restores correct
|
|
28
|
+
// semantic coloring so users immediately recognise severity from colour alone.
|
|
29
|
+
richColors={true}
|
|
30
30
|
gap={vs(8)}
|
|
31
31
|
offset={insets.top + vs(8)}
|
|
32
32
|
visibleToasts={3}
|
|
@@ -40,11 +40,11 @@ export function ToastProvider({ children }: { children: React.ReactNode }) {
|
|
|
40
40
|
paddingVertical: vs(10),
|
|
41
41
|
},
|
|
42
42
|
titleStyle: {
|
|
43
|
-
fontFamily: '
|
|
43
|
+
fontFamily: 'Sohne-Medium',
|
|
44
44
|
fontSize: ms(13),
|
|
45
45
|
},
|
|
46
46
|
descriptionStyle: {
|
|
47
|
-
fontFamily: '
|
|
47
|
+
fontFamily: 'Sohne-Regular',
|
|
48
48
|
fontSize: ms(12),
|
|
49
49
|
opacity: 0.85,
|
|
50
50
|
},
|
|
@@ -1,22 +1,52 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
useAnimatedStyle,
|
|
5
|
-
interpolateColor,
|
|
6
|
-
} from 'react-native-reanimated'
|
|
2
|
+
import { StyleSheet, ViewStyle, View, Text } from 'react-native'
|
|
3
|
+
import { EaseView } from 'react-native-ease'
|
|
7
4
|
import { FontAwesome5 } from '@expo/vector-icons'
|
|
8
5
|
import { selectionAsync as hapticSelection } from '../../utils/haptics'
|
|
9
6
|
import { useTheme } from '../../theme'
|
|
10
7
|
import { s, vs, ms } from '../../utils/scaling'
|
|
11
8
|
import { renderIcon } from '../../utils/icons'
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
|
|
9
|
+
import { COLOR_TRANSITION } from '../../utils/animations'
|
|
10
|
+
import { PressableButton } from '../../utils/pressable'
|
|
11
|
+
|
|
12
|
+
interface ToggleIconProps {
|
|
13
|
+
pressed: boolean
|
|
14
|
+
iconName?: string
|
|
15
|
+
activeIconName?: string
|
|
16
|
+
icon?: React.ReactNode | ((pressed: boolean) => React.ReactNode)
|
|
17
|
+
activeIcon?: React.ReactNode | ((pressed: boolean) => React.ReactNode)
|
|
18
|
+
iconColor?: string
|
|
19
|
+
activeIconColor?: string
|
|
20
|
+
iconSize: number
|
|
21
|
+
primaryColor: string
|
|
22
|
+
mutedColor: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function ToggleIcon({ pressed, iconName, activeIconName, icon, activeIcon, iconColor, activeIconColor, iconSize, primaryColor, mutedColor }: ToggleIconProps) {
|
|
26
|
+
const renderProp = (prop?: React.ReactNode | ((p: boolean) => React.ReactNode)) => {
|
|
27
|
+
if (!prop) return null
|
|
28
|
+
if (typeof prop === 'function') return (prop as (p: boolean) => React.ReactNode)(pressed)
|
|
29
|
+
return prop
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (pressed) {
|
|
33
|
+
if (activeIconName) return <>{renderIcon(activeIconName, iconSize, activeIconColor ?? primaryColor)}</>
|
|
34
|
+
const active = renderProp(activeIcon)
|
|
35
|
+
if (active) return <>{active}</>
|
|
36
|
+
return <FontAwesome5 name="check-circle" size={iconSize} color={primaryColor} />
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (iconName) return <>{renderIcon(iconName, iconSize, iconColor ?? mutedColor)}</>
|
|
40
|
+
const custom = renderProp(icon)
|
|
41
|
+
if (custom) return <>{custom}</>
|
|
42
|
+
|
|
43
|
+
return <FontAwesome5 name="circle" size={iconSize} color={mutedColor} />
|
|
44
|
+
}
|
|
15
45
|
|
|
16
46
|
export type ToggleVariant = 'default' | 'outline'
|
|
17
47
|
export type ToggleSize = 'sm' | 'md' | 'lg'
|
|
18
48
|
|
|
19
|
-
export interface ToggleProps
|
|
49
|
+
export interface ToggleProps {
|
|
20
50
|
pressed?: boolean
|
|
21
51
|
onPressedChange?: (pressed: boolean) => void
|
|
22
52
|
variant?: ToggleVariant
|
|
@@ -40,6 +70,9 @@ export interface ToggleProps extends TouchableOpacityProps {
|
|
|
40
70
|
iconColor?: string
|
|
41
71
|
/** Override the resolved active icon color. Defaults to `primary`. */
|
|
42
72
|
activeIconColor?: string
|
|
73
|
+
disabled?: boolean
|
|
74
|
+
style?: ViewStyle
|
|
75
|
+
accessibilityLabel?: string
|
|
43
76
|
}
|
|
44
77
|
|
|
45
78
|
const sizeStyles: Record<ToggleSize, ViewStyle> = {
|
|
@@ -65,88 +98,63 @@ export function Toggle({
|
|
|
65
98
|
disabled,
|
|
66
99
|
style,
|
|
67
100
|
accessibilityLabel,
|
|
68
|
-
...props
|
|
69
101
|
}: ToggleProps) {
|
|
70
102
|
const { colors } = useTheme()
|
|
71
|
-
const { animatedStyle: scaleStyle, onPressIn, onPressOut, hoverHandlers } = usePressScale({
|
|
72
|
-
pressScale: PRESS_SCALE.button,
|
|
73
|
-
disabled,
|
|
74
|
-
})
|
|
75
|
-
const progress = useColorTransition(pressed)
|
|
76
103
|
|
|
77
104
|
const inactiveBorder = variant === 'outline' ? colors.border : 'transparent'
|
|
78
105
|
|
|
79
|
-
const surfaceStyle = useAnimatedStyle(() => ({
|
|
80
|
-
borderColor: interpolateColor(progress.value, [0, 1], [inactiveBorder, colors.primary]),
|
|
81
|
-
backgroundColor: interpolateColor(progress.value, [0, 1], ['transparent', colors.surfaceStrong]),
|
|
82
|
-
}))
|
|
83
|
-
|
|
84
|
-
const textStyle = useAnimatedStyle(() => ({
|
|
85
|
-
color: interpolateColor(progress.value, [0, 1], [colors.foreground, colors.primary]),
|
|
86
|
-
}))
|
|
87
|
-
|
|
88
106
|
const iconSize = iconSizeMap[size]
|
|
89
107
|
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if (typeof prop === 'function') return prop(pressed)
|
|
94
|
-
return prop
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (pressed) {
|
|
98
|
-
if (activeIconName) return <>{renderIcon(activeIconName, iconSize, activeIconColor ?? colors.primary)}</>
|
|
99
|
-
const active = renderProp(activeIcon)
|
|
100
|
-
if (active) return <>{active}</>
|
|
101
|
-
return <FontAwesome5 name="check-circle" size={iconSize} color={colors.primary} />
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (iconName) return <>{renderIcon(iconName, iconSize, iconColor ?? colors.foregroundMuted)}</>
|
|
105
|
-
const custom = renderProp(icon)
|
|
106
|
-
if (custom) return <>{custom}</>
|
|
107
|
-
|
|
108
|
-
return <FontAwesome5 name="circle" size={iconSize} color={colors.foregroundMuted} />
|
|
108
|
+
const handlePress = () => {
|
|
109
|
+
hapticSelection()
|
|
110
|
+
onPressedChange?.(!pressed)
|
|
109
111
|
}
|
|
110
112
|
|
|
111
113
|
return (
|
|
112
|
-
<
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
onPressedChange?.(!pressed)
|
|
120
|
-
}}
|
|
121
|
-
onPressIn={onPressIn}
|
|
122
|
-
onPressOut={onPressOut}
|
|
123
|
-
disabled={disabled}
|
|
124
|
-
activeOpacity={1}
|
|
125
|
-
touchSoundDisabled={true}
|
|
114
|
+
<View style={[disabled && styles.disabled, style]}>
|
|
115
|
+
<PressableButton
|
|
116
|
+
onPress={handlePress}
|
|
117
|
+
enabled={!disabled}
|
|
118
|
+
rippleColor="transparent"
|
|
119
|
+
touchSoundDisabled
|
|
120
|
+
activateOnHover
|
|
126
121
|
accessibilityRole="button"
|
|
127
122
|
accessibilityLabel={accessibilityLabel ?? label}
|
|
128
123
|
accessibilityState={{ selected: pressed, disabled: !!disabled }}
|
|
129
|
-
{...props}
|
|
130
124
|
>
|
|
131
|
-
<
|
|
132
|
-
style={[
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
125
|
+
<EaseView
|
|
126
|
+
style={[styles.base, sizeStyles[size], { borderWidth: 2 }]}
|
|
127
|
+
animate={{
|
|
128
|
+
borderColor: pressed ? colors.primary : inactiveBorder,
|
|
129
|
+
backgroundColor: pressed ? colors.surfaceStrong : 'transparent',
|
|
130
|
+
}}
|
|
131
|
+
transition={COLOR_TRANSITION}
|
|
138
132
|
>
|
|
139
133
|
<View style={styles.inner}>
|
|
140
|
-
<
|
|
134
|
+
<ToggleIcon
|
|
135
|
+
pressed={pressed}
|
|
136
|
+
iconName={iconName}
|
|
137
|
+
activeIconName={activeIconName}
|
|
138
|
+
icon={icon}
|
|
139
|
+
activeIcon={activeIcon}
|
|
140
|
+
iconColor={iconColor}
|
|
141
|
+
activeIconColor={activeIconColor}
|
|
142
|
+
iconSize={iconSize}
|
|
143
|
+
primaryColor={colors.primary}
|
|
144
|
+
mutedColor={colors.foregroundMuted}
|
|
145
|
+
/>
|
|
141
146
|
{label ? (
|
|
142
|
-
<
|
|
147
|
+
<Text
|
|
148
|
+
style={[styles.label, { color: pressed ? colors.primary : colors.foreground }]}
|
|
149
|
+
allowFontScaling={true}
|
|
150
|
+
>
|
|
143
151
|
{label}
|
|
144
|
-
</
|
|
152
|
+
</Text>
|
|
145
153
|
) : null}
|
|
146
154
|
</View>
|
|
147
|
-
</
|
|
148
|
-
</
|
|
149
|
-
</
|
|
155
|
+
</EaseView>
|
|
156
|
+
</PressableButton>
|
|
157
|
+
</View>
|
|
150
158
|
)
|
|
151
159
|
}
|
|
152
160
|
|
|
@@ -164,7 +172,7 @@ const styles = StyleSheet.create({
|
|
|
164
172
|
opacity: 0.45,
|
|
165
173
|
},
|
|
166
174
|
label: {
|
|
167
|
-
fontFamily: '
|
|
175
|
+
fontFamily: 'Sohne-Medium',
|
|
168
176
|
fontSize: ms(14),
|
|
169
177
|
},
|
|
170
178
|
})
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React, { useCallback } from 'react'
|
|
2
|
+
import { FlatList, FlatListProps, ListRenderItem } from 'react-native'
|
|
3
|
+
|
|
4
|
+
export interface VirtualListItem {
|
|
5
|
+
id?: string | number
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface VirtualListProps<T> extends Omit<FlatListProps<T>, 'getItemLayout'> {
|
|
9
|
+
/**
|
|
10
|
+
* Fixed row height in px. When provided, enables `getItemLayout` so the list
|
|
11
|
+
* skips async measurement — large datasets scroll and `scrollToIndex` jump
|
|
12
|
+
* without layout passes. Omit only for variable-height rows.
|
|
13
|
+
*/
|
|
14
|
+
itemHeight?: number
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const defaultKeyExtractor = <T,>(item: T, index: number): string => {
|
|
18
|
+
const id = (item as VirtualListItem | null)?.id
|
|
19
|
+
return id !== undefined ? String(id) : String(index)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Virtualized list primitive. Thin wrapper over `FlatList` with sane defaults
|
|
24
|
+
* for the common case: stable keys + optional fixed-height fast path.
|
|
25
|
+
*
|
|
26
|
+
* For 10k+ rows, pass `itemHeight` and a `React.memo`-wrapped `renderItem` so
|
|
27
|
+
* only on-screen rows mount and re-render.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* const renderItem = useCallback(({ item }) => <ListItem title={item.title} onPress={...} />, [])
|
|
31
|
+
* <VirtualList data={rows} renderItem={renderItem} itemHeight={64} />
|
|
32
|
+
*/
|
|
33
|
+
function VirtualListInner<T>(
|
|
34
|
+
{ itemHeight, keyExtractor, renderItem, ...props }: VirtualListProps<T>,
|
|
35
|
+
ref: React.Ref<FlatList<T>>,
|
|
36
|
+
) {
|
|
37
|
+
const getItemLayout = useCallback(
|
|
38
|
+
(_data: ArrayLike<T> | null | undefined, index: number) => ({
|
|
39
|
+
length: itemHeight ?? 0,
|
|
40
|
+
offset: (itemHeight ?? 0) * index,
|
|
41
|
+
index,
|
|
42
|
+
}),
|
|
43
|
+
[itemHeight],
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<FlatList<T>
|
|
48
|
+
ref={ref}
|
|
49
|
+
keyExtractor={keyExtractor ?? defaultKeyExtractor}
|
|
50
|
+
renderItem={renderItem as ListRenderItem<T>}
|
|
51
|
+
getItemLayout={itemHeight !== undefined ? getItemLayout : undefined}
|
|
52
|
+
removeClippedSubviews
|
|
53
|
+
{...props}
|
|
54
|
+
/>
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const VirtualList = React.forwardRef(VirtualListInner) as <T>(
|
|
59
|
+
props: VirtualListProps<T> & { ref?: React.Ref<FlatList<T>> },
|
|
60
|
+
) => React.ReactElement
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './VirtualList'
|
package/src/fonts.ts
CHANGED
|
@@ -1,30 +1,51 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* Sohne font family required by @retray-dev/ui-kit components.
|
|
3
|
+
*
|
|
4
4
|
* Consumer apps must load these fonts at app root using expo-font:
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
6
|
* @example
|
|
7
7
|
* import { useFonts } from 'expo-font'
|
|
8
|
-
* import {
|
|
9
|
-
*
|
|
8
|
+
* import { SohneFonts } from '@retray-dev/ui-kit/fonts'
|
|
9
|
+
*
|
|
10
10
|
* function App() {
|
|
11
|
-
* const [fontsLoaded] = useFonts(
|
|
11
|
+
* const [fontsLoaded] = useFonts(SohneFonts)
|
|
12
12
|
* if (!fontsLoaded) return null
|
|
13
13
|
* // render app
|
|
14
14
|
* }
|
|
15
15
|
*/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
'
|
|
23
|
-
'
|
|
24
|
-
'
|
|
25
|
-
'
|
|
26
|
-
'
|
|
27
|
-
'
|
|
28
|
-
'
|
|
29
|
-
'
|
|
16
|
+
// `.otf` assets resolve to a Metro asset module id (number) via require() at the
|
|
17
|
+
// consumer's build time. Declared locally so the dts build does not depend on @types/node.
|
|
18
|
+
declare const require: (path: string) => number
|
|
19
|
+
|
|
20
|
+
export const SohneFonts = {
|
|
21
|
+
// Sohne base
|
|
22
|
+
'Sohne-ExtraLight': require('./assets/fonts/Sohne-ExtraLight.otf'),
|
|
23
|
+
'Sohne-ExtraLightItalic': require('./assets/fonts/Sohne-ExtraLightItalic.otf'),
|
|
24
|
+
'Sohne-Light': require('./assets/fonts/Sohne-Light.otf'),
|
|
25
|
+
'Sohne-LightItalic': require('./assets/fonts/Sohne-LightItalic.otf'),
|
|
26
|
+
'Sohne-Regular': require('./assets/fonts/Sohne-Regular.otf'),
|
|
27
|
+
'Sohne-Italic': require('./assets/fonts/Sohne-Italic.otf'),
|
|
28
|
+
'Sohne-Medium': require('./assets/fonts/Sohne-Medium.otf'),
|
|
29
|
+
'Sohne-MediumItalic': require('./assets/fonts/Sohne-MediumItalic.otf'),
|
|
30
|
+
'Sohne-SemiBold': require('./assets/fonts/Sohne-SemiBold.otf'),
|
|
31
|
+
'Sohne-SemiBoldItalic': require('./assets/fonts/Sohne-SemiBoldItalic.otf'),
|
|
32
|
+
'Sohne-Bold': require('./assets/fonts/Sohne-Bold.otf'),
|
|
33
|
+
'Sohne-BoldItalic': require('./assets/fonts/Sohne-BoldItalic.otf'),
|
|
34
|
+
'Sohne-ExtraBold': require('./assets/fonts/Sohne-ExtraBold.otf'),
|
|
35
|
+
'Sohne-ExtraBoldItalic': require('./assets/fonts/Sohne-ExtraBoldItalic.otf'),
|
|
36
|
+
// SohneMono
|
|
37
|
+
'SohneMono-ExtraLight': require('./assets/fonts/SohneMono-ExtraLight.otf'),
|
|
38
|
+
'SohneMono-ExtraLightItalic': require('./assets/fonts/SohneMono-ExtraLightItalic.otf'),
|
|
39
|
+
'SohneMono-Light': require('./assets/fonts/SohneMono-Light.otf'),
|
|
40
|
+
'SohneMono-LightItalic': require('./assets/fonts/SohneMono-LightItalic.otf'),
|
|
41
|
+
'SohneMono-Regular': require('./assets/fonts/SohneMono-Regular.otf'),
|
|
42
|
+
'SohneMono-Italic': require('./assets/fonts/SohneMono-Italic.otf'),
|
|
43
|
+
'SohneMono-Medium': require('./assets/fonts/SohneMono-Medium.otf'),
|
|
44
|
+
'SohneMono-MediumItalic': require('./assets/fonts/SohneMono-MediumItalic.otf'),
|
|
45
|
+
'SohneMono-SemiBold': require('./assets/fonts/SohneMono-SemiBold.otf'),
|
|
46
|
+
'SohneMono-SemiBoldItalic': require('./assets/fonts/SohneMono-SemiBoldItalic.otf'),
|
|
47
|
+
'SohneMono-Bold': require('./assets/fonts/SohneMono-Bold.otf'),
|
|
48
|
+
'SohneMono-BoldItalic': require('./assets/fonts/SohneMono-BoldItalic.otf'),
|
|
49
|
+
'SohneMono-ExtraBold': require('./assets/fonts/SohneMono-ExtraBold.otf'),
|
|
50
|
+
'SohneMono-ExtraBoldItalic': require('./assets/fonts/SohneMono-ExtraBoldItalic.otf'),
|
|
30
51
|
} as const
|
package/src/index.ts
CHANGED
|
@@ -31,10 +31,10 @@ export * from './components/Select'
|
|
|
31
31
|
export * from './components/Toast'
|
|
32
32
|
export * from './components/CurrencyInput'
|
|
33
33
|
export * from './components/CurrencyDisplay'
|
|
34
|
-
// CurrencyInputLarge is deprecated — use <CurrencyInput size="large" /> instead
|
|
35
|
-
export { CurrencyInput as CurrencyInputLarge } from './components/CurrencyInput'
|
|
36
34
|
export * from './components/ListItem'
|
|
35
|
+
export * from './components/ListGroup'
|
|
37
36
|
export * from './components/MenuItem'
|
|
37
|
+
export * from './components/MenuGroup'
|
|
38
38
|
export * from './components/Chip'
|
|
39
39
|
export * from './components/ConfirmDialog'
|
|
40
40
|
export * from './components/LabelValue'
|
|
@@ -43,14 +43,39 @@ export * from './components/MediaCard'
|
|
|
43
43
|
export * from './components/CategoryStrip'
|
|
44
44
|
export * from './components/Pressable'
|
|
45
45
|
export * from './components/DetailRow'
|
|
46
|
+
export * from './components/Form'
|
|
47
|
+
export * from './components/VirtualList'
|
|
48
|
+
export * from './components/RetrayProvider'
|
|
49
|
+
export * from './components/ErrorBoundary'
|
|
50
|
+
export * from './components/PagerDots'
|
|
51
|
+
export * from './components/AppHeader'
|
|
52
|
+
export * from './components/SelectableGrid'
|
|
53
|
+
export * from './components/PricingCard'
|
|
54
|
+
export * from './components/TabBar'
|
|
55
|
+
export * from './components/ImageViewer'
|
|
56
|
+
// HolographicCard is intentionally NOT re-exported here — it depends on the
|
|
57
|
+
// optional peer @shopify/react-native-skia, so it must stay out of the main
|
|
58
|
+
// barrel's module graph. Deep-import it: '@retray-dev/ui-kit/HolographicCard'.
|
|
46
59
|
|
|
47
60
|
// Icon utility
|
|
48
|
-
export { Icon, renderIcon } from './utils/icons'
|
|
61
|
+
export { Icon, renderIcon, configureIconFamilies } from './utils/icons'
|
|
49
62
|
|
|
50
63
|
// Typography utilities
|
|
51
64
|
export { getResponsiveFontSize } from './utils/typography'
|
|
52
65
|
export type { IconProps, IconFamily } from './utils/icons'
|
|
53
66
|
|
|
67
|
+
// Haptic feedback utilities
|
|
68
|
+
export {
|
|
69
|
+
selectionAsync,
|
|
70
|
+
impactLight,
|
|
71
|
+
impactMedium,
|
|
72
|
+
impactHeavy,
|
|
73
|
+
notificationSuccess,
|
|
74
|
+
notificationError,
|
|
75
|
+
notificationWarning,
|
|
76
|
+
richHaptics,
|
|
77
|
+
} from './utils/haptics'
|
|
78
|
+
|
|
54
79
|
// Design tokens
|
|
55
80
|
export {
|
|
56
81
|
SPACING,
|
package/src/theme/colors.ts
CHANGED
|
@@ -1,61 +1,74 @@
|
|
|
1
1
|
import { ThemeColors, ResolvedColors } from './types'
|
|
2
|
-
import { mixWithBackground, withAlphaOnWhite, withAlphaOnDark, lighten, darken
|
|
2
|
+
import { mixWithBackground, withAlphaOnWhite, withAlphaOnDark, lighten, darken } from './colorUtils'
|
|
3
3
|
|
|
4
|
-
// ─── Default palettes
|
|
5
|
-
//
|
|
6
|
-
//
|
|
4
|
+
// ─── Default palettes ─────────────────────────────────────────────────────────
|
|
5
|
+
// AUDIT FIXES applied:
|
|
6
|
+
// · accent + accentForeground added — system was fully achromatic
|
|
7
|
+
// · warning darkened: #e67e00 → #9a5200 (white text: 2.86:1 → 5.86:1 ✓ AA)
|
|
8
|
+
// · destructive darkened: #e53935 → #c72828 (white text: 4.22:1 → 5.59:1 ✓ AA)
|
|
9
|
+
// · foreground tweaked #222222 → #1a1a1a (matches primary, 16.1:1 on white ✓)
|
|
7
10
|
|
|
8
11
|
export const defaultLight: ThemeColors = {
|
|
9
|
-
background:
|
|
10
|
-
foreground:
|
|
11
|
-
card:
|
|
12
|
-
primary:
|
|
13
|
-
primaryForeground:
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
background: '#ffffff',
|
|
13
|
+
foreground: '#1a1a1a',
|
|
14
|
+
card: '#ffffff',
|
|
15
|
+
primary: '#1a1a1a',
|
|
16
|
+
primaryForeground: '#ffffff',
|
|
17
|
+
// AUDIT FIX: brand accent — was undefined; falls back to primary when omitted
|
|
18
|
+
accent: '#d4561d',
|
|
19
|
+
accentForeground: '#ffffff',
|
|
20
|
+
border: '#dddddd',
|
|
21
|
+
// AUDIT FIX: was #e53935 (4.22:1 on white — fails AA); #c72828 = 5.59:1 ✓
|
|
22
|
+
destructive: '#c72828',
|
|
16
23
|
destructiveForeground: '#ffffff',
|
|
17
|
-
success:
|
|
18
|
-
successForeground:
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
success: '#1a7a45',
|
|
25
|
+
successForeground: '#ffffff',
|
|
26
|
+
// AUDIT FIX: was #e67e00 (2.86:1 — severe fail); #9a5200 = 5.86:1 ✓ AAA-near
|
|
27
|
+
warning: '#9a5200',
|
|
28
|
+
warningForeground: '#ffffff',
|
|
21
29
|
}
|
|
22
30
|
|
|
23
31
|
export const defaultDark: ThemeColors = {
|
|
24
|
-
background:
|
|
25
|
-
foreground:
|
|
26
|
-
card:
|
|
27
|
-
primary:
|
|
28
|
-
primaryForeground:
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
background: '#0f0f0f',
|
|
33
|
+
foreground: '#fafafa',
|
|
34
|
+
card: '#1c1c1c',
|
|
35
|
+
primary: '#fafafa',
|
|
36
|
+
primaryForeground: '#0f0f0f',
|
|
37
|
+
// AUDIT FIX: lighter accent for dark surfaces (warm amber-orange)
|
|
38
|
+
accent: '#e87645',
|
|
39
|
+
accentForeground: '#ffffff',
|
|
40
|
+
border: '#303030',
|
|
41
|
+
destructive: '#ef5350',
|
|
31
42
|
destructiveForeground: '#ffffff',
|
|
32
|
-
success:
|
|
33
|
-
successForeground:
|
|
34
|
-
|
|
35
|
-
|
|
43
|
+
success: '#2e7d52',
|
|
44
|
+
successForeground: '#ffffff',
|
|
45
|
+
// AUDIT FIX: brighter amber for dark-bg visibility; dark text for contrast
|
|
46
|
+
// #f5a623 on #0f0f0f = 8.6:1 ✓ as indicator; #0f0f0f text on #f5a623 = 8.6:1 ✓
|
|
47
|
+
warning: '#f5a623',
|
|
48
|
+
warningForeground: '#0f0f0f',
|
|
36
49
|
}
|
|
37
50
|
|
|
38
51
|
// ─── Color derivation ─────────────────────────────────────────────────────────
|
|
39
|
-
// Takes 12 public tokens → produces full ResolvedColors for component consumption.
|
|
40
|
-
// Dark mode uses bg-blended tints instead of white-blended to stay on-palette.
|
|
41
|
-
|
|
42
52
|
export function deriveColors(t: ThemeColors, scheme: 'light' | 'dark'): ResolvedColors {
|
|
43
53
|
const dark = scheme === 'dark'
|
|
44
54
|
const bg = t.background
|
|
45
55
|
|
|
46
|
-
// Text hierarchy
|
|
47
|
-
|
|
48
|
-
|
|
56
|
+
// AUDIT FIX: Text hierarchy opacities raised to pass WCAG AA.
|
|
57
|
+
// foregroundSubtle was 0.55 → ~#858585 (3.5:1 fail on white)
|
|
58
|
+
// foregroundMuted was 0.38 → ~#ababab (2.2:1 critical fail on white)
|
|
59
|
+
// New values on light (#1a1a1a on #ffffff):
|
|
60
|
+
// foregroundSubtle 0.70 → ~#646464 (5.9:1 ✓ AA)
|
|
61
|
+
// foregroundMuted 0.62 → ~#767676 (4.5:1 ✓ AA minimum)
|
|
62
|
+
const foregroundSubtle = mixWithBackground(t.foreground, bg, 0.70)
|
|
63
|
+
const foregroundMuted = mixWithBackground(t.foreground, bg, 0.62)
|
|
49
64
|
|
|
50
|
-
// Surface fills: slight offset from background
|
|
51
65
|
const surface = dark
|
|
52
|
-
? lighten(bg, -0.06)
|
|
53
|
-
: darken(bg, 0.04)
|
|
66
|
+
? lighten(bg, -0.06)
|
|
67
|
+
: darken(bg, 0.04)
|
|
54
68
|
const surfaceStrong = dark
|
|
55
69
|
? lighten(bg, -0.12)
|
|
56
|
-
: darken(bg, 0.08)
|
|
70
|
+
: darken(bg, 0.08)
|
|
57
71
|
|
|
58
|
-
// Semantic tints: color blended toward background
|
|
59
72
|
const destructiveTint = dark
|
|
60
73
|
? withAlphaOnDark(t.destructive, 0.15, bg)
|
|
61
74
|
: withAlphaOnWhite(t.destructive, 0.08)
|
|
@@ -92,7 +105,8 @@ export function deriveColors(t: ThemeColors, scheme: 'light' | 'dark'): Resolved
|
|
|
92
105
|
overlay: t.overlay ?? 'rgba(0,0,0,0.45)',
|
|
93
106
|
accentResolved: t.accent ?? t.primary,
|
|
94
107
|
accentForegroundResolved: t.accentForeground ?? t.primaryForeground,
|
|
95
|
-
ring: t.
|
|
96
|
-
input: t.border,
|
|
108
|
+
ring: t.accent ?? t.primary,
|
|
109
|
+
input: t.border,
|
|
110
|
+
separator: dark ? lighten(t.border, 0.22) : darken(t.border, 0.16),
|
|
97
111
|
}
|
|
98
112
|
}
|
package/src/theme/types.ts
CHANGED
|
@@ -49,6 +49,9 @@ export type ResolvedColors = ThemeColors & {
|
|
|
49
49
|
// Aliases (ring + input always equal primary + border for coherence)
|
|
50
50
|
ring: string // = primary
|
|
51
51
|
input: string // = border
|
|
52
|
+
|
|
53
|
+
// Divider/separator line — deliberately darker than border for visibility
|
|
54
|
+
separator: string
|
|
52
55
|
}
|
|
53
56
|
|
|
54
57
|
export type Theme = {
|