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

[pickers] Implement clearable field behavior #9095

Merged
merged 73 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
7608dab
WIP: add clearable behavior
noraleonte May 22, 2023
f9041a8
WIP: add clearable prop
noraleonte May 22, 2023
64020ec
first iteration of clearable behavior on DateField
noraleonte May 23, 2023
a5df0c8
Update packages/x-date-pickers/src/internals/hooks/useField/useField.ts
noraleonte May 31, 2023
ad72dda
add clearable prop to fields
noraleonte Jun 8, 2023
2afdb9a
fix conflicts
noraleonte Jun 8, 2023
2d47443
implement clearable for simple pickers
noraleonte Jun 20, 2023
f9d2246
Merge branch 'master' of https://github.com/noraleonte/mui-x into imp…
noraleonte Jun 20, 2023
d2504ff
remove hover behavior from hook
noraleonte Jun 20, 2023
99d657d
Implement field clearable props with slotProps
noraleonte Jun 20, 2023
fed4597
update docs
noraleonte Jun 21, 2023
692ea58
proptypes
noraleonte Jun 21, 2023
6c7ee33
api docs
noraleonte Jun 21, 2023
afbe1da
clear picker demo
noraleonte Jun 21, 2023
a0369ad
fix label
noraleonte Jun 21, 2023
d936ad3
fix diff
noraleonte Jun 21, 2023
b206d51
update clearable prop preview
noraleonte Jun 21, 2023
855ac34
fix demos
noraleonte Jun 21, 2023
2ce8be4
avoid clearable prop to be passed to multi-input pickers
noraleonte Jun 21, 2023
e1b8c53
fix diffs in demo files
noraleonte Jun 22, 2023
3aff317
avoid the use of clearable props in multi input fields
noraleonte Jun 22, 2023
5abfcff
Merge branch 'master' of https://github.com/noraleonte/mui-x into imp…
noraleonte Jun 22, 2023
c5fbec0
ts format
noraleonte Jun 22, 2023
5b731e2
types and api for multi input fields
noraleonte Jun 22, 2023
6f1b33d
clean up demos
noraleonte Jun 22, 2023
bbad262
fix the failing types
noraleonte Jun 23, 2023
a71ac0b
fix failing test fpr MobileDateRangePicker
noraleonte Jun 23, 2023
b5f9dfd
ts format & proptypes
noraleonte Jun 26, 2023
8bc32b0
api docs
noraleonte Jun 26, 2023
54cbb6b
Merge branch 'master' of https://github.com/noraleonte/mui-x into imp…
noraleonte Jun 27, 2023
daa2fb9
Merge branch 'master' of https://github.com/noraleonte/mui-x into imp…
noraleonte Jul 3, 2023
49c776f
adapt documentation examples
noraleonte Jul 3, 2023
0e49665
ts format for browser field demo
noraleonte Jul 3, 2023
2fd7849
Merge branch 'master' of https://github.com/noraleonte/mui-x into imp…
noraleonte Jul 6, 2023
a8f30be
clean up demos
noraleonte Jul 6, 2023
1d81271
Merge branch 'master' of https://github.com/noraleonte/mui-x into imp…
noraleonte Jul 17, 2023
035fe5c
Apply suggestions from code review
noraleonte Jul 24, 2023
db8456b
Merge branch 'master' of https://github.com/noraleonte/mui-x into imp…
noraleonte Jul 24, 2023
44ef3fb
Lukas' feedback
noraleonte Jul 24, 2023
cf0caad
prop-types
noraleonte Jul 24, 2023
a815305
yarn docs:api
noraleonte Jul 24, 2023
db1fdda
remove tabIndex
noraleonte Jul 25, 2023
897cbd4
Merge branch 'master' of https://github.com/noraleonte/mui-x into imp…
noraleonte Jul 28, 2023
e3103b8
Merge master
noraleonte Jul 31, 2023
7b759c0
small addition
noraleonte Aug 7, 2023
6f4a906
Merge branch 'master' of https://github.com/noraleonte/mui-x into imp…
noraleonte Aug 7, 2023
792cdd2
clear inputAdornment fix
noraleonte Aug 10, 2023
7d45012
Merge branch 'master' of https://github.com/noraleonte/mui-x into imp…
noraleonte Aug 10, 2023
b2674a3
fix demo bug
noraleonte Aug 10, 2023
74b2347
ts format, proptypes and api build
noraleonte Aug 10, 2023
3625ba2
fix
noraleonte Aug 10, 2023
f6ff951
Apply suggestions from code review
noraleonte Aug 28, 2023
9635b26
Lukas' feedback 2
noraleonte Aug 28, 2023
1efb0d7
Merge branch 'implement-clear-input-behavior' of https://github.com/n…
noraleonte Aug 28, 2023
137d325
revert inputAdornment fix and move useClearableField to new hooks folder
noraleonte Aug 28, 2023
558dbe0
Merge branch 'master' of https://github.com/noraleonte/mui-x into imp…
noraleonte Aug 28, 2023
4826ce5
avoid using stopPropagation
noraleonte Aug 28, 2023
bc23d5f
fix failing type
noraleonte Aug 28, 2023
3bc69c1
Lukas' feedback
noraleonte Aug 29, 2023
aa0ef98
Fix overlapping icons in the demos
noraleonte Aug 30, 2023
8576d32
Merge master
noraleonte Sep 1, 2023
c7d0f93
Extend picker slots to accept clearIcon and clearButton
noraleonte Sep 1, 2023
83cff7e
run scripts
noraleonte Sep 1, 2023
5b2ca22
Merge branch 'master' of https://github.com/noraleonte/mui-x into imp…
noraleonte Sep 8, 2023
cdded7a
Merge branch 'master' of https://github.com/noraleonte/mui-x into imp…
noraleonte Sep 15, 2023
28d8198
Merge branch 'master' of https://github.com/noraleonte/mui-x into imp…
noraleonte Sep 22, 2023
c7a1ce0
Lukas review
noraleonte Sep 22, 2023
d3ed31d
Lukas review
noraleonte Sep 27, 2023
8107e9b
add support for components and componentProps
noraleonte Sep 27, 2023
c1f0c8a
rename fieldClearLabel
noraleonte Sep 28, 2023
acf7588
fix clearButton title placement
noraleonte Sep 28, 2023
aafaca3
Lukas review
noraleonte Sep 28, 2023
089d467
replace visibility with opacity
noraleonte Sep 28, 2023
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
74 changes: 56 additions & 18 deletions docs/data/date-pickers/custom-field/PickerWithBrowserField.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { unstable_useMultiInputDateRangeField as useMultiInputDateRangeField } f
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import { unstable_useDateField as useDateField } from '@mui/x-date-pickers/DateField';

