@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.
Files changed (155) hide show
  1. package/.turbo/turbo-build.log +5 -4
  2. package/.turbo/turbo-lint.log +70 -69
  3. package/CHANGELOG.md +149 -0
  4. package/build/components/Button/ButtonRoot.js +8 -0
  5. package/build/components/Combobox/Combobox.context.d.ts +13 -0
  6. package/build/components/Combobox/Combobox.context.js +9 -0
  7. package/build/components/Combobox/Combobox.d.ts +6 -0
  8. package/build/components/Combobox/Combobox.js +246 -0
  9. package/build/components/Combobox/Combobox.props.d.ts +180 -0
  10. package/build/components/Combobox/Combobox.props.js +1 -0
  11. package/build/components/Combobox/ComboboxOption.d.ts +6 -0
  12. package/build/components/Combobox/ComboboxOption.js +56 -0
  13. package/build/components/Combobox/index.d.ts +4 -0
  14. package/build/components/Combobox/index.js +3 -0
  15. package/build/components/DatePicker/TimePicker.d.ts +3 -0
  16. package/build/components/DatePicker/TimePicker.js +84 -0
  17. package/build/components/DatePicker/time-picker/animated-math.d.ts +4 -0
  18. package/build/components/DatePicker/time-picker/animated-math.js +19 -0
  19. package/build/components/DatePicker/time-picker/period-native.d.ts +6 -0
  20. package/build/components/DatePicker/time-picker/period-native.js +17 -0
  21. package/build/components/DatePicker/time-picker/period-picker.d.ts +6 -0
  22. package/build/components/DatePicker/time-picker/period-picker.js +10 -0
  23. package/build/components/DatePicker/time-picker/period-web.d.ts +6 -0
  24. package/build/components/DatePicker/time-picker/period-web.js +21 -0
  25. package/build/components/DatePicker/time-picker/wheel-native.d.ts +8 -0
  26. package/build/components/DatePicker/time-picker/wheel-native.js +19 -0
  27. package/build/components/DatePicker/time-picker/wheel-picker/index.d.ts +2 -0
  28. package/build/components/DatePicker/time-picker/wheel-picker/index.js +2 -0
  29. package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker-item.d.ts +16 -0
  30. package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker-item.js +97 -0
  31. package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker.d.ts +21 -0
  32. package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker.js +88 -0
  33. package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker.style.d.ts +23 -0
  34. package/build/components/DatePicker/time-picker/wheel-picker/wheel-picker.style.js +21 -0
  35. package/build/components/DatePicker/time-picker/wheel-web.d.ts +8 -0
  36. package/build/components/DatePicker/time-picker/wheel-web.js +146 -0
  37. package/build/components/DatePicker/time-picker/wheel.d.ts +8 -0
  38. package/build/components/DatePicker/time-picker/wheel.js +10 -0
  39. package/build/components/List/List.js +2 -2
  40. package/build/components/Modal/Modal.js +31 -42
  41. package/build/components/Modal/Modal.web.js +3 -3
  42. package/build/components/Pagination/Pagination.d.ts +6 -0
  43. package/build/components/Pagination/Pagination.js +125 -0
  44. package/build/components/Pagination/Pagination.props.d.ts +26 -0
  45. package/build/components/Pagination/Pagination.props.js +1 -0
  46. package/build/components/Pagination/Pagination.utils.d.ts +2 -0
  47. package/build/components/Pagination/Pagination.utils.js +20 -0
  48. package/build/components/Pagination/Pagination.utils.test.d.ts +1 -0
  49. package/build/components/Pagination/Pagination.utils.test.js +16 -0
  50. package/build/components/Pagination/index.d.ts +2 -0
  51. package/build/components/Pagination/index.js +1 -0
  52. package/build/components/SafeAreaView/SafeAreaView.d.ts +5 -0
  53. package/build/components/SafeAreaView/SafeAreaView.js +117 -0
  54. package/build/components/SafeAreaView/SafeAreaView.props.d.ts +17 -0
  55. package/build/components/SafeAreaView/SafeAreaView.props.js +1 -0
  56. package/build/components/SafeAreaView/index.d.ts +2 -0
  57. package/build/components/SafeAreaView/index.js +1 -0
  58. package/build/components/Select/Select.d.ts +1 -1
  59. package/build/components/Select/Select.js +6 -5
  60. package/build/components/Select/Select.props.d.ts +4 -0
  61. package/build/components/Select/SelectOption.d.ts +1 -1
  62. package/build/components/Select/SelectOption.js +2 -2
  63. package/build/components/Table/Table.context.d.ts +12 -0
  64. package/build/components/Table/Table.context.js +9 -0
  65. package/build/components/Table/Table.d.ts +6 -0
  66. package/build/components/Table/Table.js +71 -0
  67. package/build/components/Table/Table.props.d.ts +56 -0
  68. package/build/components/Table/Table.props.js +1 -0
  69. package/build/components/Table/Table.utils.d.ts +5 -0
  70. package/build/components/Table/Table.utils.js +48 -0
  71. package/build/components/Table/Table.utils.test.d.ts +1 -0
  72. package/build/components/Table/Table.utils.test.js +71 -0
  73. package/build/components/Table/TableBody.d.ts +6 -0
  74. package/build/components/Table/TableBody.js +16 -0
  75. package/build/components/Table/TableCell.d.ts +10 -0
  76. package/build/components/Table/TableCell.js +44 -0
  77. package/build/components/Table/TableHeader.d.ts +6 -0
  78. package/build/components/Table/TableHeader.js +24 -0
  79. package/build/components/Table/TableHeaderCell.d.ts +10 -0
  80. package/build/components/Table/TableHeaderCell.js +97 -0
  81. package/build/components/Table/TablePagination.d.ts +6 -0
  82. package/build/components/Table/TablePagination.js +7 -0
  83. package/build/components/Table/TableRow.d.ts +8 -0
  84. package/build/components/Table/TableRow.js +25 -0
  85. package/build/components/Table/index.d.ts +8 -0
  86. package/build/components/Table/index.js +7 -0
  87. package/build/components/Timeline/Timeline.d.ts +6 -0
  88. package/build/components/Timeline/Timeline.js +34 -0
  89. package/build/components/Timeline/Timeline.props.d.ts +47 -0
  90. package/build/components/Timeline/Timeline.props.js +1 -0
  91. package/build/components/Timeline/TimelineItem.d.ts +6 -0
  92. package/build/components/Timeline/TimelineItem.js +235 -0
  93. package/build/components/Timeline/index.d.ts +3 -0
  94. package/build/components/Timeline/index.js +2 -0
  95. package/build/components/VerificationInput/VerificationInput.js +3 -3
  96. package/build/components/index.d.ts +5 -0
  97. package/build/components/index.js +5 -0
  98. package/build/tokens/components/dark/timeline.d.ts +2 -2
  99. package/build/tokens/components/dark/timeline.js +2 -2
  100. package/docs/components/AllComponents.web.tsx +106 -23
  101. package/docs/llm-docs/unistyles-llms-full.txt +1132 -534
  102. package/docs/llm-docs/unistyles-llms-small.txt +37 -37
  103. package/package.json +4 -4
  104. package/src/components/Button/Button.stories.tsx +43 -7
  105. package/src/components/Button/ButtonRoot.tsx +8 -0
  106. package/src/components/Combobox/Combobox.context.ts +26 -0
  107. package/src/components/Combobox/Combobox.docs.mdx +277 -0
  108. package/src/components/Combobox/Combobox.figma.tsx +60 -0
  109. package/src/components/Combobox/Combobox.props.ts +187 -0
  110. package/src/components/Combobox/Combobox.stories.tsx +233 -0
  111. package/src/components/Combobox/Combobox.tsx +446 -0
  112. package/src/components/Combobox/ComboboxOption.tsx +100 -0
  113. package/src/components/Combobox/index.ts +9 -0
  114. package/src/components/List/List.tsx +5 -4
  115. package/src/components/Modal/Modal.tsx +67 -74
  116. package/src/components/Modal/Modal.web.tsx +3 -3
  117. package/src/components/Pagination/Pagination.docs.mdx +99 -0
  118. package/src/components/Pagination/Pagination.figma.tsx +20 -0
  119. package/src/components/Pagination/Pagination.props.ts +28 -0
  120. package/src/components/Pagination/Pagination.stories.tsx +88 -0
  121. package/src/components/Pagination/Pagination.tsx +248 -0
  122. package/src/components/Pagination/Pagination.utils.test.ts +20 -0
  123. package/src/components/Pagination/Pagination.utils.ts +37 -0
  124. package/src/components/Pagination/index.ts +2 -0
  125. package/src/components/SafeAreaView/SafeAreaView.props.ts +20 -0
  126. package/src/components/SafeAreaView/SafeAreaView.tsx +173 -0
  127. package/src/components/SafeAreaView/index.ts +2 -0
  128. package/src/components/Select/Select.props.ts +4 -0
  129. package/src/components/Select/Select.tsx +35 -28
  130. package/src/components/Select/SelectOption.tsx +2 -0
  131. package/src/components/Table/Table.context.tsx +23 -0
  132. package/src/components/Table/Table.docs.mdx +239 -0
  133. package/src/components/Table/Table.figma.tsx +65 -0
  134. package/src/components/Table/Table.props.ts +65 -0
  135. package/src/components/Table/Table.stories.tsx +399 -0
  136. package/src/components/Table/Table.tsx +127 -0
  137. package/src/components/Table/Table.utils.test.ts +82 -0
  138. package/src/components/Table/Table.utils.ts +72 -0
  139. package/src/components/Table/TableBody.tsx +25 -0
  140. package/src/components/Table/TableCell.tsx +67 -0
  141. package/src/components/Table/TableHeader.tsx +41 -0
  142. package/src/components/Table/TableHeaderCell.tsx +136 -0
  143. package/src/components/Table/TablePagination.tsx +10 -0
  144. package/src/components/Table/TableRow.tsx +42 -0
  145. package/src/components/Table/index.ts +16 -0
  146. package/src/components/Timeline/Timeline.docs.mdx +177 -0
  147. package/src/components/Timeline/Timeline.figma.tsx +89 -0
  148. package/src/components/Timeline/Timeline.props.ts +51 -0
  149. package/src/components/Timeline/Timeline.stories.tsx +102 -0
  150. package/src/components/Timeline/Timeline.tsx +48 -0
  151. package/src/components/Timeline/TimelineItem.tsx +293 -0
  152. package/src/components/Timeline/index.ts +9 -0
  153. package/src/components/VerificationInput/VerificationInput.tsx +3 -0
  154. package/src/components/index.ts +5 -0
  155. package/src/tokens/components/dark/timeline.ts +2 -2
