carbon-react 111.8.5 → 111.9.1

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 (43) hide show
  1. package/esm/__internal__/focus-trap/focus-trap-utils.js +21 -1
  2. package/esm/__internal__/focus-trap/focus-trap.component.js +4 -0
  3. package/esm/components/flat-table/flat-table-cell/flat-table-cell.component.js +11 -1
  4. package/esm/components/flat-table/flat-table-cell/flat-table-cell.style.js +3 -1
  5. package/esm/components/flat-table/flat-table-checkbox/flat-table-checkbox.component.js +11 -1
  6. package/esm/components/flat-table/flat-table-checkbox/flat-table-checkbox.style.js +3 -2
  7. package/esm/components/flat-table/flat-table-head/flat-table-head.style.js +8 -7
  8. package/esm/components/flat-table/flat-table-header/flat-table-header.component.js +11 -1
  9. package/esm/components/flat-table/flat-table-header/flat-table-header.d.ts +2 -0
  10. package/esm/components/flat-table/flat-table-header/flat-table-header.style.js +31 -22
  11. package/esm/components/flat-table/flat-table-row/flat-table-row.component.js +46 -19
  12. package/esm/components/flat-table/flat-table-row/flat-table-row.style.js +72 -22
  13. package/esm/components/flat-table/flat-table-row-header/flat-table-row-header.component.js +31 -6
  14. package/esm/components/flat-table/flat-table-row-header/flat-table-row-header.d.ts +2 -0
  15. package/esm/components/flat-table/flat-table-row-header/flat-table-row-header.style.js +11 -4
  16. package/esm/components/flat-table/flat-table.style.js +68 -19
  17. package/esm/components/grouped-character/grouped-character.component.d.ts +30 -0
  18. package/esm/components/grouped-character/grouped-character.component.js +544 -41
  19. package/esm/components/grouped-character/grouped-character.utils.d.ts +2 -0
  20. package/esm/components/grouped-character/index.d.ts +2 -1
  21. package/lib/__internal__/focus-trap/focus-trap-utils.js +21 -1
  22. package/lib/__internal__/focus-trap/focus-trap.component.js +4 -0
  23. package/lib/components/flat-table/flat-table-cell/flat-table-cell.component.js +11 -1
  24. package/lib/components/flat-table/flat-table-cell/flat-table-cell.style.js +3 -1
  25. package/lib/components/flat-table/flat-table-checkbox/flat-table-checkbox.component.js +11 -1
  26. package/lib/components/flat-table/flat-table-checkbox/flat-table-checkbox.style.js +3 -2
  27. package/lib/components/flat-table/flat-table-head/flat-table-head.style.js +8 -7
  28. package/lib/components/flat-table/flat-table-header/flat-table-header.component.js +11 -1
  29. package/lib/components/flat-table/flat-table-header/flat-table-header.d.ts +2 -0
  30. package/lib/components/flat-table/flat-table-header/flat-table-header.style.js +34 -23
  31. package/lib/components/flat-table/flat-table-row/flat-table-row.component.js +47 -19
  32. package/lib/components/flat-table/flat-table-row/flat-table-row.style.js +72 -22
  33. package/lib/components/flat-table/flat-table-row-header/flat-table-row-header.component.js +35 -6
  34. package/lib/components/flat-table/flat-table-row-header/flat-table-row-header.d.ts +2 -0
  35. package/lib/components/flat-table/flat-table-row-header/flat-table-row-header.style.js +11 -4
  36. package/lib/components/flat-table/flat-table.style.js +69 -20
  37. package/lib/components/grouped-character/grouped-character.component.d.ts +30 -0
  38. package/lib/components/grouped-character/grouped-character.component.js +545 -45
  39. package/lib/components/grouped-character/grouped-character.utils.d.ts +2 -0
  40. package/lib/components/grouped-character/index.d.ts +2 -1
  41. package/package.json +1 -1
  42. package/esm/components/grouped-character/grouped-character.d.ts +0 -23
  43. package/lib/components/grouped-character/grouped-character.d.ts +0 -23
