@patternfly/react-core 6.0.0-alpha.76 → 6.0.0-alpha.78

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 (177) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/components/package.json +1 -1
  3. package/deprecated/package.json +1 -1
  4. package/dist/dynamic/components/AboutModal/package.json +1 -1
  5. package/dist/dynamic/components/Accordion/package.json +1 -1
  6. package/dist/dynamic/components/ActionList/package.json +1 -1
  7. package/dist/dynamic/components/Alert/package.json +1 -1
  8. package/dist/dynamic/components/Avatar/package.json +1 -1
  9. package/dist/dynamic/components/BackToTop/package.json +1 -1
  10. package/dist/dynamic/components/Backdrop/package.json +1 -1
  11. package/dist/dynamic/components/BackgroundImage/package.json +1 -1
  12. package/dist/dynamic/components/Badge/package.json +1 -1
  13. package/dist/dynamic/components/Banner/package.json +1 -1
  14. package/dist/dynamic/components/Brand/package.json +1 -1
  15. package/dist/dynamic/components/Breadcrumb/package.json +1 -1
  16. package/dist/dynamic/components/Button/package.json +1 -1
  17. package/dist/dynamic/components/CalendarMonth/package.json +1 -1
  18. package/dist/dynamic/components/Card/package.json +1 -1
  19. package/dist/dynamic/components/Checkbox/package.json +1 -1
  20. package/dist/dynamic/components/ClipboardCopy/package.json +1 -1
  21. package/dist/dynamic/components/CodeBlock/package.json +1 -1
  22. package/dist/dynamic/components/Content/package.json +1 -1
  23. package/dist/dynamic/components/DataList/package.json +1 -1
  24. package/dist/dynamic/components/DatePicker/package.json +1 -1
  25. package/dist/dynamic/components/DescriptionList/package.json +1 -1
  26. package/dist/dynamic/components/Divider/package.json +1 -1
  27. package/dist/dynamic/components/Drawer/package.json +1 -1
  28. package/dist/dynamic/components/Dropdown/package.json +1 -1
  29. package/dist/dynamic/components/DualListSelector/package.json +1 -1
  30. package/dist/dynamic/components/EmptyState/package.json +1 -1
  31. package/dist/dynamic/components/ExpandableSection/package.json +1 -1
  32. package/dist/dynamic/components/FileUpload/package.json +1 -1
  33. package/dist/dynamic/components/Form/package.json +1 -1
  34. package/dist/dynamic/components/FormSelect/package.json +1 -1
  35. package/dist/dynamic/components/HelperText/package.json +1 -1
  36. package/dist/dynamic/components/Hint/package.json +1 -1
  37. package/dist/dynamic/components/Icon/package.json +1 -1
  38. package/dist/dynamic/components/InputGroup/package.json +1 -1
  39. package/dist/dynamic/components/JumpLinks/package.json +1 -1
  40. package/dist/dynamic/components/Label/package.json +1 -1
  41. package/dist/dynamic/components/List/package.json +1 -1
  42. package/dist/dynamic/components/LoginPage/package.json +1 -1
  43. package/dist/dynamic/components/Masthead/package.json +1 -1
  44. package/dist/dynamic/components/Menu/package.json +1 -1
  45. package/dist/dynamic/components/MenuToggle/package.json +1 -1
  46. package/dist/dynamic/components/Modal/package.json +1 -1
  47. package/dist/dynamic/components/MultipleFileUpload/package.json +1 -1
  48. package/dist/dynamic/components/Nav/package.json +1 -1
  49. package/dist/dynamic/components/NotificationBadge/package.json +1 -1
  50. package/dist/dynamic/components/NotificationDrawer/package.json +1 -1
  51. package/dist/dynamic/components/NumberInput/package.json +1 -1
  52. package/dist/dynamic/components/OverflowMenu/package.json +1 -1
  53. package/dist/dynamic/components/Page/package.json +1 -1
  54. package/dist/dynamic/components/Pagination/package.json +1 -1
  55. package/dist/dynamic/components/Panel/package.json +1 -1
  56. package/dist/dynamic/components/Popover/package.json +1 -1
  57. package/dist/dynamic/components/Progress/package.json +1 -1
  58. package/dist/dynamic/components/ProgressStepper/package.json +1 -1
  59. package/dist/dynamic/components/Radio/package.json +1 -1
  60. package/dist/dynamic/components/SearchInput/package.json +1 -1
  61. package/dist/dynamic/components/Select/package.json +1 -1
  62. package/dist/dynamic/components/Sidebar/package.json +1 -1
  63. package/dist/dynamic/components/SimpleList/package.json +1 -1
  64. package/dist/dynamic/components/Skeleton/package.json +1 -1
  65. package/dist/dynamic/components/SkipToContent/package.json +1 -1
  66. package/dist/dynamic/components/Slider/package.json +1 -1
  67. package/dist/dynamic/components/Spinner/package.json +1 -1
  68. package/dist/dynamic/components/Switch/package.json +1 -1
  69. package/dist/dynamic/components/Tabs/package.json +1 -1
  70. package/dist/dynamic/components/TextArea/package.json +1 -1
  71. package/dist/dynamic/components/TextInput/package.json +1 -1
  72. package/dist/dynamic/components/TextInputGroup/package.json +1 -1
  73. package/dist/dynamic/components/Tile/package.json +1 -1
  74. package/dist/dynamic/components/TimePicker/package.json +1 -1
  75. package/dist/dynamic/components/Timestamp/package.json +1 -1
  76. package/dist/dynamic/components/Title/package.json +1 -1
  77. package/dist/dynamic/components/ToggleGroup/package.json +1 -1
  78. package/dist/dynamic/components/Toolbar/package.json +1 -1
  79. package/dist/dynamic/components/Tooltip/package.json +1 -1
  80. package/dist/dynamic/components/TreeView/package.json +1 -1
  81. package/dist/dynamic/components/Truncate/package.json +1 -1
  82. package/dist/dynamic/components/Wizard/hooks/package.json +1 -1
  83. package/dist/dynamic/components/Wizard/package.json +1 -1
  84. package/dist/dynamic/deprecated/components/Chip/package.json +1 -1
  85. package/dist/dynamic/deprecated/components/DragDrop/package.json +1 -1
  86. package/dist/dynamic/deprecated/components/DualListSelector/package.json +1 -1
  87. package/dist/dynamic/deprecated/components/Modal/package.json +1 -1
  88. package/dist/dynamic/deprecated/components/Wizard/package.json +1 -1
  89. package/dist/dynamic/deprecated/components/package.json +1 -1
  90. package/dist/dynamic/helpers/FocusTrap/FocusTrap/package.json +1 -1
  91. package/dist/dynamic/helpers/GenerateId/GenerateId/package.json +1 -1
  92. package/dist/dynamic/helpers/KeyboardHandler/package.json +1 -1
  93. package/dist/dynamic/helpers/OUIA/ouia/package.json +1 -1
  94. package/dist/dynamic/helpers/Popper/Popper/package.json +1 -1
  95. package/dist/dynamic/helpers/constants/package.json +1 -1
  96. package/dist/dynamic/helpers/datetimeUtils/package.json +1 -1
  97. package/dist/dynamic/helpers/fileUtils/package.json +1 -1
  98. package/dist/dynamic/helpers/htmlConstants/package.json +1 -1
  99. package/dist/dynamic/helpers/package.json +1 -1
  100. package/dist/dynamic/helpers/resizeObserver/package.json +1 -1
  101. package/dist/dynamic/helpers/typeUtils/package.json +1 -1
  102. package/dist/dynamic/helpers/useInterval/package.json +1 -1
  103. package/dist/dynamic/helpers/useIsomorphicLayout/package.json +1 -1
  104. package/dist/dynamic/helpers/useUnmountEffect/package.json +1 -1
  105. package/dist/dynamic/helpers/util/package.json +1 -1
  106. package/dist/dynamic/layouts/Bullseye/package.json +1 -1
  107. package/dist/dynamic/layouts/Flex/package.json +1 -1
  108. package/dist/dynamic/layouts/Gallery/package.json +1 -1
  109. package/dist/dynamic/layouts/Grid/package.json +1 -1
  110. package/dist/dynamic/layouts/Level/package.json +1 -1
  111. package/dist/dynamic/layouts/Split/package.json +1 -1
  112. package/dist/dynamic/layouts/Stack/package.json +1 -1
  113. package/dist/dynamic/styles/package.json +1 -1
  114. package/dist/esm/components/JumpLinks/JumpLinks.d.ts.map +1 -1
  115. package/dist/esm/components/JumpLinks/JumpLinks.js +2 -7
  116. package/dist/esm/components/JumpLinks/JumpLinks.js.map +1 -1
  117. package/dist/esm/components/Page/PageSidebarBody.d.ts +2 -0
  118. package/dist/esm/components/Page/PageSidebarBody.d.ts.map +1 -1
  119. package/dist/esm/components/Page/PageSidebarBody.js +2 -2
  120. package/dist/esm/components/Page/PageSidebarBody.js.map +1 -1
  121. package/dist/esm/components/Pagination/PaginationOptionsMenu.js +1 -1
  122. package/dist/esm/components/Pagination/PaginationOptionsMenu.js.map +1 -1
  123. package/dist/esm/components/Switch/Switch.d.ts +6 -6
  124. package/dist/esm/components/Switch/Switch.d.ts.map +1 -1
  125. package/dist/esm/components/Switch/Switch.js +11 -8
  126. package/dist/esm/components/Switch/Switch.js.map +1 -1
  127. package/dist/esm/components/Tabs/Tabs.d.ts.map +1 -1
  128. package/dist/esm/components/Tabs/Tabs.js +2 -4
  129. package/dist/esm/components/Tabs/Tabs.js.map +1 -1
  130. package/dist/js/components/JumpLinks/JumpLinks.d.ts.map +1 -1
  131. package/dist/js/components/JumpLinks/JumpLinks.js +2 -7
  132. package/dist/js/components/JumpLinks/JumpLinks.js.map +1 -1
  133. package/dist/js/components/Page/PageSidebarBody.d.ts +2 -0
  134. package/dist/js/components/Page/PageSidebarBody.d.ts.map +1 -1
  135. package/dist/js/components/Page/PageSidebarBody.js +2 -2
  136. package/dist/js/components/Page/PageSidebarBody.js.map +1 -1
  137. package/dist/js/components/Pagination/PaginationOptionsMenu.js +1 -1
  138. package/dist/js/components/Pagination/PaginationOptionsMenu.js.map +1 -1
  139. package/dist/js/components/Switch/Switch.d.ts +6 -6
  140. package/dist/js/components/Switch/Switch.d.ts.map +1 -1
  141. package/dist/js/components/Switch/Switch.js +11 -8
  142. package/dist/js/components/Switch/Switch.js.map +1 -1
  143. package/dist/js/components/Tabs/Tabs.d.ts.map +1 -1
  144. package/dist/js/components/Tabs/Tabs.js +2 -4
  145. package/dist/js/components/Tabs/Tabs.js.map +1 -1
  146. package/dist/styles/assets/images/img_avatar-dark.svg +22 -16
  147. package/dist/styles/assets/images/img_avatar-light.svg +25 -18
  148. package/dist/styles/assets/pficon/pf-v6-pficon.woff2 +0 -0
  149. package/dist/styles/assets/pficon/pficon.scss +36 -0
  150. package/dist/styles/base-no-reset.css +936 -905
  151. package/dist/styles/base.css +936 -905
  152. package/dist/umd/assets/{output-B_N2Kl1_.css → output-Dt8Et40Q.css} +4660 -5446
  153. package/dist/umd/react-core.min.js +3 -3
  154. package/helpers/package.json +1 -1
  155. package/layouts/package.json +1 -1
  156. package/next/package.json +1 -1
  157. package/package.json +6 -6
  158. package/src/components/JumpLinks/JumpLinks.tsx +6 -4
  159. package/src/components/JumpLinks/__tests__/__snapshots__/JumpLinks.test.tsx.snap +6 -6
  160. package/src/components/Page/PageSidebarBody.tsx +4 -0
  161. package/src/components/Page/examples/PageMultipleSidebarBody.tsx +6 -3
  162. package/src/components/Pagination/PaginationOptionsMenu.tsx +1 -1
  163. package/src/components/Switch/Switch.tsx +24 -21
  164. package/src/components/Switch/__tests__/Switch.test.tsx +14 -7
  165. package/src/components/Switch/__tests__/__snapshots__/Switch.test.tsx.snap +16 -36
  166. package/src/components/Switch/examples/Switch.md +8 -0
  167. package/src/components/Switch/examples/SwitchBasic.tsx +1 -2
  168. package/src/components/Switch/examples/SwitchCheckedWithLabel.tsx +1 -3
  169. package/src/components/Switch/examples/SwitchDisabled.tsx +13 -12
  170. package/src/components/Switch/examples/SwitchReversed.tsx +1 -2
  171. package/src/components/Switch/examples/SwitchUncontrolled.tsx +6 -2
  172. package/src/components/Switch/examples/SwitchWithoutLabel.tsx +8 -1
  173. package/src/components/Tabs/Tabs.tsx +6 -8
  174. package/src/components/Tabs/__tests__/__snapshots__/Tabs.test.tsx.snap +5 -3
  175. package/src/demos/JumpLinks.md +1 -2
  176. package/src/demos/Page.md +6 -0
  177. package/src/demos/examples/Page/PageContextSelector.tsx +319 -0
