import * as React from 'react'; import { IPersonaProps } from '@fluentui/react/lib/Persona'; import { ExtendedPeoplePicker } from '@fluentui/react/lib/ExtendedPicker'; import { PrimaryButton } from '@fluentui/react/lib/Button'; import { SuggestionsStore, FloatingPeoplePicker } from '@fluentui/react/lib/FloatingPicker'; import { SelectedPeopleList, IExtendedPersonaProps } from '@fluentui/react/lib/SelectedItemsList'; import { FocusZoneTabbableElements } from '@fluentui/react/lib/FocusZone'; import { mergeStyleSets, getTheme } from '@fluentui/react/lib/Styling'; import { people, mru, groupOne, groupTwo } from '@fluentui/example-data'; import { useConst } from '@fluentui/react-hooks'; const theme = getTheme(); const startsWith = (text: string, filterText: string): boolean => { return text.toLowerCase().indexOf(filterText.toLowerCase()) === 0; }; const classNames = mergeStyleSets({ picker: { maxWidth: 400, marginBottom: 15 }, headerItem: { borderBottom: '1px solid ' + theme.palette.neutralLight, padding: '8px 12px', }, footerItem: { borderBottom: '1px solid ' + theme.palette.neutralLight, height: 60, paddingLeft: 12, }, to: { padding: '0 10px' }, }); const focusZoneProps = { shouldInputLoseFocusOnArrowKey: () => true, handleTabKey: FocusZoneTabbableElements.all, }; export const ExtendedPeoplePickerBasicExample: React.FunctionComponent = () => { const picker = React.useRef(null); const [peopleList, setPeopleList] = React.useState(people); const [mostRecentlyUsed, setMostRecentlyUsed] = React.useState(mru); const [searchMoreAvailable, setSearchMoreAvailable] = React.useState(true); const getEditingItemText = (item: IExtendedPersonaProps): string => { return item.text as string; }; const onSetFocusButtonClicked = React.useCallback((): void => { picker.current?.focus(); }, []); const onExpandItem = (item: IExtendedPersonaProps): void => { const selectedItemsList = picker.current?.selectedItemsList.current; if (selectedItemsList) { (selectedItemsList as SelectedPeopleList).replaceItem(item, getExpandedGroupItems(item)); } }; const onRemoveSuggestion = (item: IPersonaProps): void => { const itemIndex = peopleList.indexOf(item); const itemMruIndex = mostRecentlyUsed.indexOf(item); if (itemIndex >= 0) { setPeopleList(peopleList.slice(0, itemIndex).concat(peopleList.slice(itemIndex + 1))); } if (itemMruIndex >= 0) { setMostRecentlyUsed(mostRecentlyUsed.slice(0, itemMruIndex).concat(mostRecentlyUsed.slice(itemMruIndex + 1))); } }; const onFilterChanged = (filterText: string, currentPersonas?: IPersonaProps[]): Promise | null => { let filteredPersonas: IPersonaProps[] = []; if (filterText) { filteredPersonas = peopleList.filter((item: IPersonaProps) => startsWith(item.text || '', filterText)); filteredPersonas = removeDuplicates(filteredPersonas, currentPersonas); } return convertResultsToPromise(filteredPersonas); }; const returnMostRecentlyUsed = (): IPersonaProps[] | Promise | null => { let currentMostRecentlyUsed = mostRecentlyUsed; const items = picker.current?.items || []; currentMostRecentlyUsed = removeDuplicates(currentMostRecentlyUsed, items); return convertResultsToPromise(currentMostRecentlyUsed); }; const onCopyItems = (items: IExtendedPersonaProps[]): string => { return items.map(item => item.text).join(', '); }; const shouldShowForceResolve = (): boolean => { const floatingPicker = picker.current?.floatingPicker.current; return !!floatingPicker && validateInput(floatingPicker.inputText) && floatingPicker.suggestions.length === 0; }; const shouldShowSuggestedContacts = (): boolean => { return picker.current?.inputElement?.value === ''; }; const listContainsPersona = (persona: IPersonaProps, personas?: IPersonaProps[]): boolean => { return !!personas && personas.some((item: IPersonaProps) => item.text === persona.text); }; const removeDuplicates = (personas: IPersonaProps[], possibleDupes?: IPersonaProps[]): IPersonaProps[] => { return personas.filter((persona: IPersonaProps) => !listContainsPersona(persona, possibleDupes)); }; const onInputChanged = (): void => { setSearchMoreAvailable(true); }; const convertResultsToPromise = (results: IPersonaProps[]): Promise => { return new Promise(resolve => setTimeout(() => resolve(results), 150)); }; const validateInput = (input: string): boolean => { return input.indexOf('@') !== -1; }; const getExpandedGroupItems = (item: IExtendedPersonaProps): IExtendedPersonaProps[] => { return item.text === 'Group One' ? groupOne : item.text === 'Group Two' ? groupTwo : []; }; const suggestionProps = useConst({ showRemoveButtons: true, headerItemsProps: [ { renderItem: () => { return (
Use this address: {picker.current?.inputElement?.value || ''}
); }, shouldShow: () => { return !!picker.current?.inputElement && picker.current.inputElement.value.indexOf('@') > -1; }, onExecute: () => { const floatingPicker = picker.current?.floatingPicker.current; if (floatingPicker) { floatingPicker.forceResolveSuggestion(); } }, ariaLabel: 'Use the typed address', }, { renderItem: () => { return
Suggested Contacts
; }, shouldShow: shouldShowSuggestedContacts, }, ], footerItemsProps: [ { renderItem: () => { return
No results
; }, shouldShow: () => { const floatingPicker = picker.current?.floatingPicker.current; return !!floatingPicker && floatingPicker.suggestions.length === 0; }, }, { renderItem: () => { return
Search for more
; }, onExecute: () => { setSearchMoreAvailable(false); }, shouldShow: () => { return searchMoreAvailable && !shouldShowSuggestedContacts(); }, ariaLabel: 'Search more', }, ], shouldSelectFirstItem: () => { return !shouldShowSuggestedContacts(); }, }); const floatingPickerProps = { suggestionsStore: new SuggestionsStore(), onResolveSuggestions: onFilterChanged, getTextFromItem: (persona: IPersonaProps) => persona.text || '', pickerSuggestionsProps: suggestionProps, key: 'normal', onRemoveSuggestion: onRemoveSuggestion, onValidateInput: validateInput, onZeroQuerySuggestion: returnMostRecentlyUsed, showForceResolve: shouldShowForceResolve, onInputChanged: onInputChanged, onSuggestionsHidden: () => { console.log('FLOATINGPICKER: hidden'); }, onSuggestionsShown: () => { console.log('FLOATINGPICKER: shown'); }, }; const selectedItemsListProps = { onCopyItems: onCopyItems, onExpandGroup: onExpandItem, removeMenuItemText: 'Remove', copyMenuItemText: 'Copy name', editMenuItemText: 'Edit', getEditingItemText: getEditingItemText, onRenderFloatingPicker: FloatingPeoplePicker, floatingPickerProps: floatingPickerProps, }; return (
console.log('onBlur called'), onFocus: () => console.log('onFocus called'), 'aria-label': 'People Picker', }} componentRef={picker} headerComponent={
To:
} focusZoneProps={focusZoneProps} />
); };