@retray-dev/ui-kit 6.2.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 +444 -10
- 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 -873
- package/dist/index.d.ts +94 -873
- package/dist/index.js +751 -357
- package/dist/index.mjs +50 -3895
- 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 +3 -3
- 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 +10 -11
- package/src/components/ButtonGroup/ButtonGroup.tsx +13 -10
- package/src/components/Card/Card.tsx +17 -34
- package/src/components/CategoryStrip/CategoryStrip.tsx +24 -21
- package/src/components/Checkbox/Checkbox.tsx +11 -6
- package/src/components/Chip/Chip.tsx +17 -15
- 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 +4 -2
- 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 +9 -10
- package/src/components/MediaCard/MediaCard.tsx +7 -5
- package/src/components/MenuGroup/MenuGroup.tsx +145 -0
- package/src/components/MenuGroup/index.ts +1 -0
- package/src/components/MenuItem/MenuItem.tsx +7 -9
- package/src/components/MonthPicker/MonthPicker.tsx +2 -2
- package/src/components/RadioGroup/RadioGroup.tsx +11 -14
- package/src/components/Select/Select.tsx +6 -6
- package/src/components/Separator/Separator.tsx +1 -3
- package/src/components/Sheet/Sheet.tsx +81 -17
- package/src/components/Skeleton/Skeleton.tsx +1 -1
- package/src/components/Slider/Slider.tsx +2 -2
- package/src/components/Spinner/Spinner.tsx +1 -1
- package/src/components/Switch/Switch.tsx +28 -5
- package/src/components/Tabs/Tabs.tsx +22 -18
- package/src/components/Text/Text.tsx +3 -1
- package/src/components/Textarea/Textarea.tsx +18 -14
- package/src/components/Toast/Toast.tsx +6 -6
- package/src/components/Toggle/Toggle.tsx +47 -23
- 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/icons.ts +47 -20
- 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
|
@@ -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,48 @@
|
|
|
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
|
+
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
17
|
+
export const SohneFonts = {
|
|
18
|
+
// Sohne base
|
|
19
|
+
'Sohne-ExtraLight': require('./assets/fonts/Sohne-ExtraLight.otf'),
|
|
20
|
+
'Sohne-ExtraLightItalic': require('./assets/fonts/Sohne-ExtraLightItalic.otf'),
|
|
21
|
+
'Sohne-Light': require('./assets/fonts/Sohne-Light.otf'),
|
|
22
|
+
'Sohne-LightItalic': require('./assets/fonts/Sohne-LightItalic.otf'),
|
|
23
|
+
'Sohne-Regular': require('./assets/fonts/Sohne-Regular.otf'),
|
|
24
|
+
'Sohne-Italic': require('./assets/fonts/Sohne-Italic.otf'),
|
|
25
|
+
'Sohne-Medium': require('./assets/fonts/Sohne-Medium.otf'),
|
|
26
|
+
'Sohne-MediumItalic': require('./assets/fonts/Sohne-MediumItalic.otf'),
|
|
27
|
+
'Sohne-SemiBold': require('./assets/fonts/Sohne-SemiBold.otf'),
|
|
28
|
+
'Sohne-SemiBoldItalic': require('./assets/fonts/Sohne-SemiBoldItalic.otf'),
|
|
29
|
+
'Sohne-Bold': require('./assets/fonts/Sohne-Bold.otf'),
|
|
30
|
+
'Sohne-BoldItalic': require('./assets/fonts/Sohne-BoldItalic.otf'),
|
|
31
|
+
'Sohne-ExtraBold': require('./assets/fonts/Sohne-ExtraBold.otf'),
|
|
32
|
+
'Sohne-ExtraBoldItalic': require('./assets/fonts/Sohne-ExtraBoldItalic.otf'),
|
|
33
|
+
// SohneMono
|
|
34
|
+
'SohneMono-ExtraLight': require('./assets/fonts/SohneMono-ExtraLight.otf'),
|
|
35
|
+
'SohneMono-ExtraLightItalic': require('./assets/fonts/SohneMono-ExtraLightItalic.otf'),
|
|
36
|
+
'SohneMono-Light': require('./assets/fonts/SohneMono-Light.otf'),
|
|
37
|
+
'SohneMono-LightItalic': require('./assets/fonts/SohneMono-LightItalic.otf'),
|
|
38
|
+
'SohneMono-Regular': require('./assets/fonts/SohneMono-Regular.otf'),
|
|
39
|
+
'SohneMono-Italic': require('./assets/fonts/SohneMono-Italic.otf'),
|
|
40
|
+
'SohneMono-Medium': require('./assets/fonts/SohneMono-Medium.otf'),
|
|
41
|
+
'SohneMono-MediumItalic': require('./assets/fonts/SohneMono-MediumItalic.otf'),
|
|
42
|
+
'SohneMono-SemiBold': require('./assets/fonts/SohneMono-SemiBold.otf'),
|
|
43
|
+
'SohneMono-SemiBoldItalic': require('./assets/fonts/SohneMono-SemiBoldItalic.otf'),
|
|
44
|
+
'SohneMono-Bold': require('./assets/fonts/SohneMono-Bold.otf'),
|
|
45
|
+
'SohneMono-BoldItalic': require('./assets/fonts/SohneMono-BoldItalic.otf'),
|
|
46
|
+
'SohneMono-ExtraBold': require('./assets/fonts/SohneMono-ExtraBold.otf'),
|
|
47
|
+
'SohneMono-ExtraBoldItalic': require('./assets/fonts/SohneMono-ExtraBoldItalic.otf'),
|
|
30
48
|
} as const
|
package/src/index.ts
CHANGED
|
@@ -34,7 +34,9 @@ export * from './components/CurrencyDisplay'
|
|
|
34
34
|
// CurrencyInputLarge is deprecated — use <CurrencyInput size="large" /> instead
|
|
35
35
|
export { CurrencyInput as CurrencyInputLarge } from './components/CurrencyInput'
|
|
36
36
|
export * from './components/ListItem'
|
|
37
|
+
export * from './components/ListGroup'
|
|
37
38
|
export * from './components/MenuItem'
|
|
39
|
+
export * from './components/MenuGroup'
|
|
38
40
|
export * from './components/Chip'
|
|
39
41
|
export * from './components/ConfirmDialog'
|
|
40
42
|
export * from './components/LabelValue'
|
|
@@ -43,9 +45,11 @@ export * from './components/MediaCard'
|
|
|
43
45
|
export * from './components/CategoryStrip'
|
|
44
46
|
export * from './components/Pressable'
|
|
45
47
|
export * from './components/DetailRow'
|
|
48
|
+
export * from './components/Form'
|
|
49
|
+
export * from './components/VirtualList'
|
|
46
50
|
|
|
47
51
|
// Icon utility
|
|
48
|
-
export { Icon, renderIcon } from './utils/icons'
|
|
52
|
+
export { Icon, renderIcon, configureIconFamilies } from './utils/icons'
|
|
49
53
|
|
|
50
54
|
// Typography utilities
|
|
51
55
|
export { getResponsiveFontSize } from './utils/typography'
|
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 = {
|
package/src/tokens.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// ─── Spacing ─────────────────────────────────────────────────────────────────
|
|
2
|
-
// 8pt grid with 2pt micro-step. `section` for major band separators (Airbnb: 64px).
|
|
3
2
|
export const SPACING = {
|
|
4
3
|
xxs: 2,
|
|
5
4
|
xs: 4,
|
|
@@ -22,8 +21,6 @@ export const ICON_SIZES = {
|
|
|
22
21
|
} as const
|
|
23
22
|
|
|
24
23
|
// ─── Border radius ────────────────────────────────────────────────────────────
|
|
25
|
-
// Airbnb-aligned shape language — soft everywhere, no hard corners on interactive elements.
|
|
26
|
-
// xs: micro chips/tags sm: inputs/forms md: cards lg: sheet corners xl: primary CTAs (pill)
|
|
27
24
|
export const RADIUS = {
|
|
28
25
|
none: 0,
|
|
29
26
|
xs: 4,
|
|
@@ -35,7 +32,6 @@ export const RADIUS = {
|
|
|
35
32
|
} as const
|
|
36
33
|
|
|
37
34
|
// ─── Shadows ──────────────────────────────────────────────────────────────────
|
|
38
|
-
// Multi-tier. Default card usage = sm. Hover float = md. Modals = lg/xl.
|
|
39
35
|
export const SHADOWS = {
|
|
40
36
|
sm: {
|
|
41
37
|
shadowColor: '#000',
|
|
@@ -73,118 +69,132 @@ export const BREAKPOINTS = {
|
|
|
73
69
|
} as const
|
|
74
70
|
|
|
75
71
|
// ─── Typography ───────────────────────────────────────────────────────────────
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
//
|
|
72
|
+
// AUDIT FIX: Rationalised display scale — removed weight inversions and size
|
|
73
|
+
// collisions. display-lg/md separated by 4px with matching weights. title-md/sm
|
|
74
|
+
// now actually differ in size. uppercase-tag raised from 10px → 11px for
|
|
75
|
+
// minimum mobile readability (Apple HIG: 11pt floor).
|
|
79
76
|
export const TYPOGRAPHY = {
|
|
80
77
|
'display-hero': {
|
|
81
|
-
fontFamily: '
|
|
78
|
+
fontFamily: 'Sohne-Bold',
|
|
82
79
|
fontSize: 64,
|
|
83
80
|
fontWeight: '700' as const,
|
|
84
81
|
lineHeight: 70,
|
|
85
82
|
letterSpacing: -1,
|
|
86
83
|
},
|
|
87
84
|
'display-xl': {
|
|
88
|
-
fontFamily: '
|
|
85
|
+
fontFamily: 'Sohne-Bold',
|
|
89
86
|
fontSize: 28,
|
|
90
87
|
fontWeight: '700' as const,
|
|
91
88
|
lineHeight: 40,
|
|
92
89
|
letterSpacing: 0,
|
|
93
90
|
},
|
|
91
|
+
// AUDIT FIX: was 22px/500 — raised to 24px/600; removes weight inversion vs display-md
|
|
94
92
|
'display-lg': {
|
|
95
|
-
fontFamily: '
|
|
96
|
-
fontSize:
|
|
97
|
-
fontWeight: '
|
|
98
|
-
lineHeight:
|
|
99
|
-
letterSpacing: -0.
|
|
93
|
+
fontFamily: 'Sohne-SemiBold',
|
|
94
|
+
fontSize: 24,
|
|
95
|
+
fontWeight: '600' as const,
|
|
96
|
+
lineHeight: 32,
|
|
97
|
+
letterSpacing: -0.3,
|
|
100
98
|
},
|
|
99
|
+
// AUDIT FIX: was 21px/700 — lowered to 20px/600; weight normalised, 4px gap preserved
|
|
101
100
|
'display-md': {
|
|
102
|
-
fontFamily: '
|
|
103
|
-
fontSize:
|
|
104
|
-
fontWeight: '
|
|
105
|
-
lineHeight:
|
|
101
|
+
fontFamily: 'Sohne-SemiBold',
|
|
102
|
+
fontSize: 20,
|
|
103
|
+
fontWeight: '600' as const,
|
|
104
|
+
lineHeight: 28,
|
|
106
105
|
letterSpacing: 0,
|
|
107
106
|
},
|
|
108
107
|
'display-sm': {
|
|
109
|
-
fontFamily: '
|
|
110
|
-
fontSize:
|
|
108
|
+
fontFamily: 'Sohne-SemiBold',
|
|
109
|
+
fontSize: 18,
|
|
111
110
|
fontWeight: '600' as const,
|
|
112
111
|
lineHeight: 24,
|
|
113
112
|
letterSpacing: -0.18,
|
|
114
113
|
},
|
|
114
|
+
// AUDIT FIX: was 16px — raised to 17px so title-md > title-sm is size-visible
|
|
115
115
|
'title-md': {
|
|
116
|
-
fontFamily: '
|
|
117
|
-
fontSize:
|
|
116
|
+
fontFamily: 'Sohne-SemiBold',
|
|
117
|
+
fontSize: 17,
|
|
118
118
|
fontWeight: '600' as const,
|
|
119
|
-
lineHeight:
|
|
119
|
+
lineHeight: 22,
|
|
120
120
|
letterSpacing: 0,
|
|
121
121
|
},
|
|
122
|
+
// AUDIT FIX: was 16px — lowered to 15px; now distinct from title-md
|
|
122
123
|
'title-sm': {
|
|
123
|
-
fontFamily: '
|
|
124
|
-
fontSize:
|
|
124
|
+
fontFamily: 'Sohne-Medium',
|
|
125
|
+
fontSize: 15,
|
|
125
126
|
fontWeight: '500' as const,
|
|
126
127
|
lineHeight: 20,
|
|
127
128
|
letterSpacing: 0,
|
|
128
129
|
},
|
|
129
130
|
'body-md': {
|
|
130
|
-
fontFamily: '
|
|
131
|
+
fontFamily: 'Sohne-Regular',
|
|
131
132
|
fontSize: 16,
|
|
132
133
|
fontWeight: '400' as const,
|
|
133
134
|
lineHeight: 24,
|
|
134
135
|
letterSpacing: 0,
|
|
135
136
|
},
|
|
136
137
|
'body-sm': {
|
|
137
|
-
fontFamily: '
|
|
138
|
+
fontFamily: 'Sohne-Regular',
|
|
138
139
|
fontSize: 14,
|
|
139
140
|
fontWeight: '400' as const,
|
|
140
141
|
lineHeight: 20,
|
|
141
142
|
letterSpacing: 0,
|
|
142
143
|
},
|
|
143
|
-
caption: {
|
|
144
|
-
fontFamily: '
|
|
144
|
+
'caption': {
|
|
145
|
+
fontFamily: 'Sohne-Medium',
|
|
145
146
|
fontSize: 14,
|
|
146
147
|
fontWeight: '500' as const,
|
|
147
148
|
lineHeight: 18,
|
|
148
149
|
letterSpacing: 0,
|
|
149
150
|
},
|
|
150
151
|
'caption-sm': {
|
|
151
|
-
fontFamily: '
|
|
152
|
+
fontFamily: 'Sohne-Regular',
|
|
152
153
|
fontSize: 13,
|
|
153
154
|
fontWeight: '400' as const,
|
|
154
155
|
lineHeight: 16,
|
|
155
156
|
letterSpacing: 0,
|
|
156
157
|
},
|
|
157
158
|
'badge-text': {
|
|
158
|
-
fontFamily: '
|
|
159
|
+
fontFamily: 'Sohne-SemiBold',
|
|
159
160
|
fontSize: 11,
|
|
160
161
|
fontWeight: '600' as const,
|
|
161
|
-
lineHeight:
|
|
162
|
+
lineHeight: 14,
|
|
163
|
+
letterSpacing: 0,
|
|
164
|
+
},
|
|
165
|
+
// AUDIT FIX: added badge-text-md so Badge md size has a canonical token
|
|
166
|
+
'badge-text-md': {
|
|
167
|
+
fontFamily: 'Sohne-SemiBold',
|
|
168
|
+
fontSize: 13,
|
|
169
|
+
fontWeight: '600' as const,
|
|
170
|
+
lineHeight: 16,
|
|
162
171
|
letterSpacing: 0,
|
|
163
172
|
},
|
|
164
173
|
'micro-label': {
|
|
165
|
-
fontFamily: '
|
|
174
|
+
fontFamily: 'Sohne-Bold',
|
|
166
175
|
fontSize: 12,
|
|
167
176
|
fontWeight: '700' as const,
|
|
168
177
|
lineHeight: 16,
|
|
169
178
|
letterSpacing: 0,
|
|
170
179
|
},
|
|
180
|
+
// AUDIT FIX: was 10px/0.8 letterSpacing — raised to 11px/0.6; minimum mobile readability
|
|
171
181
|
'uppercase-tag': {
|
|
172
|
-
fontFamily: '
|
|
173
|
-
fontSize:
|
|
182
|
+
fontFamily: 'Sohne-Bold',
|
|
183
|
+
fontSize: 11,
|
|
174
184
|
fontWeight: '700' as const,
|
|
175
|
-
lineHeight:
|
|
176
|
-
letterSpacing: 0.
|
|
185
|
+
lineHeight: 14,
|
|
186
|
+
letterSpacing: 0.6,
|
|
177
187
|
textTransform: 'uppercase' as const,
|
|
178
188
|
},
|
|
179
189
|
'button-lg': {
|
|
180
|
-
fontFamily: '
|
|
190
|
+
fontFamily: 'Sohne-Medium',
|
|
181
191
|
fontSize: 16,
|
|
182
192
|
fontWeight: '500' as const,
|
|
183
193
|
lineHeight: 22,
|
|
184
194
|
letterSpacing: 0,
|
|
185
195
|
},
|
|
186
196
|
'button-sm': {
|
|
187
|
-
fontFamily: '
|
|
197
|
+
fontFamily: 'Sohne-Medium',
|
|
188
198
|
fontSize: 14,
|
|
189
199
|
fontWeight: '500' as const,
|
|
190
200
|
lineHeight: 18,
|
package/src/utils/icons.ts
CHANGED
|
@@ -17,36 +17,63 @@ export interface IconProps {
|
|
|
17
17
|
family?: IconFamily
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
type
|
|
20
|
+
type IconComponentType = React.ComponentType<{ name: string; size: number; color: string }>
|
|
21
|
+
type IconFamilyEntry = {
|
|
21
22
|
name: IconFamily
|
|
22
|
-
component:
|
|
23
|
-
glyphMap
|
|
23
|
+
component: IconComponentType
|
|
24
|
+
/** Deferred — glyphMap is only read when the resolution cache is first built. */
|
|
25
|
+
getGlyphMap: () => Record<string, number>
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
{ name: '
|
|
28
|
+
type WithGlyphMap = { glyphMap?: Record<string, number> }
|
|
29
|
+
|
|
30
|
+
const glyphMapOf = (mod: unknown): Record<string, number> =>
|
|
31
|
+
(mod as WithGlyphMap).glyphMap ?? {}
|
|
32
|
+
|
|
33
|
+
// Priority order: highest-priority family LAST so it overwrites lower-priority entries in the cache.
|
|
34
|
+
const ALL_FAMILIES: IconFamilyEntry[] = [
|
|
35
|
+
{ name: 'Ionicons', component: Ionicons as unknown as IconComponentType, getGlyphMap: () => glyphMapOf(Ionicons) },
|
|
36
|
+
{ name: 'MaterialIcons', component: MaterialIcons as unknown as IconComponentType, getGlyphMap: () => glyphMapOf(MaterialIcons) },
|
|
37
|
+
{ name: 'FontAwesome5', component: FontAwesome5 as unknown as IconComponentType, getGlyphMap: () => glyphMapOf(FontAwesome5) },
|
|
38
|
+
{ name: 'Entypo', component: Entypo as unknown as IconComponentType, getGlyphMap: () => glyphMapOf(Entypo) },
|
|
39
|
+
{ name: 'AntDesign', component: AntDesign as unknown as IconComponentType, getGlyphMap: () => glyphMapOf(AntDesign) },
|
|
40
|
+
{ name: 'Feather', component: Feather as unknown as IconComponentType, getGlyphMap: () => glyphMapOf(Feather) },
|
|
34
41
|
]
|
|
35
42
|
|
|
36
|
-
|
|
43
|
+
// Active families participating in name resolution. Defaults to all six.
|
|
44
|
+
let activeFamilies: IconFamilyEntry[] = ALL_FAMILIES
|
|
45
|
+
let resolvedCache: Map<string, IconFamilyEntry> | null = null
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Restrict which icon families participate in automatic name resolution.
|
|
49
|
+
* Narrowing to the families you actually use shrinks the resolution cache and
|
|
50
|
+
* speeds up the first `renderIcon` call (no scanning thousands of unused glyphs).
|
|
51
|
+
*
|
|
52
|
+
* Note: all six families are still statically imported by this module — Metro
|
|
53
|
+
* bundles them regardless. This controls *resolution scope*, not bundle size.
|
|
54
|
+
*
|
|
55
|
+
* @example configureIconFamilies(['Feather', 'MaterialIcons'])
|
|
56
|
+
*/
|
|
57
|
+
export function configureIconFamilies(families: IconFamily[]): void {
|
|
58
|
+
const order = families
|
|
59
|
+
.map((n) => ALL_FAMILIES.find((f) => f.name === n))
|
|
60
|
+
.filter((f): f is IconFamilyEntry => f !== undefined)
|
|
61
|
+
activeFamilies = order.length > 0 ? order : ALL_FAMILIES
|
|
62
|
+
resolvedCache = null // invalidate — rebuilt lazily on next resolve
|
|
63
|
+
}
|
|
37
64
|
|
|
38
|
-
function buildCache(): Map<string,
|
|
39
|
-
const cache = new Map<string,
|
|
40
|
-
for (const family of
|
|
41
|
-
|
|
42
|
-
for (const iconName of Object.keys(
|
|
65
|
+
function buildCache(): Map<string, IconFamilyEntry> {
|
|
66
|
+
const cache = new Map<string, IconFamilyEntry>()
|
|
67
|
+
for (const family of activeFamilies) {
|
|
68
|
+
const glyphMap = family.getGlyphMap()
|
|
69
|
+
for (const iconName of Object.keys(glyphMap)) {
|
|
43
70
|
cache.set(iconName, family)
|
|
44
71
|
}
|
|
45
72
|
}
|
|
46
73
|
return cache
|
|
47
74
|
}
|
|
48
75
|
|
|
49
|
-
function resolveFamily(name: string):
|
|
76
|
+
function resolveFamily(name: string): IconFamilyEntry | null {
|
|
50
77
|
if (!resolvedCache) {
|
|
51
78
|
resolvedCache = buildCache()
|
|
52
79
|
}
|
|
@@ -54,10 +81,10 @@ function resolveFamily(name: string): ResolvedFamily | null {
|
|
|
54
81
|
}
|
|
55
82
|
|
|
56
83
|
export function Icon({ name, size, color, family }: IconProps): React.ReactElement | null {
|
|
57
|
-
let resolved:
|
|
84
|
+
let resolved: IconFamilyEntry | null = null
|
|
58
85
|
|
|
59
86
|
if (family) {
|
|
60
|
-
resolved =
|
|
87
|
+
resolved = ALL_FAMILIES.find((f) => f.name === family) ?? null
|
|
61
88
|
} else {
|
|
62
89
|
resolved = resolveFamily(name)
|
|
63
90
|
}
|
|
@@ -48,11 +48,13 @@ export function usePressScale({
|
|
|
48
48
|
|
|
49
49
|
const onPressIn = useCallback(() => {
|
|
50
50
|
if (disabled) return
|
|
51
|
+
// eslint-disable-next-line react-hooks/immutability
|
|
51
52
|
scale.value = withSpring(pressScale, pressInSpring)
|
|
52
53
|
}, [disabled, pressScale, pressInSpring, scale])
|
|
53
54
|
|
|
54
55
|
const onPressOut = useCallback(() => {
|
|
55
56
|
if (disabled) return
|
|
57
|
+
// eslint-disable-next-line react-hooks/immutability
|
|
56
58
|
scale.value = withSpring(1, pressOutSpring)
|
|
57
59
|
}, [disabled, pressOutSpring, scale])
|
|
58
60
|
|
|
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
|