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.
Files changed (130) 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.map +1 -1
  9. package/components/uis/Button/Button.js +10 -10
  10. package/components/uis/Card/Card.d.ts +2 -1
  11. package/components/uis/Card/Card.d.ts.map +1 -1
  12. package/components/uis/Card/Card.js +12 -3
  13. package/components/uis/Checkbox/Checkbox.d.ts.map +1 -1
  14. package/components/uis/Checkbox/Checkbox.js +1 -1
  15. package/components/uis/CustomPressable/CustomPressable.d.ts.map +1 -1
  16. package/components/uis/CustomPressable/CustomPressable.js +6 -6
  17. package/components/uis/EditText/EditText.d.ts.map +1 -1
  18. package/components/uis/EditText/EditText.js +17 -12
  19. package/components/uis/Fab/Fab.d.ts +2 -2
  20. package/components/uis/Fab/Fab.d.ts.map +1 -1
  21. package/components/uis/Fab/Fab.js +22 -4
  22. package/components/uis/Icon/Icon.d.ts.map +1 -1
  23. package/components/uis/Icon/Icon.js +6 -3
  24. package/components/uis/IconButton/IconButton.d.ts.map +1 -1
  25. package/components/uis/IconButton/IconButton.js +43 -41
  26. package/components/uis/LoadingIndicator/LoadingIndicator.d.ts +2 -1
  27. package/components/uis/LoadingIndicator/LoadingIndicator.d.ts.map +1 -1
  28. package/components/uis/LoadingIndicator/LoadingIndicator.js +4 -4
  29. package/components/uis/RadioGroup/RadioButton.d.ts.map +1 -1
  30. package/components/uis/RadioGroup/RadioButton.js +1 -1
  31. package/components/uis/RadioGroup/RadioGroup.d.ts.map +1 -1
  32. package/components/uis/RadioGroup/RadioGroup.js +16 -3
  33. package/components/uis/Rating/Rating.d.ts.map +1 -1
  34. package/components/uis/Rating/Rating.js +23 -19
  35. package/components/uis/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  36. package/components/uis/SegmentedControl/SegmentedControl.js +1 -1
  37. package/components/uis/StatusbarBrightness/StatusBarBrightness.d.ts +2 -2
  38. package/components/uis/StatusbarBrightness/StatusBarBrightness.d.ts.map +1 -1
  39. package/components/uis/StatusbarBrightness/StatusBarBrightness.js +1 -1
  40. package/components/uis/SwitchToggle/SwitchToggle.d.ts.map +1 -1
  41. package/components/uis/SwitchToggle/SwitchToggle.js +1 -1
  42. package/hooks/useHoverState.d.ts +8 -0
  43. package/hooks/useHoverState.d.ts.map +1 -0
  44. package/hooks/useHoverState.js +16 -0
  45. package/package.json +18 -6
  46. package/providers/ThemeProvider.d.ts.map +1 -1
  47. package/providers/ThemeProvider.js +0 -1
  48. package/providers/index.d.ts.map +1 -1
  49. package/providers/index.js +3 -2
  50. package/components/uis/Icon/selection.json +0 -1
  51. package/src/components/common/ErrorBoundary/ErrorBoundary.tsx +0 -75
  52. package/src/components/modals/AlertDialog/AlertDialog.stories.tsx +0 -216
  53. package/src/components/modals/AlertDialog/AlertDialog.test.tsx +0 -251
  54. package/src/components/modals/AlertDialog/AlertDialog.tsx +0 -356
  55. package/src/components/modals/Snackbar/Snackbar.stories.tsx +0 -182
  56. package/src/components/modals/Snackbar/Snackbar.test.tsx +0 -319
  57. package/src/components/modals/Snackbar/Snackbar.tsx +0 -260
  58. package/src/components/modals/Snackbar/const.ts +0 -4
  59. package/src/components/uis/Accordion/Accordion.stories.tsx +0 -167
  60. package/src/components/uis/Accordion/Accordion.test.tsx +0 -272
  61. package/src/components/uis/Accordion/Accordion.tsx +0 -109
  62. package/src/components/uis/Accordion/AccordionItem.tsx +0 -306
  63. package/src/components/uis/Button/Button.stories.tsx +0 -218
  64. package/src/components/uis/Button/Button.test.tsx +0 -694
  65. package/src/components/uis/Button/Button.tsx +0 -440
  66. package/src/components/uis/Card/Card.test.tsx +0 -146
  67. package/src/components/uis/Card/Card.tsx +0 -102
  68. package/src/components/uis/Checkbox/Checkbox.stories.tsx +0 -216
  69. package/src/components/uis/Checkbox/Checkbox.test.tsx +0 -267
  70. package/src/components/uis/Checkbox/Checkbox.tsx +0 -225
  71. package/src/components/uis/CustomPressable/CustomPressable.tsx +0 -48
  72. package/src/components/uis/EditText/EditText.stories.tsx +0 -124
  73. package/src/components/uis/EditText/EditText.test.tsx +0 -477
  74. package/src/components/uis/EditText/EditText.tsx +0 -593
  75. package/src/components/uis/Fab/Fab.stories.tsx +0 -133
  76. package/src/components/uis/Fab/Fab.test.tsx +0 -110
  77. package/src/components/uis/Fab/Fab.tsx +0 -168
  78. package/src/components/uis/Hr/Hr.test.tsx +0 -26
  79. package/src/components/uis/Hr/Hr.tsx +0 -19
  80. package/src/components/uis/Icon/Icon.stories.tsx +0 -98
  81. package/src/components/uis/Icon/Icon.test.tsx +0 -49
  82. package/src/components/uis/Icon/Icon.tsx +0 -3819
  83. package/src/components/uis/IconButton/IconButton.test.tsx +0 -204
  84. package/src/components/uis/IconButton/IconButton.tsx +0 -279
  85. package/src/components/uis/LoadingIndicator/LoadingIndicator.tsx +0 -126
  86. package/src/components/uis/LoadingIndicator/LodingIndicator.stories.tsx +0 -81
  87. package/src/components/uis/PinchZoom/PinchZoom.stories.tsx +0 -266
  88. package/src/components/uis/PinchZoom/PinchZoom.test.tsx +0 -113
  89. package/src/components/uis/PinchZoom/PinchZoom.tsx +0 -424
  90. package/src/components/uis/RadioGroup/RadioButton.tsx +0 -193
  91. package/src/components/uis/RadioGroup/RadioGroup.stories.tsx +0 -188
  92. package/src/components/uis/RadioGroup/RadioGroup.test.tsx +0 -354
  93. package/src/components/uis/RadioGroup/RadioGroup.tsx +0 -109
  94. package/src/components/uis/Rating/Rating.test.tsx +0 -98
  95. package/src/components/uis/Rating/Rating.tsx +0 -200
  96. package/src/components/uis/SegmentedControl/SegmentedControl.stories.tsx +0 -546
  97. package/src/components/uis/SegmentedControl/SegmentedControl.test.tsx +0 -274
  98. package/src/components/uis/SegmentedControl/SegmentedControl.tsx +0 -232
  99. package/src/components/uis/StatusbarBrightness/StatusBarBrightness.test.tsx +0 -41
  100. package/src/components/uis/StatusbarBrightness/StatusBarBrightness.tsx +0 -26
  101. package/src/components/uis/Styled/StyledComponents.tsx +0 -217
  102. package/src/components/uis/SwitchToggle/SwitchToggle.stories.tsx +0 -75
  103. package/src/components/uis/SwitchToggle/SwitchToggle.test.tsx +0 -149
  104. package/src/components/uis/SwitchToggle/SwitchToggle.tsx +0 -309
  105. package/src/components/uis/Typography/Typography.stories.tsx +0 -149
  106. package/src/components/uis/Typography/Typography.test.tsx +0 -58
  107. package/src/components/uis/Typography/Typography.tsx +0 -386
  108. package/src/hooks/index.ts +0 -2
  109. package/src/hooks/useAnimations.ts +0 -71
  110. package/src/hooks/useDebouncedColorScheme.tsx +0 -30
  111. package/src/hooks/useOptimizedStyles.ts +0 -22
  112. package/src/hooks/usePerformance.ts +0 -93
  113. package/src/index.tsx +0 -38
  114. package/src/providers/ThemeProvider.tsx +0 -177
  115. package/src/providers/index.tsx +0 -130
  116. package/src/test/testUtils.tsx +0 -101
  117. package/src/types/common.ts +0 -77
  118. package/src/types/index.ts +0 -1
  119. package/src/types/kstyled.d.ts +0 -6
  120. package/src/utils/accessibility.ts +0 -110
  121. package/src/utils/colors.ts +0 -151
  122. package/src/utils/createCtx.tsx +0 -26
  123. package/src/utils/guards.ts +0 -93
  124. package/src/utils/index.ts +0 -2
  125. package/src/utils/performanceTest.ts +0 -174
  126. package/src/utils/platform.ts +0 -69
  127. package/src/utils/theme.ts +0 -38
  128. package/test/testUtils.d.ts +0 -113
  129. package/test/testUtils.d.ts.map +0 -1
  130. package/test/testUtils.js +0 -65
