Skip to content

Commit 065a8d5

Browse files
authored
Merge pull request #98 from mg-chao/master
feats: TimePickerElement
2 parents 4154993 + af8c7ef commit 065a8d5

File tree

3 files changed

+200
-45
lines changed

3 files changed

+200
-45
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { TimePickerElement, FormContainer } from 'react-hook-form-mui/src'
2+
import { ComponentMeta, ComponentStory } from '@storybook/react'
3+
import DateFnsProvider from '../src/DateFnsProvider'
4+
import { action } from '@storybook/addon-actions'
5+
import { SubmitButton } from '../src/Shared'
6+
7+
export default {
8+
title: 'TimePickerElement',
9+
component: TimePickerElement,
10+
} as ComponentMeta<typeof TimePickerElement>
11+
12+
const Template: ComponentStory<typeof TimePickerElement> = (args) => (
13+
<DateFnsProvider>
14+
<FormContainer defaultValues={{}} onSuccess={action('submit')}>
15+
<TimePickerElement {...args} />
16+
<br />
17+
<SubmitButton />
18+
</FormContainer>
19+
</DateFnsProvider>
20+
)
21+
22+
export const Basic = Template.bind({})
23+
Basic.args = {
24+
label: 'Time Picker',
25+
name: 'basic',
26+
}
27+
28+
export const RequiredPicker = Template.bind({})
29+
RequiredPicker.args = {
30+
label: 'Time Picker',
31+
name: 'required_picker',
32+
required: true,
33+
}
34+
35+
export const RequiredPickerCustom = Template.bind({})
36+
RequiredPickerCustom.args = {
37+
label: 'Time Picker',
38+
name: 'required_picker_custom',
39+
required: true,
40+
validation: { required: 'Custom required message' },
41+
}
+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import { TimePicker, TimePickerProps } from '@mui/x-date-pickers/TimePicker'
2+
import {
3+
Control,
4+
Controller,
5+
ControllerProps,
6+
FieldError,
7+
Path,
8+
} from 'react-hook-form'
9+
import { TextField, TextFieldProps } from '@mui/material'
10+
import { FieldValues } from 'react-hook-form/dist/types/fields'
11+
12+
export declare type ParseableDate<TDate> =
13+
| string
14+
| number
15+
| Date
16+
| null
17+
| undefined
18+
| TDate
19+
20+
export type TimePickerElementProps<
21+
T extends FieldValues,
22+
TInputDate,
23+
TDate = TInputDate
24+
> = Omit<
25+
TimePickerProps<TInputDate, TDate>,
26+
'value' | 'onChange' | 'renderInput'
27+
> & {
28+
name: Path<T>
29+
required?: boolean
30+
isDate?: boolean
31+
parseError?: (error: FieldError) => string
32+
onChange?: (value: TDate, keyboardInputValue?: string) => void
33+
validation?: ControllerProps['rules']
34+
parseDate?: (value: TDate, keyboardInputValue?: string) => TDate
35+
control?: Control<T>
36+
inputProps?: TextFieldProps
37+
helperText?: TextFieldProps['helperText']
38+
}
39+
40+
export default function TimePickerElement<TFieldValues extends FieldValues>({
41+
parseError,
42+
name,
43+
required,
44+
parseDate,
45+
validation = {},
46+
inputProps,
47+
control,
48+
...rest
49+
}: TimePickerElementProps<TFieldValues, string | null>): JSX.Element {
50+
if (required && !validation.required) {
51+
validation.required = 'This field is required'
52+
}
53+
54+
return (
55+
<Controller
56+
name={name}
57+
rules={validation}
58+
control={control}
59+
render={({
60+
field: { onChange, value },
61+
fieldState: { error, invalid },
62+
}) => (
63+
<TimePicker
64+
{...rest}
65+
value={value || ''}
66+
onChange={(value, keyboardInputValue) => {
67+
let newValue: string | null = null
68+
if (keyboardInputValue) {
69+
if (typeof parseDate === 'function') {
70+
newValue = parseDate(value, keyboardInputValue)
71+
} else {
72+
newValue = keyboardInputValue
73+
}
74+
} else {
75+
if (typeof parseDate === 'function') {
76+
newValue = parseDate(value)
77+
} else {
78+
newValue = value
79+
}
80+
}
81+
onChange(newValue, keyboardInputValue)
82+
if (typeof rest.onChange === 'function') {
83+
rest.onChange(newValue, keyboardInputValue)
84+
}
85+
}}
86+
renderInput={(params) => (
87+
<TextField
88+
{...params}
89+
inputProps={{
90+
...params?.inputProps,
91+
...(!value && {
92+
value: '',
93+
}),
94+
}}
95+
{...inputProps}
96+
required={!!required}
97+
error={invalid}
98+
helperText={
99+
error
100+
? typeof parseError === 'function'
101+
? parseError(error)
102+
: error.message
103+
: inputProps?.helperText || rest.helperText
104+
}
105+
/>
106+
)}
107+
/>
108+
)}
109+
/>
110+
)
111+
}

