@kaizen/components 1.45.3 → 1.46.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.
@@ -3,6 +3,7 @@ import { CheckedStatus } from "../Checkbox";
3
3
  import { OverrideClassName } from "../types/OverrideClassName";
4
4
  export type TableContainerProps = {
5
5
  children?: React.ReactNode;
6
+ /** @default "compact" */
6
7
  variant?: "compact" | "default" | "data";
7
8
  };
8
9
  /**
@@ -17,6 +18,13 @@ export declare const TableHeader: ({ children, ...otherProps }: TableHeaderProps
17
18
  export type TableHeaderRowProps = {
18
19
  children?: React.ReactNode;
19
20
  };
21
+ export type TableHeaderRowCellCheckboxProps = {
22
+ checkable?: boolean;
23
+ checkedStatus?: CheckedStatus;
24
+ /** This will be passed into the aria-label for the checkbox to provide context to the user */
25
+ checkboxLabel?: string;
26
+ onCheck?: (event: React.ChangeEvent<HTMLInputElement>) => any;
27
+ };
20
28
  /**
21
29
  * @param width value between 1 and 0, to be calculated as a percentage
22
30
  * @param flex CSS flex shorthand as a string. Be sure to specify the flex grow,
@@ -30,9 +38,6 @@ export type TableHeaderRowCellProps = {
30
38
  flex?: string;
31
39
  href?: string;
32
40
  icon?: ReactElement;
33
- checkable?: boolean;
34
- checkedStatus?: CheckedStatus;
35
- onCheck?: (event: React.ChangeEvent<HTMLInputElement>) => any;
36
41
  reversed?: boolean;
37
42
  /**
38
43
  * Shows an up or down arrow, to show that the column is sorted.
@@ -41,14 +46,19 @@ export type TableHeaderRowCellProps = {
41
46
  wrapping?: "nowrap" | "wrap";
42
47
  align?: "start" | "center" | "end";
43
48
  tooltipInfo?: string;
49
+ /** If set, this will hide the tooltip exclamation icon. Useful in situations where
50
+ the table header does not have enough space. This should be done with caution as tooltips
51
+ should have a visual indicator to users */
44
52
  isTooltipIconHidden?: boolean;
45
53
  /**
46
54
  * Specify where the tooltip should be rendered.
47
55
  */
48
56
  tooltipPortalSelector?: string | undefined;
57
+ /** If set, this will show the arrow in the direction provided
58
+ when the header cell is hovered over. */
49
59
  sortingArrowsOnHover?: "ascending" | "descending" | undefined;
50
- } & OverrideClassName<HTMLAttributes<HTMLElement>>;
51
- export declare const TableHeaderRowCell: ({ labelText, onClick, href, width, flex, icon, checkable, checkedStatus, onCheck, reversed, sorting: sortingRaw, wrapping, align, tooltipInfo, isTooltipIconHidden, tooltipPortalSelector, sortingArrowsOnHover, classNameOverride, ...otherProps }: TableHeaderRowCellProps) => JSX.Element;
60
+ } & TableHeaderRowCellCheckboxProps & OverrideClassName<HTMLAttributes<HTMLElement>>;
61
+ export declare const TableHeaderRowCell: ({ labelText, onClick, href, width, flex, icon, checkable, checkedStatus, checkboxLabel, onCheck, reversed, sorting: sortingRaw, wrapping, align, tooltipInfo, isTooltipIconHidden, tooltipPortalSelector, sortingArrowsOnHover, classNameOverride, ...otherProps }: TableHeaderRowCellProps) => JSX.Element;
52
62
  type ButtonClickEvent = (e: React.MouseEvent<HTMLButtonElement>) => void;
53
63
  type AnchorClickEvent = (e: React.MouseEvent<HTMLAnchorElement>) => void;
54
64
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaizen/components",
3
- "version": "1.45.3",
3
+ "version": "1.46.0",
4
4
  "description": "Kaizen component library",
5
5
  "author": "Geoffrey Chong <geoff.chong@cultureamp.com>",
6
6
  "homepage": "https://cultureamp.design",
@@ -109,8 +109,8 @@
109
109
  "ts-node": "^10.9.2",
110
110
  "ts-patch": "^3.1.2",
