Skip to content

Commit 9b0d4d1

Browse files
committed
Placeholder for ListItemPicker, ListPicker, and PeoplePicker, deprecation of placeHolder for ListPicker
1 parent 376b042 commit 9b0d4d1

File tree

10 files changed

+85
-40
lines changed

10 files changed

+85
-40
lines changed

docs/documentation/docs/controls/ListItemPicker.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,6 @@ The `ListItemPicker` control can be configured with the following properties:
6060
| noResultsFoundText | string | no | The text that should appear when no results are returned. |
6161
| disabled | boolean | no | Specifies if the control is disabled or not. |
6262
| filter | string | no | condition to filter list Item, same as $filter ODATA parameter|
63+
| placeholder | string | no | Short text hint to display in empty picker |
6364

6465
![](https://telemetry.sharepointpnp.com/sp-dev-fx-controls-react/wiki/controls/ListItemPicker)

docs/documentation/docs/controls/ListPicker.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ The `ListPicker` control can be configured with the following properties:
5959
| selectedList | string OR string[] | no | Keys of the selected item(s). If you provide this, you must maintain selection state by observing onSelectionChanged events and passing a new value in when changed. |
6060
| multiSelect | boolean | no | Optional mode indicates if multi-choice selections is allowed. Default to `false`. |
6161
| label | string | no | Label to use for the control. |
62+
| placeHolder | string | no | Placeholder label to show in the dropdown. **Deprecated. Use `placeholder` instead.** |
6263
| placeholder | string | no | Placeholder label to show in the dropdown. |
6364
| onSelectionChanged | (newValue: string OR string[]): void | no | Callback function when the selected option changes. |
6465

docs/documentation/docs/controls/PeoplePicker.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ The People picker control can be configured with the following properties:
7575
| ensureUser | boolean | no | When ensure user property is true, it will return the local user ID on the current site when doing a tenant wide search. | false |
7676
| suggestionsLimit | number | no | Maximum number of suggestions to show in the full suggestion list. | 5 |
7777
| resolveDelay | number | no | Add delay to resolve and search users | 200 |
78+
| placeholder | string | no | Short text hint to display in empty picker |
7879

7980
Enum `PrincipalType`
8081

src/controls/listItemPicker/IListItemPickerProps.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ export interface IListItemPickerProps {
1414
disabled?: boolean;
1515
suggestionsHeaderText?:string;
1616
noResultsFoundText?:string;
17+
/**
18+
* Placeholder to be displayed in an empty term picker
19+
*/
20+
placeholder?: string;
1721

1822
onSelectedItem: (item:any) => void;
1923
}

src/controls/listItemPicker/ListItemPicker.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export class ListItemPicker extends React.Component<IListItemPickerProps, IListI
4141
* Render the field
4242
*/
4343
public render(): React.ReactElement<IListItemPickerProps> {
44-
const { className, disabled, itemLimit } = this.props;
44+
const { className, disabled, itemLimit, placeholder } = this.props;
4545

4646
return (
4747
<div>
@@ -56,7 +56,10 @@ export class ListItemPicker extends React.Component<IListItemPickerProps, IListI
5656
onChange={this.onItemChanged}
5757
className={className}
5858
itemLimit={itemLimit}
59-
disabled={disabled} />
59+
disabled={disabled}
60+
inputProps={{
61+
placeholder: placeholder
62+
}} />
6063

6164
<Label style={{color:'#FF0000'}}> {this.state.errorMessage} </Label>
6265
</div>

src/controls/listPicker/IListPicker.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ export interface IListPickerProps {
4949
* Input placeholder text. Displayed until option is selected.
5050
*/
5151
placeHolder?: string;
52+
/**
53+
* Input placeholder text. Displayed until option is selected.
54+
*/
55+
placeholder?: string;
5256
/**
5357
* Callback issues when the selected option changes
5458
*/

src/controls/listPicker/ListPicker.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,14 @@ export class ListPicker extends React.Component<IListPickerProps, IListPickerSta
144144
*/
145145
public render(): JSX.Element {
146146
const { loading, options, selectedList } = this.state;
147-
const { className, disabled, multiSelect, label, placeHolder } = this.props;
147+
const { className, disabled, multiSelect, label, placeHolder, placeholder } = this.props;
148148

149149
const dropdownOptions: IDropdownProps = {
150150
className: className,
151151
options: options,
152152
disabled: ( loading || disabled ),
153153
label: label,
154-
placeHolder: placeHolder,
154+
placeHolder: placeholder || placeHolder,
155155
onChanged: this.onChanged
156156
};
157157

src/controls/peoplepicker/IPeoplePicker.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ export interface IPeoplePickerProps {
9494
* When ensure user property is true, it will return the local user ID on the current site when doing a tenant wide search
9595
*/
9696
ensureUser?: boolean;
97+
/**
98+
* Placeholder to be displayed in an empty term picker
99+
*/
100+
placeholder?: string;
97101
}
98102

99103
export interface IPeoplePickerState {

src/controls/peoplepicker/PeoplePickerComponent.tsx

Lines changed: 59 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ export class PeoplePicker extends React.Component<IPeoplePickerProps, IPeoplePic
5555
*/
5656
public componentWillUpdate(nextProps: IPeoplePickerProps, nextState: IPeoplePickerState): void {
5757
if (!isEqual(this.props.defaultSelectedUsers, nextProps.defaultSelectedUsers) ||
58-
this.props.groupName !== nextProps.groupName ||
59-
this.props.webAbsoluteUrl !== nextProps.webAbsoluteUrl ||
60-
this.peopleSearchService.getSumOfPrincipalTypes(this.props.principalTypes) !== this.peopleSearchService.getSumOfPrincipalTypes(nextProps.principalTypes)) {
58+
this.props.groupName !== nextProps.groupName ||
59+
this.props.webAbsoluteUrl !== nextProps.webAbsoluteUrl ||
60+
this.peopleSearchService.getSumOfPrincipalTypes(this.props.principalTypes) !== this.peopleSearchService.getSumOfPrincipalTypes(nextProps.principalTypes)) {
6161
this.getInitialPersons(nextProps);
6262
}
6363
}
@@ -101,7 +101,7 @@ export class PeoplePicker extends React.Component<IPeoplePickerProps, IPeoplePic
101101
/**
102102
* A search field change occured
103103
*/
104-
private onSearchFieldChanged = async (searchText: string, currentSelected: IPersonaProps[]): Promise<IPersonaProps[]> => {
104+
private onSearchFieldChanged = async (searchText: string, currentSelected: IPersonaProps[]): Promise<IPersonaProps[]> => {
105105
if (searchText.length > 2) {
106106
const results = await this.peopleSearchService.searchPeople(searchText, this.suggestionsLimit, this.props.principalTypes, this.props.webAbsoluteUrl, this.groupId, this.props.ensureUser);
107107
// Remove duplicates
@@ -176,64 +176,89 @@ export class PeoplePicker extends React.Component<IPeoplePickerProps, IPeoplePic
176176
* Default React component render method
177177
*/
178178
public render(): React.ReactElement<IPeoplePickerProps> {
179+
180+
const {
181+
peoplePickerCntrlclassName,
182+
peoplePickerWPclassName,
183+
isRequired,
184+
titleText,
185+
suggestionsLimit,
186+
placeholder,
187+
personSelectionLimit,
188+
disabled,
189+
showtooltip,
190+
tooltipMessage,
191+
tooltipDirectional,
192+
errorMessageClassName,
193+
errorMessage
194+
} = this.props;
195+
196+
const {
197+
selectedPersons,
198+
resolveDelay,
199+
errorMessage: stateErrorMessage,
200+
showRequiredError
201+
} = this.state;
202+
179203
const suggestionProps: IBasePickerSuggestionsProps = {
180204
suggestionsHeaderText: strings.peoplePickerSuggestionsHeaderText,
181205
noResultsFoundText: strings.genericNoResultsFoundText,
182206
loadingText: strings.peoplePickerLoadingText,
183-
resultsMaximumNumber: this.props.suggestionsLimit ? this.props.suggestionsLimit : 5,
207+
resultsMaximumNumber: suggestionsLimit ? suggestionsLimit : 5,
184208
searchingText: strings.PeoplePickerSearchText
185209
};
186210

187211

188212
const peoplepicker = (
189-
<div id="people" className={`${styles.defaultClass} ${this.props.peoplePickerWPclassName ? this.props.peoplePickerWPclassName : ''}`}>
190-
{this.props.titleText && <Label required={this.props.isRequired}>{this.props.titleText}</Label>}
213+
<div id="people" className={`${styles.defaultClass} ${peoplePickerWPclassName ? peoplePickerWPclassName : ''}`}>
214+
{titleText && <Label required={isRequired}>{titleText}</Label>}
191215

192216
<NormalPeoplePicker pickerSuggestionsProps={suggestionProps}
193-
onResolveSuggestions={this.onSearchFieldChanged}
194-
onEmptyInputFocus={this.returnMostRecentlyUsedPerson}
195-
getTextFromItem={(peoplePersonaMenu: IPersonaProps) => peoplePersonaMenu.text}
196-
className={`ms-PeoplePicker ${this.props.peoplePickerCntrlclassName ? this.props.peoplePickerCntrlclassName : ''}`}
197-
key={'normal'}
198-
removeButtonAriaLabel={'Remove'}
199-
inputProps={{
200-
'aria-label': 'People Picker'
201-
}}
202-
selectedItems={this.state.selectedPersons}
203-
itemLimit={this.props.personSelectionLimit || 1}
204-
disabled={this.props.disabled || !!this.state.errorMessage}
205-
onChange={this.onChange}
206-
resolveDelay={this.state.resolveDelay} />
217+
onResolveSuggestions={this.onSearchFieldChanged}
218+
onEmptyInputFocus={this.returnMostRecentlyUsedPerson}
219+
getTextFromItem={(peoplePersonaMenu: IPersonaProps) => peoplePersonaMenu.text}
220+
className={`ms-PeoplePicker ${peoplePickerCntrlclassName ? peoplePickerCntrlclassName : ''}`}
221+
key={'normal'}
222+
removeButtonAriaLabel={'Remove'}
223+
inputProps={{
224+
'aria-label': 'People Picker',
225+
placeholder: placeholder
226+
}}
227+
selectedItems={selectedPersons}
228+
itemLimit={personSelectionLimit || 1}
229+
disabled={disabled || !!stateErrorMessage}
230+
onChange={this.onChange}
231+
resolveDelay={resolveDelay} />
207232
</div>
208233
);
209234

210235
return (
211236
<div>
212237
{
213-
this.props.showtooltip ? (
214-
<TooltipHost content={this.props.tooltipMessage || strings.peoplePickerComponentTooltipMessage}
215-
id='pntp'
216-
calloutProps={{ gapSpace: 0 }}
217-
directionalHint={this.props.tooltipDirectional || DirectionalHint.leftTopEdge}>
238+
showtooltip ? (
239+
<TooltipHost content={tooltipMessage || strings.peoplePickerComponentTooltipMessage}
240+
id='pntp'
241+
calloutProps={{ gapSpace: 0 }}
242+
directionalHint={tooltipDirectional || DirectionalHint.leftTopEdge}>
218243
{peoplepicker}
219244
</TooltipHost>
220245
) : (
221-
<div>
222-
{peoplepicker}
223-
</div>
224-
)
246+
<div>
247+
{peoplepicker}
248+
</div>
249+
)
225250
}
226251

227252
{
228-
((this.props.isRequired && this.state.showRequiredError) || (this.state.errorMessage)) && (
229-
<p className={`ms-TextField-errorMessage ${styles.errorMessage} ${this.props.errorMessageClassName ? this.props.errorMessageClassName : ''}`}>
253+
((isRequired && showRequiredError) || (stateErrorMessage)) && (
254+
<p className={`ms-TextField-errorMessage ${styles.errorMessage} ${errorMessageClassName ? errorMessageClassName : ''}`}>
230255
<Icon iconName='Error' className={styles.errorIcon} />
231256
{
232-
this.state.errorMessage && <span data-automation-id="error-message">{this.state.errorMessage}</span>
257+
stateErrorMessage && <span data-automation-id="error-message">{stateErrorMessage}</span>
233258
}
234259

235260
{
236-
(this.props.isRequired && this.state.showRequiredError) && <span data-automation-id="error-message">{this.props.errorMessage ? this.props.errorMessage : strings.peoplePickerComponentErrorMessage}</span>
261+
(isRequired && showRequiredError) && <span data-automation-id="error-message">{errorMessage ? errorMessage : strings.peoplePickerComponentErrorMessage}</span>
237262
}
238263
</p>
239264
)

src/webparts/controlsTest/components/ControlsTest.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,8 @@ export default class ControlsTest extends React.Component<IControlsTestProps, IC
516516
showHiddenInUI={false}
517517
principalTypes={[PrincipalType.User, PrincipalType.SharePointGroup, PrincipalType.SecurityGroup, PrincipalType.DistributionList]}
518518
suggestionsLimit={2}
519-
resolveDelay={200} />
519+
resolveDelay={200}
520+
placeholder={'Select a SharePoint principal (User or Group)'} />
520521

521522
<PeoplePicker context={this.props.context}
522523
titleText="People Picker (local scoped)"
@@ -684,7 +685,7 @@ export default class ControlsTest extends React.Component<IControlsTestProps, IC
684685
<div className="ms-font-m">List picker tester:
685686
<ListPicker context={this.props.context}
686687
label="Select your list(s)"
687-
placeHolder="Select your list(s)"
688+
placeholder="Select your list(s)"
688689
baseTemplate={100}
689690
includeHidden={false}
690691
multiSelect={true}
@@ -700,6 +701,7 @@ export default class ControlsTest extends React.Component<IControlsTestProps, IC
700701
filter={"Title eq 'SPFx'"}
701702
itemLimit={5}
702703
context={this.props.context}
704+
placeholder={'Select list items'}
703705
onSelectedItem={this.listItemPickerDataSelected} />
704706

705707
</div>

0 commit comments

Comments
 (0)