packages/rhf-mui/src/index.ts

+48-45
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,49 @@
1-
export {default as TextFieldElement} from './TextFieldElement'
2-
export type {TextFieldElementProps} from './TextFieldElement'
3-
4-
export {default as FormContainer} from './FormContainer'
5-
export type {FormContainerProps} from './FormContainer'
6-
7-
export {default as DatePickerElement} from './DatePickerElement'
8-
export type {DatePickerElementProps} from './DatePickerElement'
9-
10-
export {default as DateTimePickerElement} from './DateTimePickerElement'
11-
export type {DateTimePickerElementProps} from './DateTimePickerElement'
12-
13-
export {default as CheckboxElement} from './CheckboxElement'
14-
export type {CheckboxElementProps} from './CheckboxElement'
15-
16-
export {default as SelectElement} from './SelectElement'
17-
export type {SelectElementProps} from './SelectElement'
18-
19-
export {default as CheckboxButtonGroup} from './CheckboxButtonGroup'
20-
export type {CheckboxButtonGroupProps} from './CheckboxButtonGroup'
21-
22-
export {default as MultiSelectElement} from './MultiSelectElement'
23-
export type {MultiSelectElementProps} from './MultiSelectElement'
24-
25-
export {default as PasswordElement} from './PasswordElement'
26-
export type {PasswordElementProps} from './PasswordElement'
27-
28-
export {default as RadioButtonGroup} from './RadioButtonGroup'
29-
export type {RadioButtonGroupProps} from './RadioButtonGroup'
30-
31-
export {default as SwitchElement} from './SwitchElement'
32-
export type {SwitchElementProps} from './SwitchElement'
33-
34-
export {default as PasswordRepeatElement} from './PasswordRepeatElement'
35-
export type {PasswordRepeatElementProps} from './PasswordRepeatElement'
36-
37-
export {default as AutocompleteElement} from './AutocompleteElement'
38-
export type {AutocompleteElementProps} from './AutocompleteElement'
39-
40-
export {default as SliderElement} from './SliderElement'
41-
export type {SliderElementProps} from './SliderElement'
42-
43-
export {default as ToggleButtonGroupElement} from './ToggleButtonGroupElement'
44-
export type {ToggleButtonGroupElementProps} from './ToggleButtonGroupElement'
45-
1+
export {default as TextFieldElement} from './TextFieldElement'
2+
export type {TextFieldElementProps} from './TextFieldElement'
3+
4+
export {default as FormContainer} from './FormContainer'
5+
export type {FormContainerProps} from './FormContainer'
6+
7+
export {default as DatePickerElement} from './DatePickerElement'
8+
export type {DatePickerElementProps} from './DatePickerElement'
9+
10+
export {default as DateTimePickerElement} from './DateTimePickerElement'
11+
export type {DateTimePickerElementProps} from './DateTimePickerElement'
12+
13+
export {default as TimePickerElement} from './TimePickerElement'
14+
export type {TimePickerElementProps} from './TimePickerElement'
15+
16+
export {default as CheckboxElement} from './CheckboxElement'
17+
export type {CheckboxElementProps} from './CheckboxElement'
18+
19+
export {default as SelectElement} from './SelectElement'
20+
export type {SelectElementProps} from './SelectElement'
21+
22+
export {default as CheckboxButtonGroup} from './CheckboxButtonGroup'
23+
export type {CheckboxButtonGroupProps} from './CheckboxButtonGroup'
24+
25+
export {default as MultiSelectElement} from './MultiSelectElement'
26+
export type {MultiSelectElementProps} from './MultiSelectElement'
27+
28+
export {default as PasswordElement} from './PasswordElement'
29+
export type {PasswordElementProps} from './PasswordElement'
30+
31+
export {default as RadioButtonGroup} from './RadioButtonGroup'
32+
export type {RadioButtonGroupProps} from './RadioButtonGroup'
33+
34+
export {default as SwitchElement} from './SwitchElement'
35+
export type {SwitchElementProps} from './SwitchElement'
36+
37+
export {default as PasswordRepeatElement} from './PasswordRepeatElement'
38+
export type {PasswordRepeatElementProps} from './PasswordRepeatElement'
39+
40+
export {default as AutocompleteElement} from './AutocompleteElement'
41+
export type {AutocompleteElementProps} from './AutocompleteElement'
42+
43+
export {default as SliderElement} from './SliderElement'
44+
export type {SliderElementProps} from './SliderElement'
45+
46+
export {default as ToggleButtonGroupElement} from './ToggleButtonGroupElement'
47+
export type {ToggleButtonGroupElementProps} from './ToggleButtonGroupElement'
48+
4649
export * from 'react-hook-form'

0 commit comments

Comments
 (0)