cpk-ui 0.5.5 → 0.7.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/README.md +80 -147
- package/components/modals/AlertDialog/AlertDialog.d.ts.map +1 -1
- package/components/modals/AlertDialog/AlertDialog.js +14 -7
- package/components/modals/Snackbar/Snackbar.d.ts.map +1 -1
- package/components/modals/Snackbar/Snackbar.js +20 -17
- package/components/uis/Accordion/AccordionItem.d.ts.map +1 -1
- package/components/uis/Accordion/AccordionItem.js +41 -17
- package/components/uis/Button/Button.d.ts.map +1 -1
- package/components/uis/Button/Button.js +10 -10
- package/components/uis/Card/Card.d.ts +2 -1
- package/components/uis/Card/Card.d.ts.map +1 -1
- package/components/uis/Card/Card.js +12 -3
- package/components/uis/Checkbox/Checkbox.d.ts.map +1 -1
- package/components/uis/Checkbox/Checkbox.js +1 -1
- package/components/uis/CustomPressable/CustomPressable.d.ts.map +1 -1
- package/components/uis/CustomPressable/CustomPressable.js +6 -6
- package/components/uis/EditText/EditText.d.ts.map +1 -1
- package/components/uis/EditText/EditText.js +17 -12
- package/components/uis/Fab/Fab.d.ts +2 -2
- package/components/uis/Fab/Fab.d.ts.map +1 -1
- package/components/uis/Fab/Fab.js +22 -4
- package/components/uis/Icon/Icon.d.ts.map +1 -1
- package/components/uis/Icon/Icon.js +6 -3
- package/components/uis/IconButton/IconButton.d.ts.map +1 -1
- package/components/uis/IconButton/IconButton.js +43 -41
- package/components/uis/LoadingIndicator/LoadingIndicator.d.ts +2 -1
- package/components/uis/LoadingIndicator/LoadingIndicator.d.ts.map +1 -1
- package/components/uis/LoadingIndicator/LoadingIndicator.js +4 -4
- package/components/uis/RadioGroup/RadioButton.d.ts.map +1 -1
- package/components/uis/RadioGroup/RadioButton.js +1 -1
- package/components/uis/RadioGroup/RadioGroup.d.ts.map +1 -1
- package/components/uis/RadioGroup/RadioGroup.js +16 -3
- package/components/uis/Rating/Rating.d.ts.map +1 -1
- package/components/uis/Rating/Rating.js +23 -19
- package/components/uis/SegmentedControl/SegmentedControl.d.ts.map +1 -1
- package/components/uis/SegmentedControl/SegmentedControl.js +1 -1
- package/components/uis/StatusbarBrightness/StatusBarBrightness.d.ts +2 -2
- package/components/uis/StatusbarBrightness/StatusBarBrightness.d.ts.map +1 -1
- package/components/uis/StatusbarBrightness/StatusBarBrightness.js +1 -1
- package/components/uis/SwitchToggle/SwitchToggle.d.ts.map +1 -1
- package/components/uis/SwitchToggle/SwitchToggle.js +1 -1
- package/hooks/useHoverState.d.ts +8 -0
- package/hooks/useHoverState.d.ts.map +1 -0
- package/hooks/useHoverState.js +16 -0
- package/package.json +18 -6
- package/providers/ThemeProvider.d.ts.map +1 -1
- package/providers/ThemeProvider.js +0 -1
- package/providers/index.d.ts.map +1 -1
- package/providers/index.js +3 -2
- package/components/uis/Icon/selection.json +0 -1
- package/src/components/common/ErrorBoundary/ErrorBoundary.tsx +0 -75
- package/src/components/modals/AlertDialog/AlertDialog.stories.tsx +0 -216
- package/src/components/modals/AlertDialog/AlertDialog.test.tsx +0 -251
- package/src/components/modals/AlertDialog/AlertDialog.tsx +0 -356
- package/src/components/modals/Snackbar/Snackbar.stories.tsx +0 -182
- package/src/components/modals/Snackbar/Snackbar.test.tsx +0 -319
- package/src/components/modals/Snackbar/Snackbar.tsx +0 -260
- package/src/components/modals/Snackbar/const.ts +0 -4
- package/src/components/uis/Accordion/Accordion.stories.tsx +0 -167
- package/src/components/uis/Accordion/Accordion.test.tsx +0 -272
- package/src/components/uis/Accordion/Accordion.tsx +0 -109
- package/src/components/uis/Accordion/AccordionItem.tsx +0 -306
- package/src/components/uis/Button/Button.stories.tsx +0 -218
- package/src/components/uis/Button/Button.test.tsx +0 -694
- package/src/components/uis/Button/Button.tsx +0 -440
- package/src/components/uis/Card/Card.test.tsx +0 -146
- package/src/components/uis/Card/Card.tsx +0 -102
- package/src/components/uis/Checkbox/Checkbox.stories.tsx +0 -216
- package/src/components/uis/Checkbox/Checkbox.test.tsx +0 -267
- package/src/components/uis/Checkbox/Checkbox.tsx +0 -225
- package/src/components/uis/CustomPressable/CustomPressable.tsx +0 -48
- package/src/components/uis/EditText/EditText.stories.tsx +0 -124
- package/src/components/uis/EditText/EditText.test.tsx +0 -477
- package/src/components/uis/EditText/EditText.tsx +0 -593
- package/src/components/uis/Fab/Fab.stories.tsx +0 -133
- package/src/components/uis/Fab/Fab.test.tsx +0 -110
- package/src/components/uis/Fab/Fab.tsx +0 -168
- package/src/components/uis/Hr/Hr.test.tsx +0 -26
- package/src/components/uis/Hr/Hr.tsx +0 -19
- package/src/components/uis/Icon/Icon.stories.tsx +0 -98
- package/src/components/uis/Icon/Icon.test.tsx +0 -49
- package/src/components/uis/Icon/Icon.tsx +0 -3819
- package/src/components/uis/IconButton/IconButton.test.tsx +0 -204
- package/src/components/uis/IconButton/IconButton.tsx +0 -279
- package/src/components/uis/LoadingIndicator/LoadingIndicator.tsx +0 -126
- package/src/components/uis/LoadingIndicator/LodingIndicator.stories.tsx +0 -81
- package/src/components/uis/PinchZoom/PinchZoom.stories.tsx +0 -266
- package/src/components/uis/PinchZoom/PinchZoom.test.tsx +0 -113
- package/src/components/uis/PinchZoom/PinchZoom.tsx +0 -424
- package/src/components/uis/RadioGroup/RadioButton.tsx +0 -193
- package/src/components/uis/RadioGroup/RadioGroup.stories.tsx +0 -188
- package/src/components/uis/RadioGroup/RadioGroup.test.tsx +0 -354
- package/src/components/uis/RadioGroup/RadioGroup.tsx +0 -109
- package/src/components/uis/Rating/Rating.test.tsx +0 -98
- package/src/components/uis/Rating/Rating.tsx +0 -200
- package/src/components/uis/SegmentedControl/SegmentedControl.stories.tsx +0 -546
- package/src/components/uis/SegmentedControl/SegmentedControl.test.tsx +0 -274
- package/src/components/uis/SegmentedControl/SegmentedControl.tsx +0 -232
- package/src/components/uis/StatusbarBrightness/StatusBarBrightness.test.tsx +0 -41
- package/src/components/uis/StatusbarBrightness/StatusBarBrightness.tsx +0 -26
- package/src/components/uis/Styled/StyledComponents.tsx +0 -217
- package/src/components/uis/SwitchToggle/SwitchToggle.stories.tsx +0 -75
- package/src/components/uis/SwitchToggle/SwitchToggle.test.tsx +0 -149
- package/src/components/uis/SwitchToggle/SwitchToggle.tsx +0 -309
- package/src/components/uis/Typography/Typography.stories.tsx +0 -149
- package/src/components/uis/Typography/Typography.test.tsx +0 -58
- package/src/components/uis/Typography/Typography.tsx +0 -386
- package/src/hooks/index.ts +0 -2
- package/src/hooks/useAnimations.ts +0 -71
- package/src/hooks/useDebouncedColorScheme.tsx +0 -30
- package/src/hooks/useOptimizedStyles.ts +0 -22
- package/src/hooks/usePerformance.ts +0 -93
- package/src/index.tsx +0 -38
- package/src/providers/ThemeProvider.tsx +0 -177
- package/src/providers/index.tsx +0 -130
- package/src/test/testUtils.tsx +0 -101
- package/src/types/common.ts +0 -77
- package/src/types/index.ts +0 -1
- package/src/types/kstyled.d.ts +0 -6
- package/src/utils/accessibility.ts +0 -110
- package/src/utils/colors.ts +0 -151
- package/src/utils/createCtx.tsx +0 -26
- package/src/utils/guards.ts +0 -93
- package/src/utils/index.ts +0 -2
- package/src/utils/performanceTest.ts +0 -174
- package/src/utils/platform.ts +0 -69
- package/src/utils/theme.ts +0 -38
- package/test/testUtils.d.ts +0 -113
- package/test/testUtils.d.ts.map +0 -1
- package/test/testUtils.js +0 -65
|
@@ -1,306 +0,0 @@
|
|
|
1
|
-
// Caveat: Expo web needs React to be imported
|
|
2
|
-
import React, {useCallback, useEffect, useMemo, useRef, useState, type ReactElement} from 'react';
|
|
3
|
-
import type {LayoutChangeEvent} from 'react-native';
|
|
4
|
-
import {Animated, Easing, TouchableOpacity, View} from 'react-native';
|
|
5
|
-
import {styled, css} from 'kstyled';
|
|
6
|
-
|
|
7
|
-
import {Icon} from '../Icon/Icon';
|
|
8
|
-
import {Typography} from '../Typography/Typography';
|
|
9
|
-
|
|
10
|
-
import type {AccordionBaseProps} from './Accordion';
|
|
11
|
-
|
|
12
|
-
import type {AccordionSizeType} from './Accordion';
|
|
13
|
-
|
|
14
|
-
const TitleTouch = styled(TouchableOpacity)<{$size?: AccordionSizeType}>`
|
|
15
|
-
height: ${({$size = 'medium'}) => {
|
|
16
|
-
if (typeof $size === 'number') return $size * 2.4;
|
|
17
|
-
return $size === 'small' ? 40 : $size === 'large' ? 56 : 48;
|
|
18
|
-
}};
|
|
19
|
-
background-color: ${({theme}) => theme.bg.basic};
|
|
20
|
-
|
|
21
|
-
flex-direction: row;
|
|
22
|
-
align-items: center;
|
|
23
|
-
padding-top: ${({$size = 'medium'}) => {
|
|
24
|
-
if (typeof $size === 'number') return $size * 0.4;
|
|
25
|
-
return $size === 'small' ? 6 : $size === 'large' ? 10 : 8;
|
|
26
|
-
}};
|
|
27
|
-
padding-bottom: ${({$size = 'medium'}) => {
|
|
28
|
-
if (typeof $size === 'number') return $size * 0.4;
|
|
29
|
-
return $size === 'small' ? 6 : $size === 'large' ? 10 : 8;
|
|
30
|
-
}};
|
|
31
|
-
padding-left: ${({$size = 'medium'}) => {
|
|
32
|
-
if (typeof $size === 'number') return $size * 0.6;
|
|
33
|
-
return $size === 'small' ? 10 : $size === 'large' ? 14 : 12;
|
|
34
|
-
}};
|
|
35
|
-
padding-right: ${({$size = 'medium'}) => {
|
|
36
|
-
if (typeof $size === 'number') return $size * 0.6;
|
|
37
|
-
return $size === 'small' ? 10 : $size === 'large' ? 14 : 12;
|
|
38
|
-
}};
|
|
39
|
-
`;
|
|
40
|
-
|
|
41
|
-
const StyledIcon = styled(Icon)<{$size?: AccordionSizeType}>`
|
|
42
|
-
color: ${({theme}) => theme.text.basic};
|
|
43
|
-
font-weight: bold;
|
|
44
|
-
font-size: ${({$size = 'medium'}) => {
|
|
45
|
-
if (typeof $size === 'number') return $size * 0.7;
|
|
46
|
-
return $size === 'small' ? 12 : $size === 'large' ? 16 : 14;
|
|
47
|
-
}};
|
|
48
|
-
`;
|
|
49
|
-
|
|
50
|
-
const ItemTouch = styled(TouchableOpacity)<{$size?: AccordionSizeType}>`
|
|
51
|
-
background-color: ${({theme}) => theme.bg.paper};
|
|
52
|
-
padding-top: ${({$size = 'medium'}) => {
|
|
53
|
-
if (typeof $size === 'number') return $size * 0.4;
|
|
54
|
-
return $size === 'small' ? 6 : $size === 'large' ? 10 : 8;
|
|
55
|
-
}};
|
|
56
|
-
padding-bottom: ${({$size = 'medium'}) => {
|
|
57
|
-
if (typeof $size === 'number') return $size * 0.4;
|
|
58
|
-
return $size === 'small' ? 6 : $size === 'large' ? 10 : 8;
|
|
59
|
-
}};
|
|
60
|
-
padding-left: ${({$size = 'medium'}) => {
|
|
61
|
-
if (typeof $size === 'number') return $size * 0.6;
|
|
62
|
-
return $size === 'small' ? 10 : $size === 'large' ? 14 : 12;
|
|
63
|
-
}};
|
|
64
|
-
padding-right: ${({$size = 'medium'}) => {
|
|
65
|
-
if (typeof $size === 'number') return $size * 0.6;
|
|
66
|
-
return $size === 'small' ? 10 : $size === 'large' ? 14 : 12;
|
|
67
|
-
}};
|
|
68
|
-
|
|
69
|
-
flex-direction: row;
|
|
70
|
-
align-items: center;
|
|
71
|
-
`;
|
|
72
|
-
|
|
73
|
-
export type AccordionItemDataType<T, K> = {
|
|
74
|
-
title: T;
|
|
75
|
-
items: K[];
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
type Props<T, K> = Omit<AccordionBaseProps<T, K>, 'data' | 'style'> & {
|
|
79
|
-
testID: string;
|
|
80
|
-
data: AccordionItemDataType<string, string> | AccordionItemDataType<T, K>;
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
export function AccordionItem<T, K>({
|
|
84
|
-
testID,
|
|
85
|
-
data: data,
|
|
86
|
-
size = 'medium',
|
|
87
|
-
shouldAnimate = true,
|
|
88
|
-
collapseOnStart = true,
|
|
89
|
-
animDuration = 200,
|
|
90
|
-
activeOpacity = 1,
|
|
91
|
-
toggleElement,
|
|
92
|
-
toggleElementPosition,
|
|
93
|
-
onPressItem,
|
|
94
|
-
renderTitle,
|
|
95
|
-
renderItem,
|
|
96
|
-
styles,
|
|
97
|
-
}: Props<T, K>): ReactElement {
|
|
98
|
-
// Calculate icon size based on accordion size
|
|
99
|
-
const iconSize = typeof size === 'number'
|
|
100
|
-
? size * 0.7
|
|
101
|
-
: size === 'small' ? 12 : size === 'large' ? 16 : 14;
|
|
102
|
-
|
|
103
|
-
const defaultToggleElement = <StyledIcon name="CaretDown" $size={size} size={iconSize} />;
|
|
104
|
-
const dropDownAnimValueRef = useRef(new Animated.Value(0));
|
|
105
|
-
const rotateAnimValueRef = useRef(new Animated.Value(0));
|
|
106
|
-
const fadeItemAnim = useRef(new Animated.Value(0)).current;
|
|
107
|
-
const [itemHeight, setItemHeight] = useState(0);
|
|
108
|
-
const [collapsed, setCollapsed] = useState(collapseOnStart);
|
|
109
|
-
|
|
110
|
-
// Memoize animation configuration
|
|
111
|
-
const animationConfig = useMemo(() => ({
|
|
112
|
-
duration: animDuration,
|
|
113
|
-
easing: Easing.linear,
|
|
114
|
-
useNativeDriver: false,
|
|
115
|
-
}), [animDuration]);
|
|
116
|
-
|
|
117
|
-
useEffect(() => {
|
|
118
|
-
Animated.timing(fadeItemAnim, {
|
|
119
|
-
toValue: collapsed ? 0 : 1,
|
|
120
|
-
duration: !collapsed ? 300 : 100,
|
|
121
|
-
useNativeDriver: false,
|
|
122
|
-
}).start();
|
|
123
|
-
}, [fadeItemAnim, collapsed]);
|
|
124
|
-
|
|
125
|
-
useEffect(() => {
|
|
126
|
-
const targetValue = collapsed ? 0 : 1;
|
|
127
|
-
|
|
128
|
-
if (!shouldAnimate) {
|
|
129
|
-
rotateAnimValueRef.current.setValue(targetValue);
|
|
130
|
-
dropDownAnimValueRef.current.setValue(targetValue);
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const config = {
|
|
135
|
-
...animationConfig,
|
|
136
|
-
toValue: targetValue,
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
Animated.parallel([
|
|
140
|
-
Animated.timing(rotateAnimValueRef.current, config),
|
|
141
|
-
Animated.timing(dropDownAnimValueRef.current, config),
|
|
142
|
-
]).start();
|
|
143
|
-
}, [collapsed, shouldAnimate, animationConfig]);
|
|
144
|
-
|
|
145
|
-
// Memoize callbacks
|
|
146
|
-
const handleToggle = useCallback(() => {
|
|
147
|
-
setCollapsed(!collapsed);
|
|
148
|
-
}, [collapsed]);
|
|
149
|
-
|
|
150
|
-
const handleItemPress = useCallback((body: K | string) => {
|
|
151
|
-
onPressItem?.(data.title, body);
|
|
152
|
-
}, [onPressItem, data.title]);
|
|
153
|
-
|
|
154
|
-
const handleLayout = useCallback((e: LayoutChangeEvent) => {
|
|
155
|
-
setItemHeight(e.nativeEvent.layout.height);
|
|
156
|
-
}, []);
|
|
157
|
-
|
|
158
|
-
// Calculate margin based on size
|
|
159
|
-
const toggleMargin = typeof size === 'number'
|
|
160
|
-
? size * 0.6
|
|
161
|
-
: size === 'small' ? 10 : size === 'large' ? 14 : 12;
|
|
162
|
-
|
|
163
|
-
// Memoize toggle element container
|
|
164
|
-
const toggleElContainer = useMemo(() => (
|
|
165
|
-
<Animated.View
|
|
166
|
-
style={[
|
|
167
|
-
css`
|
|
168
|
-
margin-right: ${toggleElementPosition === 'left' ? toggleMargin : 0}px;
|
|
169
|
-
`,
|
|
170
|
-
{
|
|
171
|
-
transform: [
|
|
172
|
-
{
|
|
173
|
-
rotate: rotateAnimValueRef.current.interpolate({
|
|
174
|
-
inputRange: [0, 1],
|
|
175
|
-
outputRange: ['0deg', '180deg'],
|
|
176
|
-
}),
|
|
177
|
-
},
|
|
178
|
-
],
|
|
179
|
-
},
|
|
180
|
-
styles?.toggleElement,
|
|
181
|
-
]}
|
|
182
|
-
>
|
|
183
|
-
{toggleElement || defaultToggleElement}
|
|
184
|
-
</Animated.View>
|
|
185
|
-
), [toggleElement, defaultToggleElement, toggleElementPosition, toggleMargin, styles?.toggleElement]);
|
|
186
|
-
|
|
187
|
-
// Memoize container styles
|
|
188
|
-
const containerStyles = useMemo(() => [
|
|
189
|
-
css`
|
|
190
|
-
background-color: transparent;
|
|
191
|
-
overflow: hidden;
|
|
192
|
-
flex-direction: column-reverse;
|
|
193
|
-
`,
|
|
194
|
-
styles?.container,
|
|
195
|
-
], [styles?.container]);
|
|
196
|
-
|
|
197
|
-
const titleContainerStyles = useMemo(() => [
|
|
198
|
-
css`
|
|
199
|
-
justify-content: ${toggleElementPosition === 'right'
|
|
200
|
-
? 'space-between'
|
|
201
|
-
: 'flex-start'};
|
|
202
|
-
`,
|
|
203
|
-
styles?.titleContainer,
|
|
204
|
-
], [toggleElementPosition, styles?.titleContainer]);
|
|
205
|
-
|
|
206
|
-
// Memoize animated styles
|
|
207
|
-
const animatedItemStyles = useMemo(() => [
|
|
208
|
-
{
|
|
209
|
-
opacity: fadeItemAnim,
|
|
210
|
-
height: dropDownAnimValueRef.current.interpolate({
|
|
211
|
-
inputRange: [0, 1],
|
|
212
|
-
outputRange: [0, itemHeight],
|
|
213
|
-
}),
|
|
214
|
-
},
|
|
215
|
-
], [fadeItemAnim, itemHeight]);
|
|
216
|
-
|
|
217
|
-
// Calculate font sizes based on size prop
|
|
218
|
-
const titleFontSize = typeof size === 'number'
|
|
219
|
-
? size
|
|
220
|
-
: size === 'small' ? 14 : size === 'large' ? 18 : 16;
|
|
221
|
-
|
|
222
|
-
const itemFontSize = typeof size === 'number'
|
|
223
|
-
? size * 0.875
|
|
224
|
-
: size === 'small' ? 12 : size === 'large' ? 16 : 14;
|
|
225
|
-
|
|
226
|
-
return (
|
|
227
|
-
<Animated.View style={containerStyles}>
|
|
228
|
-
{/* Invisible: Place it at the top for z-index */}
|
|
229
|
-
<View
|
|
230
|
-
onLayout={handleLayout}
|
|
231
|
-
style={css`
|
|
232
|
-
position: absolute;
|
|
233
|
-
opacity: 0;
|
|
234
|
-
`}
|
|
235
|
-
>
|
|
236
|
-
{data.items.map((body, index) => (
|
|
237
|
-
<ItemTouch
|
|
238
|
-
activeOpacity={activeOpacity}
|
|
239
|
-
key={`body-${index}`}
|
|
240
|
-
onPress={() => handleItemPress(body)}
|
|
241
|
-
$size={size}
|
|
242
|
-
>
|
|
243
|
-
{typeof body === 'string' && !renderItem ? (
|
|
244
|
-
<Typography.Body3 style={[{fontSize: itemFontSize}, styles?.itemText]}>
|
|
245
|
-
{body}
|
|
246
|
-
</Typography.Body3>
|
|
247
|
-
) : (
|
|
248
|
-
renderItem?.(body as K)
|
|
249
|
-
)}
|
|
250
|
-
</ItemTouch>
|
|
251
|
-
))}
|
|
252
|
-
</View>
|
|
253
|
-
|
|
254
|
-
{/* Item */}
|
|
255
|
-
<Animated.View
|
|
256
|
-
accessibilityState={{expanded: !collapsed}}
|
|
257
|
-
style={animatedItemStyles}
|
|
258
|
-
testID={`body-${testID}`}
|
|
259
|
-
>
|
|
260
|
-
{data.items.map((body, index) => (
|
|
261
|
-
<ItemTouch
|
|
262
|
-
activeOpacity={activeOpacity}
|
|
263
|
-
key={`body-${index}`}
|
|
264
|
-
onPress={() => handleItemPress(body)}
|
|
265
|
-
style={styles?.itemContainer}
|
|
266
|
-
$size={size}
|
|
267
|
-
>
|
|
268
|
-
{typeof body === 'string' && !renderItem ? (
|
|
269
|
-
<Typography.Body3 style={[{fontSize: itemFontSize}, styles?.itemText]}>
|
|
270
|
-
{body}
|
|
271
|
-
</Typography.Body3>
|
|
272
|
-
) : (
|
|
273
|
-
renderItem?.(body as K)
|
|
274
|
-
)}
|
|
275
|
-
</ItemTouch>
|
|
276
|
-
))}
|
|
277
|
-
</Animated.View>
|
|
278
|
-
|
|
279
|
-
{/* Title */}
|
|
280
|
-
<TitleTouch
|
|
281
|
-
activeOpacity={activeOpacity}
|
|
282
|
-
onPress={handleToggle}
|
|
283
|
-
accessibilityRole="button"
|
|
284
|
-
accessibilityLabel={typeof data.title === 'string' ? data.title : 'Accordion section'}
|
|
285
|
-
accessibilityState={{expanded: !collapsed}}
|
|
286
|
-
accessibilityHint={collapsed ? 'Double tap to expand' : 'Double tap to collapse'}
|
|
287
|
-
style={titleContainerStyles}
|
|
288
|
-
testID={`title-${testID}`}
|
|
289
|
-
$size={size}
|
|
290
|
-
>
|
|
291
|
-
{toggleElementPosition === 'left' ? toggleElContainer : null}
|
|
292
|
-
{typeof data.title === 'string' && !renderTitle ? (
|
|
293
|
-
<Typography.Heading4 style={[{fontSize: titleFontSize}, styles?.titleText]}>
|
|
294
|
-
{data.title}
|
|
295
|
-
</Typography.Heading4>
|
|
296
|
-
) : (
|
|
297
|
-
renderTitle?.(data.title as T)
|
|
298
|
-
)}
|
|
299
|
-
{toggleElementPosition === 'right' ? toggleElContainer : null}
|
|
300
|
-
</TitleTouch>
|
|
301
|
-
</Animated.View>
|
|
302
|
-
);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// Export memoized component for better performance
|
|
306
|
-
export default React.memo(AccordionItem) as typeof AccordionItem;
|
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
import {action} from '@storybook/addon-actions';
|
|
2
|
-
import type {Meta, StoryObj} from '@storybook/react';
|
|
3
|
-
|
|
4
|
-
import {withThemeProvider} from '../../../../.storybook/decorators';
|
|
5
|
-
|
|
6
|
-
import type {ButtonColorType, ButtonSizeType, ButtonType} from './Button';
|
|
7
|
-
import {Button} from './Button';
|
|
8
|
-
import {ThemeParam} from '../../../utils/theme';
|
|
9
|
-
|
|
10
|
-
const buttonTypes: ButtonType[] = ['outlined', 'solid', 'text'];
|
|
11
|
-
const buttonSizes: ButtonSizeType[] = ['large', 'medium', 'small'];
|
|
12
|
-
|
|
13
|
-
const buttonColors: ButtonColorType[] = [
|
|
14
|
-
'primary',
|
|
15
|
-
'success',
|
|
16
|
-
'info',
|
|
17
|
-
'warning',
|
|
18
|
-
'danger',
|
|
19
|
-
'light',
|
|
20
|
-
'secondary',
|
|
21
|
-
];
|
|
22
|
-
|
|
23
|
-
const meta = {
|
|
24
|
-
title: 'Button',
|
|
25
|
-
component: Button,
|
|
26
|
-
parameters: {
|
|
27
|
-
notes: `
|
|
28
|
-
A versatile Button component with multiple variants, sizes, and customization options.
|
|
29
|
-
|
|
30
|
-
## Features
|
|
31
|
-
- **Three Button Types**: Solid, outlined, and text buttons
|
|
32
|
-
- **Flexible Sizing**: Preset sizes and custom numeric values
|
|
33
|
-
- **Color Variants**: Multiple color options for different contexts
|
|
34
|
-
- **Loading State**: Built-in loading indicator
|
|
35
|
-
- **Icon Support**: Add icons before or after button text
|
|
36
|
-
- **Haptic Feedback**: Optional haptic feedback on press (mobile)
|
|
37
|
-
- **Hover Effects**: Automatic hover effects on web
|
|
38
|
-
|
|
39
|
-
## Size Options
|
|
40
|
-
- \`small\`: 8px vertical, 16px horizontal padding
|
|
41
|
-
- \`medium\`: 12px vertical, 24px horizontal padding (default)
|
|
42
|
-
- \`large\`: 16px vertical, 24px horizontal padding
|
|
43
|
-
- Custom number: Calculated as \`size * 0.6\` vertical, \`size * 1.2\` horizontal padding
|
|
44
|
-
|
|
45
|
-
## Button Types
|
|
46
|
-
- \`solid\`: Filled background with contrast text
|
|
47
|
-
- \`outlined\`: Transparent background with colored border
|
|
48
|
-
- \`text\`: Minimal styling, no border or background
|
|
49
|
-
|
|
50
|
-
## Usage
|
|
51
|
-
\`\`\`tsx
|
|
52
|
-
<Button
|
|
53
|
-
text="Click me"
|
|
54
|
-
type="solid"
|
|
55
|
-
color="primary"
|
|
56
|
-
size="medium"
|
|
57
|
-
onPress={() => console.log('Pressed')}
|
|
58
|
-
/>
|
|
59
|
-
\`\`\`
|
|
60
|
-
`,
|
|
61
|
-
docs: {
|
|
62
|
-
description: {
|
|
63
|
-
component: `
|
|
64
|
-
A versatile Button component with multiple variants, sizes, and customization options.
|
|
65
|
-
|
|
66
|
-
## Features
|
|
67
|
-
- **Three Button Types**: Solid, outlined, and text buttons
|
|
68
|
-
- **Flexible Sizing**: Preset sizes and custom numeric values
|
|
69
|
-
- **Color Variants**: Multiple color options for different contexts
|
|
70
|
-
- **Loading State**: Built-in loading indicator
|
|
71
|
-
- **Icon Support**: Add icons before or after button text
|
|
72
|
-
- **Haptic Feedback**: Optional haptic feedback on press (mobile)
|
|
73
|
-
- **Hover Effects**: Automatic hover effects on web
|
|
74
|
-
|
|
75
|
-
## Size Options
|
|
76
|
-
- \`small\`: 8px vertical, 16px horizontal padding
|
|
77
|
-
- \`medium\`: 12px vertical, 24px horizontal padding (default)
|
|
78
|
-
- \`large\`: 16px vertical, 24px horizontal padding
|
|
79
|
-
- Custom number: Calculated as \`size * 0.6\` vertical, \`size * 1.2\` horizontal padding
|
|
80
|
-
|
|
81
|
-
## Button Types
|
|
82
|
-
- \`solid\`: Filled background with contrast text
|
|
83
|
-
- \`outlined\`: Transparent background with colored border
|
|
84
|
-
- \`text\`: Minimal styling, no border or background
|
|
85
|
-
|
|
86
|
-
## Usage
|
|
87
|
-
\`\`\`tsx
|
|
88
|
-
<Button
|
|
89
|
-
text="Click me"
|
|
90
|
-
type="solid"
|
|
91
|
-
color="primary"
|
|
92
|
-
size="medium"
|
|
93
|
-
onPress={() => console.log('Pressed')}
|
|
94
|
-
/>
|
|
95
|
-
\`\`\`
|
|
96
|
-
`,
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
args: {
|
|
101
|
-
text: 'Hello world',
|
|
102
|
-
type: 'solid',
|
|
103
|
-
color: 'primary',
|
|
104
|
-
size: 'medium',
|
|
105
|
-
onPress: action('onPress'),
|
|
106
|
-
},
|
|
107
|
-
argTypes: {
|
|
108
|
-
type: {
|
|
109
|
-
control: 'select',
|
|
110
|
-
options: buttonTypes,
|
|
111
|
-
description: 'Visual style of the button (solid, outlined, or text)',
|
|
112
|
-
},
|
|
113
|
-
color: {
|
|
114
|
-
control: 'select',
|
|
115
|
-
options: buttonColors,
|
|
116
|
-
description: 'Color variant of the button',
|
|
117
|
-
},
|
|
118
|
-
size: {
|
|
119
|
-
control: 'radio',
|
|
120
|
-
options: ['small', 'medium', 'large', 16, 20, 24, 32],
|
|
121
|
-
description: 'Button size: "small" (8/16px), "medium" (12/24px), "large" (16/24px), or custom number for calculated padding',
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
decorators: [
|
|
125
|
-
(Story, context) =>
|
|
126
|
-
withThemeProvider(
|
|
127
|
-
Story,
|
|
128
|
-
context,
|
|
129
|
-
// @ts-ignore
|
|
130
|
-
context.args.theme,
|
|
131
|
-
),
|
|
132
|
-
],
|
|
133
|
-
} satisfies Meta<typeof Button>;
|
|
134
|
-
|
|
135
|
-
export default meta;
|
|
136
|
-
|
|
137
|
-
type Story = StoryObj<typeof meta>;
|
|
138
|
-
|
|
139
|
-
export const Basic: Story = {
|
|
140
|
-
args: {
|
|
141
|
-
text: 'Basic Button',
|
|
142
|
-
type: 'solid',
|
|
143
|
-
color: 'primary',
|
|
144
|
-
size: 'medium',
|
|
145
|
-
onPress: action('onPress'),
|
|
146
|
-
},
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
export const Secondary: Story = {
|
|
150
|
-
args: {
|
|
151
|
-
text: 'Secondary Button',
|
|
152
|
-
type: 'outlined',
|
|
153
|
-
color: 'secondary',
|
|
154
|
-
size: 'large',
|
|
155
|
-
onPress: action('onPress'),
|
|
156
|
-
},
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
export const Danger: Story = {
|
|
160
|
-
args: {
|
|
161
|
-
text: 'Danger Button',
|
|
162
|
-
type: 'solid',
|
|
163
|
-
color: 'danger',
|
|
164
|
-
size: 'small',
|
|
165
|
-
onPress: action('onPress'),
|
|
166
|
-
},
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
const disableAllExcept = (allowedField: string) => {
|
|
170
|
-
const argTypes = {
|
|
171
|
-
text: {table: {disable: true}},
|
|
172
|
-
type: {table: {disable: true}},
|
|
173
|
-
color: {table: {disable: true}},
|
|
174
|
-
size: {table: {disable: true}},
|
|
175
|
-
onPress: {table: {disable: true}},
|
|
176
|
-
testID: {table: {disable: true}},
|
|
177
|
-
disabled: {table: {disable: true}},
|
|
178
|
-
loadingElement: {table: {disable: true}},
|
|
179
|
-
borderRadius: {table: {disable: true}},
|
|
180
|
-
startElement: {table: {disable: true}},
|
|
181
|
-
endElement: {table: {disable: true}},
|
|
182
|
-
activeOpacity: {table: {disable: true}},
|
|
183
|
-
touchableHighlightProps: {table: {disable: true}},
|
|
184
|
-
hitSlop: {table: {disable: true}},
|
|
185
|
-
theme: {control: 'object'},
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
if (argTypes[allowedField]) {
|
|
189
|
-
argTypes[allowedField] = {table: {disable: false}};
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return argTypes;
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
export const CustomColor: Story = {
|
|
196
|
-
args: {
|
|
197
|
-
// @ts-ignore
|
|
198
|
-
theme: {
|
|
199
|
-
light: {
|
|
200
|
-
button: {
|
|
201
|
-
primary: {
|
|
202
|
-
bg: 'red',
|
|
203
|
-
text: 'white',
|
|
204
|
-
},
|
|
205
|
-
},
|
|
206
|
-
},
|
|
207
|
-
dark: {
|
|
208
|
-
button: {
|
|
209
|
-
primary: {
|
|
210
|
-
bg: 'pink',
|
|
211
|
-
text: 'red',
|
|
212
|
-
},
|
|
213
|
-
},
|
|
214
|
-
},
|
|
215
|
-
} as ThemeParam,
|
|
216
|
-
},
|
|
217
|
-
argTypes: disableAllExcept('theme'),
|
|
218
|
-
};
|