@@ -6,6 +6,8 @@ import { useOUIAProps, OUIAProps } from '../../helpers/OUIA/ouia';
66import { Badge } from '../Badge' ;
77import StarIcon from '@patternfly/react-icons/dist/esm/icons/star-icon' ;
88import OutlinedStarIcon from '@patternfly/react-icons/dist/esm/icons/outlined-star-icon' ;
9+ import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon' ;
10+ import { hamburgerIcon } from './hamburgerIcon' ;
911
1012export enum ButtonVariant {
1113 primary = 'primary' ,
@@ -97,6 +99,14 @@ export interface ButtonProps extends Omit<React.HTMLProps<HTMLButtonElement>, 'r
9799 tabIndex ?: number ;
98100 /** Adds danger styling to secondary or link button variants */
99101 isDanger ?: boolean ;
102+ /** Flag indicating whether content the button controls is expanded or not. Required when isHamburger is true. */
103+ isExpanded ?: boolean ;
104+ /** Flag indicating the button is a settings button. This will override the icon property. */
105+ isSettings ?: boolean ;
106+ /** Flag indicating the button is a hamburger button. This will override the icon property. */
107+ isHamburger ?: boolean ;
108+ /** Adjusts and animates the hamburger icon to indicate what will happen upon clicking the button. */
109+ hamburgerVariant ?: 'expand' | 'collapse' ;
100110 /** @hide Forwarded ref */
101111 innerRef ?: React . Ref < any > ;
102112 /** Adds count number to button */
@@ -117,6 +127,10 @@ const ButtonBase: React.FunctionComponent<ButtonProps> = ({
117127 isAriaDisabled = false ,
118128 isLoading = null ,
119129 isDanger = false ,
130+ isExpanded,
131+ isSettings,
132+ isHamburger,
133+ hamburgerVariant,
120134 spinnerAriaValueText,
121135 spinnerAriaLabelledBy,
122136 spinnerAriaLabel,
@@ -140,10 +154,17 @@ const ButtonBase: React.FunctionComponent<ButtonProps> = ({
140154 countOptions,
141155 ...props
142156} : ButtonProps ) => {
143- if ( isFavorite && ! ariaLabel && ! props [ 'aria-labelledby' ] ) {
157+ if ( isHamburger && ! [ true , false ] . includes ( isExpanded ) ) {
144158 // eslint-disable-next-line no-console
145159 console . error (
146- 'Button: Each favorite button must have a unique accessible name provided via aria-label or aria-labelledby'
160+ 'Button: when the isHamburger property is passed in, you must also pass in a boolean value to the isExpanded property. It is expected that a hamburger button controls the expansion of other content.'
161+ ) ;
162+ }
163+ // TODO: Remove isSettings || isHamburger || isFavorite conditional in breaking change to throw this warning for any button that does not have children or aria name
164+ if ( ( isSettings || isHamburger || isFavorite ) && ! ariaLabel && ! children && ! props [ 'aria-labelledby' ] ) {
165+ // eslint-disable-next-line no-console
166+ console . error (
167+ 'Button: you must provide either visible text content or an accessible name via the aria-label or aria-labelledby properties.'
147168 ) ;
148169 }
149170
@@ -152,7 +173,7 @@ const ButtonBase: React.FunctionComponent<ButtonProps> = ({
152173 const isButtonElement = Component === 'button' ;
153174 const isInlineSpan = isInline && Component === 'span' ;
154175 const isIconAlignedAtEnd = iconPosition === 'end' || iconPosition === 'right' ;
155- const shouldOverrideIcon = isFavorite ;
176+ const shouldOverrideIcon = isSettings || isHamburger || isFavorite ;
156177
157178 const preventedEvents = inoperableEvents . reduce (
158179 ( handlers , eventToPrevent ) => ( {
@@ -190,6 +211,12 @@ const ButtonBase: React.FunctionComponent<ButtonProps> = ({
190211 ) ;
191212 }
192213
214+ if ( isSettings ) {
215+ iconContent = < CogIcon /> ;
216+ }
217+ if ( isHamburger ) {
218+ iconContent = hamburgerIcon ;
219+ }
193220 if ( icon && ! shouldOverrideIcon ) {
194221 iconContent = icon ;
195222 }
@@ -202,21 +229,24 @@ const ButtonBase: React.FunctionComponent<ButtonProps> = ({
202229 )
203230 ) ;
204231 } ;
205-
206232 const _icon = renderIcon ( ) ;
207233 const _children = children && < span className = { css ( 'pf-v6-c-button__text' ) } > { children } </ span > ;
208234 // We only want to render the aria-disabled attribute when true, similar to the disabled attribute natively.
209235 const shouldRenderAriaDisabled = isAriaDisabled || ( ! isButtonElement && isDisabled ) ;
210236
211237 return (
212238 < Component
239+ aria-expanded = { isExpanded } // Move this after the spread props in next breaking change
213240 { ...props }
214241 { ...( isAriaDisabled ? preventedEvents : null ) }
215242 { ...( shouldRenderAriaDisabled && { 'aria-disabled' : true } ) }
216243 aria-label = { ariaLabel }
217244 className = { css (
218245 styles . button ,
219246 styles . modifiers [ variant ] ,
247+ isSettings && styles . modifiers . settings ,
248+ isHamburger && styles . modifiers . hamburger ,
249+ isHamburger && hamburgerVariant && styles . modifiers [ hamburgerVariant ] ,
220250 isBlock && styles . modifiers . block ,
221251 isDisabled && ! isButtonElement && styles . modifiers . disabled ,
222252 isAriaDisabled && styles . modifiers . ariaDisabled ,
0 commit comments