@@ -1,440 +0,0 @@
1
- import React, {useCallback, useMemo, useRef, type ReactElement} from 'react';
2
- import type {
3
- Insets,
4
- StyleProp,
5
- TextStyle,
6
- TouchableHighlightProps,
7
- ViewStyle,
8
- } from 'react-native';
9
- import {Platform, TouchableHighlight, View} from 'react-native';
10
- import {useHover} from 'react-native-web-hooks';
11
- import {styled, css} from 'kstyled';
12
-
13
- import {useTheme} from '../../../providers/ThemeProvider';
14
- import {cloneElemWithDefaultColors} from '../../../utils/guards';
15
- import type {CpkTheme} from '../../../utils/theme';
16
- import {LoadingIndicator} from '../LoadingIndicator/LoadingIndicator';
17
- import {Typography} from '../Typography/Typography';
18
- import * as Haptics from 'expo-haptics';
19
-
20
- export type ButtonType = 'text' | 'solid' | 'outlined';
21
- export type ButtonColorType =
22
- | 'primary'
23
- | 'secondary'
24
- | 'success'
25
- | 'danger'
26
- | 'warning'
27
- | 'info'
28
- | 'light';
29
- export type ButtonSizeType = 'small' | 'medium' | 'large' | number;
30
-
31
- export type Props = {
32
- testID?: string;
33
- type?: ButtonType;
34
- color?: ButtonColorType;
35
- size?: ButtonSizeType;
36
- disabled?: boolean;
37
- loading?: boolean;
38
- loadingColor?: string;
39
- loadingElement?: ReactElement;
40
- text?: string | ReactElement;
41
- borderRadius?: number;
42
- startElement?: ReactElement;
43
- endElement?: ReactElement;
44
- style?: StyleProp<Omit<ViewStyle, 'borderRadius' | 'padding'>>;
45
- styles?: Styles;
46
- onPress?: TouchableHighlightProps['onPress'];
47
- activeOpacity?: TouchableHighlightProps['activeOpacity'];
48
- touchableHighlightProps?: Omit<
49
- TouchableHighlightProps,
50
- 'onPress' | 'activeOpacity' | 'style'
51
- >;
52
- hitSlop?: null | Insets | number | undefined;
53
- hapticFeedback?: Haptics.ImpactFeedbackStyle;
54
- accessibilityLabel?: string;
55
- };
56
-
57
- type Styles = {
58
- container?: StyleProp<ViewStyle>;
59
- content?: StyleProp<ViewStyle>;
60
- loading?: StyleProp<ViewStyle>;
61
- text?: StyleProp<TextStyle>;
62
- disabled?: StyleProp<ViewStyle>;
63
- disabledText?: StyleProp<TextStyle>;
64
- hovered?: StyleProp<ViewStyle>;
65
- };
66
-
67
- type ButtonContainerStyleProps = {
68
- $type: ButtonType;
69
- $size?: ButtonSizeType;
70
- $outlined?: boolean;
71
- $disabled?: boolean;
72
- $loading?: boolean;
73
- };
74
-
75
- const ButtonContainer = styled.View<ButtonContainerStyleProps>`
76
- align-self: stretch;
77
- flex-direction: row;
78
- align-items: center;
79
- justify-content: center;
80
- `;
81
-
82
- // Memoize style calculation function
83
- const calculateStyles = ({
84
- theme,
85
- type,
86
- color,
87
- size,
88
- loading,
89
- disabled,
90
- borderRadius,
91
- hovered,
92
- styles,
93
- }: {
94
- theme: CpkTheme;
95
- type: ButtonType;
96
- color: ButtonColorType;
97
- size: ButtonSizeType;
98
- loading: boolean;
99
- disabled: boolean;
100
- borderRadius: number;
101
- hovered: boolean;
102
- styles?: Styles;
103
- }): Styles => {
104
- const isDisabled = disabled || loading;
105
- const padding =
106
- type === 'text'
107
- ? '8px'
108
- : typeof size === 'number'
109
- ? `${size * 0.6}px ${size * 1.2}px`
110
- : size === 'large'
111
- ? '16px 24px'
112
- : size === 'medium'
113
- ? '12px 24px'
114
- : size === 'small'
115
- ? '8px 16px'
116
- : '12px 24px';
117
-
118
- const borderWidth = type === 'outlined' ? 1 : 0;
119
- const backgroundColor =
120
- type === 'solid'
121
- ? isDisabled
122
- ? theme.button.disabled.bg
123
- : theme.button[color].bg
124
- : type === 'outlined'
125
- ? theme.bg.basic
126
- : 'transparent';
127
-
128
- const borderColor =
129
- type === 'outlined'
130
- ? isDisabled
131
- ? theme.bg.disabled
132
- : theme.button[color].bg
133
- : backgroundColor;
134
-
135
- const textColor = isDisabled
136
- ? theme.button.disabled.text
137
- : type === 'solid'
138
- ? theme.button[color].text
139
- : theme.button[color].bg;
140
-
141
- return {
142
- container: [
143
- css`
144
- background-color: ${backgroundColor};
145
- border-top-color: ${borderColor};
146
- border-bottom-color: ${borderColor};
147
- border-left-color: ${borderColor};
148
- border-right-color: ${borderColor};
149
- border-width: ${borderWidth}px;
150
- padding: ${padding};
151
- `,
152
- styles?.container,
153
- ],
154
- content: [
155
- css`
156
- flex-direction: row;
157
- align-items: center;
158
- opacity: ${loading ? '0' : '1'};
159
- gap: 8px;
160
- `,
161
- styles?.content,
162
- ],
163
- loading: [
164
- css`
165
- position: absolute;
166
- opacity: ${loading ? '1' : '0'};
167
- `,
168
- styles?.loading,
169
- ],
170
- text: [
171
- css`
172
- color: ${textColor};
173
- `,
174
- styles?.text,
175
- ],
176
- hovered: hovered
177
- ? [
178
- {
179
- shadowColor: 'black',
180
- shadowOpacity: 0.24,
181
- shadowRadius: 16,
182
- elevation: 10,
183
- borderRadius,
184
- },
185
- styles?.hovered,
186
- ]
187
- : undefined,
188
- disabled: isDisabled
189
- ? [
190
- css`
191
- background-color: ${theme.button.disabled.bg};
192
- border-top-color: ${theme.bg.disabled};
193
- border-bottom-color: ${theme.bg.disabled};
194
- border-left-color: ${theme.bg.disabled};
195
- border-right-color: ${theme.bg.disabled};
196
- `,
197
- styles?.disabled,
198
- ]
199
- : undefined,
200
- };
201
- };
202
-
203
- // Memoize button state hook
204
- const useButtonState = ({
205
- disabled,
206
- onPress,
207
- loading,
208
- }: {
209
- disabled?: boolean;
210
- onPress?: TouchableHighlightProps['onPress'];
211
- loading: boolean;
212
- }): {
213
- innerDisabled: boolean;
214
- isLoading: boolean;
215
- } => {
216
- return useMemo(
217
- () => ({
218
- innerDisabled: disabled || !onPress,
219
- isLoading: loading,
220
- }),
221
- [disabled, onPress, loading],
222
- );
223
- };
224
-
225
- export function Button({
226
- testID,
227
- type = 'solid',
228
- color = 'primary',
229
- size = 'medium',
230
- disabled,
231
- loading = false,
232
- loadingElement,
233
- text,
234
- startElement,
235
- endElement,
236
- style,
237
- styles,
238
- onPress,
239
- activeOpacity = 0.8,
240
- touchableHighlightProps,
241
- borderRadius = 4,
242
- loadingColor,
243
- hitSlop = {top: 8, bottom: 8, left: 8, right: 8},
244
- hapticFeedback,
245
- accessibilityLabel,
246
- }: Props): ReactElement {
247
- const ref = useRef<React.ElementRef<typeof TouchableHighlight>>(null);
248
- const hovered = useHover(ref);
249
- const {theme} = useTheme();
250
-
251
- const {innerDisabled} = useButtonState({disabled, onPress, loading});
252
-
253
- // Memoize styles calculation
254
- const compositeStyles: Styles = useMemo(
255
- () =>
256
- calculateStyles({
257
- theme,
258
- type,
259
- color,
260
- size,
261
- loading,
262
- disabled: innerDisabled,
263
- borderRadius,
264
- hovered,
265
- styles,
266
- }),
267
- [
268
- theme,
269
- type,
270
- color,
271
- size,
272
- loading,
273
- innerDisabled,
274
- borderRadius,
275
- hovered,
276
- styles,
277
- ],
278
- );
279
-
280
- // Memoize loading view
281
- const LoadingView = useMemo(
282
- () =>
283
- loadingElement ?? (
284
- <LoadingIndicator
285
- color={
286
- loadingColor
287
- ? loadingColor
288
- : type === 'solid'
289
- ? theme.text.contrast
290
- : theme.text.basic
291
- }
292
- size="small"
293
- />
294
- ),
295
- [loadingElement, loadingColor, type, theme.text.contrast, theme.text.basic],
296
- );
297
-
298
- // Memoize style resolvers
299
- const resolveStyle = useCallback(<T,>(style: StyleProp<T>): T | undefined => {
300
- if (Array.isArray(style)) {
301
- return style.find((s): s is T => !!s);
302
- }
303
- return (style as T) || undefined;
304
- }, []);
305
-
306
- const viewStyle = useMemo(
307
- () => resolveStyle<ViewStyle>(compositeStyles.container),
308
- [resolveStyle, compositeStyles.container],
309
- );
310
- const textStyle = useMemo(
311
- () => resolveStyle<TextStyle>(compositeStyles.text),
312
- [resolveStyle, compositeStyles.text],
313
- );
314
-
315
- // Memoize child view
316
- const ChildView = useMemo(
317
- () => (
318
- <>
319
- {cloneElemWithDefaultColors({
320
- element: startElement,
321
- backgroundColor: viewStyle?.backgroundColor,
322
- color: textStyle?.color,
323
- })}
324
- {!text || typeof text === 'string' ? (
325
- <Typography.Body2 style={compositeStyles.text}>
326
- {text}
327
- </Typography.Body2>
328
- ) : (
329
- text
330
- )}
331
- {cloneElemWithDefaultColors({
332
- element: endElement,
333
- backgroundColor: viewStyle?.backgroundColor,
334
- color: textStyle?.color,
335
- })}
336
- </>
337
- ),
338
- [
339
- startElement,
340
- endElement,
341
- text,
342
- compositeStyles.text,
343
- viewStyle?.backgroundColor,
344
- textStyle?.color,
345
- ],
346
- );
347
-
348
- // Memoize container renderer
349
- const renderContainer = useCallback(
350
- ({
351
- children,
352
- loadingView,
353
- }: {
354
- children: ReactElement;
355
- loadingView: ReactElement;
356
- }): ReactElement => (
357
- <ButtonContainer
358
- $disabled={innerDisabled}
359
- $size={size}
360
- style={[
361
- hovered && !innerDisabled && compositeStyles.hovered,
362
- compositeStyles.container,
363
- type === 'text' &&
364
- css`
365
- background-color: transparent;
366
- `,
367
- innerDisabled && compositeStyles.disabled,
368
- !!borderRadius && {borderRadius},
369
- ]}
370
- testID={loading ? 'loading-view' : 'button-container'}
371
- $type={type}
372
- >
373
- <View style={compositeStyles.content}>{children}</View>
374
- <View style={compositeStyles.loading}>{loadingView}</View>
375
- </ButtonContainer>
376
- ),
377
- [
378
- innerDisabled,
379
- size,
380
- compositeStyles.container,
381
- compositeStyles.hovered,
382
- compositeStyles.disabled,
383
- compositeStyles.content,
384
- compositeStyles.loading,
385
- hovered,
386
- type,
387
- loading,
388
- ],
389
- );
390
-
391
- // Memoize press handler
392
- const handlePress = useCallback(
393
- (e: any) => {
394
- onPress?.(e);
395
- if (hapticFeedback) {
396
- Haptics.impactAsync(hapticFeedback);
397
- }
398
- },
399
- [onPress, hapticFeedback],
400
- );
401
-
402
- // Memoize button styles
403
- const buttonStyles = useMemo(
404
- () => [
405
- style,
406
- css`
407
- border-radius: ${borderRadius}px;
408
- `,
409
- ],
410
- [style, borderRadius],
411
- );
412
-
413
- return (
414
- <TouchableHighlight
415
- accessibilityLabel={accessibilityLabel ?? (typeof text === 'string' ? text : undefined)}
416
- accessibilityRole="button"
417
- activeOpacity={activeOpacity}
418
- delayPressIn={30}
419
- disabled={innerDisabled || loading || !onPress}
420
- hitSlop={hitSlop}
421
- onPress={handlePress}
422
- ref={Platform.select({
423
- web: ref,
424
- default: undefined,
425
- })}
426
- style={buttonStyles}
427
- testID={testID}
428
- underlayColor={type === 'text' ? 'transparent' : theme.role.underlay}
429
- {...touchableHighlightProps}
430
- >
431
- {renderContainer({
432
- children: ChildView,
433
- loadingView: LoadingView,
434
- })}
435
- </TouchableHighlight>
436
- );
437
- }
438
-
439
- // Export memoized component for better performance
440
- export default React.memo(Button) as typeof Button;
@@ -1,146 +0,0 @@
1
- import '@testing-library/jest-native/extend-expect';
2
-
3
- import React, {type ReactElement} from 'react';
4
- import {Text} from 'react-native';
5
- import type {RenderAPI} from '@testing-library/react-native';
6
- import {fireEvent, render} from '@testing-library/react-native';
7
-
8
- import {createComponent} from '../../../../test/testUtils';
9
- import {Card} from './Card';
10
- import type {CardProps} from './Card';
11
- import type {ThemeType} from '../../../providers/ThemeProvider';
12
-
13
- let testingLib: RenderAPI;
14
-
15
- const Component = ({
16
- props,
17
- themeType,
18
- }: {
19
- props?: CardProps;
20
- themeType?: ThemeType;
21
- }): ReactElement =>
22
- createComponent(
23
- <Card {...props}>
24
- <Text>Test Content</Text>
25
- </Card>,
26
- themeType,
27
- );
28
-
29
- describe('[Card]', () => {
30
- it('should render without crashing', () => {
31
- testingLib = render(Component({}));
32
-
33
- const json = testingLib.toJSON();
34
- expect(json).toBeTruthy();
35
- });
36
-
37
- it('should render with default props', () => {
38
- testingLib = render(Component({}));
39
-
40
- const cardContainer = testingLib.getByTestId('card-container');
41
- expect(cardContainer).toBeTruthy();
42
- });
43
-
44
- it('should render children content', () => {
45
- testingLib = render(Component({}));
46
-
47
- expect(testingLib.getByText('Test Content')).toBeTruthy();
48
- });
49
-
50
- it('should handle onPress when provided', () => {
51
- const mockOnPress = jest.fn();
52
- testingLib = render(Component({props: {onPress: mockOnPress}}));
53
-
54
- const cardContainer = testingLib.getByTestId('card-container');
55
- fireEvent.press(cardContainer);
56
-
57
- expect(mockOnPress).toHaveBeenCalledTimes(1);
58
- });
59
-
60
- it('should apply custom testID', () => {
61
- const customTestID = 'custom-card';
62
- testingLib = render(Component({props: {testID: customTestID}}));
63
-
64
- expect(testingLib.getByTestId(customTestID)).toBeTruthy();
65
- });
66
-
67
- it('should apply custom elevation', () => {
68
- testingLib = render(Component({props: {elevation: 5}}));
69
-
70
- const cardContainer = testingLib.getByTestId('card-container');
71
- expect(cardContainer).toBeTruthy();
72
- });
73
-
74
- it('should apply custom border radius', () => {
75
- testingLib = render(Component({props: {borderRadius: 12}}));
76
-
77
- const cardContainer = testingLib.getByTestId('card-container');
78
- expect(cardContainer).toBeTruthy();
79
- });
80
-
81
- it('should apply custom padding', () => {
82
- testingLib = render(Component({props: {padding: 24}}));
83
-
84
- const cardContainer = testingLib.getByTestId('card-container');
85
- expect(cardContainer).toBeTruthy();
86
- });
87
-
88
- it('should apply custom margin', () => {
89
- testingLib = render(Component({props: {margin: 16}}));
90
-
91
- const cardContainer = testingLib.getByTestId('card-container');
92
- expect(cardContainer).toBeTruthy();
93
- });
94
-
95
- it('should apply custom background color', () => {
96
- testingLib = render(Component({props: {backgroundColor: '#ff0000'}}));
97
-
98
- const cardContainer = testingLib.getByTestId('card-container');
99
- expect(cardContainer).toBeTruthy();
100
- });
101
-
102
- describe('Themes', () => {
103
- it('should render correctly with light theme', () => {
104
- testingLib = render(Component({themeType: 'light'}));
105
-
106
- const cardContainer = testingLib.getByTestId('card-container');
107
- expect(cardContainer).toBeTruthy();
108
- });
109
-
110
- it('should render correctly with dark theme', () => {
111
- testingLib = render(Component({themeType: 'dark'}));
112
-
113
- const cardContainer = testingLib.getByTestId('card-container');
114
- expect(cardContainer).toBeTruthy();
115
- });
116
- });
117
-
118
- describe('Custom Styles', () => {
119
- it('should apply custom container styles', () => {
120
- const customStyles = {
121
- container: {
122
- borderWidth: 2,
123
- borderColor: '#000',
124
- },
125
- };
126
-
127
- testingLib = render(Component({props: {styles: customStyles}}));
128
-
129
- const cardContainer = testingLib.getByTestId('card-container');
130
- expect(cardContainer).toBeTruthy();
131
- });
132
-
133
- it('should apply custom content styles', () => {
134
- const customStyles = {
135
- content: {
136
- alignItems: 'center' as const,
137
- },
138
- };
139
-
140
- testingLib = render(Component({props: {styles: customStyles}}));
141
-
142
- const cardContainer = testingLib.getByTestId('card-container');
143
- expect(cardContainer).toBeTruthy();
144
- });
145
- });
146
- });
@@ -1,102 +0,0 @@
1
- /**
2
- * @name Card
3
- *
4
- * See the style guide: https://github.com/hyochan/style-guide/blob/main/docs/REACT.md
5
- */
6
- import React from 'react';
7
- import type {StyleProp, ViewStyle} from 'react-native';
8
- import {TouchableOpacity, View} from 'react-native';
9
- import {styled, css} from 'kstyled';
10
-
11
- import {useTheme} from '../../../providers/ThemeProvider';
12
-
13
- type Styles = {
14
- container?: StyleProp<ViewStyle>;
15
- content?: StyleProp<ViewStyle>;
16
- };
17
-
18
- export type CardProps = {
19
- testID?: string;
20
- children?: React.ReactNode;
21
- elevation?: number;
22
- borderRadius?: number;
23
- padding?: number;
24
- margin?: number;
25
- backgroundColor?: string;
26
- style?: StyleProp<ViewStyle>;
27
- styles?: Styles;
28
- onPress?: () => void;
29
- };
30
-
31
- export default function Card({
32
- testID = 'card-container',
33
- children,
34
- elevation = 2,
35
- borderRadius = 8,
36
- padding = 16,
37
- margin = 0,
38
- backgroundColor,
39
- style,
40
- styles,
41
- onPress,
42
- }: CardProps): JSX.Element {
43
- const {theme} = useTheme();
44
-
45
- const shadowStyle = React.useMemo(() => ({
46
- elevation: elevation,
47
- shadowOffset: {
48
- width: 0,
49
- height: elevation / 2,
50
- },
51
- shadowOpacity: 0.1,
52
- shadowRadius: elevation,
53
- shadowColor: theme.text.basic,
54
- }), [elevation, theme.text.basic]);
55
-
56
- const containerStyle = React.useMemo(() => [
57
- {
58
- backgroundColor: backgroundColor || theme.bg.paper,
59
- borderRadius: borderRadius,
60
- padding: padding,
61
- margin: margin,
62
- },
63
- shadowStyle,
64
- style,
65
- styles?.container,
66
- ], [backgroundColor, theme.bg.paper, borderRadius, padding, margin, shadowStyle, style, styles?.container]);
67
-
68
- if (onPress) {
69
- return (
70
- <TouchableContainer
71
- testID={testID}
72
- style={containerStyle}
73
- onPress={onPress}
74
- activeOpacity={0.8}
75
- >
76
- <View style={styles?.content}>
77
- {children}
78
- </View>
79
- </TouchableContainer>
80
- );
81
- }
82
-
83
- return (
84
- <Container testID={testID} style={containerStyle}>
85
- <View style={styles?.content}>
86
- {children}
87
- </View>
88
- </Container>
89
- );
90
- }
91
-
92
- const Container = styled.View`
93
- background-color: ${({theme}) => theme.bg.paper};
94
- border-radius: 8px;
95
- `;
96
-
97
- const TouchableContainer = styled.TouchableOpacity`
98
- background-color: ${({theme}) => theme.bg.paper};
99
- border-radius: 8px;
100
- `;
101
-
102
- export {Card};