@indico-data/design-system 2.5.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/.storybook/preview.ts +4 -14
  2. package/lib/index.css +178 -0
  3. package/lib/index.d.ts +43 -3
  4. package/lib/index.esm.css +178 -0
  5. package/lib/index.esm.js +28 -1
  6. package/lib/index.esm.js.map +1 -1
  7. package/lib/index.js +30 -0
  8. package/lib/index.js.map +1 -1
  9. package/lib/src/components/forms/checkbox/Checkbox.d.ts +12 -0
  10. package/lib/src/components/forms/checkbox/Checkbox.stories.d.ts +7 -0
  11. package/lib/src/components/forms/checkbox/__tests__/Checkbox.test.d.ts +1 -0
  12. package/lib/src/components/forms/checkbox/index.d.ts +1 -0
  13. package/lib/src/components/forms/radio/Radio.d.ts +11 -0
  14. package/lib/src/components/forms/radio/Radio.stories.d.ts +6 -0
  15. package/lib/src/components/forms/radio/__tests__/Radio.test.d.ts +1 -0
  16. package/lib/src/components/forms/radio/index.d.ts +1 -0
  17. package/lib/src/components/index.d.ts +2 -0
  18. package/lib/src/index.d.ts +3 -0
  19. package/package.json +1 -1
  20. package/src/components/forms/checkbox/Checkbox.mdx +67 -0
  21. package/src/components/forms/checkbox/Checkbox.stories.tsx +169 -0
  22. package/src/components/forms/checkbox/Checkbox.tsx +55 -0
  23. package/src/components/forms/checkbox/__tests__/Checkbox.test.tsx +35 -0
  24. package/src/components/forms/checkbox/index.ts +1 -0
  25. package/src/components/forms/checkbox/styles/Checkbox.scss +98 -0
  26. package/src/components/forms/radio/Radio.mdx +83 -0
  27. package/src/components/forms/radio/Radio.stories.tsx +121 -0
  28. package/src/components/forms/radio/Radio.tsx +47 -0
  29. package/src/components/forms/radio/__tests__/Radio.test.tsx +35 -0
  30. package/src/components/forms/radio/index.ts +1 -0
  31. package/src/components/forms/radio/styles/Radio.scss +98 -0
  32. package/src/components/index.ts +2 -0
  33. package/src/index.ts +3 -0
  34. package/src/styles/index.scss +2 -0
  35. package/src/styles/storybook.scss +15 -0