@@ -0,0 +1,88 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { memo, useEffect, useMemo, useRef, useState } from 'react';
3
+ import { Animated, Platform, View, } from 'react-native';
4
+ import WheelPickerItem from './wheel-picker-item';
5
+ import styles from './wheel-picker.style';
6
+ const WheelPicker = ({ value, options, onChange, selectedIndicatorStyle = {}, containerStyle = {}, itemStyle = {}, itemHeight = 40, scaleFunction = (x) => 1.0 ** x, rotationFunction = (x) => 1 - Math.pow(1 / 2, x), opacityFunction = (x) => Math.pow(1 / 3, x), visibleRest = 2, decelerationRate = 'normal', containerProps = {}, flatListProps = {}, }) => {
7
+ const momentumStarted = useRef(false);
8
+ const selectedIndex = options.findIndex(item => item.value === value);
9
+ const flatListRef = useRef(null);
10
+ const [scrollY] = useState(new Animated.Value(selectedIndex * itemHeight));
11
+ const containerHeight = (1 + visibleRest * 2) * itemHeight;
12
+ const paddedOptions = useMemo(() => {
13
+ const array = [...options];
14
+ for (let i = 0; i < visibleRest; i++) {
15
+ array.unshift(null);
16
+ array.push(null);
17
+ }
18
+ return array;
19
+ }, [options, visibleRest]);
20
+ const offsets = useMemo(() => [...Array(paddedOptions.length)].map((_, i) => i * itemHeight), [paddedOptions, itemHeight]);
21
+ const currentScrollIndex = useMemo(() => Animated.add(Animated.divide(scrollY, itemHeight), visibleRest), [visibleRest, scrollY, itemHeight]);
22
+ const handleScrollEnd = (event) => {
23
+ const offsetY = Math.min(itemHeight * (options.length - 1), Math.max(event.nativeEvent.contentOffset.y, 0));
24
+ let index = Math.floor(offsetY / itemHeight);
25
+ const remainder = offsetY % itemHeight;
26
+ if (remainder > itemHeight / 2) {
27
+ index++;
28
+ }
29
+ if (index !== selectedIndex) {
30
+ onChange(options[index]?.value || 0);
31
+ }
32
+ };
33
+ const handleMomentumScrollBegin = () => {
34
+ momentumStarted.current = true;
35
+ };
36
+ const handleMomentumScrollEnd = (event) => {
37
+ momentumStarted.current = false;
38
+ handleScrollEnd(event);
39
+ };
40
+ const handleScrollEndDrag = (event) => {
41
+ // Capture the offset value immediately
42
+ const offsetY = event.nativeEvent.contentOffset?.y;
43
+ // We'll start a short timer to see if momentum scroll begins
44
+ setTimeout(() => {
45
+ // If momentum scroll hasn't started within the timeout,
46
+ // then it was a slow scroll that won't trigger momentum
47
+ if (!momentumStarted.current && offsetY !== undefined) {
48
+ // Create a synthetic event with just the data we need
49
+ const syntheticEvent = {
50
+ nativeEvent: {
51
+ contentOffset: { y: offsetY },
52
+ },
53
+ };
54
+ handleScrollEnd(syntheticEvent);
55
+ }
56
+ }, 50);
57
+ };
58
+ useEffect(() => {
59
+ if (selectedIndex < 0 || selectedIndex >= options.length) {
60
+ throw new Error(`Selected index ${selectedIndex} is out of bounds [0, ${options.length - 1}]`);
61
+ }
62
+ }, [selectedIndex, options]);
63
+ /**
64
+ * If selectedIndex is changed from outside (not via onChange) we need to scroll to the specified index.
65
+ * This ensures that what the user sees as selected in the picker always corresponds to the value state.
66
+ */
67
+ useEffect(() => {
68
+ flatListRef.current?.scrollToIndex({
69
+ index: selectedIndex,
70
+ animated: Platform.OS === 'ios',
71
+ });
72
+ }, [selectedIndex, itemHeight]);
73
+ return (_jsxs(View, { style: [styles.container, { height: containerHeight }, containerStyle], ...containerProps, children: [_jsx(View, { style: [
74
+ styles.selectedIndicator,
75
+ selectedIndicatorStyle,
76
+ {
77
+ transform: [{ translateY: -itemHeight / 2 }],
78
+ height: itemHeight,
79
+ },
80
+ ] }), _jsx(Animated.FlatList, { ...flatListProps, ref: flatListRef, nestedScrollEnabled: true, style: styles.scrollView, showsVerticalScrollIndicator: false, onScroll: Animated.event([{ nativeEvent: { contentOffset: { y: scrollY } } }], {
81
+ useNativeDriver: true,
82
+ }), onScrollEndDrag: handleScrollEndDrag, onMomentumScrollBegin: handleMomentumScrollBegin, onMomentumScrollEnd: handleMomentumScrollEnd, snapToOffsets: offsets, decelerationRate: decelerationRate, initialScrollIndex: selectedIndex, getItemLayout: (_, index) => ({
83
+ length: itemHeight,
84
+ offset: itemHeight * index,
85
+ index,
86
+ }), data: paddedOptions, keyExtractor: (item, index) => item ? `${item.value}-${item.text}-${index}` : `null-${index}`, renderItem: ({ item: option, index }) => (_jsx(WheelPickerItem, { index: index, option: option, style: itemStyle, height: itemHeight, currentScrollIndex: currentScrollIndex, scaleFunction: scaleFunction, rotationFunction: rotationFunction, opacityFunction: opacityFunction, visibleRest: visibleRest }, `option-${index}`)) })] }));
87
+ };
88
+ export default memo(WheelPicker);
@@ -0,0 +1,23 @@
1
+ declare const _default: {
2
+ container: {
3
+ position: "relative";
4
+ };
5
+ selectedIndicator: {
6
+ position: "absolute";
7
+ width: "100%";
8
+ top: "50%";
9
+ };
10
+ scrollView: {
11
+ overflow: "hidden";
12
+ flex: number;
13
+ };
14
+ option: {
15
+ alignItems: "center";
16
+ justifyContent: "center";
17
+ paddingHorizontal: number;
18
+ zIndex: number;
19
+ };
20
+ } & {
21
+ useVariants: (variants: never) => void;
22
+ };
23
+ export default _default;
@@ -0,0 +1,21 @@
1
+ import { StyleSheet } from 'react-native-unistyles';
2
+ export default StyleSheet.create({
3
+ container: {
4
+ position: 'relative',
5
+ },
6
+ selectedIndicator: {
7
+ position: 'absolute',
8
+ width: '100%',
9
+ top: '50%',
10
+ },
11
+ scrollView: {
12
+ overflow: 'hidden',
13
+ flex: 1,
14
+ },
15
+ option: {
16
+ alignItems: 'center',
17
+ justifyContent: 'center',
18
+ paddingHorizontal: 16,
19
+ zIndex: 100,
20
+ },
21
+ });
@@ -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,146 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { memo, useMemo, useRef } from 'react';
3
+ import { Animated, PanResponder, Platform, View } from 'react-native';
4
+ import { StyleSheet } from 'react-native-unistyles';
5
+ import { isEqual } from '../../../utils';
6
+ import { BodyText } from '../../BodyText';
7
+ import { CONTAINER_HEIGHT } from '../enums';
8
+ import { sin } from './animated-math';
9
+ const ITEM_HEIGHT = 44;
10
+ const WheelWeb = ({ value, setValue = () => { }, items }) => {
11
+ const displayCount = 5;
12
+ const translateY = useRef(new Animated.Value(0)).current;
13
+ const renderCount = displayCount * 2 < items.length ? displayCount * 8 : displayCount * 2 - 1;
14
+ const circular = items.length >= displayCount;
15
+ const height = 140;
16
+ const radius = height / 2;
17
+ const valueIndex = useMemo(() => {
18
+ return Math.max(0, items.findIndex(item => item.value === value));
19
+ }, [items, value]);
20
+ const panResponder = useMemo(() => {
21
+ return PanResponder.create({
22
+ onMoveShouldSetPanResponder: () => true,
23
+ onStartShouldSetPanResponderCapture: () => true,
24
+ onPanResponderGrant: () => {
25
+ translateY.setValue(0);
26
+ },
27
+ onPanResponderMove: (evt, gestureState) => {
28
+ translateY.setValue(gestureState.dy);
29
+ evt.stopPropagation();
30
+ },
31
+ onPanResponderRelease: (_, gestureState) => {
32
+ translateY.extractOffset();
33
+ let newValueIndex = valueIndex - Math.round(gestureState.dy / ((radius * 2) / displayCount));
34
+ if (circular) {
35
+ newValueIndex = (newValueIndex + items.length) % items.length;
36
+ }
37
+ else {
38
+ if (newValueIndex < 0) {
39
+ newValueIndex = 0;
40
+ }
41
+ else if (newValueIndex >= items.length) {
42
+ newValueIndex = items.length - 1;
43
+ }
44
+ }
45
+ const newValue = items[newValueIndex];
46
+ if (newValue?.value === value) {
47
+ translateY.setOffset(0);
48
+ translateY.setValue(0);
49
+ }
50
+ else if (newValue?.value) {
51
+ setValue(newValue.value);
52
+ }
53
+ else if (items[0]?.value) {
54
+ setValue(items[0].value);
55
+ }
56
+ },
57
+ });
58
+ }, [circular, displayCount, radius, setValue, value, valueIndex, items, translateY]);
59
+ const displayValues = useMemo(() => {
60
+ const centerIndex = Math.floor(renderCount / 2);
61
+ return Array.from({ length: renderCount }, (_, index) => {
62
+ let targetIndex = valueIndex + index - centerIndex;
63
+ if (circular) {
64
+ targetIndex = ((targetIndex % items.length) + items.length) % items.length;
65
+ }
66
+ else {
67
+ targetIndex = Math.max(0, Math.min(targetIndex, items.length - 1));
68
+ }
69
+ return items[targetIndex] || items[0];
70
+ });
71
+ }, [renderCount, valueIndex, items, circular]);
72
+ const animatedAngles = useMemo(() => {
73
+ //translateY.setValue(0);
74
+ translateY.setOffset(0);
75
+ const currentIndex = displayValues.findIndex(item => item?.value === value);
76
+ return displayValues && displayValues.length > 0
77
+ ? displayValues.map((_, index) => translateY
78
+ .interpolate({
79
+ inputRange: [-radius, radius],
80
+ outputRange: [
81
+ -radius + ((radius * 2) / displayCount) * (index - currentIndex),
82
+ radius + ((radius * 2) / displayCount) * (index - currentIndex),
83
+ ],
84
+ extrapolate: 'extend',
85
+ })
86
+ .interpolate({
87
+ inputRange: [-radius, radius],
88
+ outputRange: [-Math.PI / 2, Math.PI / 2],
89
+ extrapolate: 'clamp',
90
+ }))
91
+ : [];
92
+ }, [displayValues, radius, value, displayCount, translateY]);
93
+ return (_jsxs(View, { style: [styles.container], ...panResponder.panHandlers, children: [_jsx(View, { style: [
94
+ styles.selectedIndicator,
95
+ {
96
+ transform: [{ translateY: -ITEM_HEIGHT / 2 }],
97
+ height: ITEM_HEIGHT,
98
+ },
99
+ ] }), displayValues?.map((displayValue, index) => {
100
+ const animatedAngle = animatedAngles[index];
101
+ return (_jsx(Animated.View, { style: {
102
+ position: 'absolute',
103
+ height: ITEM_HEIGHT - 10,
104
+ transform: animatedAngle
105
+ ? [
106
+ {
107
+ translateY: Animated.multiply(radius, sin(animatedAngle)),
108
+ },
109
+ {
110
+ rotateX: animatedAngle.interpolate({
111
+ inputRange: [-Math.PI / 2, Math.PI / 2],
112
+ outputRange: ['-89deg', '89deg'],
113
+ extrapolate: 'clamp',
114
+ }),
115
+ },
116
+ ]
117
+ : [],
118
+ opacity: displayValue?.value !== value ? 0.3 : 1,
119
+ }, children: _jsx(BodyText, { children: displayValue?.text }) }, `${displayValue?.text}-${index}`));
120
+ })] }));
121
+ };
122
+ const styles = StyleSheet.create({
123
+ container: {
124
+ minWidth: 30,
125
+ overflow: 'hidden',
126
+ alignItems: 'center',
127
+ justifyContent: 'center',
128
+ height: CONTAINER_HEIGHT / 2,
129
+ ...Platform.select({
130
+ web: {
131
+ cursor: 'pointer',
132
+ userSelect: 'none',
133
+ },
134
+ }),
135
+ },
136
+ selectedIndicator: {
137
+ position: 'absolute',
138
+ width: '100%',
139
+ top: '50%',
140
+ },
141
+ });
142
+ const customComparator = (prev, next) => {
143
+ const areEqual = prev.value === next.value && prev.setValue === next.setValue && isEqual(prev.items, next.items);
144
+ return areEqual;
145
+ };
146
+ export default memo(WheelWeb, customComparator);
@@ -0,0 +1,8 @@
1
+ import { PickerOption } from '../DatePicker.props';
2
+ type WheelProps = {
3
+ value: number | string;
4
+ setValue?: (value: any) => void;
5
+ items: PickerOption[];
6
+ };
7
+ declare const _default: import("react").MemoExoticComponent<(props: WheelProps) => import("react/jsx-runtime").JSX.Element>;
8
+ export default _default;
@@ -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 WheelNative from './wheel-native';
5
+ import WheelWeb from './wheel-web';
6
+ const Wheel = (props) => {
7
+ const Component = Platform.OS === 'web' ? WheelWeb : WheelNative;
8
+ return _jsx(Component, { ...props });
9
+ };
10
+ export default memo(Wheel);
@@ -6,7 +6,7 @@ import { Card } from '../Card';
6
6
  import { SectionHeader } from '../SectionHeader';
