@arbor-education/design-system.components 0.1.5 → 0.2.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/CHANGELOG.md +6 -0
- package/dist/components/formField/fieldset/Fieldset.d.ts +6 -0
- package/dist/components/formField/fieldset/Fieldset.d.ts.map +1 -0
- package/dist/components/formField/fieldset/Fieldset.js +7 -0
- package/dist/components/formField/fieldset/Fieldset.js.map +1 -0
- package/dist/components/formField/fieldset/Fieldset.stories.d.ts +28 -0
- package/dist/components/formField/fieldset/Fieldset.stories.d.ts.map +1 -0
- package/dist/components/formField/fieldset/Fieldset.stories.js +51 -0
- package/dist/components/formField/fieldset/Fieldset.stories.js.map +1 -0
- package/dist/components/formField/fieldset/Fieldset.test.d.ts +2 -0
- package/dist/components/formField/fieldset/Fieldset.test.d.ts.map +1 -0
- package/dist/components/formField/fieldset/Fieldset.test.js +62 -0
- package/dist/components/formField/fieldset/Fieldset.test.js.map +1 -0
- package/dist/components/formField/inputs/checkbox/CheckboxGroup.d.ts +8 -0
- package/dist/components/formField/inputs/checkbox/CheckboxGroup.d.ts.map +1 -0
- package/dist/components/formField/inputs/checkbox/CheckboxGroup.js +8 -0
- package/dist/components/formField/inputs/checkbox/CheckboxGroup.js.map +1 -0
- package/dist/components/formField/inputs/checkbox/CheckboxGroup.test.d.ts +2 -0
- package/dist/components/formField/inputs/checkbox/CheckboxGroup.test.d.ts.map +1 -0
- package/dist/components/formField/inputs/checkbox/CheckboxGroup.test.js +86 -0
- package/dist/components/formField/inputs/checkbox/CheckboxGroup.test.js.map +1 -0
- package/dist/components/formField/inputs/checkbox/CheckboxInput.stories.d.ts +3 -1
- package/dist/components/formField/inputs/checkbox/CheckboxInput.stories.d.ts.map +1 -1
- package/dist/components/formField/inputs/checkbox/CheckboxInput.stories.js +7 -0
- package/dist/components/formField/inputs/checkbox/CheckboxInput.stories.js.map +1 -1
- package/dist/components/formField/inputs/radio/RadioButtonGroup.d.ts +11 -0
- package/dist/components/formField/inputs/radio/RadioButtonGroup.d.ts.map +1 -0
- package/dist/components/formField/inputs/radio/RadioButtonGroup.js +8 -0
- package/dist/components/formField/inputs/radio/RadioButtonGroup.js.map +1 -0
- package/dist/components/formField/inputs/radio/RadioButtonGroup.test.d.ts +2 -0
- package/dist/components/formField/inputs/radio/RadioButtonGroup.test.d.ts.map +1 -0
- package/dist/components/formField/inputs/radio/RadioButtonGroup.test.js +86 -0
- package/dist/components/formField/inputs/radio/RadioButtonGroup.test.js.map +1 -0
- package/dist/components/formField/inputs/radio/RadioButtonInput.stories.d.ts.map +1 -1
- package/dist/components/formField/inputs/radio/RadioButtonInput.stories.js +8 -2
- package/dist/components/formField/inputs/radio/RadioButtonInput.stories.js.map +1 -1
- package/dist/components/separator/Separator.d.ts +7 -0
- package/dist/components/separator/Separator.d.ts.map +1 -0
- package/dist/components/separator/Separator.js +8 -0
- package/dist/components/separator/Separator.js.map +1 -0
- package/dist/components/separator/Separator.stories.d.ts +10 -0
- package/dist/components/separator/Separator.stories.d.ts.map +1 -0
- package/dist/components/separator/Separator.stories.js +12 -0
- package/dist/components/separator/Separator.stories.js.map +1 -0
- package/dist/components/separator/Separator.test.d.ts +2 -0
- package/dist/components/separator/Separator.test.d.ts.map +1 -0
- package/dist/components/separator/Separator.test.js +10 -0
- package/dist/components/separator/Separator.test.js.map +1 -0
- package/dist/components/table/Table.d.ts +13 -0
- package/dist/components/table/Table.d.ts.map +1 -1
- package/dist/components/table/Table.js +43 -7
- package/dist/components/table/Table.js.map +1 -1
- package/dist/components/table/Table.stories.d.ts.map +1 -1
- package/dist/components/table/Table.stories.js +8 -1
- package/dist/components/table/Table.stories.js.map +1 -1
- package/dist/components/table/Table.test.js +254 -2
- package/dist/components/table/Table.test.js.map +1 -1
- package/dist/components/table/pagination/TableSettingsDropdown.d.ts +2 -0
- package/dist/components/table/pagination/TableSettingsDropdown.d.ts.map +1 -0
- package/dist/components/table/pagination/TableSettingsDropdown.js +43 -0
- package/dist/components/table/pagination/TableSettingsDropdown.js.map +1 -0
- package/dist/components/table/useTableSettings.d.ts +22 -0
- package/dist/components/table/useTableSettings.d.ts.map +1 -0
- package/dist/components/table/useTableSettings.js +28 -0
- package/dist/components/table/useTableSettings.js.map +1 -0
- package/dist/index.css +31 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/hooks/useComponentDidUpdate.d.ts +7 -0
- package/dist/utils/hooks/useComponentDidUpdate.d.ts.map +1 -0
- package/dist/utils/hooks/useComponentDidUpdate.js +18 -0
- package/dist/utils/hooks/useComponentDidUpdate.js.map +1 -0
- package/dist/utils/hooks/useComponentDidUpdate.test.d.ts +2 -0
- package/dist/utils/hooks/useComponentDidUpdate.test.d.ts.map +1 -0
- package/dist/utils/hooks/useComponentDidUpdate.test.js +69 -0
- package/dist/utils/hooks/useComponentDidUpdate.test.js.map +1 -0
- package/package.json +1 -1
- package/src/components/formField/fieldset/Fieldset.stories.tsx +89 -0
- package/src/components/formField/fieldset/Fieldset.test.tsx +85 -0
- package/src/components/formField/fieldset/Fieldset.tsx +17 -0
- package/src/components/formField/fieldset/fieldset.scss +19 -0
- package/src/components/formField/inputs/checkbox/CheckboxGroup.test.tsx +127 -0
- package/src/components/formField/inputs/checkbox/CheckboxGroup.tsx +17 -0
- package/src/components/formField/inputs/checkbox/CheckboxInput.stories.tsx +12 -1
- package/src/components/formField/inputs/radio/RadioButtonGroup.test.tsx +190 -0
- package/src/components/formField/inputs/radio/RadioButtonGroup.tsx +22 -0
- package/src/components/formField/inputs/radio/RadioButtonInput.stories.tsx +16 -7
- package/src/components/formField/label/label.scss +1 -1
- package/src/components/separator/Separator.stories.tsx +15 -0
- package/src/components/separator/Separator.test.tsx +10 -0
- package/src/components/separator/Separator.tsx +15 -0
- package/src/components/separator/separator.scss +6 -0
- package/src/components/table/Table.stories.tsx +8 -1
- package/src/components/table/Table.test.tsx +444 -1
- package/src/components/table/Table.tsx +69 -24
- package/src/components/table/pagination/TableSettingsDropdown.tsx +90 -0
- package/src/components/table/table.scss +6 -0
- package/src/components/table/useTableSettings.ts +47 -0
- package/src/index.scss +2 -0
- package/src/index.ts +2 -0
- package/src/utils/hooks/useComponentDidUpdate.test.ts +107 -0
- package/src/utils/hooks/useComponentDidUpdate.ts +19 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { expect, test, describe, vi } from 'vitest';
|
|
2
|
+
import { CheckboxGroup } from './CheckboxGroup';
|
|
3
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
4
|
+
import '@testing-library/jest-dom/vitest';
|
|
5
|
+
|
|
6
|
+
describe('CheckboxGroup component', () => {
|
|
7
|
+
const mockOptions = [
|
|
8
|
+
{ id: 'option1', label: 'Option 1', checked: false, onChange: vi.fn() },
|
|
9
|
+
{ id: 'option2', label: 'Option 2', checked: true, onChange: vi.fn() },
|
|
10
|
+
{ id: 'option3', label: 'Option 3', checked: false, onChange: vi.fn() },
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
test('renders fieldset with legend', () => {
|
|
14
|
+
render(
|
|
15
|
+
<CheckboxGroup legend="Choose options" options={mockOptions} />,
|
|
16
|
+
);
|
|
17
|
+
expect(screen.getByText('Choose options')).toBeInTheDocument();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('renders all checkbox options', () => {
|
|
21
|
+
render(
|
|
22
|
+
<CheckboxGroup legend="Choose options" options={mockOptions} />,
|
|
23
|
+
);
|
|
24
|
+
expect(screen.getByRole('checkbox', { name: 'Option 1' })).toBeInTheDocument();
|
|
25
|
+
expect(screen.getByRole('checkbox', { name: 'Option 2' })).toBeInTheDocument();
|
|
26
|
+
expect(screen.getByRole('checkbox', { name: 'Option 3' })).toBeInTheDocument();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('applies checked state to checkboxes', () => {
|
|
30
|
+
render(
|
|
31
|
+
<CheckboxGroup legend="Choose options" options={mockOptions} />,
|
|
32
|
+
);
|
|
33
|
+
const option1 = screen.getByRole('checkbox', { name: 'Option 1' }) as HTMLInputElement;
|
|
34
|
+
const option2 = screen.getByRole('checkbox', { name: 'Option 2' }) as HTMLInputElement;
|
|
35
|
+
const option3 = screen.getByRole('checkbox', { name: 'Option 3' }) as HTMLInputElement;
|
|
36
|
+
|
|
37
|
+
expect(option1.checked).toBe(false);
|
|
38
|
+
expect(option2.checked).toBe(true);
|
|
39
|
+
expect(option3.checked).toBe(false);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('calls onChange when a checkbox is clicked', () => {
|
|
43
|
+
const handleChange1 = vi.fn();
|
|
44
|
+
const options = [
|
|
45
|
+
{ id: 'option1', label: 'Option 1', checked: false, onChange: handleChange1, value: 'value1' },
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
render(
|
|
49
|
+
<CheckboxGroup legend="Choose options" options={options} />,
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
const checkbox = screen.getByRole('checkbox', { name: 'Option 1' });
|
|
53
|
+
fireEvent.click(checkbox);
|
|
54
|
+
expect(handleChange1).toHaveBeenCalledExactlyOnceWith(
|
|
55
|
+
expect.objectContaining({
|
|
56
|
+
target: checkbox,
|
|
57
|
+
}),
|
|
58
|
+
);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('renders empty group when options array is empty', () => {
|
|
62
|
+
render(
|
|
63
|
+
<CheckboxGroup legend="Choose options" options={[]} />,
|
|
64
|
+
);
|
|
65
|
+
expect(screen.getByText('Choose options')).toBeInTheDocument();
|
|
66
|
+
const checkboxes = screen.queryAllByRole('checkbox');
|
|
67
|
+
expect(checkboxes).toHaveLength(0);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('passes through fieldset props', () => {
|
|
71
|
+
render(
|
|
72
|
+
<CheckboxGroup
|
|
73
|
+
legend="Choose options"
|
|
74
|
+
options={mockOptions}
|
|
75
|
+
className="custom-class"
|
|
76
|
+
data-testid="test-fieldset"
|
|
77
|
+
/>,
|
|
78
|
+
);
|
|
79
|
+
const fieldset = screen.getByTestId('test-fieldset');
|
|
80
|
+
expect(fieldset).toBeInTheDocument();
|
|
81
|
+
expect(fieldset).toHaveClass('custom-class');
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test('renders options without labels', () => {
|
|
85
|
+
const optionsWithoutLabels = [
|
|
86
|
+
{ id: 'option1', checked: false, onChange: vi.fn() },
|
|
87
|
+
{ id: 'option2', checked: false, onChange: vi.fn() },
|
|
88
|
+
];
|
|
89
|
+
render(
|
|
90
|
+
<CheckboxGroup legend="Choose options" options={optionsWithoutLabels} />,
|
|
91
|
+
);
|
|
92
|
+
const checkboxes = screen.getAllByRole('checkbox');
|
|
93
|
+
expect(checkboxes).toHaveLength(2);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('supports disabled fieldset', () => {
|
|
97
|
+
render(
|
|
98
|
+
<CheckboxGroup
|
|
99
|
+
legend="Choose options"
|
|
100
|
+
options={mockOptions}
|
|
101
|
+
disabled
|
|
102
|
+
/>,
|
|
103
|
+
);
|
|
104
|
+
const fieldset = screen.getByText('Choose options').closest('fieldset');
|
|
105
|
+
expect(fieldset).toBeDisabled();
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test('passes additional HTML attributes to checkboxes', () => {
|
|
109
|
+
const optionsWithAttributes = [
|
|
110
|
+
{
|
|
111
|
+
'id': 'option1',
|
|
112
|
+
'label': 'Option 1',
|
|
113
|
+
'checked': false,
|
|
114
|
+
'onChange': vi.fn(),
|
|
115
|
+
'data-custom': 'value1',
|
|
116
|
+
'aria-describedby': 'description1',
|
|
117
|
+
},
|
|
118
|
+
];
|
|
119
|
+
render(
|
|
120
|
+
<CheckboxGroup legend="Choose options" options={optionsWithAttributes} />,
|
|
121
|
+
);
|
|
122
|
+
const checkbox = screen.getByRole('checkbox', { name: 'Option 1' });
|
|
123
|
+
|
|
124
|
+
expect(checkbox).toHaveAttribute('data-custom', 'value1');
|
|
125
|
+
expect(checkbox).toHaveAttribute('aria-describedby', 'description1');
|
|
126
|
+
});
|
|
127
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Fieldset, type FieldsetProps } from 'Components/formField/fieldset/Fieldset';
|
|
2
|
+
import { CheckboxInput, type CheckboxInputProps } from './CheckboxInput';
|
|
3
|
+
|
|
4
|
+
type CheckboxGroupProps = {
|
|
5
|
+
options: CheckboxInputProps[];
|
|
6
|
+
} & FieldsetProps;
|
|
7
|
+
|
|
8
|
+
export const CheckboxGroup = (props: CheckboxGroupProps) => {
|
|
9
|
+
const { options, ...rest } = props;
|
|
10
|
+
return (
|
|
11
|
+
<Fieldset {...rest}>
|
|
12
|
+
{options.map((option: CheckboxInputProps) => (
|
|
13
|
+
<CheckboxInput key={option.id} {...option} />
|
|
14
|
+
))}
|
|
15
|
+
</Fieldset>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import type { Meta } from '@storybook/react-vite';
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
2
|
import { CheckboxInput } from './CheckboxInput';
|
|
3
|
+
import { CheckboxGroup } from './CheckboxGroup';
|
|
3
4
|
|
|
4
5
|
const meta: Meta<typeof CheckboxInput> = {
|
|
5
6
|
title: 'Components/FormField/Inputs/Checkbox',
|
|
6
7
|
component: CheckboxInput,
|
|
7
8
|
};
|
|
8
9
|
|
|
10
|
+
type Story = StoryObj<typeof meta>;
|
|
11
|
+
|
|
9
12
|
export const Default = {
|
|
10
13
|
parameters: {
|
|
11
14
|
layout: 'centered',
|
|
@@ -19,4 +22,12 @@ export const Default = {
|
|
|
19
22
|
},
|
|
20
23
|
};
|
|
21
24
|
|
|
25
|
+
export const CheckboxGroupStory: Story = {
|
|
26
|
+
render: () => {
|
|
27
|
+
return (
|
|
28
|
+
<CheckboxGroup legend="Checkbox group" options={[{ id: 'option1', label: 'Option 1' }, { id: 'option2', label: 'Option 2' }, { id: 'option3', label: 'Option 3' }]} />
|
|
29
|
+
);
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
22
33
|
export default meta;
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { expect, test, describe, vi } from 'vitest';
|
|
2
|
+
import { RadioButtonGroup } from './RadioButtonGroup';
|
|
3
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
4
|
+
import '@testing-library/jest-dom/vitest';
|
|
5
|
+
|
|
6
|
+
describe('RadioButtonGroup component', () => {
|
|
7
|
+
const mockOptions = [
|
|
8
|
+
{ id: 'option1', value: 'value1', label: 'Option 1' },
|
|
9
|
+
{ id: 'option2', value: 'value2', label: 'Option 2' },
|
|
10
|
+
{ id: 'option3', value: 'value3', label: 'Option 3' },
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
test('renders fieldset with legend', () => {
|
|
14
|
+
render(
|
|
15
|
+
<RadioButtonGroup
|
|
16
|
+
legend="Choose an option"
|
|
17
|
+
name="test-group"
|
|
18
|
+
options={mockOptions}
|
|
19
|
+
checkedValue="value1"
|
|
20
|
+
onChange={vi.fn()}
|
|
21
|
+
/>,
|
|
22
|
+
);
|
|
23
|
+
expect(screen.getByText('Choose an option')).toBeInTheDocument();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('renders all radio button options', () => {
|
|
27
|
+
render(
|
|
28
|
+
<RadioButtonGroup
|
|
29
|
+
legend="Choose an option"
|
|
30
|
+
name="test-group"
|
|
31
|
+
options={mockOptions}
|
|
32
|
+
checkedValue="value1"
|
|
33
|
+
onChange={vi.fn()}
|
|
34
|
+
/>,
|
|
35
|
+
);
|
|
36
|
+
expect(screen.getByRole('radio', { name: 'Option 1' })).toBeInTheDocument();
|
|
37
|
+
expect(screen.getByRole('radio', { name: 'Option 2' })).toBeInTheDocument();
|
|
38
|
+
expect(screen.getByRole('radio', { name: 'Option 3' })).toBeInTheDocument();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('applies the same name attribute to all radio buttons', () => {
|
|
42
|
+
render(
|
|
43
|
+
<RadioButtonGroup
|
|
44
|
+
legend="Choose an option"
|
|
45
|
+
name="test-group"
|
|
46
|
+
options={mockOptions}
|
|
47
|
+
checkedValue="value1"
|
|
48
|
+
onChange={vi.fn()}
|
|
49
|
+
/>,
|
|
50
|
+
);
|
|
51
|
+
const radios = screen.getAllByRole('radio');
|
|
52
|
+
radios.forEach((radio) => {
|
|
53
|
+
expect(radio).toHaveAttribute('name', 'test-group');
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('initially checks the correct radio button based on checkedValue', () => {
|
|
58
|
+
render(
|
|
59
|
+
<RadioButtonGroup
|
|
60
|
+
legend="Choose an option"
|
|
61
|
+
name="test-group"
|
|
62
|
+
options={mockOptions}
|
|
63
|
+
checkedValue="value2"
|
|
64
|
+
onChange={vi.fn()}
|
|
65
|
+
/>,
|
|
66
|
+
);
|
|
67
|
+
const option1 = screen.getByRole('radio', { name: 'Option 1' }) as HTMLInputElement;
|
|
68
|
+
const option2 = screen.getByRole('radio', { name: 'Option 2' }) as HTMLInputElement;
|
|
69
|
+
const option3 = screen.getByRole('radio', { name: 'Option 3' }) as HTMLInputElement;
|
|
70
|
+
|
|
71
|
+
expect(option1.checked).toBe(false);
|
|
72
|
+
expect(option2.checked).toBe(true);
|
|
73
|
+
expect(option3.checked).toBe(false);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test('calls onChange when a radio button is clicked', () => {
|
|
77
|
+
const handleChange = vi.fn();
|
|
78
|
+
render(
|
|
79
|
+
<RadioButtonGroup
|
|
80
|
+
legend="Choose an option"
|
|
81
|
+
name="test-group"
|
|
82
|
+
options={mockOptions}
|
|
83
|
+
checkedValue="value1"
|
|
84
|
+
onChange={handleChange}
|
|
85
|
+
/>,
|
|
86
|
+
);
|
|
87
|
+
const option2 = screen.getByRole('radio', { name: 'Option 2' });
|
|
88
|
+
fireEvent.click(option2);
|
|
89
|
+
expect(handleChange).toHaveBeenCalledExactlyOnceWith(expect.objectContaining({
|
|
90
|
+
target: expect.objectContaining({
|
|
91
|
+
value: 'value2',
|
|
92
|
+
}),
|
|
93
|
+
}));
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('renders with single option', () => {
|
|
97
|
+
const singleOption = [{ id: 'option1', value: 'value1', label: 'Only Option' }];
|
|
98
|
+
render(
|
|
99
|
+
<RadioButtonGroup
|
|
100
|
+
legend="Choose an option"
|
|
101
|
+
name="test-group"
|
|
102
|
+
options={singleOption}
|
|
103
|
+
checkedValue="value1"
|
|
104
|
+
onChange={vi.fn()}
|
|
105
|
+
/>,
|
|
106
|
+
);
|
|
107
|
+
const radios = screen.getAllByRole('radio');
|
|
108
|
+
expect(radios).toHaveLength(1);
|
|
109
|
+
expect(screen.getByRole('radio', { name: 'Only Option' })).toBeInTheDocument();
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test('renders empty group when options array is empty', () => {
|
|
113
|
+
render(
|
|
114
|
+
<RadioButtonGroup
|
|
115
|
+
legend="Choose an option"
|
|
116
|
+
name="test-group"
|
|
117
|
+
options={[]}
|
|
118
|
+
checkedValue=""
|
|
119
|
+
onChange={vi.fn()}
|
|
120
|
+
/>,
|
|
121
|
+
);
|
|
122
|
+
expect(screen.getByText('Choose an option')).toBeInTheDocument();
|
|
123
|
+
const radios = screen.queryAllByRole('radio');
|
|
124
|
+
expect(radios).toHaveLength(0);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test('passes through fieldset props', () => {
|
|
128
|
+
render(
|
|
129
|
+
<RadioButtonGroup
|
|
130
|
+
legend="Choose an option"
|
|
131
|
+
name="test-group"
|
|
132
|
+
options={mockOptions}
|
|
133
|
+
checkedValue="value1"
|
|
134
|
+
onChange={vi.fn()}
|
|
135
|
+
className="custom-class"
|
|
136
|
+
data-testid="test-fieldset"
|
|
137
|
+
/>,
|
|
138
|
+
);
|
|
139
|
+
const fieldset = screen.getByTestId('test-fieldset');
|
|
140
|
+
expect(fieldset).toBeInTheDocument();
|
|
141
|
+
expect(fieldset).toHaveClass('custom-class');
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test('updates checked state when checkedValue changes', () => {
|
|
145
|
+
const { rerender } = render(
|
|
146
|
+
<RadioButtonGroup
|
|
147
|
+
legend="Choose an option"
|
|
148
|
+
name="test-group"
|
|
149
|
+
options={mockOptions}
|
|
150
|
+
checkedValue="value1"
|
|
151
|
+
onChange={vi.fn()}
|
|
152
|
+
/>,
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
let option1 = screen.getByRole('radio', { name: 'Option 1' }) as HTMLInputElement;
|
|
156
|
+
let option2 = screen.getByRole('radio', { name: 'Option 2' }) as HTMLInputElement;
|
|
157
|
+
expect(option1.checked).toBe(true);
|
|
158
|
+
expect(option2.checked).toBe(false);
|
|
159
|
+
|
|
160
|
+
rerender(
|
|
161
|
+
<RadioButtonGroup
|
|
162
|
+
legend="Choose an option"
|
|
163
|
+
name="test-group"
|
|
164
|
+
options={mockOptions}
|
|
165
|
+
checkedValue="value2"
|
|
166
|
+
onChange={vi.fn()}
|
|
167
|
+
/>,
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
option1 = screen.getByRole('radio', { name: 'Option 1' }) as HTMLInputElement;
|
|
171
|
+
option2 = screen.getByRole('radio', { name: 'Option 2' }) as HTMLInputElement;
|
|
172
|
+
expect(option1.checked).toBe(false);
|
|
173
|
+
expect(option2.checked).toBe(true);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test('supports disabled fieldset', () => {
|
|
177
|
+
render(
|
|
178
|
+
<RadioButtonGroup
|
|
179
|
+
legend="Choose an option"
|
|
180
|
+
name="test-group"
|
|
181
|
+
options={mockOptions}
|
|
182
|
+
checkedValue="value1"
|
|
183
|
+
onChange={vi.fn()}
|
|
184
|
+
disabled
|
|
185
|
+
/>,
|
|
186
|
+
);
|
|
187
|
+
const fieldset = screen.getByText('Choose an option').closest('fieldset');
|
|
188
|
+
expect(fieldset).toBeDisabled();
|
|
189
|
+
});
|
|
190
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ChangeEvent } from 'react';
|
|
2
|
+
import { RadioButtonInput, type RadioButtonInputProps } from './RadioButtonInput';
|
|
3
|
+
import { Fieldset, type FieldsetProps } from '../../fieldset/Fieldset';
|
|
4
|
+
|
|
5
|
+
export type RadioButtonGroupProps = {
|
|
6
|
+
name: string;
|
|
7
|
+
options: RadioButtonInputProps[];
|
|
8
|
+
checkedValue: string;
|
|
9
|
+
onChange: (event: ChangeEvent<HTMLInputElement>) => void;
|
|
10
|
+
} & Omit<FieldsetProps, 'onChange'>;
|
|
11
|
+
|
|
12
|
+
export const RadioButtonGroup = (props: RadioButtonGroupProps) => {
|
|
13
|
+
const { legend, name, options, checkedValue, onChange, ...rest } = props;
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<Fieldset legend={legend} {...rest}>
|
|
17
|
+
{options.map((option: RadioButtonInputProps) => (
|
|
18
|
+
<RadioButtonInput key={option.id} name={name} value={option.value} label={option.label} checked={checkedValue === option.value} onChange={onChange} />
|
|
19
|
+
))}
|
|
20
|
+
</Fieldset>
|
|
21
|
+
);
|
|
22
|
+
};
|
|
@@ -2,6 +2,8 @@ import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
|
2
2
|
import { fn } from 'storybook/test';
|
|
3
3
|
|
|
4
4
|
import { RadioButtonInput } from './RadioButtonInput';
|
|
5
|
+
import { RadioButtonGroup } from './RadioButtonGroup';
|
|
6
|
+
import { useState } from 'react';
|
|
5
7
|
|
|
6
8
|
const meta = {
|
|
7
9
|
title: 'Components/FormField/Inputs/RadioButton',
|
|
@@ -87,11 +89,18 @@ export const DisabledChecked: Story = {
|
|
|
87
89
|
|
|
88
90
|
// Radio button group example
|
|
89
91
|
export const RadioGroup: Story = {
|
|
90
|
-
render: () =>
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
render: () => {
|
|
93
|
+
const options = [{ label: 'Option 1', value: 'option1' }, { label: 'Option 2', value: 'option2' }, { label: 'Option 3', value: 'option3' }];
|
|
94
|
+
const [checkedValue, setCheckedValue] = useState<string>(options[0]?.value ?? '');
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
<RadioButtonGroup
|
|
98
|
+
legend="Radio group"
|
|
99
|
+
name="group"
|
|
100
|
+
options={options}
|
|
101
|
+
checkedValue={checkedValue}
|
|
102
|
+
onChange={e => setCheckedValue(e.target.value)}
|
|
103
|
+
/>
|
|
104
|
+
);
|
|
105
|
+
},
|
|
97
106
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
.ds-label {
|
|
2
2
|
font-family: var(--font-family-standard);
|
|
3
3
|
font-size: var(--font-size-2-13);
|
|
4
|
-
font-weight: var(--
|
|
4
|
+
font-weight: var(--type-body-bold-weight);
|
|
5
5
|
color: var(--form-field-label-color-text);
|
|
6
6
|
line-height: 150%;
|
|
7
7
|
margin-bottom: var(--form-field-spacing-vertical);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Meta } from '@storybook/react-vite';
|
|
2
|
+
import { Separator } from './Separator';
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof Separator> = {
|
|
5
|
+
title: 'Components/Separator',
|
|
6
|
+
component: Separator,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const Default = {
|
|
10
|
+
args: {
|
|
11
|
+
title: 'titleValue',
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default meta;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { expect, test } from 'vitest';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import { Separator } from './Separator';
|
|
4
|
+
import '@testing-library/jest-dom/vitest';
|
|
5
|
+
|
|
6
|
+
test('Separator says hello', () => {
|
|
7
|
+
render(<Separator />);
|
|
8
|
+
|
|
9
|
+
expect(screen.getByRole('separator')).toBeInTheDocument();
|
|
10
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import classNames from 'classnames';
|
|
2
|
+
import { Separator as RadixSeparator } from 'radix-ui';
|
|
3
|
+
|
|
4
|
+
type SeparatorProps = {
|
|
5
|
+
className?: string;
|
|
6
|
+
} & RadixSeparator.SeparatorProps;
|
|
7
|
+
|
|
8
|
+
export const Separator = (props: SeparatorProps) => {
|
|
9
|
+
const {
|
|
10
|
+
className,
|
|
11
|
+
...rest
|
|
12
|
+
} = props;
|
|
13
|
+
|
|
14
|
+
return <RadixSeparator.Root className={classNames('ds-separator', className)} {...rest} />;
|
|
15
|
+
};
|
|
@@ -9,6 +9,7 @@ import { useState, type ComponentProps } from 'react';
|
|
|
9
9
|
import { RowCountInfo } from './pagination/RowCountInfo';
|
|
10
10
|
import { PaginationPanel } from './pagination/PaginationPanel';
|
|
11
11
|
import { HideColumnsDropdown } from './HideColumnsDropdown';
|
|
12
|
+
import { TableSettingsDropdown } from './pagination/TableSettingsDropdown';
|
|
12
13
|
|
|
13
14
|
type TableProps = ComponentProps<typeof Table>;
|
|
14
15
|
|
|
@@ -64,7 +65,7 @@ const HeaderContent = [
|
|
|
64
65
|
</div>,
|
|
65
66
|
<div key={1} style={{ display: 'flex', gap: '1rem' }}>
|
|
66
67
|
<Icon name="download" />
|
|
67
|
-
<
|
|
68
|
+
<TableSettingsDropdown />
|
|
68
69
|
<Icon name="circle-help" />
|
|
69
70
|
<Icon name="expand" />
|
|
70
71
|
</div>,
|
|
@@ -102,6 +103,12 @@ export const WithHeader: Story = {
|
|
|
102
103
|
defaultColDef: defaultColDef,
|
|
103
104
|
domLayout: 'autoHeight',
|
|
104
105
|
headerContent: HeaderContent,
|
|
106
|
+
onTableSettingsChanged: (newSettings) => {
|
|
107
|
+
console.log('Settings changed', newSettings);
|
|
108
|
+
},
|
|
109
|
+
onTableSettingsReset: () => {
|
|
110
|
+
console.log('Settings reset');
|
|
111
|
+
},
|
|
105
112
|
},
|
|
106
113
|
};
|
|
107
114
|
|