@@ -3,6 +3,6 @@
3
3
  "main": "../dist/js/helpers/index.js",
4
4
  "module": "../dist/esm/helpers/index.js",
5
5
  "typings": "../dist/esm/helpers/index.d.ts",
6
- "version": "6.0.0-alpha.75",
6
+ "version": "6.0.0-alpha.77",
7
7
  "private": true
8
8
  }
@@ -3,6 +3,6 @@
3
3
  "main": "../dist/js/layouts/index.js",
4
4
  "module": "../dist/esm/layouts/index.js",
5
5
  "typings": "../dist/esm/layouts/index.d.ts",
6
- "version": "6.0.0-alpha.75",
6
+ "version": "6.0.0-alpha.77",
7
7
  "private": true
8
8
  }
package/next/package.json CHANGED
@@ -3,6 +3,6 @@
3
3
  "main": "../dist/js/next/index.js",
4
4
  "module": "../dist/esm/next/index.js",
5
5
  "typings": "../dist/esm/next/index.d.ts",
6
- "version": "6.0.0-alpha.75",
6
+ "version": "6.0.0-alpha.77",
7
7
  "private": true
8
8
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-core",
3
- "version": "6.0.0-alpha.76",
3
+ "version": "6.0.0-alpha.78",
4
4
  "description": "This library provides a set of common React components for use with the PatternFly reference implementation.",
