cpk-ui 0.5.4 → 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.
Files changed (136) hide show
  1. package/README.md +80 -147
  2. package/components/modals/AlertDialog/AlertDialog.d.ts.map +1 -1
  3. package/components/modals/AlertDialog/AlertDialog.js +14 -7
  4. package/components/modals/Snackbar/Snackbar.d.ts.map +1 -1
  5. package/components/modals/Snackbar/Snackbar.js +20 -17
  6. package/components/uis/Accordion/AccordionItem.d.ts.map +1 -1
  7. package/components/uis/Accordion/AccordionItem.js +41 -17
  8. package/components/uis/Button/Button.d.ts +2 -1
  9. package/components/uis/Button/Button.d.ts.map +1 -1
  10. package/components/uis/Button/Button.js +11 -11
  11. package/components/uis/Card/Card.d.ts +2 -1
  12. package/components/uis/Card/Card.d.ts.map +1 -1
  13. package/components/uis/Card/Card.js +12 -3
  14. package/components/uis/Checkbox/Checkbox.d.ts +2 -1
  15. package/components/uis/Checkbox/Checkbox.d.ts.map +1 -1
  16. package/components/uis/Checkbox/Checkbox.js +2 -2
  17. package/components/uis/CustomPressable/CustomPressable.d.ts.map +1 -1
  18. package/components/uis/CustomPressable/CustomPressable.js +6 -6
  19. package/components/uis/EditText/EditText.d.ts +1 -0
  20. package/components/uis/EditText/EditText.d.ts.map +1 -1
  21. package/components/uis/EditText/EditText.js +18 -13
  22. package/components/uis/Fab/Fab.d.ts +2 -2
  23. package/components/uis/Fab/Fab.d.ts.map +1 -1
  24. package/components/uis/Fab/Fab.js +22 -4
  25. package/components/uis/Icon/Icon.d.ts.map +1 -1
  26. package/components/uis/Icon/Icon.js +6 -3
  27. package/components/uis/IconButton/IconButton.d.ts +2 -1
  28. package/components/uis/IconButton/IconButton.d.ts.map +1 -1
  29. package/components/uis/IconButton/IconButton.js +44 -42
  30. package/components/uis/LoadingIndicator/LoadingIndicator.d.ts +2 -1
  31. package/components/uis/LoadingIndicator/LoadingIndicator.d.ts.map +1 -1
  32. package/components/uis/LoadingIndicator/LoadingIndicator.js +4 -4
  33. package/components/uis/RadioGroup/RadioButton.d.ts +2 -1
  34. package/components/uis/RadioGroup/RadioButton.d.ts.map +1 -1
  35. package/components/uis/RadioGroup/RadioButton.js +2 -2
  36. package/components/uis/RadioGroup/RadioGroup.d.ts.map +1 -1
  37. package/components/uis/RadioGroup/RadioGroup.js +16 -3
  38. package/components/uis/Rating/Rating.d.ts.map +1 -1
  39. package/components/uis/Rating/Rating.js +23 -19
  40. package/components/uis/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  41. package/components/uis/SegmentedControl/SegmentedControl.js +1 -1
  42. package/components/uis/StatusbarBrightness/StatusBarBrightness.d.ts +2 -2
  43. package/components/uis/StatusbarBrightness/StatusBarBrightness.d.ts.map +1 -1
  44. package/components/uis/StatusbarBrightness/StatusBarBrightness.js +1 -1
  45. package/components/uis/SwitchToggle/SwitchToggle.d.ts +2 -1
  46. package/components/uis/SwitchToggle/SwitchToggle.d.ts.map +1 -1
  47. package/components/uis/SwitchToggle/SwitchToggle.js +2 -2
  48. package/hooks/useHoverState.d.ts +8 -0
  49. package/hooks/useHoverState.d.ts.map +1 -0
  50. package/hooks/useHoverState.js +16 -0
  51. package/package.json +18 -6
  52. package/providers/ThemeProvider.d.ts.map +1 -1
  53. package/providers/ThemeProvider.js +0 -1
  54. package/providers/index.d.ts.map +1 -1
  55. package/providers/index.js +3 -2
  56. package/components/uis/Icon/selection.json +0 -1
  57. package/src/components/common/ErrorBoundary/ErrorBoundary.tsx +0 -75
  58. package/src/components/modals/AlertDialog/AlertDialog.stories.tsx +0 -216
  59. package/src/components/modals/AlertDialog/AlertDialog.test.tsx +0 -251
  60. package/src/components/modals/AlertDialog/AlertDialog.tsx +0 -356
  61. package/src/components/modals/Snackbar/Snackbar.stories.tsx +0 -182
  62. package/src/components/modals/Snackbar/Snackbar.test.tsx +0 -319
  63. package/src/components/modals/Snackbar/Snackbar.tsx +0 -260
  64. package/src/components/modals/Snackbar/const.ts +0 -4
  65. package/src/components/uis/Accordion/Accordion.stories.tsx +0 -167
  66. package/src/components/uis/Accordion/Accordion.test.tsx +0 -272
  67. package/src/components/uis/Accordion/Accordion.tsx +0 -109
  68. package/src/components/uis/Accordion/AccordionItem.tsx +0 -306
  69. package/src/components/uis/Button/Button.stories.tsx +0 -218
  70. package/src/components/uis/Button/Button.test.tsx +0 -620
  71. package/src/components/uis/Button/Button.tsx +0 -436
  72. package/src/components/uis/Card/Card.test.tsx +0 -146
  73. package/src/components/uis/Card/Card.tsx +0 -102
  74. package/src/components/uis/Checkbox/Checkbox.stories.tsx +0 -216
  75. package/src/components/uis/Checkbox/Checkbox.test.tsx +0 -173
  76. package/src/components/uis/Checkbox/Checkbox.tsx +0 -220
  77. package/src/components/uis/CustomPressable/CustomPressable.tsx +0 -48
  78. package/src/components/uis/EditText/EditText.stories.tsx +0 -124
  79. package/src/components/uis/EditText/EditText.test.tsx +0 -477
  80. package/src/components/uis/EditText/EditText.tsx +0 -590
  81. package/src/components/uis/Fab/Fab.stories.tsx +0 -133
  82. package/src/components/uis/Fab/Fab.test.tsx +0 -110
  83. package/src/components/uis/Fab/Fab.tsx +0 -168
  84. package/src/components/uis/Hr/Hr.test.tsx +0 -26
  85. package/src/components/uis/Hr/Hr.tsx +0 -19
  86. package/src/components/uis/Icon/Icon.stories.tsx +0 -98
  87. package/src/components/uis/Icon/Icon.test.tsx +0 -49
  88. package/src/components/uis/Icon/Icon.tsx +0 -3819
  89. package/src/components/uis/IconButton/IconButton.test.tsx +0 -165
  90. package/src/components/uis/IconButton/IconButton.tsx +0 -275
  91. package/src/components/uis/LoadingIndicator/LoadingIndicator.tsx +0 -126
  92. package/src/components/uis/LoadingIndicator/LodingIndicator.stories.tsx +0 -81
  93. package/src/components/uis/PinchZoom/PinchZoom.stories.tsx +0 -266
  94. package/src/components/uis/PinchZoom/PinchZoom.test.tsx +0 -113
  95. package/src/components/uis/PinchZoom/PinchZoom.tsx +0 -424
  96. package/src/components/uis/RadioGroup/RadioButton.tsx +0 -188
  97. package/src/components/uis/RadioGroup/RadioGroup.stories.tsx +0 -188
  98. package/src/components/uis/RadioGroup/RadioGroup.test.tsx +0 -287
  99. package/src/components/uis/RadioGroup/RadioGroup.tsx +0 -109
  100. package/src/components/uis/Rating/Rating.test.tsx +0 -98
  101. package/src/components/uis/Rating/Rating.tsx +0 -200
  102. package/src/components/uis/SegmentedControl/SegmentedControl.stories.tsx +0 -546
  103. package/src/components/uis/SegmentedControl/SegmentedControl.test.tsx +0 -274
  104. package/src/components/uis/SegmentedControl/SegmentedControl.tsx +0 -229
  105. package/src/components/uis/StatusbarBrightness/StatusBarBrightness.test.tsx +0 -41
  106. package/src/components/uis/StatusbarBrightness/StatusBarBrightness.tsx +0 -26
  107. package/src/components/uis/Styled/StyledComponents.tsx +0 -217
  108. package/src/components/uis/SwitchToggle/SwitchToggle.stories.tsx +0 -75
  109. package/src/components/uis/SwitchToggle/SwitchToggle.test.tsx +0 -105
  110. package/src/components/uis/SwitchToggle/SwitchToggle.tsx +0 -305
  111. package/src/components/uis/Typography/Typography.stories.tsx +0 -149
  112. package/src/components/uis/Typography/Typography.test.tsx +0 -58
  113. package/src/components/uis/Typography/Typography.tsx +0 -386
  114. package/src/hooks/index.ts +0 -2
  115. package/src/hooks/useAnimations.ts +0 -71
  116. package/src/hooks/useDebouncedColorScheme.tsx +0 -30
  117. package/src/hooks/useOptimizedStyles.ts +0 -22
  118. package/src/hooks/usePerformance.ts +0 -93
  119. package/src/index.tsx +0 -38
  120. package/src/providers/ThemeProvider.tsx +0 -177
  121. package/src/providers/index.tsx +0 -130
  122. package/src/test/testUtils.tsx +0 -101
  123. package/src/types/common.ts +0 -77
  124. package/src/types/index.ts +0 -1
  125. package/src/types/kstyled.d.ts +0 -6
  126. package/src/utils/accessibility.ts +0 -110
  127. package/src/utils/colors.ts +0 -151
  128. package/src/utils/createCtx.tsx +0 -26
  129. package/src/utils/guards.ts +0 -93
  130. package/src/utils/index.ts +0 -2
  131. package/src/utils/performanceTest.ts +0 -174
  132. package/src/utils/platform.ts +0 -69
  133. package/src/utils/theme.ts +0 -38
  134. package/test/testUtils.d.ts +0 -113
  135. package/test/testUtils.d.ts.map +0 -1
  136. 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
- };