uikit-react-public 0.27.1 → 0.28.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/dist/components/Chip/Chip.d.ts +11 -0
- package/dist/components/Chip/Chip.stories.d.ts +25 -0
- package/dist/components/Chip/__tests__/Chip.test.d.ts +1 -0
- package/dist/components/Chip/index.d.ts +2 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/index.js +2961 -2819
- package/lib/components/BaseCheckbox/BaseCheckbox.tsx +1 -5
- package/lib/components/Checkbox/__tests__/__snapshots__/Checkbox.test.tsx.snap +4 -4
- package/lib/components/Chip/Chip.stories.tsx +37 -0
- package/lib/components/Chip/Chip.tsx +191 -0
- package/lib/components/Chip/__tests__/Chip.test.tsx +287 -0
- package/lib/components/Chip/__tests__/__snapshots__/Chip.test.tsx.snap +255 -0
- package/lib/components/Chip/index.ts +2 -0
- package/lib/components/MenuNew/MenuItemText.tsx +6 -0
- package/lib/components/MenuNew/__tests__/Menu.test.tsx +36 -0
- package/lib/components/Table/subcomponents/Cell/__tests__/__snapshots__/Cell.test.tsx.snap +1 -1
- package/lib/components/Table/subcomponents/HeadCell/__tests__/__snapshots__/HeadCell.test.tsx.snap +1 -1
- package/lib/components/index.ts +3 -0
- package/package.json +1 -1
|
@@ -116,11 +116,7 @@ const BaseCheckbox = ({
|
|
|
116
116
|
grid-area: 1 / 1;
|
|
117
117
|
line-height: 0;
|
|
118
118
|
pointer-events: none;
|
|
119
|
-
|
|
120
|
-
input:focus-visible + & {
|
|
121
|
-
outline: 2px solid currentColor;
|
|
122
|
-
outline-offset: 2px;
|
|
123
|
-
}
|
|
119
|
+
outline: none;
|
|
124
120
|
`;
|
|
125
121
|
|
|
126
122
|
const style = cx(NAME, rootStyle, className);
|
|
@@ -13,7 +13,7 @@ exports[`Checkbox > snapshot: checked prop 1`] = `
|
|
|
13
13
|
/>
|
|
14
14
|
<span
|
|
15
15
|
aria-hidden="true"
|
|
16
|
-
class="css-
|
|
16
|
+
class="css-g3adpt"
|
|
17
17
|
>
|
|
18
18
|
<svg
|
|
19
19
|
class="ucl-uikit-icon css-1nacdsu"
|
|
@@ -49,7 +49,7 @@ exports[`Checkbox > snapshot: indeterminate prop 1`] = `
|
|
|
49
49
|
/>
|
|
50
50
|
<span
|
|
51
51
|
aria-hidden="true"
|
|
52
|
-
class="css-
|
|
52
|
+
class="css-g3adpt"
|
|
53
53
|
>
|
|
54
54
|
<svg
|
|
55
55
|
class="ucl-uikit-icon css-2i3jn5"
|
|
@@ -87,7 +87,7 @@ exports[`Checkbox > snapshot: no props 1`] = `
|
|
|
87
87
|
/>
|
|
88
88
|
<span
|
|
89
89
|
aria-hidden="true"
|
|
90
|
-
class="css-
|
|
90
|
+
class="css-g3adpt"
|
|
91
91
|
/>
|
|
92
92
|
</span>
|
|
93
93
|
`;
|
|
@@ -104,7 +104,7 @@ exports[`Checkbox > snapshot: testId prop 1`] = `
|
|
|
104
104
|
/>
|
|
105
105
|
<span
|
|
106
106
|
aria-hidden="true"
|
|
107
|
-
class="css-
|
|
107
|
+
class="css-g3adpt"
|
|
108
108
|
/>
|
|
109
109
|
</span>
|
|
110
110
|
`;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { useArgs } from '@storybook/preview-api';
|
|
3
|
+
|
|
4
|
+
import Chip from './Chip';
|
|
5
|
+
|
|
6
|
+
const meta = {
|
|
7
|
+
title: 'Components/Chip',
|
|
8
|
+
component: Chip,
|
|
9
|
+
argTypes: {
|
|
10
|
+
label: { control: { type: 'text' } },
|
|
11
|
+
checked: { control: { type: 'boolean' } },
|
|
12
|
+
disabled: { control: { type: 'boolean' } },
|
|
13
|
+
},
|
|
14
|
+
} satisfies Meta<typeof Chip>;
|
|
15
|
+
|
|
16
|
+
export default meta;
|
|
17
|
+
type Story = StoryObj<typeof meta>;
|
|
18
|
+
|
|
19
|
+
export const Default: Story = {
|
|
20
|
+
args: {
|
|
21
|
+
label: 'Student',
|
|
22
|
+
checked: false,
|
|
23
|
+
disabled: false,
|
|
24
|
+
},
|
|
25
|
+
render: (args) => {
|
|
26
|
+
const [{ checked }, updateArgs] = useArgs();
|
|
27
|
+
const onChange = () => updateArgs({ checked: !checked });
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<Chip
|
|
31
|
+
{...args}
|
|
32
|
+
checked={checked}
|
|
33
|
+
onChange={onChange}
|
|
34
|
+
/>
|
|
35
|
+
);
|
|
36
|
+
},
|
|
37
|
+
};
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { memo, forwardRef } from 'react';
|
|
2
|
+
import { css, cx } from '@emotion/css';
|
|
3
|
+
import useTheme from '../../theme/useTheme';
|
|
4
|
+
import BaseCheckbox, { BaseCheckboxProps } from '../BaseCheckbox';
|
|
5
|
+
import Icon from '../Icon';
|
|
6
|
+
import Text from '../Text';
|
|
7
|
+
import marginsStyle, { MarginProps } from '../common/marginsStyle';
|
|
8
|
+
|
|
9
|
+
export const NAME = 'ucl-uikit-chip';
|
|
10
|
+
|
|
11
|
+
export interface ChipBaseProps extends Omit<
|
|
12
|
+
BaseCheckboxProps,
|
|
13
|
+
| 'renderVisual'
|
|
14
|
+
| 'checkedComponent'
|
|
15
|
+
| 'uncheckedComponent'
|
|
16
|
+
| 'indeterminateComponent'
|
|
17
|
+
| 'indeterminate'
|
|
18
|
+
> {
|
|
19
|
+
label: string;
|
|
20
|
+
ariaLabel?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type ChipProps = ChipBaseProps & MarginProps;
|
|
24
|
+
|
|
25
|
+
export type Ref = HTMLInputElement;
|
|
26
|
+
|
|
27
|
+
const Chip = forwardRef<Ref, ChipProps>(
|
|
28
|
+
(
|
|
29
|
+
{
|
|
30
|
+
label,
|
|
31
|
+
checked,
|
|
32
|
+
defaultChecked,
|
|
33
|
+
disabled,
|
|
34
|
+
testId = NAME,
|
|
35
|
+
ariaLabel,
|
|
36
|
+
className,
|
|
37
|
+
...props
|
|
38
|
+
},
|
|
39
|
+
ref
|
|
40
|
+
) => {
|
|
41
|
+
const [theme] = useTheme();
|
|
42
|
+
|
|
43
|
+
const baseStyle = css`
|
|
44
|
+
position: relative;
|
|
45
|
+
display: inline-flex;
|
|
46
|
+
align-items: center;
|
|
47
|
+
justify-content: center;
|
|
48
|
+
min-height: 32px;
|
|
49
|
+
width: fit-content;
|
|
50
|
+
padding: ${theme.margin.m4} ${theme.margin.m16};
|
|
51
|
+
border: ${theme.border.b1} solid ${theme.colour.icon.brand};
|
|
52
|
+
border-radius: 16px;
|
|
53
|
+
outline: none;
|
|
54
|
+
box-sizing: border-box;
|
|
55
|
+
color: ${theme.colour.icon.inverse};
|
|
56
|
+
transition:
|
|
57
|
+
background-color 0.15s ease-out,
|
|
58
|
+
border-color 0.15s ease-out;
|
|
59
|
+
cursor: pointer;
|
|
60
|
+
background-color: ${theme.colour.icon.inverse};
|
|
61
|
+
color: ${theme.colour.icon.brand};
|
|
62
|
+
|
|
63
|
+
&:hover {
|
|
64
|
+
background-color: ${theme.colour.fill.brandSubtleHover};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&:has(input:focus-visible) {
|
|
68
|
+
box-shadow: ${theme.boxShadow.focus};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
&:has(input:checked) {
|
|
72
|
+
background-color: ${theme.colour.icon.brandSelectedOnBgFill};
|
|
73
|
+
border-color: ${theme.colour.icon.brandSelectedOnBgFill};
|
|
74
|
+
color: ${theme.colour.icon.inverse};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
&:has(input:checked):hover {
|
|
78
|
+
background-color: ${theme.colour.icon.brandSelectedOnBgFill};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
&:has(input:disabled),
|
|
82
|
+
&:has(input:disabled):hover {
|
|
83
|
+
background-color: ${theme.colour.fill.disabled};
|
|
84
|
+
border-color: ${theme.colour.border.disabled};
|
|
85
|
+
color: ${theme.colour.text.disabled};
|
|
86
|
+
cursor: not-allowed;
|
|
87
|
+
}
|
|
88
|
+
`;
|
|
89
|
+
|
|
90
|
+
const style = cx(NAME, baseStyle, marginsStyle(props, theme), className);
|
|
91
|
+
|
|
92
|
+
const contentStyle = css`
|
|
93
|
+
display: inline-flex;
|
|
94
|
+
align-items: center;
|
|
95
|
+
justify-content: center;
|
|
96
|
+
`;
|
|
97
|
+
|
|
98
|
+
const iconBaseStyle = css`
|
|
99
|
+
flex-shrink: 0;
|
|
100
|
+
color: inherit;
|
|
101
|
+
user-select: none;
|
|
102
|
+
pointer-events: none;
|
|
103
|
+
transition:
|
|
104
|
+
opacity 0.15s ease-out,
|
|
105
|
+
margin-left 0.15s ease-out,
|
|
106
|
+
margin-right 0.15s ease-out;
|
|
107
|
+
|
|
108
|
+
@media (prefers-reduced-motion: reduce) {
|
|
109
|
+
transition: none;
|
|
110
|
+
}
|
|
111
|
+
`;
|
|
112
|
+
|
|
113
|
+
const iconVisibleStyle = css`
|
|
114
|
+
opacity: 1;
|
|
115
|
+
margin-left: 0;
|
|
116
|
+
margin-right: 0;
|
|
117
|
+
`;
|
|
118
|
+
|
|
119
|
+
const iconHiddenStyle = css`
|
|
120
|
+
opacity: 0;
|
|
121
|
+
margin-left: -4px;
|
|
122
|
+
margin-right: 4px;
|
|
123
|
+
`;
|
|
124
|
+
|
|
125
|
+
const labelBaseStyle = css`
|
|
126
|
+
color: inherit;
|
|
127
|
+
transition:
|
|
128
|
+
margin-left 0.15s ease-out,
|
|
129
|
+
margin-right 0.15s ease-out;
|
|
130
|
+
|
|
131
|
+
@media (prefers-reduced-motion: reduce) {
|
|
132
|
+
transition: none;
|
|
133
|
+
}
|
|
134
|
+
`;
|
|
135
|
+
|
|
136
|
+
const labelCheckedStyle = css`
|
|
137
|
+
margin-left: ${theme.margin.m4};
|
|
138
|
+
margin-right: 0;
|
|
139
|
+
`;
|
|
140
|
+
|
|
141
|
+
const labelUncheckedStyle = css`
|
|
142
|
+
margin-left: -6px;
|
|
143
|
+
margin-right: 10px;
|
|
144
|
+
`;
|
|
145
|
+
|
|
146
|
+
return (
|
|
147
|
+
<label className={style}>
|
|
148
|
+
<BaseCheckbox
|
|
149
|
+
ref={ref}
|
|
150
|
+
testId={`${testId}__root`}
|
|
151
|
+
data-testid={testId}
|
|
152
|
+
aria-label={ariaLabel}
|
|
153
|
+
checked={checked}
|
|
154
|
+
defaultChecked={defaultChecked}
|
|
155
|
+
disabled={disabled}
|
|
156
|
+
renderVisual={({ checked }) => {
|
|
157
|
+
const iconStyle = cx(
|
|
158
|
+
iconBaseStyle,
|
|
159
|
+
checked && iconVisibleStyle,
|
|
160
|
+
!checked && iconHiddenStyle
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
const labelStyle = cx(
|
|
164
|
+
labelBaseStyle,
|
|
165
|
+
checked && labelCheckedStyle,
|
|
166
|
+
!checked && labelUncheckedStyle
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
return (
|
|
170
|
+
<span className={contentStyle}>
|
|
171
|
+
<Icon.Check
|
|
172
|
+
className={iconStyle}
|
|
173
|
+
size={16}
|
|
174
|
+
/>
|
|
175
|
+
<Text
|
|
176
|
+
level='sm-semibold'
|
|
177
|
+
className={labelStyle}
|
|
178
|
+
>
|
|
179
|
+
{label}
|
|
180
|
+
</Text>
|
|
181
|
+
</span>
|
|
182
|
+
);
|
|
183
|
+
}}
|
|
184
|
+
{...props}
|
|
185
|
+
/>
|
|
186
|
+
</label>
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
export default memo(Chip);
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { createRef } from 'react';
|
|
2
|
+
import { describe, expect, test, vi } from 'vitest';
|
|
3
|
+
import { render, screen } from '@testing-library/react';
|
|
4
|
+
import userEvent from '@testing-library/user-event';
|
|
5
|
+
import { ThemeContextProvider } from '../../../theme/useTheme';
|
|
6
|
+
import Chip from '../Chip';
|
|
7
|
+
|
|
8
|
+
describe('Chip', () => {
|
|
9
|
+
test('snapshot: no props', () => {
|
|
10
|
+
const renderResult = render(
|
|
11
|
+
<ThemeContextProvider>
|
|
12
|
+
<Chip label='Student' />
|
|
13
|
+
</ThemeContextProvider>
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
expect(renderResult.container.firstChild).toMatchSnapshot();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('snapshot: checked prop', () => {
|
|
20
|
+
const renderResult = render(
|
|
21
|
+
<ThemeContextProvider>
|
|
22
|
+
<Chip
|
|
23
|
+
label='Student'
|
|
24
|
+
checked
|
|
25
|
+
onChange={() => {}}
|
|
26
|
+
/>
|
|
27
|
+
</ThemeContextProvider>
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
expect(renderResult.container.firstChild).toMatchSnapshot();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('snapshot: disabled prop', () => {
|
|
34
|
+
const renderResult = render(
|
|
35
|
+
<ThemeContextProvider>
|
|
36
|
+
<Chip
|
|
37
|
+
label='Student'
|
|
38
|
+
disabled
|
|
39
|
+
/>
|
|
40
|
+
</ThemeContextProvider>
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
expect(renderResult.container.firstChild).toMatchSnapshot();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('snapshot: disabled and checked props', () => {
|
|
47
|
+
const renderResult = render(
|
|
48
|
+
<ThemeContextProvider>
|
|
49
|
+
<Chip
|
|
50
|
+
label='Student'
|
|
51
|
+
checked
|
|
52
|
+
disabled
|
|
53
|
+
/>
|
|
54
|
+
</ThemeContextProvider>
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
expect(renderResult.container.firstChild).toMatchSnapshot();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('snapshot: testId prop', () => {
|
|
61
|
+
const renderResult = render(
|
|
62
|
+
<ThemeContextProvider>
|
|
63
|
+
<Chip
|
|
64
|
+
label='Student'
|
|
65
|
+
testId='test123'
|
|
66
|
+
/>
|
|
67
|
+
</ThemeContextProvider>
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
expect(renderResult.container.firstChild).toMatchSnapshot();
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test('checked prop: controlled state does not toggle without rerender', async () => {
|
|
74
|
+
const user = userEvent.setup();
|
|
75
|
+
const handleChange = vi.fn();
|
|
76
|
+
|
|
77
|
+
render(
|
|
78
|
+
<ThemeContextProvider>
|
|
79
|
+
<Chip
|
|
80
|
+
label='Student'
|
|
81
|
+
checked
|
|
82
|
+
onChange={handleChange}
|
|
83
|
+
/>
|
|
84
|
+
</ThemeContextProvider>
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const checkbox = screen.getByRole('checkbox') as HTMLInputElement;
|
|
88
|
+
expect(checkbox.checked).toBe(true);
|
|
89
|
+
|
|
90
|
+
await user.click(checkbox);
|
|
91
|
+
expect(handleChange).toHaveBeenCalledTimes(1);
|
|
92
|
+
expect(checkbox.checked).toBe(true);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test('defaultChecked prop: initializes as checked in uncontrolled mode', () => {
|
|
96
|
+
render(
|
|
97
|
+
<ThemeContextProvider>
|
|
98
|
+
<Chip
|
|
99
|
+
label='Student'
|
|
100
|
+
defaultChecked
|
|
101
|
+
/>
|
|
102
|
+
</ThemeContextProvider>
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
const checkbox = screen.getByRole('checkbox') as HTMLInputElement;
|
|
106
|
+
expect(checkbox.checked).toBe(true);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test('test ID: default', () => {
|
|
110
|
+
render(
|
|
111
|
+
<ThemeContextProvider>
|
|
112
|
+
<Chip label='Student' />
|
|
113
|
+
</ThemeContextProvider>
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
const chip = screen.getByTestId('ucl-uikit-chip');
|
|
117
|
+
expect(chip).toBeDefined();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test('test ID: custom', () => {
|
|
121
|
+
render(
|
|
122
|
+
<ThemeContextProvider>
|
|
123
|
+
<Chip
|
|
124
|
+
label='Student'
|
|
125
|
+
testId='custom-test-id'
|
|
126
|
+
/>
|
|
127
|
+
</ThemeContextProvider>
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
const chip = screen.getByTestId('custom-test-id');
|
|
131
|
+
expect(chip).toBeDefined();
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test('click: uncontrolled via checkbox', async () => {
|
|
135
|
+
const user = userEvent.setup();
|
|
136
|
+
const handleChange = vi.fn();
|
|
137
|
+
|
|
138
|
+
render(
|
|
139
|
+
<ThemeContextProvider>
|
|
140
|
+
<Chip
|
|
141
|
+
label='Student'
|
|
142
|
+
onChange={handleChange}
|
|
143
|
+
/>
|
|
144
|
+
</ThemeContextProvider>
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
const checkbox = screen.getByRole('checkbox') as HTMLInputElement;
|
|
148
|
+
expect(checkbox.checked).toBe(false);
|
|
149
|
+
|
|
150
|
+
await user.click(checkbox);
|
|
151
|
+
expect(checkbox.checked).toBe(true);
|
|
152
|
+
expect(handleChange).toHaveBeenCalledTimes(1);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test('click: label toggles checkbox', async () => {
|
|
156
|
+
const user = userEvent.setup();
|
|
157
|
+
const handleChange = vi.fn();
|
|
158
|
+
|
|
159
|
+
render(
|
|
160
|
+
<ThemeContextProvider>
|
|
161
|
+
<Chip
|
|
162
|
+
label='Student'
|
|
163
|
+
onChange={handleChange}
|
|
164
|
+
/>
|
|
165
|
+
</ThemeContextProvider>
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
const checkbox = screen.getByRole('checkbox') as HTMLInputElement;
|
|
169
|
+
const label = screen.getByText('Student').closest('label');
|
|
170
|
+
expect(checkbox.checked).toBe(false);
|
|
171
|
+
expect(label).not.toBeNull();
|
|
172
|
+
|
|
173
|
+
await user.click(label!);
|
|
174
|
+
expect(checkbox.checked).toBe(true);
|
|
175
|
+
expect(handleChange).toHaveBeenCalledTimes(1);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
test('click: disabled', async () => {
|
|
179
|
+
const user = userEvent.setup();
|
|
180
|
+
const handleChange = vi.fn();
|
|
181
|
+
|
|
182
|
+
render(
|
|
183
|
+
<ThemeContextProvider>
|
|
184
|
+
<Chip
|
|
185
|
+
label='Student'
|
|
186
|
+
disabled
|
|
187
|
+
onChange={handleChange}
|
|
188
|
+
/>
|
|
189
|
+
</ThemeContextProvider>
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
const checkbox = screen.getByRole('checkbox') as HTMLInputElement;
|
|
193
|
+
const label = screen.getByText('Student').closest('label');
|
|
194
|
+
expect(checkbox.checked).toBe(false);
|
|
195
|
+
expect(label).not.toBeNull();
|
|
196
|
+
|
|
197
|
+
await user.click(label!);
|
|
198
|
+
expect(checkbox.checked).toBe(false);
|
|
199
|
+
expect(handleChange).not.toHaveBeenCalled();
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
test('click: disabled and checked remains checked', async () => {
|
|
203
|
+
const user = userEvent.setup();
|
|
204
|
+
const handleChange = vi.fn();
|
|
205
|
+
|
|
206
|
+
render(
|
|
207
|
+
<ThemeContextProvider>
|
|
208
|
+
<Chip
|
|
209
|
+
label='Student'
|
|
210
|
+
checked
|
|
211
|
+
disabled
|
|
212
|
+
onChange={handleChange}
|
|
213
|
+
/>
|
|
214
|
+
</ThemeContextProvider>
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
const checkbox = screen.getByRole('checkbox') as HTMLInputElement;
|
|
218
|
+
const label = screen.getByText('Student').closest('label');
|
|
219
|
+
expect(checkbox.checked).toBe(true);
|
|
220
|
+
expect(label).not.toBeNull();
|
|
221
|
+
|
|
222
|
+
await user.click(label!);
|
|
223
|
+
expect(checkbox.checked).toBe(true);
|
|
224
|
+
expect(handleChange).not.toHaveBeenCalled();
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
test('uses BaseCheckbox', () => {
|
|
228
|
+
render(
|
|
229
|
+
<ThemeContextProvider>
|
|
230
|
+
<Chip label='Student' />
|
|
231
|
+
</ThemeContextProvider>
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
const root = screen.getByTestId('ucl-uikit-chip__root');
|
|
235
|
+
|
|
236
|
+
expect(root).toHaveClass('ucl-uikit-base-checkbox');
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
test('ariaLabel prop is applied to the input as aria-label', () => {
|
|
240
|
+
render(
|
|
241
|
+
<ThemeContextProvider>
|
|
242
|
+
<Chip
|
|
243
|
+
label='Student'
|
|
244
|
+
ariaLabel='Select student'
|
|
245
|
+
/>
|
|
246
|
+
</ThemeContextProvider>
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
expect(screen.getByRole('checkbox')).toHaveAttribute(
|
|
250
|
+
'aria-label',
|
|
251
|
+
'Select student'
|
|
252
|
+
);
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
test('aria-label passed via spread props overrides ariaLabel', () => {
|
|
256
|
+
render(
|
|
257
|
+
<ThemeContextProvider>
|
|
258
|
+
<Chip
|
|
259
|
+
label='Student'
|
|
260
|
+
ariaLabel='Default label'
|
|
261
|
+
aria-label='Override label'
|
|
262
|
+
/>
|
|
263
|
+
</ThemeContextProvider>
|
|
264
|
+
);
|
|
265
|
+
|
|
266
|
+
expect(screen.getByRole('checkbox')).toHaveAttribute(
|
|
267
|
+
'aria-label',
|
|
268
|
+
'Override label'
|
|
269
|
+
);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
test('ref is forwarded to the underlying input element', () => {
|
|
273
|
+
const ref = createRef<HTMLInputElement>();
|
|
274
|
+
|
|
275
|
+
render(
|
|
276
|
+
<ThemeContextProvider>
|
|
277
|
+
<Chip
|
|
278
|
+
label='Student'
|
|
279
|
+
ref={ref}
|
|
280
|
+
/>
|
|
281
|
+
</ThemeContextProvider>
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
expect(ref.current).toBeInstanceOf(HTMLInputElement);
|
|
285
|
+
expect(ref.current).toBe(screen.getByRole('checkbox'));
|
|
286
|
+
});
|
|
287
|
+
});
|