5
5
  "main": "dist/js/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -47,15 +47,15 @@
47
47
  "clean:exports": "node scripts/cleanDistExports.js"
48
48
  },
49
49
  "dependencies": {
50
- "@patternfly/react-icons": "^6.0.0-alpha.28",
51
- "@patternfly/react-styles": "^6.0.0-alpha.27",
52
- "@patternfly/react-tokens": "^6.0.0-alpha.27",
50
+ "@patternfly/react-icons": "^6.0.0-alpha.29",
51
+ "@patternfly/react-styles": "^6.0.0-alpha.28",
52
+ "@patternfly/react-tokens": "^6.0.0-alpha.28",
53
53
  "focus-trap": "7.5.4",
54
54
  "react-dropzone": "^14.2.3",
55
55
  "tslib": "^2.6.2"
56
56
  },
57
57
  "devDependencies": {
58
- "@patternfly/patternfly": "6.0.0-alpha.166",
58
+ "@patternfly/patternfly": "6.0.0-alpha.180",
59
59
  "case-anything": "^2.1.13",
60
60
  "css": "^3.0.0",
61
61
  "fs-extra": "^11.2.0"
@@ -64,5 +64,5 @@
64
64
  "react": "^17 || ^18",
65
65
  "react-dom": "^17 || ^18"
66
66
  },
