uikit-react-public 0.26.3 → 0.27.1
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/BaseCheckbox/BaseCheckbox.d.ts +26 -0
- package/dist/components/BaseCheckbox/BaseCheckbox.stories.d.ts +29 -0
- package/dist/components/BaseCheckbox/__tests__/BaseCheckbox.test.d.ts +1 -0
- package/dist/components/BaseCheckbox/index.d.ts +2 -0
- package/dist/components/MenuNew/MenuAccordion/MenuAccordionItem.d.ts +2 -3
- package/dist/components/MenuNew/MenuBaseItem.d.ts +2 -1
- package/dist/components/MenuNew/index.d.ts +1 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/index.js +2865 -2776
- package/lib/components/BaseCheckbox/BaseCheckbox.stories.tsx +82 -0
- package/lib/components/BaseCheckbox/BaseCheckbox.tsx +168 -0
- package/lib/components/BaseCheckbox/__tests__/BaseCheckbox.test.tsx +98 -0
- package/lib/components/BaseCheckbox/index.ts +2 -0
- package/lib/components/Checkbox/Checkbox.tsx +49 -53
- package/lib/components/Checkbox/__tests__/__snapshots__/Checkbox.test.tsx.snap +66 -43
- package/lib/components/MenuNew/MenuAccordion/MenuAccordion.tsx +2 -1
- package/lib/components/MenuNew/MenuAccordion/MenuAccordionItem.tsx +7 -6
- package/lib/components/MenuNew/MenuBaseItem.tsx +17 -0
- package/lib/components/MenuNew/__tests__/Menu.test.tsx +64 -0
- package/lib/components/MenuNew/index.ts +1 -0
- package/lib/components/Table/subcomponents/Cell/__tests__/__snapshots__/Cell.test.tsx.snap +7 -2
- package/lib/components/Table/subcomponents/HeadCell/__tests__/__snapshots__/HeadCell.test.tsx.snap +7 -2
- package/lib/components/index.ts +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { useArgs } from '@storybook/preview-api';
|
|
3
|
+
|
|
4
|
+
import BaseCheckbox from './BaseCheckbox';
|
|
5
|
+
import Icon from '../Icon';
|
|
6
|
+
|
|
7
|
+
const meta = {
|
|
8
|
+
title: 'Components/BaseCheckbox',
|
|
9
|
+
component: BaseCheckbox,
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: 'centered',
|
|
12
|
+
},
|
|
13
|
+
argTypes: {
|
|
14
|
+
checked: { control: { type: 'boolean' } },
|
|
15
|
+
indeterminate: { control: { type: 'boolean' } },
|
|
16
|
+
disabled: { control: { type: 'boolean' } },
|
|
17
|
+
},
|
|
18
|
+
} satisfies Meta<typeof BaseCheckbox>;
|
|
19
|
+
|
|
20
|
+
export default meta;
|
|
21
|
+
type Story = StoryObj<typeof meta>;
|
|
22
|
+
|
|
23
|
+
export const Default: Story = {
|
|
24
|
+
args: {
|
|
25
|
+
checked: false,
|
|
26
|
+
indeterminate: false,
|
|
27
|
+
uncheckedComponent: <Icon.Square size={32} />,
|
|
28
|
+
checkedComponent: <Icon.CheckSquare size={32} />,
|
|
29
|
+
indeterminateComponent: <Icon.MinusSquare size={32} />,
|
|
30
|
+
},
|
|
31
|
+
render: (args) => {
|
|
32
|
+
const [, updateArgs] = useArgs();
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<BaseCheckbox
|
|
36
|
+
{...args}
|
|
37
|
+
onChange={(ev) => updateArgs({ checked: ev.target.checked })}
|
|
38
|
+
/>
|
|
39
|
+
);
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const RenderVisual: Story = {
|
|
44
|
+
args: {
|
|
45
|
+
checked: false,
|
|
46
|
+
indeterminate: false,
|
|
47
|
+
renderVisual: ({ checked, indeterminate }) => (
|
|
48
|
+
<Icon.Empty
|
|
49
|
+
size={32}
|
|
50
|
+
strokeLinecap='square'
|
|
51
|
+
strokeLinejoin='miter'
|
|
52
|
+
>
|
|
53
|
+
<rect
|
|
54
|
+
x='5'
|
|
55
|
+
y='5'
|
|
56
|
+
width='14'
|
|
57
|
+
height='14'
|
|
58
|
+
rx='2'
|
|
59
|
+
/>
|
|
60
|
+
{indeterminate && (
|
|
61
|
+
<line
|
|
62
|
+
x1='9'
|
|
63
|
+
y1='16'
|
|
64
|
+
x2='23'
|
|
65
|
+
y2='16'
|
|
66
|
+
/>
|
|
67
|
+
)}
|
|
68
|
+
{checked && <polyline points='23 11 14 20 10 16' />}
|
|
69
|
+
</Icon.Empty>
|
|
70
|
+
),
|
|
71
|
+
},
|
|
72
|
+
render: (args) => {
|
|
73
|
+
const [, updateArgs] = useArgs();
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<BaseCheckbox
|
|
77
|
+
{...args}
|
|
78
|
+
onChange={(ev) => updateArgs({ checked: ev.target.checked })}
|
|
79
|
+
/>
|
|
80
|
+
);
|
|
81
|
+
},
|
|
82
|
+
};
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ChangeEvent,
|
|
3
|
+
InputHTMLAttributes,
|
|
4
|
+
memo,
|
|
5
|
+
ReactNode,
|
|
6
|
+
Ref,
|
|
7
|
+
useCallback,
|
|
8
|
+
useEffect,
|
|
9
|
+
useRef,
|
|
10
|
+
useState,
|
|
11
|
+
} from 'react';
|
|
12
|
+
import { css, cx } from '@emotion/css';
|
|
13
|
+
|
|
14
|
+
export const NAME = 'ucl-uikit-base-checkbox';
|
|
15
|
+
|
|
16
|
+
export interface BaseCheckboxState {
|
|
17
|
+
checked: boolean;
|
|
18
|
+
indeterminate: boolean;
|
|
19
|
+
disabled: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface BaseCheckboxBaseProps extends Omit<
|
|
23
|
+
InputHTMLAttributes<HTMLInputElement>,
|
|
24
|
+
'type'
|
|
25
|
+
> {
|
|
26
|
+
indeterminate?: boolean;
|
|
27
|
+
testId?: string;
|
|
28
|
+
ref?: Ref<HTMLInputElement>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
type BaseCheckboxVisualProps =
|
|
32
|
+
| {
|
|
33
|
+
renderVisual: (state: BaseCheckboxState) => ReactNode;
|
|
34
|
+
checkedComponent?: never;
|
|
35
|
+
uncheckedComponent?: never;
|
|
36
|
+
indeterminateComponent?: never;
|
|
37
|
+
}
|
|
38
|
+
| {
|
|
39
|
+
renderVisual?: never;
|
|
40
|
+
checkedComponent: ReactNode;
|
|
41
|
+
uncheckedComponent: ReactNode;
|
|
42
|
+
indeterminateComponent?: ReactNode;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export type BaseCheckboxProps = BaseCheckboxBaseProps & BaseCheckboxVisualProps;
|
|
46
|
+
|
|
47
|
+
const BaseCheckbox = ({
|
|
48
|
+
renderVisual,
|
|
49
|
+
checkedComponent,
|
|
50
|
+
uncheckedComponent,
|
|
51
|
+
indeterminateComponent,
|
|
52
|
+
checked,
|
|
53
|
+
defaultChecked,
|
|
54
|
+
indeterminate = false,
|
|
55
|
+
disabled,
|
|
56
|
+
testId = NAME,
|
|
57
|
+
className,
|
|
58
|
+
onChange,
|
|
59
|
+
ref,
|
|
60
|
+
...props
|
|
61
|
+
}: BaseCheckboxProps) => {
|
|
62
|
+
const inputRef = useRef<HTMLInputElement | null>(null);
|
|
63
|
+
|
|
64
|
+
const isControlled = checked !== undefined;
|
|
65
|
+
const [internalChecked, setInternalChecked] = useState(
|
|
66
|
+
defaultChecked ?? false
|
|
67
|
+
);
|
|
68
|
+
const displayedChecked = isControlled ? checked : internalChecked;
|
|
69
|
+
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
if (inputRef.current) {
|
|
72
|
+
inputRef.current.indeterminate = indeterminate;
|
|
73
|
+
}
|
|
74
|
+
}, [indeterminate]);
|
|
75
|
+
|
|
76
|
+
const setRef = useCallback(
|
|
77
|
+
(node: HTMLInputElement | null) => {
|
|
78
|
+
inputRef.current = node;
|
|
79
|
+
|
|
80
|
+
if (typeof ref === 'function') {
|
|
81
|
+
ref(node);
|
|
82
|
+
} else if (ref) {
|
|
83
|
+
ref.current = node;
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
[ref]
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
const handleChange = (ev: ChangeEvent<HTMLInputElement>) => {
|
|
90
|
+
if (!isControlled) {
|
|
91
|
+
setInternalChecked(ev.target.checked);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
onChange?.(ev);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const rootStyle = css`
|
|
98
|
+
position: relative;
|
|
99
|
+
display: inline-grid;
|
|
100
|
+
cursor: ${disabled ? 'not-allowed' : 'pointer'};
|
|
101
|
+
`;
|
|
102
|
+
|
|
103
|
+
const inputStyle = css`
|
|
104
|
+
position: absolute;
|
|
105
|
+
inset: 0;
|
|
106
|
+
width: 100%;
|
|
107
|
+
height: 100%;
|
|
108
|
+
margin: 0;
|
|
109
|
+
padding: 0;
|
|
110
|
+
border: 0;
|
|
111
|
+
opacity: 0;
|
|
112
|
+
cursor: inherit;
|
|
113
|
+
`;
|
|
114
|
+
|
|
115
|
+
const visualStyle = css`
|
|
116
|
+
grid-area: 1 / 1;
|
|
117
|
+
line-height: 0;
|
|
118
|
+
pointer-events: none;
|
|
119
|
+
|
|
120
|
+
input:focus-visible + & {
|
|
121
|
+
outline: 2px solid currentColor;
|
|
122
|
+
outline-offset: 2px;
|
|
123
|
+
}
|
|
124
|
+
`;
|
|
125
|
+
|
|
126
|
+
const style = cx(NAME, rootStyle, className);
|
|
127
|
+
|
|
128
|
+
const visualState = {
|
|
129
|
+
checked: displayedChecked,
|
|
130
|
+
indeterminate,
|
|
131
|
+
disabled: !!disabled,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const visual = renderVisual
|
|
135
|
+
? renderVisual(visualState)
|
|
136
|
+
: indeterminate && indeterminateComponent
|
|
137
|
+
? indeterminateComponent
|
|
138
|
+
: displayedChecked
|
|
139
|
+
? checkedComponent
|
|
140
|
+
: uncheckedComponent;
|
|
141
|
+
|
|
142
|
+
return (
|
|
143
|
+
<span
|
|
144
|
+
className={style}
|
|
145
|
+
data-testid={testId}
|
|
146
|
+
>
|
|
147
|
+
<input
|
|
148
|
+
ref={setRef}
|
|
149
|
+
type='checkbox'
|
|
150
|
+
className={inputStyle}
|
|
151
|
+
{...props}
|
|
152
|
+
checked={isControlled ? checked : undefined}
|
|
153
|
+
defaultChecked={isControlled ? undefined : defaultChecked}
|
|
154
|
+
disabled={disabled}
|
|
155
|
+
aria-checked={indeterminate ? 'mixed' : props['aria-checked']}
|
|
156
|
+
onChange={handleChange}
|
|
157
|
+
/>
|
|
158
|
+
<span
|
|
159
|
+
className={visualStyle}
|
|
160
|
+
aria-hidden='true'
|
|
161
|
+
>
|
|
162
|
+
{visual}
|
|
163
|
+
</span>
|
|
164
|
+
</span>
|
|
165
|
+
);
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export default memo(BaseCheckbox);
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { describe, expect, test, vi } from 'vitest';
|
|
2
|
+
import { render } from '@testing-library/react';
|
|
3
|
+
import userEvent from '@testing-library/user-event';
|
|
4
|
+
|
|
5
|
+
import BaseCheckbox from '../BaseCheckbox';
|
|
6
|
+
|
|
7
|
+
describe('BaseCheckbox', () => {
|
|
8
|
+
test('renders the unchecked visual by default', () => {
|
|
9
|
+
const { getByText, queryByText } = render(
|
|
10
|
+
<BaseCheckbox
|
|
11
|
+
uncheckedComponent={<span>Unchecked</span>}
|
|
12
|
+
checkedComponent={<span>Checked</span>}
|
|
13
|
+
/>
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
expect(getByText('Unchecked')).toBeTruthy();
|
|
17
|
+
expect(queryByText('Checked')).toBeNull();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('renders the checked visual when checked', () => {
|
|
21
|
+
const { getByText, queryByText } = render(
|
|
22
|
+
<BaseCheckbox
|
|
23
|
+
checked
|
|
24
|
+
uncheckedComponent={<span>Unchecked</span>}
|
|
25
|
+
checkedComponent={<span>Checked</span>}
|
|
26
|
+
/>
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
expect(getByText('Checked')).toBeTruthy();
|
|
30
|
+
expect(queryByText('Unchecked')).toBeNull();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('renders the indeterminate visual when indeterminate', () => {
|
|
34
|
+
const { getByRole, getByText } = render(
|
|
35
|
+
<BaseCheckbox
|
|
36
|
+
checked
|
|
37
|
+
indeterminate
|
|
38
|
+
uncheckedComponent={<span>Unchecked</span>}
|
|
39
|
+
checkedComponent={<span>Checked</span>}
|
|
40
|
+
indeterminateComponent={<span>Indeterminate</span>}
|
|
41
|
+
/>
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
expect(getByText('Indeterminate')).toBeTruthy();
|
|
45
|
+
expect(getByRole('checkbox')).toHaveAttribute('aria-checked', 'mixed');
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('updates uncontrolled state when clicked', async () => {
|
|
49
|
+
const user = userEvent.setup();
|
|
50
|
+
const { getByRole, getByText } = render(
|
|
51
|
+
<BaseCheckbox
|
|
52
|
+
uncheckedComponent={<span>Unchecked</span>}
|
|
53
|
+
checkedComponent={<span>Checked</span>}
|
|
54
|
+
/>
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
await user.click(getByRole('checkbox'));
|
|
58
|
+
|
|
59
|
+
expect(getByText('Checked')).toBeTruthy();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test('calls onChange when clicked', async () => {
|
|
63
|
+
const user = userEvent.setup();
|
|
64
|
+
const onChange = vi.fn();
|
|
65
|
+
const { getByRole } = render(
|
|
66
|
+
<BaseCheckbox
|
|
67
|
+
uncheckedComponent={<span>Unchecked</span>}
|
|
68
|
+
checkedComponent={<span>Checked</span>}
|
|
69
|
+
onChange={onChange}
|
|
70
|
+
/>
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
await user.click(getByRole('checkbox'));
|
|
74
|
+
|
|
75
|
+
expect(onChange).toHaveBeenCalledTimes(1);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test('passes state to renderVisual', async () => {
|
|
79
|
+
const user = userEvent.setup();
|
|
80
|
+
const { getByRole, getByText } = render(
|
|
81
|
+
<BaseCheckbox
|
|
82
|
+
renderVisual={({ checked, indeterminate, disabled }) => (
|
|
83
|
+
<span>
|
|
84
|
+
{checked ? 'Checked' : 'Unchecked'}
|
|
85
|
+
{indeterminate ? ' mixed' : ''}
|
|
86
|
+
{disabled ? ' disabled' : ''}
|
|
87
|
+
</span>
|
|
88
|
+
)}
|
|
89
|
+
/>
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
expect(getByText('Unchecked')).toBeTruthy();
|
|
93
|
+
|
|
94
|
+
await user.click(getByRole('checkbox'));
|
|
95
|
+
|
|
96
|
+
expect(getByText('Checked')).toBeTruthy();
|
|
97
|
+
});
|
|
98
|
+
});
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
} from 'react';
|
|
8
8
|
import { css, cx } from '@emotion/css';
|
|
9
9
|
import useTheme from '../../theme/useTheme';
|
|
10
|
+
import BaseCheckbox from '../BaseCheckbox';
|
|
10
11
|
import Icon from '../Icon';
|
|
11
12
|
import marginsStyle, { MarginProps } from '../common/marginsStyle';
|
|
12
13
|
|
|
@@ -32,6 +33,7 @@ const Checkbox = forwardRef<Ref, CheckboxProps>(
|
|
|
32
33
|
testId = NAME,
|
|
33
34
|
ariaLabel,
|
|
34
35
|
className,
|
|
36
|
+
onChange,
|
|
35
37
|
...props
|
|
36
38
|
},
|
|
37
39
|
ref
|
|
@@ -48,12 +50,11 @@ const Checkbox = forwardRef<Ref, CheckboxProps>(
|
|
|
48
50
|
if (!isControlled) {
|
|
49
51
|
setInternalChecked(ev.target.checked);
|
|
50
52
|
}
|
|
51
|
-
|
|
53
|
+
onChange?.(ev);
|
|
52
54
|
};
|
|
53
55
|
|
|
54
56
|
const baseStyle = css`
|
|
55
57
|
position: relative;
|
|
56
|
-
display: inline-block;
|
|
57
58
|
width: 24px;
|
|
58
59
|
height: 24px;
|
|
59
60
|
flex-shrink: 0;
|
|
@@ -104,20 +105,6 @@ const Checkbox = forwardRef<Ref, CheckboxProps>(
|
|
|
104
105
|
className
|
|
105
106
|
);
|
|
106
107
|
|
|
107
|
-
const hiddenInputStyle = css`
|
|
108
|
-
cursor: inherit;
|
|
109
|
-
position: absolute;
|
|
110
|
-
opacity: 0;
|
|
111
|
-
left: -1px;
|
|
112
|
-
top: -1px;
|
|
113
|
-
width: calc(100% + 2px);
|
|
114
|
-
height: calc(100% + 2px);
|
|
115
|
-
border-radius: 2px;
|
|
116
|
-
border: none;
|
|
117
|
-
margin: 0;
|
|
118
|
-
padding: 0;
|
|
119
|
-
`;
|
|
120
|
-
|
|
121
108
|
const checkStyle = css`
|
|
122
109
|
position: absolute;
|
|
123
110
|
left: -1px;
|
|
@@ -135,43 +122,52 @@ const Checkbox = forwardRef<Ref, CheckboxProps>(
|
|
|
135
122
|
`;
|
|
136
123
|
|
|
137
124
|
return (
|
|
138
|
-
<
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
125
|
+
<BaseCheckbox
|
|
126
|
+
ref={ref}
|
|
127
|
+
className={style}
|
|
128
|
+
testId={`${testId}__root`}
|
|
129
|
+
data-testid={testId}
|
|
130
|
+
aria-label={ariaLabel}
|
|
131
|
+
checked={isControlled ? checked : undefined}
|
|
132
|
+
defaultChecked={isControlled ? undefined : defaultChecked}
|
|
133
|
+
disabled={disabled}
|
|
134
|
+
indeterminate={indeterminate}
|
|
135
|
+
renderVisual={(state) => {
|
|
136
|
+
if (state.indeterminate) {
|
|
137
|
+
return (
|
|
138
|
+
<Icon.Empty
|
|
139
|
+
className={indeterminateLineStyle}
|
|
140
|
+
size={24}
|
|
141
|
+
strokeLinecap='square'
|
|
142
|
+
>
|
|
143
|
+
<line
|
|
144
|
+
x1='7'
|
|
145
|
+
y1='12'
|
|
146
|
+
x2='17'
|
|
147
|
+
y2='12'
|
|
148
|
+
/>
|
|
149
|
+
</Icon.Empty>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (state.checked) {
|
|
154
|
+
return (
|
|
155
|
+
<Icon.Empty
|
|
156
|
+
className={checkStyle}
|
|
157
|
+
size={24}
|
|
158
|
+
strokeLinecap='square'
|
|
159
|
+
strokeLinejoin='miter'
|
|
160
|
+
>
|
|
161
|
+
<polyline points='17 9 10 16 7 13' />
|
|
162
|
+
</Icon.Empty>
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return null;
|
|
167
|
+
}}
|
|
168
|
+
onChange={handleChange}
|
|
169
|
+
{...props}
|
|
170
|
+
/>
|
|
175
171
|
);
|
|
176
172
|
}
|
|
177
173
|
);
|
|
@@ -2,86 +2,109 @@
|
|
|
2
2
|
|
|
3
3
|
exports[`Checkbox > snapshot: checked prop 1`] = `
|
|
4
4
|
<span
|
|
5
|
-
class="ucl-uikit-checkbox css-
|
|
5
|
+
class="ucl-uikit-base-checkbox ucl-uikit-checkbox css-ohh0va"
|
|
6
|
+
data-testid="ucl-uikit-checkbox__root"
|
|
6
7
|
>
|
|
7
8
|
<input
|
|
8
9
|
checked=""
|
|
9
|
-
class="css-
|
|
10
|
+
class="css-1bjd9qx"
|
|
10
11
|
data-testid="ucl-uikit-checkbox"
|
|
11
12
|
type="checkbox"
|
|
12
13
|
/>
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
fill="none"
|
|
17
|
-
height="24"
|
|
18
|
-
stroke="currentColor"
|
|
19
|
-
stroke-linecap="square"
|
|
20
|
-
stroke-linejoin="miter"
|
|
21
|
-
stroke-width="2"
|
|
22
|
-
viewBox="0 0 24 24"
|
|
23
|
-
width="24"
|
|
24
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
14
|
+
<span
|
|
15
|
+
aria-hidden="true"
|
|
16
|
+
class="css-1quq9cp"
|
|
25
17
|
>
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
18
|
+
<svg
|
|
19
|
+
class="ucl-uikit-icon css-1nacdsu"
|
|
20
|
+
data-testid="ucl-uikit-icon"
|
|
21
|
+
fill="none"
|
|
22
|
+
height="24"
|
|
23
|
+
stroke="currentColor"
|
|
24
|
+
stroke-linecap="square"
|
|
25
|
+
stroke-linejoin="miter"
|
|
26
|
+
stroke-width="2"
|
|
27
|
+
viewBox="0 0 24 24"
|
|
28
|
+
width="24"
|
|
29
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
30
|
+
>
|
|
31
|
+
<polyline
|
|
32
|
+
points="17 9 10 16 7 13"
|
|
33
|
+
/>
|
|
34
|
+
</svg>
|
|
35
|
+
</span>
|
|
30
36
|
</span>
|
|
31
37
|
`;
|
|
32
38
|
|
|
33
39
|
exports[`Checkbox > snapshot: indeterminate prop 1`] = `
|
|
34
40
|
<span
|
|
35
|
-
class="ucl-uikit-checkbox css-
|
|
41
|
+
class="ucl-uikit-base-checkbox ucl-uikit-checkbox css-ohh0va"
|
|
42
|
+
data-testid="ucl-uikit-checkbox__root"
|
|
36
43
|
>
|
|
37
44
|
<input
|
|
38
|
-
|
|
45
|
+
aria-checked="mixed"
|
|
46
|
+
class="css-1bjd9qx"
|
|
39
47
|
data-testid="ucl-uikit-checkbox"
|
|
40
48
|
type="checkbox"
|
|
41
49
|
/>
|
|
42
|
-
<
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
fill="none"
|
|
46
|
-
height="24"
|
|
47
|
-
stroke="currentColor"
|
|
48
|
-
stroke-linecap="square"
|
|
49
|
-
stroke-linejoin="round"
|
|
50
|
-
stroke-width="2"
|
|
51
|
-
viewBox="0 0 24 24"
|
|
52
|
-
width="24"
|
|
53
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
50
|
+
<span
|
|
51
|
+
aria-hidden="true"
|
|
52
|
+
class="css-1quq9cp"
|
|
54
53
|
>
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
54
|
+
<svg
|
|
55
|
+
class="ucl-uikit-icon css-2i3jn5"
|
|
56
|
+
data-testid="ucl-uikit-icon"
|
|
57
|
+
fill="none"
|
|
58
|
+
height="24"
|
|
59
|
+
stroke="currentColor"
|
|
60
|
+
stroke-linecap="square"
|
|
61
|
+
stroke-linejoin="round"
|
|
62
|
+
stroke-width="2"
|
|
63
|
+
viewBox="0 0 24 24"
|
|
64
|
+
width="24"
|
|
65
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
66
|
+
>
|
|
67
|
+
<line
|
|
68
|
+
x1="7"
|
|
69
|
+
x2="17"
|
|
70
|
+
y1="12"
|
|
71
|
+
y2="12"
|
|
72
|
+
/>
|
|
73
|
+
</svg>
|
|
74
|
+
</span>
|
|
62
75
|
</span>
|
|
63
76
|
`;
|
|
64
77
|
|
|
65
78
|
exports[`Checkbox > snapshot: no props 1`] = `
|
|
66
79
|
<span
|
|
67
|
-
class="ucl-uikit-checkbox css-
|
|
80
|
+
class="ucl-uikit-base-checkbox ucl-uikit-checkbox css-tfrbiv"
|
|
81
|
+
data-testid="ucl-uikit-checkbox__root"
|
|
68
82
|
>
|
|
69
83
|
<input
|
|
70
|
-
class="css-
|
|
84
|
+
class="css-1bjd9qx"
|
|
71
85
|
data-testid="ucl-uikit-checkbox"
|
|
72
86
|
type="checkbox"
|
|
73
87
|
/>
|
|
88
|
+
<span
|
|
89
|
+
aria-hidden="true"
|
|
90
|
+
class="css-1quq9cp"
|
|
91
|
+
/>
|
|
74
92
|
</span>
|
|
75
93
|
`;
|
|
76
94
|
|
|
77
95
|
exports[`Checkbox > snapshot: testId prop 1`] = `
|
|
78
96
|
<span
|
|
79
|
-
class="ucl-uikit-checkbox css-
|
|
97
|
+
class="ucl-uikit-base-checkbox ucl-uikit-checkbox css-tfrbiv"
|
|
98
|
+
data-testid="test123__root"
|
|
80
99
|
>
|
|
81
100
|
<input
|
|
82
|
-
class="css-
|
|
101
|
+
class="css-1bjd9qx"
|
|
83
102
|
data-testid="test123"
|
|
84
103
|
type="checkbox"
|
|
85
104
|
/>
|
|
105
|
+
<span
|
|
106
|
+
aria-hidden="true"
|
|
107
|
+
class="css-1quq9cp"
|
|
108
|
+
/>
|
|
86
109
|
</span>
|
|
87
110
|
`;
|
|
@@ -63,7 +63,8 @@ const MenuAccordion = ({
|
|
|
63
63
|
const bodyStyle = css`
|
|
64
64
|
display: grid;
|
|
65
65
|
grid-template-rows: 0fr;
|
|
66
|
-
width: 100
|
|
66
|
+
width: calc(100% + ${FOCUS_RING_GUTTER_PX * 2}px);
|
|
67
|
+
margin-left: -${FOCUS_RING_GUTTER_PX}px;
|
|
67
68
|
margin-top: 0;
|
|
68
69
|
overflow: hidden;
|
|
69
70
|
opacity: 0;
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { HTMLAttributes } from 'react';
|
|
2
1
|
import { css, cx } from '@emotion/css';
|
|
3
|
-
import MenuBaseItem from '../MenuBaseItem';
|
|
2
|
+
import MenuBaseItem, { MenuBaseItemProps } from '../MenuBaseItem';
|
|
4
3
|
import MenuItemText from '../MenuItemText';
|
|
5
4
|
import { useTheme } from '../../../theme';
|
|
6
5
|
|
|
7
6
|
export const NAME = 'ucl-uikit-menu__accordion-item';
|
|
8
7
|
const FOCUS_RING_GUTTER_PX = 6;
|
|
9
8
|
|
|
10
|
-
export interface MenuAccordionItemProps extends
|
|
11
|
-
|
|
9
|
+
export interface MenuAccordionItemProps extends Omit<
|
|
10
|
+
MenuBaseItemProps,
|
|
11
|
+
'iconPosition'
|
|
12
|
+
> {
|
|
12
13
|
testId?: string;
|
|
13
14
|
}
|
|
14
15
|
|
|
@@ -24,10 +25,10 @@ const MenuAccordionItem = ({
|
|
|
24
25
|
const baseStyle = css`
|
|
25
26
|
width: calc(100% - ${FOCUS_RING_GUTTER_PX * 2}px);
|
|
26
27
|
margin: 0 ${FOCUS_RING_GUTTER_PX}px;
|
|
27
|
-
padding-left:
|
|
28
|
+
padding-left: ${theme.padding.p40};
|
|
28
29
|
|
|
29
30
|
@media screen and (min-width: ${theme.breakpoints.tablet}px) {
|
|
30
|
-
padding: 0
|
|
31
|
+
padding: 0 ${theme.padding.p56};
|
|
31
32
|
}
|
|
32
33
|
`;
|
|
33
34
|
|