@carbon/react 1.70.0-rc.0 → 1.71.0-rc.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/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +756 -756
- package/es/components/AILabel/index.js +15 -15
- package/es/components/CheckboxGroup/CheckboxGroup.js +1 -1
- package/es/components/CodeSnippet/CodeSnippet.d.ts +5 -2
- package/es/components/CodeSnippet/CodeSnippet.js +40 -1
- package/es/components/ComboBox/ComboBox.js +28 -23
- package/es/components/ComboButton/index.js +40 -1
- package/es/components/ComposedModal/ComposedModal.js +6 -2
- package/es/components/ContentSwitcher/ContentSwitcher.d.ts +2 -2
- package/es/components/ContentSwitcher/ContentSwitcher.js +1 -1
- package/es/components/Copy/Copy.d.ts +5 -2
- package/es/components/Copy/Copy.js +40 -1
- package/es/components/CopyButton/CopyButton.d.ts +5 -2
- package/es/components/CopyButton/CopyButton.js +40 -1
- package/es/components/DataTable/Table.d.ts +9 -1
- package/es/components/DataTable/Table.js +7 -2
- package/es/components/DataTable/TableSelectRow.js +14 -6
- package/es/components/DataTable/TableToolbarSearch.js +1 -1
- package/es/components/DataTable/stories/examples/TableToolbarFilter.d.ts +1 -1
- package/es/components/DatePicker/DatePicker.js +0 -8
- package/es/components/DatePicker/plugins/appendToPlugin.js +2 -2
- package/es/components/DatePicker/plugins/fixEventsPlugin.js +4 -4
- package/es/components/DatePicker/plugins/rangePlugin.js +2 -2
- package/es/components/DatePickerInput/DatePickerInput.d.ts +6 -1
- package/es/components/DatePickerInput/DatePickerInput.js +16 -10
- package/es/components/Dropdown/Dropdown.d.ts +5 -0
- package/es/components/Dropdown/Dropdown.js +132 -92
- package/es/components/FeatureFlags/index.js +1 -2
- package/es/components/IconButton/index.d.ts +4 -1
- package/es/components/IconButton/index.js +40 -1
- package/es/components/InlineCheckbox/InlineCheckbox.d.ts +50 -0
- package/es/components/InlineCheckbox/InlineCheckbox.js +3 -6
- package/es/components/InlineCheckbox/index.d.ts +9 -0
- package/es/components/LayoutDirection/LayoutDirection.d.ts +44 -0
- package/es/components/LayoutDirection/LayoutDirectionContext.d.ts +10 -0
- package/es/components/LayoutDirection/useLayoutDirection.d.ts +12 -0
- package/es/components/Menu/MenuItem.js +0 -3
- package/es/components/MultiSelect/FilterableMultiSelect.d.ts +1 -1
- package/es/components/MultiSelect/FilterableMultiSelect.js +1 -2
- package/es/components/MultiSelect/MultiSelect.js +1 -1
- package/es/components/Notification/Notification.d.ts +9 -2
- package/es/components/Notification/Notification.js +16 -2
- package/es/components/NumberInput/NumberInput.d.ts +5 -0
- package/es/components/NumberInput/NumberInput.js +17 -9
- package/es/components/OverflowMenu/OverflowMenu.js +1 -1
- package/es/components/OverflowMenu/next/index.js +40 -1
- package/es/components/Pagination/Pagination.js +2 -2
- package/es/components/Pagination/experimental/PageSelector.js +1 -1
- package/es/components/PaginationNav/PaginationNav.d.ts +1 -1
- package/es/components/PaginationNav/PaginationNav.js +10 -5
- package/es/components/Popover/index.js +2 -2
- package/es/components/SkeletonText/SkeletonText.js +1 -1
- package/es/components/Tabs/Tabs.js +46 -29
- package/es/components/TextArea/TextArea.d.ts +5 -0
- package/es/components/TextArea/TextArea.js +15 -7
- package/es/components/TextInput/TextInput.d.ts +5 -0
- package/es/components/TextInput/TextInput.js +15 -7
- package/es/components/TreeView/TreeNode.js +1 -1
- package/es/components/TreeView/TreeView.js +1 -1
- package/es/components/UIShell/HeaderMenu.js +1 -1
- package/es/components/UIShell/SideNav.js +1 -1
- package/es/components/UIShell/SideNavItems.js +1 -1
- package/es/components/UIShell/SideNavMenu.js +1 -1
- package/es/components/UIShell/SideNavMenuItem.d.ts +5 -1
- package/es/components/UIShell/SideNavMenuItem.js +7 -2
- package/es/components/UIShell/Switcher.js +1 -1
- package/lib/components/AILabel/index.js +15 -15
- package/lib/components/CheckboxGroup/CheckboxGroup.js +1 -1
- package/lib/components/CodeSnippet/CodeSnippet.d.ts +5 -2
- package/lib/components/CodeSnippet/CodeSnippet.js +40 -1
- package/lib/components/ComboBox/ComboBox.js +29 -23
- package/lib/components/ComboButton/index.js +40 -1
- package/lib/components/ComposedModal/ComposedModal.js +6 -2
- package/lib/components/ContentSwitcher/ContentSwitcher.d.ts +2 -2
- package/lib/components/ContentSwitcher/ContentSwitcher.js +1 -1
- package/lib/components/Copy/Copy.d.ts +5 -2
- package/lib/components/Copy/Copy.js +40 -1
- package/lib/components/CopyButton/CopyButton.d.ts +5 -2
- package/lib/components/CopyButton/CopyButton.js +40 -1
- package/lib/components/DataTable/Table.d.ts +9 -1
- package/lib/components/DataTable/Table.js +7 -2
- package/lib/components/DataTable/TableSelectRow.js +14 -6
- package/lib/components/DataTable/TableToolbarSearch.js +1 -1
- package/lib/components/DataTable/stories/examples/TableToolbarFilter.d.ts +1 -1
- package/lib/components/DatePicker/DatePicker.js +0 -8
- package/lib/components/DatePicker/plugins/appendToPlugin.js +2 -2
- package/lib/components/DatePicker/plugins/fixEventsPlugin.js +4 -4
- package/lib/components/DatePicker/plugins/rangePlugin.js +2 -2
- package/lib/components/DatePickerInput/DatePickerInput.d.ts +6 -1
- package/lib/components/DatePickerInput/DatePickerInput.js +16 -10
- package/lib/components/Dropdown/Dropdown.d.ts +5 -0
- package/lib/components/Dropdown/Dropdown.js +131 -91
- package/lib/components/FeatureFlags/index.js +1 -2
- package/lib/components/IconButton/index.d.ts +4 -1
- package/lib/components/IconButton/index.js +40 -1
- package/lib/components/InlineCheckbox/InlineCheckbox.d.ts +50 -0
- package/lib/components/InlineCheckbox/InlineCheckbox.js +3 -6
- package/lib/components/InlineCheckbox/index.d.ts +9 -0
- package/lib/components/LayoutDirection/LayoutDirection.d.ts +44 -0
- package/lib/components/LayoutDirection/LayoutDirectionContext.d.ts +10 -0
- package/lib/components/LayoutDirection/useLayoutDirection.d.ts +12 -0
- package/lib/components/Menu/MenuItem.js +0 -3
- package/lib/components/MultiSelect/FilterableMultiSelect.d.ts +1 -1
- package/lib/components/MultiSelect/FilterableMultiSelect.js +1 -2
- package/lib/components/MultiSelect/MultiSelect.js +1 -1
- package/lib/components/Notification/Notification.d.ts +9 -2
- package/lib/components/Notification/Notification.js +16 -2
- package/lib/components/NumberInput/NumberInput.d.ts +5 -0
- package/lib/components/NumberInput/NumberInput.js +17 -9
- package/lib/components/OverflowMenu/OverflowMenu.js +1 -1
- package/lib/components/OverflowMenu/next/index.js +40 -1
- package/lib/components/Pagination/Pagination.js +2 -2
- package/lib/components/Pagination/experimental/PageSelector.js +1 -1
- package/lib/components/PaginationNav/PaginationNav.d.ts +1 -1
- package/lib/components/PaginationNav/PaginationNav.js +10 -5
- package/lib/components/Popover/index.js +2 -2
- package/lib/components/SkeletonText/SkeletonText.js +1 -1
- package/lib/components/Tabs/Tabs.js +46 -29
- package/lib/components/TextArea/TextArea.d.ts +5 -0
- package/lib/components/TextArea/TextArea.js +15 -7
- package/lib/components/TextInput/TextInput.d.ts +5 -0
- package/lib/components/TextInput/TextInput.js +15 -7
- package/lib/components/TreeView/TreeNode.js +1 -1
- package/lib/components/TreeView/TreeView.js +1 -1
- package/lib/components/UIShell/HeaderMenu.js +1 -1
- package/lib/components/UIShell/SideNav.js +1 -1
- package/lib/components/UIShell/SideNavItems.js +1 -1
- package/lib/components/UIShell/SideNavMenu.js +1 -1
- package/lib/components/UIShell/SideNavMenuItem.d.ts +5 -1
- package/lib/components/UIShell/SideNavMenuItem.js +7 -2
- package/lib/components/UIShell/Switcher.js +1 -1
- package/package.json +5 -5
|
@@ -13,7 +13,7 @@ interface TableToolbarFilterProps {
|
|
|
13
13
|
/**
|
|
14
14
|
* Provide an optional hook that is called each time the input is updated
|
|
15
15
|
*/
|
|
16
|
-
onChange?: (event: '' | ChangeEvent<HTMLInputElement
|
|
16
|
+
onChange?: (event: '' | ChangeEvent<HTMLInputElement>) => void;
|
|
17
17
|
/**
|
|
18
18
|
* Provide an function that is called when the apply button is clicked
|
|
19
19
|
*/
|
|
@@ -530,9 +530,6 @@ const DatePicker = /*#__PURE__*/React__default.forwardRef(function DatePicker(_r
|
|
|
530
530
|
const closeCalendar = event => {
|
|
531
531
|
calendarRef.current.close();
|
|
532
532
|
// Remove focus from endDate calendar input
|
|
533
|
-
if (document.activeElement instanceof HTMLElement) {
|
|
534
|
-
document.activeElement.blur();
|
|
535
|
-
}
|
|
536
533
|
onCalendarClose(calendarRef.current.selectedDates, '', calendarRef.current, {
|
|
537
534
|
type: 'clickOutside'
|
|
538
535
|
});
|
|
@@ -558,12 +555,7 @@ const DatePicker = /*#__PURE__*/React__default.forwardRef(function DatePicker(_r
|
|
|
558
555
|
if (!calendarRef.current || !startInputField.current) return;
|
|
559
556
|
const handleKeyDown = event => {
|
|
560
557
|
if (match(event, Tab) && !event.shiftKey && document.activeElement === endInputField.current && calendarRef.current.isOpen) {
|
|
561
|
-
event.preventDefault();
|
|
562
558
|
calendarRef.current.close();
|
|
563
|
-
// Remove focus from endDate calendar input
|
|
564
|
-
document.activeElement instanceof HTMLElement &&
|
|
565
|
-
// this is to fix the TS warning
|
|
566
|
-
document?.activeElement?.blur();
|
|
567
559
|
onCalendarClose(calendarRef.current.selectedDates, '', calendarRef.current, event);
|
|
568
560
|
}
|
|
569
561
|
};
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* @param {object} config Plugin configuration.
|
|
10
10
|
* @returns {Plugin} A Flatpickr plugin to put adjust the position of calendar dropdown.
|
|
11
11
|
*/
|
|
12
|
-
var carbonFlatpickrAppendToPlugin =
|
|
12
|
+
var carbonFlatpickrAppendToPlugin = config => fp => {
|
|
13
13
|
/**
|
|
14
14
|
* Adjusts the floating menu position after Flatpicker sets it.
|
|
15
15
|
*/
|
|
@@ -51,6 +51,6 @@ var carbonFlatpickrAppendToPlugin = (config => fp => {
|
|
|
51
51
|
onReady: register,
|
|
52
52
|
onPreCalendarPosition: handlePreCalendarPosition
|
|
53
53
|
};
|
|
54
|
-
}
|
|
54
|
+
};
|
|
55
55
|
|
|
56
56
|
export { carbonFlatpickrAppendToPlugin as default };
|
|
@@ -12,7 +12,7 @@ import { Enter, ArrowLeft, ArrowRight, ArrowDown } from '../../../internal/keybo
|
|
|
12
12
|
* @param {object} config Plugin configuration.
|
|
13
13
|
* @returns {Plugin} A Flatpickr plugin to fix Flatpickr's behavior of certain events.
|
|
14
14
|
*/
|
|
15
|
-
var carbonFlatpickrFixEventsPlugin =
|
|
15
|
+
var carbonFlatpickrFixEventsPlugin = config => fp => {
|
|
16
16
|
const {
|
|
17
17
|
inputFrom,
|
|
18
18
|
inputTo,
|
|
@@ -76,7 +76,7 @@ var carbonFlatpickrFixEventsPlugin = (config => fp => {
|
|
|
76
76
|
if (inputTo === target && fp.selectedDates[1]) {
|
|
77
77
|
// Using getTime() enables the ability to more readily compare the date currently
|
|
78
78
|
// selected in the calendar and the date currently in the value of the input
|
|
79
|
-
const withoutTime = date => date
|
|
79
|
+
const withoutTime = date => date?.setHours(0, 0, 0, 0);
|
|
80
80
|
const selectedToDate = withoutTime(new Date(fp.selectedDates[1]));
|
|
81
81
|
const currentValueToDate = withoutTime(parseDateWithFormat(inputTo.value));
|
|
82
82
|
|
|
@@ -88,7 +88,7 @@ var carbonFlatpickrFixEventsPlugin = (config => fp => {
|
|
|
88
88
|
fp.setDate([inputFrom.value, inputTo && inputTo.value], true, fp.config.dateFormat);
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
|
-
const isValidDate = date => date
|
|
91
|
+
const isValidDate = date => date?.toString() !== 'Invalid Date';
|
|
92
92
|
// save end date in calendar inmediately after it's been written down
|
|
93
93
|
if (inputTo === target && fp.selectedDates.length === 1 && inputTo.value) {
|
|
94
94
|
if (isValidDate(parseDateWithFormat(inputTo.value))) {
|
|
@@ -150,6 +150,6 @@ var carbonFlatpickrFixEventsPlugin = (config => fp => {
|
|
|
150
150
|
onReady: [register, init],
|
|
151
151
|
onDestroy: [release]
|
|
152
152
|
};
|
|
153
|
-
}
|
|
153
|
+
};
|
|
154
154
|
|
|
155
155
|
export { carbonFlatpickrFixEventsPlugin as default };
|
|
@@ -14,7 +14,7 @@ import rangePlugin from 'flatpickr/dist/plugins/rangePlugin';
|
|
|
14
14
|
* Workaround for: https://github.com/flatpickr/flatpickr/issues/1944
|
|
15
15
|
* * A logic to ensure `fp.setDate()` call won't end up with "startDate to endDate" set to the first `<input>`
|
|
16
16
|
*/
|
|
17
|
-
var carbonFlatpickrRangePlugin =
|
|
17
|
+
var carbonFlatpickrRangePlugin = config => {
|
|
18
18
|
const factory = rangePlugin(Object.assign({
|
|
19
19
|
position: 'left'
|
|
20
20
|
}, config));
|
|
@@ -49,6 +49,6 @@ var carbonFlatpickrRangePlugin = (config => {
|
|
|
49
49
|
onPreCalendarPosition() {}
|
|
50
50
|
});
|
|
51
51
|
};
|
|
52
|
-
}
|
|
52
|
+
};
|
|
53
53
|
|
|
54
54
|
export { carbonFlatpickrRangePlugin as default };
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import { ReactElementLike, ReactNodeArray } from 'prop-types';
|
|
8
|
-
import React from 'react';
|
|
8
|
+
import React, { ReactNode } from 'react';
|
|
9
9
|
import { ReactAttr } from '../../types/common';
|
|
10
10
|
type ExcludedAttributes = 'value' | 'onChange' | 'locale' | 'children';
|
|
11
11
|
export type ReactNodeLike = ReactElementLike | ReactNodeArray | string | number | boolean | null | undefined;
|
|
@@ -19,6 +19,10 @@ export interface DatePickerInputProps extends Omit<ReactAttr<HTMLInputElement>,
|
|
|
19
19
|
* * `range` - With calendar dropdown and a date range.
|
|
20
20
|
*/
|
|
21
21
|
datePickerType?: 'simple' | 'single' | 'range';
|
|
22
|
+
/**
|
|
23
|
+
* **Experimental**: Provide a `decorator` component to be rendered inside the `DatePickerInput` component
|
|
24
|
+
*/
|
|
25
|
+
decorator?: ReactNode;
|
|
22
26
|
/**
|
|
23
27
|
* Specify whether or not the input should be disabled
|
|
24
28
|
*/
|
|
@@ -77,6 +81,7 @@ export interface DatePickerInputProps extends Omit<ReactAttr<HTMLInputElement>,
|
|
|
77
81
|
*/
|
|
78
82
|
size?: 'sm' | 'md' | 'lg';
|
|
79
83
|
/**
|
|
84
|
+
* @deprecated please use decorator instead.
|
|
80
85
|
* **Experimental**: Provide a `Slug` component to be rendered inside the `DatePickerInput` component
|
|
81
86
|
*/
|
|
82
87
|
slug?: ReactNodeLike;
|
|
@@ -14,11 +14,13 @@ import '../FluidForm/FluidForm.js';
|
|
|
14
14
|
import { FormContext } from '../FluidForm/FormContext.js';
|
|
15
15
|
import { useId } from '../../internal/useId.js';
|
|
16
16
|
import '../Text/index.js';
|
|
17
|
+
import deprecate from '../../prop-types/deprecate.js';
|
|
17
18
|
import { Text } from '../Text/Text.js';
|
|
18
19
|
|
|
19
20
|
const DatePickerInput = /*#__PURE__*/React__default.forwardRef(function DatePickerInput(props, ref) {
|
|
20
21
|
const {
|
|
21
22
|
datePickerType,
|
|
23
|
+
decorator,
|
|
22
24
|
disabled = false,
|
|
23
25
|
helperText,
|
|
24
26
|
hideLabel,
|
|
@@ -61,7 +63,8 @@ const DatePickerInput = /*#__PURE__*/React__default.forwardRef(function DatePick
|
|
|
61
63
|
const wrapperClasses = cx(`${prefix}--date-picker-input__wrapper`, {
|
|
62
64
|
[`${prefix}--date-picker-input__wrapper--invalid`]: invalid,
|
|
63
65
|
[`${prefix}--date-picker-input__wrapper--warn`]: warn,
|
|
64
|
-
[`${prefix}--date-picker-input__wrapper--slug`]: slug
|
|
66
|
+
[`${prefix}--date-picker-input__wrapper--slug`]: slug,
|
|
67
|
+
[`${prefix}--date-picker-input__wrapper--decorator`]: decorator
|
|
65
68
|
});
|
|
66
69
|
const labelClasses = cx(`${prefix}--label`, {
|
|
67
70
|
[`${prefix}--visually-hidden`]: hideLabel,
|
|
@@ -95,10 +98,10 @@ const DatePickerInput = /*#__PURE__*/React__default.forwardRef(function DatePick
|
|
|
95
98
|
}
|
|
96
99
|
const input = /*#__PURE__*/React__default.createElement("input", inputProps);
|
|
97
100
|
|
|
98
|
-
//
|
|
99
|
-
let
|
|
100
|
-
if (
|
|
101
|
-
|
|
101
|
+
// AILabel always size `mini`
|
|
102
|
+
let normalizedDecorator = /*#__PURE__*/React__default.isValidElement(slug ?? decorator) ? slug ?? decorator : null;
|
|
103
|
+
if (normalizedDecorator && normalizedDecorator['type']?.displayName === 'AILabel') {
|
|
104
|
+
normalizedDecorator = /*#__PURE__*/React__default.cloneElement(normalizedDecorator, {
|
|
102
105
|
size: 'mini'
|
|
103
106
|
});
|
|
104
107
|
}
|
|
@@ -110,7 +113,9 @@ const DatePickerInput = /*#__PURE__*/React__default.forwardRef(function DatePick
|
|
|
110
113
|
className: labelClasses
|
|
111
114
|
}, labelText), /*#__PURE__*/React__default.createElement("div", {
|
|
112
115
|
className: wrapperClasses
|
|
113
|
-
}, /*#__PURE__*/React__default.createElement("span", null, input,
|
|
116
|
+
}, /*#__PURE__*/React__default.createElement("span", null, input, slug ? normalizedDecorator : decorator ? /*#__PURE__*/React__default.createElement("div", {
|
|
117
|
+
className: `${prefix}--date-picker-input-inner-wrapper--decorator`
|
|
118
|
+
}, normalizedDecorator) : '', isFluid && /*#__PURE__*/React__default.createElement(DatePickerIcon, {
|
|
114
119
|
datePickerType: datePickerType
|
|
115
120
|
}), /*#__PURE__*/React__default.createElement(DatePickerIcon, {
|
|
116
121
|
datePickerType: datePickerType,
|
|
@@ -141,6 +146,10 @@ DatePickerInput.propTypes = {
|
|
|
141
146
|
* * `range` - With calendar dropdown and a date range.
|
|
142
147
|
*/
|
|
143
148
|
datePickerType: PropTypes.oneOf(['simple', 'single', 'range']),
|
|
149
|
+
/**
|
|
150
|
+
* **Experimental**: Provide a decorator component to be rendered inside the `RadioButton` component
|
|
151
|
+
*/
|
|
152
|
+
decorator: PropTypes.node,
|
|
144
153
|
/**
|
|
145
154
|
* Specify whether or not the input should be disabled
|
|
146
155
|
*/
|
|
@@ -204,10 +213,7 @@ DatePickerInput.propTypes = {
|
|
|
204
213
|
* Specify the size of the Date Picker Input. Currently supports either `sm`, `md`, or `lg` as an option.
|
|
205
214
|
*/
|
|
206
215
|
size: PropTypes.oneOf(['sm', 'md', 'lg']),
|
|
207
|
-
|
|
208
|
-
* **Experimental**: Provide a `Slug` component to be rendered inside the `DatePickerInput` component
|
|
209
|
-
*/
|
|
210
|
-
slug: PropTypes.node,
|
|
216
|
+
slug: deprecate(PropTypes.node, 'The `slug` prop has been deprecated and will be removed in the next major version. Use the decorator prop instead.'),
|
|
211
217
|
/**
|
|
212
218
|
* Specify the type of the `<input>`
|
|
213
219
|
*/
|
|
@@ -27,6 +27,10 @@ export interface DropdownProps<ItemType> extends Omit<ReactAttr<HTMLDivElement>,
|
|
|
27
27
|
* **Experimental**: Will attempt to automatically align the floating element to avoid collisions with the viewport and being clipped by ancestor elements.
|
|
28
28
|
*/
|
|
29
29
|
autoAlign?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* **Experimental**: Provide a `decorator` component to be rendered inside the `Dropdown` component
|
|
32
|
+
*/
|
|
33
|
+
decorator?: ReactNode;
|
|
30
34
|
/**
|
|
31
35
|
* Specify the direction of the dropdown. Can be either top or bottom.
|
|
32
36
|
*/
|
|
@@ -120,6 +124,7 @@ export interface DropdownProps<ItemType> extends Omit<ReactAttr<HTMLDivElement>,
|
|
|
120
124
|
*/
|
|
121
125
|
size?: ListBoxSize;
|
|
122
126
|
/**
|
|
127
|
+
* @deprecated please use `decorator` instead.
|
|
123
128
|
* **Experimental**: Provide a `Slug` component to be rendered inside the `Dropdown` component
|
|
124
129
|
*/
|
|
125
130
|
slug?: ReactNode;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
9
|
-
import React__default, { useEffect, useContext,
|
|
9
|
+
import React__default, { useEffect, useContext, useCallback, useMemo, useState } from 'react';
|
|
10
10
|
import { useSelect } from 'downshift';
|
|
11
11
|
import cx from 'classnames';
|
|
12
12
|
import PropTypes from 'prop-types';
|
|
@@ -39,13 +39,50 @@ const defaultItemToString = item => {
|
|
|
39
39
|
}
|
|
40
40
|
return '';
|
|
41
41
|
};
|
|
42
|
+
/**
|
|
43
|
+
* Custom state reducer for `useSelect` in Downshift, providing control over
|
|
44
|
+
* state changes.
|
|
45
|
+
*
|
|
46
|
+
* This function is called each time `useSelect` updates its internal state or
|
|
47
|
+
* triggers `onStateChange`. It allows for fine-grained control of state
|
|
48
|
+
* updates by modifying or overriding the default changes from Downshift's
|
|
49
|
+
* reducer.
|
|
50
|
+
* https://github.com/downshift-js/downshift/tree/master/src/hooks/useSelect#statereducer
|
|
51
|
+
*
|
|
52
|
+
* @param {Object} state - The current full state of the Downshift component.
|
|
53
|
+
* @param {Object} actionAndChanges - Contains the action type and proposed
|
|
54
|
+
* changes from the default Downshift reducer.
|
|
55
|
+
* @param {Object} actionAndChanges.changes - Suggested state changes.
|
|
56
|
+
* @param {string} actionAndChanges.type - The action type for the state
|
|
57
|
+
* change (e.g., item selection).
|
|
58
|
+
* @returns {Object} - The modified state based on custom logic or default
|
|
59
|
+
* changes if no custom logic applies.
|
|
60
|
+
*/
|
|
61
|
+
function stateReducer(state, actionAndChanges) {
|
|
62
|
+
const {
|
|
63
|
+
changes,
|
|
64
|
+
type
|
|
65
|
+
} = actionAndChanges;
|
|
66
|
+
switch (type) {
|
|
67
|
+
case ItemMouseMove:
|
|
68
|
+
case MenuMouseLeave:
|
|
69
|
+
if (changes.highlightedIndex === state.highlightedIndex) {
|
|
70
|
+
// Prevent state update if highlightedIndex hasn't changed
|
|
71
|
+
return state;
|
|
72
|
+
}
|
|
73
|
+
return changes;
|
|
74
|
+
default:
|
|
75
|
+
return changes;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
42
78
|
const Dropdown = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
|
|
43
79
|
let {
|
|
44
80
|
autoAlign = false,
|
|
45
81
|
className: containerClassName,
|
|
82
|
+
decorator,
|
|
46
83
|
disabled = false,
|
|
47
84
|
direction = 'bottom',
|
|
48
|
-
items,
|
|
85
|
+
items: itemsProp,
|
|
49
86
|
label,
|
|
50
87
|
['aria-label']: ariaLabel,
|
|
51
88
|
ariaLabel: deprecatedAriaLabel,
|
|
@@ -118,49 +155,47 @@ const Dropdown = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
|
|
|
118
155
|
const {
|
|
119
156
|
isFluid
|
|
120
157
|
} = useContext(FormContext);
|
|
121
|
-
const
|
|
158
|
+
const onSelectedItemChange = useCallback(_ref3 => {
|
|
159
|
+
let {
|
|
160
|
+
selectedItem
|
|
161
|
+
} = _ref3;
|
|
162
|
+
if (onChange) {
|
|
163
|
+
onChange({
|
|
164
|
+
selectedItem: selectedItem ?? null
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}, [onChange]);
|
|
168
|
+
const isItemDisabled = useCallback((item, _index) => {
|
|
169
|
+
const isObject = item !== null && typeof item === 'object';
|
|
170
|
+
return isObject && 'disabled' in item && item.disabled === true;
|
|
171
|
+
}, []);
|
|
172
|
+
const onHighlightedIndexChange = useCallback(changes => {
|
|
173
|
+
const {
|
|
174
|
+
highlightedIndex
|
|
175
|
+
} = changes;
|
|
176
|
+
if (highlightedIndex !== undefined && highlightedIndex > -1 && typeof window !== undefined) {
|
|
177
|
+
const itemArray = document.querySelectorAll(`li.${prefix}--list-box__menu-item[role="option"]`);
|
|
178
|
+
const highlightedItem = itemArray[highlightedIndex];
|
|
179
|
+
if (highlightedItem) {
|
|
180
|
+
highlightedItem.scrollIntoView({
|
|
181
|
+
behavior: 'smooth',
|
|
182
|
+
block: 'nearest'
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}, [prefix]);
|
|
187
|
+
const items = useMemo(() => itemsProp, [itemsProp]);
|
|
188
|
+
const selectProps = useMemo(() => ({
|
|
122
189
|
items,
|
|
123
190
|
itemToString,
|
|
124
191
|
initialSelectedItem,
|
|
125
192
|
onSelectedItemChange,
|
|
126
193
|
stateReducer,
|
|
127
|
-
isItemDisabled
|
|
128
|
-
|
|
129
|
-
return isObject && 'disabled' in item && item.disabled === true;
|
|
130
|
-
},
|
|
131
|
-
onHighlightedIndexChange: _ref3 => {
|
|
132
|
-
let {
|
|
133
|
-
highlightedIndex
|
|
134
|
-
} = _ref3;
|
|
135
|
-
if (highlightedIndex > -1 && typeof window !== undefined) {
|
|
136
|
-
const itemArray = document.querySelectorAll(`li.${prefix}--list-box__menu-item[role="option"]`);
|
|
137
|
-
const highlightedItem = itemArray[highlightedIndex];
|
|
138
|
-
if (highlightedItem) {
|
|
139
|
-
highlightedItem.scrollIntoView({
|
|
140
|
-
behavior: 'smooth',
|
|
141
|
-
block: 'nearest'
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
},
|
|
194
|
+
isItemDisabled,
|
|
195
|
+
onHighlightedIndexChange,
|
|
146
196
|
...downshiftProps
|
|
147
|
-
};
|
|
197
|
+
}), [items, itemToString, initialSelectedItem, onSelectedItemChange, stateReducer, isItemDisabled, onHighlightedIndexChange, downshiftProps]);
|
|
148
198
|
const dropdownInstanceId = useId();
|
|
149
|
-
function stateReducer(state, actionAndChanges) {
|
|
150
|
-
const {
|
|
151
|
-
changes,
|
|
152
|
-
type
|
|
153
|
-
} = actionAndChanges;
|
|
154
|
-
switch (type) {
|
|
155
|
-
case ItemMouseMove:
|
|
156
|
-
case MenuMouseLeave:
|
|
157
|
-
return {
|
|
158
|
-
...changes,
|
|
159
|
-
highlightedIndex: state.highlightedIndex
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
return changes;
|
|
163
|
-
}
|
|
164
199
|
|
|
165
200
|
// only set selectedItem if the prop is defined. Setting if it is undefined
|
|
166
201
|
// will overwrite default selected items from useSelect
|
|
@@ -205,80 +240,79 @@ const Dropdown = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
|
|
|
205
240
|
[`${prefix}--list-box__wrapper--inline--invalid`]: inline && invalid,
|
|
206
241
|
[`${prefix}--list-box__wrapper--fluid--invalid`]: isFluid && invalid,
|
|
207
242
|
[`${prefix}--list-box__wrapper--fluid--focus`]: isFluid && isFocused && !isOpen,
|
|
208
|
-
[`${prefix}--list-box__wrapper--slug`]: slug
|
|
243
|
+
[`${prefix}--list-box__wrapper--slug`]: slug,
|
|
244
|
+
[`${prefix}--list-box__wrapper--decorator`]: decorator
|
|
209
245
|
});
|
|
210
246
|
const helperId = !helperText ? undefined : `dropdown-helper-text-${dropdownInstanceId}`;
|
|
211
247
|
|
|
212
248
|
// needs to be Capitalized for react to render it correctly
|
|
213
249
|
const ItemToElement = itemToElement;
|
|
214
|
-
const toggleButtonProps = getToggleButtonProps({
|
|
250
|
+
const toggleButtonProps = useMemo(() => getToggleButtonProps({
|
|
215
251
|
'aria-label': ariaLabel || deprecatedAriaLabel
|
|
216
|
-
});
|
|
252
|
+
}), [getToggleButtonProps, ariaLabel, deprecatedAriaLabel, isOpen]);
|
|
217
253
|
const helper = helperText && !isFluid ? /*#__PURE__*/React__default.createElement("div", {
|
|
218
254
|
id: helperId,
|
|
219
255
|
className: helperClasses
|
|
220
256
|
}, helperText) : null;
|
|
221
|
-
function onSelectedItemChange(_ref4) {
|
|
222
|
-
let {
|
|
223
|
-
selectedItem
|
|
224
|
-
} = _ref4;
|
|
225
|
-
if (onChange) {
|
|
226
|
-
onChange({
|
|
227
|
-
selectedItem: selectedItem ?? null
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
257
|
const handleFocus = evt => {
|
|
232
258
|
setIsFocused(evt.type === 'focus' ? true : false);
|
|
233
259
|
};
|
|
234
260
|
const mergedRef = mergeRefs(toggleButtonProps.ref, ref);
|
|
235
261
|
const [currTimer, setCurrTimer] = useState();
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
onClick: evt => {
|
|
241
|
-
// NOTE: does not prevent click
|
|
242
|
-
evt.preventDefault();
|
|
243
|
-
// focus on the element as per readonly input behavior
|
|
244
|
-
mergedRef?.current?.focus();
|
|
245
|
-
},
|
|
246
|
-
onKeyDown: evt => {
|
|
247
|
-
const selectAccessKeys = ['ArrowDown', 'ArrowUp', ' ', 'Enter'];
|
|
248
|
-
// This prevents the select from opening for the above keys
|
|
249
|
-
if (selectAccessKeys.includes(evt.key)) {
|
|
250
|
-
evt.preventDefault();
|
|
251
|
-
}
|
|
262
|
+
const [isTyping, setIsTyping] = useState(false);
|
|
263
|
+
const onKeyDownHandler = useCallback(evt => {
|
|
264
|
+
if (evt.code !== 'Space' || !['ArrowDown', 'ArrowUp', ' ', 'Enter'].includes(evt.key)) {
|
|
265
|
+
setIsTyping(true);
|
|
252
266
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
setIsTyping(true);
|
|
267
|
+
if (isTyping && evt.code === 'Space' || !['ArrowDown', 'ArrowUp', ' ', 'Enter'].includes(evt.key)) {
|
|
268
|
+
if (currTimer) {
|
|
269
|
+
clearTimeout(currTimer);
|
|
257
270
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
271
|
+
setCurrTimer(setTimeout(() => {
|
|
272
|
+
setIsTyping(false);
|
|
273
|
+
}, 3000));
|
|
274
|
+
}
|
|
275
|
+
if (toggleButtonProps.onKeyDown) {
|
|
276
|
+
toggleButtonProps.onKeyDown(evt);
|
|
277
|
+
}
|
|
278
|
+
}, [isTyping, currTimer, toggleButtonProps]);
|
|
279
|
+
const readOnlyEventHandlers = useMemo(() => {
|
|
280
|
+
if (readOnly) {
|
|
281
|
+
return {
|
|
282
|
+
onClick: evt => {
|
|
283
|
+
// NOTE: does not prevent click
|
|
284
|
+
evt.preventDefault();
|
|
285
|
+
// focus on the element as per readonly input behavior
|
|
286
|
+
mergedRef?.current?.focus();
|
|
287
|
+
},
|
|
288
|
+
onKeyDown: evt => {
|
|
289
|
+
const selectAccessKeys = ['ArrowDown', 'ArrowUp', ' ', 'Enter'];
|
|
290
|
+
// This prevents the select from opening for the above keys
|
|
291
|
+
if (selectAccessKeys.includes(evt.key)) {
|
|
292
|
+
evt.preventDefault();
|
|
293
|
+
}
|
|
261
294
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
toggleButtonProps.onKeyDown(evt);
|
|
268
|
-
}
|
|
295
|
+
};
|
|
296
|
+
} else {
|
|
297
|
+
return {
|
|
298
|
+
onKeyDown: onKeyDownHandler
|
|
299
|
+
};
|
|
269
300
|
}
|
|
270
|
-
};
|
|
301
|
+
}, [readOnly, onKeyDownHandler]);
|
|
271
302
|
const menuProps = useMemo(() => getMenuProps({
|
|
272
303
|
ref: enableFloatingStyles || autoAlign ? refs.setFloating : null
|
|
273
|
-
}), [autoAlign, getMenuProps, refs.setFloating]);
|
|
304
|
+
}), [autoAlign, getMenuProps, refs.setFloating, enableFloatingStyles]);
|
|
274
305
|
|
|
275
|
-
//
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
306
|
+
// AILabel is always size `mini`
|
|
307
|
+
const normalizedDecorator = useMemo(() => {
|
|
308
|
+
let element = slug ?? decorator;
|
|
309
|
+
if (element && element['type']?.displayName === 'AILabel') {
|
|
310
|
+
return /*#__PURE__*/React__default.cloneElement(element, {
|
|
311
|
+
size: 'mini'
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
return /*#__PURE__*/React__default.isValidElement(element) ? element : null;
|
|
315
|
+
}, [slug, decorator]);
|
|
282
316
|
return /*#__PURE__*/React__default.createElement("div", _extends({
|
|
283
317
|
className: wrapperClasses
|
|
284
318
|
}, other), titleText && /*#__PURE__*/React__default.createElement("label", _extends({
|
|
@@ -317,7 +351,9 @@ const Dropdown = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
|
|
|
317
351
|
}, selectedItem ? renderSelectedItem ? renderSelectedItem(selectedItem) : itemToString(selectedItem) : label), /*#__PURE__*/React__default.createElement(ListBox.MenuIcon, {
|
|
318
352
|
isOpen: isOpen,
|
|
319
353
|
translateWithId: translateWithId
|
|
320
|
-
})),
|
|
354
|
+
})), slug ? normalizedDecorator : decorator ? /*#__PURE__*/React__default.createElement("div", {
|
|
355
|
+
className: `${prefix}--list-box__inner-wrapper--decorator`
|
|
356
|
+
}, normalizedDecorator) : '', /*#__PURE__*/React__default.createElement(ListBox.Menu, menuProps, isOpen && items.map((item, index) => {
|
|
321
357
|
const isObject = item !== null && typeof item === 'object';
|
|
322
358
|
const itemProps = getItemProps({
|
|
323
359
|
item,
|
|
@@ -360,6 +396,10 @@ Dropdown.propTypes = {
|
|
|
360
396
|
* Provide a custom className to be applied on the cds--dropdown node
|
|
361
397
|
*/
|
|
362
398
|
className: PropTypes.string,
|
|
399
|
+
/**
|
|
400
|
+
* **Experimental**: Provide a `decorator` component to be rendered inside the `Dropdown` component
|
|
401
|
+
*/
|
|
402
|
+
decorator: PropTypes.node,
|
|
363
403
|
/**
|
|
364
404
|
* Specify the direction of the dropdown. Can be either top or bottom.
|
|
365
405
|
*/
|
|
@@ -453,7 +493,7 @@ Dropdown.propTypes = {
|
|
|
453
493
|
/**
|
|
454
494
|
* **Experimental**: Provide a `Slug` component to be rendered inside the `Dropdown` component
|
|
455
495
|
*/
|
|
456
|
-
slug: PropTypes.node,
|
|
496
|
+
slug: deprecate(PropTypes.node, 'The `slug` prop for `Dropdown` has ' + 'been deprecated in favor of the new `decorator` prop. It will be removed in the next major release.'),
|
|
457
497
|
/**
|
|
458
498
|
* Provide the title text that will be read by a screen reader when
|
|
459
499
|
* visiting this control
|
|
@@ -120,8 +120,7 @@ function useChangedValue(value, compare, callback) {
|
|
|
120
120
|
*/
|
|
121
121
|
function useFeatureFlag(flag) {
|
|
122
122
|
const scope = useContext(FeatureFlagContext);
|
|
123
|
-
|
|
124
|
-
return scope.enabled(flag) ?? false;
|
|
123
|
+
return scope.enabled(flag);
|
|
125
124
|
}
|
|
126
125
|
|
|
127
126
|
/**
|
|
@@ -8,11 +8,14 @@ import React, { ReactNode } from 'react';
|
|
|
8
8
|
import { ButtonSize } from '../Button';
|
|
9
9
|
export declare const IconButtonKinds: readonly ["primary", "secondary", "ghost", "tertiary"];
|
|
10
10
|
export type IconButtonKind = (typeof IconButtonKinds)[number];
|
|
11
|
+
export type DeprecatedIconButtonAlignment = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'left-bottom' | 'left-top' | 'right-bottom' | 'right-top';
|
|
12
|
+
export type NewIconButtonAlignment = 'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'left-end' | 'left-start' | 'right-end' | 'right-start';
|
|
13
|
+
export type IconButtonAlignment = DeprecatedIconButtonAlignment | NewIconButtonAlignment;
|
|
11
14
|
interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
12
15
|
/**
|
|
13
16
|
* Specify how the trigger should align with the tooltip
|
|
14
17
|
*/
|
|
15
|
-
align?:
|
|
18
|
+
align?: IconButtonAlignment;
|
|
16
19
|
/**
|
|
17
20
|
* **Experimental**: Will attempt to automatically align the tooltip
|
|
18
21
|
*/
|
|
@@ -13,8 +13,22 @@ import '../Tooltip/DefinitionTooltip.js';
|
|
|
13
13
|
import { Tooltip } from '../Tooltip/Tooltip.js';
|
|
14
14
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
15
15
|
import ButtonBase from '../Button/ButtonBase.js';
|
|
16
|
+
import deprecateValuesWithin from '../../prop-types/deprecateValuesWithin.js';
|
|
16
17
|
|
|
17
18
|
const IconButtonKinds = ['primary', 'secondary', 'ghost', 'tertiary'];
|
|
19
|
+
const propMappingFunction = deprecatedValue => {
|
|
20
|
+
const mapping = {
|
|
21
|
+
'top-left': 'top-start',
|
|
22
|
+
'top-right': 'top-end',
|
|
23
|
+
'bottom-left': 'bottom-start',
|
|
24
|
+
'bottom-right': 'bottom-end',
|
|
25
|
+
'left-bottom': 'left-end',
|
|
26
|
+
'left-top': 'left-start',
|
|
27
|
+
'right-bottom': 'right-end',
|
|
28
|
+
'right-top': 'right-start'
|
|
29
|
+
};
|
|
30
|
+
return mapping[deprecatedValue];
|
|
31
|
+
};
|
|
18
32
|
const IconButton = /*#__PURE__*/React__default.forwardRef(function IconButton(_ref, ref) {
|
|
19
33
|
let {
|
|
20
34
|
align,
|
|
@@ -60,7 +74,32 @@ IconButton.propTypes = {
|
|
|
60
74
|
/**
|
|
61
75
|
* Specify how the trigger should align with the tooltip
|
|
62
76
|
*/
|
|
63
|
-
align: PropTypes.oneOf(['top', 'top-left',
|
|
77
|
+
align: deprecateValuesWithin(PropTypes.oneOf(['top', 'top-left',
|
|
78
|
+
// deprecated use top-start instead
|
|
79
|
+
'top-right',
|
|
80
|
+
// deprecated use top-end instead
|
|
81
|
+
|
|
82
|
+
'bottom', 'bottom-left',
|
|
83
|
+
// deprecated use bottom-start instead
|
|
84
|
+
'bottom-right',
|
|
85
|
+
// deprecated use bottom-end instead
|
|
86
|
+
|
|
87
|
+
'left', 'left-bottom',
|
|
88
|
+
// deprecated use left-end instead
|
|
89
|
+
'left-top',
|
|
90
|
+
// deprecated use left-start instead
|
|
91
|
+
|
|
92
|
+
'right', 'right-bottom',
|
|
93
|
+
// deprecated use right-end instead
|
|
94
|
+
'right-top',
|
|
95
|
+
// deprecated use right-start instead
|
|
96
|
+
|
|
97
|
+
// new values to match floating-ui
|
|
98
|
+
'top-start', 'top-end', 'bottom-start', 'bottom-end', 'left-end', 'left-start', 'right-end', 'right-start']),
|
|
99
|
+
//allowed prop values
|
|
100
|
+
['top', 'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end', 'left', 'left-start', 'left-end', 'right', 'right-start', 'right-end'],
|
|
101
|
+
//optional mapper function
|
|
102
|
+
propMappingFunction),
|
|
64
103
|
/**
|
|
65
104
|
* **Experimental**: Will attempt to automatically align the tooltip
|
|
66
105
|
*/
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface InlineCheckboxProps {
|
|
3
|
+
'aria-label': string;
|
|
4
|
+
/**
|
|
5
|
+
* Deprecated, please use `aria-label` instead.
|
|
6
|
+
* Specify the label for the control
|
|
7
|
+
*/
|
|
8
|
+
ariaLabel?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Specify whether the underlying control is checked,
|
|
11
|
+
* or not
|
|
12
|
+
* @default false
|
|
13
|
+
* */
|
|
14
|
+
checked?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Specify whether the underlying input control should be disabled
|
|
17
|
+
* @default false
|
|
18
|
+
*/
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Provide an `id` for the underlying input control
|
|
22
|
+
*/
|
|
23
|
+
id: string;
|
|
24
|
+
/**
|
|
25
|
+
* Specify whether the control is in an indeterminate state
|
|
26
|
+
*/
|
|
27
|
+
indeterminate?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Provide a `name` for the underlying input control
|
|
30
|
+
*/
|
|
31
|
+
name: string;
|
|
32
|
+
/**
|
|
33
|
+
* Provide an optional hook that is called each time the input is updated
|
|
34
|
+
*/
|
|
35
|
+
onChange?: (checked: boolean, id: string, event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
36
|
+
/**
|
|
37
|
+
* Provide a handler that is invoked when a user clicks on the control
|
|
38
|
+
*/
|
|
39
|
+
onClick?: (event: React.MouseEvent<HTMLInputElement>) => void;
|
|
40
|
+
/**
|
|
41
|
+
* Provide a handler that is invoked on the key down event for the control
|
|
42
|
+
*/
|
|
43
|
+
onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;
|
|
44
|
+
/**
|
|
45
|
+
* Provide an optional tooltip for the InlineCheckbox
|
|
46
|
+
*/
|
|
47
|
+
title?: string;
|
|
48
|
+
}
|
|
49
|
+
declare const InlineCheckbox: React.ForwardRefExoticComponent<InlineCheckboxProps & React.RefAttributes<HTMLInputElement>>;
|
|
50
|
+
export default InlineCheckbox;
|