carbon-react 119.7.2 → 119.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/esm/components/action-popover/action-popover-context.d.ts +2 -0
  2. package/esm/components/action-popover/action-popover-item/action-popover-item.component.d.ts +17 -2
  3. package/esm/components/action-popover/action-popover-item/action-popover-item.component.js +89 -41
  4. package/esm/components/action-popover/action-popover-menu/action-popover-menu.component.d.ts +6 -3
  5. package/esm/components/action-popover/action-popover-menu/action-popover-menu.component.js +19 -6
  6. package/esm/components/action-popover/action-popover.component.d.ts +5 -2
  7. package/esm/components/action-popover/action-popover.component.js +2 -0
  8. package/esm/components/action-popover/action-popover.style.d.ts +12 -4
  9. package/esm/components/action-popover/action-popover.style.js +107 -19
  10. package/esm/components/select/option/option.component.d.ts +7 -1
  11. package/esm/components/select/option/option.component.js +3 -0
  12. package/esm/components/select/option-group-header/option-group-header.component.d.ts +7 -1
  13. package/esm/components/select/option-group-header/option-group-header.component.js +4 -0
  14. package/esm/components/select/option-row/option-row.component.d.ts +6 -6
  15. package/esm/components/select/option-row/option-row.component.js +4 -1
  16. package/esm/components/select/select-list/select-list.component.js +1 -1
  17. package/lib/components/action-popover/action-popover-context.d.ts +2 -0
  18. package/lib/components/action-popover/action-popover-item/action-popover-item.component.d.ts +17 -2
  19. package/lib/components/action-popover/action-popover-item/action-popover-item.component.js +88 -40
  20. package/lib/components/action-popover/action-popover-menu/action-popover-menu.component.d.ts +6 -3
  21. package/lib/components/action-popover/action-popover-menu/action-popover-menu.component.js +18 -5
  22. package/lib/components/action-popover/action-popover.component.d.ts +5 -2
  23. package/lib/components/action-popover/action-popover.component.js +2 -0
  24. package/lib/components/action-popover/action-popover.style.d.ts +12 -4
  25. package/lib/components/action-popover/action-popover.style.js +109 -19
  26. package/lib/components/select/option/option.component.d.ts +7 -1
  27. package/lib/components/select/option/option.component.js +3 -0
  28. package/lib/components/select/option-group-header/option-group-header.component.d.ts +7 -1
  29. package/lib/components/select/option-group-header/option-group-header.component.js +4 -0
  30. package/lib/components/select/option-row/option-row.component.d.ts +6 -6
  31. package/lib/components/select/option-row/option-row.component.js +4 -1
  32. package/lib/components/select/select-list/select-list.component.js +1 -1
  33. package/package.json +1 -1
@@ -1,7 +1,9 @@
1
1
  import React from "react";
2
+ export declare type Alignment = "left" | "right";
2
3
  declare type ActionPopoverContextType = {
3
4
  setOpenPopover: (isOpen: boolean) => void;
4
5
  focusButton: () => void;
6
+ submenuPosition: Alignment;
5
7
  isOpenPopover: boolean;
6
8
  };
7
9
  declare const ActionPopoverContext: React.Context<ActionPopoverContextType | null>;
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
+ import { Alignment } from "../action-popover-context";
2
3
  import { IconType } from "../../icon";
