Skip to content

Commit 96459d8

Browse files
committed
datepicker refactor
1 parent c50d504 commit 96459d8

File tree

4 files changed

+139
-56
lines changed

4 files changed

+139
-56
lines changed

apps/sensenet/src/style.css

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,41 @@ span.icon svg {
225225
.leftTree span[class*='MuiTypography-body'] {
226226
font-size: 12px;
227227
} */
228+
229+
.react-datepicker-wrapper {
230+
width: 100%;
231+
max-width: 420px;
232+
}
233+
234+
.react-datepicker-wrapper input {
235+
width: 100%;
236+
height: 37px;
237+
border: 1px solid #dbdbdb;
238+
border-radius: 4px 4px 0 0;
239+
padding: 9px;
240+
font: caption;
241+
}
242+
243+
.react-datepicker-wrapper input:hover {
244+
border-color: #666;
245+
cursor: text;
246+
}
247+
248+
.react-datepicker-wrapper input:disabled {
249+
cursor: default;
250+
border: 1px solid #dbdbdb;
251+
}
252+
253+
.theme-dark .react-datepicker-wrapper input {
254+
border: 1px solid #2c2c2c;
255+
color: white;
256+
background-color: #121212;
257+
}
258+
259+
.theme-dark .react-datepicker-wrapper input:hover {
260+
border-color: #666;
261+
}
262+
263+
.theme-dark .react-datepicker-wrapper input:disabled {
264+
border: 1px solid #2c2c2c;
265+
}

packages/sn-controls-react/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
"@sensenet/search-react": "^2.1.5",
6464
"date-fns": "^2.29.3",
6565
"react-color": "^2.19.3",
66+
"react-datepicker": "7.6.0",
6667
"react-responsive": "^8.2.0",
6768
"tslib": "^2.4.0"
6869
},

packages/sn-controls-react/src/fieldcontrols/date-picker.tsx

Lines changed: 40 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
/**
22
* @module FieldControls
33
*/
4-
import { createStyles, FormHelperText, makeStyles, TextField, Theme, Tooltip, Typography } from '@material-ui/core'
5-
import { KeyboardDateTimePicker, MuiPickersUtilsProvider } from '@material-ui/pickers'
6-
import type { MaterialUiPickersDate } from '@material-ui/pickers/typings/date'
4+
import { createStyles, FormHelperText, makeStyles, Theme, Tooltip, Typography } from '@material-ui/core'
75
import { deepMerge } from '@sensenet/client-utils'
86
import { DateTimeFieldSetting, DateTimeMode } from '@sensenet/default-content-types'
9-
import DateFnsUtils from '@date-io/date-fns'
107
import intlFormatDistance from 'date-fns/intlFormatDistance'
118
import React, { useState } from 'react'
9+
import DatePickerLib from 'react-datepicker'
1210
import { changeTemplatedValue } from '../helpers'
1311
import { ReactClientFieldSetting } from './client-field-setting'
1412
import { defaultLocalization } from './localization'
13+
import 'react-datepicker/dist/react-datepicker.css'
14+
1515
const minDatePickerDate = new Date('0001-01-01')
1616

