@utilitywarehouse/hearth-react-native 0.27.2 → 0.28.0-testid-fix-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/.turbo/turbo-build.log +5 -4
- package/.turbo/turbo-lint.log +70 -69
- package/CHANGELOG.md +149 -0
- package/build/components/Button/ButtonRoot.js +8 -0
- package/build/components/Combobox/Combobox.context.d.ts +13 -0
- package/build/components/Combobox/Combobox.context.js +9 -0
- package/build/components/Combobox/Combobox.d.ts +6 -0
- package/build/components/Combobox/Combobox.js +246 -0
- package/build/components/Combobox/Combobox.props.d.ts +180 -0
- package/build/components/Combobox/Combobox.props.js +1 -0
- package/build/components/Combobox/ComboboxOption.d.ts +6 -0
- package/build/components/Combobox/ComboboxOption.js +56 -0
- package/build/components/Combobox/index.d.ts +4 -0
- package/build/components/Combobox/index.js +3 -0
- package/build/components/DatePicker/TimePicker.d.ts +3 -0
- package/build/components/DatePicker/TimePicker.js +84 -0
- package/build/components/DatePicker/time-picker/animated-math.d.ts +4 -0
- package/build/components/DatePicker/time-picker/animated-math.js +19 -0
- package/build/components/DatePicker/time-picker/period-native.d.ts +6 -0
- package/build/components/DatePicker/time-picker/period-native.js +17 -0
- package/build/components/DatePicker/time-picker/period-picker.d.ts +6 -0
- package/build/components/DatePicker/time-picker/period-picker.js +10 -0
- package/build/components/DatePicker/time-picker/period-web.d.ts +6 -0
- package/build/components/DatePicker/time-picker/period-web.js +21 -0
- package/build/components/DatePicker/time-picker/wheel-native.d.ts +8 -0
- package/build/components/DatePicker/time-picker/wheel-native.js +19 -0
- package/build/components/DatePicker/time-picker/wheel-picker/index.d.ts +2 -0
- package/build/components/DatePicker/time-picker/wheel-picker/index.js +2 -0
- package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker-item.d.ts +16 -0
- package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker-item.js +97 -0
- package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker.d.ts +21 -0
- package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker.js +88 -0
- package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker.style.d.ts +23 -0
- package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker.style.js +21 -0
- package/build/components/DatePicker/time-picker/wheel-web.d.ts +8 -0
- package/build/components/DatePicker/time-picker/wheel-web.js +146 -0
- package/build/components/DatePicker/time-picker/wheel.d.ts +8 -0
- package/build/components/DatePicker/time-picker/wheel.js +10 -0
- package/build/components/List/List.js +2 -2
- package/build/components/Modal/Modal.js +31 -42
- package/build/components/Modal/Modal.web.js +3 -3
- package/build/components/Pagination/Pagination.d.ts +6 -0
- package/build/components/Pagination/Pagination.js +125 -0
- package/build/components/Pagination/Pagination.props.d.ts +26 -0
- package/build/components/Pagination/Pagination.props.js +1 -0
- package/build/components/Pagination/Pagination.utils.d.ts +2 -0
- package/build/components/Pagination/Pagination.utils.js +20 -0
- package/build/components/Pagination/Pagination.utils.test.d.ts +1 -0
- package/build/components/Pagination/Pagination.utils.test.js +16 -0
- package/build/components/Pagination/index.d.ts +2 -0
- package/build/components/Pagination/index.js +1 -0
- package/build/components/SafeAreaView/SafeAreaView.d.ts +5 -0
- package/build/components/SafeAreaView/SafeAreaView.js +117 -0
- package/build/components/SafeAreaView/SafeAreaView.props.d.ts +17 -0
- package/build/components/SafeAreaView/SafeAreaView.props.js +1 -0
- package/build/components/SafeAreaView/index.d.ts +2 -0
- package/build/components/SafeAreaView/index.js +1 -0
- package/build/components/Select/Select.d.ts +1 -1
- package/build/components/Select/Select.js +6 -5
- package/build/components/Select/Select.props.d.ts +4 -0
- package/build/components/Select/SelectOption.d.ts +1 -1
- package/build/components/Select/SelectOption.js +2 -2
- package/build/components/Table/Table.context.d.ts +12 -0
- package/build/components/Table/Table.context.js +9 -0
- package/build/components/Table/Table.d.ts +6 -0
- package/build/components/Table/Table.js +71 -0
- package/build/components/Table/Table.props.d.ts +56 -0
- package/build/components/Table/Table.props.js +1 -0
- package/build/components/Table/Table.utils.d.ts +5 -0
- package/build/components/Table/Table.utils.js +48 -0
- package/build/components/Table/Table.utils.test.d.ts +1 -0
- package/build/components/Table/Table.utils.test.js +71 -0
- package/build/components/Table/TableBody.d.ts +6 -0
- package/build/components/Table/TableBody.js +16 -0
- package/build/components/Table/TableCell.d.ts +10 -0
- package/build/components/Table/TableCell.js +44 -0
- package/build/components/Table/TableHeader.d.ts +6 -0
- package/build/components/Table/TableHeader.js +24 -0
- package/build/components/Table/TableHeaderCell.d.ts +10 -0
- package/build/components/Table/TableHeaderCell.js +97 -0
- package/build/components/Table/TablePagination.d.ts +6 -0
- package/build/components/Table/TablePagination.js +7 -0
- package/build/components/Table/TableRow.d.ts +8 -0
- package/build/components/Table/TableRow.js +25 -0
- package/build/components/Table/index.d.ts +8 -0
- package/build/components/Table/index.js +7 -0
- package/build/components/Timeline/Timeline.d.ts +6 -0
- package/build/components/Timeline/Timeline.js +34 -0
- package/build/components/Timeline/Timeline.props.d.ts +47 -0
- package/build/components/Timeline/Timeline.props.js +1 -0
- package/build/components/Timeline/TimelineItem.d.ts +6 -0
- package/build/components/Timeline/TimelineItem.js +235 -0
- package/build/components/Timeline/index.d.ts +3 -0
- package/build/components/Timeline/index.js +2 -0
- package/build/components/VerificationInput/VerificationInput.js +3 -3
- package/build/components/index.d.ts +5 -0
- package/build/components/index.js +5 -0
- package/build/tokens/components/dark/timeline.d.ts +2 -2
- package/build/tokens/components/dark/timeline.js +2 -2
- package/docs/components/AllComponents.web.tsx +106 -23
- package/docs/llm-docs/unistyles-llms-full.txt +1132 -534
- package/docs/llm-docs/unistyles-llms-small.txt +37 -37
- package/package.json +4 -4
- package/src/components/Button/Button.stories.tsx +43 -7
- package/src/components/Button/ButtonRoot.tsx +8 -0
- package/src/components/Combobox/Combobox.context.ts +26 -0
- package/src/components/Combobox/Combobox.docs.mdx +277 -0
- package/src/components/Combobox/Combobox.figma.tsx +60 -0
- package/src/components/Combobox/Combobox.props.ts +187 -0
- package/src/components/Combobox/Combobox.stories.tsx +233 -0
- package/src/components/Combobox/Combobox.tsx +446 -0
- package/src/components/Combobox/ComboboxOption.tsx +100 -0
- package/src/components/Combobox/index.ts +9 -0
- package/src/components/List/List.tsx +5 -4
- package/src/components/Modal/Modal.tsx +67 -74
- package/src/components/Modal/Modal.web.tsx +3 -3
- package/src/components/Pagination/Pagination.docs.mdx +99 -0
- package/src/components/Pagination/Pagination.figma.tsx +20 -0
- package/src/components/Pagination/Pagination.props.ts +28 -0
- package/src/components/Pagination/Pagination.stories.tsx +88 -0
- package/src/components/Pagination/Pagination.tsx +248 -0
- package/src/components/Pagination/Pagination.utils.test.ts +20 -0
- package/src/components/Pagination/Pagination.utils.ts +37 -0
- package/src/components/Pagination/index.ts +2 -0
- package/src/components/SafeAreaView/SafeAreaView.props.ts +20 -0
- package/src/components/SafeAreaView/SafeAreaView.tsx +173 -0
- package/src/components/SafeAreaView/index.ts +2 -0
- package/src/components/Select/Select.props.ts +4 -0
- package/src/components/Select/Select.tsx +35 -28
- package/src/components/Select/SelectOption.tsx +2 -0
- package/src/components/Table/Table.context.tsx +23 -0
- package/src/components/Table/Table.docs.mdx +239 -0
- package/src/components/Table/Table.figma.tsx +65 -0
- package/src/components/Table/Table.props.ts +65 -0
- package/src/components/Table/Table.stories.tsx +399 -0
- package/src/components/Table/Table.tsx +127 -0
- package/src/components/Table/Table.utils.test.ts +82 -0
- package/src/components/Table/Table.utils.ts +72 -0
- package/src/components/Table/TableBody.tsx +25 -0
- package/src/components/Table/TableCell.tsx +67 -0
- package/src/components/Table/TableHeader.tsx +41 -0
- package/src/components/Table/TableHeaderCell.tsx +136 -0
- package/src/components/Table/TablePagination.tsx +10 -0
- package/src/components/Table/TableRow.tsx +42 -0
- package/src/components/Table/index.ts +16 -0
- package/src/components/Timeline/Timeline.docs.mdx +177 -0
- package/src/components/Timeline/Timeline.figma.tsx +89 -0
- package/src/components/Timeline/Timeline.props.ts +51 -0
- package/src/components/Timeline/Timeline.stories.tsx +102 -0
- package/src/components/Timeline/Timeline.tsx +48 -0
- package/src/components/Timeline/TimelineItem.tsx +293 -0
- package/src/components/Timeline/index.ts +9 -0
- package/src/components/VerificationInput/VerificationInput.tsx +3 -0
- package/src/components/index.ts +5 -0
- package/src/tokens/components/dark/timeline.ts +2 -2
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { BottomSheetFlatListProps } from '@gorhom/bottom-sheet/lib/typescript/components/bottomSheetScrollable/types';
|
|
2
|
+
import { ComponentType, ReactNode } from 'react';
|
|
3
|
+
import { ViewProps } from 'react-native';
|
|
4
|
+
import { BottomSheetProps } from '../BottomSheet';
|
|
5
|
+
import { ComboboxSelection } from './Combobox.context';
|
|
6
|
+
type ValidationStatus = 'initial' | 'valid' | 'invalid';
|
|
7
|
+
export interface ComboboxOptionItemProps {
|
|
8
|
+
/**
|
|
9
|
+
* Label shown for this option.
|
|
10
|
+
*/
|
|
11
|
+
label: string;
|
|
12
|
+
/**
|
|
13
|
+
* Value returned when this option is selected.
|
|
14
|
+
*/
|
|
15
|
+
value: string;
|
|
16
|
+
/**
|
|
17
|
+
* Optional icon shown before the option label.
|
|
18
|
+
*/
|
|
19
|
+
leadingIcon?: ComponentType;
|
|
20
|
+
/**
|
|
21
|
+
* Optional icon shown after the option label.
|
|
22
|
+
*/
|
|
23
|
+
trailingIcon?: ComponentType;
|
|
24
|
+
/**
|
|
25
|
+
* Additional searchable terms for this option.
|
|
26
|
+
*/
|
|
27
|
+
keywords?: string[];
|
|
28
|
+
/**
|
|
29
|
+
* Whether this option is disabled.
|
|
30
|
+
*/
|
|
31
|
+
disabled?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface ComboboxRenderContentProps {
|
|
34
|
+
/**
|
|
35
|
+
* Current search value used by both the trigger and bottom sheet input.
|
|
36
|
+
*/
|
|
37
|
+
search: string;
|
|
38
|
+
/**
|
|
39
|
+
* Update the search value.
|
|
40
|
+
*/
|
|
41
|
+
setSearch: (value: string) => void;
|
|
42
|
+
/**
|
|
43
|
+
* Close the bottom sheet.
|
|
44
|
+
*/
|
|
45
|
+
close: () => void;
|
|
46
|
+
/**
|
|
47
|
+
* Select an option, update the trigger text and close the bottom sheet.
|
|
48
|
+
*/
|
|
49
|
+
selectOption: (option: ComboboxSelection) => void;
|
|
50
|
+
/**
|
|
51
|
+
* Currently selected value.
|
|
52
|
+
*/
|
|
53
|
+
selectedValue?: string | null;
|
|
54
|
+
}
|
|
55
|
+
export interface ComboboxOptionProps extends ComboboxOptionItemProps {
|
|
56
|
+
/**
|
|
57
|
+
* Whether this option is selected.
|
|
58
|
+
*/
|
|
59
|
+
selected?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Custom press handler for this option.
|
|
62
|
+
*/
|
|
63
|
+
onPress?: (value: string) => void;
|
|
64
|
+
}
|
|
65
|
+
type ComboboxChildren = ReactNode | ((props: ComboboxRenderContentProps) => ReactNode);
|
|
66
|
+
interface ComboboxProps extends Omit<ViewProps, 'children'> {
|
|
67
|
+
/**
|
|
68
|
+
* Array of options to render using the default bottom sheet list.
|
|
69
|
+
*/
|
|
70
|
+
options?: ComboboxOptionItemProps[];
|
|
71
|
+
/**
|
|
72
|
+
* Currently selected value.
|
|
73
|
+
*/
|
|
74
|
+
value?: string | null;
|
|
75
|
+
/**
|
|
76
|
+
* Callback fired when the selected value changes.
|
|
77
|
+
*/
|
|
78
|
+
onValueChange?: (value: string | null) => void;
|
|
79
|
+
/**
|
|
80
|
+
* Controlled search value used by the trigger and bottom sheet input.
|
|
81
|
+
*/
|
|
82
|
+
inputValue?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Callback fired when the search value changes.
|
|
85
|
+
*/
|
|
86
|
+
onInputValueChange?: (value: string) => void;
|
|
87
|
+
/**
|
|
88
|
+
* Label shown above the combobox.
|
|
89
|
+
*/
|
|
90
|
+
label?: string;
|
|
91
|
+
/**
|
|
92
|
+
* The variant of the label text.
|
|
93
|
+
*
|
|
94
|
+
* @default 'body'
|
|
95
|
+
*/
|
|
96
|
+
labelVariant?: 'heading' | 'body';
|
|
97
|
+
/**
|
|
98
|
+
* Helper text shown below the label.
|
|
99
|
+
*/
|
|
100
|
+
helperText?: string;
|
|
101
|
+
/**
|
|
102
|
+
* Optional helper icon.
|
|
103
|
+
*/
|
|
104
|
+
helperIcon?: ComponentType;
|
|
105
|
+
/**
|
|
106
|
+
* Text shown for invalid state.
|
|
107
|
+
*/
|
|
108
|
+
invalidText?: string;
|
|
109
|
+
/**
|
|
110
|
+
* Text shown for valid state.
|
|
111
|
+
*/
|
|
112
|
+
validText?: string;
|
|
113
|
+
/**
|
|
114
|
+
* Placeholder shown when the combobox is empty.
|
|
115
|
+
*
|
|
116
|
+
* @default 'Search'
|
|
117
|
+
*/
|
|
118
|
+
placeholder?: string;
|
|
119
|
+
/**
|
|
120
|
+
* Placeholder shown in the bottom sheet search input.
|
|
121
|
+
*
|
|
122
|
+
* @default 'Search'
|
|
123
|
+
*/
|
|
124
|
+
searchPlaceholder?: string;
|
|
125
|
+
/**
|
|
126
|
+
* Whether the combobox is disabled.
|
|
127
|
+
*/
|
|
128
|
+
disabled?: boolean;
|
|
129
|
+
/**
|
|
130
|
+
* Validation status for the combobox.
|
|
131
|
+
*
|
|
132
|
+
* @default 'initial'
|
|
133
|
+
*/
|
|
134
|
+
validationStatus?: ValidationStatus;
|
|
135
|
+
/**
|
|
136
|
+
* Whether the combobox is required.
|
|
137
|
+
*
|
|
138
|
+
* @default true
|
|
139
|
+
*/
|
|
140
|
+
required?: boolean;
|
|
141
|
+
/**
|
|
142
|
+
* Heading displayed above the bottom sheet search input.
|
|
143
|
+
*/
|
|
144
|
+
menuHeading?: string;
|
|
145
|
+
/**
|
|
146
|
+
* Custom bottom sheet content, or a render function for fully custom list rendering.
|
|
147
|
+
*/
|
|
148
|
+
children?: ComboboxChildren;
|
|
149
|
+
/**
|
|
150
|
+
* Props passed to the BottomSheetModal.
|
|
151
|
+
*/
|
|
152
|
+
bottomSheetProps?: Partial<BottomSheetProps>;
|
|
153
|
+
/**
|
|
154
|
+
* Text shown when no options match the current search.
|
|
155
|
+
*
|
|
156
|
+
* @default 'No options found'
|
|
157
|
+
*/
|
|
158
|
+
noOptionsFoundText?: string;
|
|
159
|
+
/**
|
|
160
|
+
* Props passed to the default BottomSheetFlatList renderer.
|
|
161
|
+
*/
|
|
162
|
+
listProps?: Partial<BottomSheetFlatListProps<ComboboxOptionItemProps>>;
|
|
163
|
+
/**
|
|
164
|
+
* Whether the combobox should show a loading spinner.
|
|
165
|
+
*/
|
|
166
|
+
loading?: boolean;
|
|
167
|
+
/**
|
|
168
|
+
* Whether the combobox is readonly.
|
|
169
|
+
*/
|
|
170
|
+
readonly?: boolean;
|
|
171
|
+
/**
|
|
172
|
+
* Resolve a label for a selected value when the current options array does not contain it.
|
|
173
|
+
*/
|
|
174
|
+
getValueLabel?: (value: string | null | undefined) => string;
|
|
175
|
+
/**
|
|
176
|
+
* Override the default filtering behaviour for the default options list.
|
|
177
|
+
*/
|
|
178
|
+
filterOption?: (option: ComboboxOptionItemProps, search: string) => boolean;
|
|
179
|
+
}
|
|
180
|
+
export default ComboboxProps;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ComboboxOptionProps } from './Combobox.props';
|
|
2
|
+
declare const ComboboxOption: {
|
|
3
|
+
({ label, value, leadingIcon: LeftIcon, trailingIcon: RightIcon, selected, disabled, onPress, }: ComboboxOptionProps): import("react/jsx-runtime").JSX.Element;
|
|
4
|
+
displayName: string;
|
|
5
|
+
};
|
|
6
|
+
export default ComboboxOption;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { TickSmallIcon } from '@utilitywarehouse/hearth-react-native-icons';
|
|
3
|
+
import { Pressable, View } from 'react-native';
|
|
4
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
5
|
+
import { BodyText } from '../BodyText';
|
|
6
|
+
import { Icon } from '../Icon';
|
|
7
|
+
import { useComboboxContext } from './Combobox.context';
|
|
8
|
+
const ComboboxOption = ({ label, value, leadingIcon: LeftIcon, trailingIcon: RightIcon, selected, disabled, onPress, }) => {
|
|
9
|
+
const { selectedValue, selectOption } = useComboboxContext();
|
|
10
|
+
const isSelected = selected !== undefined ? selected : selectedValue === value;
|
|
11
|
+
styles.useVariants({ disabled });
|
|
12
|
+
const handlePress = () => {
|
|
13
|
+
if (disabled) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (onPress) {
|
|
17
|
+
onPress(value);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
selectOption({ label, value });
|
|
21
|
+
};
|
|
22
|
+
return (_jsxs(Pressable, { onPress: handlePress, disabled: disabled, style: ({ pressed }) => [styles.container, pressed && styles.pressed], children: [!!LeftIcon && (_jsx(View, { children: _jsx(Icon, { as: LeftIcon, style: styles.icon }) })), _jsx(View, { style: styles.labelContainer, children: _jsx(BodyText, { children: label }) }), isSelected && (_jsx(View, { children: _jsx(Icon, { as: TickSmallIcon, style: styles.icon }) })), !!RightIcon && !isSelected && (_jsx(View, { children: _jsx(Icon, { as: RightIcon, style: styles.icon }) }))] }));
|
|
23
|
+
};
|
|
24
|
+
const styles = StyleSheet.create(theme => ({
|
|
25
|
+
container: {
|
|
26
|
+
flexDirection: 'row',
|
|
27
|
+
alignItems: 'center',
|
|
28
|
+
gap: theme.components.select.dropdown.item.gap,
|
|
29
|
+
borderRadius: theme.components.select.dropdown.item.borderRadius,
|
|
30
|
+
paddingVertical: theme.components.select.dropdown.item.padding,
|
|
31
|
+
paddingHorizontal: theme.components.select.dropdown.padding,
|
|
32
|
+
variants: {
|
|
33
|
+
disabled: {
|
|
34
|
+
true: {
|
|
35
|
+
opacity: theme.opacity.disabled,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
_web: {
|
|
40
|
+
_hover: {
|
|
41
|
+
backgroundColor: theme.color.interactive.functional.surface.subtle.hover,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
icon: {
|
|
46
|
+
color: theme.color.interactive.functional.foreground.subtle,
|
|
47
|
+
},
|
|
48
|
+
pressed: {
|
|
49
|
+
backgroundColor: theme.color.interactive.functional.surface.subtle.active,
|
|
50
|
+
},
|
|
51
|
+
labelContainer: {
|
|
52
|
+
flex: 1,
|
|
53
|
+
},
|
|
54
|
+
}));
|
|
55
|
+
ComboboxOption.displayName = 'ComboboxOption';
|
|
56
|
+
export default ComboboxOption;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { default as Combobox } from './Combobox';
|
|
2
|
+
export { ComboboxContext, useComboboxContext } from './Combobox.context';
|
|
3
|
+
export { default as ComboboxOption } from './ComboboxOption';
|
|
4
|
+
export type { default as ComboboxProps, ComboboxOptionItemProps, ComboboxOptionProps, ComboboxRenderContentProps, } from './Combobox.props';
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import dayjs from 'dayjs';
|
|
3
|
+
import { useCallback, useMemo } from 'react';
|
|
4
|
+
import { ScrollView, View } from 'react-native';
|
|
5
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
6
|
+
import { BodyText } from '../BodyText';
|
|
7
|
+
import { useDatePickerContext } from './DatePicker.context';
|
|
8
|
+
import { CONTAINER_HEIGHT } from './enums';
|
|
9
|
+
import PeriodPicker from './time-picker/period-picker';
|
|
10
|
+
import Wheel from './time-picker/wheel';
|
|
11
|
+
import { formatNumber, getParsedDate } from './utils';
|
|
12
|
+
const createNumberList = (num, numerals, startFrom = 0) => {
|
|
13
|
+
return Array.from({ length: num }, (_, i) => ({
|
|
14
|
+
value: i + startFrom,
|
|
15
|
+
text: i + startFrom < 10
|
|
16
|
+
? `${formatNumber(0, numerals)}${formatNumber(i + startFrom, numerals)}`
|
|
17
|
+
: `${formatNumber(i + startFrom, numerals)}`,
|
|
18
|
+
}));
|
|
19
|
+
};
|
|
20
|
+
const TimePicker = () => {
|
|
21
|
+
const { currentDate, date, onSelectDate, timeZone, numerals = 'latn', use12Hours, } = useDatePickerContext();
|
|
22
|
+
const hours = useMemo(() => createNumberList(use12Hours ? 12 : 24, numerals, use12Hours ? 1 : 0), [numerals, use12Hours]);
|
|
23
|
+
const minutes = useMemo(() => createNumberList(60, numerals), [numerals]);
|
|
24
|
+
const { hour, hour12, minute, period } = getParsedDate(date || currentDate);
|
|
25
|
+
const handleChangeHour = useCallback((value) => {
|
|
26
|
+
let hour24 = value;
|
|
27
|
+
if (use12Hours) {
|
|
28
|
+
if (period === 'AM' && value === 12) {
|
|
29
|
+
hour24 = 0;
|
|
30
|
+
}
|
|
31
|
+
else if (period === 'PM' && value < 12) {
|
|
32
|
+
hour24 = value + 12;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
hour24 = value;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const newDate = dayjs.tz(date, timeZone).hour(hour24).minute(minute);
|
|
39
|
+
onSelectDate(newDate);
|
|
40
|
+
}, [date, onSelectDate, timeZone, use12Hours, period, minute]);
|
|
41
|
+
const handleChangeMinute = useCallback((value) => {
|
|
42
|
+
const newDate = dayjs.tz(date, timeZone).minute(value);
|
|
43
|
+
onSelectDate(newDate);
|
|
44
|
+
}, [date, onSelectDate, timeZone]);
|
|
45
|
+
const handlePeriodChange = useCallback((newPeriod) => {
|
|
46
|
+
let newHour = hour12;
|
|
47
|
+
if (newPeriod === 'PM' && hour12 < 12) {
|
|
48
|
+
newHour = hour12 + 12;
|
|
49
|
+
}
|
|
50
|
+
else if (newPeriod === 'AM' && hour12 === 12) {
|
|
51
|
+
newHour = 0;
|
|
52
|
+
}
|
|
53
|
+
else if (newPeriod === 'AM' && hour >= 12) {
|
|
54
|
+
newHour = hour12;
|
|
55
|
+
}
|
|
56
|
+
const newDate = dayjs.tz(date || currentDate, timeZone).hour(newHour);
|
|
57
|
+
onSelectDate(newDate);
|
|
58
|
+
}, [date, currentDate, onSelectDate, timeZone, hour, hour12]);
|
|
59
|
+
return (_jsxs(ScrollView, { horizontal: true, scrollEnabled: false, contentContainerStyle: styles.container, testID: "time-selector", children: [_jsxs(View, { style: styles.timePickerContainer, children: [_jsx(View, { style: styles.wheelContainer, children: _jsx(Wheel, { value: use12Hours ? hour12 : hour, items: hours, setValue: handleChangeHour }) }), _jsx(BodyText, { style: styles.timeSeparator, children: ":" }), _jsx(View, { style: styles.wheelContainer, children: _jsx(Wheel, { value: minute, items: minutes, setValue: handleChangeMinute }) })] }), use12Hours && period ? (_jsx(View, { style: styles.periodContainer, children: _jsx(PeriodPicker, { value: period, setValue: handlePeriodChange }) })) : null] }));
|
|
60
|
+
};
|
|
61
|
+
const styles = StyleSheet.create({
|
|
62
|
+
container: {
|
|
63
|
+
flex: 1,
|
|
64
|
+
alignItems: 'center',
|
|
65
|
+
justifyContent: 'center',
|
|
66
|
+
},
|
|
67
|
+
wheelContainer: {
|
|
68
|
+
flex: 1,
|
|
69
|
+
},
|
|
70
|
+
timePickerContainer: {
|
|
71
|
+
alignItems: 'center',
|
|
72
|
+
justifyContent: 'center',
|
|
73
|
+
width: CONTAINER_HEIGHT / 2,
|
|
74
|
+
height: CONTAINER_HEIGHT / 2,
|
|
75
|
+
flexDirection: 'row',
|
|
76
|
+
},
|
|
77
|
+
timeSeparator: {
|
|
78
|
+
marginHorizontal: 5,
|
|
79
|
+
},
|
|
80
|
+
periodContainer: {
|
|
81
|
+
marginLeft: 10,
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
export default TimePicker;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Animated } from 'react-native';
|
|
2
|
+
const FACTORIAL_3 = 3 * 2;
|
|
3
|
+
const FACTORIAL_5 = 5 * 4 * FACTORIAL_3;
|
|
4
|
+
const FACTORIAL_7 = 7 * 6 * FACTORIAL_5;
|
|
5
|
+
function sin(animated) {
|
|
6
|
+
const normalized = normalize(animated);
|
|
7
|
+
const square = Animated.multiply(normalized, normalized);
|
|
8
|
+
const pow3 = Animated.multiply(normalized, square);
|
|
9
|
+
const pow5 = Animated.multiply(pow3, square);
|
|
10
|
+
const pow7 = Animated.multiply(pow5, square);
|
|
11
|
+
return Animated.add(Animated.add(normalized, Animated.multiply(pow3, -1 / FACTORIAL_3)), Animated.add(Animated.multiply(pow5, 1 / FACTORIAL_5), Animated.multiply(pow7, -1 / FACTORIAL_7)));
|
|
12
|
+
}
|
|
13
|
+
function normalize(animated) {
|
|
14
|
+
return Animated.add(Animated.modulo(Animated.add(animated, Math.PI), Math.PI * 2), -Math.PI).interpolate({
|
|
15
|
+
inputRange: [-Math.PI, -Math.PI / 2, Math.PI / 2, Math.PI],
|
|
16
|
+
outputRange: [0, -Math.PI / 2, Math.PI / 2, 0],
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
export { sin, normalize };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
import WheelPicker from './wheel-picker';
|
|
4
|
+
const options = [
|
|
5
|
+
{ value: 'AM', text: 'AM' },
|
|
6
|
+
{ value: 'PM', text: 'PM' },
|
|
7
|
+
];
|
|
8
|
+
const PeriodNative = ({ value, setValue = () => { } }) => {
|
|
9
|
+
return (_jsx(WheelPicker, { value: value, options: options, onChange: setValue,
|
|
10
|
+
//containerStyle={defaultStyles.container}
|
|
11
|
+
itemHeight: 44, decelerationRate: "fast" }));
|
|
12
|
+
};
|
|
13
|
+
const customComparator = (prev, next) => {
|
|
14
|
+
const areEqual = prev.value === next.value && prev.setValue === next.setValue;
|
|
15
|
+
return areEqual;
|
|
16
|
+
};
|
|
17
|
+
export default memo(PeriodNative, customComparator);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
import { Platform } from 'react-native';
|
|
4
|
+
import PeriodNative from './period-native';
|
|
5
|
+
import PeriodWeb from './period-web';
|
|
6
|
+
const PeriodPicker = (props) => {
|
|
7
|
+
const Component = Platform.OS === 'web' ? PeriodWeb : PeriodNative;
|
|
8
|
+
return _jsx(Component, { ...props });
|
|
9
|
+
};
|
|
10
|
+
export default memo(PeriodPicker);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
import { Pressable, View } from 'react-native';
|
|
4
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
5
|
+
import { BodyText } from '../../BodyText';
|
|
6
|
+
const PeriodWeb = ({ value, setValue = () => { } }) => {
|
|
7
|
+
return (_jsx(Pressable, { onPress: () => setValue(value == 'AM' ? 'PM' : 'AM'), children: _jsx(View, { style: [styles.period], children: _jsx(BodyText, { children: value }) }) }));
|
|
8
|
+
};
|
|
9
|
+
const styles = StyleSheet.create({
|
|
10
|
+
period: {
|
|
11
|
+
width: 65,
|
|
12
|
+
height: 44,
|
|
13
|
+
alignItems: 'center',
|
|
14
|
+
justifyContent: 'center',
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
const customComparator = (prev, next) => {
|
|
18
|
+
const areEqual = prev.value === next.value && prev.setValue === next.setValue;
|
|
19
|
+
return areEqual;
|
|
20
|
+
};
|
|
21
|
+
export default memo(PeriodWeb, customComparator);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { PickerOption } from '../DatePicker.props';
|
|
2
|
+
interface WheelProps {
|
|
3
|
+
value: number | string;
|
|
4
|
+
setValue?: (value: any) => void;
|
|
5
|
+
items: PickerOption[];
|
|
6
|
+
}
|
|
7
|
+
declare const _default: import("react").MemoExoticComponent<({ value, setValue, items }: WheelProps) => import("react/jsx-runtime").JSX.Element>;
|
|
8
|
+
export default _default;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
import { Platform } from 'react-native';
|
|
4
|
+
import { StyleSheet } from 'react-native-unistyles';
|
|
5
|
+
import WheelPicker from './wheel-picker';
|
|
6
|
+
const WheelNative = ({ value, setValue = () => { }, items }) => {
|
|
7
|
+
return (_jsx(WheelPicker, { value: value, options: items, onChange: setValue, containerStyle: styles.container, itemHeight: 44, decelerationRate: "fast" }));
|
|
8
|
+
};
|
|
9
|
+
const styles = StyleSheet.create({
|
|
10
|
+
container: {
|
|
11
|
+
display: 'flex',
|
|
12
|
+
...Platform.select({
|
|
13
|
+
web: {
|
|
14
|
+
userSelect: 'none',
|
|
15
|
+
},
|
|
16
|
+
}),
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
export default memo(WheelNative);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Animated, StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
import { PickerOption } from '../../DatePicker.props';
|
|
4
|
+
interface ItemProps {
|
|
5
|
+
style: StyleProp<ViewStyle>;
|
|
6
|
+
option: PickerOption | null;
|
|
7
|
+
height: number;
|
|
8
|
+
index: number;
|
|
9
|
+
currentScrollIndex: Animated.AnimatedAddition<number>;
|
|
10
|
+
visibleRest: number;
|
|
11
|
+
rotationFunction: (x: number) => number;
|
|
12
|
+
opacityFunction: (x: number) => number;
|
|
13
|
+
scaleFunction: (x: number) => number;
|
|
14
|
+
}
|
|
15
|
+
declare const _default: React.NamedExoticComponent<ItemProps>;
|
|
16
|
+
export default _default;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Animated } from 'react-native';
|
|
4
|
+
import { BodyText } from '../../../BodyText';
|
|
5
|
+
import styles from './wheel-picker.style';
|
|
6
|
+
const WheelPickerItem = ({ style, height, option, index, visibleRest, currentScrollIndex, opacityFunction, rotationFunction, scaleFunction, }) => {
|
|
7
|
+
const relativeScrollIndex = Animated.subtract(index, currentScrollIndex);
|
|
8
|
+
const translateY = relativeScrollIndex.interpolate({
|
|
9
|
+
inputRange: (() => {
|
|
10
|
+
const range = [0];
|
|
11
|
+
for (let i = 1; i <= visibleRest + 1; i++) {
|
|
12
|
+
range.unshift(-i);
|
|
13
|
+
range.push(i);
|
|
14
|
+
}
|
|
15
|
+
return range;
|
|
16
|
+
})(),
|
|
17
|
+
outputRange: (() => {
|
|
18
|
+
const range = [0];
|
|
19
|
+
for (let i = 1; i <= visibleRest + 1; i++) {
|
|
20
|
+
let y = (height / 2) * (1 - Math.sin(Math.PI / 2 - rotationFunction(i)));
|
|
21
|
+
for (let j = 1; j < i; j++) {
|
|
22
|
+
y += height * (1 - Math.sin(Math.PI / 2 - rotationFunction(j)));
|
|
23
|
+
}
|
|
24
|
+
range.unshift(y);
|
|
25
|
+
range.push(-y);
|
|
26
|
+
}
|
|
27
|
+
return range;
|
|
28
|
+
})(),
|
|
29
|
+
});
|
|
30
|
+
const opacity = relativeScrollIndex.interpolate({
|
|
31
|
+
inputRange: (() => {
|
|
32
|
+
const range = [0];
|
|
33
|
+
for (let i = 1; i <= visibleRest + 1; i++) {
|
|
34
|
+
range.unshift(-i);
|
|
35
|
+
range.push(i);
|
|
36
|
+
}
|
|
37
|
+
return range;
|
|
38
|
+
})(),
|
|
39
|
+
outputRange: (() => {
|
|
40
|
+
const range = [1];
|
|
41
|
+
for (let x = 1; x <= visibleRest + 1; x++) {
|
|
42
|
+
const y = opacityFunction(x);
|
|
43
|
+
range.unshift(y);
|
|
44
|
+
range.push(y);
|
|
45
|
+
}
|
|
46
|
+
return range;
|
|
47
|
+
})(),
|
|
48
|
+
});
|
|
49
|
+
const scale = relativeScrollIndex.interpolate({
|
|
50
|
+
inputRange: (() => {
|
|
51
|
+
const range = [0];
|
|
52
|
+
for (let i = 1; i <= visibleRest + 1; i++) {
|
|
53
|
+
range.unshift(-i);
|
|
54
|
+
range.push(i);
|
|
55
|
+
}
|
|
56
|
+
return range;
|
|
57
|
+
})(),
|
|
58
|
+
outputRange: (() => {
|
|
59
|
+
const range = [1.0];
|
|
60
|
+
for (let x = 1; x <= visibleRest + 1; x++) {
|
|
61
|
+
const y = scaleFunction(x);
|
|
62
|
+
range.unshift(y);
|
|
63
|
+
range.push(y);
|
|
64
|
+
}
|
|
65
|
+
return range;
|
|
66
|
+
})(),
|
|
67
|
+
});
|
|
68
|
+
const rotateX = relativeScrollIndex.interpolate({
|
|
69
|
+
inputRange: (() => {
|
|
70
|
+
const range = [0];
|
|
71
|
+
for (let i = 1; i <= visibleRest + 1; i++) {
|
|
72
|
+
range.unshift(-i);
|
|
73
|
+
range.push(i);
|
|
74
|
+
}
|
|
75
|
+
return range;
|
|
76
|
+
})(),
|
|
77
|
+
outputRange: (() => {
|
|
78
|
+
const range = ['0deg'];
|
|
79
|
+
for (let x = 1; x <= visibleRest + 1; x++) {
|
|
80
|
+
const y = rotationFunction(x);
|
|
81
|
+
range.unshift(`${y}deg`);
|
|
82
|
+
range.push(`${y}deg`);
|
|
83
|
+
}
|
|
84
|
+
return range;
|
|
85
|
+
})(),
|
|
86
|
+
});
|
|
87
|
+
return (_jsx(Animated.View, { style: [
|
|
88
|
+
styles.option,
|
|
89
|
+
style,
|
|
90
|
+
{
|
|
91
|
+
height,
|
|
92
|
+
opacity,
|
|
93
|
+
transform: [{ translateY }, { rotateX }, { scale }],
|
|
94
|
+
},
|
|
95
|
+
], children: _jsx(BodyText, { children: option?.text }) }));
|
|
96
|
+
};
|
|
97
|
+
export default React.memo(WheelPickerItem);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FlatListProps, StyleProp, ViewProps, ViewStyle } from 'react-native';
|
|
3
|
+
import { PickerOption } from '../../DatePicker.props';
|
|
4
|
+
interface Props {
|
|
5
|
+
value: number | string;
|
|
6
|
+
options: PickerOption[];
|
|
7
|
+
onChange: (index: number | string) => void;
|
|
8
|
+
selectedIndicatorStyle?: StyleProp<ViewStyle>;
|
|
9
|
+
itemStyle?: ViewStyle;
|
|
10
|
+
itemHeight?: number;
|
|
11
|
+
containerStyle?: ViewStyle;
|
|
12
|
+
containerProps?: Omit<ViewProps, 'style'>;
|
|
13
|
+
scaleFunction?: (x: number) => number;
|
|
14
|
+
rotationFunction?: (x: number) => number;
|
|
15
|
+
opacityFunction?: (x: number) => number;
|
|
16
|
+
visibleRest?: number;
|
|
17
|
+
decelerationRate?: 'normal' | 'fast' | number;
|
|
18
|
+
flatListProps?: Omit<FlatListProps<PickerOption | null>, 'data' | 'renderItem'>;
|
|
19
|
+
}
|
|
20
|
+
declare const _default: React.NamedExoticComponent<Props>;
|
|
21
|
+
export default _default;
|