Skip to content

Commit

Permalink
docs(v8 Picker): Add wrapped text example and information about trunc…
Browse files Browse the repository at this point in the history
…ation in the docs (#33238)
  • Loading branch information
emmayjiang authored Nov 8, 2024
1 parent f429fc5 commit 027ab04
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 0 deletions.
8 changes: 8 additions & 0 deletions packages/react-examples/src/react/Pickers/Pickers.doc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { TagPickerCustomRemoveIconExample } from './TagPicker.CustomRemoveIcon.E
import { IDocPageProps } from '@fluentui/react/lib/common/DocPage.types';
import { TagPickerBasicExample } from './TagPicker.Basic.Example';
import { TagPickerInlineExample } from './TagPicker.Inline.Example';
import { TagPickerWrappedExample } from './TagPicker.Wrapped.Example';

const TagPickerExampleCode =
require('!raw-loader?esModule=false!@fluentui/react-examples/src/react/Pickers/TagPicker.Basic.Example.tsx') as string;
Expand All @@ -14,6 +15,8 @@ const PickerCustomResultExampleCode =
require('!raw-loader?esModule=false!@fluentui/react-examples/src/react/Pickers/Picker.CustomResult.Example.tsx') as string;
const TagPickerCustomRemoveIconExampleCode =
require('!raw-loader?esModule=false!@fluentui/react-examples/src/react/Pickers/TagPicker.CustomRemoveIcon.Example.tsx') as string;
const TagPickerWrappedExampleCode =
require('!raw-loader?esModule=false!@fluentui/react-examples/src/react/Pickers/TagPicker.Wrapped.Example.tsx') as string;

export const PickersPageProps: IDocPageProps = {
title: 'Pickers',
Expand All @@ -40,6 +43,11 @@ export const PickersPageProps: IDocPageProps = {
code: TagPickerCustomRemoveIconExampleCode,
view: <TagPickerCustomRemoveIconExample />,
},
{
title: 'Tag Picker with wrapped text',
code: TagPickerWrappedExampleCode,
view: <TagPickerWrappedExample />,
},
],
overview: require<string>('!raw-loader?esModule=false!@fluentui/react-examples/src/react/Pickers/docs/PickersOverview.md'),
bestPractices: require<string>('!raw-loader?esModule=false!@fluentui/react-examples/src/react/Pickers/docs/PickersBestPractices.md'),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import * as React from 'react';

import {
TagPicker,
IBasePicker,
ITag,
IInputProps,
IBasePickerSuggestionsProps,
TagItemSuggestion,
ITagItemSuggestionStyles,
} from '@fluentui/react/lib/Pickers';
import { mergeStyles } from '@fluentui/react/lib/Styling';
import { useId } from '@fluentui/react-hooks';

const rootClass = mergeStyles({
maxWidth: 500,
});

const inputProps: IInputProps = {
onBlur: (ev: React.FocusEvent<HTMLInputElement>) => console.log('onBlur called'),
onFocus: (ev: React.FocusEvent<HTMLInputElement>) => console.log('onFocus called'),
};

const pickerSuggestionsProps: IBasePickerSuggestionsProps = {
suggestionsHeaderText: 'Suggested tags',
noResultsFoundText: 'No tags found',
};

const testTags: ITag[] = [
'A short tag',
'A very long tag that spans more than the entire width of the picker and forces the text to wrap',
'A second very long tag that spans more than the entire width of the picker and forces the text to wrap',
'A third very long tag that spans more than the entire width of the picker and forces the text to wrap',
].map(item => ({ key: item, name: item }));

const filterSelectedTags = (filterText: string, tagList: ITag[]): ITag[] => {
return filterText ? testTags.filter(tag => tag.name.toLowerCase().indexOf(filterText.toLowerCase()) === 0) : [];
};

const getTextFromItem = (item: ITag) => item.name;

const tagStyles: Partial<ITagItemSuggestionStyles> = {
suggestionTextOverflow: {
height: 'auto',
whiteSpace: 'normal',
maxWidth: 500,
},
};

const onRenderSuggestionItem = (props: ITag) => {
return <TagItemSuggestion styles={tagStyles}>{props.name}</TagItemSuggestion>;
};

export const TagPickerWrappedExample: React.FunctionComponent = () => {
const pickerId = useId('wrapped-picker');
const picker = React.useRef<IBasePicker<ITag>>(null);

return (
<div className={rootClass}>
<label htmlFor={pickerId}>Choose a tag</label>
<TagPicker
onRenderSuggestionsItem={onRenderSuggestionItem}
removeButtonAriaLabel="Remove"
selectionAriaLabel="Selected tags"
componentRef={picker}
onResolveSuggestions={filterSelectedTags}
getTextFromItem={getTextFromItem}
pickerSuggestionsProps={pickerSuggestionsProps}
inputProps={{
...inputProps,
id: pickerId,
}}
/>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,9 @@ Picker dropdowns render in their own layer by default to ensure they are not cli
```js
pickerCalloutProps={{ doNotLayer: true }}
```

#### Truncation

By default, the Picker truncates item text in the dropdown instead of wrapping to a new line. To avoid losing meaningful information, adjusting styles to wrap the text is recommended. Tooltips are not shown for truncated text within the dropdown to avoid nested popups and the usability and accessibility issues they cause.

The Wrapped Picker example demonstrates how to override truncation styles to support wrapping. The default style will continue to truncate to support existing implementations.
2 changes: 2 additions & 0 deletions packages/react-examples/src/react/Pickers/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export { TagPickerCustomRemoveIconExample as TagPickerCustomRemoveIcon } from '.

export { TagPickerInlineExample as TagPickerInline } from './TagPicker.Inline.Example';

export { TagPickerWrappedExample as TagPickerWrapped } from './TagPicker.Wrapped.Example';

export default {
title: 'Components/Pickers',
};

0 comments on commit 027ab04

Please sign in to comment.