@@ -0,0 +1,121 @@
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+ import { Radio, RadioProps } from './Radio';
3
+ import { SetStateAction, useState } from 'react';
4
+
5
+ const meta: Meta = {
6
+ title: 'Forms/Radio',
7
+ component: Radio,
8
+ argTypes: {
9
+ ref: {
10
+ table: {
11
+ disable: true,
12
+ },
13
+ },
14
+ onChange: {
15
+ control: false,
16
+ description: 'onChange event handler',
17
+ table: {
18
+ category: 'Callbacks',
19
+ type: {
20
+ summary: '(e: React.ChangeEvent<HTMLInputElement>) => void',
21
+ },
22
+ },
23
+ action: 'onChange',
24
+ },
25
+ label: {
26
+ control: 'text',
27
+ description: 'The label for the Radio field',
28
+ table: {
29
+ category: 'Props',
30
+ type: {
31
+ summary: 'string',
32
+ },
33
+ },
34
+ defaultValue: { summary: '' },
35
+ },
36
+ name: {
37
+ control: 'text',
38
+ description: 'The name for the Radio field',
39
+ table: {
40
+ category: 'Props',
41
+ type: {
42
+ summary: 'string',
43
+ },
44
+ },
45
+ defaultValue: { summary: '' },
46
+ },
47
+ value: {
48
+ control: 'text',
49
+ description: 'This holds the value that will be emitted when the radio is selected',
50
+ table: {
51
+ category: 'Props',
52
+ type: {
53
+ summary: 'string',
54
+ },
55
+ },
56
+ defaultValue: { summary: null },
57
+ },
58
+ id: {
59
+ control: 'text',
60
+ description: 'This explains what button group this radio belongs to.',
61
+ table: {
62
+ category: 'Props',
63
+ type: {
64
+ summary: 'string',
65
+ },
66
+ },
67
+ defaultValue: { summary: '' },
68
+ },
69
+ isDisabled: {
70
+ control: 'boolean',
71
+ description: 'Toggles the disabled state of the Radio field',
72
+ table: {
73
+ category: 'Props',
74
+ type: {
75
+ summary: 'boolean',
76
+ },
77
+ },
78
+ defaultValue: { summary: false },
79
+ },
80
+ },
81
+ };
82
+
83
+ export default meta;
84
+
85
+ type Story = StoryObj<typeof Radio>;
86
+
87
+ const radioList = [
88
+ { id: 'one', label: 'Radio Label One', name: 'radio', value: 'radio' },
89
+ { id: 'two', label: 'Radio Label Two', name: 'radio', value: 'radio' },
90
+ { id: 'three', label: 'Radio Label Three', name: 'radio', value: 'radio' },
91
+ ];
92
+ export const Default: Story = {
93
+ args: {
94
+ id: 'one',
95
+ label: 'Radio Label',
96
+ name: 'radio',
97
+ value: 'radio',
98
+ isDisabled: false,
99
+ },
100
+ render: (args) => {
101
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
102
+ console.log(e.target.value);
103
+ };
104
+ return (
105
+ <div>
106
+ <h2 className="mb-2">Radio Buttons</h2>
107
+ {radioList.map((radio) => (
108
+ <Radio
109
+ key={radio.id}
110
+ onChange={handleChange}
111
+ id={radio.id}
112
+ label={radio.label}
113
+ name={radio.name}
114
+ value={radio.value}
115
+ isDisabled={args.isDisabled}
116
+ />
117
+ ))}
118
+ </div>
119
+ );
120
+ },
121
+ };
@@ -0,0 +1,47 @@
1
+ import React from 'react';
2
+
3
+ export interface RadioProps {
4
+ ref?: React.LegacyRef<HTMLInputElement>;
5
+ id: string;
6
+ label: string;
7
+ name: string;
8
+ value?: string;
9
+ onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
10
+ isDisabled?: boolean;
11
+ }
12
+
13
+ export const Radio = ({
14
+ ref,
15
+ id,
16
+ label,
17
+ name,
18
+ value,
19
+ onChange,
20
+ isDisabled,
21
+ ...rest
22
+ }: RadioProps) => {
23
+ return (
24
+ <div className="form-control">
25
+ <div className="radio-wrapper">
26
+ <input
27
+ data-testid={`form-radio-input-${name}`}
28
+ {...rest}
29
+ className="radio-input"
30
+ type="radio"
31
+ id={id}
32
+ name={name}
33
+ value={value}
34
+ disabled={isDisabled}
35
+ ref={ref}
36
+ onChange={onChange}
37
+ tabIndex={0}
38
+ aria-describedby={id}
39
+ aria-label={label}
40
+ />
41
+ <label htmlFor={id} className="radio-input-label" data-testid={`label-radio-input-${name}`}>
42
+ {label}
43
+ </label>
44
+ </div>
45
+ </div>
46
+ );
47
+ };
@@ -0,0 +1,35 @@
1
+ import { render, screen, act } from '@testing-library/react';
2
+ import { Radio } from '@/components/forms/radio/Radio';
3
+ import userEvent from '@testing-library/user-event';
4
+
5
+ const handleOnChange = jest.fn();
6
+
7
+ describe('radio', () => {
8
+ it('renders the radio input field', () => {
9
+ render(
10
+ <Radio
11
+ label="Option 1"
12
+ name="name"
13
+ ref={undefined}
14
+ onChange={handleOnChange}
15
+ id={'ButtonGroup'}
16
+ />,
17
+ );
18
+ expect(screen.getByLabelText('Option 1')).toBeInTheDocument();
19
+ });
20
+
21
+ it('calls the onChange function when the radio input is clicked', async () => {
22
+ render(
23
+ <Radio
24
+ label="Option 1"
25
+ name="name"
26
+ ref={undefined}
27
+ onChange={handleOnChange}
28
+ id={'ButtonGroup'}
29
+ />,
30
+ );
31
+ expect(handleOnChange).toHaveBeenCalledTimes(0);
32
+ await userEvent.click(screen.getByLabelText('Option 1'));
33
+ expect(handleOnChange).toHaveBeenCalledTimes(1);
34
+ });
35
+ });
@@ -0,0 +1 @@
1
+ export { Radio } from './Radio';
@@ -0,0 +1,98 @@
1
+ // Common Variables
2
+ :root,
3
+ :root [data-theme='light'],
4
+ :root [data-theme='dark'] {
5
+ --pf-radio-background-color: var(--pf-white-color);
6
+ --pf-radio-check-color: var(--pf-primary-color);
7
+ --pf-radio-border-color: var(--pf-gray-color);
8
+ --pf-radio-disabled-color: var(--pf-gray-color-400);
9
+ }
10
+
11
+ // Dark Theme Specific Variables
12
+ :root [data-theme='dark'] {
13
+ --pf-radio-background-color: transparent;
14
+ --pf-radio-check-color: var(--pf-white-color);
15
+ --pf-radio-border-color: var(--pf-white-color);
16
+ --pf-radio-disabled-color: var(--pf-gray-color-300);
17
+ }
18
+
19
+ .form-control {
20
+ .radio-wrapper {
21
+ display: flex;
22
+ margin-bottom: var(--pf-margin-2);
23
+ align-items: center;
24
+ }
25
+ .radio-input {
26
+ margin: 0;
27
+ margin-right: var(--pf-margin-2);
28
+ cursor: pointer;
29
+ }
30
+ .radio-input-label {
31
+ cursor: pointer;
32
+ }
33
+ [type='radio']:checked,
34
+ [type='radio']:not(:checked) {
35
+ position: absolute;
36
+ left: -9999px;
37
+ }
38
+ [type='radio']:checked + label,
39
+ [type='radio']:not(:checked) + label {
40
+ position: relative;
41
+ padding-left: var(--pf-padding-7);
42
+ cursor: pointer;
43
+ line-height: 20px;
44
+ display: inline-block;
45
+ }
46
+ [type='radio']:checked + label:before,
47
+ [type='radio']:not(:checked) + label:before {
48
+ content: '';
49
+ position: absolute;
50
+ left: 0;
51
+ top: 0;
52
+ width: 18px;
53
+ height: 18px;
54
+ border: 1px solid var(--pf-radio-border-color);
55
+ border-radius: 100%;
56
+ background: var(--pf-radio-background-color);
57
+ }
58
+ [type='radio']:checked + label:after,
59
+ [type='radio']:not(:checked) + label:after {
60
+ content: '';
61
+ width: 12px;
62
+ height: 12px;
63
+ background: var(--pf-radio-check-color);
64
+ position: absolute;
65
+ top: 4px;
66
+ left: 4px;
67
+ border-radius: 100%;
68
+ -webkit-transition: all 0.2s ease;
69
+ transition: all 0.2s ease;
70
+ }
71
+ [type='radio']:not(:checked) + label:after {
72
+ opacity: 0;
73
+ -webkit-transform: scale(0);
74
+ transform: scale(0);
75
+ }
76
+ [type='radio']:checked + label:after {
77
+ opacity: 1;
78
+ -webkit-transform: scale(1);
79
+ transform: scale(1);
80
+ }
81
+ [type='radio']:disabled,
82
+ [type='radio']:disabled + label {
83
+ cursor: not-allowed;
84
+ }
85
+
86
+ [type='radio']:disabled + label {
87
+ color: var(--pf-radio-disabled-color);
88
+ opacity: 0.5;
89
+ }
90
+
91
+ [type='radio']:disabled + label:before {
92
+ border-color: var(--pf-radio-disabled-color);
93
+ }
94
+
95
+ [type='radio']:disabled + label:after {
96
+ background: var(--pf-radio-disabled-color);
97
+ }
98
+ }
@@ -3,3 +3,5 @@ export { Button } from './button';
3
3
  export { Icon } from './icons';