@@ -41,6 +41,19 @@ const getRadioElementToFocus = (groupName, shiftKey) => {
41
41
 
42
42
  const getNextElement = (element, focusableElements, shiftKey) => {
43
43
  const currentIndex = focusableElements.indexOf(element);
44
+
45
+ if (currentIndex === -1) {
46
+ // we're not currently on a focusable element - most likely because the focusableElements come from a different focus trap!
47
+ // So we need to leave focus where it is.
48
+ // The exception is when the focus is on the document body - perhaps because the previously-focused element was dynamically removed.
49
+ // In that case focus the first element.
50
+ if (element === document.body) {
51
+ return focusableElements[0];
52
+ }
53
+
54
+ return element;
55
+ }
56
+
44
57
  const increment = shiftKey ? -1 : 1;
45
58
  let nextIndex = currentIndex;
46
59
  let foundElement;
@@ -61,7 +74,14 @@ const getNextElement = (element, focusableElements, shiftKey) => {
61
74
  if (nextElement === element) {
62
75
  // guard in case there is only one focusable element (or only a single radio group) in the trap.
63
76
  // If this happens we don't want to freeze the browser by looping forever, and it's OK to just focus
64
- // the same element we're already on
77
+ // the same element we're already on.
78
+ // There is an exception though: if we're in a single radio group, we need to ensure we focus on
79
+ // the correct one. This may not be "element" if it's not currently focused (due to the focus actually
80
+ // being on a wrapper element and this function being called with the first/last element as "element").
81
+ if (isRadio(element) && document.activeElement !== element) {
82
+ return getRadioElementToFocus(element.getAttribute("name"), shiftKey);
83
+ }
84
+
65
85
  return element;
66
86
  }
67
87
 
@@ -94,6 +94,10 @@ const FocusTrap = ({
94
94
  elementToFocus = getNextElement(activeElement, focusableElements, ev.shiftKey);
95
95
  }
96
96
 
97
+ setElementFocus(elementToFocus);
98
+ ev.preventDefault();
99
+ } else if (activeElement === (wrapperRef === null || wrapperRef === void 0 ? void 0 : wrapperRef.current)) {
100
+ const elementToFocus = getNextElement(lastElement, focusableElements, ev.shiftKey);
97
101
  setElementFocus(elementToFocus);
98
102
  ev.preventDefault();
99
103
  } else {
@@ -20,6 +20,7 @@ const FlatTableCell = ({
20
20
  reportCellWidth,
21
21
  cellIndex,
22
22
  leftPosition,
23
+ rightPosition,
23
24
  width,
24
25
  truncate = false,
25
26
  title,
@@ -32,8 +33,10 @@ const FlatTableCell = ({
32
33
  }
33
34
  }, [reportCellWidth, cellIndex]);
34
35
  return /*#__PURE__*/React.createElement(StyledFlatTableCell, _extends({
35
- leftPosition: leftPosition || 0,
36
+ leftPosition: leftPosition,
37
+ rightPosition: rightPosition,
36
38
  makeCellSticky: !!reportCellWidth,
39
+ className: reportCellWidth ? "isSticky" : undefined,
37
40
  ref: ref,
38
41
  align: align,
39
42
  "data-element": "flat-table-cell",
@@ -104,6 +107,13 @@ FlatTableCell.propTypes = {
104
107
  */
105
108
  leftPosition: PropTypes.number,
106
109
 
110
+ /**
111
+ * @private
112
+ * @ignore
113
+ * Sets the right position when sticky column found
114
+ */
115
+ rightPosition: PropTypes.number,
116
+
107
117
  /**
108
118
  * @private
109
119
  * @ignore
@@ -13,6 +13,7 @@ const StyledFlatTableCell = styled.td`
13
13
  theme,
14
14
  rowSpan,
15
15
  leftPosition,
16
+ rightPosition,
16
17
  makeCellSticky,
17
18
  colWidth,
18
19
  isTruncated,
@@ -73,7 +74,8 @@ const StyledFlatTableCell = styled.td`
73
74
  `}
74
75
 
75
76
  ${makeCellSticky && css`
76
- left: ${leftPosition}px;
77
+ ${leftPosition !== undefined && `left: ${leftPosition}px;`}
78
+ ${rightPosition !== undefined && `right: ${rightPosition}px;`}
77
79
  position: sticky;
78
80
  `}
79
81
 
@@ -12,6 +12,7 @@ const FlatTableCheckbox = ({
12
12
  selectable = true,
13
13
  onClick,
14
14
  leftPosition,
15
+ rightPosition,
15
16
  cellIndex,
16
17
  reportCellWidth,
17
18
  ariaLabelledBy,
@@ -37,7 +38,9 @@ const FlatTableCheckbox = ({
37
38
  return /*#__PURE__*/React.createElement(StyledFlatTableCheckbox, _extends({
38
39
  ref: ref,
39
40
  makeCellSticky: !!reportCellWidth,
40
- leftPosition: leftPosition || 0,
41
+ className: reportCellWidth ? "isSticky" : undefined,
42
+ leftPosition: leftPosition,
43
+ rightPosition: rightPosition,
41
44
  "data-element": dataElement,
42
45
  as: as
43
46
  }, rest), selectable && /*#__PURE__*/React.createElement(Checkbox, {
@@ -77,6 +80,13 @@ FlatTableCheckbox.propTypes = {
77
80
  */
78
81
  leftPosition: PropTypes.number,
79
82
 
83
+ /**
84
+ * @private
85
+ * @ignore
86
+ * Sets the right position when sticky column found
87
+ */
88
+ rightPosition: PropTypes.number,
89
+
80
90
  /**
81
91
  * @private
82
92
  * @ignore
@@ -4,6 +4,7 @@ const StyledFlatTableCheckbox = styled.td`
4
4
  ${({
5
5
  as,
6
6
  leftPosition,
7
+ rightPosition,
7
8
  makeCellSticky
8
9
  }) => css`
9
10
  ${as === "td" && css`
@@ -35,7 +36,6 @@ const StyledFlatTableCheckbox = styled.td`
35
36
  left: auto;
36
37
  padding: 0;
37
38
  text-align: left;
38
- top: 0;
39
39
  user-select: none;
40
40
  vertical-align: middle;
41
41
  white-space: nowrap;
@@ -43,7 +43,8 @@ const StyledFlatTableCheckbox = styled.td`
43
43
 
44
44
  ${makeCellSticky && css`
45
45
  top: auto;
46
- left: ${leftPosition}px;
46
+ ${leftPosition !== undefined && `left: ${leftPosition}px;`}
47
+ ${rightPosition !== undefined && `right: ${rightPosition}px;`}
47
48
  position: sticky;
48
49
  `}
49
50
  `}
@@ -3,13 +3,14 @@ import baseTheme from "../../../style/themes/base";
3
3
  import { StyledFlatTableRowHeader } from "../flat-table-row-header/flat-table-row-header.style";
4
4
  import StyledFlatTableCheckbox from "../flat-table-checkbox/flat-table-checkbox.style";
5
5
  const StyledFlatTableHead = styled.thead`
6
- ${StyledFlatTableRowHeader}, ${StyledFlatTableCheckbox} {
7
- border-left: none;
8
- border-right: none;
9
- font-weight: 700;
10
- z-index: ${({
11
- theme
12
- }) => theme.zIndex.overlay};
6
+ &&& {
7
+ ${StyledFlatTableCheckbox} {
8
+ border-left: none;
9
+ border-right: none;
10
+ }
11
+ ${StyledFlatTableRowHeader}, ${StyledFlatTableCheckbox} {
12
+ font-weight: 700;
13
+ }
13
14
  }
14
15
  `;
15
16
  StyledFlatTableHead.defaultProps = {
@@ -19,6 +19,7 @@ const FlatTableHeader = ({
19
19
  reportCellWidth,
20
20
  cellIndex,
21
21
  leftPosition,
22
+ rightPosition,
22
23
  ...rest
23
24
  }) => {
24
25
  const ref = useRef(null);
@@ -32,8 +33,10 @@ const FlatTableHeader = ({
32
33
  }, [reportCellWidth, cellIndex]);
33
34
  return /*#__PURE__*/React.createElement(StyledFlatTableHeader, _extends({
34
35
  ref: ref,
35
- leftPosition: leftPosition || 0,
36
+ leftPosition: leftPosition,
37
+ rightPosition: rightPosition,
36
38
  makeCellSticky: !!reportCellWidth,
39
+ className: reportCellWidth ? "isSticky" : undefined,
37
40
  align: align,
38
41
  colorTheme: colorTheme,
39
42
  "data-element": "flat-table-header",
@@ -69,6 +72,13 @@ FlatTableHeader.propTypes = {
69
72
  */
70
73
  leftPosition: PropTypes.number,
71
74
 
75
+ /**
76
+ * @private
77
+ * @ignore
78
+ * Sets the right position when sticky column found
79
+ */
80
+ rightPosition: PropTypes.number,
81
+
72
82
  /**
73
83
  * @private
74
84
  * @ignore
@@ -15,6 +15,8 @@ export interface FlatTableHeaderProps extends PaddingProps {
15
15
  rowspan?: number | string;
16
16
  /** Sets a custom vertical right border */
17
17
  verticalBorder?: TableBorderSize;
18
+ /** Sets the color of the right border */
19
+ verticalBorderColor?: string;
18
20
  /** Column width, pass a number to set a fixed width in pixels */
19
21
  width?: number;
20
22
  }
@@ -1,6 +1,8 @@
1
1
  import styled, { css } from "styled-components";
2
2
  import { padding } from "styled-system";
3
3
  import getAlternativeBackgroundColor from "./flat-table-header-utils";
4
+ import baseTheme from "../../../style/themes/base";
5
+ import { toColor } from "../../../style/utils/color";
4
6
  const verticalBorderSizes = {
5
7
  small: "1px",
6
8
  medium: "2px",
@@ -12,9 +14,12 @@ const StyledFlatTableHeader = styled.th`
12
14
  alternativeBgColor,
13
15
  colWidth,
14
16
  leftPosition,
17
+ rightPosition,
15
18
  makeCellSticky,
16
19
  verticalBorder,
17
- colorTheme
20
+ verticalBorderColor,
21
+ colorTheme,
22
+ theme
18
23
  }) => css`
19
24
  background-color: transparent;
20
25
  border-width: 0;
@@ -22,7 +27,6 @@ const StyledFlatTableHeader = styled.th`
22
27
  font-weight: 700;
23
28
  left: auto;
24
29
  text-align: ${align};
25
- top: 0;
26
30
  user-select: none;
27
31
  vertical-align: middle;
28
32
  white-space: nowrap;
@@ -58,36 +62,41 @@ const StyledFlatTableHeader = styled.th`
58
62
  `};
59
63
 
60
64
  ${makeCellSticky && css`
61
- left: ${leftPosition}px;
62
- position: sticky;
63
- &&& {
64
- z-index: 1002;
65
- }
66
-
67
- &:first-child {
68
- padding-right: 0.395em;
65
+ ${leftPosition !== undefined && `left: ${leftPosition}px;`}
66
+ ${rightPosition !== undefined && `right: ${rightPosition}px;`}
67
+ position: sticky;
68
+
69
+ &:first-child {
70
+ padding-right: 0.395em;
69
71
 
70
- /* Applies specific styling for Firefox. Increased padding is required to ensure no gap is present between
71
- the th elements. This includes FlatTableHeader and FlatTableRowHeader */
72
- @-moz-document url-prefix() {
73
- padding-right: 2px;
74
- }
72
+ /* Applies specific styling for Firefox. Increased padding is required to ensure no gap is present between
73
+ the th elements. This includes FlatTableHeader and FlatTableRowHeader */
74
+ @-moz-document url-prefix() {
75
+ padding-right: 2px;
76
+ }
75
77
 
76
- /* Styling for safari. Increased padding is required to ensure no gap is present between
77
- the th elements. This includes FlatTableHeader and FlatTableRowHeader */
78
- @media not all and (min-resolution:.001dpcm) {
79
- @supports (-webkit-appearance:none) and (stroke-color:transparent) {
80
- padding-right: 0.9em;
78
+ /* Styling for safari. Increased padding is required to ensure no gap is present between
79
+ the th elements. This includes FlatTableHeader and FlatTableRowHeader */
80
+ @media not all and (min-resolution:.001dpcm) {
81
+ @supports (-webkit-appearance:none) and (stroke-color:transparent) {
82
+ padding-right: 0.9em;
83
+ }
81
84
  }
82
- }
83
- `}
85
+ `}
84
86
 
85
87
  &&& {
86
88
  ${verticalBorder && css`
87
89
  border-right-width: ${verticalBorderSizes[verticalBorder]};
88
90
  `}
91
+
92
+ ${verticalBorderColor && css`
93
+ border-right-color: ${toColor(theme, verticalBorderColor)};
94
+ `}
89
95
  }
90
96
  }
91
97
  `}
92
98
  `;
99
+ StyledFlatTableHeader.defaultProps = {
100
+ theme: baseTheme
101
+ };
93
102
  export default StyledFlatTableHeader;
@@ -2,6 +2,7 @@ function _extends() { _extends = Object.assign || function (target) { for (var i
2
2
 
3
3
  import React, { useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
4
4
  import PropTypes from "prop-types";
5
+ import invariant from "invariant";
5
6
  import Event from "../../../__internal__/utils/helpers/events";
6
7
  import StyledFlatTableRow from "./flat-table-row.style";
7
8
  import { DrawerSidebarContext } from "../../drawer";
@@ -35,13 +36,24 @@ const FlatTableRow = /*#__PURE__*/React.forwardRef(({
35
36
  let rowRef = useRef();
36
37
  if (ref) rowRef = ref;
37
38
  const firstColumnExpandable = expandableArea === "firstColumn";
38
- const [stickyCellWidths, setStickyCellWidths] = useState([]);
39
+ const [leftStickyCellWidths, setLeftStickyCellWidths] = useState([]);
40
+ const [rightStickyCellWidths, setRightStickyCellWidths] = useState([]);
39
41
  const [leftPositions, setLeftPositions] = useState([]);
42
+ const [rightPositions, setRightPositions] = useState([]);
40
43
  const childrenArray = useMemo(() => React.Children.toArray(children), [children]);
41
- const rowHeaderIndex = useMemo(() => childrenArray.findIndex(child => child.type.displayName === FlatTableRowHeader.displayName), [childrenArray]);
44
+ const lhsRowHeaderIndex = useMemo(() => childrenArray.findIndex(child => child.type.displayName === FlatTableRowHeader.displayName && child.props.stickyAlignment !== "right"), [childrenArray]);
45
+ const rhsRowHeaderIndex = useMemo(() => childrenArray.findIndex(child => child.type.displayName === FlatTableRowHeader.displayName && child.props.stickyAlignment === "right"), [childrenArray]);
46
+ const noStickyColumnsOverlap = useMemo(() => {
47
+ const hasLhsColumn = lhsRowHeaderIndex !== -1;
48
+ const hasRhsColumn = rhsRowHeaderIndex !== -1;
49
+ if (!hasLhsColumn || !hasRhsColumn) return true;
50
+ return lhsRowHeaderIndex < rhsRowHeaderIndex;
51
+ }, [lhsRowHeaderIndex, rhsRowHeaderIndex]);
52
+ !noStickyColumnsOverlap ? process.env.NODE_ENV !== "production" ? invariant(false, `Do not render a right hand side \`${FlatTableRowHeader.displayName}\` before left hand side \`${FlatTableRowHeader.displayName}\``) : invariant(false) : void 0;
42
53
  const themeContext = useContext(FlatTableThemeContext);
43
54
  const reportCellWidth = useCallback((width, index) => {
44
- const copiedArray = stickyCellWidths;
55
+ const isLeftSticky = index < lhsRowHeaderIndex;
56
+ const copiedArray = isLeftSticky ? leftStickyCellWidths : rightStickyCellWidths;
45
57
 
46
58
  if (copiedArray[index] !== undefined) {
47
59
  copiedArray[index] = width;
@@ -49,11 +61,14 @@ const FlatTableRow = /*#__PURE__*/React.forwardRef(({
49
61
  copiedArray.push(width);
50
62
  }
51
63
 
52
- setStickyCellWidths(copiedArray);
53
- }, [stickyCellWidths]);
64
+ if (isLeftSticky) {
65
+ setLeftStickyCellWidths(copiedArray);
66
+ } else {
67
+ setRightStickyCellWidths(copiedArray);
68
+ }
69
+ }, [lhsRowHeaderIndex, leftStickyCellWidths, rightStickyCellWidths]);
54
70
  let interactiveRowProps = {};
55
-
56
- const firstCellIndex = () => childrenArray[0].type === FlatTableCheckbox ? 1 : 0;
71
+ const firstCellIndex = childrenArray[0].type === FlatTableCheckbox ? 1 : 0;
57
72
 
58
73
  const toggleExpanded = () => setIsExpanded(!isExpanded);
59
74
 
@@ -97,13 +112,22 @@ const FlatTableRow = /*#__PURE__*/React.forwardRef(({
97
112
  }
98
113
  }
99
114
 
115
+ const buildPositionArray = (setter, widthsArray, length) => {
116
+ setter([0, ...Array.from({
117
+ length
118
+ }).map((_, index) => widthsArray.slice(0, index + 1).reduce((a, b) => a + b, 0), 0)]);
119
+ };
120
+
121
+ useLayoutEffect(() => {
122
+ if (leftStickyCellWidths.length && lhsRowHeaderIndex !== -1) {
123
+ buildPositionArray(setLeftPositions, leftStickyCellWidths, lhsRowHeaderIndex);
124
+ }
125
+ }, [lhsRowHeaderIndex, leftStickyCellWidths]);
100
126
  useLayoutEffect(() => {
101
- if (stickyCellWidths.length && rowHeaderIndex !== -1) {
102
- setLeftPositions([0, ...Array.from({
103
- length: rowHeaderIndex
104
- }).map((_, index) => stickyCellWidths.slice(0, index + 1).reduce((a, b) => a + b, 0), 0)]);
127
+ if (rightStickyCellWidths.length && rhsRowHeaderIndex !== -1) {
128
+ buildPositionArray(setRightPositions, rightStickyCellWidths, childrenArray.length - (rhsRowHeaderIndex + 1));
105
129
  }
106
- }, [rowHeaderIndex, stickyCellWidths]);
130
+ }, [rhsRowHeaderIndex, rightStickyCellWidths, childrenArray]);
107
131
  useEffect(() => {
108
132
  setIsExpanded(expanded);
109
133
  }, [expanded]);
@@ -117,9 +141,10 @@ const FlatTableRow = /*#__PURE__*/React.forwardRef(({
117
141
  highlighted: highlighted,
118
142
  selected: selected,
119
143
  onClick: handleClick,
120
- firstCellIndex: firstCellIndex(),
144
+ firstCellIndex: firstCellIndex,
121
145
  ref: rowRef,
122
- rowHeaderIndex: rowHeaderIndex,
146
+ lhsRowHeaderIndex: lhsRowHeaderIndex,
147
+ rhsRowHeaderIndex: rhsRowHeaderIndex,
123
148
  colorTheme: themeContext.colorTheme,
124
149
  size: themeContext.size,
125
150
  stickyOffset: stickyOffset,
@@ -127,15 +152,17 @@ const FlatTableRow = /*#__PURE__*/React.forwardRef(({
127
152
  horizontalBorderColor: horizontalBorderColor,
128
153
  horizontalBorderSize: horizontalBorderSize,
129
154
  applyBorderLeft: applyBorderLeft,
130
- draggable: draggable
155
+ draggable: draggable,
156
+ totalChildren: childrenArray.length
131
157
  }, interactiveRowProps, rest), React.Children.map(children, (child, index) => {
132
158
  return child && /*#__PURE__*/React.cloneElement(child, {
133
- expandable: expandable && index === firstCellIndex(),
134
- onClick: expandable && index === firstCellIndex() && firstColumnExpandable ? () => toggleExpanded() : undefined,
135
- onKeyDown: expandable && index === firstCellIndex() && firstColumnExpandable ? handleCellKeyDown : undefined,
159
+ expandable: expandable && index === firstCellIndex,
160
+ onClick: expandable && index === firstCellIndex && firstColumnExpandable ? () => toggleExpanded() : undefined,
161
+ onKeyDown: expandable && index === firstCellIndex && firstColumnExpandable ? handleCellKeyDown : undefined,
136
162
  cellIndex: index,
137
- reportCellWidth: index < rowHeaderIndex ? reportCellWidth : undefined,
163
+ reportCellWidth: index < lhsRowHeaderIndex || rhsRowHeaderIndex !== -1 && index > rhsRowHeaderIndex ? reportCellWidth : undefined,
138
164
  leftPosition: leftPositions[index],
165
+ rightPosition: rightPositions[childrenArray.length - (index + 1)],
139
166
  ...child.props
140
167
  });
141
168
  }));
@@ -11,22 +11,31 @@ const horizontalBorderSizes = {
11
11
  large: "4px"
12
12
  };
13
13
 
14
- const stickyColumnFocusStyling = (index, theme) => {
14
+ const getLeftStickyStyling = index => index === 0 && css`
15
+ &:first-of-type::before {
16
+ border-left: 3px solid var(--colorsSemanticFocus500);
17
+ }
18
+ `;
19
+
20
+ const getRightStickyStyling = (index, totalChildren) => index === totalChildren - 1 && css`
21
+ &:last-of-type {
22
+ border-right: 2px solid var(--colorsSemanticFocus500);
23
+ }
24
+ `;
25
+
26
+ const stickyColumnFocusStyling = theme => {
15
27
  return `
16
- border-left: 2px solid
17
- ${index === 0 ? "var(--colorsSemanticFocus500)" : "var(--colorsUtilityMajor100)"};
18
28
  width: calc(100% + 1px);
19
- top: 0;
20
- z-index: ${theme.zIndex.overlay + 2};
29
+ z-index: ${theme.zIndex.overlay};
21
30
  :before {
22
31
  content: "";
23
32
  border-top: 2px solid var(--colorsSemanticFocus500);
24
33
  border-bottom: 2px solid var(--colorsSemanticFocus500);
25
34
  display: block;
26
- left: 0px;
35
+ left: -2px;
27
36
  top: 0px;
28
37
  height: calc(100% - 3px);
29
- width: 101%;
38
+ width: 103%;
30
39
  position: absolute;
31
40
  z-index: ${theme.zIndex.overlay};
32
41
  }
@@ -51,6 +60,20 @@ const borderColor = colorTheme => {
51
60
  }
52
61
  };
53
62
 
63
+ const verticalBorderColor = colorTheme => {
64
+ switch (colorTheme) {
65
+ case "transparent-base":
66
+ return "var(--colorsUtilityMajor025)";
67
+
68
+ case "transparent-white":
69
+ return "var(--colorsUtilityYang100)";
70
+ // default theme is "dark"
71
+
72
+ default:
73
+ return "var(--colorsUtilityMajor100)";
74
+ }
75
+ };
76
+
54
77
  const StyledFlatTableRow = styled.tr`
55
78
  ${({
56
79
  bgColor,
@@ -59,7 +82,9 @@ const StyledFlatTableRow = styled.tr`
59
82
  stickyOffset,
60
83
  isRowInteractive,
61
84
  isFirstColumnInteractive,
62
- rowHeaderIndex,
85
+ lhsRowHeaderIndex,
86
+ rhsRowHeaderIndex,
87
+ totalChildren,
63
88
  firstCellIndex,
64
89
  colorTheme,
65
90
  expandable,
@@ -105,6 +130,31 @@ const StyledFlatTableRow = styled.tr`
105
130
  `}
106
131
  }
107
132
 
133
+ ${StyledFlatTableRowHeader} + td {
134
+ border-left: none;
135
+ }
136
+
137
+ ${lhsRowHeaderIndex !== -1 && css`
138
+ ${StyledFlatTableRowHeader}:nth-child(${lhsRowHeaderIndex + 1}) {
139
+ border-right: 2px solid ${verticalBorderColor(colorTheme)};
140
+ }
141
+ `}
142
+
143
+ ${rhsRowHeaderIndex !== -1 && css`
144
+ ${StyledFlatTableRowHeader}:nth-child(${rhsRowHeaderIndex + 1}) {
145
+ border-left: 2px solid ${verticalBorderColor(colorTheme)};
146
+ }
147
+ ${StyledFlatTableHeader}:nth-child(${rhsRowHeaderIndex}) {
148
+ border-right: none;
149
+ }
150
+ `}
151
+
152
+ ${rhsRowHeaderIndex === totalChildren - 1 && css`
153
+ td:last-of-type {
154
+ border-right: none;
155
+ }
156
+ `}
157
+
108
158
  ${StyledFlatTableHeader} {
109
159
  border-bottom: 1px solid ${borderColor(colorTheme)};
110
160
 
@@ -157,17 +207,27 @@ const StyledFlatTableRow = styled.tr`
157
207
  }
158
208
  }
159
209
 
210
+ td:first-of-type:not(:nth-child(${lhsRowHeaderIndex + 2}))::before {
211
+ border-left: 3px solid var(--colorsSemanticFocus500);
212
+ }
213
+
214
+ td:last-of-type:not(:nth-child(${rhsRowHeaderIndex})) {
215
+ border-right: 2px solid var(--colorsSemanticFocus500);
216
+ }
217
+
160
218
  ${StyledFlatTableRowHeader} {
161
- ${stickyColumnFocusStyling(rowHeaderIndex, theme)}
219
+ ${getLeftStickyStyling(lhsRowHeaderIndex)}
220
+ ${getRightStickyStyling(rhsRowHeaderIndex, totalChildren)}
221
+ ${stickyColumnFocusStyling(theme)}
162
222
  }
163
223
 
164
- ${![-1, 0].includes(rowHeaderIndex) && css`
224
+ ${![-1, 0].includes(lhsRowHeaderIndex) && css`
165
225
  ${Array.from({
166
- length: rowHeaderIndex
226
+ length: lhsRowHeaderIndex
167
227
  }).map((_, index) => {
168
228
  return `
169
229
  td:nth-of-type(${index + 1}) {
170
- ${stickyColumnFocusStyling(index, theme)}
230
+ ${stickyColumnFocusStyling(theme)}
171
231
  }
172
232
  `;
173
233
  })}
@@ -197,16 +257,6 @@ const StyledFlatTableRow = styled.tr`
197
257
  }
198
258
  `}
199
259
 
200
- ${![-1, 0].includes(rowHeaderIndex) && css`
201
- td:nth-of-type(${rowHeaderIndex + 1}) {
202
- border-left: 1px solid
203
- ${customBorderColor || "var(--colorsUtilityMajor100)"};
204
- }
205
-
206
- th:nth-of-type(${rowHeaderIndex + 2}) {
207
- border-left: 1px solid ${customBorderColor || borderColor(colorTheme)};
208
- }
209
- `}
210
260
 
211
261
  ${applyBorderLeft && css`
212
262
  th:first-of-type {
@@ -1,6 +1,6 @@
1
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
2
 
3
- import React from "react";
3
+ import React, { useCallback } from "react";
4
4
  import PropTypes from "prop-types";
5
5
  import styledSystemPropTypes from "@styled-system/prop-types";
6
6
  import { filterStyledSystemPaddingProps } from "../../../style/utils";
@@ -18,22 +18,32 @@ const FlatTableRowHeader = ({
18
18
  onClick,
19
19
  onKeyDown,
20
20
  leftPosition,
21
+ rightPosition,
21
22
  truncate,
22
23
  title,
24
+ stickyAlignment = "left",
23
25
  ...rest
24
26
  }) => {
27
+ const handleOnClick = useCallback(ev => {
28
+ if (expandable && onClick) onClick(ev);
29
+ }, [expandable, onClick]);
30
+ const handleOnKeyDown = useCallback(ev => {
31
+ if (expandable && onKeyDown) onKeyDown(ev);
32
+ }, [expandable, onKeyDown]);
25
33
  return /*#__PURE__*/React.createElement(StyledFlatTableRowHeader, _extends({
26
- leftPosition: leftPosition || 0,
34
+ leftPosition: stickyAlignment === "left" ? leftPosition || 0 : undefined,
35
+ rightPosition: stickyAlignment === "right" ? rightPosition || 0 : undefined,
27
36
  align: align,
28
37
  "data-element": "flat-table-row-header",
29
38
  colWidth: width,
30
39
  py: py || "10px",
31
40
  px: px || 3,
32
- onClick: expandable && onClick ? onClick : undefined,
41
+ onClick: handleOnClick,
33
42
  tabIndex: expandable && onClick ? 0 : undefined,
34
- onKeyDown: expandable && onKeyDown ? onKeyDown : undefined,
43
+ onKeyDown: handleOnKeyDown,
35
44
  isTruncated: truncate,
36
- expandable: expandable
45
+ expandable: expandable,
46
+ stickyAlignment: stickyAlignment
37
47
  }, rest), /*#__PURE__*/React.createElement(StyledFlatTableRowHeaderContent, {
38
48
  title: truncate && !title && typeof children === "string" ? children : title,
39
49
  expandable: expandable
@@ -83,7 +93,22 @@ FlatTableRowHeader.propTypes = {
83
93
  verticalBorder: PropTypes.oneOf(["small", "medium", "large"]),
84
94
 
85
95
  /** Sets a vertical right border color, provide design token, any color from palette or any valid css color value. */
86
- verticalBorderColor: PropTypes.string
96
+ verticalBorderColor: PropTypes.string,
97
+
98
+ /** Defines whether the column should be sticky on the left or right hand side of the Table */
99
+ stickyAlignment: PropTypes.oneOf(["left", "right"]),
100
+
101
+ /**
102
+ * @private
103
+ * @ignore
104
+ */
105
+ leftPosition: PropTypes.number,
106
+
107
+ /**
108
+ * @private
109
+ * @ignore
110
+ */
111
+ rightPosition: PropTypes.number
87
112
  };
88
113
  FlatTableRowHeader.displayName = "FlatTableRowHeader";
89
114
  export default FlatTableRowHeader;
@@ -16,6 +16,8 @@ export interface FlatTableRowHeaderProps extends PaddingProps {
16
16
  verticalBorder?: TableBorderSize;
17
17
  /** Sets the color of the right border */
18
18
  verticalBorderColor?: string;
19
+ /** Defines whether the column should be sticky on the left or right hand side of the Table */
20
+ stickyAlignment?: "left" | "right";
19
21
  }
20
22
 
21
23
  declare function FlatTableRowHeader(