@primer/components 32.0.1-rc.44e3df9b → 32.1.0-rc.6f5d2b00

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 (41) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/browser.esm.js +7 -1
  3. package/dist/browser.esm.js.map +1 -1
  4. package/dist/browser.umd.js +7 -1
  5. package/dist/browser.umd.js.map +1 -1
  6. package/docs/content/Checkbox.md +118 -0
  7. package/docs/src/@primer/gatsby-theme-doctocat/nav.yml +2 -0
  8. package/lib/Checkbox.d.ts +29 -0
  9. package/lib/Checkbox.js +64 -0
  10. package/lib/Overlay.d.ts +5 -3
  11. package/lib/__tests__/Checkbox.test.d.ts +2 -0
  12. package/lib/__tests__/Checkbox.test.js +189 -0
  13. package/lib/__tests__/Overlay.types.test.d.ts +3 -0
  14. package/lib/__tests__/Overlay.types.test.js +38 -0
  15. package/lib/__tests__/SelectPanel.types.test.d.ts +3 -0
  16. package/lib/__tests__/SelectPanel.types.test.js +44 -0
  17. package/lib/index.d.ts +2 -0
  18. package/lib/index.js +8 -0
  19. package/lib/stories/Checkbox.stories.js +227 -0
  20. package/lib-esm/Checkbox.d.ts +29 -0
  21. package/lib-esm/Checkbox.js +44 -0
  22. package/lib-esm/Overlay.d.ts +5 -3
  23. package/lib-esm/__tests__/Checkbox.test.d.ts +2 -0
  24. package/lib-esm/__tests__/Checkbox.test.js +169 -0
  25. package/lib-esm/__tests__/Overlay.types.test.d.ts +3 -0
  26. package/lib-esm/__tests__/Overlay.types.test.js +29 -0
  27. package/lib-esm/__tests__/SelectPanel.types.test.d.ts +3 -0
  28. package/lib-esm/__tests__/SelectPanel.types.test.js +29 -0
  29. package/lib-esm/index.d.ts +2 -0
  30. package/lib-esm/index.js +1 -0
  31. package/lib-esm/stories/Checkbox.stories.js +197 -0
  32. package/package.json +1 -1
  33. package/src/Checkbox.tsx +75 -0
  34. package/src/Overlay.tsx +7 -4
  35. package/src/__tests__/Checkbox.test.tsx +155 -0
  36. package/src/__tests__/Overlay.types.test.tsx +15 -0
  37. package/src/__tests__/SelectPanel.types.test.tsx +31 -0
  38. package/src/__tests__/__snapshots__/Checkbox.test.tsx.snap +16 -0
  39. package/src/index.ts +3 -0
  40. package/src/stories/Checkbox.stories.tsx +164 -0
  41. package/stats.html +1 -1
@@ -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;
@@ -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;
@@ -0,0 +1,44 @@
1
+ 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); }
2
+
3
+ import styled from 'styled-components';
4
+ import { useProvidedRefOrCreate } from './hooks';
5
+ import React, { useLayoutEffect } from 'react';
6
+ import sx from './sx';
7
+ const StyledCheckbox = styled.input.withConfig({
8
+ displayName: "Checkbox__StyledCheckbox",
9
+ componentId: "i51804-0"
10
+ })(["cursor:pointer;", " ", ""], props => props.disabled && `cursor: not-allowed;`, sx);
11
+ /**
12
+ * An accessible, native checkbox component
13
+ */
14
+
15
+ const Checkbox = /*#__PURE__*/React.forwardRef(({
16
+ checked,
17
+ indeterminate,
18
+ disabled,
19
+ sx: sxProp,
20
+ required,
21
+ validationStatus,
22
+ ...rest
23
+ }, ref) => {
24
+ const checkboxRef = useProvidedRefOrCreate(ref);
25
+ useLayoutEffect(() => {
26
+ if (checkboxRef.current) {
27
+ checkboxRef.current.indeterminate = indeterminate || false;
28
+ }
29
+ }, [indeterminate, checked, checkboxRef]);
30
+ return /*#__PURE__*/React.createElement(StyledCheckbox, _extends({
31
+ type: "checkbox",
32
+ disabled: disabled,
33
+ "aria-disabled": disabled ? 'true' : 'false',
34
+ ref: ref || checkboxRef,
35
+ checked: indeterminate ? false : checked,
36
+ "aria-checked": indeterminate ? 'mixed' : checked ? 'true' : 'false',
37
+ sx: sxProp,
38
+ required: required,
39
+ "aria-required": required ? 'true' : 'false',
40
+ "aria-invalid": validationStatus === 'error' ? 'true' : 'false'
41
+ }, rest));
42
+ });
43
+ Checkbox.displayName = 'Checkbox';
44
+ export default Checkbox;
@@ -1,8 +1,9 @@
1
- import React from 'react';
1
+ import React, { ComponentPropsWithRef } from 'react';
2
2
  import { AriaRole, Merge } from './utils/types';