4
4
  export { Table } from './table';
5
5
  export { Input } from './forms/input';
6
+ export { Radio } from './forms/radio';
7
+ export { Checkbox } from './forms/checkbox';
package/src/index.ts CHANGED
@@ -61,3 +61,6 @@ export { Container, Row, Col } from './components/grid';
61
61
  export { Button } from './components/button';
62
62
  export { Icon } from './components/icons';
63
63
  export { Table } from './components/table';
64
+ export { Input } from './components/forms/input';
65
+ export { Radio as RadioInput } from './components/forms/radio';
66
+ export { Checkbox } from './components/forms/checkbox';
@@ -7,6 +7,8 @@
7
7
  @import '../components/grid/styles/Grid.scss';
8
8
  @import '../components/table/styles/Table.scss';
9
9
  @import '../components/forms/input/styles/Input.scss';
10
+ @import '../components/forms/radio/styles/Radio.scss';
11
+ @import '../components/forms/checkbox/styles/Checkbox.scss';
10
12
 
11
13
  @import 'typography';
12
14
  @import 'colors';
@@ -0,0 +1,15 @@
1
+ :root [data-theme='light'],
2
+ :root {
3
+ --storybook-bg-color: var(--pf-white-color);
4
+ --storybook-font-color: var(--pf-gray-color);
5
+ }
6
+
7
+ :root [data-theme='dark'] {
8
+ --storybook-bg-color: var(--pf-primary-color-300);
9
+ --storybook-font-color: var(--pf-white-color);
10
+ }
11
+
12
+ .sb__story {
13
+ background-color: var(--storybook-bg-color);
14
+ color: var(--storybook-font-color);
15
+ }