@primer/components 32.0.2-rc.859381a1 → 32.1.0-rc.6f5d2b00
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +5 -1
- package/dist/browser.esm.js +7 -1
- package/dist/browser.esm.js.map +1 -1
- package/dist/browser.umd.js +7 -1
- package/dist/browser.umd.js.map +1 -1
- package/docs/content/Checkbox.md +118 -0
- package/docs/src/@primer/gatsby-theme-doctocat/nav.yml +2 -0
- package/lib/Checkbox.d.ts +29 -0
- package/lib/Checkbox.js +64 -0
- package/lib/__tests__/Checkbox.test.d.ts +2 -0
- package/lib/__tests__/Checkbox.test.js +189 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +8 -0
- package/lib/stories/Checkbox.stories.js +227 -0
- package/lib-esm/Checkbox.d.ts +29 -0
- package/lib-esm/Checkbox.js +44 -0
- package/lib-esm/__tests__/Checkbox.test.d.ts +2 -0
- package/lib-esm/__tests__/Checkbox.test.js +169 -0
- package/lib-esm/index.d.ts +2 -0
- package/lib-esm/index.js +1 -0
- package/lib-esm/stories/Checkbox.stories.js +197 -0
- package/package.json +1 -1
- package/src/Checkbox.tsx +75 -0
- package/src/__tests__/Checkbox.test.tsx +155 -0
- package/src/__tests__/__snapshots__/Checkbox.test.tsx.snap +16 -0
- package/src/index.ts +3 -0
- package/src/stories/Checkbox.stories.tsx +164 -0
- package/stats.html +1 -1
@@ -0,0 +1,118 @@
|
|
1
|
+
---
|
2
|
+
title: Checkbox
|
3
|
+
description: Use checkboxes to toggle between checked and unchecked states in a list or as a standalone form field
|
4
|
+
status: Alpha
|
5
|
+
source: https://github.com/primer/react/blob/main/src/Checklist.tsx
|
6
|
+
storybook: '/react/storybook?path=/story/forms-checkbox--default'
|
7
|
+
---
|
8
|
+
|
9
|
+
import {ComponentChecklist} from '../src/component-checklist'
|
10
|
+
|
11
|
+
## Default example
|
12
|
+
|
13
|
+
The `Checkbox` component can be used in controlled and uncontrolled modes.
|
14
|
+
|
15
|
+
```jsx live
|
16
|
+
<>
|
17
|
+
<Box as="form" sx={{p: 3, pt: 0, display: 'flex', alignItems: 'center'}}>
|
18
|
+
<Checkbox id="default-checkbox" />
|
19
|
+
<Text as="label" htmlFor="default-checkbox" sx={{fontSize: 2, fontWeight: 'bold', marginLeft: 1}}>
|
20
|
+
Default checkbox
|
21
|
+
</Text>
|
22
|
+
</Box>
|
23
|
+
<Box as="form" sx={{p: 3, display: 'flex', alignItems: 'center'}}>
|
24
|
+
<Checkbox id="always-checked-checkbox" checked={true} />
|
25
|
+
<Text as="label" htmlFor="always-checked-checkbox" sx={{fontSize: 2, fontWeight: 'bold', marginLeft: 1}}>
|
26
|
+
Always checked
|
27
|
+
</Text>
|
28
|
+
</Box>
|
29
|
+
<Box as="form" sx={{p: 3, display: 'flex', alignItems: 'center'}}>
|
30
|
+
<Checkbox id="always-unchecked-checkbox" checked={false} />
|
31
|
+
<Text as="label" htmlFor="always-unchecked-checkbox" sx={{fontSize: 2, fontWeight: 'bold', marginLeft: 1}}>
|
32
|
+
Always unchecked
|
33
|
+
</Text>
|
34
|
+
</Box>
|
35
|
+
|
36
|
+
<Box as="form" sx={{p: 3, display: 'flex', alignItems: 'center'}}>
|
37
|
+
<Checkbox id="inactive-checkbox" checked={true} disabled />
|
38
|
+
<Text as="label" htmlFor="inactive-checkbox" sx={{fontSize: 2, fontWeight: 'bold', marginLeft: 1}}>
|
39
|
+
Inactive
|
40
|
+
</Text>
|
41
|
+
</Box>
|
42
|
+
</>
|
43
|
+
```
|
44
|
+
|
45
|
+
<Note variant="warning">
|
46
|
+
Checkbox components should always be accompanied by a corresponding label to improve support for assistive technologies.
|
47
|
+
</Note>
|
48
|
+
|
49
|
+
## Indeterminate example
|
50
|
+
|
51
|
+
An `indeterminate` checkbox state should be used if the input value is neither true nor false. This can be useful in situations where you are required to display an incomplete state, or one that is dependent on other input selections to determine a value.
|
52
|
+
|
53
|
+
```jsx live
|
54
|
+
<>
|
55
|
+
<Box as="form" sx={{p: 3, pt: 0, pb: 1, display: 'flex', alignItems: 'center'}}>
|
56
|
+
<Checkbox id="indeterminate-checkbox" onChange={() => {}} indeterminate={true} />
|
57
|
+
<Text as="label" sx={{fontSize: 2, fontWeight: 'bold', marginLeft: 1}} htmlFor="controlled-checkbox">
|
58
|
+
<Text sx={{display: 'block'}}>Default checkbox</Text>
|
59
|
+
</Text>
|
60
|
+
</Box>
|
61
|
+
<Box key={`sub-checkbox-0`} as="form" sx={{p: 1, pl: 6, display: 'flex', alignItems: 'center'}}>
|
62
|
+
<Checkbox id={`sub-checkbox-0`} checked={true} onChange={() => {}} />
|
63
|
+
<Text as="label" sx={{fontSize: 2, fontWeight: 'bold', marginLeft: 1}} htmlFor={`sub-checkbox-0`}>
|
64
|
+
<Text sx={{display: 'block'}}>Checkbox 1</Text>
|
65
|
+
</Text>
|
66
|
+
</Box>
|
67
|
+
<Box key={`sub-checkbox-1`} as="form" sx={{p: 1, pl: 6, display: 'flex', alignItems: 'center'}}>
|
68
|
+
<Checkbox id={`sub-checkbox-1`} checked={false} onChange={() => {}} />
|
69
|
+
<Text as="label" sx={{fontSize: 2, fontWeight: 'bold', marginLeft: 1}} htmlFor={`sub-checkbox-1`}>
|
70
|
+
<Text sx={{display: 'block'}}>Checkbox 2</Text>
|
71
|
+
</Text>
|
72
|
+
</Box>
|
73
|
+
<Box key={`sub-checkbox-2`} as="form" sx={{p: 1, pl: 6, display: 'flex', alignItems: 'center'}}>
|
74
|
+
<Checkbox id={`sub-checkbox-2`} checked={false} onChange={() => {}} />
|
75
|
+
<Text as="label" sx={{fontSize: 2, fontWeight: 'bold', marginLeft: 1}} htmlFor={`sub-checkbox-2`}>
|
76
|
+
<Text sx={{display: 'block'}}>Checkbox 3</Text>
|
77
|
+
</Text>
|
78
|
+
</Box>
|
79
|
+
<Box key={`sub-checkbox-3`} as="form" sx={{p: 1, pl: 6, display: 'flex', alignItems: 'center'}}>
|
80
|
+
<Checkbox id={`sub-checkbox-3`} checked={false} onChange={() => {}} />
|
81
|
+
<Text as="label" sx={{fontSize: 2, fontWeight: 'bold', marginLeft: 1}} htmlFor={`sub-checkbox-3`}>
|
82
|
+
<Text sx={{display: 'block'}}>Checkbox 4</Text>
|
83
|
+
</Text>
|
84
|
+
</Box>
|
85
|
+
</>
|
86
|
+
```
|
87
|
+
|
88
|
+
## Component props
|
89
|
+
|
90
|
+
Native `<input>` attributes are forwarded to the underlying React `input` component and are not listed below.
|
91
|
+
|
92
|
+
| Name | Type | Default | Description |
|
93
|
+
| :------------- | :---------- | :-------: | :------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
94
|
+
| checked | Boolean | undefined | Optional. Modifies true/false value of the native checkbox |
|
95
|
+
| defaultChecked | Boolean | undefined | Optional. Checks the input by default in uncontrolled mode |
|
96
|
+
| onChange | ChangeEvent | undefined | Optional. A callback function that is triggered when the checked state has been changed. |
|
97
|
+
| disabled | Boolean | undefined | Optional. Modifies the native disabled state of the native checkbox |
|
98
|
+
| indeterminate | Boolean | undefined | Optional. Applies an [indeterminate](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox#attr-indeterminate) state to the checkbox |
|
99
|
+
|
100
|
+
## Component status
|
101
|
+
|
102
|
+
<ComponentChecklist
|
103
|
+
items={{
|
104
|
+
propsDocumented: true,
|
105
|
+
noUnnecessaryDeps: true,
|
106
|
+
adaptsToThemes: true,
|
107
|
+
adaptsToScreenSizes: true,
|
108
|
+
fullTestCoverage: true,
|
109
|
+
usedInProduction: false,
|
110
|
+
usageExamplesDocumented: false,
|
111
|
+
designReviewed: false,
|
112
|
+
a11yReviewed: false,
|
113
|
+
stableApi: false,
|
114
|
+
addressedApiFeedback: false,
|
115
|
+
hasDesignGuidelines: false,
|
116
|
+
hasFigmaComponent: false
|
117
|
+
}}
|
118
|
+
/>
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import React, { InputHTMLAttributes } from 'react';
|
2
|
+
import { SxProp } from './sx';
|
3
|
+
export declare type CheckboxProps = {
|
4
|
+
/**
|
5
|
+
* Apply indeterminate visual appearance to the checkbox
|
6
|
+
*/
|
7
|
+
indeterminate?: boolean;
|
8
|
+
/**
|
9
|
+
* Apply inactive visual appearance to the checkbox
|
10
|
+
*/
|
11
|
+
disabled?: boolean;
|
12
|
+
/**
|
13
|
+
* Forward a ref to the underlying input element
|
14
|
+
*/
|
15
|
+
ref?: React.RefObject<HTMLInputElement>;
|
16
|
+
/**
|
17
|
+
* Indicates whether the checkbox must be checked
|
18
|
+
*/
|
19
|
+
required?: boolean;
|
20
|
+
/**
|
21
|
+
* Indicates whether the checkbox validation state
|
22
|
+
*/
|
23
|
+
validationStatus?: 'error' | 'success';
|
24
|
+
} & InputHTMLAttributes<HTMLInputElement> & SxProp;
|
25
|
+
/**
|
26
|
+
* An accessible, native checkbox component
|
27
|
+
*/
|
28
|
+
declare const Checkbox: React.ForwardRefExoticComponent<Pick<CheckboxProps, "sx" | keyof React.InputHTMLAttributes<HTMLInputElement> | "indeterminate" | "validationStatus"> & React.RefAttributes<HTMLInputElement>>;
|
29
|
+
export default Checkbox;
|
package/lib/Checkbox.js
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.default = void 0;
|
7
|
+
|
8
|
+
var _styledComponents = _interopRequireDefault(require("styled-components"));
|
9
|
+
|
10
|
+
var _hooks = require("./hooks");
|
11
|
+
|
12
|
+
var _react = _interopRequireWildcard(require("react"));
|
13
|
+
|
14
|
+
var _sx = _interopRequireDefault(require("./sx"));
|
15
|
+
|
16
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
17
|
+
|
18
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
19
|
+
|
20
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
21
|
+
|
22
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
23
|
+
|
24
|
+
const StyledCheckbox = _styledComponents.default.input.withConfig({
|
25
|
+
displayName: "Checkbox__StyledCheckbox",
|
26
|
+
componentId: "i51804-0"
|
27
|
+
})(["cursor:pointer;", " ", ""], props => props.disabled && `cursor: not-allowed;`, _sx.default);
|
28
|
+
/**
|
29
|
+
* An accessible, native checkbox component
|
30
|
+
*/
|
31
|
+
|
32
|
+
|
33
|
+
const Checkbox = /*#__PURE__*/_react.default.forwardRef(({
|
34
|
+
checked,
|
35
|
+
indeterminate,
|
36
|
+
disabled,
|
37
|
+
sx: sxProp,
|
38
|
+
required,
|
39
|
+
validationStatus,
|
40
|
+
...rest
|
41
|
+
}, ref) => {
|
42
|
+
const checkboxRef = (0, _hooks.useProvidedRefOrCreate)(ref);
|
43
|
+
(0, _react.useLayoutEffect)(() => {
|
44
|
+
if (checkboxRef.current) {
|
45
|
+
checkboxRef.current.indeterminate = indeterminate || false;
|
46
|
+
}
|
47
|
+
}, [indeterminate, checked, checkboxRef]);
|
48
|
+
return /*#__PURE__*/_react.default.createElement(StyledCheckbox, _extends({
|
49
|
+
type: "checkbox",
|
50
|
+
disabled: disabled,
|
51
|
+
"aria-disabled": disabled ? 'true' : 'false',
|
52
|
+
ref: ref || checkboxRef,
|
53
|
+
checked: indeterminate ? false : checked,
|
54
|
+
"aria-checked": indeterminate ? 'mixed' : checked ? 'true' : 'false',
|
55
|
+
sx: sxProp,
|
56
|
+
required: required,
|
57
|
+
"aria-required": required ? 'true' : 'false',
|
58
|
+
"aria-invalid": validationStatus === 'error' ? 'true' : 'false'
|
59
|
+
}, rest));
|
60
|
+
});
|
61
|
+
|
62
|
+
Checkbox.displayName = 'Checkbox';
|
63
|
+
var _default = Checkbox;
|
64
|
+
exports.default = _default;
|
@@ -0,0 +1,189 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
var _react = _interopRequireDefault(require("react"));
|
4
|
+
|
5
|
+
var _ = require("..");
|
6
|
+
|
7
|
+
var _testing = require("../utils/testing");
|
8
|
+
|
9
|
+
var _react2 = require("@testing-library/react");
|
10
|
+
|
11
|
+
var _jestAxe = require("jest-axe");
|
12
|
+
|
13
|
+
require("babel-polyfill");
|
14
|
+
|
15
|
+
require("@testing-library/jest-dom");
|
16
|
+
|
17
|
+
var _userEvent = _interopRequireDefault(require("@testing-library/user-event"));
|
18
|
+
|
19
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
20
|
+
|
21
|
+
expect.extend(_jestAxe.toHaveNoViolations);
|
22
|
+
describe('Checkbox', () => {
|
23
|
+
beforeEach(() => {
|
24
|
+
jest.resetAllMocks();
|
25
|
+
(0, _react2.cleanup)();
|
26
|
+
});
|
27
|
+
(0, _testing.behavesAsComponent)({
|
28
|
+
Component: _.Checkbox
|
29
|
+
});
|
30
|
+
(0, _testing.checkExports)('Checkbox', {
|
31
|
+
default: _.Checkbox
|
32
|
+
});
|
33
|
+
it('renders a valid checkbox input', () => {
|
34
|
+
const {
|
35
|
+
getByRole
|
36
|
+
} = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(_.Checkbox, null));
|
37
|
+
const checkbox = getByRole('checkbox');
|
38
|
+
expect(checkbox).toBeDefined();
|
39
|
+
});
|
40
|
+
it('renders an unchecked checkbox by default', () => {
|
41
|
+
const {
|
42
|
+
getByRole
|
43
|
+
} = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(_.Checkbox, null));
|
44
|
+
const checkbox = getByRole('checkbox');
|
45
|
+
expect(checkbox.checked).toEqual(false);
|
46
|
+
});
|
47
|
+
it('renders an active checkbox when checked attribute is passed', () => {
|
48
|
+
const handleChange = jest.fn();
|
49
|
+
const {
|
50
|
+
getByRole
|
51
|
+
} = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(_.Checkbox, {
|
52
|
+
checked: true,
|
53
|
+
onChange: handleChange
|
54
|
+
}));
|
55
|
+
const checkbox = getByRole('checkbox');
|
56
|
+
expect(checkbox.checked).toEqual(true);
|
57
|
+
});
|
58
|
+
it('accepts a change handler that can alter the checkbox state', () => {
|
59
|
+
const handleChange = jest.fn();
|
60
|
+
const {
|
61
|
+
getByRole
|
62
|
+
} = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(_.Checkbox, {
|
63
|
+
onChange: handleChange
|
64
|
+
}));
|
65
|
+
const checkbox = getByRole('checkbox');
|
66
|
+
expect(checkbox.checked).toEqual(false);
|
67
|
+
|
68
|
+
_userEvent.default.click(checkbox);
|
69
|
+
|
70
|
+
expect(handleChange).toHaveBeenCalled();
|
71
|
+
expect(checkbox.checked).toEqual(true);
|
72
|
+
|
73
|
+
_userEvent.default.click(checkbox);
|
74
|
+
|
75
|
+
expect(handleChange).toHaveBeenCalled();
|
76
|
+
expect(checkbox.checked).toEqual(false);
|
77
|
+
});
|
78
|
+
it('renders an indeterminate prop correctly', () => {
|
79
|
+
const handleChange = jest.fn();
|
80
|
+
const {
|
81
|
+
getByRole
|
82
|
+
} = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(_.Checkbox, {
|
83
|
+
indeterminate: true,
|
84
|
+
checked: true,
|
85
|
+
onChange: handleChange
|
86
|
+
}));
|
87
|
+
const checkbox = getByRole('checkbox');
|
88
|
+
expect(checkbox.indeterminate).toEqual(true);
|
89
|
+
expect(checkbox.checked).toEqual(false);
|
90
|
+
});
|
91
|
+
it('renders an inactive checkbox state correctly', () => {
|
92
|
+
const handleChange = jest.fn();
|
93
|
+
const {
|
94
|
+
getByRole,
|
95
|
+
rerender
|
96
|
+
} = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(_.Checkbox, {
|
97
|
+
disabled: true,
|
98
|
+
onChange: handleChange
|
99
|
+
}));
|
100
|
+
const checkbox = getByRole('checkbox');
|
101
|
+
expect(checkbox.disabled).toEqual(true);
|
102
|
+
expect(checkbox.checked).toEqual(false);
|
103
|
+
expect(checkbox).toHaveAttribute('aria-disabled', 'true');
|
104
|
+
|
105
|
+
_userEvent.default.click(checkbox);
|
106
|
+
|
107
|
+
expect(checkbox.disabled).toEqual(true);
|
108
|
+
expect(checkbox.checked).toEqual(false);
|
109
|
+
expect(checkbox).toHaveAttribute('aria-disabled', 'true'); // remove disabled attribute and retest
|
110
|
+
|
111
|
+
rerender( /*#__PURE__*/_react.default.createElement(_.Checkbox, {
|
112
|
+
onChange: handleChange
|
113
|
+
}));
|
114
|
+
expect(checkbox).toHaveAttribute('aria-disabled', 'false');
|
115
|
+
});
|
116
|
+
it('renders an uncontrolled component correctly', () => {
|
117
|
+
const {
|
118
|
+
getByRole
|
119
|
+
} = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(_.Checkbox, {
|
120
|
+
defaultChecked: true
|
121
|
+
}));
|
122
|
+
const checkbox = getByRole('checkbox');
|
123
|
+
expect(checkbox.checked).toEqual(true);
|
124
|
+
|
125
|
+
_userEvent.default.click(checkbox);
|
126
|
+
|
127
|
+
expect(checkbox.checked).toEqual(false);
|
128
|
+
});
|
129
|
+
it('renders an aria-checked attribute correctly', () => {
|
130
|
+
const handleChange = jest.fn();
|
131
|
+
const {
|
132
|
+
getByRole,
|
133
|
+
rerender
|
134
|
+
} = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(_.Checkbox, {
|
135
|
+
checked: false,
|
136
|
+
onChange: handleChange
|
137
|
+
}));
|
138
|
+
const checkbox = getByRole('checkbox');
|
139
|
+
expect(checkbox).toHaveAttribute('aria-checked', 'false');
|
140
|
+
rerender( /*#__PURE__*/_react.default.createElement(_.Checkbox, {
|
141
|
+
checked: true,
|
142
|
+
onChange: handleChange
|
143
|
+
}));
|
144
|
+
expect(checkbox).toHaveAttribute('aria-checked', 'true');
|
145
|
+
rerender( /*#__PURE__*/_react.default.createElement(_.Checkbox, {
|
146
|
+
indeterminate: true,
|
147
|
+
checked: true,
|
148
|
+
onChange: handleChange
|
149
|
+
}));
|
150
|
+
expect(checkbox).toHaveAttribute('aria-checked', 'mixed');
|
151
|
+
});
|
152
|
+
it('renders an invalid aria state when validation prop indicates an error', () => {
|
153
|
+
const handleChange = jest.fn();
|
154
|
+
const {
|
155
|
+
getByRole,
|
156
|
+
rerender
|
157
|
+
} = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(_.Checkbox, {
|
158
|
+
onChange: handleChange
|
159
|
+
}));
|
160
|
+
const checkbox = getByRole('checkbox');
|
161
|
+
expect(checkbox).toHaveAttribute('aria-invalid', 'false');
|
162
|
+
rerender( /*#__PURE__*/_react.default.createElement(_.Checkbox, {
|
163
|
+
onChange: handleChange,
|
164
|
+
validationStatus: "success"
|
165
|
+
}));
|
166
|
+
expect(checkbox).toHaveAttribute('aria-invalid', 'false');
|
167
|
+
rerender( /*#__PURE__*/_react.default.createElement(_.Checkbox, {
|
168
|
+
onChange: handleChange,
|
169
|
+
validationStatus: "error"
|
170
|
+
}));
|
171
|
+
expect(checkbox).toHaveAttribute('aria-invalid', 'true');
|
172
|
+
});
|
173
|
+
it('renders an aria state indicating the field is required', () => {
|
174
|
+
const handleChange = jest.fn();
|
175
|
+
const {
|
176
|
+
getByRole,
|
177
|
+
rerender
|
178
|
+
} = (0, _react2.render)( /*#__PURE__*/_react.default.createElement(_.Checkbox, {
|
179
|
+
onChange: handleChange
|
180
|
+
}));
|
181
|
+
const checkbox = getByRole('checkbox');
|
182
|
+
expect(checkbox).toHaveAttribute('aria-required', 'false');
|
183
|
+
rerender( /*#__PURE__*/_react.default.createElement(_.Checkbox, {
|
184
|
+
onChange: handleChange,
|
185
|
+
required: true
|
186
|
+
}));
|
187
|
+
expect(checkbox).toHaveAttribute('aria-required', 'true');
|
188
|
+
});
|
189
|
+
});
|
package/lib/index.d.ts
CHANGED
@@ -115,4 +115,6 @@ export { default as Truncate } from './Truncate';
|
|
115
115
|
export type { TruncateProps } from './Truncate';
|
116
116
|
export { default as UnderlineNav } from './UnderlineNav';
|
117
117
|
export type { UnderlineNavProps, UnderlineNavLinkProps } from './UnderlineNav';
|
118
|
+
export { default as Checkbox } from './Checkbox';
|
119
|
+
export type { CheckboxProps } from './Checkbox';
|
118
120
|
export { SSRProvider, useSSRSafeId } from './utils/ssr';
|
package/lib/index.js
CHANGED
@@ -495,6 +495,12 @@ Object.defineProperty(exports, "UnderlineNav", {
|
|
495
495
|
return _UnderlineNav.default;
|
496
496
|
}
|
497
497
|
});
|
498
|
+
Object.defineProperty(exports, "Checkbox", {
|
499
|
+
enumerable: true,
|
500
|
+
get: function () {
|
501
|
+
return _Checkbox.default;
|
502
|
+
}
|
503
|
+
});
|
498
504
|
Object.defineProperty(exports, "SSRProvider", {
|
499
505
|
enumerable: true,
|
500
506
|
get: function () {
|
@@ -636,6 +642,8 @@ var _Truncate = _interopRequireDefault(require("./Truncate"));
|
|
636
642
|
|
637
643
|
var _UnderlineNav = _interopRequireDefault(require("./UnderlineNav"));
|
638
644
|
|
645
|
+
var _Checkbox = _interopRequireDefault(require("./Checkbox"));
|
646
|
+
|
639
647
|
var _ssr = require("./utils/ssr");
|
640
648
|
|
641
649
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
@@ -0,0 +1,227 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.Indeterminate = exports.Uncontrolled = exports.Default = exports.default = void 0;
|
7
|
+
|
8
|
+
var _react = _interopRequireWildcard(require("react"));
|
9
|
+
|
10
|
+
var _styledComponents = _interopRequireDefault(require("styled-components"));
|
11
|
+
|
12
|
+
var _2 = require("..");
|
13
|
+
|
14
|
+
var _addonActions = require("@storybook/addon-actions");
|
15
|
+
|
16
|
+
var _constants = require("../constants");
|
17
|
+
|
18
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
19
|
+
|
20
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
21
|
+
|
22
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
23
|
+
|
24
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
25
|
+
|
26
|
+
var _default = {
|
27
|
+
title: 'Forms/Checkbox',
|
28
|
+
component: _2.Checkbox,
|
29
|
+
decorators: [Story => {
|
30
|
+
return /*#__PURE__*/_react.default.createElement(_2.ThemeProvider, null, /*#__PURE__*/_react.default.createElement(_2.BaseStyles, null, /*#__PURE__*/_react.default.createElement(_2.Box, {
|
31
|
+
paddingTop: 5
|
32
|
+
}, Story())));
|
33
|
+
}],
|
34
|
+
argTypes: {
|
35
|
+
sx: {
|
36
|
+
table: {
|
37
|
+
disable: true
|
38
|
+
}
|
39
|
+
},
|
40
|
+
disabled: {
|
41
|
+
name: 'Disabled',
|
42
|
+
defaultValue: false,
|
43
|
+
control: {
|
44
|
+
type: 'boolean'
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
};
|
49
|
+
exports.default = _default;
|
50
|
+
|
51
|
+
const StyledLabel = _styledComponents.default.label.withConfig({
|
52
|
+
displayName: "Checkboxstories__StyledLabel",
|
53
|
+
componentId: "sdupvr-0"
|
54
|
+
})(["user-select:none;font-weight:600;font-size:14px;line-height:18px;margin-left:16px;", ""], _constants.COMMON);
|
55
|
+
|
56
|
+
const StyledSubLabel = (0, _styledComponents.default)(_2.Text).withConfig({
|
57
|
+
displayName: "Checkboxstories__StyledSubLabel",
|
58
|
+
componentId: "sdupvr-1"
|
59
|
+
})(["color:", ";font-size:13px;", ""], (0, _constants.get)('colors.fg.muted'), _constants.COMMON);
|
60
|
+
|
61
|
+
const Default = args => {
|
62
|
+
const [isChecked, setChecked] = (0, _react.useState)(false);
|
63
|
+
|
64
|
+
const handleChange = event => {
|
65
|
+
setChecked(event.target.checked);
|
66
|
+
(0, _addonActions.action)('Change event triggered');
|
67
|
+
};
|
68
|
+
|
69
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_2.Box, {
|
70
|
+
as: "form",
|
71
|
+
sx: {
|
72
|
+
p: 3,
|
73
|
+
display: 'flex',
|
74
|
+
alignItems: 'flex-start'
|
75
|
+
}
|
76
|
+
}, /*#__PURE__*/_react.default.createElement(_2.Checkbox, _extends({
|
77
|
+
id: "controlled-checkbox",
|
78
|
+
onChange: handleChange,
|
79
|
+
checked: isChecked
|
80
|
+
}, args)), /*#__PURE__*/_react.default.createElement(StyledLabel, {
|
81
|
+
htmlFor: "controlled-checkbox"
|
82
|
+
}, /*#__PURE__*/_react.default.createElement(_2.Text, {
|
83
|
+
sx: {
|
84
|
+
display: 'block'
|
85
|
+
}
|
86
|
+
}, "Default checkbox"), /*#__PURE__*/_react.default.createElement(StyledSubLabel, null, "controlled"))), /*#__PURE__*/_react.default.createElement(_2.Box, {
|
87
|
+
as: "form",
|
88
|
+
sx: {
|
89
|
+
p: 3,
|
90
|
+
display: 'flex',
|
91
|
+
alignItems: 'flex-start'
|
92
|
+
}
|
93
|
+
}, /*#__PURE__*/_react.default.createElement(_2.Checkbox, _extends({
|
94
|
+
id: "always-checked-checkbox",
|
95
|
+
checked: true
|
96
|
+
}, args)), /*#__PURE__*/_react.default.createElement(StyledLabel, {
|
97
|
+
htmlFor: "always-checked-checkbox"
|
98
|
+
}, /*#__PURE__*/_react.default.createElement(_2.Text, {
|
99
|
+
sx: {
|
100
|
+
display: 'block'
|
101
|
+
}
|
102
|
+
}, "Always checked"), /*#__PURE__*/_react.default.createElement(StyledSubLabel, null, "checked=\"true\""))), /*#__PURE__*/_react.default.createElement(_2.Box, {
|
103
|
+
as: "form",
|
104
|
+
sx: {
|
105
|
+
p: 3,
|
106
|
+
display: 'flex',
|
107
|
+
alignItems: 'flex-start'
|
108
|
+
}
|
109
|
+
}, /*#__PURE__*/_react.default.createElement(_2.Checkbox, _extends({
|
110
|
+
id: "always-unchecked-checkbox",
|
111
|
+
checked: false
|
112
|
+
}, args)), /*#__PURE__*/_react.default.createElement(StyledLabel, {
|
113
|
+
htmlFor: "always-unchecked-checkbox"
|
114
|
+
}, /*#__PURE__*/_react.default.createElement(_2.Text, {
|
115
|
+
sx: {
|
116
|
+
display: 'block'
|
117
|
+
}
|
118
|
+
}, "Always unchecked"), /*#__PURE__*/_react.default.createElement(StyledSubLabel, null, "checked=\"false\""))), /*#__PURE__*/_react.default.createElement(_2.Box, {
|
119
|
+
as: "form",
|
120
|
+
sx: {
|
121
|
+
p: 3,
|
122
|
+
display: 'flex',
|
123
|
+
alignItems: 'flex-start'
|
124
|
+
}
|
125
|
+
}, /*#__PURE__*/_react.default.createElement(_2.Checkbox, {
|
126
|
+
id: "disabled-checkbox",
|
127
|
+
disabled: true,
|
128
|
+
checked: false
|
129
|
+
}), /*#__PURE__*/_react.default.createElement(StyledLabel, {
|
130
|
+
htmlFor: "disabled-checkbox"
|
131
|
+
}, /*#__PURE__*/_react.default.createElement(_2.Text, {
|
132
|
+
sx: {
|
133
|
+
display: 'block'
|
134
|
+
}
|
135
|
+
}, "Inactive"), /*#__PURE__*/_react.default.createElement(StyledSubLabel, null, "disabled=\"true\""))));
|
136
|
+
};
|
137
|
+
|
138
|
+
exports.Default = Default;
|
139
|
+
|
140
|
+
const Uncontrolled = args => {
|
141
|
+
const checkboxRef = (0, _react.useRef)(null);
|
142
|
+
(0, _react.useLayoutEffect)(() => {
|
143
|
+
if (checkboxRef.current) {
|
144
|
+
checkboxRef.current.checked = true;
|
145
|
+
}
|
146
|
+
}, []);
|
147
|
+
return /*#__PURE__*/_react.default.createElement(_2.Box, {
|
148
|
+
as: "form",
|
149
|
+
sx: {
|
150
|
+
p: 3,
|
151
|
+
display: 'flex',
|
152
|
+
alignItems: 'flex-start'
|
153
|
+
}
|
154
|
+
}, /*#__PURE__*/_react.default.createElement(_2.Checkbox, _extends({
|
155
|
+
id: "uncontrolled-checkbox",
|
156
|
+
ref: checkboxRef
|
157
|
+
}, args)), /*#__PURE__*/_react.default.createElement(StyledLabel, {
|
158
|
+
htmlFor: "uncontrolled-checkbox"
|
159
|
+
}, /*#__PURE__*/_react.default.createElement(_2.Text, {
|
160
|
+
sx: {
|
161
|
+
display: 'block'
|
162
|
+
}
|
163
|
+
}, "Uncontrolled checkbox"), /*#__PURE__*/_react.default.createElement(StyledSubLabel, null, "Checked by default")));
|
164
|
+
};
|
165
|
+
|
166
|
+
exports.Uncontrolled = Uncontrolled;
|
167
|
+
Uncontrolled.displayName = "Uncontrolled";
|
168
|
+
|
169
|
+
const Indeterminate = args => {
|
170
|
+
const [checkboxes, setCheckboxes] = (0, _react.useState)([false, false, false, false]);
|
171
|
+
|
172
|
+
const handleChange = (_, index) => {
|
173
|
+
const newCheckboxes = [...checkboxes];
|
174
|
+
newCheckboxes[index] = !checkboxes[index];
|
175
|
+
setCheckboxes(newCheckboxes);
|
176
|
+
};
|
177
|
+
|
178
|
+
const handleIndeterminateChange = () => {
|
179
|
+
if (checkboxes.every(checkbox => checkbox)) {
|
180
|
+
return setCheckboxes(checkboxes.map(() => false));
|
181
|
+
}
|
182
|
+
|
183
|
+
const newCheckboxes = checkboxes.map(() => true);
|
184
|
+
setCheckboxes(newCheckboxes);
|
185
|
+
};
|
186
|
+
|
187
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_2.Box, {
|
188
|
+
as: "form",
|
189
|
+
sx: {
|
190
|
+
p: 3,
|
191
|
+
display: 'flex',
|
192
|
+
alignItems: 'flex-start'
|
193
|
+
}
|
194
|
+
}, /*#__PURE__*/_react.default.createElement(_2.Checkbox, {
|
195
|
+
id: "indeterminate-checkbox",
|
196
|
+
checked: checkboxes.every(Boolean),
|
197
|
+
onChange: handleIndeterminateChange,
|
198
|
+
indeterminate: !checkboxes.every(Boolean)
|
199
|
+
}), /*#__PURE__*/_react.default.createElement(StyledLabel, {
|
200
|
+
htmlFor: "controlled-checkbox"
|
201
|
+
}, /*#__PURE__*/_react.default.createElement(_2.Text, {
|
202
|
+
sx: {
|
203
|
+
display: 'block'
|
204
|
+
}
|
205
|
+
}, "Default checkbox"), /*#__PURE__*/_react.default.createElement(StyledSubLabel, null, "controlled"))), checkboxes.map((field, index) => /*#__PURE__*/_react.default.createElement(_2.Box, {
|
206
|
+
key: `sub-checkbox-${index}`,
|
207
|
+
as: "form",
|
208
|
+
sx: {
|
209
|
+
p: 1,
|
210
|
+
pl: 7,
|
211
|
+
display: 'flex',
|
212
|
+
alignItems: 'flex-start'
|
213
|
+
}
|
214
|
+
}, /*#__PURE__*/_react.default.createElement(_2.Checkbox, _extends({
|
215
|
+
id: `sub-checkbox-${index}`,
|
216
|
+
checked: checkboxes[index],
|
217
|
+
onChange: event => handleChange(event, index)
|
218
|
+
}, args)), /*#__PURE__*/_react.default.createElement(StyledLabel, {
|
219
|
+
htmlFor: `sub-checkbox-${index}`
|
220
|
+
}, /*#__PURE__*/_react.default.createElement(_2.Text, {
|
221
|
+
sx: {
|
222
|
+
display: 'block'
|
223
|
+
}
|
224
|
+
}, "Checkbox ", index + 1)))));
|
225
|
+
};
|
226
|
+
|
227
|
+
exports.Indeterminate = Indeterminate;
|