3
3
  import { TouchOrMouseEvent } from './hooks';
4
4
  import { SxProp } from './sx';
5
5
  import { AnchorSide } from './behaviors/anchoredPosition';
6
+ import { ForwardRefComponent as PolymorphicForwardRefComponent } from '@radix-ui/react-polymorphic';
6
7
  declare type StyledOverlayProps = {
7
8
  width?: keyof typeof widthMap;
8
9
  height?: keyof typeof heightMap;
@@ -42,7 +43,7 @@ declare type BaseOverlayProps = {
42
43
  role?: AriaRole;
43
44
  children?: React.ReactNode;
44
45
  };
45
- export declare type OverlayProps = Merge<StyledOverlayProps, BaseOverlayProps>;
46
+ declare type OwnOverlayProps = Merge<StyledOverlayProps, BaseOverlayProps>;
46
47
  /**
47
48
  * An `Overlay` is a flexible floating surface, used to display transient content such as menus,
48
49
  * selection options, dialogs, and more. Overlays use shadows to express elevation. The `Overlay`
@@ -60,5 +61,6 @@ export declare type OverlayProps = Merge<StyledOverlayProps, BaseOverlayProps>;
60
61
  * @param left Optional. Horizontal position of the overlay, relative to its closest positioned ancestor (often its `Portal`).
61
62
  * @param portalContainerName Optional. The name of the portal container to render the Overlay into.
62
63
  */
63
- declare const Overlay: React.ForwardRefExoticComponent<Omit<StyledOverlayProps, keyof BaseOverlayProps> & BaseOverlayProps & React.RefAttributes<HTMLDivElement>>;
64
+ declare const Overlay: PolymorphicForwardRefComponent<"div", OwnOverlayProps>;
65
+ export declare type OverlayProps = ComponentPropsWithRef<typeof Overlay>;
64
66
  export default Overlay;
@@ -0,0 +1,2 @@
1
+ import 'babel-polyfill';
2
+ import '@testing-library/jest-dom';
@@ -0,0 +1,169 @@
1
+ import React from 'react';
2
+ import { Checkbox } from '..';
3
+ import { behavesAsComponent, checkExports } from '../utils/testing';
4
+ import { render, cleanup } from '@testing-library/react';
5
+ import { toHaveNoViolations } from 'jest-axe';
6
+ import 'babel-polyfill';
7
+ import '@testing-library/jest-dom';
8
+ import userEvent from '@testing-library/user-event';
9
+ expect.extend(toHaveNoViolations);
10
+ describe('Checkbox', () => {
11
+ beforeEach(() => {
12
+ jest.resetAllMocks();
13
+ cleanup();
14
+ });
15
+ behavesAsComponent({
16
+ Component: Checkbox
17
+ });
18
+ checkExports('Checkbox', {
19
+ default: Checkbox
20
+ });
21
+ it('renders a valid checkbox input', () => {
22
+ const {
23
+ getByRole
24
+ } = render( /*#__PURE__*/React.createElement(Checkbox, null));
25
+ const checkbox = getByRole('checkbox');
26
+ expect(checkbox).toBeDefined();
27
+ });
28
+ it('renders an unchecked checkbox by default', () => {
29
+ const {
30
+ getByRole
31
+ } = render( /*#__PURE__*/React.createElement(Checkbox, null));
32
+ const checkbox = getByRole('checkbox');
33
+ expect(checkbox.checked).toEqual(false);
34
+ });
35
+ it('renders an active checkbox when checked attribute is passed', () => {
36
+ const handleChange = jest.fn();
37
+ const {
38
+ getByRole
39
+ } = render( /*#__PURE__*/React.createElement(Checkbox, {
40
+ checked: true,
41
+ onChange: handleChange
42
+ }));
43
+ const checkbox = getByRole('checkbox');
44
+ expect(checkbox.checked).toEqual(true);
45
+ });
46
+ it('accepts a change handler that can alter the checkbox state', () => {
47
+ const handleChange = jest.fn();
48
+ const {
49
+ getByRole
50
+ } = render( /*#__PURE__*/React.createElement(Checkbox, {
51
+ onChange: handleChange
52
+ }));
53
+ const checkbox = getByRole('checkbox');
54
+ expect(checkbox.checked).toEqual(false);
55
+ userEvent.click(checkbox);
56
+ expect(handleChange).toHaveBeenCalled();
57
+ expect(checkbox.checked).toEqual(true);
58
+ userEvent.click(checkbox);
59
+ expect(handleChange).toHaveBeenCalled();
60
+ expect(checkbox.checked).toEqual(false);
61
+ });
62
+ it('renders an indeterminate prop correctly', () => {
63
+ const handleChange = jest.fn();
64
+ const {
65
+ getByRole
66
+ } = render( /*#__PURE__*/React.createElement(Checkbox, {
67
+ indeterminate: true,
68
+ checked: true,
69
+ onChange: handleChange
70
+ }));
71
+ const checkbox = getByRole('checkbox');
72
+ expect(checkbox.indeterminate).toEqual(true);
73
+ expect(checkbox.checked).toEqual(false);
74
+ });
75
+ it('renders an inactive checkbox state correctly', () => {
76
+ const handleChange = jest.fn();
77
+ const {
78
+ getByRole,
79
+ rerender
80
+ } = render( /*#__PURE__*/React.createElement(Checkbox, {
81
+ disabled: true,
82
+ onChange: handleChange
83
+ }));
84
+ const checkbox = getByRole('checkbox');
85
+ expect(checkbox.disabled).toEqual(true);
86
+ expect(checkbox.checked).toEqual(false);
87
+ expect(checkbox).toHaveAttribute('aria-disabled', 'true');
88
+ userEvent.click(checkbox);
89
+ expect(checkbox.disabled).toEqual(true);
90
+ expect(checkbox.checked).toEqual(false);
91
+ expect(checkbox).toHaveAttribute('aria-disabled', 'true'); // remove disabled attribute and retest
92
+
93
+ rerender( /*#__PURE__*/React.createElement(Checkbox, {
94
+ onChange: handleChange
95
+ }));
96
+ expect(checkbox).toHaveAttribute('aria-disabled', 'false');
97
+ });
98
+ it('renders an uncontrolled component correctly', () => {
99
+ const {
100
+ getByRole
101
+ } = render( /*#__PURE__*/React.createElement(Checkbox, {
102
+ defaultChecked: true
103
+ }));
104
+ const checkbox = getByRole('checkbox');
105
+ expect(checkbox.checked).toEqual(true);
106
+ userEvent.click(checkbox);
107
+ expect(checkbox.checked).toEqual(false);
108
+ });
109
+ it('renders an aria-checked attribute correctly', () => {
110
+ const handleChange = jest.fn();
111
+ const {
112
+ getByRole,
113
+ rerender
114
+ } = render( /*#__PURE__*/React.createElement(Checkbox, {
115
+ checked: false,
116
+ onChange: handleChange
117
+ }));
118
+ const checkbox = getByRole('checkbox');
119
+ expect(checkbox).toHaveAttribute('aria-checked', 'false');
120
+ rerender( /*#__PURE__*/React.createElement(Checkbox, {
121
+ checked: true,
122
+ onChange: handleChange
123
+ }));
124
+ expect(checkbox).toHaveAttribute('aria-checked', 'true');
125
+ rerender( /*#__PURE__*/React.createElement(Checkbox, {
126
+ indeterminate: true,
127
+ checked: true,
128
+ onChange: handleChange
129
+ }));
130
+ expect(checkbox).toHaveAttribute('aria-checked', 'mixed');
131
+ });
132
+ it('renders an invalid aria state when validation prop indicates an error', () => {
133
+ const handleChange = jest.fn();
134
+ const {
135
+ getByRole,
136
+ rerender
137
+ } = render( /*#__PURE__*/React.createElement(Checkbox, {
138
+ onChange: handleChange
139
+ }));
140
+ const checkbox = getByRole('checkbox');
141
+ expect(checkbox).toHaveAttribute('aria-invalid', 'false');
142
+ rerender( /*#__PURE__*/React.createElement(Checkbox, {
143
+ onChange: handleChange,
144
+ validationStatus: "success"
145
+ }));
146
+ expect(checkbox).toHaveAttribute('aria-invalid', 'false');
147
+ rerender( /*#__PURE__*/React.createElement(Checkbox, {
148
+ onChange: handleChange,
149
+ validationStatus: "error"
150
+ }));
151
+ expect(checkbox).toHaveAttribute('aria-invalid', 'true');
152
+ });
153
+ it('renders an aria state indicating the field is required', () => {
154
+ const handleChange = jest.fn();
155
+ const {
156
+ getByRole,
157
+ rerender
158
+ } = render( /*#__PURE__*/React.createElement(Checkbox, {
159
+ onChange: handleChange
160
+ }));
161
+ const checkbox = getByRole('checkbox');
162
+ expect(checkbox).toHaveAttribute('aria-required', 'false');
163
+ rerender( /*#__PURE__*/React.createElement(Checkbox, {
164
+ onChange: handleChange,
165
+ required: true
166
+ }));
167
+ expect(checkbox).toHaveAttribute('aria-required', 'true');
168
+ });
169
+ });
@@ -1,3 +1,6 @@
1
1
  import React from 'react';
2
2
  export declare function shouldAcceptCallWithNoProps(ref: React.RefObject<HTMLElement>): JSX.Element;
3
+ export declare function shouldAcceptCallWithDOMProps(ref: React.RefObject<HTMLElement>): JSX.Element;
4
+ export declare function shouldNotAcceptCallWithDOMPropsThatDontMatchElement(ref: React.RefObject<HTMLElement>): JSX.Element;
5
+ export declare function shouldAcceptCallWithAsAndDOMProps(ref: React.RefObject<HTMLElement>): JSX.Element;
3
6
  export declare function shouldNotAcceptSystemProps(ref: React.RefObject<HTMLElement>): JSX.Element;
@@ -8,6 +8,35 @@ export function shouldAcceptCallWithNoProps(ref) {
8
8
  });
