diff --git a/packages/fluentui/CHANGELOG.md b/packages/fluentui/CHANGELOG.md index e2f34094e8515..f30739a2dac60 100644 --- a/packages/fluentui/CHANGELOG.md +++ b/packages/fluentui/CHANGELOG.md @@ -30,6 +30,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - fix `Tooltip` constrast style for pointing and subtle=false @yuanboxue-amber ([#22696](https://github.com/microsoft/fluentui/pull/22696)) - Vertical menu background color should not change on focus in dark theme @yuanboxue-amber ([#22707](https://github.com/microsoft/fluentui/pull/22707)) - Align `default` scheme colors between v0 and v9 @jurokapsiar ([#22699](https://github.com/microsoft/fluentui/pull/22699)) +- Fix `Pill` to be selectable by keyboard @chpalac ([#22839](https://github.com/microsoft/fluentui/pull/22839)) ### Documentation - Use https for Embed and Video examples @Hirse ([#22738](https://github.com/microsoft/fluentui/pull/22738)) diff --git a/packages/fluentui/accessibility/src/behaviors/Pill/pillBehavior.ts b/packages/fluentui/accessibility/src/behaviors/Pill/pillBehavior.ts index 1f5a3dc54fa8b..1b9c4a4aa6c11 100644 --- a/packages/fluentui/accessibility/src/behaviors/Pill/pillBehavior.ts +++ b/packages/fluentui/accessibility/src/behaviors/Pill/pillBehavior.ts @@ -5,9 +5,9 @@ import { IS_FOCUSABLE_ATTRIBUTE } from '../../attributes'; export const pillBehavior: Accessibility = p => ({ attributes: { root: { - role: p.actionable ? 'button' : 'none', - tabIndex: p.actionable ? 0 : -1, - [IS_FOCUSABLE_ATTRIBUTE]: p.actionable || p.role === 'option', + role: p.actionable || p.selectable ? 'button' : 'none', + tabIndex: p.actionable || p.selectable ? 0 : -1, + [IS_FOCUSABLE_ATTRIBUTE]: p.actionable || p.selectable || p.role === 'option', ...(p.selectable && { 'aria-selected': p.selected, }), @@ -15,10 +15,12 @@ export const pillBehavior: Accessibility = p => ({ }, keyActions: { root: { - ...(p.actionable && { + ...(p.dismissible && { performDismiss: { keyCombinations: [{ keyCode: keyboardKey.Delete }, { keyCode: keyboardKey.Backspace }], }, + }), + ...((p.selectable || p.actionable) && { performClick: { keyCombinations: [{ keyCode: keyboardKey.Enter }, { keyCode: SpacebarKey }], }, @@ -32,4 +34,5 @@ export type PillBehaviorProps = { selectable: boolean; selected: boolean; role: AriaRole; + dismissible: boolean; }; diff --git a/packages/fluentui/react-northstar/src/components/Pill/Pill.tsx b/packages/fluentui/react-northstar/src/components/Pill/Pill.tsx index a61b7cfc4dd2a..179b0c0f0a7d0 100644 --- a/packages/fluentui/react-northstar/src/components/Pill/Pill.tsx +++ b/packages/fluentui/react-northstar/src/components/Pill/Pill.tsx @@ -2,7 +2,7 @@ import * as PropTypes from 'prop-types'; import * as React from 'react'; import * as customPropTypes from '@fluentui/react-proptypes'; import * as _ from 'lodash'; -import { Accessibility, pillBehavior, PillBehaviorProps } from '@fluentui/accessibility'; +import { Accessibility, AriaRole, pillBehavior, PillBehaviorProps } from '@fluentui/accessibility'; import { UIComponentProps, ContentComponentProps, commonPropTypes, SizeValue, createShorthand } from '../../utils'; import { ShorthandValue, FluentComponentStaticProps, ComponentEventHandler } from '../../types'; import { BoxProps } from '../Box/Box'; @@ -103,16 +103,20 @@ export interface PillProps extends UIComponentProps, ContentComponentProps; + + /** + * Role to be set in the pill root element + */ + role?: AriaRole; } export type PillStylesProps = Required< - Pick + Pick >; export const pillClassName = 'ui-pill'; /** - * THIS COMPONENT IS UNSTABLE * Pills should be used when representing an input, as a way to filter content, or to represent an attribute. */ export const Pill = (React.forwardRef((props, ref) => { @@ -139,6 +143,8 @@ export const Pill = (React.forwardRef((props, ref) = icon, selectable, selectedIndicator, + role, + onDismiss, } = props; const [selected, setSelected] = useAutoControlled({ @@ -172,6 +178,8 @@ export const Pill = (React.forwardRef((props, ref) = actionable, selectable, selected, + role, + dismissible: Boolean(onDismiss), }), rtl: context.rtl, }); @@ -185,6 +193,7 @@ export const Pill = (React.forwardRef((props, ref) = disabled, selectable, selected, + actionable, }), mapPropsToInlineStyles: () => ({ className, @@ -212,7 +221,7 @@ export const Pill = (React.forwardRef((props, ref) = {...getA11yProps('root', { className: classes.root, ref, - ...(actionable && { onClick: handleClick }), + ...((actionable || selectable) && { onClick: handleClick }), ...unhandledProps, })} > @@ -236,7 +245,7 @@ export const Pill = (React.forwardRef((props, ref) = actionable, }), })} - {actionable && + {Boolean(onDismiss) && createShorthand(PillAction, action || {}, { overrideProps: (prevProps: PillActionProps & { onClick: (e: React.MouseEvent) => void }) => ({ onClick: e => { @@ -255,6 +264,7 @@ export const Pill = (React.forwardRef((props, ref) = Pill.defaultProps = { as: 'span' as const, + accessibility: pillBehavior, }; Pill.propTypes = { diff --git a/packages/fluentui/react-northstar/src/themes/teams/components/Pill/pillStyles.ts b/packages/fluentui/react-northstar/src/themes/teams/components/Pill/pillStyles.ts index 6fca9cc0adc0a..b3fbab955e8f3 100644 --- a/packages/fluentui/react-northstar/src/themes/teams/components/Pill/pillStyles.ts +++ b/packages/fluentui/react-northstar/src/themes/teams/components/Pill/pillStyles.ts @@ -82,6 +82,10 @@ export const pillStyles: ComponentSlotStylesPrepared