react-native-molecules 0.5.0-beta.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/Accordion/Accordion.tsx +89 -0
- package/components/Accordion/AccordionItem.tsx +94 -0
- package/components/Accordion/AccordionItemContent.tsx +17 -0
- package/components/Accordion/AccordionItemHeader.tsx +122 -0
- package/components/Accordion/index.tsx +36 -0
- package/components/Accordion/utils.ts +62 -0
- package/components/ActivityIndicator/ActivityIndicator.ios.tsx +1 -0
- package/components/ActivityIndicator/ActivityIndicator.tsx +200 -0
- package/components/ActivityIndicator/AnimatedSpinner.tsx +121 -0
- package/components/ActivityIndicator/index.tsx +17 -0
- package/components/Appbar/AppbarActions.tsx +13 -0
- package/components/Appbar/AppbarBase.tsx +60 -0
- package/components/Appbar/AppbarCenterAligned.tsx +13 -0
- package/components/Appbar/AppbarLarge.tsx +13 -0
- package/components/Appbar/AppbarLeft.tsx +26 -0
- package/components/Appbar/AppbarMedium.tsx +13 -0
- package/components/Appbar/AppbarRight.tsx +40 -0
- package/components/Appbar/AppbarSmall.tsx +13 -0
- package/components/Appbar/AppbarTitle.tsx +49 -0
- package/components/Appbar/index.tsx +46 -0
- package/components/Appbar/types.ts +19 -0
- package/components/Appbar/utils.ts +127 -0
- package/components/Avatar/Avatar.tsx +189 -0
- package/components/Avatar/index.tsx +11 -0
- package/components/Avatar/utils.ts +35 -0
- package/components/Backdrop/Backdrop.tsx +18 -0
- package/components/Backdrop/index.tsx +11 -0
- package/components/Backdrop/types.ts +3 -0
- package/components/Backdrop/utils.ts +21 -0
- package/components/Badge/Badge.tsx +29 -0
- package/components/Badge/index.tsx +11 -0
- package/components/Badge/utils.ts +38 -0
- package/components/Button/Button.tsx +349 -0
- package/components/Button/index.tsx +11 -0
- package/components/Button/types.ts +5 -0
- package/components/Button/utils.ts +416 -0
- package/components/Card/Card.tsx +160 -0
- package/components/Card/CardActions.tsx +18 -0
- package/components/Card/CardContent.tsx +29 -0
- package/components/Card/CardHeader.tsx +31 -0
- package/components/Card/CardHeadline.tsx +15 -0
- package/components/Card/CardMedia.tsx +36 -0
- package/components/Card/CardSubhead.tsx +15 -0
- package/components/Card/CardText.tsx +13 -0
- package/components/Card/CardTypography.tsx +113 -0
- package/components/Card/index.tsx +38 -0
- package/components/Card/types.ts +1 -0
- package/components/Card/utils.ts +23 -0
- package/components/Checkbox/Checkbox.tsx +123 -0
- package/components/Checkbox/CheckboxBase.ios.tsx +86 -0
- package/components/Checkbox/CheckboxBase.tsx +216 -0
- package/components/Checkbox/index.tsx +11 -0
- package/components/Checkbox/types.ts +72 -0
- package/components/Checkbox/utils.ts +210 -0
- package/components/Chip/Chip.tsx +416 -0
- package/components/Chip/index.tsx +51 -0
- package/components/Chip/utils.ts +100 -0
- package/components/DatePickerDocked/DatePickerDocked.tsx +30 -0
- package/components/DatePickerDocked/DatePickerDockedHeader.tsx +129 -0
- package/components/DatePickerDocked/index.tsx +21 -0
- package/components/DatePickerDocked/types.ts +11 -0
- package/components/DatePickerDocked/utils.ts +155 -0
- package/components/DatePickerInline/AutoSizer.tsx +46 -0
- package/components/DatePickerInline/DatePickerContext.tsx +21 -0
- package/components/DatePickerInline/DatePickerInline.tsx +82 -0
- package/components/DatePickerInline/DatePickerInlineBase.tsx +181 -0
- package/components/DatePickerInline/DatePickerInlineHeader.tsx +108 -0
- package/components/DatePickerInline/Day.tsx +88 -0
- package/components/DatePickerInline/DayName.tsx +17 -0
- package/components/DatePickerInline/DayNames.tsx +32 -0
- package/components/DatePickerInline/DayRange.tsx +48 -0
- package/components/DatePickerInline/HeaderItem.tsx +111 -0
- package/components/DatePickerInline/Month.tsx +233 -0
- package/components/DatePickerInline/MonthPicker.tsx +174 -0
- package/components/DatePickerInline/Swiper.native.tsx +172 -0
- package/components/DatePickerInline/Swiper.tsx +172 -0
- package/components/DatePickerInline/SwiperUtils.ts +40 -0
- package/components/DatePickerInline/Week.tsx +67 -0
- package/components/DatePickerInline/YearPicker.tsx +139 -0
- package/components/DatePickerInline/dateUtils.tsx +334 -0
- package/components/DatePickerInline/index.tsx +41 -0
- package/components/DatePickerInline/types.ts +104 -0
- package/components/DatePickerInline/utils.ts +367 -0
- package/components/DatePickerInput/DatePickerInput.tsx +139 -0
- package/components/DatePickerInput/DatePickerInputModal.tsx +48 -0
- package/components/DatePickerInput/DatePickerInputWithoutModal.tsx +77 -0
- package/components/DatePickerInput/DateRangeInput.tsx +88 -0
- package/components/DatePickerInput/index.tsx +14 -0
- package/components/DatePickerInput/inputUtils.ts +138 -0
- package/components/DatePickerInput/types.ts +28 -0
- package/components/DatePickerInput/utils.ts +16 -0
- package/components/DatePickerModal/AnimatedCrossView.tsx +94 -0
- package/components/DatePickerModal/CalendarEdit.tsx +139 -0
- package/components/DatePickerModal/DatePickerModal.tsx +85 -0
- package/components/DatePickerModal/DatePickerModalContent.tsx +155 -0
- package/components/DatePickerModal/DatePickerModalContentHeader.tsx +213 -0
- package/components/DatePickerModal/DatePickerModalHeader.tsx +74 -0
- package/components/DatePickerModal/DatePickerModalHeaderBackground.tsx +13 -0
- package/components/DatePickerModal/index.tsx +20 -0
- package/components/DatePickerModal/types.ts +92 -0
- package/components/DatePickerModal/utils.ts +121 -0
- package/components/DateTimePicker/DateTimePicker.tsx +172 -0
- package/components/DateTimePicker/index.tsx +14 -0
- package/components/DateTimePicker/utils.ts +13 -0
- package/components/Dialog/Dialog.tsx +66 -0
- package/components/Dialog/DialogActions.tsx +89 -0
- package/components/Dialog/DialogContent.tsx +37 -0
- package/components/Dialog/DialogIcon.tsx +69 -0
- package/components/Dialog/DialogTitle.tsx +68 -0
- package/components/Dialog/index.tsx +37 -0
- package/components/Dialog/utils.ts +80 -0
- package/components/Drawer/Collapsible/DrawerCollapsible.tsx +22 -0
- package/components/Drawer/Collapsible/DrawerCollapsibleItem.tsx +38 -0
- package/components/Drawer/Collapsible/DrawerCollapsibleItemContent.tsx +16 -0
- package/components/Drawer/Collapsible/DrawerCollapsibleItemHeader.tsx +48 -0
- package/components/Drawer/Collapsible/index.tsx +23 -0
- package/components/Drawer/Collapsible/utils.ts +49 -0
- package/components/Drawer/Drawer.tsx +43 -0
- package/components/Drawer/DrawerContent.tsx +35 -0
- package/components/Drawer/DrawerFooter.tsx +27 -0
- package/components/Drawer/DrawerHeader.tsx +27 -0
- package/components/Drawer/DrawerItem.tsx +206 -0
- package/components/Drawer/DrawerItemGroup.tsx +82 -0
- package/components/Drawer/index.tsx +47 -0
- package/components/Drawer/types.ts +3 -0
- package/components/Drawer/utils.ts +8 -0
- package/components/ElementGroup/ElementGroup.tsx +139 -0
- package/components/ElementGroup/index.tsx +11 -0
- package/components/ElementGroup/utils.ts +25 -0
- package/components/FAB/FAB.tsx +176 -0
- package/components/FAB/index.tsx +12 -0
- package/components/FAB/types.ts +1 -0
- package/components/FAB/utils.ts +221 -0
- package/components/FilePicker/FilePicker.tsx +133 -0
- package/components/FilePicker/index.tsx +11 -0
- package/components/FilePicker/utils.ts +13 -0
- package/components/HelperText/HelperText.tsx +139 -0
- package/components/HelperText/index.tsx +11 -0
- package/components/HelperText/utils.ts +29 -0
- package/components/HorizontalDivider/HorizontalDivider.tsx +101 -0
- package/components/HorizontalDivider/index.tsx +13 -0
- package/components/Icon/CrossFadeIcon.tsx +116 -0
- package/components/Icon/Icon.tsx +41 -0
- package/components/Icon/iconFactory.tsx +23 -0
- package/components/Icon/index.tsx +11 -0
- package/components/Icon/types.ts +35 -0
- package/components/IconButton/IconButton.tsx +218 -0
- package/components/IconButton/index.tsx +11 -0
- package/components/IconButton/types.ts +1 -0
- package/components/IconButton/utils.ts +325 -0
- package/components/If/index.tsx +13 -0
- package/components/InputAddon/InputAddon.tsx +27 -0
- package/components/InputAddon/index.tsx +11 -0
- package/components/InputAddon/utils.ts +33 -0
- package/components/Link/Link.tsx +48 -0
- package/components/Link/index.tsx +11 -0
- package/components/Link/utils.ts +37 -0
- package/components/ListItem/ListItem.tsx +136 -0
- package/components/ListItem/ListItemDescription.tsx +25 -0
- package/components/ListItem/ListItemTitle.tsx +25 -0
- package/components/ListItem/index.tsx +18 -0
- package/components/ListItem/utils.ts +113 -0
- package/components/Menu/Menu.tsx +69 -0
- package/components/Menu/MenuDivider.tsx +13 -0
- package/components/Menu/MenuItem.tsx +128 -0
- package/components/Menu/index.tsx +19 -0
- package/components/Menu/utils.ts +92 -0
- package/components/Modal/Modal.tsx +261 -0
- package/components/Modal/index.tsx +11 -0
- package/components/Modal/utils.ts +45 -0
- package/components/NavigationRail/NavigationRail.tsx +32 -0
- package/components/NavigationRail/NavigationRailContent.tsx +25 -0
- package/components/NavigationRail/NavigationRailFooter.tsx +18 -0
- package/components/NavigationRail/NavigationRailHeader.tsx +18 -0
- package/components/NavigationRail/NavigationRailItem.tsx +226 -0
- package/components/NavigationRail/index.tsx +35 -0
- package/components/NavigationRail/utils.ts +170 -0
- package/components/NavigationStack/NavigationStack.tsx +85 -0
- package/components/NavigationStack/NavigationStackItem.tsx +60 -0
- package/components/NavigationStack/index.tsx +20 -0
- package/components/NavigationStack/utils.tsx +16 -0
- package/components/Popover/Popover.native.tsx +185 -0
- package/components/Popover/Popover.tsx +198 -0
- package/components/Popover/common.ts +459 -0
- package/components/Popover/index.ts +2 -0
- package/components/Portal/Portal.tsx +13 -0
- package/components/Portal/index.tsx +12 -0
- package/components/RadioButton/RadioButton.tsx +138 -0
- package/components/RadioButton/RadioButtonAndroid.tsx +188 -0
- package/components/RadioButton/RadioButtonGroup.tsx +98 -0
- package/components/RadioButton/RadioButtonIOS.tsx +106 -0
- package/components/RadioButton/RadioButtonItem.tsx +232 -0
- package/components/RadioButton/index.ts +27 -0
- package/components/RadioButton/utils.ts +164 -0
- package/components/Rating/Rating.tsx +149 -0
- package/components/Rating/RatingItem.tsx +125 -0
- package/components/Rating/index.tsx +13 -0
- package/components/Rating/utils.ts +38 -0
- package/components/Select/Select.tsx +1038 -0
- package/components/Select/index.ts +14 -0
- package/components/Select/types.ts +115 -0
- package/components/StateLayer/StateLayer.tsx +12 -0
- package/components/StateLayer/index.tsx +11 -0
- package/components/StateLayer/utils.ts +17 -0
- package/components/Surface/BackgroundContextWrapper.tsx +27 -0
- package/components/Surface/Surface.android.tsx +62 -0
- package/components/Surface/Surface.ios.tsx +123 -0
- package/components/Surface/Surface.tsx +48 -0
- package/components/Surface/index.tsx +12 -0
- package/components/Surface/utils.ts +106 -0
- package/components/Switch/Switch.ios.tsx +67 -0
- package/components/Switch/Switch.tsx +278 -0
- package/components/Switch/index.tsx +11 -0
- package/components/Switch/utils.ts +283 -0
- package/components/Tabs/TabItem.tsx +150 -0
- package/components/Tabs/TabLabel.tsx +84 -0
- package/components/Tabs/Tabs.tsx +398 -0
- package/components/Tabs/index.tsx +21 -0
- package/components/Tabs/utils.ts +126 -0
- package/components/Text/Text.tsx +23 -0
- package/components/Text/index.tsx +2 -0
- package/components/Text/textFactory.tsx +33 -0
- package/components/TextInput/InputLabel.tsx +181 -0
- package/components/TextInput/TextInput.tsx +693 -0
- package/components/TextInput/index.tsx +16 -0
- package/components/TextInput/types.ts +96 -0
- package/components/TextInput/utils.ts +544 -0
- package/components/TextInputWithMask/TextInputMask.tsx +57 -0
- package/components/TextInputWithMask/index.tsx +11 -0
- package/components/TextInputWithMask/utils.ts +56 -0
- package/components/TimePicker/AmPmSwitcher.tsx +99 -0
- package/components/TimePicker/AnalogClock.tsx +165 -0
- package/components/TimePicker/AnalogClockHours.tsx +163 -0
- package/components/TimePicker/AnalogClockMinutes.tsx +68 -0
- package/components/TimePicker/AnimatedClockSwitcher.tsx +72 -0
- package/components/TimePicker/DisplayModeContext.tsx +6 -0
- package/components/TimePicker/TimeInput.tsx +112 -0
- package/components/TimePicker/TimeInputs.tsx +148 -0
- package/components/TimePicker/TimePicker.tsx +130 -0
- package/components/TimePicker/index.tsx +19 -0
- package/components/TimePicker/timeUtils.ts +159 -0
- package/components/TimePicker/utils.ts +285 -0
- package/components/TimePickerField/TimePickerField.tsx +152 -0
- package/components/TimePickerField/index.tsx +14 -0
- package/components/TimePickerField/sanitizeTime.ts +85 -0
- package/components/TimePickerField/utils.ts +95 -0
- package/components/TimePickerModal/TimePickerModal.tsx +115 -0
- package/components/TimePickerModal/index.tsx +14 -0
- package/components/TimePickerModal/utils.ts +48 -0
- package/components/Tooltip/Tooltip.tsx +137 -0
- package/components/Tooltip/TooltipContent.tsx +12 -0
- package/components/Tooltip/TooltipTrigger.tsx +94 -0
- package/components/Tooltip/index.tsx +20 -0
- package/components/Tooltip/utils.ts +21 -0
- package/components/TouchableRipple/TouchableRipple.native.tsx +105 -0
- package/components/TouchableRipple/TouchableRipple.tsx +286 -0
- package/components/TouchableRipple/index.tsx +14 -0
- package/components/TouchableRipple/utils.ts +15 -0
- package/components/VerticalDivider/VerticalDivider.tsx +99 -0
- package/components/VerticalDivider/index.tsx +13 -0
- package/context-bridge/index.tsx +87 -0
- package/core/componentsRegistry.ts +164 -0
- package/core/index.tsx +2 -0
- package/fast-context/index.tsx +190 -0
- package/hocs/index.tsx +5 -0
- package/hocs/typedMemo.tsx +5 -0
- package/hocs/withKeyboardAccessibility.tsx +231 -0
- package/hocs/withPortal.tsx +16 -0
- package/hooks/createPsuedoHook.tsx +50 -0
- package/hooks/index.tsx +29 -0
- package/hooks/useActionState.native.tsx +22 -0
- package/hooks/useActionState.tsx +34 -0
- package/hooks/useActive.tsx +5 -0
- package/hooks/useBreakpoints.tsx +7 -0
- package/hooks/useColorMode.tsx +17 -0
- package/hooks/useContrastColor.ts +15 -0
- package/hooks/useControlledValue.tsx +68 -0
- package/hooks/useFilePicker.tsx +48 -0
- package/hooks/useFocus.tsx +5 -0
- package/hooks/useHandleNumberFormat.tsx +106 -0
- package/hooks/useHover.tsx +5 -0
- package/hooks/useKeyboardDismissable.ts +66 -0
- package/hooks/useLatest.tsx +9 -0
- package/hooks/useMediaQuery.tsx +64 -0
- package/hooks/useMergedRefs.ts +14 -0
- package/hooks/usePrevious.ts +13 -0
- package/hooks/useQueryFilter.tsx +35 -0
- package/hooks/useSearchable.tsx +74 -0
- package/hooks/useSubcomponents.tsx +59 -0
- package/hooks/useTheme.ts +3 -0
- package/hooks/useToggle.tsx +24 -0
- package/package.json +114 -0
- package/shortcuts-manager/EventsManager.tsx +121 -0
- package/shortcuts-manager/ShortcutsManager/ShortcutsManager.native.tsx +9 -0
- package/shortcuts-manager/ShortcutsManager/ShortcutsManager.tsx +58 -0
- package/shortcuts-manager/ShortcutsManager/index.tsx +2 -0
- package/shortcuts-manager/ShortcutsManager/utils.tsx +30 -0
- package/shortcuts-manager/index.tsx +6 -0
- package/shortcuts-manager/types.ts +24 -0
- package/shortcuts-manager/useIsKeyPressed/index.tsx +1 -0
- package/shortcuts-manager/useIsKeyPressed/useIsKeyPress.tsx +9 -0
- package/shortcuts-manager/useSetScopes/index.tsx +1 -0
- package/shortcuts-manager/useSetScopes/useSetScopes.native.tsx +9 -0
- package/shortcuts-manager/useSetScopes/useSetScopes.tsx +25 -0
- package/shortcuts-manager/useShortcut/index.tsx +2 -0
- package/shortcuts-manager/useShortcut/types.ts +3 -0
- package/shortcuts-manager/useShortcut/useShortcut.native.tsx +9 -0
- package/shortcuts-manager/useShortcut/useShortcut.tsx +61 -0
- package/shortcuts-manager/utils.ts +105 -0
- package/styles/index.ts +4 -0
- package/styles/overlay.ts +69 -0
- package/styles/shadow.ts +21 -0
- package/styles/themes/DarkTheme.tsx +98 -0
- package/styles/themes/LightTheme.tsx +212 -0
- package/styles/themes/tokens.ts +248 -0
- package/styles/utils.ts +11 -0
- package/types/index.ts +129 -0
- package/types/theme.ts +159 -0
- package/utils/DocumentPicker/documentPicker.native.ts +10 -0
- package/utils/DocumentPicker/documentPicker.ts +76 -0
- package/utils/DocumentPicker/index.ts +2 -0
- package/utils/DocumentPicker/types.ts +28 -0
- package/utils/addEventListener.tsx +51 -0
- package/utils/backgroundContext.ts +9 -0
- package/utils/color.ts +22 -0
- package/utils/compare/index.ts +54 -0
- package/utils/composeEventHandlers.ts +9 -0
- package/utils/createNumberMask/createNumberMask.ts +98 -0
- package/utils/createNumberMask/index.ts +5 -0
- package/utils/createSyntheticEvent.ts +31 -0
- package/utils/date-fns.ts +7 -0
- package/utils/dateTimePicker.ts +5 -0
- package/utils/escapeRegex.ts +9 -0
- package/utils/extractTextStyles.ts +52 -0
- package/utils/formatNumberWithMask/formatNumberWithMask.ts +26 -0
- package/utils/formatNumberWithMask/formatWithMask.ts +119 -0
- package/utils/formatNumberWithMask/index.ts +6 -0
- package/utils/getCursorStyle/getCursorStyle.native.ts +1 -0
- package/utils/getCursorStyle/getCursorStyle.ts +1 -0
- package/utils/getCursorStyle/index.ts +1 -0
- package/utils/getOS/getOS.native.ts +7 -0
- package/utils/getOS/getOS.ts +24 -0
- package/utils/getOS/index.ts +1 -0
- package/utils/getyearRange.ts +5 -0
- package/utils/index.ts +20 -0
- package/utils/lodash.ts +50 -0
- package/utils/mergeRefs.ts +13 -0
- package/utils/normalizeBorderRadiuses.ts +24 -0
- package/utils/normalizeSpacings.ts +110 -0
- package/utils/normalizeToNumberString/index.ts +4 -0
- package/utils/normalizeToNumberString/normalizeToNumberString.ts +48 -0
- package/utils/repository.ts +103 -0
- package/utils/resolveColorMode.ts +9 -0
- package/utils/resolveStateVariant.ts +26 -0
- package/utils/tokenStylesParser.ts +7 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type Context,
|
|
3
|
+
createContext,
|
|
4
|
+
type ReactNode,
|
|
5
|
+
type RefObject,
|
|
6
|
+
useCallback,
|
|
7
|
+
useContext,
|
|
8
|
+
useEffect,
|
|
9
|
+
useMemo,
|
|
10
|
+
useRef,
|
|
11
|
+
} from 'react';
|
|
12
|
+
import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector';
|
|
13
|
+
|
|
14
|
+
import typedMemo from '../hocs/typedMemo';
|
|
15
|
+
import { usePrevious } from '../hooks';
|
|
16
|
+
import { shallowCompare } from '../utils';
|
|
17
|
+
|
|
18
|
+
type StoreDataType = Record<string, any>;
|
|
19
|
+
|
|
20
|
+
type SelectorOutputType<IStore, SelectorOutput> = (store: IStore) => SelectorOutput;
|
|
21
|
+
|
|
22
|
+
type UseStoreDataReturnType<T> = {
|
|
23
|
+
get: () => T;
|
|
24
|
+
set: (value: (prev: T) => Partial<T>) => void;
|
|
25
|
+
store: RefObject<T>;
|
|
26
|
+
subscribe: (callback: () => void) => () => void;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const useStoreData = <IStore extends StoreDataType>(
|
|
30
|
+
value: IStore,
|
|
31
|
+
defaultValue: IStore | null,
|
|
32
|
+
watch: boolean = false,
|
|
33
|
+
): UseStoreDataReturnType<IStore> => {
|
|
34
|
+
const store = useRef<IStore>({ ...defaultValue, ...(value as IStore) });
|
|
35
|
+
const watchRef = useRef(watch);
|
|
36
|
+
|
|
37
|
+
const get = useCallback(() => store.current, [store]);
|
|
38
|
+
|
|
39
|
+
const subscribers = useRef(new Set<() => void>());
|
|
40
|
+
|
|
41
|
+
const set = useCallback(
|
|
42
|
+
(callback: (prev: IStore) => Partial<IStore>) => {
|
|
43
|
+
store.current = { ...store.current, ...callback(store.current) };
|
|
44
|
+
subscribers.current.forEach(subscriber => subscriber());
|
|
45
|
+
},
|
|
46
|
+
[store],
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const subscribe = useCallback((callback: () => void) => {
|
|
50
|
+
subscribers.current.add(callback);
|
|
51
|
+
|
|
52
|
+
return () => subscribers.current.delete(callback);
|
|
53
|
+
}, []);
|
|
54
|
+
|
|
55
|
+
/** The effect is required to trigger the updates on the consumers */
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
if (!watchRef.current) return;
|
|
58
|
+
set(prev => ({ ...prev, ...value }));
|
|
59
|
+
}, [set, value]);
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Cases:
|
|
63
|
+
* 1. when the value updates, we want the data to be updated immediately
|
|
64
|
+
* 2. the data stored in store.current may not be current with regards to the parent and the parent must have dropped the references related to the data.
|
|
65
|
+
* 3. because store.current is a ref, on watch and change, if we update store.current, no side-effect introduced.
|
|
66
|
+
*/
|
|
67
|
+
if (usePrevious(value).current !== value && watchRef.current) {
|
|
68
|
+
store.current = { ...store.current, ...value };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return useMemo(
|
|
72
|
+
() => ({
|
|
73
|
+
get,
|
|
74
|
+
set,
|
|
75
|
+
subscribe,
|
|
76
|
+
store,
|
|
77
|
+
}),
|
|
78
|
+
[get, set, subscribe],
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export const createFastContext = <T extends StoreDataType = {}>(
|
|
83
|
+
defaultValue: T | null = null,
|
|
84
|
+
watch: boolean = false,
|
|
85
|
+
) => {
|
|
86
|
+
const context = createContext<UseStoreDataReturnType<T> | null>(null);
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
/**
|
|
90
|
+
* using the value from here will never cause a rerender as context is based on refs.
|
|
91
|
+
*/
|
|
92
|
+
useStoreRef: createUseRefContext(context),
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
*
|
|
96
|
+
* the value is memoized and thus changing the value will have no effect.
|
|
97
|
+
* use key prop to unmount and remount if necessary. alternatively use set from the context to update the value.
|
|
98
|
+
*
|
|
99
|
+
*/
|
|
100
|
+
Provider: createProvider<T>(
|
|
101
|
+
context as Context<UseStoreDataReturnType<T>>,
|
|
102
|
+
defaultValue,
|
|
103
|
+
watch,
|
|
104
|
+
),
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
*
|
|
108
|
+
* @param selector
|
|
109
|
+
* @param equalityCheck
|
|
110
|
+
* @returns tuple, first item is return value of the selector and the second item is setter
|
|
111
|
+
*
|
|
112
|
+
*/
|
|
113
|
+
useContext: <SelectorOutput,>(
|
|
114
|
+
selector: SelectorOutputType<T, SelectorOutput>,
|
|
115
|
+
equalityCheck = shallowCompare,
|
|
116
|
+
) => useStore(context as Context<UseStoreDataReturnType<T>>, selector, equalityCheck),
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
*
|
|
120
|
+
* @param selector
|
|
121
|
+
* @param equalityCheck
|
|
122
|
+
* @returns return value of the selector
|
|
123
|
+
*
|
|
124
|
+
*/
|
|
125
|
+
useContextValue: <SelectorOutput,>(
|
|
126
|
+
selector: SelectorOutputType<T, SelectorOutput>,
|
|
127
|
+
equalityCheck = shallowCompare,
|
|
128
|
+
) => useStoreValue(context as Context<UseStoreDataReturnType<T>>, selector, equalityCheck),
|
|
129
|
+
/**
|
|
130
|
+
* context of the store. Useful for ContextBridge
|
|
131
|
+
*/
|
|
132
|
+
Context: context,
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export const createProvider = <T extends Record<string, any> = {}>(
|
|
137
|
+
StoreContext: Context<UseStoreDataReturnType<T>>,
|
|
138
|
+
defaultValue: T | null,
|
|
139
|
+
watch: boolean,
|
|
140
|
+
) =>
|
|
141
|
+
typedMemo(({ value, children }: { value: T; children: ReactNode }) => {
|
|
142
|
+
return (
|
|
143
|
+
<StoreContext.Provider value={useStoreData<T>(value, defaultValue, watch) as any}>
|
|
144
|
+
{children}
|
|
145
|
+
</StoreContext.Provider>
|
|
146
|
+
);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
export const createUseRefContext = <T,>(_Context: Context<UseStoreDataReturnType<T> | null>) => {
|
|
150
|
+
return () => {
|
|
151
|
+
const value = useContext<UseStoreDataReturnType<T> | null>(_Context);
|
|
152
|
+
if (value === null)
|
|
153
|
+
throw 'Fast Context requires the value to be wrapped in a Provider with a value.';
|
|
154
|
+
|
|
155
|
+
return value;
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export const useStore = <IStore extends StoreDataType, SelectorOutput>(
|
|
160
|
+
_Context: Context<UseStoreDataReturnType<IStore>>,
|
|
161
|
+
selector: SelectorOutputType<IStore, SelectorOutput>,
|
|
162
|
+
equalityFn = Object.is,
|
|
163
|
+
): [SelectorOutput, (value: (prev: IStore) => Partial<IStore>) => void] => {
|
|
164
|
+
const store = useContext(_Context);
|
|
165
|
+
if (!store) {
|
|
166
|
+
throw new Error('Store not found');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const state = useSyncExternalStoreWithSelector(
|
|
170
|
+
store.subscribe,
|
|
171
|
+
() => {
|
|
172
|
+
return store.get();
|
|
173
|
+
},
|
|
174
|
+
undefined,
|
|
175
|
+
snapshot => {
|
|
176
|
+
return selector(snapshot);
|
|
177
|
+
},
|
|
178
|
+
equalityFn,
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
return [state, store.set];
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
export const useStoreValue = <IStore extends StoreDataType, SelectorOutput>(
|
|
185
|
+
_Context: Context<UseStoreDataReturnType<IStore>>,
|
|
186
|
+
selector: SelectorOutputType<IStore, SelectorOutput>,
|
|
187
|
+
equalityFn = Object.is,
|
|
188
|
+
) => {
|
|
189
|
+
return useStore(_Context, selector, equalityFn)[0];
|
|
190
|
+
};
|
package/hocs/index.tsx
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type ComponentType,
|
|
3
|
+
forwardRef,
|
|
4
|
+
Fragment,
|
|
5
|
+
memo,
|
|
6
|
+
type ReactNode,
|
|
7
|
+
type RefObject,
|
|
8
|
+
useCallback,
|
|
9
|
+
useEffect,
|
|
10
|
+
useImperativeHandle,
|
|
11
|
+
useMemo,
|
|
12
|
+
useRef,
|
|
13
|
+
} from 'react';
|
|
14
|
+
import type { FlatList } from 'react-native';
|
|
15
|
+
import type { SectionList } from 'react-native';
|
|
16
|
+
import { Platform } from 'react-native';
|
|
17
|
+
|
|
18
|
+
import { createFastContext } from '../fast-context';
|
|
19
|
+
import useLatest from '../hooks/useLatest';
|
|
20
|
+
|
|
21
|
+
export type Store = {
|
|
22
|
+
currentIndex: number | null;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const defaultValue = { currentIndex: null };
|
|
26
|
+
|
|
27
|
+
const {
|
|
28
|
+
useStoreRef,
|
|
29
|
+
Provider,
|
|
30
|
+
useContext: useFastContext,
|
|
31
|
+
useContextValue,
|
|
32
|
+
} = createFastContext<Store>();
|
|
33
|
+
|
|
34
|
+
const withKeyboardAccessibility = <P extends Record<string, any>>(
|
|
35
|
+
Component: ComponentType<P>,
|
|
36
|
+
key: string = 'records',
|
|
37
|
+
isFlat: boolean = false,
|
|
38
|
+
) =>
|
|
39
|
+
// @ts-expect-error // TODO - fix ts issues
|
|
40
|
+
forwardRef(({ enableKeyboardNavigation, onCancel, ...props }: P, ref: any) => {
|
|
41
|
+
const componentRef = useRef<FlatList | SectionList>(null);
|
|
42
|
+
const records = props[key] as any[];
|
|
43
|
+
|
|
44
|
+
const recordsIndexMap = useMemo(() => {
|
|
45
|
+
if (!records) return {};
|
|
46
|
+
|
|
47
|
+
const flattenRecords = isFlat
|
|
48
|
+
? records
|
|
49
|
+
: records.reduce((acc, item, sectionIndex) => {
|
|
50
|
+
return acc.concat(
|
|
51
|
+
(item.data || []).map((t: any) => ({ ...t, sectionIndex })),
|
|
52
|
+
);
|
|
53
|
+
}, [] as any[]);
|
|
54
|
+
|
|
55
|
+
return flattenRecords.reduce((acc: Record<number, any>, item: any, i: number) => {
|
|
56
|
+
acc[i] = item;
|
|
57
|
+
|
|
58
|
+
return acc;
|
|
59
|
+
}, {} as Record<number, any>);
|
|
60
|
+
}, [records]);
|
|
61
|
+
|
|
62
|
+
const length = useMemo(() => {
|
|
63
|
+
if (!isFlat) {
|
|
64
|
+
return records.reduce((acc, item) => {
|
|
65
|
+
acc += item.data.length;
|
|
66
|
+
return acc;
|
|
67
|
+
}, 0);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return records.length;
|
|
71
|
+
}, [records]);
|
|
72
|
+
|
|
73
|
+
const onSelectItem = useCallback(
|
|
74
|
+
(index: number) => {
|
|
75
|
+
const selectItem = recordsIndexMap[index];
|
|
76
|
+
|
|
77
|
+
if (!selectItem) return props.onSelectionChange?.(props.selection);
|
|
78
|
+
|
|
79
|
+
props.onSelectionChange?.(
|
|
80
|
+
props.multiple ? [...props.selection, selectItem] : selectItem,
|
|
81
|
+
);
|
|
82
|
+
},
|
|
83
|
+
[props, recordsIndexMap],
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
useImperativeHandle(ref, () => componentRef.current);
|
|
87
|
+
|
|
88
|
+
const Wrapper =
|
|
89
|
+
enableKeyboardNavigation && Platform.OS === 'web' ? AccessibilityWrapper : Fragment;
|
|
90
|
+
|
|
91
|
+
const accessibilityWrapperProps =
|
|
92
|
+
enableKeyboardNavigation && Platform.OS === 'web'
|
|
93
|
+
? {
|
|
94
|
+
listRef: componentRef as any,
|
|
95
|
+
listLength: length,
|
|
96
|
+
onSelectItem: onSelectItem,
|
|
97
|
+
isFlat,
|
|
98
|
+
onCancel,
|
|
99
|
+
}
|
|
100
|
+
: {};
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<Provider value={defaultValue}>
|
|
104
|
+
<Wrapper
|
|
105
|
+
{...(accessibilityWrapperProps as Omit<AccessibilityWrapperProps, 'children'>)}>
|
|
106
|
+
<Component {...(props as P)} ref={componentRef} />
|
|
107
|
+
</Wrapper>
|
|
108
|
+
</Provider>
|
|
109
|
+
);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
type AccessibilityWrapperProps = {
|
|
113
|
+
children: ReactNode;
|
|
114
|
+
listRef: RefObject<FlatList> | RefObject<SectionList>;
|
|
115
|
+
listLength: number;
|
|
116
|
+
onSelectItem: (index: number) => void;
|
|
117
|
+
isFlat: boolean;
|
|
118
|
+
onCancel?: () => void;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const withPreventDefault =
|
|
122
|
+
(func: (e: KeyboardEvent) => void, preventDefault = true) =>
|
|
123
|
+
(e: KeyboardEvent) => {
|
|
124
|
+
if (preventDefault) e.preventDefault();
|
|
125
|
+
func(e);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const AccessibilityWrapper = memo(
|
|
129
|
+
({
|
|
130
|
+
children,
|
|
131
|
+
listRef,
|
|
132
|
+
listLength,
|
|
133
|
+
onSelectItem,
|
|
134
|
+
isFlat,
|
|
135
|
+
onCancel,
|
|
136
|
+
}: AccessibilityWrapperProps) => {
|
|
137
|
+
const [currentIndex, setStore] = useFastContext(state => state.currentIndex);
|
|
138
|
+
|
|
139
|
+
// use the ref here to avoid recreation of the keyToFunctionMap function
|
|
140
|
+
const { store: currentIndexRef } = useStoreRef();
|
|
141
|
+
|
|
142
|
+
const keyToFunctionMap = useMemo(
|
|
143
|
+
() => ({
|
|
144
|
+
ArrowUp: withPreventDefault(() =>
|
|
145
|
+
setStore(prev => ({
|
|
146
|
+
currentIndex:
|
|
147
|
+
prev.currentIndex === null || prev.currentIndex === 0
|
|
148
|
+
? listLength - 1
|
|
149
|
+
: prev.currentIndex - 1,
|
|
150
|
+
})),
|
|
151
|
+
),
|
|
152
|
+
ArrowDown: withPreventDefault(() =>
|
|
153
|
+
setStore(prev => ({
|
|
154
|
+
currentIndex:
|
|
155
|
+
prev.currentIndex === null || prev.currentIndex === listLength - 1
|
|
156
|
+
? 0
|
|
157
|
+
: prev.currentIndex + 1,
|
|
158
|
+
})),
|
|
159
|
+
),
|
|
160
|
+
Enter: withPreventDefault(e => {
|
|
161
|
+
if (currentIndexRef.current.currentIndex === null) return;
|
|
162
|
+
e.preventDefault();
|
|
163
|
+
onSelectItem(currentIndexRef.current.currentIndex);
|
|
164
|
+
}, false),
|
|
165
|
+
Escape: withPreventDefault(e => {
|
|
166
|
+
if (currentIndexRef.current.currentIndex === null) onCancel?.();
|
|
167
|
+
e.preventDefault();
|
|
168
|
+
setStore(() => ({
|
|
169
|
+
currentIndex: null,
|
|
170
|
+
}));
|
|
171
|
+
}, false),
|
|
172
|
+
}),
|
|
173
|
+
[currentIndexRef, listLength, onCancel, onSelectItem, setStore],
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
const onKeyPress = useCallback(
|
|
177
|
+
(e: KeyboardEvent) => {
|
|
178
|
+
const keyFunction = keyToFunctionMap[e.key as keyof typeof keyToFunctionMap];
|
|
179
|
+
|
|
180
|
+
if (!keyFunction) return;
|
|
181
|
+
|
|
182
|
+
keyFunction(e);
|
|
183
|
+
},
|
|
184
|
+
[keyToFunctionMap],
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
const listLengthLatest = useLatest(listLength);
|
|
188
|
+
useEffect(() => {
|
|
189
|
+
if (listRef && !!listRef.current) {
|
|
190
|
+
if (
|
|
191
|
+
currentIndex === null ||
|
|
192
|
+
currentIndex < 0 ||
|
|
193
|
+
currentIndex > listLengthLatest.current - 1
|
|
194
|
+
)
|
|
195
|
+
return;
|
|
196
|
+
|
|
197
|
+
if (isFlat) {
|
|
198
|
+
(listRef as RefObject<FlatList>).current?.scrollToIndex?.({
|
|
199
|
+
index: currentIndex || 0,
|
|
200
|
+
animated: false,
|
|
201
|
+
});
|
|
202
|
+
} else {
|
|
203
|
+
(listRef as RefObject<SectionList>).current?.scrollToLocation({
|
|
204
|
+
animated: false,
|
|
205
|
+
sectionIndex: 0,
|
|
206
|
+
itemIndex: currentIndex,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}, [currentIndex, isFlat, listRef, listLengthLatest]);
|
|
211
|
+
|
|
212
|
+
useEffect(() => {
|
|
213
|
+
const controller = new AbortController();
|
|
214
|
+
window.addEventListener('keydown', onKeyPress, {
|
|
215
|
+
capture: true,
|
|
216
|
+
signal: controller.signal,
|
|
217
|
+
} as AddEventListenerOptions);
|
|
218
|
+
|
|
219
|
+
return () => {
|
|
220
|
+
controller.abort();
|
|
221
|
+
};
|
|
222
|
+
}, [onKeyPress]);
|
|
223
|
+
|
|
224
|
+
return <>{children}</>;
|
|
225
|
+
},
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
export const useCurrentIndexStore = useFastContext;
|
|
229
|
+
export const useCurrentIndexStoreValue = useContextValue;
|
|
230
|
+
|
|
231
|
+
export default withKeyboardAccessibility;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type ComponentType } from 'react';
|
|
2
|
+
|
|
3
|
+
import { Portal } from '../components/Portal';
|
|
4
|
+
|
|
5
|
+
const withPortal =
|
|
6
|
+
<T,>(Component: ComponentType<T>) =>
|
|
7
|
+
(props: T) => {
|
|
8
|
+
return (
|
|
9
|
+
<Portal name={'withPortal' + (Component.displayName ?? '')}>
|
|
10
|
+
{/* @ts-ignore */}
|
|
11
|
+
<Component {...(props as T)} />
|
|
12
|
+
</Portal>
|
|
13
|
+
);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default withPortal;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Platform } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export default function createPseudoHook<T>({ events }: { events: string[] }) {
|
|
5
|
+
return function (ref: React.RefObject<T>, listen: boolean = true) {
|
|
6
|
+
if (Platform.OS !== 'web') {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const [isActive, setActive] = React.useState(false);
|
|
11
|
+
|
|
12
|
+
React.useEffect(() => {
|
|
13
|
+
const [eventIn, eventOut] = events;
|
|
14
|
+
|
|
15
|
+
const node = ref?.current;
|
|
16
|
+
if (!node || !listen) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const resolve = (value: boolean) => {
|
|
20
|
+
setActive(value);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// @ts-ignore
|
|
24
|
+
const onStart = resolve.bind(this, true);
|
|
25
|
+
// @ts-ignore
|
|
26
|
+
const onEnd = resolve.bind(this, false);
|
|
27
|
+
|
|
28
|
+
// @ts-ignore
|
|
29
|
+
node.addEventListener(eventIn, onStart);
|
|
30
|
+
// @ts-ignore
|
|
31
|
+
node.addEventListener(eventOut, onEnd);
|
|
32
|
+
|
|
33
|
+
// Special case for useActive to respond when the user drags out of the view and releases.
|
|
34
|
+
if (eventOut === 'mouseup') {
|
|
35
|
+
document.addEventListener(eventOut, onEnd, false);
|
|
36
|
+
}
|
|
37
|
+
return () => {
|
|
38
|
+
document.removeEventListener(eventOut, onEnd, false);
|
|
39
|
+
// @ts-ignore
|
|
40
|
+
node.removeEventListener(eventIn, onStart);
|
|
41
|
+
// @ts-ignore
|
|
42
|
+
node.removeEventListener(eventOut, onEnd);
|
|
43
|
+
};
|
|
44
|
+
// we only take initial value of listen
|
|
45
|
+
// eslint-disable-next-line
|
|
46
|
+
}, [ref]);
|
|
47
|
+
|
|
48
|
+
return isActive;
|
|
49
|
+
};
|
|
50
|
+
}
|
package/hooks/index.tsx
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// export { usePortal } from '@gorhom/portal';
|
|
2
|
+
|
|
3
|
+
export * from './useActionState';
|
|
4
|
+
export * from './useActive';
|
|
5
|
+
export { default as useBreakpoints } from './useBreakpoints';
|
|
6
|
+
export { default as useColorMode } from './useColorMode';
|
|
7
|
+
export { useContrastColor } from './useContrastColor';
|
|
8
|
+
export { default as useControlledValue } from './useControlledValue';
|
|
9
|
+
export * from './useFocus';
|
|
10
|
+
export {
|
|
11
|
+
type NumberMaskConfig,
|
|
12
|
+
default as useHandleNumberFormat,
|
|
13
|
+
type UseHandleNumberFormatProps,
|
|
14
|
+
} from './useHandleNumberFormat';
|
|
15
|
+
export * from './useHover';
|
|
16
|
+
export * from './useKeyboardDismissable';
|
|
17
|
+
export { default as useLatest } from './useLatest';
|
|
18
|
+
export { useMediaQuery } from './useMediaQuery';
|
|
19
|
+
export { useMergedRefs } from './useMergedRefs';
|
|
20
|
+
export { default as usePrevious } from './usePrevious';
|
|
21
|
+
export * from './useQueryFilter';
|
|
22
|
+
export {
|
|
23
|
+
default as useSearchable,
|
|
24
|
+
type UseSearchableProps,
|
|
25
|
+
useSearchInputProps,
|
|
26
|
+
} from './useSearchable';
|
|
27
|
+
export { default as useSubcomponents, type UseSubcomponentsProps } from './useSubcomponents';
|
|
28
|
+
export * from './useTheme';
|
|
29
|
+
export { default as useToggle } from './useToggle';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type RefObject, useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
export type UseActionStateProps = {
|
|
4
|
+
pressed?: boolean;
|
|
5
|
+
hovered?: boolean;
|
|
6
|
+
focused?: boolean;
|
|
7
|
+
actionsToListen?: ('pressed' | 'hovered' | 'focused')[];
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const useActionState = (
|
|
11
|
+
props: UseActionStateProps & { ref?: RefObject<any> | React.ForwardedRef<any> } = {},
|
|
12
|
+
) => {
|
|
13
|
+
const ref = useRef(null);
|
|
14
|
+
const actionsRef = (props.ref ?? ref) as RefObject<any>;
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
actionsRef,
|
|
18
|
+
hovered: false,
|
|
19
|
+
pressed: false,
|
|
20
|
+
focused: false,
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type RefObject, useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
import { useActive } from './useActive';
|
|
4
|
+
import { useFocus } from './useFocus';
|
|
5
|
+
import { useHover } from './useHover';
|
|
6
|
+
|
|
7
|
+
export type UseActionStateProps = {
|
|
8
|
+
pressed?: boolean;
|
|
9
|
+
hovered?: boolean;
|
|
10
|
+
focused?: boolean;
|
|
11
|
+
actionsToListen?: ('press' | 'hover' | 'focus')[];
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const useActionState = (
|
|
15
|
+
props: UseActionStateProps & { ref?: RefObject<any> | React.ForwardedRef<any> } = {},
|
|
16
|
+
) => {
|
|
17
|
+
const ref = useRef(null);
|
|
18
|
+
const actionsRef = (
|
|
19
|
+
(props.ref as any)?.current === undefined ? ref : props.ref
|
|
20
|
+
) as RefObject<any>;
|
|
21
|
+
const hovered =
|
|
22
|
+
useHover(actionsRef, props.actionsToListen?.includes('hover')) || !!props.hovered;
|
|
23
|
+
const pressed =
|
|
24
|
+
useActive(actionsRef, props.actionsToListen?.includes('press')) || !!props.pressed;
|
|
25
|
+
const focused =
|
|
26
|
+
useFocus(actionsRef, props.actionsToListen?.includes('focus')) || !!props.focused;
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
actionsRef,
|
|
30
|
+
hovered,
|
|
31
|
+
pressed,
|
|
32
|
+
focused,
|
|
33
|
+
};
|
|
34
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { UnistylesRuntime, useUnistyles } from 'react-native-unistyles';
|
|
3
|
+
|
|
4
|
+
import { type ColorMode, resolveColorMode } from '../utils/resolveColorMode';
|
|
5
|
+
|
|
6
|
+
const useColorMode = () => {
|
|
7
|
+
const themeName = useUnistyles().theme.dark ? 'dark' : 'light';
|
|
8
|
+
return useMemo(
|
|
9
|
+
() => ({
|
|
10
|
+
colorMode: resolveColorMode(themeName as ColorMode),
|
|
11
|
+
setColorMode: UnistylesRuntime.setTheme,
|
|
12
|
+
}),
|
|
13
|
+
[themeName],
|
|
14
|
+
);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default useColorMode;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { useUnistyles } from 'react-native-unistyles';
|
|
3
|
+
|
|
4
|
+
import { resolveContrastColor } from '../utils/color';
|
|
5
|
+
|
|
6
|
+
export const useContrastColor = (bgColor: string, lightColor?: string, darkColor?: string) => {
|
|
7
|
+
const isDarkMode = useUnistyles().theme.dark;
|
|
8
|
+
|
|
9
|
+
return useMemo(
|
|
10
|
+
() => resolveContrastColor(bgColor, lightColor, darkColor, isDarkMode),
|
|
11
|
+
[bgColor, lightColor, darkColor, isDarkMode],
|
|
12
|
+
);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default useContrastColor;
|