9
9
  }
10
10
  shouldAcceptCallWithNoProps.displayName = "shouldAcceptCallWithNoProps";
11
+ export function shouldAcceptCallWithDOMProps(ref) {
12
+ return /*#__PURE__*/React.createElement(Overlay, {
13
+ returnFocusRef: ref,
14
+ onClickOutside: () => null,
15
+ onEscape: () => null,
16
+ onMouseDown: () => null
17
+ });
18
+ }
19
+ shouldAcceptCallWithDOMProps.displayName = "shouldAcceptCallWithDOMProps";
20
+ export function shouldNotAcceptCallWithDOMPropsThatDontMatchElement(ref) {
21
+ // @ts-expect-error href should not be allowed on a <div>
22
+ return /*#__PURE__*/React.createElement(Overlay, {
23
+ returnFocusRef: ref,
24
+ onClickOutside: () => null,
25
+ onEscape: () => null,
26
+ href: "//primer.style/"
27
+ });
28
+ }
29
+ shouldNotAcceptCallWithDOMPropsThatDontMatchElement.displayName = "shouldNotAcceptCallWithDOMPropsThatDontMatchElement";
30
+ export function shouldAcceptCallWithAsAndDOMProps(ref) {
31
+ return /*#__PURE__*/React.createElement(Overlay, {
32
+ as: "a",
33
+ returnFocusRef: ref,
34
+ onClickOutside: () => null,
35
+ onEscape: () => null,
36
+ href: "//primer.style/"
37
+ });
38
+ }
39
+ shouldAcceptCallWithAsAndDOMProps.displayName = "shouldAcceptCallWithAsAndDOMProps";
11
40
  export function shouldNotAcceptSystemProps(ref) {
12
41
  return /*#__PURE__*/React.createElement(Overlay, {
13
42
  returnFocusRef: ref,
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ export declare function shouldAcceptCallWithNoProps(): JSX.Element;
3
+ export declare function shouldAcceptDOMPropsOnOverlay(): JSX.Element;
@@ -0,0 +1,29 @@
1
+ import React from 'react';
2
+ import { SelectPanel } from '../SelectPanel';
3
+ export function shouldAcceptCallWithNoProps() {
4
+ return /*#__PURE__*/React.createElement(SelectPanel, {
5
+ placeholderText: "",
6
+ open: false,
7
+ onOpenChange: () => null,
8
+ items: [],
9
+ selected: [],
10
+ onSelectedChange: () => null,
11
+ onFilterChange: () => null
12
+ });
13
+ }
14
+ shouldAcceptCallWithNoProps.displayName = "shouldAcceptCallWithNoProps";
15
+ export function shouldAcceptDOMPropsOnOverlay() {
16
+ return /*#__PURE__*/React.createElement(SelectPanel, {
17
+ placeholderText: "",
18
+ open: false,
19
+ onOpenChange: () => null,
20
+ items: [],
21
+ selected: [],
22
+ onSelectedChange: () => null,
23
+ onFilterChange: () => null,
24
+ overlayProps: {
25
+ onMouseDown: () => null
26
+ }
27
+ });
28
+ }
29
+ shouldAcceptDOMPropsOnOverlay.displayName = "shouldAcceptDOMPropsOnOverlay";
@@ -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-esm/index.js CHANGED
@@ -70,4 +70,5 @@ export { default as Token, IssueLabelToken, AvatarToken } from './Token';
70
70
  export { default as Tooltip } from './Tooltip';
71
71
  export { default as Truncate } from './Truncate';
72
72
  export { default as UnderlineNav } from './UnderlineNav';
73
+ export { default as Checkbox } from './Checkbox';
73
74
  export { SSRProvider, useSSRSafeId } from './utils/ssr';