import { useClearableField } from '@mui/x-date-pickers/hooks';

const BrowserField = React.forwardRef((props, inputRef) => {
const {
disabled,
Expand All @@ -24,12 +26,13 @@ const BrowserField = React.forwardRef((props, inputRef) => {
error,
focused,
ownerState,
sx,
...other
} = props;

return (
<Box
sx={{ display: 'flex', alignItems: 'center', flexGrow: 1 }}
sx={{ ...(sx || {}), display: 'flex', alignItems: 'center', flexGrow: 1 }}
id={id}
ref={containerRef}
>
Expand All @@ -50,26 +53,42 @@ const BrowserSingleInputDateRangeField = React.forwardRef((props, ref) => {
ownerState: props,
});

const response = useSingleInputDateRangeField({
const {
onClear,
clearable,
slots: inSlots,
slotProps: inSlotProps,
...fieldProps
} = useSingleInputDateRangeField({
props: textFieldProps,
inputRef: externalInputRef,
});

return (
<BrowserField
{...response}
style={{
minWidth: 300,
}}
InputProps={{
...response.InputProps,
ref,
/* If you don't need a clear button, you can skip the use of this hook */
const { InputProps: ProcessedInputProps, fieldProps: processedFieldProps } =
useClearableField({
onClear,
clearable,
fieldProps,
InputProps: {
...fieldProps.InputProps,
endAdornment: (
<IconButton onClick={onAdornmentClick}>
<DateRangeIcon />
</IconButton>
),
},
slots: inSlots,
slotProps: inSlotProps,
});

return (
<BrowserField
{...processedFieldProps}
style={{
minWidth: 300,
}}
InputProps={{ ...ProcessedInputProps, ref }}
/>
);
});
Expand All @@ -87,14 +106,14 @@ function BrowserSingleInputDateRangePicker(props) {

return (
<DateRangePicker
{...props}
open={isOpen}
onClose={handleClose}
onOpen={handleOpen}
slots={{ field: BrowserSingleInputDateRangeField }}
slotProps={{
field: { onAdornmentClick: toggleOpen },
field: { onAdornmentClick: toggleOpen, ...props?.slotProps?.field },
}}
{...props}
/>
);
}
Expand Down Expand Up @@ -170,14 +189,25 @@ function BrowserDateRangePicker(props) {
}

function BrowserDateField(props) {
const { inputRef: externalInputRef, slots, slotProps, ...textFieldProps } = props;
const { inputRef: externalInputRef, ...textFieldProps } = props;

const response = useDateField({
const { onClear, clearable, slots, slotProps, ...fieldProps } = useDateField({
props: textFieldProps,
inputRef: externalInputRef,
});

return <BrowserField {...response} />;
/* If you don't need a clear button, you can skip the use of this hook */
const { InputProps: ProcessedInputProps, fieldProps: processedFieldProps } =
useClearableField({
onClear,
clearable,
fieldProps,
InputProps: fieldProps.InputProps,
slots,
slotProps,
});

return <BrowserField {...processedFieldProps} InputProps={ProcessedInputProps} />;
}

function BrowserDatePicker(props) {
Expand All @@ -192,8 +222,16 @@ export default function PickerWithBrowserField() {
<DemoContainer
components={['DatePicker', 'SingleInputDateRangeField', 'DateRangePicker']}
>
<BrowserDatePicker />
<BrowserSingleInputDateRangePicker />
<BrowserDatePicker
slotProps={{
field: { clearable: true },
}}
/>
<BrowserSingleInputDateRangePicker
slotProps={{
field: { clearable: true },
}}
/>
<BrowserDateRangePicker />
</DemoContainer>
</LocalizationProvider>
Expand Down
91 changes: 73 additions & 18 deletions docs/data/date-pickers/custom-field/PickerWithBrowserField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ import {
unstable_useDateField as useDateField,
UseDateFieldProps,
} from '@mui/x-date-pickers/DateField';
import {
DateFieldSlotsComponent,
DateFieldSlotsComponentsProps,
} from '@mui/x-date-pickers/DateField/DateField.types';
import { useClearableField } from '@mui/x-date-pickers/hooks';
import {
BaseMultiInputFieldProps,
DateRange,
Expand All @@ -45,6 +50,7 @@ interface BrowserFieldProps
error?: boolean;
focused?: boolean;
ownerState?: any;
sx?: any;
}

type BrowserFieldComponent = ((
Expand All @@ -62,12 +68,13 @@ const BrowserField = React.forwardRef(
error,
focused,
ownerState,
sx,
...other
} = props;

return (
<Box
sx={{ display: 'flex', alignItems: 'center', flexGrow: 1 }}
sx={{ ...(sx || {}), display: 'flex', alignItems: 'center', flexGrow: 1 }}
id={id}
ref={containerRef}
>
Expand Down Expand Up @@ -109,26 +116,47 @@ const BrowserSingleInputDateRangeField = React.forwardRef(
ownerState: props as any,
});

const response = useSingleInputDateRangeField<Dayjs, typeof textFieldProps>({
const {
onClear,
clearable,
slots: inSlots,
slotProps: inSlotProps,
...fieldProps
} = useSingleInputDateRangeField<Dayjs, typeof textFieldProps>({
props: textFieldProps,
inputRef: externalInputRef,
});

return (
<BrowserField
{...response}
style={{
minWidth: 300,
}}
InputProps={{
...response.InputProps,
ref,
/* If you don't need a clear button, you can skip the use of this hook */
const { InputProps: ProcessedInputProps, fieldProps: processedFieldProps } =
useClearableField<
{},
typeof textFieldProps.InputProps,
DateFieldSlotsComponent,
DateFieldSlotsComponentsProps<Dayjs>
>({
onClear,
clearable,
fieldProps,
InputProps: {
...fieldProps.InputProps,
endAdornment: (
<IconButton onClick={onAdornmentClick}>
<DateRangeIcon />
</IconButton>
),
},
slots: inSlots as any,
slotProps: inSlotProps as any,
});

return (
<BrowserField
{...processedFieldProps}
style={{
minWidth: 300,
}}
InputProps={{ ...ProcessedInputProps, ref }}
/>
);
},
Expand All @@ -147,14 +175,14 @@ function BrowserSingleInputDateRangePicker(props: DateRangePickerProps<Dayjs>) {

return (
<DateRangePicker
{...props}
open={isOpen}
onClose={handleClose}
onOpen={handleOpen}
slots={{ field: BrowserSingleInputDateRangeField }}
slotProps={{
field: { onAdornmentClick: toggleOpen } as any,
field: { onAdornmentClick: toggleOpen, ...props?.slotProps?.field } as any,
}}
{...props}
/>
);
}
Expand Down Expand Up @@ -257,14 +285,33 @@ interface BrowserDateFieldProps
> {}

function BrowserDateField(props: BrowserDateFieldProps) {
const { inputRef: externalInputRef, slots, slotProps, ...textFieldProps } = props;
const { inputRef: externalInputRef, ...textFieldProps } = props;

const response = useDateField<Dayjs, typeof textFieldProps>({
const { onClear, clearable, slots, slotProps, ...fieldProps } = useDateField<
Dayjs,
typeof textFieldProps
>({
props: textFieldProps,
inputRef: externalInputRef,
});

return <BrowserField {...response} />;
/* If you don't need a clear button, you can skip the use of this hook */
const { InputProps: ProcessedInputProps, fieldProps: processedFieldProps } =
useClearableField<
{},
typeof textFieldProps.InputProps,
DateFieldSlotsComponent,
DateFieldSlotsComponentsProps<Dayjs>
>({
onClear,
clearable,
fieldProps,
InputProps: fieldProps.InputProps,
slots,
slotProps,
});

return <BrowserField {...processedFieldProps} InputProps={ProcessedInputProps} />;
}

function BrowserDatePicker(props: DatePickerProps<Dayjs>) {
Expand All @@ -279,8 +326,16 @@ export default function PickerWithBrowserField() {
<DemoContainer
components={['DatePicker', 'SingleInputDateRangeField', 'DateRangePicker']}
>
<BrowserDatePicker />
<BrowserSingleInputDateRangePicker />
<BrowserDatePicker
slotProps={{
field: { clearable: true },
}}
/>
<BrowserSingleInputDateRangePicker
slotProps={{
field: { clearable: true },
}}
/>
<BrowserDateRangePicker />
</DemoContainer>
</LocalizationProvider>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
<BrowserDatePicker />
<BrowserSingleInputDateRangePicker />
<BrowserDatePicker
slotProps={{
field: { clearable: true },
}}
/>
<BrowserSingleInputDateRangePicker
slotProps={{
field: { clearable: true },
}}
/>
<BrowserDateRangePicker />
Loading