@@ -164,7 +158,7 @@ exports[`Component Examples renders PeoplePicker.List.Example.tsx correctly 1`]
outline: 1px solid WindowText;
}
data-ktp-execute-target={true}
- id="checkbox-2"
+ id="checkbox-1"
onChange={[Function]}
type="checkbox"
/>
@@ -192,7 +186,7 @@ exports[`Component Examples renders PeoplePicker.List.Example.tsx correctly 1`]
right: 0px;
top: 0px;
}
- htmlFor="checkbox-2"
+ htmlFor="checkbox-1"
>
@@ -351,7 +345,7 @@ exports[`Component Examples renders PeoplePicker.List.Example.tsx correctly 1`]
right: 0px;
top: 0px;
}
- htmlFor="checkbox-3"
+ htmlFor="checkbox-2"
>
+
+ Selected contacts
+
-
-
-
+ }
+ value=""
+ />
@@ -162,7 +157,7 @@ exports[`Component Examples renders PeoplePicker.Normal.Example.tsx correctly 1`
outline: 1px solid WindowText;
}
data-ktp-execute-target={true}
- id="checkbox-2"
+ id="checkbox-1"
onChange={[Function]}
type="checkbox"
/>
@@ -190,7 +185,7 @@ exports[`Component Examples renders PeoplePicker.Normal.Example.tsx correctly 1`
right: 0px;
top: 0px;
}
- htmlFor="checkbox-2"
+ htmlFor="checkbox-1"
>
@@ -349,7 +344,7 @@ exports[`Component Examples renders PeoplePicker.Normal.Example.tsx correctly 1`
right: 0px;
top: 0px;
}
- htmlFor="checkbox-3"
+ htmlFor="checkbox-2"
>
+
+ Selected contacts
+
-
-
-
-
-
-
+
+
+
+
-
- Annie Lindqvist
-
+ Annie Lindqvist
+
+
-
- Designer
-
+ Designer
+
+
-
- In a meeting
-
+ In a meeting
+
+
-
- Available at 4:00pm
-
+ Available at 4:00pm
-
* {
- left: 0px;
- position: relative;
- top: 0px;
- }
- &:hover {
- background-color: #f3f2f1;
- background: #c8c6c4;
- color: #201f1e;
- }
- @media screen and (-ms-high-contrast: active), (forced-colors: active){&:hover {
- border-color: Highlight;
- color: Highlight;
- }
- &:active {
- background-color: #edebe9;
- color: #005a9e;
- }
- data-is-focusable={true}
- onClick={[Function]}
- onKeyDown={[Function]}
- onKeyPress={[Function]}
- onKeyUp={[Function]}
- onMouseDown={[Function]}
- onMouseUp={[Function]}
- type="button"
- >
-
-
-
-
-
-
-
* {
+ left: 0px;
+ position: relative;
+ top: 0px;
+ }
&:hover {
- background: #edebe9;
+ background-color: #f3f2f1;
+ background: #c8c6c4;
+ color: #201f1e;
}
- @media screen and (-ms-high-contrast: active), (forced-colors: active){& {
- border: 1px solid WindowText;
+ @media screen and (-ms-high-contrast: active), (forced-colors: active){&:hover {
+ border-color: Highlight;
+ color: Highlight;
+ }
+ &:active {
+ background-color: #edebe9;
+ color: #005a9e;
}
data-is-focusable={true}
- data-is-sub-focuszone={true}
- data-selection-index={1}
- role="listitem"
+ data-selection-index={0}
+ id="id__27"
+ onClick={[Function]}
+ onKeyDown={[Function]}
+ onKeyPress={[Function]}
+ onKeyUp={[Function]}
+ onMouseDown={[Function]}
+ onMouseUp={[Function]}
+ type="button"
+ >
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
- Aaron Reid
-
+ Aaron Reid
+
+
-
- Designer
-
+ Designer
+
+
-
- In a meeting
-
+ In a meeting
+
+
-
- Available at 4:00pm
-
+ Available at 4:00pm
-
* {
- left: 0px;
- position: relative;
- top: 0px;
- }
- &:hover {
- background-color: #f3f2f1;
- background: #c8c6c4;
- color: #201f1e;
- }
- @media screen and (-ms-high-contrast: active), (forced-colors: active){&:hover {
- border-color: Highlight;
- color: Highlight;
- }
- &:active {
- background-color: #edebe9;
- color: #005a9e;
- }
- data-is-focusable={true}
- onClick={[Function]}
- onKeyDown={[Function]}
- onKeyPress={[Function]}
- onKeyUp={[Function]}
- onMouseDown={[Function]}
- onMouseUp={[Function]}
- type="button"
- >
-
-
-
-
-
-
-
* {
+ left: 0px;
+ position: relative;
+ top: 0px;
+ }
&:hover {
- background: #edebe9;
+ background-color: #f3f2f1;
+ background: #c8c6c4;
+ color: #201f1e;
+ }
+ @media screen and (-ms-high-contrast: active), (forced-colors: active){&:hover {
+ border-color: Highlight;
+ color: Highlight;
}
- @media screen and (-ms-high-contrast: active), (forced-colors: active){& {
- border: 1px solid WindowText;
+ &:active {
+ background-color: #edebe9;
+ color: #005a9e;
}
data-is-focusable={true}
- data-is-sub-focuszone={true}
- data-selection-index={2}
- role="listitem"
+ data-selection-index={1}
+ id="id__28"
+ onClick={[Function]}
+ onKeyDown={[Function]}
+ onKeyPress={[Function]}
+ onKeyUp={[Function]}
+ onMouseDown={[Function]}
+ onMouseUp={[Function]}
+ type="button"
+ >
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
- Alex Lundberg
-
+ Alex Lundberg
+
+
-
- Software Developer
-
+ Software Developer
+
+
-
- In a meeting
-
+ In a meeting
+
+
-
- Available at 4:00pm
-
+ Available at 4:00pm
-
+ * {
+ left: 0px;
+ position: relative;
+ top: 0px;
+ }
+ &:hover {
+ background-color: #f3f2f1;
+ background: #c8c6c4;
+ color: #201f1e;
+ }
+ @media screen and (-ms-high-contrast: active), (forced-colors: active){&:hover {
+ border-color: Highlight;
+ color: Highlight;
+ }
+ &:active {
+ background-color: #edebe9;
+ color: #005a9e;
+ }
+ data-is-focusable={true}
+ data-selection-index={2}
+ id="id__29"
+ onClick={[Function]}
+ onKeyDown={[Function]}
+ onKeyPress={[Function]}
+ onKeyUp={[Function]}
+ onMouseDown={[Function]}
+ onMouseUp={[Function]}
+ type="button"
+ >
+ * {
- left: 0px;
- position: relative;
- top: 0px;
- }
- &:hover {
- background-color: #f3f2f1;
- background: #c8c6c4;
- color: #201f1e;
- }
- @media screen and (-ms-high-contrast: active), (forced-colors: active){&:hover {
- border-color: Highlight;
- color: Highlight;
- }
- &:active {
- background-color: #edebe9;
- color: #005a9e;
- }
- data-is-focusable={true}
- onClick={[Function]}
- onKeyDown={[Function]}
- onKeyPress={[Function]}
- onKeyUp={[Function]}
- onMouseDown={[Function]}
- onMouseUp={[Function]}
- type="button"
+ data-automationid="splitbuttonprimary"
>
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
+ }
+ value=""
+ />
@@ -1513,7 +1509,7 @@ exports[`Component Examples renders PeoplePicker.PreselectedItems.Example.tsx co
outline: 1px solid WindowText;
}
data-ktp-execute-target={true}
- id="checkbox-26"
+ id="checkbox-25"
onChange={[Function]}
type="checkbox"
/>
@@ -1541,7 +1537,7 @@ exports[`Component Examples renders PeoplePicker.PreselectedItems.Example.tsx co
right: 0px;
top: 0px;
}
- htmlFor="checkbox-26"
+ htmlFor="checkbox-25"
>
@@ -1700,7 +1696,7 @@ exports[`Component Examples renders PeoplePicker.PreselectedItems.Example.tsx co
right: 0px;
top: 0px;
}
- htmlFor="checkbox-27"
+ htmlFor="checkbox-26"
>
+
+ Selected contacts
+
-
-
-
+ }
+ value=""
+ />
@@ -162,7 +157,7 @@ exports[`Component Examples renders PeoplePicker.ProcessSelection.Example.tsx co
outline: 1px solid WindowText;
}
data-ktp-execute-target={true}
- id="checkbox-2"
+ id="checkbox-1"
onChange={[Function]}
type="checkbox"
/>
@@ -190,7 +185,7 @@ exports[`Component Examples renders PeoplePicker.ProcessSelection.Example.tsx co
right: 0px;
top: 0px;
}
- htmlFor="checkbox-2"
+ htmlFor="checkbox-1"
>
@@ -349,7 +344,7 @@ exports[`Component Examples renders PeoplePicker.ProcessSelection.Example.tsx co
right: 0px;
top: 0px;
}
- htmlFor="checkbox-3"
+ htmlFor="checkbox-2"
>
+
+ Selected colors
+
-
-
-
+ }
+ value=""
+ />
@@ -256,102 +251,97 @@ exports[`Component Examples renders TagPicker.Basic.Example.tsx correctly 1`] =
+
+ Selected colors
+
-
-
-
+ }
+ value=""
+ />
diff --git a/packages/react/etc/react.api.md b/packages/react/etc/react.api.md
index 95e8234b83bac..a25b62b23ada1 100644
--- a/packages/react/etc/react.api.md
+++ b/packages/react/etc/react.api.md
@@ -17,7 +17,6 @@ import { ICSSPixelUnitRule } from '@fluentui/merge-styles/lib/IRawStyleBase';
import { ICSSRule } from '@fluentui/merge-styles/lib/IRawStyleBase';
import { IDateFormatting } from '@fluentui/date-time-utilities';
import { IDayGridOptions } from '@fluentui/date-time-utilities';
-import { IFocusZone } from '@fluentui/react-focus';
import { IFocusZoneProps } from '@fluentui/react-focus';
import { IFontStyles } from '@fluentui/style-utilities';
import { IHTMLSlot } from '@fluentui/foundation-legacy';
@@ -310,8 +309,6 @@ export class BasePicker> extends React.Componen
// (undocumented)
focusInput(): void;
// (undocumented)
- protected focusZone: React.RefObject;
- // (undocumented)
protected getActiveDescendant(): string | undefined;
// (undocumented)
static getDerivedStateFromProps(newProps: IBasePickerProps): {
@@ -332,6 +329,8 @@ export class BasePicker> extends React.Componen
protected onClick: (ev: React.MouseEvent) => void;
protected onEmptyInputFocus(): void;
// (undocumented)
+ protected onFocus: () => void;
+ // (undocumented)
protected onGetMoreResults: () => void;
// (undocumented)
protected onInputBlur: (ev: React.FocusEvent) => void;
@@ -371,7 +370,7 @@ export class BasePicker> extends React.Componen
protected root: React.RefObject;
// (undocumented)
protected selection: Selection;
- // (undocumented)
+ // @deprecated (undocumented)
protected _shouldFocusZoneEnterInnerZone: (ev: React.KeyboardEvent) => boolean;
// (undocumented)
protected suggestionElement: React.RefObject>;
@@ -1587,6 +1586,8 @@ export interface IBasePickerProps extends React.Props {
input: string;
}) => string) | string;
selectedItems?: T[];
+ selectionAriaLabel?: string;
+ selectionRole?: string;
styles?: IStyleFunctionOrObject;
theme?: ITheme;
}
diff --git a/packages/react/src/components/pickers/BasePicker.test.tsx b/packages/react/src/components/pickers/BasePicker.test.tsx
index ceb81aca15562..b3fba02eb950b 100644
--- a/packages/react/src/components/pickers/BasePicker.test.tsx
+++ b/packages/react/src/components/pickers/BasePicker.test.tsx
@@ -527,4 +527,91 @@ describe('BasePicker', () => {
expect(moreButton.id).toEqual('sug-selectedAction');
expect(input.getAttribute('aria-activedescendant')).toEqual('sug-selectedAction');
});
+
+ it('focuses the input when the focus method is called', () => {
+ document.body.appendChild(root);
+
+ const picker = React.createRef>();
+
+ ReactDOM.render(
+ ,
+ root,
+ );
+
+ const input = document.querySelector('.ms-BasePicker-input') as HTMLInputElement;
+ picker.current?.focus();
+
+ expect(document.activeElement).toBe(input);
+ });
+
+ it('focuses the last selected item after removing input', () => {
+ jest.useFakeTimers();
+ document.body.appendChild(root);
+
+ const onRenderFocusableItem = (props: IPickerItemProps): JSX.Element => (
+
+ {basicRenderer(props)}
+
+ );
+ ReactDOM.render(
+ ,
+ root,
+ );
+
+ const input = document.querySelector('.ms-BasePicker-input') as HTMLInputElement;
+ input.focus();
+ input.value = 'bl';
+ ReactTestUtils.Simulate.input(input);
+ runAllTimers();
+
+ const suggestionOptions = document.querySelectorAll('.ms-Suggestions-itemButton');
+ ReactTestUtils.Simulate.click(suggestionOptions[0]);
+
+ const selectedItem = document.querySelector('button[data-selection-index]');
+
+ expect(document.activeElement).toBe(selectedItem);
+ });
+
+ it('focuses the next selected item after removing a selection', () => {
+ jest.useFakeTimers();
+ document.body.appendChild(root);
+
+ const onRenderFocusableItem = (props: IPickerItemProps): JSX.Element => {
+ return (
+
+ {basicRenderer(props)}
+
+ );
+ };
+ ReactDOM.render(
+ ,
+ root,
+ );
+
+ const selectedEls = document.querySelectorAll('button[data-selection-index]');
+ (selectedEls[0] as HTMLButtonElement).focus();
+ ReactTestUtils.Simulate.click(selectedEls[0]);
+
+ jest.runAllTimers();
+
+ expect(document.activeElement).toBe(selectedEls[1]);
+ });
});
diff --git a/packages/react/src/components/pickers/BasePicker.tsx b/packages/react/src/components/pickers/BasePicker.tsx
index ffd04593e156e..77f60d607dff2 100644
--- a/packages/react/src/components/pickers/BasePicker.tsx
+++ b/packages/react/src/components/pickers/BasePicker.tsx
@@ -10,7 +10,6 @@ import {
initializeComponentRef,
} from '../../Utilities';
import { IProcessedStyleSet } from '../../Styling';
-import { IFocusZone, FocusZone, FocusZoneDirection } from '../../FocusZone';
import { Callout } from '../../Callout';
import { Selection, SelectionZone, SelectionMode } from '../../utilities/selection/index';
import { DirectionalHint } from '../../common/DirectionalHint';
@@ -95,7 +94,6 @@ export class BasePicker> extends React.Componen
// Refs
protected root = React.createRef();
protected input = React.createRef();
- protected focusZone = React.createRef();
protected suggestionElement = React.createRef>();
protected selection: Selection;
@@ -167,6 +165,10 @@ export class BasePicker> extends React.Componen
this.selection.setIndexSelected(currentSelectedIndex, false, true);
this.resetFocus(currentSelectedIndex);
}
+ // Reset focus to last item if the input is removed
+ else if (this.state.items.length > oldState.items.length && !this.canAddItems()) {
+ this.resetFocus(this.state.items.length - 1);
+ }
}
}
}
@@ -179,8 +181,8 @@ export class BasePicker> extends React.Componen
}
public focus() {
- if (this.focusZone.current) {
- this.focusZone.current.focus();
+ if (this.input.current) {
+ this.input.current.focus();
}
}
@@ -243,7 +245,7 @@ export class BasePicker> extends React.Componen
public render(): JSX.Element {
const { suggestedDisplayValue, isFocused, items } = this.state;
- const { className, inputProps, disabled, theme, styles } = this.props;
+ const { className, inputProps, disabled, selectionAriaLabel, selectionRole = 'list', theme, styles } = this.props;
const suggestionsAvailable = this.state.suggestionsVisible ? this._ariaMap.suggestionList : '';
// TODO
// Clean this up by leaving only the first part after removing support for SASS.
@@ -270,47 +272,61 @@ export class BasePicker> extends React.Componen
screenReaderText: legacyStyles.screenReaderOnly,
};
+ const comboLabel = this.props['aria-label'] || inputProps?.['aria-label'];
+
+ // selectionAriaLabel is contained in a separate rather than an aria-label on the items list
+ // because if the items list has an aria-label, the aria-describedby on the input will only read
+ // that label instead of all the selected items. Using aria-labelledby instead fixes this, since
+ // aria-describedby and aria-labelledby will not follow a second aria-labelledby
return (
-
-
- {this.getSuggestionsAlert(classNames.screenReaderText)}
-
-
- {items.length > 0 && (
-
- {this.renderItems()}
-
- )}
- {this.canAddItems() && (
-
0 ? this._ariaMap.selectedItems : undefined}
- aria-expanded={!!this.state.suggestionsVisible}
- aria-haspopup="listbox"
- aria-label={this.props['aria-label'] || inputProps?.['aria-label']}
- role="combobox"
- disabled={disabled}
- onInputChange={this.props.onInputChange}
- />
- )}
-
-
-
+
+ {this.getSuggestionsAlert(classNames.screenReaderText)}
+
+ {selectionAriaLabel || comboLabel}
+
+
+
+ {items.length > 0 && (
+
+ {this.renderItems()}
+
+ )}
+ {this.canAddItems() && (
+
0 ? this._ariaMap.selectedItems : undefined}
+ aria-expanded={!!this.state.suggestionsVisible}
+ aria-haspopup="listbox"
+ aria-label={comboLabel}
+ role="combobox"
+ disabled={disabled}
+ onInputChange={this.props.onInputChange}
+ />
+ )}
+
+
{this.renderSuggestions()}
);
@@ -386,8 +402,8 @@ export class BasePicker
> extends React.Componen
(this.root.current.querySelectorAll('[data-selection-index]')[
Math.min(index!, items.length - 1)
] as HTMLElement | null);
- if (newEl && this.focusZone.current) {
- this.focusZone.current.focusElement(newEl);
+ if (newEl) {
+ newEl.focus();
}
} else if (!this.canAddItems()) {
this.resetFocus(items.length - 1);
@@ -533,8 +549,6 @@ export class BasePicker> extends React.Componen
// For example when an item is selected or removed from the selected list it should be treated
// as though the input is still focused.
if (!this.state.isFocused) {
- this.setState({ isFocused: true });
-
this._userTriggeredSuggestions();
if (this.props.inputProps && this.props.inputProps.onFocus) {
@@ -590,6 +604,12 @@ export class BasePicker> extends React.Componen
}
};
+ protected onFocus = () => {
+ if (!this.state.isFocused) {
+ this.setState({ isFocused: true });
+ }
+ };
+
protected onKeyDown = (ev: React.KeyboardEvent): void => {
// eslint-disable-next-line deprecation/deprecation
const keyCode = ev.which;
@@ -826,6 +846,9 @@ export class BasePicker> extends React.Componen
}
}
+ /**
+ * @deprecated this is no longer necessary as focuszone has been removed
+ */
protected _shouldFocusZoneEnterInnerZone = (ev: React.KeyboardEvent): boolean => {
// If suggestions are shown const up/down keys control them, otherwise allow them through to control the focusZone.
if (this.state.suggestionsVisible) {
@@ -987,7 +1010,7 @@ export class BasePicker> extends React.Componen
export class BasePickerListBelow> extends BasePicker {
public render(): JSX.Element {
const { suggestedDisplayValue, isFocused } = this.state;
- const { className, inputProps, disabled, theme, styles } = this.props;
+ const { className, inputProps, disabled, selectionAriaLabel, selectionRole = 'list', theme, styles } = this.props;
const suggestionsAvailable: string | undefined = this.state.suggestionsVisible ? this._ariaMap.suggestionList : '';
// TODO
@@ -1018,8 +1041,11 @@ export class BasePickerListBelow> extends BaseP
input: css('ms-BasePicker-input', legacyStyles.pickerInput, inputProps && inputProps.className),
screenReaderText: legacyStyles.screenReaderOnly,
};
+
+ const comboLabel = this.props['aria-label'] || inputProps?.['aria-label'];
+
return (
-
+
{this.getSuggestionsAlert(classNames.screenReaderText)}
@@ -1036,7 +1062,9 @@ export class BasePickerListBelow> extends BaseP
aria-controls={suggestionsAvailable || undefined}
aria-expanded={!!this.state.suggestionsVisible}
aria-haspopup="listbox"
+ aria-label={comboLabel}
role="combobox"
+ id={inputProps?.id ? inputProps.id : this._ariaMap.combobox}
disabled={disabled}
onInputChange={this.props.onInputChange}
/>
@@ -1044,17 +1072,14 @@ export class BasePickerListBelow> extends BaseP
{this.renderSuggestions()}
-
{this.renderItems()}
-
+
);
diff --git a/packages/react/src/components/pickers/BasePicker.types.ts b/packages/react/src/components/pickers/BasePicker.types.ts
index 8675614050a0c..f898fde92f1ef 100644
--- a/packages/react/src/components/pickers/BasePicker.types.ts
+++ b/packages/react/src/components/pickers/BasePicker.types.ts
@@ -192,6 +192,20 @@ export interface IBasePickerProps
extends React.Props {
*/
selectedItems?: T[];
+ /**
+ * Aria label for the displayed selection. A good value would be something like "Selected Contacts".
+ * @defaultvalue ''
+ */
+ selectionAriaLabel?: string;
+
+ /**
+ * Override the role used for the element containing selected items.
+ * Update this if onRenderItem does not return elements with role="listitem".
+ * A good alternative would be 'group'.
+ * @defaultvalue 'list'
+ */
+ selectionRole?: string;
+
/**
* A callback used to modify the input string.
*/
diff --git a/packages/react/src/components/pickers/PeoplePicker/PeoplePickerItems/PeoplePickerItem.tsx b/packages/react/src/components/pickers/PeoplePicker/PeoplePickerItems/PeoplePickerItem.tsx
index 9dfcfc927f3e9..996b536d7947c 100644
--- a/packages/react/src/components/pickers/PeoplePicker/PeoplePickerItems/PeoplePickerItem.tsx
+++ b/packages/react/src/components/pickers/PeoplePicker/PeoplePickerItems/PeoplePickerItem.tsx
@@ -42,23 +42,19 @@ export const PeoplePickerItemBase = (props: IPeoplePickerItemSelectedProps) => {
: undefined;
return (
-
+
);
diff --git a/packages/react/src/components/pickers/PeoplePicker/__snapshots__/PeoplePicker.test.tsx.snap b/packages/react/src/components/pickers/PeoplePicker/__snapshots__/PeoplePicker.test.tsx.snap
index 345b91314b625..6f3cb93a98249 100644
--- a/packages/react/src/components/pickers/PeoplePicker/__snapshots__/PeoplePicker.test.tsx.snap
+++ b/packages/react/src/components/pickers/PeoplePicker/__snapshots__/PeoplePicker.test.tsx.snap
@@ -4,101 +4,94 @@ exports[`PeoplePicker renders correctly 1`] = `
+
-
-
-
+ }
+ value=""
+ />
@@ -108,560 +101,553 @@ exports[`PeoplePicker renders correctly with preselected items 1`] = `
+
-
-
-
-
-
-
+
+
+
+
-
- Annie Lindqvist
-
+ Annie Lindqvist
+
+
-
- Designer
-
+ Designer
+
+
-
- In a meeting
-
+ In a meeting
+
+
-
- Available at 4:00pm
-
+ Available at 4:00pm
-
+ * {
+ left: 0px;
+ position: relative;
+ top: 0px;
+ }
+ &:hover {
+ background-color: #f3f2f1;
+ background: #c8c6c4;
+ color: #201f1e;
+ }
+ @media screen and (-ms-high-contrast: active), (forced-colors: active){&:hover {
+ border-color: Highlight;
+ color: Highlight;
+ }
+ &:active {
+ background-color: #edebe9;
+ color: #005a9e;
+ }
+ data-is-focusable={true}
+ data-selection-index={0}
+ id="id__9"
+ onClick={[Function]}
+ onKeyDown={[Function]}
+ onKeyPress={[Function]}
+ onKeyUp={[Function]}
+ onMouseDown={[Function]}
+ onMouseUp={[Function]}
+ type="button"
+ >
+ * {
- left: 0px;
- position: relative;
- top: 0px;
- }
- &:hover {
- background-color: #f3f2f1;
- background: #c8c6c4;
- color: #201f1e;
- }
- @media screen and (-ms-high-contrast: active), (forced-colors: active){&:hover {
- border-color: Highlight;
- color: Highlight;
- }
- &:active {
- background-color: #edebe9;
- color: #005a9e;
- }
- data-is-focusable={true}
- onClick={[Function]}
- onKeyDown={[Function]}
- onKeyPress={[Function]}
- onKeyUp={[Function]}
- onMouseDown={[Function]}
- onMouseUp={[Function]}
- type="button"
+ data-automationid="splitbuttonprimary"
>
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
+ }
+ value=""
+ />
diff --git a/packages/react/src/components/pickers/TagPicker/TagItem.tsx b/packages/react/src/components/pickers/TagPicker/TagItem.tsx
index 13d3fbd81a332..3cae3bc68a882 100644
--- a/packages/react/src/components/pickers/TagPicker/TagItem.tsx
+++ b/packages/react/src/components/pickers/TagPicker/TagItem.tsx
@@ -5,6 +5,7 @@ import { IconButton } from '../../../Button';
import { ITagItemProps, ITagItemStyleProps, ITagItemStyles } from './TagPicker.types';
import { getStyles } from './TagItem.styles';
+import { useId } from '@fluentui/react-hooks';
const getClassNames = classNamesFunction
();
@@ -33,23 +34,31 @@ export const TagItemBase = (props: ITagItemProps) => {
disabled,
});
+ const itemId = useId();
+
+ const disabledAttrs = enableTagFocusInDisabledPicker
+ ? {
+ 'aria-disabled': disabled,
+ tabindex: 0,
+ }
+ : {
+ disabled: disabled,
+ };
+
return (
-
-
+
+
{children}
);
diff --git a/packages/react/src/components/pickers/TagPicker/__snapshots__/TagItem.test.tsx.snap b/packages/react/src/components/pickers/TagPicker/__snapshots__/TagItem.test.tsx.snap
index 95e20d712a8df..6b108b0916777 100644
--- a/packages/react/src/components/pickers/TagPicker/__snapshots__/TagItem.test.tsx.snap
+++ b/packages/react/src/components/pickers/TagPicker/__snapshots__/TagItem.test.tsx.snap
@@ -54,12 +54,9 @@ exports[`TagItem accepts title override 1`] = `
@media screen and (-ms-high-contrast: active), (forced-colors: active){& {
border: 1px solid WindowText;
}
- data-is-focusable={true}
- data-selection-index={0}
role="listitem"
>
Red
Red color
+
-
-
-
+ black
+
+ * {
+ left: 0px;
+ position: relative;
+ top: 0px;
}
- &:hover .ms-TagItem-close {
+ &:hover {
+ background-color: #f3f2f1;
+ background: #e1dfdd;
color: #323130;
}
- @media screen and (-ms-high-contrast: active), (forced-colors: active){& {
- border: 1px solid WindowText;
+ @media screen and (-ms-high-contrast: active), (forced-colors: active){&:hover {
+ border-color: Highlight;
+ color: Highlight;
+ }
+ &:active {
+ background-color: #005a9e;
+ color: #ffffff;
}
data-is-focusable={true}
data-selection-index={0}
- role="listitem"
+ id="id__1"
+ onClick={[Function]}
+ onKeyDown={[Function]}
+ onKeyPress={[Function]}
+ onKeyUp={[Function]}
+ onMouseDown={[Function]}
+ onMouseUp={[Function]}
+ type="button"
>
- black
-
- * {
- left: 0px;
- position: relative;
- top: 0px;
- }
- &:hover {
- background-color: #f3f2f1;
- background: #e1dfdd;
- color: #323130;
- }
- @media screen and (-ms-high-contrast: active), (forced-colors: active){&:hover {
- border-color: Highlight;
- color: Highlight;
- }
- &:active {
- background-color: #005a9e;
- color: #ffffff;
- }
- data-is-focusable={true}
- onClick={[Function]}
- onKeyDown={[Function]}
- onKeyPress={[Function]}
- onKeyUp={[Function]}
- onMouseDown={[Function]}
- onMouseUp={[Function]}
- type="button"
+ data-automationid="splitbuttonprimary"
>
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
+ }
+ value=""
+ />
@@ -316,309 +311,304 @@ exports[`TagPicker renders picker with selected item correctly 1`] = `
+
-
-
-
+ text
+
+ * {
+ left: 0px;
+ position: relative;
+ top: 0px;
}
- &:hover .ms-TagItem-close {
+ &:hover {
+ background-color: #f3f2f1;
+ background: #e1dfdd;
color: #323130;
}
- @media screen and (-ms-high-contrast: active), (forced-colors: active){& {
- border: 1px solid WindowText;
+ @media screen and (-ms-high-contrast: active), (forced-colors: active){&:hover {
+ border-color: Highlight;
+ color: Highlight;
+ }
+ &:active {
+ background-color: #005a9e;
+ color: #ffffff;
}
data-is-focusable={true}
data-selection-index={0}
- role="listitem"
+ id="id__1"
+ onClick={[Function]}
+ onKeyDown={[Function]}
+ onKeyPress={[Function]}
+ onKeyUp={[Function]}
+ onMouseDown={[Function]}
+ onMouseUp={[Function]}
+ type="button"
>
- text
-
- * {
- left: 0px;
- position: relative;
- top: 0px;
- }
- &:hover {
- background-color: #f3f2f1;
- background: #e1dfdd;
- color: #323130;
- }
- @media screen and (-ms-high-contrast: active), (forced-colors: active){&:hover {
- border-color: Highlight;
- color: Highlight;
- }
- &:active {
- background-color: #005a9e;
- color: #ffffff;
- }
- data-is-focusable={true}
- onClick={[Function]}
- onKeyDown={[Function]}
- onKeyPress={[Function]}
- onKeyUp={[Function]}
- onMouseDown={[Function]}
- onMouseUp={[Function]}
- type="button"
+ data-automationid="splitbuttonprimary"
>
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
+ }
+ value=""
+ />
diff --git a/packages/react/src/components/pickers/__snapshots__/BasePicker.test.tsx.snap b/packages/react/src/components/pickers/__snapshots__/BasePicker.test.tsx.snap
index 0847f85865c0a..9eb5aec8339a5 100644
--- a/packages/react/src/components/pickers/__snapshots__/BasePicker.test.tsx.snap
+++ b/packages/react/src/components/pickers/__snapshots__/BasePicker.test.tsx.snap
@@ -4,63 +4,56 @@ exports[`BasePicker renders correctly 1`] = `
+
-
-
-
+ }
+ value=""
+ />
@@ -70,64 +63,57 @@ exports[`BasePicker renders with inputProps supply classnames correctly 1`] = `
+
-
-
-
+ }
+ value=""
+ />