1717
export const dateTimeOptions: Intl.DateTimeFormatOptions = {
@@ -41,83 +41,67 @@ const initialValueState = ({
4141
fieldValue,
4242
actionName,
4343
settings,
44-
}: Pick<ReactClientFieldSetting<DateTimeFieldSetting>, 'fieldValue' | 'actionName' | 'settings'>) => {
45-
if (fieldValue === '0001-01-01T00:00:00Z') {
46-
return null
47-
}
44+
}: Pick<ReactClientFieldSetting<DateTimeFieldSetting>, 'fieldValue' | 'actionName' | 'settings'>): Date | null => {
45+
if (fieldValue === '0001-01-01T00:00:00Z') return null
4846

4947
if (fieldValue) {
50-
return fieldValue
48+
const parsed = new Date(fieldValue)
49+
return isNaN(parsed.getTime()) ? null : parsed
5150
}
5251

53-
if (actionName !== 'new') {
54-
return null
55-
}
52+
if (actionName !== 'new') return null
5653

57-
const secureCheckedDateInput = changeTemplatedValue(settings.DefaultValue, settings.EvaluatedDefaultValue)
54+
const defaultVal = changeTemplatedValue(settings.DefaultValue, settings.EvaluatedDefaultValue)
55+
if (!defaultVal) return null
5856

59-
return secureCheckedDateInput
57+
const parsed = new Date(defaultVal)
58+
return isNaN(parsed.getTime()) ? null : parsed
6059
}
60+
6161
/**
6262
* Field control that represents a Date field. Available values will be populated from the FieldSettings.
6363
*/
6464
export const DatePicker: React.FC<ReactClientFieldSetting<DateTimeFieldSetting>> = (props) => {
6565
const classes = useStyles()
66-
6766
const { settings, actionName, fieldValue, locale, localization, hideDescription, fieldOnChange } = props
68-
6967
const localizationMerged = deepMerge(defaultLocalization.datePicker, localization?.datePicker)
70-
71-
const [value, setValue] = useState(initialValueState({ fieldValue, actionName, settings }))
72-
73-
const handleDateChange = (date: MaterialUiPickersDate) => {
74-
if (!date || isNaN(date.getTime())) {
75-
return
76-
}
77-
const isoString: string = new Date(date).toISOString()
78-
setValue(isoString)
79-
fieldOnChange?.(settings.Name, isoString)
80-
}
81-
68+
const [value, setValue] = useState<Date | null>(initialValueState({ fieldValue, actionName, settings }))
8269
const localeCode = locale?.code || window.navigator.language
83-
8470
const isDisabled = settings.ReadOnly || disabledDateTimes.includes(settings.Name)
85-
8671
const dateFieldValue: Date = new Date(fieldValue as string)
8772

73+
const handleDateChange = (date: Date | null) => {
74+
if (!date || isNaN(date.getTime())) return
75+
setValue(date)
76+
const isoString = date.toISOString()
77+
fieldOnChange?.(settings.Name, isoString)
78+
}
79+
8880
switch (actionName) {
8981
case 'edit':
9082
case 'new':
9183
return (
92-
<MuiPickersUtilsProvider utils={DateFnsUtils} locale={locale}>
93-
<>
94-
<label htmlFor={props.settings.Name} style={{ fontSize: '15px' }}>
95-
{props.settings.DisplayName}
96-
</label>
97-
<KeyboardDateTimePicker
98-
style={{ display: 'inherit' }}
99-
minDate={minDatePickerDate}
100-
value={value}
84+
<div style={{ display: 'flex', flexDirection: 'column' }}>
85+
<label htmlFor={props.settings.Name} style={{ fontSize: '15px' }}>
86+
{props.settings.DisplayName}
87+
</label>
88+
<div style={{ maxWidth: '420px' }}>
89+
<DatePickerLib
90+
selected={value}
10191
onChange={handleDateChange}
102-
name={settings.Name}
103-
id={settings.Name}
92+
minDate={minDatePickerDate}
93+
showTimeSelect={settings.DateTimeMode === DateTimeMode.DateAndTime}
94+
dateFormat={settings.DateTimeMode === DateTimeMode.Date ? 'yyyy-MM-dd' : 'yyyy-MM-dd HH:mm'}
95+
timeFormat="HH:mm"
96+
timeIntervals={30}
97+
locale={locale}
10498
disabled={isDisabled}
105-
InputLabelProps={{ shrink: true }}
106-
required={settings.Compulsory}
107-
format={settings.DateTimeMode === DateTimeMode.Date ? 'yyyy-MM-dd' : 'yyyy-MM-dd HH:mm'}
108-
TextFieldComponent={(params) => (
109-
<TextField
110-
{...params}
111-
variant="outlined"
112-
fullWidth
113-
InputLabelProps={{ shrink: true }}
114-
InputProps={{ ...params.InputProps, style: { maxWidth: '420px' } }}
115-
/>
116-
)}
99+
placeholderText="Select date"
100+
todayButton="Today"
117101
/>
118-
{!hideDescription && <FormHelperText>{settings.Description}</FormHelperText>}
119-
</>
120-
</MuiPickersUtilsProvider>
102+
</div>
103+
{!hideDescription && <FormHelperText>{settings.Description}</FormHelperText>}
104+
</div>
121105
)
122106
default:
123107
return (

yarn.lock

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2328,6 +2328,42 @@
23282328
resolved "https://registry.npmjs.org/@eslint/js/-/js-8.35.0.tgz"
23292329
integrity sha512-JXdzbRiWclLVoD8sNUjR443VVlYqiYmDVT6rGUEIEHU5YJW0gaVZwV2xgM7D4arkvASqD0IlLUVjHiFuxaftRw==
23302330

2331+
"@floating-ui/core@^1.7.1":
2332+
version "1.7.1"
2333+
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.7.1.tgz#1abc6b157d4a936174f9dbd078278c3a81c8bc6b"
2334+
integrity sha512-azI0DrjMMfIug/ExbBaeDVJXcY0a7EPvPjb2xAJPa4HeimBX+Z18HK8QQR3jb6356SnDDdxx+hinMLcJEDdOjw==
2335+
dependencies:
2336+
"@floating-ui/utils" "^0.2.9"
2337+
2338+
"@floating-ui/dom@^1.0.0":
2339+
version "1.7.1"
2340+
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.7.1.tgz#76a4e3cbf7a08edf40c34711cf64e0cc8053d912"
2341+
integrity sha512-cwsmW/zyw5ltYTUeeYJ60CnQuPqmGwuGVhG9w0PRaRKkAyi38BT5CKrpIbb+jtahSwUl04cWzSx9ZOIxeS6RsQ==
2342+
dependencies:
2343+
"@floating-ui/core" "^1.7.1"
2344+
"@floating-ui/utils" "^0.2.9"
2345+
2346+
"@floating-ui/react-dom@^2.1.3":
2347+
version "2.1.3"
2348+
resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.1.3.tgz#1dea32e59514a67d182f0c89c8975ff959774b61"
2349+
integrity sha512-huMBfiU9UnQ2oBwIhgzyIiSpVgvlDstU8CX0AF+wS+KzmYMs0J2a3GwuFHV1Lz+jlrQGeC1fF+Nv0QoumyV0bA==
2350+
dependencies:
2351+
"@floating-ui/dom" "^1.0.0"
2352+
2353+
"@floating-ui/react@^0.27.0":
2354+
version "0.27.12"
2355+
resolved "https://registry.yarnpkg.com/@floating-ui/react/-/react-0.27.12.tgz#f1ddb43f50aa354a54de621272c44fff51444b51"
2356+
integrity sha512-kKlWNrpIQxF1B/a2MZvE0/uyKby4960yjO91W7nVyNKmmfNi62xU9HCjL1M1eWzx/LFj/VPSwJVbwQk9Pq/68A==
2357+
dependencies:
2358+
"@floating-ui/react-dom" "^2.1.3"
2359+
"@floating-ui/utils" "^0.2.9"
2360+
tabbable "^6.0.0"
2361+
2362+
"@floating-ui/utils@^0.2.9":
2363+
version "0.2.9"
2364+
resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.9.tgz#50dea3616bc8191fb8e112283b49eaff03e78429"
2365+
integrity sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==
2366+
23312367
"@gar/promisify@^1.1.3":
23322368
version "1.1.3"
23332369
resolved "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz"
@@ -7739,6 +7775,11 @@ clsx@1.2.1, clsx@^1.0.2, clsx@^1.0.4, clsx@^1.1.1:
77397775
resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz"
77407776
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
77417777

7778+
clsx@^2.1.1:
7779+
version "2.1.1"
7780+
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999"
7781+
integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==
7782+
77427783
cmd-shim@5.0.0, cmd-shim@^5.0.0:
77437784
version "5.0.0"
77447785
resolved "https://registry.npmjs.org/cmd-shim/-/cmd-shim-5.0.0.tgz"
@@ -8807,6 +8848,11 @@ date-fns@^2.23.0, date-fns@^2.25.0, date-fns@^2.29.3:
88078848
dependencies:
88088849
"@babel/runtime" "^7.21.0"
88098850

8851+
date-fns@^3.6.0:
8852+
version "3.6.0"
8853+
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-3.6.0.tgz#f20ca4fe94f8b754951b24240676e8618c0206bf"
8854+
integrity sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==
8855+
88108856
dateformat@^3.0.0:
88118857
version "3.0.3"
88128858
resolved "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz"
@@ -18252,6 +18298,15 @@ react-data-grid@6.1.0:
1825218298
react-is-deprecated "^0.1.2"
1825318299
shallowequal "^1.1.0"
1825418300

18301+
react-datepicker@7.6.0:
18302+
version "7.6.0"
18303+
resolved "https://registry.yarnpkg.com/react-datepicker/-/react-datepicker-7.6.0.tgz#6171988c6a9dbd4f49a45a06e3510035884b6b74"
18304+
integrity sha512-9cQH6Z/qa4LrGhzdc3XoHbhrxNcMi9MKjZmYgF/1MNNaJwvdSjv3Xd+jjvrEEbKEf71ZgCA3n7fQbdwd70qCRw==
18305+
dependencies:
18306+
"@floating-ui/react" "^0.27.0"
18307+
clsx "^2.1.1"
18308+
date-fns "^3.6.0"
18309+
1825518310
react-day-picker@^8.6.0:
1825618311
version "8.10.1"
1825718312
resolved "https://registry.npmjs.org/react-day-picker/-/react-day-picker-8.10.1.tgz"
@@ -20438,6 +20493,11 @@ synckit@^0.8.4:
2043820493
"@pkgr/core" "^0.1.0"
2043920494
tslib "^2.6.2"
2044020495

20496+
tabbable@^6.0.0:
20497+
version "6.2.0"
20498+
resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97"
20499+
integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==
20500+
2044120501
table@^6.0.9:
2044220502
version "6.8.2"
2044320503
resolved "https://registry.npmjs.org/table/-/table-6.8.2.tgz"

0 commit comments

Comments
 (0)