67
- "gitHead": "625adc6f7459977f551a18d9a690bff56aea3f18"
67
+ "gitHead": "4eb47e70a3ba0ce15d70b03b8cf9602f7a7215f3"
68
68
  }
@@ -249,11 +249,13 @@ export const JumpLinks: React.FunctionComponent<JumpLinksProps> = ({
249
249
  onClick={() => setIsExpanded(!isExpanded)}
250
250
  aria-label={toggleAriaLabel}
251
251
  aria-expanded={isExpanded}
252
+ icon={
253
+ <span className={styles.jumpLinksToggleIcon}>
254
+ <AngleRightIcon />
255
+ </span>
256
+ }
252
257
  >
253
- <span className={styles.jumpLinksToggleIcon}>
254
- <AngleRightIcon />
255
- </span>
256
- {label && <span className={css(styles.jumpLinksToggleText)}> {label} </span>}
258
+ {label && label}
257
259
  </Button>
258
260
  </div>
259
261
  )}
@@ -26,7 +26,7 @@ exports[`expandable vertical with subsection 1`] = `
26
26
  type="button"
27
27
  >
28
28
  <span
29
- class="pf-v6-c-button__text"
29
+ class="pf-v6-c-button__icon pf-m-start"
30
30
  >
31
31
  <span
32
32
  class="pf-v6-c-jump-links__toggle-icon"
@@ -45,11 +45,11 @@ exports[`expandable vertical with subsection 1`] = `
45
45
  />
46
46
  </svg>
47
47
  </span>
48
- <span
49
- class="pf-v6-c-jump-links__toggle-text"
50
- >
51
- Jump to section
52
- </span>
48
+ </span>
49
+ <span
50
+ class="pf-v6-c-button__text"
51
+ >
52
+ Jump to section
53
53
  </span>
54
54
  </button>
55
55
  </div>
@@ -11,6 +11,8 @@ export interface PageSidebarBodyProps extends React.HTMLProps<HTMLDivElement> {
11
11
  usePageInsets?: boolean;
12
12
  /** Flag indicating that the page sidebar body should fill the available vertical space. */
13
13
  isFilled?: boolean;
14
+ /** Flag indicating that the page sidebar body is for a context selector/perspective switcher */
15
+ isContextSelector?: boolean;
14
16
  }
15
17
 
