1
1
'use client' ;
2
2
3
- import { dateTime } from '@gravity-ui/date-utils' ;
4
- import { Button , Popup , Sheet } from '@gravity-ui/uikit' ;
5
- import type { PopupOffset , PopupPlacement } from '@gravity-ui/uikit' ;
3
+ import { Popup , Sheet } from '@gravity-ui/uikit' ;
4
+ import type { PopupProps } from '@gravity-ui/uikit' ;
6
5
7
6
import { block } from '../../../../utils/cn' ;
8
- import { RelativeDatePicker } from '../../../RelativeDatePicker' ;
9
- import type { RelativeDatePickerProps } from '../../../RelativeDatePicker' ;
10
- import type { RelativeRangeDatePickerState } from '../../hooks/useRelativeRangeDatePickerState' ;
11
- import type { RelativeRangeDatePickerProps } from '../../types' ;
12
- import { Presets } from '../Presets/Presets' ;
13
- import { Zones } from '../Zones/Zones' ;
7
+ import type { PopupStyleProps } from '../../../types' ;
14
8
15
- import { i18n } from './i18n ' ;
16
- import { useRelativeRangeDatePickerDialogState } from './useRelativeRangeDatePickerDialogState ' ;
9
+ import { PickerForm } from './PickerForm ' ;
10
+ import type { PickerFormProps } from './PickerForm ' ;
17
11
18
12
import './PickerDialog.scss' ;
19
13
20
14
const b = block ( 'relative-range-date-picker-dialog' ) ;
21
15
22
- export interface PickerDialogProps {
23
- className ?: string ;
24
- state : RelativeRangeDatePickerState ;
25
- props : RelativeRangeDatePickerProps ;
16
+ export interface PickerDialogProps extends PickerFormProps , PopupStyleProps {
17
+ /** Popup anchor */
18
+ anchor : HTMLElement | null ;
19
+ /** Manages `Popup` visibility */
26
20
open : boolean ;
27
- placement ?: PopupPlacement ;
28
- offset ?: PopupOffset ;
21
+ /** Handles popup close event */
22
+ onClose : ( reason ?: Parameters < NonNullable < PopupProps [ 'onOpenChange' ] > > [ 2 ] | 'apply' ) => void ;
23
+ /** If true `Popup` act like a modal dialog */
24
+ modal ?: boolean ;
25
+ /** If true `Sheet` is used instead of `Popup` */
29
26
isMobile ?: boolean ;
30
- anchor : HTMLElement | null ;
31
- onClose : ( ) => void ;
32
- focusInput ?: ( ) => void ;
33
- disableFocusTrap ?: boolean ;
34
27
}
35
28
36
29
export function PickerDialog ( {
37
- props,
38
- state,
39
30
open,
40
31
onClose,
41
- focusInput,
42
32
isMobile,
43
33
anchor,
44
- className,
45
- placement,
46
- offset,
47
- disableFocusTrap,
34
+ popupClassName,
35
+ popupStyle,
36
+ popupPlacement,
37
+ popupOffset,
38
+ modal,
39
+ ...props
48
40
} : PickerDialogProps ) {
49
41
if ( isMobile ) {
50
42
return (
51
43
< Sheet
52
44
visible = { open }
53
- onClose = { onClose }
54
- contentClassName = { b ( 'content' , { mobile : true , size : 'xl' } , className ) }
45
+ onClose = { ( ) => {
46
+ onClose ( 'outside-press' ) ;
47
+ } }
48
+ contentClassName = { b ( 'content' , { mobile : true , size : 'xl' } , popupClassName ) }
55
49
>
56
- < DialogContent { ...props } size = "xl" state = { state } onApply = { onClose } />
50
+ < PickerForm
51
+ { ...props }
52
+ size = "xl"
53
+ onApply = { ( ) => {
54
+ onClose ( 'apply' ) ;
55
+ } }
56
+ />
57
57
</ Sheet >
58
58
) ;
59
59
}
@@ -63,114 +63,23 @@ export function PickerDialog({
63
63
open = { open }
64
64
onOpenChange = { ( isOpen , _event , reason ) => {
65
65
if ( ! isOpen ) {
66
- onClose ( ) ;
67
- if ( reason === 'escape-key' ) {
68
- focusInput ?.( ) ;
69
- }
66
+ onClose ( reason ) ;
70
67
}
71
68
} }
72
- placement = { placement }
73
- offset = { offset }
69
+ placement = { popupPlacement }
70
+ offset = { popupOffset }
74
71
role = "dialog"
75
72
anchorElement = { anchor }
76
- className = { b ( 'content' , { size : props . size } , className ) }
77
- modal = { ! disableFocusTrap }
73
+ className = { b ( 'content' , { size : props . size } , popupClassName ) }
74
+ style = { popupStyle }
75
+ modal = { modal }
78
76
>
79
- < DialogContent { ...props } state = { state } onApply = { onClose } />
77
+ < PickerForm
78
+ { ...props }
79
+ onApply = { ( ) => {
80
+ onClose ( 'apply' ) ;
81
+ } }
82
+ />
80
83
</ Popup >
81
84
) ;
82
85
}
83
-
84
- function DialogContent (
85
- props : {
86
- state : RelativeRangeDatePickerState ;
87
- onApply : ( ) => void ;
88
- } & RelativeRangeDatePickerProps ,
89
- ) {
90
- const state = useRelativeRangeDatePickerDialogState ( props . state , props ) ;
91
-
92
- const placeholderValue =
93
- props . placeholderValue ?. timeZone ( props . state . timeZone ) ||
94
- dateTime ( { timeZone : props . state . timeZone } ) ;
95
- const fieldProps : RelativeDatePickerProps = {
96
- timeZone : props . state . timeZone ,
97
- format : props . format ,
98
- minValue : props . minValue ,
99
- maxValue : props . maxValue ,
100
- hasClear : props . allowNullableValues ,
101
- readOnly : props . readOnly ,
102
- size : props . size ,
103
- errorPlacement : 'inside' ,
104
- } ;
105
- return (
106
- < div >
107
- < div className = { b ( 'pickers' ) } >
108
- < RelativeDatePicker
109
- { ...fieldProps }
110
- validationState = { state . startValidation ?. isInvalid ? 'invalid' : undefined }
111
- errorMessage = {
112
- state . startValidation ?. errors ?. join ( '\n' ) || i18n ( 'Value is incorrect.' )
113
- }
114
- placeholderValue = { placeholderValue . startOf ( 'day' ) }
115
- label = { i18n ( 'From' ) }
116
- value = { state . start }
117
- onUpdate = { state . setStart }
118
- />
119
- < RelativeDatePicker
120
- { ...fieldProps }
121
- validationState = { state . endValidation ?. isInvalid ? 'invalid' : undefined }
122
- errorMessage = {
123
- state . endValidation ?. errors ?. join ( '\n' ) || i18n ( 'Value is incorrect.' )
124
- }
125
- placeholderValue = { placeholderValue . endOf ( 'day' ) }
126
- label = { i18n ( 'To' ) }
127
- value = { state . end }
128
- onUpdate = { state . setEnd }
129
- roundUp
130
- />
131
- </ div >
132
- { props . withApplyButton && ! props . readOnly ? (
133
- < Button
134
- disabled = { state . isInvalid }
135
- size = { props . size }
136
- onClick = { ( ) => {
137
- state . applyValue ( ) ;
138
- props . onApply ( ) ;
139
- } }
140
- className = { b ( 'apply' ) }
141
- width = "max"
142
- >
143
- { i18n ( 'Apply' ) }
144
- </ Button >
145
- ) : null }
146
- { props . withPresets && ! props . readOnly ? (
147
- < Presets
148
- size = { props . size }
149
- presetTabs = { props . presetTabs }
150
- onChoosePreset = { ( start , end ) => {
151
- state . setRange (
152
- { type : 'relative' , value : start } ,
153
- { type : 'relative' , value : end } ,
154
- ) ;
155
- if ( ! props . withApplyButton ) {
156
- props . onApply ( ) ;
157
- }
158
- } }
159
- minValue = { props . minValue }
160
- docs = { props . docs }
161
- className = { b ( 'presets' ) }
162
- />
163
- ) : null }
164
- { props . withZonesList ? (
165
- < div className = { b ( 'zone' ) } >
166
- < Zones
167
- value = { state . timeZone }
168
- onUpdate = { state . setTimeZone }
169
- disabled = { props . readOnly }
170
- size = { props . size }
171
- />
172
- </ div >
173
- ) : null }
174
- </ div >
175
- ) ;
176
- }
0 commit comments