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,216 +0,0 @@
|
|
|
1
|
-
import {type ComponentProps} from 'react';
|
|
2
|
-
import {Text} from 'react-native';
|
|
3
|
-
import {css} from 'kstyled';
|
|
4
|
-
import type {Meta, StoryObj} from '@storybook/react';
|
|
5
|
-
|
|
6
|
-
import {withThemeProvider} from '../../../../.storybook/decorators';
|
|
7
|
-
import {Checkbox, CheckboxColor} from './Checkbox';
|
|
8
|
-
import {Typography} from '../Typography/Typography';
|
|
9
|
-
|
|
10
|
-
const colors: CheckboxColor[] = [
|
|
11
|
-
'primary',
|
|
12
|
-
'success',
|
|
13
|
-
'info',
|
|
14
|
-
'warning',
|
|
15
|
-
'danger',
|
|
16
|
-
'secondary',
|
|
17
|
-
];
|
|
18
|
-
|
|
19
|
-
const meta = {
|
|
20
|
-
title: 'Checkbox',
|
|
21
|
-
component: (props) => <Checkbox {...props} />,
|
|
22
|
-
parameters: {
|
|
23
|
-
notes: `
|
|
24
|
-
An animated Checkbox component with smooth transitions and flexible sizing options.
|
|
25
|
-
|
|
26
|
-
## Features
|
|
27
|
-
- **Smooth Animations**: Spring-based fade and scale animations
|
|
28
|
-
- **Flexible Sizing**: Preset sizes and custom numeric values
|
|
29
|
-
- **Color Variants**: Multiple color options for different contexts
|
|
30
|
-
- **Disabled State**: Can disable checkbox interaction
|
|
31
|
-
- **Icon Elements**: Add elements before or after the checkbox
|
|
32
|
-
- **Optimized Performance**: Memoized for better performance
|
|
33
|
-
|
|
34
|
-
## Size Options
|
|
35
|
-
- \`small\`: 16px checkbox
|
|
36
|
-
- \`medium\`: 20px checkbox (default)
|
|
37
|
-
- \`large\`: 24px checkbox
|
|
38
|
-
- Custom number: Any pixel value (e.g., \`size={28}\`)
|
|
39
|
-
|
|
40
|
-
## Animation Details
|
|
41
|
-
The checkbox uses two simultaneous animations:
|
|
42
|
-
- **Fade**: Opacity transition from 0 to 1
|
|
43
|
-
- **Scale**: Size transition from 0.8 to 1.0
|
|
44
|
-
|
|
45
|
-
## Usage
|
|
46
|
-
|
|
47
|
-
### With String Text
|
|
48
|
-
\`\`\`tsx
|
|
49
|
-
<Checkbox
|
|
50
|
-
checked={isChecked}
|
|
51
|
-
onPress={() => setIsChecked(!isChecked)}
|
|
52
|
-
size="medium"
|
|
53
|
-
color="primary"
|
|
54
|
-
text="Accept terms"
|
|
55
|
-
direction="right"
|
|
56
|
-
/>
|
|
57
|
-
\`\`\`
|
|
58
|
-
|
|
59
|
-
### With Custom Element
|
|
60
|
-
\`\`\`tsx
|
|
61
|
-
<Checkbox
|
|
62
|
-
checked={isChecked}
|
|
63
|
-
onPress={() => setIsChecked(!isChecked)}
|
|
64
|
-
size="large"
|
|
65
|
-
color="success"
|
|
66
|
-
text={<CustomComponent />}
|
|
67
|
-
direction="left"
|
|
68
|
-
/>
|
|
69
|
-
\`\`\`
|
|
70
|
-
`,
|
|
71
|
-
docs: {
|
|
72
|
-
description: {
|
|
73
|
-
component: `
|
|
74
|
-
An animated Checkbox component with smooth transitions and flexible sizing options.
|
|
75
|
-
|
|
76
|
-
## Features
|
|
77
|
-
- **Smooth Animations**: Spring-based fade and scale animations
|
|
78
|
-
- **Flexible Sizing**: Preset sizes and custom numeric values
|
|
79
|
-
- **Color Variants**: Multiple color options for different contexts
|
|
80
|
-
- **Disabled State**: Can disable checkbox interaction
|
|
81
|
-
- **Icon Elements**: Add elements before or after the checkbox
|
|
82
|
-
- **Optimized Performance**: Memoized for better performance
|
|
83
|
-
|
|
84
|
-
## Size Options
|
|
85
|
-
- \`small\`: 16px checkbox
|
|
86
|
-
- \`medium\`: 20px checkbox (default)
|
|
87
|
-
- \`large\`: 24px checkbox
|
|
88
|
-
- Custom number: Any pixel value (e.g., \`size={28}\`)
|
|
89
|
-
|
|
90
|
-
## Animation Details
|
|
91
|
-
The checkbox uses two simultaneous animations:
|
|
92
|
-
- **Fade**: Opacity transition from 0 to 1
|
|
93
|
-
- **Scale**: Size transition from 0.8 to 1.0
|
|
94
|
-
|
|
95
|
-
## Usage
|
|
96
|
-
|
|
97
|
-
### With String Text
|
|
98
|
-
\`\`\`tsx
|
|
99
|
-
<Checkbox
|
|
100
|
-
checked={isChecked}
|
|
101
|
-
onPress={() => setIsChecked(!isChecked)}
|
|
102
|
-
size="medium"
|
|
103
|
-
color="primary"
|
|
104
|
-
text="Accept terms"
|
|
105
|
-
direction="right"
|
|
106
|
-
/>
|
|
107
|
-
\`\`\`
|
|
108
|
-
|
|
109
|
-
### With Custom Element
|
|
110
|
-
\`\`\`tsx
|
|
111
|
-
<Checkbox
|
|
112
|
-
checked={isChecked}
|
|
113
|
-
onPress={() => setIsChecked(!isChecked)}
|
|
114
|
-
size="large"
|
|
115
|
-
color="success"
|
|
116
|
-
text={<CustomComponent />}
|
|
117
|
-
direction="left"
|
|
118
|
-
/>
|
|
119
|
-
\`\`\`
|
|
120
|
-
`,
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
argTypes: {
|
|
125
|
-
color: {
|
|
126
|
-
control: 'select',
|
|
127
|
-
options: colors,
|
|
128
|
-
description: 'Color variant of the checkbox',
|
|
129
|
-
},
|
|
130
|
-
size: {
|
|
131
|
-
control: 'radio',
|
|
132
|
-
options: ['small', 'medium', 'large', 16, 20, 24, 32],
|
|
133
|
-
description: 'Checkbox size: "small" (16px), "medium" (20px), "large" (24px), or custom number in pixels',
|
|
134
|
-
},
|
|
135
|
-
checked: {
|
|
136
|
-
defaultValue: false,
|
|
137
|
-
type: 'boolean',
|
|
138
|
-
description: 'Whether the checkbox is checked',
|
|
139
|
-
},
|
|
140
|
-
disabled: {
|
|
141
|
-
description: 'Disables checkbox interaction',
|
|
142
|
-
},
|
|
143
|
-
direction: {
|
|
144
|
-
control: 'radio',
|
|
145
|
-
options: ['left', 'right'],
|
|
146
|
-
description: 'Position of the text relative to the checkbox',
|
|
147
|
-
},
|
|
148
|
-
text: {
|
|
149
|
-
description: 'Text or custom element to display next to the checkbox',
|
|
150
|
-
},
|
|
151
|
-
},
|
|
152
|
-
decorators: [withThemeProvider],
|
|
153
|
-
} satisfies Meta<typeof Checkbox>;
|
|
154
|
-
|
|
155
|
-
export default meta;
|
|
156
|
-
|
|
157
|
-
type Story = StoryObj<typeof meta>;
|
|
158
|
-
|
|
159
|
-
export const Basic: Story = {
|
|
160
|
-
args: {
|
|
161
|
-
color: 'primary',
|
|
162
|
-
size: 'medium',
|
|
163
|
-
text: 'Click Checkbox!',
|
|
164
|
-
direction: 'right',
|
|
165
|
-
checked: false,
|
|
166
|
-
onPress: () => {},
|
|
167
|
-
},
|
|
168
|
-
argTypes: {
|
|
169
|
-
theme: {
|
|
170
|
-
control: 'select',
|
|
171
|
-
options: ['light', 'dark'],
|
|
172
|
-
},
|
|
173
|
-
},
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
export const WithLeftText: Story = {
|
|
177
|
-
args: {
|
|
178
|
-
color: 'primary',
|
|
179
|
-
size: 'medium',
|
|
180
|
-
text: 'Accept terms and conditions',
|
|
181
|
-
direction: 'left',
|
|
182
|
-
checked: false,
|
|
183
|
-
onPress: () => {},
|
|
184
|
-
},
|
|
185
|
-
argTypes: {
|
|
186
|
-
theme: {
|
|
187
|
-
control: 'select',
|
|
188
|
-
options: ['light', 'dark'],
|
|
189
|
-
},
|
|
190
|
-
},
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
export const WithCustomElement: Story = {
|
|
194
|
-
args: {
|
|
195
|
-
color: 'success',
|
|
196
|
-
size: 'large',
|
|
197
|
-
text: (
|
|
198
|
-
<Typography.Body2
|
|
199
|
-
style={css`
|
|
200
|
-
font-weight: bold;
|
|
201
|
-
`}
|
|
202
|
-
>
|
|
203
|
-
Custom Element
|
|
204
|
-
</Typography.Body2>
|
|
205
|
-
),
|
|
206
|
-
direction: 'right',
|
|
207
|
-
checked: true,
|
|
208
|
-
onPress: () => {},
|
|
209
|
-
},
|
|
210
|
-
argTypes: {
|
|
211
|
-
theme: {
|
|
212
|
-
control: 'select',
|
|
213
|
-
options: ['light', 'dark'],
|
|
214
|
-
},
|
|
215
|
-
},
|
|
216
|
-
};
|
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
import React, {type ReactElement} from 'react';
|
|
2
|
-
import {Text, View} from 'react-native';
|
|
3
|
-
import type {RenderAPI} from '@testing-library/react-native';
|
|
4
|
-
import {render} from '@testing-library/react-native';
|
|
5
|
-
|
|
6
|
-
import {createComponent} from '../../../../test/testUtils';
|
|
7
|
-
import {Checkbox, type CheckboxProps} from './Checkbox';
|
|
8
|
-
import {light} from '../../../utils/colors';
|
|
9
|
-
|
|
10
|
-
let testingLib: RenderAPI;
|
|
11
|
-
|
|
12
|
-
const Component = (props?: CheckboxProps): ReactElement =>
|
|
13
|
-
createComponent(<Checkbox {...props} />);
|
|
14
|
-
|
|
15
|
-
describe('[Checkbox]', () => {
|
|
16
|
-
it('should render without crashing', () => {
|
|
17
|
-
testingLib = render(Component());
|
|
18
|
-
|
|
19
|
-
const json = testingLib.toJSON();
|
|
20
|
-
|
|
21
|
-
expect(json).toBeTruthy();
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('should render `disabled` button', () => {
|
|
25
|
-
testingLib = render(
|
|
26
|
-
Component({
|
|
27
|
-
disabled: true,
|
|
28
|
-
}),
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
const json = testingLib.toJSON();
|
|
32
|
-
|
|
33
|
-
expect(json).toBeTruthy();
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('should render `startElement`', () => {
|
|
37
|
-
testingLib = render(
|
|
38
|
-
Component({
|
|
39
|
-
startElement: <View />,
|
|
40
|
-
}),
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
const json = testingLib.toJSON();
|
|
44
|
-
|
|
45
|
-
expect(json).toBeTruthy();
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('should render `endElement`', () => {
|
|
49
|
-
testingLib = render(
|
|
50
|
-
Component({
|
|
51
|
-
endElement: <View />,
|
|
52
|
-
}),
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
const json = testingLib.toJSON();
|
|
56
|
-
|
|
57
|
-
expect(json).toBeTruthy();
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
describe('colors', () => {
|
|
61
|
-
const colors = [
|
|
62
|
-
'primary',
|
|
63
|
-
'secondary',
|
|
64
|
-
'success',
|
|
65
|
-
'info',
|
|
66
|
-
'warning',
|
|
67
|
-
'danger',
|
|
68
|
-
];
|
|
69
|
-
|
|
70
|
-
it('should render all colors', () => {
|
|
71
|
-
testingLib = render(
|
|
72
|
-
createComponent(
|
|
73
|
-
<View>
|
|
74
|
-
{colors.map((color) => (
|
|
75
|
-
<Checkbox
|
|
76
|
-
key={color}
|
|
77
|
-
checked={true}
|
|
78
|
-
color={color as any}
|
|
79
|
-
/>
|
|
80
|
-
))}
|
|
81
|
-
</View>,
|
|
82
|
-
),
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
const json = testingLib.toJSON();
|
|
86
|
-
// $type is a transient prop used for styling only,
|
|
87
|
-
// so it's not accessible via props in tests
|
|
88
|
-
// Just verify the component renders correctly with all colors
|
|
89
|
-
expect(json).toBeTruthy();
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it('should render with specific color type and verify checked state', () => {
|
|
93
|
-
testingLib = render(
|
|
94
|
-
Component({
|
|
95
|
-
color: 'success',
|
|
96
|
-
checked: true,
|
|
97
|
-
}),
|
|
98
|
-
);
|
|
99
|
-
|
|
100
|
-
const checkbox = testingLib.getByTestId('cpk-ui-checkbox');
|
|
101
|
-
|
|
102
|
-
// While we can't directly test transient props ($type, $checked),
|
|
103
|
-
// we can verify the component renders and has the testID
|
|
104
|
-
expect(checkbox).toBeTruthy();
|
|
105
|
-
|
|
106
|
-
// The checkbox wrapper receives $checked prop which affects its styling
|
|
107
|
-
// We can verify it's rendered in checked state by checking the component structure
|
|
108
|
-
expect(checkbox).toBeDefined();
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it('should render unchecked state', () => {
|
|
112
|
-
testingLib = render(
|
|
113
|
-
Component({
|
|
114
|
-
color: 'primary',
|
|
115
|
-
checked: false,
|
|
116
|
-
}),
|
|
117
|
-
);
|
|
118
|
-
|
|
119
|
-
const checkbox = testingLib.getByTestId('cpk-ui-checkbox');
|
|
120
|
-
expect(checkbox).toBeTruthy();
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
describe('sizes', () => {
|
|
125
|
-
it('should render with small size', () => {
|
|
126
|
-
testingLib = render(
|
|
127
|
-
Component({
|
|
128
|
-
size: 'small',
|
|
129
|
-
checked: true,
|
|
130
|
-
}),
|
|
131
|
-
);
|
|
132
|
-
|
|
133
|
-
const checkbox = testingLib.getByTestId('cpk-ui-checkbox');
|
|
134
|
-
expect(checkbox).toBeTruthy();
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it('should render with medium size', () => {
|
|
138
|
-
testingLib = render(
|
|
139
|
-
Component({
|
|
140
|
-
size: 'medium',
|
|
141
|
-
checked: true,
|
|
142
|
-
}),
|
|
143
|
-
);
|
|
144
|
-
|
|
145
|
-
const checkbox = testingLib.getByTestId('cpk-ui-checkbox');
|
|
146
|
-
expect(checkbox).toBeTruthy();
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
it('should render with large size', () => {
|
|
150
|
-
testingLib = render(
|
|
151
|
-
Component({
|
|
152
|
-
size: 'large',
|
|
153
|
-
checked: true,
|
|
154
|
-
}),
|
|
155
|
-
);
|
|
156
|
-
|
|
157
|
-
const checkbox = testingLib.getByTestId('cpk-ui-checkbox');
|
|
158
|
-
expect(checkbox).toBeTruthy();
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
it('should render with custom numeric size', () => {
|
|
162
|
-
testingLib = render(
|
|
163
|
-
Component({
|
|
164
|
-
size: 24,
|
|
165
|
-
checked: true,
|
|
166
|
-
}),
|
|
167
|
-
);
|
|
168
|
-
|
|
169
|
-
const checkbox = testingLib.getByTestId('cpk-ui-checkbox');
|
|
170
|
-
expect(checkbox).toBeTruthy();
|
|
171
|
-
});
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
describe('accessibility', () => {
|
|
175
|
-
it('should have accessibilityRole="checkbox"', () => {
|
|
176
|
-
testingLib = render(
|
|
177
|
-
Component({
|
|
178
|
-
text: 'Accept terms',
|
|
179
|
-
}),
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
const json = testingLib.toJSON();
|
|
183
|
-
expect(json).toBeTruthy();
|
|
184
|
-
// The root element should have accessibilityRole
|
|
185
|
-
expect((json as any).props.accessibilityRole).toBe('checkbox');
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it('should use text as default accessibilityLabel', () => {
|
|
189
|
-
testingLib = render(
|
|
190
|
-
Component({
|
|
191
|
-
text: 'Accept terms',
|
|
192
|
-
}),
|
|
193
|
-
);
|
|
194
|
-
|
|
195
|
-
const json = testingLib.toJSON();
|
|
196
|
-
expect((json as any).props.accessibilityLabel).toBe('Accept terms');
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
it('should use custom accessibilityLabel when provided', () => {
|
|
200
|
-
testingLib = render(
|
|
201
|
-
Component({
|
|
202
|
-
text: 'Accept',
|
|
203
|
-
accessibilityLabel: 'Accept terms and conditions',
|
|
204
|
-
}),
|
|
205
|
-
);
|
|
206
|
-
|
|
207
|
-
const json = testingLib.toJSON();
|
|
208
|
-
expect((json as any).props.accessibilityLabel).toBe('Accept terms and conditions');
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
it('should have accessibilityState with checked=true when checked', () => {
|
|
212
|
-
testingLib = render(
|
|
213
|
-
Component({
|
|
214
|
-
text: 'Accept terms',
|
|
215
|
-
checked: true,
|
|
216
|
-
}),
|
|
217
|
-
);
|
|
218
|
-
|
|
219
|
-
const json = testingLib.toJSON();
|
|
220
|
-
expect((json as any).props.accessibilityState).toEqual({
|
|
221
|
-
checked: true,
|
|
222
|
-
disabled: false,
|
|
223
|
-
});
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
it('should have accessibilityState with checked=false when unchecked', () => {
|
|
227
|
-
testingLib = render(
|
|
228
|
-
Component({
|
|
229
|
-
text: 'Accept terms',
|
|
230
|
-
checked: false,
|
|
231
|
-
}),
|
|
232
|
-
);
|
|
233
|
-
|
|
234
|
-
const json = testingLib.toJSON();
|
|
235
|
-
expect((json as any).props.accessibilityState).toEqual({
|
|
236
|
-
checked: false,
|
|
237
|
-
disabled: false,
|
|
238
|
-
});
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
it('should have accessibilityState with disabled=true when disabled', () => {
|
|
242
|
-
testingLib = render(
|
|
243
|
-
Component({
|
|
244
|
-
text: 'Accept terms',
|
|
245
|
-
disabled: true,
|
|
246
|
-
}),
|
|
247
|
-
);
|
|
248
|
-
|
|
249
|
-
const json = testingLib.toJSON();
|
|
250
|
-
expect((json as any).props.accessibilityState).toEqual({
|
|
251
|
-
checked: false,
|
|
252
|
-
disabled: true,
|
|
253
|
-
});
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
it('should have undefined accessibilityLabel when text is ReactElement', () => {
|
|
257
|
-
testingLib = render(
|
|
258
|
-
Component({
|
|
259
|
-
text: <Text>Custom text</Text>,
|
|
260
|
-
}),
|
|
261
|
-
);
|
|
262
|
-
|
|
263
|
-
const json = testingLib.toJSON();
|
|
264
|
-
expect((json as any).props.accessibilityLabel).toBeUndefined();
|
|
265
|
-
});
|
|
266
|
-
});
|
|
267
|
-
});
|
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
import React, {useCallback, useEffect, useMemo, useRef, type ReactElement} from 'react';
|
|
2
|
-
import type {StyleProp, TextStyle, ViewStyle} from 'react-native';
|
|
3
|
-
import {Animated, Platform, TouchableOpacity, View} from 'react-native';
|
|
4
|
-
import {styled, css} from 'kstyled';
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
CheckboxWrapper,
|
|
8
|
-
CheckboxWrapperOutlined,
|
|
9
|
-
} from '../Styled/StyledComponents';
|
|
10
|
-
import {Icon} from '../Icon/Icon';
|
|
11
|
-
import {Typography} from '../Typography/Typography';
|
|
12
|
-
import {useTheme} from '../../../providers/ThemeProvider';
|
|
13
|
-
|
|
14
|
-
type Styles = {
|
|
15
|
-
container?: StyleProp<ViewStyle>;
|
|
16
|
-
checkbox?: StyleProp<ViewStyle>;
|
|
17
|
-
check?: ViewStyle;
|
|
18
|
-
text?: StyleProp<TextStyle>;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export type CheckboxColor =
|
|
22
|
-
| 'primary'
|
|
23
|
-
| 'secondary'
|
|
24
|
-
| 'success'
|
|
25
|
-
| 'danger'
|
|
26
|
-
| 'warning'
|
|
27
|
-
| 'info';
|
|
28
|
-
|
|
29
|
-
export type CheckboxSizeType = 'small' | 'medium' | 'large' | number;
|
|
30
|
-
|
|
31
|
-
export interface CheckboxProps {
|
|
32
|
-
onPress?: () => void;
|
|
33
|
-
style?: StyleProp<ViewStyle>;
|
|
34
|
-
styles?: Styles;
|
|
35
|
-
color?: CheckboxColor;
|
|
36
|
-
size?: CheckboxSizeType;
|
|
37
|
-
disabled?: boolean;
|
|
38
|
-
checked?: boolean;
|
|
39
|
-
text?: string | ReactElement;
|
|
40
|
-
direction?: 'left' | 'right';
|
|
41
|
-
accessibilityLabel?: string;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const Container = styled(TouchableOpacity)`
|
|
45
|
-
flex-direction: row;
|
|
46
|
-
align-items: center;
|
|
47
|
-
`;
|
|
48
|
-
|
|
49
|
-
const StyledCheckboxOutlined = styled(CheckboxWrapperOutlined)`
|
|
50
|
-
border-width: 1px;
|
|
51
|
-
margin: 0 6px;
|
|
52
|
-
|
|
53
|
-
justify-content: center;
|
|
54
|
-
align-items: center;
|
|
55
|
-
`;
|
|
56
|
-
|
|
57
|
-
// Create animated version for checkbox that needs animation
|
|
58
|
-
const AnimatedView = Animated.createAnimatedComponent(View);
|
|
59
|
-
const AnimatedCheckbox = styled(AnimatedView)`
|
|
60
|
-
margin: 0 6px;
|
|
61
|
-
|
|
62
|
-
justify-content: center;
|
|
63
|
-
align-items: center;
|
|
64
|
-
`;
|
|
65
|
-
|
|
66
|
-
const StyledCheck = styled(Icon)<{$checked?: boolean}>`
|
|
67
|
-
font-weight: bold;
|
|
68
|
-
color: ${({theme, $checked}) => ($checked ? theme.bg.basic : 'transparent')};
|
|
69
|
-
`;
|
|
70
|
-
|
|
71
|
-
export function Checkbox({
|
|
72
|
-
style,
|
|
73
|
-
styles,
|
|
74
|
-
text,
|
|
75
|
-
direction = 'right',
|
|
76
|
-
color = 'primary',
|
|
77
|
-
size = 'medium',
|
|
78
|
-
disabled = false,
|
|
79
|
-
checked = false,
|
|
80
|
-
onPress,
|
|
81
|
-
accessibilityLabel,
|
|
82
|
-
}: CheckboxProps): ReactElement {
|
|
83
|
-
const checkboxSize = typeof size === 'number'
|
|
84
|
-
? size
|
|
85
|
-
: size === 'small'
|
|
86
|
-
? 16
|
|
87
|
-
: size === 'large'
|
|
88
|
-
? 24
|
|
89
|
-
: 20;
|
|
90
|
-
|
|
91
|
-
const textFontSize = typeof size === 'number'
|
|
92
|
-
? size * 0.7
|
|
93
|
-
: size === 'small'
|
|
94
|
-
? 12
|
|
95
|
-
: size === 'large'
|
|
96
|
-
? 16
|
|
97
|
-
: 14;
|
|
98
|
-
// Separate animated values for fade and scale
|
|
99
|
-
const fadeAnim = useRef(new Animated.Value(checked ? 1 : 0)).current;
|
|
100
|
-
const scaleAnim = useRef(new Animated.Value(checked ? 1 : 0.8)).current; // Start from 0.8, not 0
|
|
101
|
-
const {theme} = useTheme();
|
|
102
|
-
|
|
103
|
-
// Memoize animation config
|
|
104
|
-
const animationConfig = useMemo(
|
|
105
|
-
() => ({
|
|
106
|
-
useNativeDriver: Platform.select({
|
|
107
|
-
web: false,
|
|
108
|
-
default: true,
|
|
109
|
-
}),
|
|
110
|
-
}),
|
|
111
|
-
[],
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
useEffect(() => {
|
|
115
|
-
Animated.parallel([
|
|
116
|
-
Animated.spring(fadeAnim, {
|
|
117
|
-
toValue: checked ? 1 : 0,
|
|
118
|
-
...animationConfig,
|
|
119
|
-
}),
|
|
120
|
-
Animated.spring(scaleAnim, {
|
|
121
|
-
toValue: checked ? 1 : 0.8, // Scale to 0.8 when unchecked, not 0
|
|
122
|
-
...animationConfig,
|
|
123
|
-
}),
|
|
124
|
-
]).start();
|
|
125
|
-
}, [fadeAnim, scaleAnim, checked, animationConfig]);
|
|
126
|
-
|
|
127
|
-
// Memoize container styles
|
|
128
|
-
const containerStyles = useMemo(
|
|
129
|
-
() => [
|
|
130
|
-
css`
|
|
131
|
-
flex: 1;
|
|
132
|
-
padding: 6px 0;
|
|
133
|
-
|
|
134
|
-
flex-direction: ${direction === 'left' ? 'row-reverse' : 'row'};
|
|
135
|
-
column-gap: 2px;
|
|
136
|
-
align-items: center;
|
|
137
|
-
`,
|
|
138
|
-
styles?.container,
|
|
139
|
-
],
|
|
140
|
-
[styles?.container, direction],
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
// Memoize checkbox size styles
|
|
144
|
-
const checkboxSizeStyles = useMemo(
|
|
145
|
-
() => ({
|
|
146
|
-
width: checkboxSize,
|
|
147
|
-
height: checkboxSize,
|
|
148
|
-
}),
|
|
149
|
-
[checkboxSize],
|
|
150
|
-
);
|
|
151
|
-
|
|
152
|
-
// Memoize animated styles
|
|
153
|
-
const animatedStyles = useMemo(
|
|
154
|
-
() => [
|
|
155
|
-
checkboxSizeStyles,
|
|
156
|
-
styles?.checkbox,
|
|
157
|
-
{
|
|
158
|
-
opacity: fadeAnim,
|
|
159
|
-
transform: [{scale: scaleAnim}],
|
|
160
|
-
},
|
|
161
|
-
],
|
|
162
|
-
[checkboxSizeStyles, styles?.checkbox, fadeAnim, scaleAnim],
|
|
163
|
-
);
|
|
164
|
-
|
|
165
|
-
// Memoize text styles
|
|
166
|
-
const textStyles = useMemo(
|
|
167
|
-
() => [
|
|
168
|
-
css`
|
|
169
|
-
font-size: ${textFontSize}px;
|
|
170
|
-
`,
|
|
171
|
-
styles?.text,
|
|
172
|
-
],
|
|
173
|
-
[textFontSize, styles?.text],
|
|
174
|
-
);
|
|
175
|
-
|
|
176
|
-
// Render text element
|
|
177
|
-
const TextElement = useMemo(() => {
|
|
178
|
-
if (!text) return null;
|
|
179
|
-
|
|
180
|
-
if (typeof text === 'string') {
|
|
181
|
-
return (
|
|
182
|
-
<Typography.Body2 style={textStyles}>
|
|
183
|
-
{text}
|
|
184
|
-
</Typography.Body2>
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return text;
|
|
189
|
-
}, [text, textStyles]);
|
|
190
|
-
|
|
191
|
-
return (
|
|
192
|
-
<Container
|
|
193
|
-
accessibilityLabel={accessibilityLabel ?? (typeof text === 'string' ? text : undefined)}
|
|
194
|
-
accessibilityRole="checkbox"
|
|
195
|
-
accessibilityState={{checked, disabled}}
|
|
196
|
-
activeOpacity={0.9}
|
|
197
|
-
disabled={disabled}
|
|
198
|
-
onPress={onPress}
|
|
199
|
-
style={style}
|
|
200
|
-
>
|
|
201
|
-
<View style={containerStyles}>
|
|
202
|
-
<StyledCheckboxOutlined
|
|
203
|
-
$checked={checked}
|
|
204
|
-
$disabled={disabled}
|
|
205
|
-
style={[checkboxSizeStyles, styles?.checkbox]}
|
|
206
|
-
testID="cpk-ui-checkbox"
|
|
207
|
-
$type={color}
|
|
208
|
-
>
|
|
209
|
-
<AnimatedCheckbox style={animatedStyles}>
|
|
210
|
-
<StyledCheck
|
|
211
|
-
$checked={checked}
|
|
212
|
-
name="Check"
|
|
213
|
-
size={checkboxSize * 0.7}
|
|
214
|
-
style={styles?.check}
|
|
215
|
-
/>
|
|
216
|
-
</AnimatedCheckbox>
|
|
217
|
-
</StyledCheckboxOutlined>
|
|
218
|
-
{TextElement}
|
|
219
|
-
</View>
|
|
220
|
-
</Container>
|
|
221
|
-
);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// Export memoized component for better performance
|
|
225
|
-
export default React.memo(Checkbox) as typeof Checkbox;
|