Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated pickers with input attribute compatibility. #33243

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
2c670c2
Updated pickers with input attribute compatibility.
tpalacino Nov 10, 2024
6fc3f66
Added change file.
tpalacino Nov 10, 2024
535676b
Merge branch 'master' into issue-22528-picker-input-attributes
tpalacino Nov 14, 2024
56ca291
Merge branch 'master' into issue-22528-picker-input-attributes
tpalacino Nov 16, 2024
77cd8e4
Merge branch 'microsoft:master' into issue-22528-picker-input-attributes
tpalacino Nov 19, 2024
75e270d
Resolved change description comment
tpalacino Nov 19, 2024
f4e00a1
Removed ariaLabel property
tpalacino Nov 19, 2024
9a16f7f
Updated label styles and removed id
tpalacino Nov 19, 2024
2962ad8
Removed default required error message
tpalacino Nov 19, 2024
f765a35
Enabled implementor to control error message display
tpalacino Nov 19, 2024
070bf48
Connected error element to the aria-describedby
tpalacino Nov 19, 2024
826c4f4
Merge branch 'master' into issue-22528-picker-input-attributes
tpalacino Nov 20, 2024
745d388
Merge branch 'master' into issue-22528-picker-input-attributes
tpalacino Nov 21, 2024
79849b6
Addressed PR feedback
tpalacino Nov 21, 2024
0e8f250
Addressed additional PR feedback
tpalacino Nov 22, 2024
9ebbbc5
Merge branch 'master' into issue-22528-picker-input-attributes
tpalacino Nov 22, 2024
c923f8a
Merge branch 'master' into issue-22528-picker-input-attributes
tpalacino Nov 27, 2024
f919df8
Merge branch 'master' into issue-22528-picker-input-attributes
tpalacino Dec 6, 2024
0f45667
Added space to aria described by
tpalacino Dec 6, 2024
f344406
Added sub-component styles for Label.
tpalacino Dec 8, 2024
af82769
Merge branch 'master' into issue-22528-picker-input-attributes
tpalacino Dec 8, 2024
e9b63d0
Merge branch 'master' into issue-22528-picker-input-attributes
tpalacino Dec 9, 2024
2996949
Update packages/react/src/components/pickers/BasePicker.tsx
khmakoto Dec 11, 2024
efd8480
Merge branch 'master' into issue-22528-picker-input-attributes
khmakoto Dec 11, 2024
cd1e5f9
Fixing build error.
khmakoto Dec 11, 2024
42ecb88
Updating snapshots.
khmakoto Dec 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Added properties: label, required, and error.",
tpalacino marked this conversation as resolved.
Show resolved Hide resolved
"packageName": "@fluentui/react",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import { TextField } from '@fluentui/react/lib/TextField';
import { Checkbox } from '@fluentui/react/lib/Checkbox';
import { IPersonaProps, IPersonaStyles } from '@fluentui/react/lib/Persona';
import {
Expand Down Expand Up @@ -42,6 +43,9 @@ const personaStyles: Partial<IPersonaStyles> = {
export const PeoplePickerListExample: React.FunctionComponent = () => {
const [delayResults, setDelayResults] = React.useState(false);
const [isPickerDisabled, setIsPickerDisabled] = React.useState(false);
const [pickerLabel, setPickerLabel] = React.useState<string | undefined>('Choose People');
const [showPickerLabel, setShowPickerLabel] = React.useState(false);
const [isPickerRequired, setIsPickerRequired] = React.useState(false);
const [mostRecentlyUsed, setMostRecentlyUsed] = React.useState<IPersonaProps[]>(mru);
const [peopleList, setPeopleList] = React.useState<IPersonaProps[]>(people);

Expand Down Expand Up @@ -102,6 +106,18 @@ export const PeoplePickerListExample: React.FunctionComponent = () => {
setIsPickerDisabled(!isPickerDisabled);
};

const onShowLabelButtonClick = (): void => {
setShowPickerLabel(!showPickerLabel);
};

const onPickerLabelChanged = (ev?: any, newValue?: string): void => {
tpalacino marked this conversation as resolved.
Show resolved Hide resolved
setPickerLabel(newValue || '');
tpalacino marked this conversation as resolved.
Show resolved Hide resolved
};

const onRequiredButtonClick = (): void => {
setIsPickerRequired(!isPickerRequired);
};

const onToggleDelayResultsChange = (): void => {
setDelayResults(!delayResults);
};
Expand All @@ -115,9 +131,17 @@ export const PeoplePickerListExample: React.FunctionComponent = () => {
);
};

const onGetErrorMessage = React.useCallback(
(items: IPersonaProps[]): string | JSX.Element | PromiseLike<string | JSX.Element> | undefined => {
return isPickerRequired && (items || []).length === 0 ? 'Please fill out this field.' : undefined;
},
[isPickerRequired],
);

return (
<div>
<ListPeoplePicker
label={showPickerLabel ? pickerLabel : undefined}
// eslint-disable-next-line react/jsx-no-bind
onResolveSuggestions={onFilterChanged}
// eslint-disable-next-line react/jsx-no-bind
Expand All @@ -141,6 +165,8 @@ export const PeoplePickerListExample: React.FunctionComponent = () => {
componentRef={picker}
resolveDelay={300}
disabled={isPickerDisabled}
required={isPickerRequired}
onGetErrorMessage={onGetErrorMessage}
/>
<Checkbox
label="Disable People Picker"
Expand All @@ -156,6 +182,28 @@ export const PeoplePickerListExample: React.FunctionComponent = () => {
onChange={onToggleDelayResultsChange}
styles={checkboxStyles}
/>
<Checkbox
label="Required People Picker"
checked={isPickerRequired}
// eslint-disable-next-line react/jsx-no-bind
onChange={onRequiredButtonClick}
styles={checkboxStyles}
/>
<Checkbox
label="Show Label"
checked={showPickerLabel}
// eslint-disable-next-line react/jsx-no-bind
onChange={onShowLabelButtonClick}
styles={checkboxStyles}
/>
{showPickerLabel && (
<TextField
label={'People Picker Label'}
value={pickerLabel}
// eslint-disable-next-line react/jsx-no-bind
onChange={onPickerLabelChanged}
tpalacino marked this conversation as resolved.
Show resolved Hide resolved
/>
)}
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import { TextField } from '@fluentui/react/lib/TextField';
import { Checkbox } from '@fluentui/react/lib/Checkbox';
import { IPersonaProps } from '@fluentui/react/lib/Persona';
import {
Expand Down Expand Up @@ -29,6 +30,9 @@ const checkboxStyles = {
export const PeoplePickerNormalExample: React.FunctionComponent = () => {
const [delayResults, setDelayResults] = React.useState(false);
const [isPickerDisabled, setIsPickerDisabled] = React.useState(false);
const [pickerLabel, setPickerLabel] = React.useState<string | undefined>('Choose People');
const [showPickerLabel, setShowPickerLabel] = React.useState(false);
const [isPickerRequired, setIsPickerRequired] = React.useState(false);
const [showSecondaryText, setShowSecondaryText] = React.useState(false);
const [mostRecentlyUsed, setMostRecentlyUsed] = React.useState<IPersonaProps[]>(mru);
const [peopleList, setPeopleList] = React.useState<IPersonaProps[]>(people);
Expand Down Expand Up @@ -103,6 +107,18 @@ export const PeoplePickerNormalExample: React.FunctionComponent = () => {
setIsPickerDisabled(!isPickerDisabled);
};

const onShowLabelButtonClick = (): void => {
setShowPickerLabel(!showPickerLabel);
};

const onPickerLabelChanged = (ev?: any, newValue?: string): void => {
tpalacino marked this conversation as resolved.
Show resolved Hide resolved
setPickerLabel(newValue || '');
tpalacino marked this conversation as resolved.
Show resolved Hide resolved
};

const onRequiredButtonClick = (): void => {
setIsPickerRequired(!isPickerRequired);
};

const onToggleDelayResultsChange = (): void => {
setDelayResults(!delayResults);
};
Expand All @@ -111,9 +127,17 @@ export const PeoplePickerNormalExample: React.FunctionComponent = () => {
setShowSecondaryText(!showSecondaryText);
};

const onGetErrorMessage = React.useCallback(
(items: IPersonaProps[]): string | JSX.Element | PromiseLike<string | JSX.Element> | undefined => {
return isPickerRequired && (items || []).length === 0 ? 'Please fill out this field.' : undefined;
},
[isPickerRequired],
);

return (
<div>
<NormalPeoplePicker
label={showPickerLabel ? pickerLabel : undefined}
// eslint-disable-next-line react/jsx-no-bind
onResolveSuggestions={onFilterChanged}
// eslint-disable-next-line react/jsx-no-bind
Expand All @@ -137,6 +161,8 @@ export const PeoplePickerNormalExample: React.FunctionComponent = () => {
onInputChange={onInputChange}
resolveDelay={300}
disabled={isPickerDisabled}
required={isPickerRequired}
onGetErrorMessage={onGetErrorMessage}
/>
<Checkbox
label="Disable People Picker"
Expand All @@ -159,6 +185,28 @@ export const PeoplePickerNormalExample: React.FunctionComponent = () => {
onChange={onToggleShowSecondaryText}
styles={checkboxStyles}
/>
<Checkbox
label="Required People Picker"
checked={isPickerRequired}
// eslint-disable-next-line react/jsx-no-bind
onChange={onRequiredButtonClick}
styles={checkboxStyles}
/>
<Checkbox
label="Show Label"
checked={showPickerLabel}
// eslint-disable-next-line react/jsx-no-bind
onChange={onShowLabelButtonClick}
styles={checkboxStyles}
/>
{showPickerLabel && (
<TextField
label={'People Picker Label'}
value={pickerLabel}
// eslint-disable-next-line react/jsx-no-bind
onChange={onPickerLabelChanged}
tpalacino marked this conversation as resolved.
Show resolved Hide resolved
/>
)}
</div>
);
};
Expand Down
28 changes: 26 additions & 2 deletions packages/react/src/components/pickers/BasePicker.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import type { IStyle } from '../../Styling';

const GlobalClassNames = {
root: 'ms-BasePicker',
label: 'ms-BasePicker-label',
text: 'ms-BasePicker-text',
itemsWrapper: 'ms-BasePicker-itemsWrapper',
input: 'ms-BasePicker-input',
error: 'ms-BasePicker-error',
};

export function getStyles(props: IBasePickerStyleProps): IBasePickerStyles {
const { className, theme, isFocused, inputClassName, disabled } = props;
const { className, theme, isFocused, inputClassName, disabled, hasErrorMessage } = props;

if (!theme) {
throw new Error('theme is undefined or null in base BasePicker getStyles function.');
Expand Down Expand Up @@ -56,8 +58,22 @@ export function getStyles(props: IBasePickerStyleProps): IBasePickerStyles {
// const disabledOverlayColor = rgbColor ? `rgba(${rgbColor.r}, ${rgbColor.g}, ${rgbColor.b}, 0.29)` : 'transparent';
const disabledOverlayColor = 'rgba(218, 218, 218, 0.29)';

const focusColor = isFocused && !disabled && (hasErrorMessage ? semanticColors.errorText : inputFocusBorderAlt);

return {
root: [classNames.root, className, { position: 'relative' }],
error: [
classNames.error,
{
fontSize: 12,
fontWeight: 400,
color: semanticColors.errorText,
margin: 0,
paddingTop: 5,
display: hasErrorMessage ? 'flex' : 'none',
alignItems: 'center',
},
],
text: [
classNames.text,
{
Expand All @@ -79,7 +95,7 @@ export function getStyles(props: IBasePickerStyleProps): IBasePickerStyles {
},
},
},
isFocused && !disabled && getInputFocusStyle(inputFocusBorderAlt, effects.roundedCorner2),
focusColor && getInputFocusStyle(focusColor, effects.roundedCorner2),
disabled && {
borderColor: disabledOverlayColor,
selectors: {
Expand All @@ -102,6 +118,14 @@ export function getStyles(props: IBasePickerStyleProps): IBasePickerStyles {
},
},
},
hasErrorMessage && {
borderColor: semanticColors.errorText,
selectors: {
':hover': {
borderColor: semanticColors.errorText,
},
},
},
],
itemsWrapper: [
classNames.itemsWrapper,
Expand Down
Loading
Loading