3
4
  export interface ActionPopoverItemProps {
4
5
  /** The text label to display for this Item */
@@ -20,10 +21,24 @@ export interface ActionPopoverItemProps {
20
21
  /** @ignore @private */
21
22
  focusItem?: boolean;
22
23
  /** @ignore @private */
23
- horizontalAlignment?: "left" | "right";
24
+ horizontalAlignment?: Alignment;
25
+ /** @ignore @private */
26
+ childHasSubmenu?: boolean;
27
+ /** @ignore @private */
28
+ childHasIcon?: boolean;
29
+ /** @ignore @private */
30
+ currentSubmenuPosition?: Alignment;
31
+ /** @ignore @private */
32
+ setChildHasSubmenu?: (value: boolean) => void;
33
+ /** @ignore @private */
34
+ setChildHasIcon?: (value: boolean) => void;
35
+ /** @ignore @private */
36
+ setCurrentSubmenuPosition?: (value: Alignment) => void;
37
+ /** @ignore @private */
38
+ isASubmenu?: boolean;
24
39
  }
25
40
  export declare const ActionPopoverItem: {
26
- ({ children, icon, disabled, onClick: onClickProp, submenu, placement, focusItem, download, href, horizontalAlignment, ...rest }: ActionPopoverItemProps): React.JSX.Element;
41
+ ({ children, icon, disabled, onClick: onClickProp, submenu, placement, focusItem, download, href, horizontalAlignment, childHasSubmenu, childHasIcon, currentSubmenuPosition, setChildHasSubmenu, setChildHasIcon, setCurrentSubmenuPosition, isASubmenu, ...rest }: ActionPopoverItemProps): React.JSX.Element;
27
42
  displayName: string;
28
43
  };
29
44
  export default ActionPopoverItem;
@@ -2,7 +2,7 @@ function _extends() { _extends = Object.assign ? Object.assign.bind() : function
2
2
  import React, { useCallback, useEffect, useRef, useState, useContext } from "react";
3
3
  import PropTypes from "prop-types";
4
4
  import invariant from "invariant";
5
- import { MenuItemIcon, SubMenuItemIcon, StyledMenuItem, StyledMenuItemWrapper } from "../action-popover.style";
5
+ import { MenuItemIcon, SubMenuItemIcon, StyledMenuItem, StyledMenuItemInnerText, StyledMenuItemOuterContainer, StyledMenuItemWrapper } from "../action-popover.style";
6
6
  import Events from "../../../__internal__/utils/helpers/events";
7
7
  import createGuid from "../../../__internal__/utils/helpers/guid";
8
8
  import ActionPopoverContext from "../action-popover-context";
@@ -12,33 +12,22 @@ const INTERVAL = 150;
12
12
  function checkRef(ref) {
13
13
  return Boolean(ref && ref.current);
14
14
  }
15
- function leftAlignSubmenu(ref, submenuRef) {
15
+ function calculateSubmenuPosition(ref, submenuRef, submenuPosition, currentSubmenuPosition) {
16
16
  /* istanbul ignore if */
17
- if (!ref.current || !submenuRef.current) return true;
17
+
18
+ if (!ref.current || !submenuRef.current) return currentSubmenuPosition || submenuPosition;
18
19
  const {
19
- left
20
+ left,
21
+ right
20
22
  } = ref.current.getBoundingClientRect();
21
23
  const {
22
24
  offsetWidth
23
25
  } = submenuRef.current;
24
- return left >= offsetWidth;
25
- }
26
- function getContainerPosition(itemRef, submenuRef, placement) {
27
- /* istanbul ignore if */
28
- if (!itemRef.current || !submenuRef.current) return undefined;
29
- const {
30
- offsetWidth: parentWidth
31
- } = itemRef.current;
32
- const {
33
- offsetWidth: submenuWidth
34
- } = submenuRef.current;
35
- const xPositionValue = leftAlignSubmenu(itemRef, submenuRef) ? -submenuWidth : parentWidth;
36
- const yPositionName = placement === "top" ? "bottom" : "top";
37
- return {
38
- left: xPositionValue,
39
- [yPositionName]: "calc(-1 * var(--spacing100))",
40
- right: "auto"
41
- };
26
+ const windowWidth = document.body.clientWidth;
27
+ if (submenuPosition === "left") {
28
+ return left >= offsetWidth ? "left" : "right";
29
+ }
30
+ return windowWidth >= right + offsetWidth ? "right" : "left";
42
31
  }
43
32
  export const ActionPopoverItem = _ref => {
44
33
  let {
@@ -52,6 +41,13 @@ export const ActionPopoverItem = _ref => {
52
41
  download,
53
42
  href,
54
43
  horizontalAlignment,
44
+ childHasSubmenu,
45
+ childHasIcon,
46
+ currentSubmenuPosition,
47
+ setChildHasSubmenu,
48
+ setChildHasIcon,
49
+ setCurrentSubmenuPosition,
50
+ isASubmenu = false,
55
51
  ...rest
56
52
  } = _ref;
57
53
  const l = useLocale();
@@ -61,14 +57,14 @@ export const ActionPopoverItem = _ref => {
61
57
  const {
62
58
  setOpenPopover,
63
59
  isOpenPopover,
64
- focusButton
60
+ focusButton,
61
+ submenuPosition
65
62
  } = context;
66
63
  const isHref = !!href;
67
64
  const [containerPosition, setContainerPosition] = useState(undefined);
68
65
  const [guid] = useState(createGuid());
69
66
  const [isOpen, setOpen] = useState(false);
70
67
  const [focusIndex, setFocusIndex] = useState(0);
71
- const [isLeftAligned, setIsLeftAligned] = useState(true);
72
68
  const submenuRef = useRef(null);
73
69
  const ref = useRef(null);
74
70
  const mouseEnterTimer = useRef(null);
@@ -78,19 +74,48 @@ export const ActionPopoverItem = _ref => {
78
74
  setOpen(false);
79
75
  }
80
76
  }, [isOpenPopover]);
77
+ useEffect(() => {
78
+ if (icon) {
79
+ setChildHasIcon?.(true);
80
+ }
81
+ if (submenu) {
82
+ setChildHasSubmenu?.(true);
83
+ }
84
+ }, [icon, setChildHasSubmenu, setChildHasIcon, submenu]);
81
85
  const alignSubmenu = useCallback(() => {
82
- if (checkRef(ref) && checkRef(submenuRef) && submenu) {
83
- const align = leftAlignSubmenu(ref, submenuRef);
84
- setIsLeftAligned(align);
85
- setContainerPosition(getContainerPosition(ref, submenuRef, placement));
86
+ const checkCalculatedSubmenuPosition = calculateSubmenuPosition(ref, submenuRef, submenuPosition, currentSubmenuPosition);
87
+ setCurrentSubmenuPosition?.(checkCalculatedSubmenuPosition);
88
+ return checkRef(ref) && checkRef(submenuRef) && submenu;
89
+ }, [submenu, setCurrentSubmenuPosition, submenuPosition, currentSubmenuPosition]);
90
+ useEffect(() => {
91
+ const getContainerPosition = () => {
92
+ /* istanbul ignore if */
93
+ if (!ref.current || !submenuRef.current) return undefined;
94
+ const {
95
+ offsetWidth: submenuWidth
96
+ } = submenuRef.current;
97
+ const leftAlignedSubmenu = currentSubmenuPosition === "left";
98
+ const leftValue = leftAlignedSubmenu ? -submenuWidth : "auto";
99
+ const rightValue = leftAlignedSubmenu ? "auto" : -submenuWidth;
100
+ const yPositionName = placement === "top" ? "bottom" : "top";
101
+ return {
102
+ left: leftValue,
103
+ [yPositionName]: "calc(-1 * var(--spacing100))",
104
+ right: rightValue
105
+ };
106
+ };
107
+ setContainerPosition(getContainerPosition);
108
+ }, [submenu, currentSubmenuPosition, placement]);
109
+ useEffect(() => {
110
+ if (submenu) {
111
+ alignSubmenu();
86
112
  }
87
- }, [submenu, placement]);
113
+ }, [alignSubmenu, submenu]);
88
114
  useEffect(() => {
89
- alignSubmenu();
90
115
  if (focusItem) {
91
116
  ref.current?.focus();
92
117
  }
93
- }, [alignSubmenu, focusItem]);
118
+ }, [focusItem]);
94
119
  useEffect(() => {
95
120
  return function cleanup() {
96
121
  if (mouseEnterTimer.current) clearTimeout(mouseEnterTimer.current);
@@ -123,7 +148,7 @@ export const ActionPopoverItem = _ref => {
123
148
  e.stopPropagation();
124
149
  } else if (!disabled) {
125
150
  if (submenu) {
126
- if (isLeftAligned) {
151
+ if (currentSubmenuPosition === "left") {
127
152
  // LEFT: open if has submenu and left aligned otherwise close submenu
128
153
  if (Events.isLeftKey(e) || Events.isEnterKey(e)) {
129
154
  setOpen(true);
@@ -159,7 +184,7 @@ export const ActionPopoverItem = _ref => {
159
184
  } else if (Events.isEnterKey(e)) {
160
185
  e.stopPropagation();
161
186
  }
162
- }, [disabled, download, isHref, isLeftAligned, onClick, submenu]);
187
+ }, [disabled, download, isHref, onClick, submenu, currentSubmenuPosition]);
163
188
  const itemSubmenuProps = {
164
189
  ...(!disabled && {
165
190
  onClick: e => {
@@ -195,8 +220,15 @@ export const ActionPopoverItem = _ref => {
195
220
  };
196
221
  const renderMenuItemIcon = () => {
197
222
  return icon && /*#__PURE__*/React.createElement(MenuItemIcon, {
198
- as: undefined,
199
- type: icon
223
+ type: icon,
224
+ "data-element": "action-popover-menu-item-icon",
225
+ horizontalAlignment: horizontalAlignment,
226
+ submenuPosition: currentSubmenuPosition,
227
+ childHasIcon: childHasIcon,
228
+ childHasSubmenu: childHasSubmenu,
229
+ hasIcon: !!icon,
230
+ hasSubmenu: !!submenu,
231
+ isASubmenu: isASubmenu
200
232
  });
201
233
  };
202
234
  return /*#__PURE__*/React.createElement(StyledMenuItemWrapper, submenu && wrapperDivProps, /*#__PURE__*/React.createElement("div", {
@@ -209,17 +241,31 @@ export const ActionPopoverItem = _ref => {
209
241
  role: "menuitem",
210
242
  tabIndex: 0,
211
243
  isDisabled: disabled,
212
- horizontalAlignment: horizontalAlignment
244
+ horizontalAlignment: horizontalAlignment,
245
+ submenuPosition: currentSubmenuPosition,
246
+ hasSubmenu: !!submenu,
247
+ childHasSubmenu: childHasSubmenu
213
248
  }, disabled && {
214
249
  "aria-disabled": true
215
250
  }, isHref && {
216
251
  as: "a",
217
252
  download,
218
253
  href
219
- }, submenu && itemSubmenuProps), submenu && checkRef(ref) && isLeftAligned ? /*#__PURE__*/React.createElement(SubMenuItemIcon, {
220
- type: "chevron_left"
221
- }) : null, horizontalAlignment === "left" ? renderMenuItemIcon() : null, children, horizontalAlignment === "right" ? renderMenuItemIcon() : null, submenu && checkRef(ref) && !isLeftAligned ? /*#__PURE__*/React.createElement(SubMenuItemIcon, {
222
- type: "chevron_right"
254
+ }, submenu && itemSubmenuProps), submenu && checkRef(ref) && currentSubmenuPosition === "left" ? /*#__PURE__*/React.createElement(SubMenuItemIcon, {
255
+ "data-element": "action-popover-menu-item-chevron",
256
+ type: "chevron_left_thick"
257
+ }) : null, /*#__PURE__*/React.createElement(StyledMenuItemOuterContainer, null, horizontalAlignment === "left" ? renderMenuItemIcon() : null, /*#__PURE__*/React.createElement(StyledMenuItemInnerText, {
258
+ "data-element": "action-popover-menu-item-inner-text",
259
+ horizontalAlignment: horizontalAlignment,
260
+ submenuPosition: currentSubmenuPosition,
261
+ isASubmenu: isASubmenu,
262
+ childHasSubmenu: childHasSubmenu,
263
+ childHasIcon: childHasIcon,
264
+ hasIcon: !!icon,
265
+ hasSubmenu: !!submenu
266
+ }, children), horizontalAlignment === "right" ? renderMenuItemIcon() : null), submenu && checkRef(ref) && currentSubmenuPosition === "right" ? /*#__PURE__*/React.createElement(SubMenuItemIcon, {
267
+ "data-element": "action-popover-menu-item-chevron",
268
+ type: "chevron_right_thick"
223
269
  }) : null), /*#__PURE__*/React.isValidElement(submenu) ? /*#__PURE__*/React.cloneElement(submenu, {
224
270
  parentID: `ActionPopoverItem_${guid}`,
225
271
  menuID: `ActionPopoverMenu_${guid}`,
@@ -229,7 +275,9 @@ export const ActionPopoverItem = _ref => {
229
275
  style: containerPosition,
230
276
  setOpen,
231
277
  setFocusIndex,
232
- focusIndex
278
+ focusIndex,
279
+ isASubmenu: true,
280
+ horizontalAlignment
233
281
  }) : null));
234
282
  };
235
283
  ActionPopoverItem.displayName = "ActionPopoverItem";
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
+ import { Alignment } from "../action-popover-context";
2
3
  export interface ActionPopoverMenuBaseProps {
3
4
  /** Children for the menu */
4
5
  children?: React.ReactNode;
@@ -15,19 +16,21 @@ export interface ActionPopoverMenuBaseProps {
15
16
  /** Unique ID for the menu's parent */
16
17
  parentID?: string;
17
18
  /** Horizontal alignment of menu items content */
18
- horizontalAlignment?: "left" | "right";
19
+ horizontalAlignment?: Alignment;
19
20
  /** Set whether the menu should open above or below the button */
20
21
  placement?: "bottom" | "top";
21
22
  /** @ignore @private */
22
23
  role?: string;
23
24
  /** @ignore @private */
25
+ isASubmenu?: boolean;
26
+ /** @ignore @private */
24
27
  "data-element"?: string;
25
28
  /** @ignore @private */
26
29
  style?: {
27
- left: number;
30
+ left: string | number;
28
31
  top?: string;
29
32
  bottom?: string;
30
- right: "auto";
33
+ right: string | number;
31
34
  };
32
35
  }
33
36
  export interface ActionPopoverMenuProps extends ActionPopoverMenuBaseProps, React.RefAttributes<HTMLDivElement> {
@@ -1,5 +1,5 @@
1
1
  function _extends() { _extends = Object.assign ? Object.assign.bind() : 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
- import React, { useCallback, useMemo, useContext } from "react";
2
+ import React, { useCallback, useMemo, useContext, useState } from "react";
3
3
  import PropTypes from "prop-types";
4
4
  import invariant from "invariant";
5
5
  import { Menu } from "../action-popover.style";
@@ -18,12 +18,14 @@ const ActionPopoverMenu = /*#__PURE__*/React.forwardRef((_ref, ref) => {
18
18
  setFocusIndex,
19
19
  placement = "bottom",
20
20
  horizontalAlignment,
21
+ isASubmenu,
21
22
  ...rest
22
23
  } = _ref;
23
24
  const context = useContext(ActionPopoverContext);
24
25
  !context ? process.env.NODE_ENV !== "production" ? invariant(false, "ActionPopoverMenu must be used within an ActionPopover component") : invariant(false) : void 0;
25
26
  const {
26
- focusButton
27
+ focusButton,
28
+ submenuPosition
27
29
  } = context;
28
30
  !(setOpen && setFocusIndex && typeof focusIndex !== "undefined") ? process.env.NODE_ENV !== "production" ? invariant(false, "ActionPopoverMenu must be used within an ActionPopover or ActionPopoverItem component") : invariant(false) : void 0;
29
31
  const hasProperChildren = useMemo(() => {
@@ -92,6 +94,9 @@ const ActionPopoverMenu = /*#__PURE__*/React.forwardRef((_ref, ref) => {
92
94
  }
93
95
  }
94
96
  }, [focusButton, setOpen, focusIndex, items, setFocusIndex]);
97
+ const [childHasSubmenu, setChildHasSubmenu] = useState(false);
98
+ const [childHasIcon, setChildHasIcon] = useState(false);
99
+ const [currentSubmenuPosition, setCurrentSubmenuPosition] = useState(submenuPosition);
95
100
  const clonedChildren = useMemo(() => {
96
101
  let index = 0;
97
102
  return React.Children.map(children, child => {
@@ -100,12 +105,19 @@ const ActionPopoverMenu = /*#__PURE__*/React.forwardRef((_ref, ref) => {
100
105
  return /*#__PURE__*/React.cloneElement(child, {
101
106
  focusItem: isOpen && focusIndex === index - 1,
102
107
  placement: child.props.submenu ? placement : undefined,
103
- horizontalAlignment
108
+ horizontalAlignment,
109
+ childHasSubmenu,
110
+ setChildHasSubmenu,
111
+ childHasIcon,
112
+ setChildHasIcon,
113
+ currentSubmenuPosition,
114
+ setCurrentSubmenuPosition,
115
+ isASubmenu
104
116
  });
105
117
  }
106
118
  return child;
107
119
  });
108
- }, [children, focusIndex, isOpen, placement, horizontalAlignment]);
120
+ }, [children, focusIndex, isOpen, placement, horizontalAlignment, childHasSubmenu, childHasIcon, currentSubmenuPosition, isASubmenu]);
109
121
  return /*#__PURE__*/React.createElement(Menu, _extends({
110
122
  "data-component": "action-popover",
111
123
  isOpen: isOpen,
@@ -121,6 +133,7 @@ ActionPopoverMenu.propTypes = {
121
133
  "data-element": PropTypes.string,
122
134
  "focusIndex": PropTypes.number,
123
135
  "horizontalAlignment": PropTypes.oneOf(["left", "right"]),
136
+ "isASubmenu": PropTypes.bool,
124
137
  "isOpen": PropTypes.bool,
125
138
  "menuID": PropTypes.string,
126
139
  "parentID": PropTypes.string,
@@ -130,8 +143,8 @@ ActionPopoverMenu.propTypes = {
130
143
  "setOpen": PropTypes.func,
131
144
  "style": PropTypes.shape({
132
145
  "bottom": PropTypes.string,
133
- "left": PropTypes.number.isRequired,
134
- "right": PropTypes.oneOf(["auto"]).isRequired,
146
+ "left": PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
147
+ "right": PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
135
148
  "top": PropTypes.string
136
149
  })
137
150
  };
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
2
  import { MarginProps } from "styled-system";
3
+ import { Alignment } from "./action-popover-context";
3
4
  export interface RenderButtonProps {
4
5
  tabIndex: number;
5
6
  "data-element": string;
@@ -14,7 +15,9 @@ export interface ActionPopoverProps extends MarginProps {
14
15
  /** Children for popover component */
15
16
  children?: React.ReactNode;
16
17
  /** Horizontal alignment of menu items content */
17
- horizontalAlignment?: "left" | "right";
18
+ horizontalAlignment?: Alignment;
19
+ /** Sets submenu position */
20
+ submenuPosition?: Alignment;
18
21
  /** Unique ID */
19
22
  id?: string;
20
23
  /** Callback to be called on menu open */
@@ -28,5 +31,5 @@ export interface ActionPopoverProps extends MarginProps {
28
31
  /** Boolean to control whether menu should align to right */
29
32
  rightAlignMenu?: boolean;
30
33
  }
31
- export declare const ActionPopover: ({ children, id, onOpen, onClose, rightAlignMenu, renderButton, placement, horizontalAlignment, ...rest }: ActionPopoverProps) => React.JSX.Element;
34
+ export declare const ActionPopover: ({ children, id, onOpen, onClose, rightAlignMenu, renderButton, placement, horizontalAlignment, submenuPosition, ...rest }: ActionPopoverProps) => React.JSX.Element;
32
35
  export default ActionPopover;
@@ -24,6 +24,7 @@ export const ActionPopover = _ref => {
24
24
  renderButton,
25
25
  placement = "bottom",
26
26
  horizontalAlignment = "left",
27
+ submenuPosition = "left",
27
28
  ...rest
28
29
  } = _ref;
29
30
  const l = useLocale();
@@ -185,6 +186,7 @@ export const ActionPopover = _ref => {
185
186
  value: {
186
187
  setOpenPopover: setOpen,
187
188
  focusButton,
189
+ submenuPosition,
188
190
  isOpenPopover: isOpen
189
191
  }
190
192
  }, isOpen && /*#__PURE__*/React.createElement(Popover, {
@@ -4,9 +4,17 @@ declare const Menu: import("styled-components").StyledComponent<"div", any, {
4
4
  }, never>;
5
5
  declare type StyledMenuItemProps = {
6
6
  isDisabled: boolean;
7
- horizontalAlignment: "left" | "right";
7
+ horizontalAlignment?: "left" | "right";
8
+ submenuPosition?: "left" | "right";
9
+ childHasSubmenu?: boolean;
10
+ childHasIcon?: boolean;
11
+ hasSubmenu?: boolean;
12
+ hasIcon?: boolean;
13
+ isASubmenu?: boolean;
8
14
  };
9
- declare const StyledMenuItem: import("styled-components").StyledComponent<"button", any, StyledMenuItemProps, never>;
15
+ declare const StyledMenuItemInnerText: import("styled-components").StyledComponent<"div", any, Omit<StyledMenuItemProps, "isDisabled">, never>;
16
+ declare const StyledMenuItemOuterContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
17
+ declare const StyledMenuItem: import("styled-components").StyledComponent<"button", any, Omit<StyledMenuItemProps, "variant">, never>;
10
18
  declare const StyledMenuItemWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
11
19
  declare const MenuItemDivider: import("styled-components").StyledComponent<"div", any, {
12
20
  "data-element": string;
@@ -14,7 +22,7 @@ declare const MenuItemDivider: import("styled-components").StyledComponent<"div"
14
22
  declare const MenuButton: import("styled-components").StyledComponent<"div", any, {}, never>;
15
23
  declare const ButtonIcon: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<import("../icon").IconProps & import("react").RefAttributes<HTMLSpanElement>>, any, {}, never>;
16
24
  declare const StyledButtonIcon: import("styled-components").StyledComponent<"div", any, {}, never>;
17
- declare const MenuItemIcon: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<import("../icon").IconProps & import("react").RefAttributes<HTMLSpanElement>>, any, {}, never>;
25
+ declare const MenuItemIcon: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<import("../icon").IconProps & import("react").RefAttributes<HTMLSpanElement>>, any, Omit<StyledMenuItemProps, "isDisabled">, never>;
18
26
  declare const SubMenuItemIcon: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<import("../icon").IconProps & import("react").RefAttributes<HTMLSpanElement>>, any, {}, never>;
19
27
  declare const MenuButtonOverrideWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
20
- export { Menu, MenuButton, ButtonIcon, StyledButtonIcon, MenuItemIcon, MenuItemDivider, SubMenuItemIcon, MenuButtonOverrideWrapper, StyledMenuItem, StyledMenuItemWrapper, };
28
+ export { Menu, MenuButton, ButtonIcon, StyledButtonIcon, MenuItemIcon, MenuItemDivider, SubMenuItemIcon, MenuButtonOverrideWrapper, StyledMenuItemInnerText, StyledMenuItemOuterContainer, StyledMenuItem, StyledMenuItemWrapper, };
@@ -24,7 +24,85 @@ const Menu = styled.div`
24
24
  return `${theme.zIndex?.popover}`;
25
25
  }}; // TODO (tokens): implement elevation tokens - FE-4437
26
26
  `;
27
+ function getPaddingValues(childHasSubmenu, childHasIcon, hasIcon, hasSubmenu) {
28
+ if (!childHasIcon && childHasSubmenu && !hasIcon && !hasSubmenu) {
29
+ return "var(--spacing400)";
30
+ }
31
+ if (childHasIcon && childHasSubmenu && !hasIcon && hasSubmenu) {
32
+ return "var(--spacing600)";
33
+ }
34
+ if (childHasIcon && childHasSubmenu && !hasIcon && !hasSubmenu) {
35
+ return "var(--spacing900)";
36
+ }
37
+ return "var(--spacing100)";
38
+ }
39
+ function getIconPaddingValues(index, horizontalAlignment, submenuPosition, siblingsHaveIconAndSubmenu, isASubmenu) {
40
+ const sameAlignment = horizontalAlignment === "left" && submenuPosition === "left" || horizontalAlignment === "right" && submenuPosition === "right";
41
+ if (siblingsHaveIconAndSubmenu && sameAlignment) {
42
+ if (horizontalAlignment === "left") {
43
+ return index === 1 ? "var(--spacing100)" : "var(--spacing400)";
44
+ }
45
+ return index === 1 ? "var(--spacing400)" : "var(--spacing100)";
46
+ }
47
+ if (isASubmenu) {
48
+ if (horizontalAlignment === "left") {
49
+ return index === 1 ? "var(--spacing100)" : "var(--spacing000)";
50
+ }
51
+ return index === 1 ? "var(--spacing000)" : "var(--spacing100)";
52
+ }
53
+ return "var(--spacing100)";
54
+ }
55
+ const StyledMenuItemInnerText = styled.div`
56
+ ${_ref3 => {
57
+ let {
58
+ childHasSubmenu,
59
+ childHasIcon,
60
+ hasIcon,
61
+ hasSubmenu,
62
+ submenuPosition,
63
+ horizontalAlignment,
64
+ isASubmenu
65
+ } = _ref3;
66
+ return css`
67
+ padding-left: ${isASubmenu ? `var(--spacing000)` : `var(--spacing100)`};
68
+ padding-right: ${isASubmenu ? `var(--spacing000)` : `var(--spacing100)`};
69
+
70
+ ${horizontalAlignment === "left" && submenuPosition === "left" && !isASubmenu && css`
71
+ padding-left: ${getPaddingValues(childHasSubmenu, childHasIcon, hasIcon, hasSubmenu)};
72
+ `}
73
+
74
+ ${horizontalAlignment === "right" && submenuPosition === "right" && !isASubmenu && css`
75
+ padding-right: ${getPaddingValues(childHasSubmenu, childHasIcon, hasIcon, hasSubmenu)};
76
+ `}
77
+ `;
78
+ }}
79
+ `;
80
+ const StyledMenuItemOuterContainer = styled.div`
81
+ display: inherit;
82
+ `;
27
83
  const StyledMenuItem = styled.button`
84
+ ${_ref4 => {
85
+ let {
86
+ horizontalAlignment,
87
+ submenuPosition,
88
+ childHasSubmenu,
89
+ hasSubmenu
90
+ } = _ref4;
91
+ return css`
92
+ justify-content: ${horizontalAlignment === "left" ? "flex-start" : "flex-end"};
93
+
94
+ ${horizontalAlignment === "left" && submenuPosition === "right" && css`
95
+ justify-content: space-between;
96
+ `}
97
+
98
+ ${horizontalAlignment === "right" && submenuPosition === "left" && css`
99
+ ${childHasSubmenu && hasSubmenu && css`
100
+ justify-content: space-between;
101
+ `}
102
+ `}
103
+ `;
104
+ }}
105
+
28
106
  text-decoration: none;
29
107
  background-color: var(--colorsActionMajorYang100);
30
108
  cursor: pointer;
@@ -41,12 +119,6 @@ const StyledMenuItem = styled.button`
41
119
  color: var(--colorsUtilityYin090);
42
120
  font-size: 14px;
43
121
  font-weight: 700;
44
- justify-content: ${_ref3 => {
45
- let {
46
- horizontalAlignment
47
- } = _ref3;
48
- return horizontalAlignment === "left" ? "flex-start" : "flex-end";
49
- }};
50
122
 
51
123
  &:focus {
52
124
  outline: var(--borderWidth300) solid var(--colorsSemanticFocus500);
@@ -54,10 +126,10 @@ const StyledMenuItem = styled.button`
54
126
  border-radius: var(--borderRadius000);
55
127
  }
56
128
 
57
- ${_ref4 => {
129
+ ${_ref5 => {
58
130
  let {
59
131
  isDisabled
60
- } = _ref4;
132
+ } = _ref5;
61
133
  return isDisabled && css`
62
134
  color: var(--colorsUtilityYin030);
63
135
  cursor: not-allowed;
@@ -69,10 +141,10 @@ const StyledMenuItem = styled.button`
69
141
  `;
70
142
  }}
71
143
 
72
- ${_ref5 => {
144
+ ${_ref6 => {
73
145
  let {
74
146
  isDisabled
75
- } = _ref5;
147
+ } = _ref6;
76
148
  return !isDisabled && css`
77
149
  &:focus,
78
150
  &:hover {
@@ -117,21 +189,37 @@ const StyledButtonIcon = styled.div`
117
189
  }
118
190
  `;
119
191
  const MenuItemIcon = styled(Icon)`
120
- padding: var(--spacing100);
121
- color: var(--colorsUtilityYin065);
192
+ ${_ref7 => {
193
+ let {
194
+ horizontalAlignment,
195
+ submenuPosition,
196
+ childHasIcon,
197
+ childHasSubmenu,
198
+ hasIcon,
199
+ hasSubmenu,
200
+ isASubmenu
201
+ } = _ref7;
202
+ return css`
203
+ justify-content: ${horizontalAlignment};
204
+ padding: var(--spacing100)
205
+ ${getIconPaddingValues(1, horizontalAlignment, submenuPosition, childHasIcon && childHasSubmenu && hasIcon && !hasSubmenu, isASubmenu)}
206
+ var(--spacing100)
207
+ ${getIconPaddingValues(2, horizontalAlignment, submenuPosition, childHasIcon && childHasSubmenu && hasIcon && !hasSubmenu, isASubmenu)};
208
+ color: var(--colorsUtilityYin065);
209
+ `;
210
+ }}
122
211
  `;
123
212
  const SubMenuItemIcon = styled(ButtonIcon)`
124
- ${_ref6 => {
213
+ ${_ref8 => {
125
214
  let {
126
215
  type
127
- } = _ref6;
216
+ } = _ref8;
128
217
  return css`
129
- position: absolute;
130
- ${type === "chevron_left" && css`
131
- left: -2px;
218
+ ${type === "chevron_left_thick" && css`
219
+ left: -5px;
132
220
  `}
133
221
 
134
- ${type === "chevron_right" && css`
222
+ ${type === "chevron_right_thick" && css`
135
223
  right: -5px;
136
224
  ${isSafari(navigator) && css`
137
225
  top: var(--sizing100);
@@ -156,4 +244,4 @@ const MenuButtonOverrideWrapper = styled.div`
156
244
  }
157
245
  }
158
246
  `;
159
- export { Menu, MenuButton, ButtonIcon, StyledButtonIcon, MenuItemIcon, MenuItemDivider, SubMenuItemIcon, MenuButtonOverrideWrapper, StyledMenuItem, StyledMenuItemWrapper };
247
+ export { Menu, MenuButton, ButtonIcon, StyledButtonIcon, MenuItemIcon, MenuItemDivider, SubMenuItemIcon, MenuButtonOverrideWrapper, StyledMenuItemInnerText, StyledMenuItemOuterContainer, StyledMenuItem, StyledMenuItemWrapper };
@@ -1,5 +1,11 @@
1
1
  import React from "react";
2
- export interface OptionProps extends Omit<React.InputHTMLAttributes<HTMLLIElement>, "value" | "onSelect" | "onClick"> {
2
+ import { TagProps } from "__internal__/utils/helpers/tags";
3
+ export interface OptionProps extends Omit<React.InputHTMLAttributes<HTMLLIElement>, "value" | "onSelect" | "onClick">, TagProps {
4
+ /**
5
+ * Unique identifier for the component.
6
+ * Will use a randomly generated GUID if none is provided.
7
+ */
8
+ id?: string;
3
9
  /** The option's visible text, displayed within <Textbox> of <Select>, and used for filtering */
4
10
  text: string;
5
11
  /** Optional: alternative rendered content, displayed within <SelectList> of <Select> (eg: an icon, an image, etc) */
@@ -116,6 +116,9 @@ Option.propTypes = {
116
116
  "dangerouslySetInnerHTML": PropTypes.shape({
117
117
  "__html": PropTypes.oneOfType([PropTypes.object, PropTypes.string]).isRequired
118
118
  }),
119
+ "data-component": PropTypes.string,
120
+ "data-element": PropTypes.string,
121
+ "data-role": PropTypes.string,
119
122
  "datatype": PropTypes.string,
120
123
  "defaultChecked": PropTypes.bool,
121
124
  "defaultValue": PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.string), PropTypes.number, PropTypes.string]),
@@ -1,7 +1,13 @@
1
1
  import React from "react";
2
2
  import { CSSProperties } from "styled-components";
3
+ import { TagProps } from "__internal__/utils/helpers/tags";
3
4
  import { IconProps } from "../../icon";
4
- export interface OptionGroupHeaderProps {
5
+ export interface OptionGroupHeaderProps extends TagProps {
6
+ /**
7
+ * Unique identifier for the component.
8
+ * Will use a randomly generated GUID if none is provided.
9
+ */
10
+ id?: string;
5
11
  /** Heading text */
6
12
  label: string;
7
13
  /** Any valid Carbon icon name */