111
111
  "typescript-transform-paths": "^3.4.7",
112
- "@kaizen/design-tokens": "10.3.20",
113
- "@kaizen/tailwind": "1.2.6"
112
+ "@kaizen/tailwind": "1.2.6",
113
+ "@kaizen/design-tokens": "10.3.20"
114
114
  },
115
115
  "peerDependencies": {
116
116
  "@cultureamp/i18n-react-intl": "^2.5.6",
@@ -20,10 +20,6 @@ $row-height-data-variant: 48px;
20
20
  &:focus {
21
21
  text-decoration: none;
22
22
  }
23
-
24
- &.headerRowCellButtonReversed {
25
- color: $color-white;
26
- }
27
23
  }
28
24
 
29
25
  // Special Table-only button reset
@@ -35,6 +31,7 @@ $row-height-data-variant: 48px;
35
31
  margin: 0;
36
32
  padding: 0;
37
33
  transition: none; // override Murmur global styles :(
34
+ outline: none;
38
35
  }
39
36
 
40
37
  .container {
@@ -80,19 +77,55 @@ $row-height-data-variant: 48px;
80
77
  .headerRowCell .headerRowCellTooltip {
81
78
  display: flex;
82
79
  align-items: stretch;
80
+ max-width: 100%;
83
81
  }
84
82
 
85
- // overflow has to be set at this level as well as on the heading for some reason ¯\_(ツ)_/¯
86
- .headerRowCell.headerRowCellNoWrap .headerRowCellTooltip {
87
- overflow: hidden;
83
+ .headerRowCell.headerRowCellNoWrap .headerRowCellContent {
84
+ max-width: 100%;
88
85
  }
89
86
 
90
87
  .headerRowCellButton {
91
88
  @include button-reset;
92
89
  @include anchor-reset;
90
+
91
+ display: flex;
92
+ align-items: stretch;
93
+ width: 100%;
94
+ // Ensures that the 100% doesn't go outside of the `headerRowCell` width
95
+ box-sizing: border-box;
96
+
97
+ &:focus-visible {
98
+ outline: none;
99
+ position: relative;
100
+
101
+ &::after {
102
+ // This offset provide enough gap on reverse for contrast ratios
103
+ $focus-ring-offset: calc((#{$border-focus-ring-border-width} * 2) + 1px);
104
+
105
+ top: 50%;
106
+ left: 50%;
107
+ transform: translate(-50%, -50%);
108
+ width: calc(100% + #{$focus-ring-offset});
109
+ height: calc(100% + #{$focus-ring-offset});
110
+ content: "";
111
+ position: absolute;
112
+ background: transparent;
113
+ border-color: $color-blue-500;
114
+ border-width: $border-focus-ring-border-width;
115
+ border-style: $border-focus-ring-border-style;
116
+ border-radius: $border-focus-ring-border-radius;
117
+ }
118
+ }
119
+ }
120
+
121
+ .headerRowCellButtonReversed {
122
+ color: $color-white;
123
+
124
+ &:focus-visible::after {
125
+ border-color: $color-blue-100;
126
+ }
93
127
  }
94
128
 
95
- .headerRowCellButton,
96
129
  .headerRowCellNoButton {
97
130
  display: flex;
98
131
  align-items: stretch;
@@ -120,6 +153,10 @@ $row-height-data-variant: 48px;
120
153
  .headerRowCellActive & {
121
154
  color: $color-purple-800;
122
155
  }
156
+
157
+ .headerRowCellButtonReversed & {
158
+ color: $color-white;
159
+ }
123
160
  }
124
161
 
125
162
  .card {
@@ -154,6 +191,29 @@ $row-height-data-variant: 48px;
154
191
  will-change: box-shadow, border-color, margin, padding, width;
155
192
  }
156
193
 
194
+ &:focus-visible {
195
+ outline: none;
196
+ position: relative;
197
+
198
+ &::after {
199
+ // This offset provide enough gap on on reverse for contrast ratios
200
+ $focus-ring-offset: calc(#{$border-focus-ring-border-width} + 2px);
201
+
202
+ top: 50%;
203
+ left: 50%;
204
+ transform: translate(-50%, -50%);
205
+ width: calc(100% + #{$focus-ring-offset});
206
+ height: calc(100% + #{$focus-ring-offset});
207
+ content: "";
208
+ position: absolute;
209
+ background: transparent;
210
+ border-color: $color-blue-500;
211
+ border-width: $border-focus-ring-border-width;
212
+ border-style: $border-focus-ring-border-style;
213
+ border-radius: inherit;
214
+ }
215
+ }
216
+
157
217
  &.well {
158
218
  margin-top: $spacing-sm;
159
219
  }
@@ -13,6 +13,7 @@ import styles from "./Table.module.scss"
13
13
 
14
14
  export type TableContainerProps = {
15
15
  children?: React.ReactNode
16
+ /** @default "compact" */
16
17
  variant?: "compact" | "default" | "data"
17
18
  }
18
19
  /**
@@ -56,6 +57,14 @@ export type TableHeaderRowProps = {
56
57
  const ratioToPercent = (width?: number): string | number | undefined =>
57
58
  width != null ? `${width * 100}%` : width
58
59
 
60
+ export type TableHeaderRowCellCheckboxProps = {
61
+ checkable?: boolean
62
+ checkedStatus?: CheckedStatus
63
+ /** This will be passed into the aria-label for the checkbox to provide context to the user */
64
+ checkboxLabel?: string
65
+ onCheck?: (event: React.ChangeEvent<HTMLInputElement>) => any
66
+ }
67
+
59
68
  /**
60
69
  * @param width value between 1 and 0, to be calculated as a percentage
61
70
  * @param flex CSS flex shorthand as a string. Be sure to specify the flex grow,
@@ -71,9 +80,6 @@ export type TableHeaderRowCellProps = {
71
80
  flex?: string
72
81
  href?: string
73
82
  icon?: ReactElement
74
- checkable?: boolean
75
- checkedStatus?: CheckedStatus
76
- onCheck?: (event: React.ChangeEvent<HTMLInputElement>) => any
77
83
  reversed?: boolean
78
84
  /**
79
85
  * Shows an up or down arrow, to show that the column is sorted.
@@ -82,13 +88,19 @@ export type TableHeaderRowCellProps = {
82
88
  wrapping?: "nowrap" | "wrap"
83
89
  align?: "start" | "center" | "end"
84
90
  tooltipInfo?: string
91
+ /** If set, this will hide the tooltip exclamation icon. Useful in situations where
92
+ the table header does not have enough space. This should be done with caution as tooltips
93
+ should have a visual indicator to users */
85
94
  isTooltipIconHidden?: boolean
86
95
  /**
87
96
  * Specify where the tooltip should be rendered.
88
97
  */
89
98
  tooltipPortalSelector?: string | undefined
99
+ /** If set, this will show the arrow in the direction provided
100
+ when the header cell is hovered over. */
90
101
  sortingArrowsOnHover?: "ascending" | "descending" | undefined
91
- } & OverrideClassName<HTMLAttributes<HTMLElement>>
102
+ } & TableHeaderRowCellCheckboxProps &
103
+ OverrideClassName<HTMLAttributes<HTMLElement>>
92
104
 
93
105
  export const TableHeaderRowCell = ({
94
106
  labelText,
@@ -99,6 +111,7 @@ export const TableHeaderRowCell = ({
99
111
  icon,
100
112
  checkable,
101
113
  checkedStatus,
114
+ checkboxLabel,
102
115
  onCheck,
103
116
  reversed,
104
117
  sorting: sortingRaw,
@@ -111,13 +124,8 @@ export const TableHeaderRowCell = ({
111
124
  wrapping = "nowrap",
112
125
  align = "start",
113
126
  tooltipInfo,
114
- // If set, this will hide the tooltip exclamation icon. Useful in situations where
115
- // the table header does not have enough space. However, we should always show a
116
- // tooltip icon as the default based on design system tooltip guidelines.
117
127
  isTooltipIconHidden = false,
118
128
  tooltipPortalSelector,
119
- // If set, this will show the arrow in the direction provided
120
- // when the header cell is hovered over.
121
129
  sortingArrowsOnHover,
122
130
  classNameOverride,
123
131
  // There aren't any other props in the type definition, so I'm unsure why we
@@ -143,12 +151,20 @@ export const TableHeaderRowCell = ({
143
151
  <div className={styles.headerRowCellLabelAndIcons}>
144
152
  {icon && (
145
153
  <span className={styles.headerRowCellIcon}>
146
- {cloneElement(icon, { title: labelText, role: "img" })}
154
+ {cloneElement(icon, {
155
+ title: labelText,
156
+ ["aria-label"]: labelText, // title is unreliable so this is a sensible fallback for tables with icons as headers without aria-labels
157
+ role: "img",
158
+ })}
147
159
  </span>
148
160
  )}
149
161
  {checkable && (
150
162
  <div className={styles.headerRowCellCheckbox}>
151
- <Checkbox checkedStatus={checkedStatus} onCheck={onCheck} />
163
+ <Checkbox
164
+ checkedStatus={checkedStatus}
165
+ onCheck={onCheck}
166
+ aria-label={checkboxLabel}
167
+ />
152
168
  </div>
153
169
  )}
154
170
  {tooltipInfo != null && !isTooltipIconHidden ? (
@@ -23,31 +23,61 @@ A table displays rows of data, including all data in a set, making it efficient
23
23
 
24
24
  <Canvas of={TableStories.Playground} />
25
25
 
26
- ## API
26
+ ## TableContainer API
27
27
 
28
- ### Data
28
+ ### Variant
29
+
30
+ Controls the spacing in each cell within the table. Options available are `compact`, `default` and `data`.
31
+
32
+ #### Compact
29
33
  <Canvas of={TableStories.Data} />
30
34
 
31
- ### Compact
32
- <Canvas of={TableStories.Compact} />
35
+ #### Default
36
+ <Canvas of={TableStories.Default} />
33
37
 
34
- ### LinkVariant
35
- <Canvas of={TableStories.LinkVariant} />
38
+ #### Data
39
+ <Canvas of={TableStories.Data} />
40
+
41
+ ## TableHeaderRowCell API
42
+
43
+ ### Sorting
44
+ <Canvas of={TableStories.Sorting} />
45
+
46
+ ### Checkbox
47
+
48
+ To ensure there appropriate context for users of assistive technologies, when using a `checkable` `TableHeaderRowCell`, we advise in the `checkboxLabel`. This will be passed to the a checkbox aria-label and be announce to screen reader users when focused.
36
49
 
37
- ### CheckboxVariant
38
50
  <Canvas of={TableStories.CheckboxVariant} />
39
51
 
40
- ### IconVariant
41
- <Canvas of={TableStories.IconVariant} />
52
+ ### Icon
42
53
 
43
- ### Expandable
44
- <Canvas of={TableStories.Expandable} />
54
+ When using providing `icon` to `TableHeaderRowCell` the `labelText` will be passed to the `aria-label` of the SVG.
55
+
56
+ <Canvas of={TableStories.IconVariant} />
45
57
 
46
- ### HeaderAlignmentAndWrapping
58
+ ### Align and wrapping
47
59
  <Canvas of={TableStories.HeaderAlignmentAndWrapping} />
48
60
 
49
- ### Tooltip
61
+ ### Tooltips
62
+
63
+ While Tooltip content can be passed to any table header via the `tooltipInfo` prop, it is strong advised to avoid this if the header is not an interactive element as the tooltip content will be unreadable to keyboard users or those that use assistive technologies.
64
+
50
65
  <Canvas of={TableStories.Tooltip} />
51
66
 
67
+ You can read more about the Tooltip component and accessibility limitation [here](https://cultureamp.design/?path=/docs/components-tooltip--docs#screen-reader-accessibility).
68
+
52
69
  ### Reversed
53
70
  <Canvas of={TableStories.Reversed} />
71
+
72
+ ## TableCard API
73
+
74
+ ### Link
75
+ <Canvas of={TableStories.LinkVariant} />
76
+
77
+ ### Expandable
78
+
79
+ The `expandable` prop introduces known accessibility issues with nesting interactive elements as children of a `button` or `anchor` tag. We recommend avoiding this pattern if possible, or creating a tier 3 component that adheres to correct WCAG hierarchy.
80
+
81
+ <Canvas of={TableStories.Expandable} />
82
+
83
+