16
18
  export const PageSidebarBody: React.FunctionComponent<PageSidebarBodyProps> = ({
@@ -18,6 +20,7 @@ export const PageSidebarBody: React.FunctionComponent<PageSidebarBodyProps> = ({
18
20
  className,
19
21
  usePageInsets,
20
22
  isFilled,
23
+ isContextSelector,
21
24
  ...props
22
25
  }: PageSidebarBodyProps) => (
23
26
  <div
@@ -26,6 +29,7 @@ export const PageSidebarBody: React.FunctionComponent<PageSidebarBodyProps> = ({
26
29
  usePageInsets && styles.modifiers.pageInsets,
27
30
  isFilled === false && styles.modifiers.noFill,
28
31
  isFilled === true && styles.modifiers.fill,
32
+ isContextSelector === true && styles.modifiers.contextSelector,
29
33
  className
30
34
  )}
31
35
  {...props}
@@ -55,10 +55,13 @@ export const PageMultipleSidebarBody: React.FunctionComponent = () => {
55
55
 
56
56
  const sidebar = (
57
57
  <PageSidebar isSidebarOpen={isSidebarOpen} id="multiple-sidebar-body-sidebar">
58
- <PageSidebarBody usePageInsets>First sidebar body (with insets)</PageSidebarBody>
59
- <PageSidebarBody isFilled={true}>Second sidebar body (with fill)</PageSidebarBody>
58
+ <PageSidebarBody isContextSelector>
59
+ First sidebar body (for a context selector/perspective switcher)
60
+ </PageSidebarBody>
61
+ <PageSidebarBody usePageInsets>Second sidebar body (with insets)</PageSidebarBody>
62
+ <PageSidebarBody isFilled={true}>Third sidebar body (with fill)</PageSidebarBody>
60
63
  <PageSidebarBody isFilled={false} usePageInsets>
61
- Third sidebar body (with insets and no fill)
64
+ Fourth sidebar body (with insets and no fill)
62
65
  </PageSidebarBody>
63
66
  </PageSidebar>
64
67
  );
@@ -73,7 +73,7 @@ export const PaginationOptionsMenu: React.FunctionComponent<PaginationOptionsMen
73
73
  firstIndex = 0,
74
74
  lastIndex = 0,
75
75
  isLastFullPageShown = false,
76
- itemsTitle = 'items',
76
+ itemsTitle = '',
77
77
  toggleTemplate,
78
78
  onPerPageSelect = () => null as any,
79
79
  containerRef
@@ -12,10 +12,12 @@ export interface SwitchProps
12
12
  id?: string;
13
13
  /** Additional classes added to the switch */
14
14
  className?: string;
15
- /** Text value for the visible label when on */
15
+ /** Text value for the visible label */
16
16
  label?: React.ReactNode;
17
- /** Text value for the visible label when off */
18
- labelOff?: React.ReactNode;
17
+ /** Adds an accessible name to the switch when the label prop is not passed, and must describe the isChecked="true" state. */
18
+ 'aria-label'?: string;
19
+ /** Adds an accessible name to the switch via one or more referenced id(s). The computed accessible name must describe the isChecked="true" state. */
20
+ 'aria-labelledby'?: string;
19
21
  /** Flag to show if the switch is checked when it is controlled by React state.
20
22
  * To make the switch uncontrolled instead use the defaultChecked prop, but do not use both.
21
23
  */
@@ -30,9 +32,7 @@ export interface SwitchProps
30
32
  isDisabled?: boolean;
31
33
  /** A callback for when the switch selection changes. (event, isChecked) => {} */
32
34
  onChange?: (event: React.FormEvent<HTMLInputElement>, checked: boolean) => void;
33
- /** Adds accessible text to the switch, and should describe the isChecked="true" state. When label is defined, aria-label should be set to the text string that is visible when isChecked is true. */
34
- 'aria-label'?: string;
35
- /** Flag to reverse the layout of toggle and label (toggle on right). */
35
+ /** Flag to reverse the layout of toggle and label (label at start, toggle at end). */
36
36
  isReversed?: boolean;
37
37
  /** Value to overwrite the randomly generated data-ouia-component-id.*/
38
38
  ouiaId?: number | string;
@@ -48,15 +48,18 @@ class Switch extends React.Component<SwitchProps & OUIAProps, { ouiaStateId: str
48
48
  isChecked: true,
49
49
  isDisabled: false,
50
50
  isReversed: false,
51
- 'aria-label': '',
51
+ 'aria-label': undefined,
52
+ 'aria-labelledby': undefined,
52
53
  onChange: () => undefined as any
53
54
  };
54
55
 
55
56
  constructor(props: SwitchProps & OUIAProps) {
56
57
  super(props);
57
- if (!props.label && !props['aria-label']) {
58
+ if (!props.label && !props['aria-label'] && !props['aria-labelledby']) {
58
59
  // eslint-disable-next-line no-console
59
- console.error('Switch: Switch requires either a label or an aria-label to be specified');
60
+ console.error(
61
+ 'Switch: Switch requires at least one of label, aria-labelledby, or aria-label props to be specified'
62
+ );
60
63
  }
61
64
 
62
65
  this.id = props.id || getUniqueId();
@@ -71,7 +74,6 @@ class Switch extends React.Component<SwitchProps & OUIAProps, { ouiaStateId: str
71
74
  id,
72
75
  className,
73
76
  label,
74
- labelOff,
75
77
  isChecked,
76
78
  defaultChecked,
77
79
  hasCheckIcon,
@@ -80,10 +82,16 @@ class Switch extends React.Component<SwitchProps & OUIAProps, { ouiaStateId: str
80
82
  isReversed,
81
83
  ouiaId,
82
84
  ouiaSafe,
85
+ 'aria-label': ariaLabel,
86
+ 'aria-labelledby': ariaLabelledBy,
83
87
  ...props
84
88
  } = this.props;
85
89
 
86
- const isAriaLabelledBy = props['aria-label'] === '';
90
+ const hasAccessibleName = label || ariaLabel || ariaLabelledBy;
91
+ const isAriaLabelledBy = hasAccessibleName && (!ariaLabel || ariaLabelledBy);
92
+ const useDefaultAriaLabelledBy = !ariaLabelledBy && !ariaLabel;
93
+ const ariaLabelledByIds = ariaLabelledBy ?? `${this.id}-label`;
94
+
87
95
  return (
88
96
  <label
89
97
  className={css(styles.switch, isReversed && styles.modifiers.reverse, className)}
@@ -94,10 +102,12 @@ class Switch extends React.Component<SwitchProps & OUIAProps, { ouiaStateId: str
94
102
  id={this.id}
95
103
  className={css(styles.switchInput)}
96
104
  type="checkbox"
105
+ role="switch"
97
106
  onChange={(event) => onChange(event, event.target.checked)}
98
107
  {...(defaultChecked !== undefined ? { defaultChecked } : { checked: isChecked })}
99
108
  disabled={isDisabled}
100
- aria-labelledby={!isAriaLabelledBy ? null : `${this.id}-${isChecked !== true ? 'off' : 'on'}`}
109
+ aria-labelledby={isAriaLabelledBy ? ariaLabelledByIds : null}
110
+ aria-label={ariaLabel}
101
111
  {...props}
102
112
  />
103
113
  {label !== undefined ? (
@@ -110,19 +120,12 @@ class Switch extends React.Component<SwitchProps & OUIAProps, { ouiaStateId: str
110
120
  )}
111
121
  </span>
112
122
  <span
113
- className={css(styles.switchLabel, styles.modifiers.on)}
114
- id={isAriaLabelledBy ? `${this.id}-on` : null}
123
+ className={css(styles.switchLabel)}
124
+ id={isAriaLabelledBy && useDefaultAriaLabelledBy ? `${this.id}-label` : null}
115
125
  aria-hidden="true"
116
126
  >
117
127
  {label}
118
128
  </span>
119
- <span
120
- className={css(styles.switchLabel, styles.modifiers.off)}
121
- id={isAriaLabelledBy ? `${this.id}-off` : null}
122
- aria-hidden="true"
123
- >
124
- {labelOff !== undefined ? labelOff : label}
125
- </span>
126
129
  </React.Fragment>
127
130
  ) : (
128
131
  <span className={css(styles.switchToggle)}>
@@ -26,15 +26,13 @@ describe('Switch', () => {
26
26
  });
27
27
 
28
28
  test('switch is checked', () => {
29
- const { asFragment } = render(
30
- <Switch id="switch-is-checked" label="On" labelOff="Off" isChecked aria-label="Switch label" />
31
- );
29
+ const { asFragment } = render(<Switch id="switch-is-checked" label="On" isChecked aria-label="Switch label" />);
32
30
  expect(asFragment()).toMatchSnapshot();
33
31
  });
34
32
 
35
33
  test('switch is not checked', () => {
36
34
  const { asFragment } = render(
37
- <Switch id="switch-is-not-checked" label="On" labelOff="Off" isChecked={false} aria-label="Switch label" />
35
+ <Switch id="switch-is-not-checked" label="On" isChecked={false} aria-label="Switch label" />
38
36
  );
39
37
  expect(asFragment()).toMatchSnapshot();
40
38
  });
@@ -84,7 +82,7 @@ describe('Switch', () => {
84
82
  expect(props.onChange).toHaveBeenCalledWith(expect.any(Object), true);
85
83
  });
86
84
 
87
- test('should throw console error when no aria-label or label is given', () => {
85
+ test('should throw console error when no aria-label, aria-labelledby, or label is given', () => {
88
86
  const myMock = jest.fn();
89
87
 
90
88
  global.console = { ...global.console, error: myMock };
@@ -93,7 +91,7 @@ describe('Switch', () => {
93
91
  expect(myMock).toHaveBeenCalled();
94
92
  });
95
93
 
96
- test('should not throw console error when label is given but no aria-label', () => {
94
+ test('should not throw console error when label is given', () => {
97
95
  const myMock = jest.fn();
98
96
  global.console = { ...global.console, error: myMock };
99
97
 
@@ -102,7 +100,7 @@ describe('Switch', () => {
102
100
  expect(myMock).not.toHaveBeenCalled();
103
101
  });
104
102
 
105
- test('should not throw console error when aria-label is given but no label', () => {
103
+ test('should not throw console error when aria-label is given', () => {
106
104
  const myMock = jest.fn();
107
105
  global.console = { ...global.console, error: myMock };
108
106
 
@@ -111,6 +109,15 @@ describe('Switch', () => {
111
109
  expect(myMock).not.toHaveBeenCalled();
112
110
  });
113
111
 
112
+ test('should not throw console error when aria-labelledby is given', () => {
113
+ const myMock = jest.fn();
114
+ global.console = { ...global.console, error: myMock };
115
+
116
+ render(<Switch {...props} aria-labelledby="some-id" />);
117
+
118
+ expect(myMock).not.toHaveBeenCalled();
119
+ });
120
+
114
121
  test('should apply reversed modifier', () => {
115
122
  render(<Switch id="reversed-switch" label="reversed switch" isReversed aria-label="Switch label" />);
116
123
  expect(screen.getByLabelText('Switch label').parentElement).toHaveClass('pf-m-reverse');
@@ -14,6 +14,7 @@ exports[`Switch no label switch is checked 1`] = `
14
14
  checked=""
15
15
  class="pf-v6-c-switch__input"
16
16
  id="no-label-switch-is-checked"
17
+ role="switch"
17
18
  type="checkbox"
18
19
  />
19
20
  <span
@@ -55,6 +56,7 @@ exports[`Switch no label switch is not checked 1`] = `
55
56
  aria-label="Switch label"
56
57
  class="pf-v6-c-switch__input"
57
58
  id="no-label-switch-is-not-checked"
59
+ role="switch"
58
60
  type="checkbox"
59
61
  />
60
62
  <span
@@ -97,6 +99,7 @@ exports[`Switch switch is checked 1`] = `
97
99
  checked=""
98
100
  class="pf-v6-c-switch__input"
99
101
  id="switch-is-checked"
102
+ role="switch"
100
103
  type="checkbox"
101
104
  />
102
105
  <span
@@ -104,16 +107,10 @@ exports[`Switch switch is checked 1`] = `
104
107
  />
105
108
  <span
106
109
  aria-hidden="true"
107
- class="pf-v6-c-switch__label pf-m-on"
110
+ class="pf-v6-c-switch__label"
108
111
  >
109
112
  On
110
113
  </span>
111
- <span
112
- aria-hidden="true"
113
- class="pf-v6-c-switch__label pf-m-off"
114
- >
115
- Off
116
- </span>
117
114
  </label>
118
115
  </DocumentFragment>
119
116
  `;
@@ -133,6 +130,7 @@ exports[`Switch switch is checked and disabled 1`] = `
133
130
  class="pf-v6-c-switch__input"
134
131
  disabled=""
135
132
  id="switch-is-checked-and-disabled"
133
+ role="switch"
136
134
  type="checkbox"
137
135
  />
138
136
  <span
@@ -174,6 +172,7 @@ exports[`Switch switch is not checked 1`] = `
174
172
  aria-label="Switch label"
175
173
  class="pf-v6-c-switch__input"
176
174
  id="switch-is-not-checked"
175
+ role="switch"
177
176
  type="checkbox"
178
177
  />
179
178
  <span
@@ -181,16 +180,10 @@ exports[`Switch switch is not checked 1`] = `
181
180
  />
182
181
  <span
183
182
  aria-hidden="true"
184
- class="pf-v6-c-switch__label pf-m-on"
183
+ class="pf-v6-c-switch__label"
185
184
  >
186
185
  On
187
186
  </span>
188
- <span
189
- aria-hidden="true"
190
- class="pf-v6-c-switch__label pf-m-off"
191
- >
192
- Off
193
- </span>
194
187
  </label>
195
188
  </DocumentFragment>
196
189
  `;
@@ -209,6 +202,7 @@ exports[`Switch switch is not checked and disabled 1`] = `
209
202
  class="pf-v6-c-switch__input"
210
203
  disabled=""
211
204
  id="switch-is-not-checked-and-disabled"
205
+ role="switch"
212
206
  type="checkbox"
213
207
  />
214
208
  <span
@@ -247,11 +241,11 @@ exports[`Switch switch with only label is checked 1`] = `
247
241
  for="switch-is-checked"
248
242
  >
249
243
  <input
250
- aria-label=""
251
- aria-labelledby="switch-is-checked-on"
244
+ aria-labelledby="switch-is-checked-label"
252
245
  checked=""
253
246
  class="pf-v6-c-switch__input"
254
247
  id="switch-is-checked"
248
+ role="switch"
255
249
  type="checkbox"
256
250
  />
257
251
  <span
@@ -259,15 +253,8 @@ exports[`Switch switch with only label is checked 1`] = `
259
253
  />
260
254
  <span
261
255
  aria-hidden="true"
262
- class="pf-v6-c-switch__label pf-m-on"
263
- id="switch-is-checked-on"
264
- >
265
- On
266
- </span>
267
- <span
268
- aria-hidden="true"
269
- class="pf-v6-c-switch__label pf-m-off"
270
- id="switch-is-checked-off"
256
+ class="pf-v6-c-switch__label"
257
+ id="switch-is-checked-label"
271
258
  >
272
259
  On
273
260
  </span>
@@ -285,10 +272,10 @@ exports[`Switch switch with only label is not checked 1`] = `
285
272
  for="switch-is-not-checked"
286
273
  >
287
274
  <input
288
- aria-label=""
289
- aria-labelledby="switch-is-not-checked-off"
275
+ aria-labelledby="switch-is-not-checked-label"
290
276
  class="pf-v6-c-switch__input"
291
277
  id="switch-is-not-checked"
278
+ role="switch"
292
279
  type="checkbox"
293
280
  />
294
281
  <span
@@ -296,15 +283,8 @@ exports[`Switch switch with only label is not checked 1`] = `
296
283
  />
297
284
  <span
298
285
  aria-hidden="true"
299
- class="pf-v6-c-switch__label pf-m-on"
300
- id="switch-is-not-checked-on"
301
- >
302
- Off
303
- </span>
304
- <span
305
- aria-hidden="true"
306
- class="pf-v6-c-switch__label pf-m-off"
307
- id="switch-is-not-checked-off"
286
+ class="pf-v6-c-switch__label"
287
+ id="switch-is-not-checked-label"
308
288
  >
309
289
  Off
310
290
  </span>
@@ -8,32 +8,40 @@ ouia: true
8
8
 
9
9
  ## Examples
10
10
 
11
+ To keep inline with accessibility guidelines, the label for a switch must never dynamically change. A dynamically changing label (such as one label for an "on" state and another label for an "off" state) can be confusing as the contexts for each label changes as the switch state does. This applies to both visible text labels as well as labels provided via `aria-label`.
12
+
11
13
  ### Basic
12
14
 
13
15
  ```ts file="./SwitchBasic.tsx"
16
+
14
17
  ```
15
18
 
16
19
  ### Reversed Layout
17
20
 
18
21
  ```ts file="./SwitchReversed.tsx"
22
+
19
23
  ```
20
24
 
21
25
  ### Without label
22
26
 
23
27
  ```ts file="./SwitchWithoutLabel.tsx"
28
+
24
29
  ```
25
30
 
26
31
  ### Checked with label
27
32
 
28
33
  ```ts file="./SwitchCheckedWithLabel.tsx"
34
+
29
35
  ```
30
36
 
31
37
  ### Disabled
32
38
 
33
39
  ```ts file="./SwitchDisabled.tsx"
40
+
34
41
  ```
35
42
 
36
43
  ### Uncontrolled
37
44
 
38
45
  ```ts file="./SwitchUncontrolled.tsx"
46
+
39
47
  ```
@@ -11,8 +11,7 @@ export const SwitchBasic: React.FunctionComponent = () => {
11
11
  return (
12
12
  <Switch
13
13
  id="simple-switch"
14
- label="Message when on"
15
- labelOff="Message when off"
14
+ label="Togglable option for basic example"
16
15
  isChecked={isChecked}
17
16
  onChange={handleChange}
18
17
  ouiaId="BasicSwitch"
@@ -10,10 +10,8 @@ export const SwitchCheckedWithLabel: React.FunctionComponent = () => {
10
10
 
11
11
  return (
12
12
  <Switch
13
- label="Message when on"
14
- labelOff="Message when off"
13
+ label="Togglable option for check icon example"
15
14
  id="checked-with-label-switch-on"
16
- aria-label="Message when on"
17
15
  isChecked={isChecked}
18
16
  hasCheckIcon
19
17
  onChange={handleChange}
@@ -3,26 +3,27 @@ import { Switch } from '@patternfly/react-core';
3
3
 
4
4
  export const SwitchDisabled: React.FunctionComponent = () => (
5
5
  <React.Fragment>
6
+ <Switch id="disabled-switch-on" label="Togglable option for disabled checked example" isChecked isDisabled />
7
+ <br />
8
+ <Switch
9
+ id="disabled-switch-off"
10
+ label="Togglable option for disabled unchecked example"
11
+ isChecked={false}
12
+ isDisabled
13
+ />
14
+ <br />
6
15
  <Switch
7
- id="disabled-switch-on"
8
- aria-label="Message when on"
9
- label="Message when on"
10
- labelOff="Message when off"
16
+ id="disabled-no-label-switch-on"
17
+ aria-label="Togglable option for checked with no visible label example"
11
18
  isChecked
12
19
  isDisabled
13
20
  />
14
21
  <br />
15
22
  <Switch
16
- id="disabled-switch-off"
17
- aria-label="Message when on"
18
- label="Message when on"
19
- labelOff="Message when off"
23
+ id="disabled-no-label-switch-off"
24
+ aria-label="Togglable option for unchecked with no visible label example"
20
25
  isChecked={false}
21
26
  isDisabled
22
27
  />
23
- <br />
24
- <Switch id="disabled-no-label-switch-on" aria-label="Message when on" isChecked isDisabled />
25
- <br />
26
- <Switch id="disabled-no-label-switch-off" aria-label="Message when on" isChecked={false} isDisabled />
27
28
  </React.Fragment>
28
29
  );
@@ -11,8 +11,7 @@ export const SwitchReversed: React.FunctionComponent = () => {
11
11
  return (
12
12
  <Switch
13
13
  id="reversed-switch"
14
- label="Message when on"
15
- labelOff="Message when off"
14
+ label="Togglable option for reversed example"
16
15
  isChecked={isChecked}
17
16
  onChange={handleChange}
18
17
  isReversed
@@ -5,10 +5,14 @@ export const SwitchUncontrolled: React.FunctionComponent = () => (
5
5
  <React.Fragment>
6
6
  <Switch
7
7
  id="uncontrolled-switch-no-label"
8
- aria-label="An uncontrolled switch with no label"
8
+ aria-label="Togglable option for uncontrolled and no visible label example"
9
9
  defaultChecked={false}
10
10
  />
11
11
  <br />
12
- <Switch id="uncontrolled-switch-with-label" label="An uncontrolled switch" defaultChecked={false} />
12
+ <Switch
13
+ id="uncontrolled-switch-with-label"
14
+ label="Togglable option for uncontrolled example"
15
+ defaultChecked={false}
16
+ />
13
17
  </React.Fragment>
14
18
  );
@@ -8,5 +8,12 @@ export const SwitchWithoutLabel: React.FunctionComponent = () => {
8
8
  setIsChecked(checked);
9
9
  };
10
10
 
11
- return <Switch id="no-label-switch-on" aria-label="Message when on" isChecked={isChecked} onChange={handleChange} />;
11
+ return (
12
+ <Switch
13
+ id="no-label-switch-on"
14
+ aria-label="Togglable option for no visible label example"
15
+ isChecked={isChecked}
16
+ onChange={handleChange}
17
+ />
18
+ );
12
19
  };
@@ -521,15 +521,13 @@ class Tabs extends React.Component<TabsProps, TabsState> {
521
521
  aria-expanded={isExpandedLocal}
522
522
  id={`${randomId}-button`}
523
523
  aria-labelledby={`${randomId}-text ${randomId}-button`}
524
- >
525
- <span className={css(styles.tabsToggleIcon)}>
526
- <AngleRightIcon arian-hidden="true" />
527
- </span>
528
- {toggleText && (
529
- <span className={css(styles.tabsToggleText)} id={`${randomId}-text`}>
530
- {toggleText}
524
+ icon={
525
+ <span className={css(styles.tabsToggleIcon)}>
526
+ <AngleRightIcon />
531
527
  </span>
532
- )}
528
+ }
529
+ >
530
+ {toggleText && <span id={`${randomId}-text`}>{toggleText}</span>}
533
531
  </Button>
534
532
  </div>
535
533
  </div>