carbon-react 109.3.2 → 109.3.5
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/esm/__internal__/fieldset/fieldset.component.d.ts +25 -0
- package/esm/__internal__/fieldset/fieldset.component.js +167 -50
- package/esm/__internal__/fieldset/fieldset.style.d.ts +13 -0
- package/esm/__internal__/fieldset/fieldset.style.js +0 -10
- package/esm/__internal__/fieldset/index.d.ts +2 -1
- package/esm/__internal__/popover/index.d.ts +2 -1
- package/esm/__internal__/popover/popover.component.d.ts +18 -0
- package/esm/__internal__/popover/popover.component.js +23 -21
- package/esm/__internal__/popover/popover.style.d.ts +2 -0
- package/esm/components/button/button.component.d.ts +2 -0
- package/esm/components/button/button.component.js +2 -0
- package/esm/components/multi-action-button/multi-action-button.component.js +1 -0
- package/esm/components/pager/pager.component.js +1 -1
- package/esm/components/pager/pager.style.js +1 -1
- package/esm/components/select/multi-select/multi-select.component.js +36 -34
- package/esm/components/select/select-list/select-list.component.js +9 -1
- package/esm/components/select/select-list/select-list.style.js +8 -1
- package/esm/components/split-button/index.d.ts +2 -2
- package/esm/components/split-button/split-button-children.style.d.ts +8 -0
- package/esm/components/split-button/split-button-children.style.js +3 -4
- package/esm/components/split-button/split-button-toggle.style.d.ts +10 -0
- package/esm/components/split-button/split-button.component.d.ts +29 -0
- package/esm/components/split-button/split-button.component.js +534 -87
- package/esm/components/split-button/split-button.config.d.ts +4 -0
- package/esm/components/split-button/split-button.style.d.ts +2 -0
- package/lib/__internal__/fieldset/fieldset.component.d.ts +25 -0
- package/lib/__internal__/fieldset/fieldset.component.js +167 -53
- package/lib/__internal__/fieldset/fieldset.style.d.ts +13 -0
- package/lib/__internal__/fieldset/fieldset.style.js +1 -12
- package/lib/__internal__/fieldset/index.d.ts +2 -1
- package/lib/__internal__/popover/index.d.ts +2 -1
- package/lib/__internal__/popover/popover.component.d.ts +18 -0
- package/lib/__internal__/popover/popover.component.js +24 -22
- package/lib/__internal__/popover/popover.style.d.ts +2 -0
- package/lib/components/button/button.component.d.ts +2 -0
- package/lib/components/button/button.component.js +2 -0
- package/lib/components/multi-action-button/multi-action-button.component.js +1 -0
- package/lib/components/pager/pager.component.js +1 -1
- package/lib/components/pager/pager.style.js +1 -1
- package/lib/components/select/multi-select/multi-select.component.js +36 -34
- package/lib/components/select/select-list/select-list.component.js +9 -1
- package/lib/components/select/select-list/select-list.style.js +8 -1
- package/lib/components/split-button/index.d.ts +2 -2
- package/lib/components/split-button/split-button-children.style.d.ts +8 -0
- package/lib/components/split-button/split-button-children.style.js +3 -4
- package/lib/components/split-button/split-button-toggle.style.d.ts +10 -0
- package/lib/components/split-button/split-button.component.d.ts +29 -0
- package/lib/components/split-button/split-button.component.js +535 -89
- package/lib/components/split-button/split-button.config.d.ts +4 -0
- package/lib/components/split-button/split-button.style.d.ts +2 -0
- package/package.json +2 -2
- package/esm/__internal__/fieldset/fieldset.d.ts +0 -37
- package/esm/__internal__/popover/popover.d.ts +0 -46
- package/esm/components/split-button/split-button.d.ts +0 -29
- package/lib/__internal__/fieldset/fieldset.d.ts +0 -37
- package/lib/__internal__/popover/popover.d.ts +0 -46
- package/lib/components/split-button/split-button.d.ts +0 -29
|
@@ -64,6 +64,7 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
64
64
|
const [highlightedValue, setHighlightedValue] = useState("");
|
|
65
65
|
const [filterText, setFilterText] = useState("");
|
|
66
66
|
const [placeholderOverride, setPlaceholderOverride] = useState();
|
|
67
|
+
const actualValue = isControlled.current ? value : selectedValue;
|
|
67
68
|
const setOpen = useCallback(() => {
|
|
68
69
|
setOpenState(isAlreadyOpen => {
|
|
69
70
|
if (!isAlreadyOpen && onOpen) {
|
|
@@ -86,6 +87,23 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
86
87
|
};
|
|
87
88
|
return customEvent;
|
|
88
89
|
}, [name, id]);
|
|
90
|
+
/* generic value update function which can be used for both controlled and uncontrolled
|
|
91
|
+
* components, both with and without onChange.
|
|
92
|
+
* It accepts a function to update the value, which is assumed to be have no side effects and therefore
|
|
93
|
+
* be safe to run more than once if needed. */
|
|
94
|
+
|
|
95
|
+
const updateValue = useCallback(updateFunction => {
|
|
96
|
+
const newValue = updateFunction(actualValue); // only call onChange if an option has been selected or deselected
|
|
97
|
+
|
|
98
|
+
if (onChange && newValue.length !== actualValue.length) {
|
|
99
|
+
onChange(createCustomEvent(newValue));
|
|
100
|
+
} // no need to update selectedValue if the component is controlled: onChange should take care of updating the value
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
if (!isControlled.current) {
|
|
104
|
+
setSelectedValue(updateFunction);
|
|
105
|
+
}
|
|
106
|
+
}, [createCustomEvent, onChange, actualValue]);
|
|
89
107
|
const handleTextboxChange = useCallback(event => {
|
|
90
108
|
const newValue = event.target.value;
|
|
91
109
|
const match = findElementWithMatchingText(newValue, children);
|
|
@@ -99,24 +117,17 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
99
117
|
setOpen();
|
|
100
118
|
}, [children, setOpen]);
|
|
101
119
|
const removeSelectedValue = useCallback(index => {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
120
|
+
isClickTriggeredBySelect.current = true;
|
|
121
|
+
updateValue(previousValue => {
|
|
105
122
|
if (!previousValue.length) {
|
|
106
123
|
return previousValue;
|
|
107
124
|
}
|
|
108
125
|
|
|
109
126
|
const newValue = [...previousValue];
|
|
110
127
|
newValue.splice(index, 1);
|
|
111
|
-
|
|
112
|
-
if (onChange) {
|
|
113
|
-
onChange(createCustomEvent(newValue));
|
|
114
|
-
return newValue;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
128
|
return newValue;
|
|
118
129
|
});
|
|
119
|
-
}, [
|
|
130
|
+
}, [updateValue]);
|
|
120
131
|
const handleTextboxKeydown = useCallback(event => {
|
|
121
132
|
const {
|
|
122
133
|
key
|
|
@@ -142,12 +153,12 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
142
153
|
|
|
143
154
|
}, [onKeyDown, readOnly, filterText, textValue, setOpen, removeSelectedValue]);
|
|
144
155
|
const accessibilityLabel = useMemo(() => {
|
|
145
|
-
return
|
|
146
|
-
return
|
|
156
|
+
return actualValue && actualValue.length ? React.Children.map(children, child => {
|
|
157
|
+
return actualValue.includes(child.props.value) ? child.props.text : false;
|
|
147
158
|
}).filter(child => child).reduce((acc, item) => {
|
|
148
159
|
return acc ? `${acc}, ${item}` : item;
|
|
149
160
|
}, "") : null;
|
|
150
|
-
}, [children,
|
|
161
|
+
}, [children, actualValue]);
|
|
151
162
|
const handleGlobalClick = useCallback(event => {
|
|
152
163
|
isMouseDownReported.current = false;
|
|
153
164
|
|
|
@@ -170,11 +181,11 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
170
181
|
const mapValuesToPills = useMemo(() => {
|
|
171
182
|
const canDelete = !disabled && !readOnly;
|
|
172
183
|
|
|
173
|
-
if (!
|
|
184
|
+
if (!actualValue.length) {
|
|
174
185
|
return "";
|
|
175
186
|
}
|
|
176
187
|
|
|
177
|
-
return
|
|
188
|
+
return actualValue.map((singleValue, index) => {
|
|
178
189
|
const matchingOption = React.Children.toArray(children).find(child => isExpectedOption(child, singleValue));
|
|
179
190
|
let pillProps = {};
|
|
180
191
|
|
|
@@ -203,22 +214,18 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
203
214
|
const onChangeMissingMessage = "onChange prop required when using a controlled input element";
|
|
204
215
|
!(isControlled.current === (value !== undefined)) ? process.env.NODE_ENV !== "production" ? invariant(false, modeSwitchedMessage) : invariant(false) : void 0;
|
|
205
216
|
!(!isControlled.current || isControlled.current && onChange) ? process.env.NODE_ENV !== "production" ? invariant(false, onChangeMissingMessage) : invariant(false) : void 0;
|
|
206
|
-
|
|
207
|
-
if (isControlled.current) {
|
|
208
|
-
setSelectedValue(value);
|
|
209
|
-
}
|
|
210
217
|
}, [value, onChange]); // removes placeholder when a value is present
|
|
211
218
|
|
|
212
219
|
useEffect(() => {
|
|
213
220
|
const hasValue = value === null || value === void 0 ? void 0 : value.length;
|
|
214
|
-
const hasSelectedValue =
|
|
221
|
+
const hasSelectedValue = actualValue === null || actualValue === void 0 ? void 0 : actualValue.length;
|
|
215
222
|
|
|
216
223
|
if (hasValue || hasSelectedValue) {
|
|
217
224
|
setPlaceholderOverride(" ");
|
|
218
225
|
} else {
|
|
219
226
|
setPlaceholderOverride(placeholder);
|
|
220
227
|
}
|
|
221
|
-
}, [value,
|
|
228
|
+
}, [value, actualValue, placeholder]);
|
|
222
229
|
useEffect(() => {
|
|
223
230
|
const clickEvent = "click";
|
|
224
231
|
window.addEventListener(clickEvent, handleGlobalClick);
|
|
@@ -335,27 +342,22 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
335
342
|
}
|
|
336
343
|
|
|
337
344
|
setTextValue("");
|
|
338
|
-
const isAlreadySelected =
|
|
345
|
+
const isAlreadySelected = actualValue.findIndex(val => isExpectedValue(val, newValue)) !== -1;
|
|
339
346
|
|
|
340
347
|
if (!isAlreadySelected && isControlled.current && onChange) {
|
|
341
|
-
onChange(createCustomEvent([...
|
|
348
|
+
onChange(createCustomEvent([...actualValue, newValue]));
|
|
342
349
|
}
|
|
343
350
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
351
|
+
textboxRef.focus();
|
|
352
|
+
isMouseDownReported.current = false;
|
|
353
|
+
updateValue(previousValue => {
|
|
348
354
|
if (isAlreadySelected) {
|
|
349
355
|
return previousValue;
|
|
350
356
|
}
|
|
351
357
|
|
|
352
|
-
if (onChange) {
|
|
353
|
-
onChange(createCustomEvent([...previousValue, newValue]));
|
|
354
|
-
}
|
|
355
|
-
|
|
356
358
|
return [...previousValue, newValue];
|
|
357
359
|
});
|
|
358
|
-
}, [createCustomEvent, onChange, textboxRef,
|
|
360
|
+
}, [createCustomEvent, onChange, textboxRef, actualValue, updateValue]);
|
|
359
361
|
|
|
360
362
|
function onSelectListClose() {
|
|
361
363
|
setOpenState(false);
|
|
@@ -389,7 +391,7 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
389
391
|
leftChildren: mapValuesToPills,
|
|
390
392
|
inputRef: assignInput,
|
|
391
393
|
formattedValue: textValue,
|
|
392
|
-
selectedValue,
|
|
394
|
+
selectedValue: actualValue,
|
|
393
395
|
onClick: handleTextboxClick,
|
|
394
396
|
onMouseDown: handleTextboxMouseDown,
|
|
395
397
|
onFocus: handleTextboxFocus,
|
|
@@ -423,7 +425,7 @@ const MultiSelect = /*#__PURE__*/React.forwardRef(({
|
|
|
423
425
|
listPlacement: listPlacement,
|
|
424
426
|
flipEnabled: flipEnabled,
|
|
425
427
|
loaderDataRole: "multi-select-list-loader",
|
|
426
|
-
multiselectValues:
|
|
428
|
+
multiselectValues: actualValue
|
|
427
429
|
}, children);
|
|
428
430
|
return /*#__PURE__*/React.createElement(StyledSelectMultiSelect, _extends({
|
|
429
431
|
disabled: disabled,
|
|
@@ -51,6 +51,7 @@ const SelectList = /*#__PURE__*/React.forwardRef(({
|
|
|
51
51
|
const [currentOptionsListIndex, setCurrentOptionsListIndex] = useState(-1);
|
|
52
52
|
const [listHeight, setListHeight] = useState(0);
|
|
53
53
|
const [listWidth, setListWidth] = useState(null);
|
|
54
|
+
const [scrollbarWidth, setScrollbarWidth] = useState(0);
|
|
54
55
|
const placement = useRef("bottom");
|
|
55
56
|
const lastFilter = useRef("");
|
|
56
57
|
const listRef = useRef();
|
|
@@ -66,6 +67,11 @@ const SelectList = /*#__PURE__*/React.forwardRef(({
|
|
|
66
67
|
allowScroll();
|
|
67
68
|
};
|
|
68
69
|
}, [allowScroll, blockScroll]);
|
|
70
|
+
useLayoutEffect(() => {
|
|
71
|
+
if (multiColumn) {
|
|
72
|
+
setScrollbarWidth(tableRef.current.offsetWidth - tableRef.current.clientWidth);
|
|
73
|
+
}
|
|
74
|
+
}, [multiColumn]);
|
|
69
75
|
const setPlacementCallback = useCallback(popper => {
|
|
70
76
|
placement.current = popper.placement;
|
|
71
77
|
}, [placement]);
|
|
@@ -287,7 +293,9 @@ const SelectList = /*#__PURE__*/React.forwardRef(({
|
|
|
287
293
|
let selectListContent = childrenWithListProps;
|
|
288
294
|
|
|
289
295
|
if (multiColumn) {
|
|
290
|
-
selectListContent = /*#__PURE__*/React.createElement(StyledSelectListTable, null, /*#__PURE__*/React.createElement(StyledSelectListTableHeader,
|
|
296
|
+
selectListContent = /*#__PURE__*/React.createElement(StyledSelectListTable, null, /*#__PURE__*/React.createElement(StyledSelectListTableHeader, {
|
|
297
|
+
scrollbarWidth: scrollbarWidth
|
|
298
|
+
}, tableHeader), /*#__PURE__*/React.createElement(StyledSelectListTableBody, {
|
|
291
299
|
ref: tableRef
|
|
292
300
|
}, childrenWithListProps));
|
|
293
301
|
}
|
|
@@ -74,11 +74,18 @@ const StyledSelectListTable = styled.table`
|
|
|
74
74
|
`; // TODO (design-tokens): to match current style for border bottom colorsUtilityMajor100
|
|
75
75
|
|
|
76
76
|
const StyledSelectListTableHeader = styled.thead`
|
|
77
|
+
border-bottom: 1px solid var(--colorsUtilityMajor050);
|
|
78
|
+
|
|
79
|
+
tr {
|
|
80
|
+
width: ${({
|
|
81
|
+
scrollbarWidth
|
|
82
|
+
}) => `calc(100% - ${scrollbarWidth}px)`};
|
|
83
|
+
}
|
|
84
|
+
|
|
77
85
|
th {
|
|
78
86
|
position: sticky;
|
|
79
87
|
top: 0;
|
|
80
88
|
padding: var(--spacing200);
|
|
81
|
-
border-bottom: 1px solid var(--colorsUtilityMajor050);
|
|
82
89
|
background-color: white;
|
|
83
90
|
text-align: left;
|
|
84
91
|
font-weight: 900;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { default } from "./split-button";
|
|
2
|
-
export type { SplitButtonProps } from "./split-button";
|
|
1
|
+
export { default } from "./split-button.component";
|
|
2
|
+
export type { SplitButtonProps } from "./split-button.component";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ThemeObject } from "../../style/themes/base";
|
|
2
|
+
declare type StyledSplitButtonChildrenContainerProps = {
|
|
3
|
+
theme: ThemeObject;
|
|
4
|
+
align: "left" | "right";
|
|
5
|
+
minWidth: number;
|
|
6
|
+
};
|
|
7
|
+
declare const StyledSplitButtonChildrenContainer: import("styled-components").StyledComponent<"div", any, StyledSplitButtonChildrenContainerProps, never>;
|
|
8
|
+
export default StyledSplitButtonChildrenContainer;
|
|
@@ -4,12 +4,11 @@ import StyledButton from "../button/button.style";
|
|
|
4
4
|
const StyledSplitButtonChildrenContainer = styled.div`
|
|
5
5
|
${({
|
|
6
6
|
theme,
|
|
7
|
-
align
|
|
7
|
+
align,
|
|
8
|
+
minWidth
|
|
8
9
|
}) => css`
|
|
9
10
|
background-color: var(--colorsActionMajorYang100);
|
|
10
|
-
min-width: ${
|
|
11
|
-
minWidth
|
|
12
|
-
}) => minWidth}px;
|
|
11
|
+
min-width: ${minWidth}px;
|
|
13
12
|
white-space: nowrap;
|
|
14
13
|
z-index: ${theme.zIndex.popover};
|
|
15
14
|
box-shadow: var(--boxShadow100);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
declare type StyledSplitButtonToggleProps = {
|
|
2
|
+
buttonType: "primary" | "secondary";
|
|
3
|
+
disabled: boolean;
|
|
4
|
+
displayed: boolean;
|
|
5
|
+
size: "small" | "medium" | "large";
|
|
6
|
+
};
|
|
7
|
+
declare const StyledSplitButtonToggle: import("styled-components").StyledComponent<"button", any, import("styled-system").SpaceProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, string | number | symbol> & import("../button").ButtonProps & {
|
|
8
|
+
iconOnly?: boolean | undefined;
|
|
9
|
+
} & StyledSplitButtonToggleProps, never>;
|
|
10
|
+
export default StyledSplitButtonToggle;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { MarginProps } from "styled-system";
|
|
3
|
+
import { IconType } from "../icon";
|
|
4
|
+
export interface SplitButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, MarginProps {
|
|
5
|
+
/** Set align of the rendered content */
|
|
6
|
+
align?: "left" | "right";
|
|
7
|
+
/** Button type: "primary" | "secondary" */
|
|
8
|
+
buttonType?: "primary" | "secondary";
|
|
9
|
+
/** The additional button to display. */
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
/** A custom value for the data-element attribute */
|
|
12
|
+
"data-element"?: string;
|
|
13
|
+
/** A custom value for the data-role attribute */
|
|
14
|
+
"data-role"?: string;
|
|
15
|
+
/** Gives the button a disabled state. */
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
/** Defines an Icon position within the button: "before" | "after" */
|
|
18
|
+
iconPosition?: "before" | "after";
|
|
19
|
+
/** Defines an Icon type within the button */
|
|
20
|
+
iconType?: IconType;
|
|
21
|
+
/** The size of the buttons in the SplitButton. */
|
|
22
|
+
size?: "small" | "medium" | "large";
|
|
23
|
+
/** Second text child, renders under main text, only when size is "large" */
|
|
24
|
+
subtext?: string;
|
|
25
|
+
/** The text to be displayed in the SplitButton. */
|
|
26
|
+
text: string;
|
|
27
|
+
}
|
|
28
|
+
export declare const SplitButton: ({ align, buttonType, children, disabled, iconPosition, iconType, onClick, size, subtext, text, "data-element": dataElement, "data-role": dataRole, ...rest }: SplitButtonProps) => JSX.Element;
|
|
29
|
+
export default SplitButton;
|