7
7
  import { ListContext } from './List.context';
8
8
  const List = ({ children, heading, helperText, headerTrailingContent, invalidText, ...props }) => {
9
- const { loading, disabled, container = 'none' } = props;
9
+ const { loading, disabled, container = 'none', testID, style, ...rest } = props;
10
10
  const orderRef = useRef([]);
11
11
  const [firstItemId, setFirstItemId] = useState(undefined);
12
12
  const containerToCard = {
@@ -35,7 +35,7 @@ const List = ({ children, heading, helperText, headerTrailingContent, invalidTex
35
35
  registerItem,
36
36
  };
37
37
  styles.useVariants({ disabled });
38
- return (_jsx(ListContext.Provider, { value: value, children: _jsxs(View, { ...props, style: [styles.container, props.style], children: [heading ? (_jsx(SectionHeader, { heading: heading, helperText: helperText, trailingContent: headerTrailingContent, invalidText: invalidText })) : null, container === 'none' ? (_jsx(View, { children: children })) : (React.Children.count(children) > 0 && (_jsx(Card, { ...containerToCard, noPadding: true, style: styles.card, children: _jsx(_Fragment, { children: children }) })))] }) }));
38
+ return (_jsx(ListContext.Provider, { value: value, children: _jsxs(View, { ...rest, style: [styles.container, style], children: [heading ? (_jsx(SectionHeader, { heading: heading, helperText: helperText, trailingContent: headerTrailingContent, invalidText: invalidText })) : null, container === 'none' ? (_jsx(View, { testID: testID, children: children })) : (React.Children.count(children) > 0 && (_jsx(Card, { ...containerToCard, noPadding: true, style: styles.card, testID: testID, children: _jsx(_Fragment, { children: children }) })))] }) }));
39
39
  };
40
40
  List.displayName = 'List';
41
41
  const styles = StyleSheet.create(theme => ({
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { BottomSheetFooter, } from '@gorhom/bottom-sheet';
3
3
  import { CloseMediumIcon } from '@utilitywarehouse/hearth-react-native-icons';
4
- import { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
5
- import { AccessibilityInfo, Dimensions, Platform, ScrollView, View, findNodeHandle } from 'react-native';
4
+ import { useCallback, useEffect, useImperativeHandle, useMemo, useRef } from 'react';
5
+ import { AccessibilityInfo, Platform, ScrollView, View, findNodeHandle } from 'react-native';
6
6
  import Animated, { Easing, useAnimatedStyle, useSharedValue, withDelay, withTiming, } from 'react-native-reanimated';
7
7
  import { StyleSheet } from 'react-native-unistyles';
8
8
  import { useTheme } from '../../hooks';
@@ -11,6 +11,7 @@ import { BodyText } from '../BodyText';
11
11
  import { BottomSheetModal, BottomSheetScrollView } from '../BottomSheet';
12
12
  import { Button } from '../Button';
13
13
  import { Heading } from '../Heading';
14
+ import { SafeAreaView } from '../SafeAreaView';
14
15
  import { Spinner } from '../Spinner';
15
16
  import { UnstyledIconButton } from '../UnstyledIconButton';
16
17
  const Modal = ({ ref, children, heading, description, showCloseButton = true, primaryButtonText, secondaryButtonText, onPressPrimaryButton, onPressCloseButton, onPressSecondaryButton, closeOnPrimaryButtonPress = true, closeOnSecondaryButtonPress = true, loading, loadingHeading = 'Loading...', fullscreen = false, image, primaryButtonProps, secondaryButtonProps, closeButtonProps, inNavModal = false, stickyFooter = true, background = 'default', scrollable = true, ...props }) => {
@@ -21,13 +22,6 @@ const Modal = ({ ref, children, heading, description, showCloseButton = true, pr
21
22
  const backgroundOpacity = useSharedValue(0);
22
23
  const pretendContentTranslateY = useSharedValue(20);
23
24
  const isBrandBackground = background === 'brand';
24
- const [inNavModalHeight, setInNavModalHeight] = useState();
25
- const isNavModalFullScreen = useMemo(() => {
26
- if (!inNavModalHeight || !inNavModal)
27
- return false;
28
- const screenHeight = Dimensions.get('window').height;
29
- return inNavModalHeight >= screenHeight;
30
- }, [inNavModalHeight, inNavModal]);
31
25
  const triggerCloseAnimation = useCallback(() => {
32
26
  if (Platform.OS === 'android' && inNavModal) {
33
27
  pretendContentTranslateY.value = withTiming(20, {
@@ -39,7 +33,7 @@ const Modal = ({ ref, children, heading, description, showCloseButton = true, pr
39
33
  easing: Easing.in(Easing.quad),
40
34
  });
41
35
  }
42
- }, [Platform.OS, inNavModal, pretendContentTranslateY, backgroundOpacity]);
36
+ }, [inNavModal, pretendContentTranslateY, backgroundOpacity]);
43
37
  useImperativeHandle(ref, () => ({
44
38
  ...bottomSheetModalRef.current,
45
39
  triggerCloseAnimation,
@@ -84,28 +78,28 @@ const Modal = ({ ref, children, heading, description, showCloseButton = true, pr
84
78
  }
85
79
  props.onChange?.(index, position, type);
86
80
  };
87
- const handleCloseButtonPress = () => {
81
+ const handleCloseButtonPress = useCallback(() => {
88
82
  bottomSheetModalRef.current?.dismiss();
89
83
  if (onPressCloseButton) {
90
84
  onPressCloseButton();
91
85
  }
92
- };
93
- const handlePrimaryButtonPress = () => {
86
+ }, [onPressCloseButton]);
87
+ const handlePrimaryButtonPress = useCallback(() => {
94
88
  if (onPressPrimaryButton) {
95
89
  onPressPrimaryButton();
96
90
  }
97
91
  if (closeOnPrimaryButtonPress) {
98
92
  bottomSheetModalRef.current?.dismiss();
99
93
  }
100
- };
101
- const handleSecondaryButtonPress = () => {
94
+ }, [closeOnPrimaryButtonPress, onPressPrimaryButton]);
95
+ const handleSecondaryButtonPress = useCallback(() => {
102
96
  if (onPressSecondaryButton) {
103
97
  onPressSecondaryButton();
104
98
  }
105
99
  if (closeOnSecondaryButtonPress) {
106
100
  bottomSheetModalRef.current?.dismiss();
107
101
  }
108
- };
102
+ }, [closeOnSecondaryButtonPress, onPressSecondaryButton]);
109
103
  const noButtons = !onPressPrimaryButton && !onPressSecondaryButton;
110
104
  styles.useVariants({
111
105
  loading,
@@ -114,27 +108,31 @@ const Modal = ({ ref, children, heading, description, showCloseButton = true, pr
114
108
  stickyFooter,
115
109
  showHandle: props.showHandle,
116
110
  background: isBrandBackground ? 'brand' : 'primary',
117
- ...(inNavModal && {
118
- fullscreen: isNavModalFullScreen,
119
- }),
120
111
  });
121
- const footer = (_jsxs(View, { style: styles.footer, children: [onPressPrimaryButton && primaryButtonText ? (_jsx(Button, { onPress: handlePrimaryButtonPress, text: primaryButtonText, inverted: isBrandBackground && inNavModal, ...primaryButtonProps, variant: primaryButtonProps?.variant ?? 'solid', colorScheme: primaryButtonProps?.colorScheme ?? 'highlight' })) : null, onPressSecondaryButton && secondaryButtonText ? (_jsx(Button, { onPress: handleSecondaryButtonPress, text: secondaryButtonText, inverted: isBrandBackground && inNavModal, ...secondaryButtonProps, variant: secondaryButtonProps?.variant ?? 'outline', colorScheme: secondaryButtonProps?.colorScheme ?? 'functional' })) : null] }));
122
- const InNavModalContainer = scrollable ? ScrollView : View;
123
- const content = (_jsx(_Fragment, { children: loading ? (_jsxs(View, { style: styles.loadingContainer, accessible: Platform.OS === 'android' ? true : undefined, accessibilityLabel: Platform.OS === 'android' ? 'Loading' : undefined, screenReaderFocusable: true, ref: viewRef, children: [_jsx(Spinner, { size: "lg", color: isBrandBackground && inNavModal ? theme.color.icon.inverted : undefined }), _jsx(Heading, { size: "lg", textAlign: "center", inverted: isBrandBackground && inNavModal, children: loadingHeading })] })) : (_jsxs(View, { style: styles.container, accessible: Platform.OS === 'android' ? true : undefined, accessibilityLabel: Platform.OS === 'android' ? 'Modal content' : undefined, screenReaderFocusable: true, ref: viewRef, children: [_jsxs(View, { style: styles.header, children: [_jsxs(View, { style: styles.headerTextContent, children: [heading && !image ? (_jsx(Heading, { size: "lg", accessible: true, inverted: isBrandBackground && inNavModal, children: heading })) : null, description && !image ? (_jsx(BodyText, { accessible: true, inverted: isBrandBackground && inNavModal, children: description })) : null] }), showCloseButton ? (_jsx(UnstyledIconButton, { icon: CloseMediumIcon, onPress: handleCloseButtonPress, accessibilityLabel: "Close modal", inverted: isBrandBackground && inNavModal, ...closeButtonProps })) : null] }), image ? (_jsxs(View, { style: styles.imageContainer, children: [image, _jsxs(View, { style: styles.textContent, children: [heading ? (_jsx(Heading, { size: "lg", textAlign: "center", accessible: true, inverted: isBrandBackground && inNavModal, children: heading })) : null, description ? (_jsx(BodyText, { textAlign: "center", accessible: true, inverted: isBrandBackground && inNavModal, children: description })) : null] })] })) : null, inNavModal && (_jsxs(InNavModalContainer, { style: { flex: stickyFooter ? 1 : 0 }, children: [children, !stickyFooter ? _jsx(View, { style: styles.inNavModalFooterContainer, children: footer }) : null] })), !inNavModal && children, ((!stickyFooter && !inNavModal) || (inNavModal && stickyFooter)) && !noButtons ? footer : null] })) }));
124
- const renderFooter = useCallback((props) => (_jsx(BottomSheetFooter, { ...props, children: _jsx(View, { style: styles.footerWrap, children: footer }) })), [
112
+ const footer = useMemo(() => (_jsxs(View, { style: styles.footer, children: [onPressPrimaryButton && primaryButtonText ? (_jsx(Button, { onPress: handlePrimaryButtonPress, text: primaryButtonText, inverted: isBrandBackground && inNavModal, ...primaryButtonProps, variant: primaryButtonProps?.variant ?? 'solid', colorScheme: primaryButtonProps?.colorScheme ?? 'highlight' })) : null, onPressSecondaryButton && secondaryButtonText ? (_jsx(Button, { onPress: handleSecondaryButtonPress, text: secondaryButtonText, inverted: isBrandBackground && inNavModal, ...secondaryButtonProps, variant: secondaryButtonProps?.variant ?? 'outline', colorScheme: secondaryButtonProps?.colorScheme ?? 'functional' })) : null] })), [
113
+ handlePrimaryButtonPress,
114
+ handleSecondaryButtonPress,
115
+ inNavModal,
116
+ isBrandBackground,
125
117
  onPressPrimaryButton,
126
- primaryButtonText,
127
118
  onPressSecondaryButton,
128
- secondaryButtonText,
129
119
  primaryButtonProps,
120
+ primaryButtonText,
130
121
  secondaryButtonProps,
122
+ secondaryButtonText,
131
123
  ]);
132
- return inNavModal ? (_jsxs(View, { onLayout: (e) => {
133
- setInNavModalHeight(e.nativeEvent.layout.height);
134
- }, style: {
124
+ const InNavModalContainer = scrollable ? ScrollView : View;
125
+ const content = (_jsx(_Fragment, { children: loading ? (_jsxs(View, { style: styles.loadingContainer, accessible: Platform.OS === 'android' ? true : undefined, accessibilityLabel: Platform.OS === 'android' ? 'Loading' : undefined, screenReaderFocusable: true, ref: viewRef, children: [_jsx(Spinner, { size: "lg", color: isBrandBackground && inNavModal ? theme.color.icon.inverted : undefined }), _jsx(Heading, { size: "lg", textAlign: "center", inverted: isBrandBackground && inNavModal, children: loadingHeading })] })) : (_jsxs(View, { style: styles.container, accessible: Platform.OS === 'android' ? true : undefined, accessibilityLabel: Platform.OS === 'android' ? 'Modal content' : undefined, screenReaderFocusable: true, ref: viewRef, children: [_jsxs(View, { style: styles.header, children: [_jsxs(View, { style: styles.headerTextContent, children: [heading && !image ? (_jsx(Heading, { size: "lg", accessible: true, inverted: isBrandBackground && inNavModal, children: heading })) : null, description && !image ? (_jsx(BodyText, { accessible: true, inverted: isBrandBackground && inNavModal, children: description })) : null] }), showCloseButton ? (_jsx(UnstyledIconButton, { icon: CloseMediumIcon, onPress: handleCloseButtonPress, accessibilityLabel: "Close modal", inverted: isBrandBackground && inNavModal, ...closeButtonProps })) : null] }), image ? (_jsxs(View, { style: styles.imageContainer, children: [image, _jsxs(View, { style: styles.textContent, children: [heading ? (_jsx(Heading, { size: "lg", textAlign: "center", accessible: true, inverted: isBrandBackground && inNavModal, children: heading })) : null, description ? (_jsx(BodyText, { textAlign: "center", accessible: true, inverted: isBrandBackground && inNavModal, children: description })) : null] })] })) : null, inNavModal && (_jsxs(InNavModalContainer, { style: {
126
+ flex: stickyFooter ? 1 : 0,
127
+ ...(scrollable ? { marginHorizontal: -1 } : {}),
128
+ }, ...(scrollable ? { contentContainerStyle: { paddingHorizontal: 1 } } : {}), children: [children, !stickyFooter ? (_jsx(View, { style: styles.inNavModalFooterContainer, children: footer })) : null] })), !inNavModal && children, ((!stickyFooter && !inNavModal) || (inNavModal && stickyFooter)) && !noButtons
129
+ ? footer
130
+ : null] })) }));
131
+ const renderFooter = useCallback((props) => (_jsx(BottomSheetFooter, { ...props, children: _jsx(View, { style: styles.footerWrap, children: footer }) })), [footer]);
132
+ return inNavModal ? (_jsxs(View, { style: {
135
133
  flex: 1,
136
134
  backgroundColor: theme.color.background[isBrandBackground ? 'brand' : 'primary'],
137
- }, children: [Platform.OS === 'android' ? (_jsx(Animated.View, { style: [styles.androidContainer, animatedBackgroundStyle], children: _jsx(Animated.View, { style: [styles.pretendContent, animatedPretendContentStyle] }) })) : null, _jsx(Animated.View, { style: [styles.inNavModalContainer, Platform.OS === 'android' && animatedInNavModalStyle], children: _jsx(View, { style: styles.inNavModalContent, children: content }) })] })) : (_jsxs(BottomSheetModal, { ref: bottomSheetModalRef, enableDynamicSizing: true, snapPoints: image || fullscreen ? ['90%'] : props.snapPoints, showHandle: typeof loading !== 'undefined' && loading ? false : props.showHandle, accessible: false, style: styles.modal, footerComponent: stickyFooter && !noButtons ? renderFooter : undefined, ...props, onChange: handleChange, children: [loading ? _jsx(View, { style: styles.loadingTop }) : null, _jsx(BottomSheetScrollView, { contentContainerStyle: styles.scrollView, ref: scrollViewRef, children: content })] }));
135
+ }, children: [Platform.OS === 'android' ? (_jsx(Animated.View, { style: [styles.androidContainer, animatedBackgroundStyle], children: _jsx(Animated.View, { style: [styles.pretendContent, animatedPretendContentStyle] }) })) : null, _jsx(Animated.View, { style: [styles.inNavModalContainer, Platform.OS === 'android' && animatedInNavModalStyle], children: _jsx(SafeAreaView, { edges: ['top', 'bottom'], style: styles.inNavModalContent, children: content }) })] })) : (_jsxs(BottomSheetModal, { ref: bottomSheetModalRef, enableDynamicSizing: true, snapPoints: image || fullscreen ? ['90%'] : props.snapPoints, showHandle: typeof loading !== 'undefined' && loading ? false : props.showHandle, accessible: false, style: styles.modal, footerComponent: stickyFooter && !noButtons ? renderFooter : undefined, ...props, onChange: handleChange, children: [loading ? _jsx(View, { style: styles.loadingTop }) : null, _jsx(BottomSheetScrollView, { contentContainerStyle: styles.scrollView, ref: scrollViewRef, children: content })] }));
138
136
  };
139
137
  const styles = StyleSheet.create((theme, rt) => ({
140
138
  modal: {
@@ -240,7 +238,7 @@ const styles = StyleSheet.create((theme, rt) => ({
240
238
  borderTopLeftRadius: theme.components.modal.borderRadius,
241
239
  borderTopRightRadius: theme.components.modal.borderRadius,
242
240
  backgroundColor: theme.color.surface.neutral.strong,
243
- paddingBottom: theme.components.modal.padding + rt.insets.bottom,
241
+ padding: theme.components.bottomSheet.padding,
244
242
  variants: {
245
243
  background: {
246
244
  primary: {},
@@ -248,24 +246,15 @@ const styles = StyleSheet.create((theme, rt) => ({
248
246
  backgroundColor: theme.color.background.brand,
249
247
  },
250
248
  },
251
- fullscreen: {
252
- true: {
253
- padding: theme.components.modal.padding,
254
- paddingTop: rt.insets.top,
255
- },
256
- false: {
257
- padding: theme.components.modal.padding,
258
- }
259
- }
260
249
  },
261
250
  },
262
251
  inNavModalFooterContainer: {
263
- paddingTop: theme.components.modal.padding,
252
+ paddingTop: theme.components.bottomSheet.padding,
264
253
  },
265
254
  androidContainer: {
266
255
  height: rt.insets.top + 18,
267
- paddingLeft: theme.components.modal.padding,
268
- paddingRight: theme.components.modal.padding,
256
+ paddingLeft: theme.components.bottomSheet.padding,
257
+ paddingRight: theme.components.bottomSheet.padding,
269
258
  justifyContent: 'flex-end',
270
259
  },
271
260
  pretendContent: {
@@ -141,13 +141,13 @@ const styles = StyleSheet.create((theme, rt) => ({
141
141
  borderTopRightRadius: theme.components.modal.borderRadius,
142
142
  backgroundColor: theme.color.surface.neutral.strong,
143
143
  gap: theme.components.modal.gap,
144
- padding: theme.components.modal.padding,
144
+ padding: theme.components.bottomSheet.padding,
145
145
  paddingBottom: theme.components.modal.padding + rt.insets.bottom,
146
146
  },
147
147
  androidContainer: {
148
148
  height: rt.insets.top + 18,
149
- paddingLeft: theme.components.modal.padding,
150
- paddingRight: theme.components.modal.padding,
149
+ paddingLeft: theme.components.bottomSheet.padding,
150
+ paddingRight: theme.components.bottomSheet.padding,
151
151
  justifyContent: 'flex-end',
152
152
  },
153
153
  pretendContent: {
@@ -0,0 +1,6 @@
1
+ import type PaginationProps from './Pagination.props';
2
+ declare const Pagination: {
3
+ ({ currentPage, totalPages, onPageChange, condensed, hideSkipButtons, style, ...props }: PaginationProps): import("react/jsx-runtime").JSX.Element;
4
+ displayName: string;
5
+ };
6
+ export default Pagination;
@@ -0,0 +1,125 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ChevronLeftSmallIcon, ChevronRightSmallIcon, SkipFirstSmallIcon, SkipLastSmallIcon, } from '@utilitywarehouse/hearth-react-native-icons';
3
+ import { useState } from 'react';
4
+ import { Pressable, View } from 'react-native';
5
+ import { StyleSheet } from 'react-native-unistyles';
6
+ import { BodyText } from '../BodyText';
7
+ import { UnstyledIconButton } from '../UnstyledIconButton';
8
+ import { ELLIPSIS, generatePageNumbers } from './Pagination.utils';
9
+ const PaginationItem = ({ label, selected = false, onPress }) => {
10
+ const [isFocused, setIsFocused] = useState(false);
11
+ styles.useVariants({ selected });
12
+ return (_jsx(Pressable, { accessibilityRole: "button", accessibilityLabel: `Go to page ${label}`, accessibilityState: { selected }, onBlur: () => setIsFocused(false), onFocus: () => setIsFocused(true), onPress: onPress, style: ({ pressed }) => [
13
+ styles.pageItem,
14
+ pressed && !selected && styles.pageItemPressed,
15
+ isFocused && styles.pageItemFocused,
16
+ ], children: _jsx(BodyText, { size: "md", style: styles.pageItemText, children: label }) }));
17
+ };
18
+ const PaginationArrowButton = ({ accessibilityLabel, disabled, icon, onPress, }) => {
19
+ return (_jsx(UnstyledIconButton, { accessibilityLabel: accessibilityLabel, disabled: disabled, icon: icon, onPress: onPress, size: "sm", style: styles.arrowButton }));
20
+ };
21
+ const Pagination = ({ currentPage, totalPages, onPageChange, condensed = false, hideSkipButtons = false, style, ...props }) => {
22
+ const pages = generatePageNumbers(currentPage, totalPages);
23
+ const handleFirst = () => {
24
+ if (currentPage !== 1) {
25
+ onPageChange(1);
26
+ }
27
+ };
28
+ const handlePrevious = () => {
29
+ if (currentPage > 1) {
30
+ onPageChange(currentPage - 1);
31
+ }
32
+ };
33
+ const handleNext = () => {
34
+ if (currentPage < totalPages) {
35
+ onPageChange(currentPage + 1);
36
+ }
37
+ };
38
+ const handleLast = () => {
39
+ if (currentPage !== totalPages) {
40
+ onPageChange(totalPages);
41
+ }
42
+ };
43
+ return (_jsxs(View, { accessibilityLabel: "Pagination", style: [styles.container, style], ...props, children: [_jsxs(View, { style: styles.controllers, children: [!hideSkipButtons ? (_jsx(PaginationArrowButton, { accessibilityLabel: "Go to first page", disabled: currentPage === 1, icon: SkipFirstSmallIcon, onPress: handleFirst })) : null, _jsx(PaginationArrowButton, { accessibilityLabel: "Go to previous page", disabled: currentPage === 1, icon: ChevronLeftSmallIcon, onPress: handlePrevious })] }), condensed ? (_jsxs(BodyText, { size: "md", children: ["Page ", currentPage, " of ", totalPages] })) : (_jsx(View, { style: styles.pages, children: pages.map((page, index) => {
44
+ if (page === ELLIPSIS) {
45
+ return (_jsx(BodyText, { size: "md", style: styles.ellipsis, children: ELLIPSIS }, `ellipsis-${index}`));
46
+ }
47
+ return (_jsx(PaginationItem, { label: page, onPress: () => onPageChange(page), selected: page === currentPage }, page));
48
+ }) })), _jsxs(View, { style: styles.controllers, children: [_jsx(PaginationArrowButton, { accessibilityLabel: "Go to next page", disabled: currentPage === totalPages, icon: ChevronRightSmallIcon, onPress: handleNext }), !hideSkipButtons ? (_jsx(PaginationArrowButton, { accessibilityLabel: "Go to last page", disabled: currentPage === totalPages, icon: SkipLastSmallIcon, onPress: handleLast })) : null] })] }));
49
+ };
50
+ PaginationItem.displayName = 'PaginationItem';
51
+ Pagination.displayName = 'Pagination';
52
+ const styles = StyleSheet.create(theme => ({
53
+ container: {
54
+ width: '100%',
55
+ minHeight: theme.components.pagination.item.height,
56
+ flexDirection: 'row',
57
+ alignItems: 'center',
58
+ justifyContent: 'space-between',
59
+ gap: theme.components.pagination.gap,
60
+ },
61
+ controllers: {
62
+ flexDirection: 'row',
63
+ alignItems: 'center',
64
+ gap: theme.components.pagination.gap,
65
+ },
66
+ arrowButton: {
67
+ width: theme.components.pagination.item.width,
68
+ height: theme.components.pagination.item.height,
69
+ },
70
+ pages: {
71
+ flex: 1,
72
+ flexDirection: 'row',
73
+ alignItems: 'center',
74
+ justifyContent: 'center',
75
+ flexWrap: 'wrap',
76
+ gap: theme.components.pagination.gap,
77
+ },
78
+ pageItem: {
79
+ width: theme.components.pagination.item.width,
80
+ height: theme.components.pagination.item.height,
81
+ borderRadius: theme.components.pagination.item.radius,
82
+ alignItems: 'center',
83
+ justifyContent: 'center',
84
+ backgroundColor: 'transparent',
85
+ _web: {
86
+ _hover: {
87
+ backgroundColor: theme.color.interactive.functional.surface.subtle.hover,
88
+ },
89
+ },
90
+ variants: {
91
+ selected: {
92
+ true: {
93
+ backgroundColor: theme.color.interactive.brand.surface.strong.default,
94
+ },
95
+ },
96
+ },
97
+ },
98
+ pageItemPressed: {
99
+ backgroundColor: theme.color.interactive.functional.surface.subtle.active,
100
+ },
101
+ pageItemFocused: {
102
+ outlineWidth: 2,
103
+ outlineOffset: -2,
104
+ outlineColor: theme.color.border.strong,
105
+ outlineStyle: 'solid',
106
+ },
107
+ pageItemText: {
108
+ variants: {
109
+ selected: {
110
+ true: {
111
+ color: theme.color.text.inverted,
112
+ },
113
+ false: {
114
+ color: theme.color.text.primary,
115
+ },
116
+ },
117
+ },
118
+ },
119
+ ellipsis: {
120
+ minWidth: theme.components.pagination.item.width,
121
+ textAlign: 'center',
122
+ color: theme.color.text.primary,
123
+ },
124
+ }));
125
+ export default Pagination;