-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixed many usability issues with the CalendarDay field (#2930)
- Loading branch information
Showing
6 changed files
with
94 additions
and
113 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
--- | ||
'@arch-ui/day-picker': patch | ||
'@keystonejs/fields': patch | ||
--- | ||
|
||
Fixed many usability issues with the CalendarDay field: | ||
- Fixed field not functioning as a proper controlled component in the Create popout. | ||
- Fixed field initially displaying "Invalid Date" before defaulting to 1970-01-01. | ||
- Filter input no longer defaults to the current date. This was bugged; submitting the form with no changes would match nothing. | ||
- Filter input now falls back to no value when given an invalid date. Previously, it was falling back to 1970-01-01. | ||
- Fixed filter input not initially displaying the current value when in edit mode (it was displaying the current date). | ||
- Fixed filter input not being initially focused. | ||
- Fixed filter input not being submitted properly if focus wasn't lost first. | ||
|
||
Updated chrono-node dependency to 1.4.6. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,57 +1,64 @@ | ||
/** @jsx jsx */ | ||
import { jsx } from '@emotion/core'; | ||
import { useState } from 'react'; | ||
import React, { useState, useEffect, forwardRef, useRef } from 'react'; | ||
import chrono from 'chrono-node'; | ||
import { Input } from '@arch-ui/input'; | ||
import { format } from 'date-fns'; | ||
|
||
export const TextDayPicker = ({ | ||
date, | ||
onChange, | ||
format: displayFormat = 'Do MMMM YYYY', | ||
...props | ||
}) => { | ||
const formatDate = newDate => (newDate === null ? '' : format(newDate, displayFormat)); | ||
|
||
const [isEditing, setIsEditing] = useState(false); | ||
const [value, setValue] = useState({ | ||
raw: date, | ||
formatted: formatDate(date), | ||
}); | ||
|
||
const toggleEditing = () => { | ||
setIsEditing(!isEditing); | ||
}; | ||
|
||
const onBlur = () => { | ||
toggleEditing(); | ||
|
||
const newDate = parseDate(value.raw); | ||
onChange(newDate); | ||
|
||
setValue({ | ||
raw: newDate, | ||
formatted: formatDate(newDate), | ||
export const TextDayPicker = forwardRef( | ||
({ date = '', onChange, format: displayFormat = 'Do MMMM YYYY', ...props }, ref) => { | ||
const formatDate = newDate => (newDate ? format(newDate, displayFormat) : ''); | ||
|
||
const [isEditing, setIsEditing] = useState(false); | ||
const [value, setValue] = useState({ | ||
raw: date, | ||
formatted: formatDate(date), | ||
}); | ||
}; | ||
|
||
const handleChange = ({ target: { value: raw } }) => { | ||
setValue(oldValue => ({ ...oldValue, raw })); | ||
}; | ||
|
||
return ( | ||
<Input | ||
value={isEditing ? value.raw : value.formatted} | ||
placeholder="Enter a date..." | ||
onFocus={toggleEditing} | ||
onBlur={onBlur} | ||
onChange={handleChange} | ||
{...props} | ||
/> | ||
); | ||
}; | ||
|
||
function parseDate(value) { | ||
const parsed = chrono.parseDate(value); | ||
return parsed === undefined ? null : format(parsed, 'YYYY-MM-DD'); | ||
} | ||
|
||
const parseCache = useRef(); | ||
|
||
useEffect(() => { | ||
// Parse the raw input. This may be a string such as 'Today'. | ||
const parsedDate = chrono.parseDate(value.raw); | ||
|
||
// If valid, convert it to ISO 8601. | ||
const isoDate = parsedDate ? format(parsedDate, 'YYYY-MM-DD') : null; | ||
|
||
// Pass it up the tree. The parent can handle the null case. | ||
onChange(isoDate); | ||
|
||
parseCache.current = isoDate; | ||
}, [value.raw]); | ||
|
||
const onFocus = () => { | ||
setIsEditing(true); | ||
}; | ||
|
||
const onBlur = () => { | ||
setIsEditing(false); | ||
|
||
const raw = parseCache.current; | ||
|
||
// At this point, the parse cache should either be null or an ISO 8601 date. | ||
if (raw) { | ||
setValue({ raw, formatted: formatDate(raw) }); | ||
} else { | ||
setValue({ raw: '', formatted: '' }); | ||
} | ||
}; | ||
|
||
const handleChange = ({ target: { value: raw } }) => { | ||
setValue(oldValue => ({ ...oldValue, raw })); | ||
}; | ||
|
||
return ( | ||
<Input | ||
ref={ref} | ||
value={isEditing ? value.raw : value.formatted} | ||
placeholder="Enter a date..." | ||
onFocus={onFocus} | ||
onBlur={onBlur} | ||
onChange={handleChange} | ||
{...props} | ||
/> | ||
); | ||
} | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,18 @@ | ||
import React, { useState } from 'react'; | ||
import { format } from 'date-fns'; | ||
import React from 'react'; | ||
import { TextDayPicker } from '@arch-ui/day-picker'; | ||
|
||
const FORMAT = 'YYYY-MM-DD'; | ||
|
||
const CalendarDayFilterView = ({ onChange, filter }) => { | ||
const [value, setValue] = useState(format(new Date(), FORMAT)); | ||
|
||
const handleSelectedChange = newValue => { | ||
const CalendarDayFilterView = ({ onChange, filter, value, innerRef }) => { | ||
const handleChange = newValue => { | ||
if (newValue === null) { | ||
newValue = format(new Date(), FORMAT); | ||
newValue = ''; | ||
} | ||
|
||
onChange(newValue); | ||
setValue(newValue); | ||
}; | ||
|
||
if (!filter) return null; | ||
|
||
return <TextDayPicker date={value} onChange={handleSelectedChange} />; | ||
return <TextDayPicker ref={innerRef} date={value} onChange={handleChange} />; | ||
}; | ||
|
||
export default CalendarDayFilterView; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -432,15 +432,6 @@ | |
"@babel/template" "^7.8.3" | ||
"@babel/types" "^7.9.5" | ||
|
||
"@babel/helper-function-name@^7.9.5": | ||
version "7.9.5" | ||
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz#2b53820d35275120e1874a82e5aabe1376920a5c" | ||
integrity sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw== | ||
dependencies: | ||
"@babel/helper-get-function-arity" "^7.8.3" | ||
"@babel/template" "^7.8.3" | ||
"@babel/types" "^7.9.5" | ||
|
||
"@babel/helper-get-function-arity@^7.7.4": | ||
version "7.7.4" | ||
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz#cb46348d2f8808e632f0ab048172130e636005f0" | ||
|
@@ -609,11 +600,6 @@ | |
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80" | ||
integrity sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g== | ||
|
||
"@babel/helper-validator-identifier@^7.9.5": | ||
version "7.9.5" | ||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80" | ||
integrity sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g== | ||
|
||
"@babel/helper-wrap-function@^7.8.3": | ||
version "7.8.3" | ||
resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz#9dbdb2bb55ef14aaa01fe8c99b629bd5352d8610" | ||
|
@@ -772,16 +758,7 @@ | |
"@babel/plugin-syntax-object-rest-spread" "^7.8.0" | ||
"@babel/plugin-transform-parameters" "^7.9.5" | ||
|
||
"@babel/plugin-proposal-object-rest-spread@^7.0.0", "@babel/plugin-proposal-object-rest-spread@^7.5.5", "@babel/plugin-proposal-object-rest-spread@^7.6.2", "@babel/plugin-proposal-object-rest-spread@^7.7.4", "@babel/plugin-proposal-object-rest-spread@^7.8.3": | ||
version "7.9.6" | ||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.6.tgz#7a093586fcb18b08266eb1a7177da671ac575b63" | ||
integrity sha512-Ga6/fhGqA9Hj+y6whNpPv8psyaK5xzrQwSPsGPloVkvmH+PqW1ixdnfJ9uIO06OjQNYol3PMnfmJ8vfZtkzF+A== | ||
dependencies: | ||
"@babel/helper-plugin-utils" "^7.8.3" | ||
"@babel/plugin-syntax-object-rest-spread" "^7.8.0" | ||
"@babel/plugin-transform-parameters" "^7.9.5" | ||
|
||
"@babel/plugin-proposal-object-rest-spread@^7.9.5", "@babel/plugin-proposal-object-rest-spread@^7.9.6": | ||
"@babel/plugin-proposal-object-rest-spread@^7.0.0", "@babel/plugin-proposal-object-rest-spread@^7.5.5", "@babel/plugin-proposal-object-rest-spread@^7.6.2", "@babel/plugin-proposal-object-rest-spread@^7.7.4", "@babel/plugin-proposal-object-rest-spread@^7.8.3", "@babel/plugin-proposal-object-rest-spread@^7.9.5", "@babel/plugin-proposal-object-rest-spread@^7.9.6": | ||
version "7.9.6" | ||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.6.tgz#7a093586fcb18b08266eb1a7177da671ac575b63" | ||
integrity sha512-Ga6/fhGqA9Hj+y6whNpPv8psyaK5xzrQwSPsGPloVkvmH+PqW1ixdnfJ9uIO06OjQNYol3PMnfmJ8vfZtkzF+A== | ||
|
@@ -1239,14 +1216,6 @@ | |
"@babel/helper-get-function-arity" "^7.8.3" | ||
"@babel/helper-plugin-utils" "^7.8.3" | ||
|
||
"@babel/plugin-transform-parameters@^7.9.5": | ||
version "7.9.5" | ||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.5.tgz#173b265746f5e15b2afe527eeda65b73623a0795" | ||
integrity sha512-0+1FhHnMfj6lIIhVvS4KGQJeuhe1GI//h5uptK4PvLt+BGBxsoUJbd3/IW002yk//6sZPlFgsG1hY6OHLcy6kA== | ||
dependencies: | ||
"@babel/helper-get-function-arity" "^7.8.3" | ||
"@babel/helper-plugin-utils" "^7.8.3" | ||
|
||
"@babel/plugin-transform-property-literals@^7.0.0", "@babel/plugin-transform-property-literals@^7.2.0", "@babel/plugin-transform-property-literals@^7.8.3": | ||
version "7.8.3" | ||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz#33194300d8539c1ed28c62ad5087ba3807b98263" | ||
|
@@ -1844,15 +1813,6 @@ | |
lodash "^4.17.13" | ||
to-fast-properties "^2.0.0" | ||
|
||
"@babel/types@^7.9.5", "@babel/types@^7.9.6": | ||
version "7.9.6" | ||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.6.tgz#2c5502b427251e9de1bd2dff95add646d95cc9f7" | ||
integrity sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA== | ||
dependencies: | ||
"@babel/helper-validator-identifier" "^7.9.5" | ||
lodash "^4.17.13" | ||
to-fast-properties "^2.0.0" | ||
|
||
"@bcoe/v8-coverage@^0.2.3": | ||
version "0.2.3" | ||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" | ||
|
@@ -6851,12 +6811,12 @@ chrome-trace-event@^1.0.0, chrome-trace-event@^1.0.2: | |
dependencies: | ||
tslib "^1.9.0" | ||
|
||
chrono-node@^1.3.5: | ||
version "1.3.5" | ||
resolved "https://registry.yarnpkg.com/chrono-node/-/chrono-node-1.3.5.tgz#a2495298a32da82bcc01ad9be7d77efa5e244122" | ||
integrity sha1-oklSmKMtqCvMAa2b59d++l4kQSI= | ||
chrono-node@^1.4.6: | ||
version "1.4.6" | ||
resolved "https://registry.yarnpkg.com/chrono-node/-/chrono-node-1.4.6.tgz#dcdc59f1cc80e65d8f6c977bd6ad4e9b82008a8e" | ||
integrity sha512-CBUbwkj2gRdCSacmJ4UvKOSsSjW5jWce3kiruZSMgmGf7FKwc2ERat32yPSqJDR8aDeA0lUJxiDzZRhXZmXBqw== | ||
dependencies: | ||
moment "^2.10.3" | ||
dayjs "^1.8.19" | ||
|
||
[email protected], ci-info@^2.0.0: | ||
version "2.0.0" | ||
|
@@ -8321,6 +8281,11 @@ date-now@^0.1.4: | |
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" | ||
integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= | ||
|
||
dayjs@^1.8.19: | ||
version "1.8.26" | ||
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.26.tgz#c6d62ccdf058ca72a8d14bb93a23501058db9f1e" | ||
integrity sha512-KqtAuIfdNfZR5sJY1Dixr2Is4ZvcCqhb0dZpCOt5dGEFiMzoIbjkTSzUb4QKTCsP+WNpGwUjAFIZrnZvUxxkhw== | ||
|
||
de-indent@^1.0.2: | ||
version "1.0.2" | ||
resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" | ||
|
@@ -16556,7 +16521,7 @@ mocha@^7.1.2: | |
yargs-parser "13.1.2" | ||
yargs-unparser "1.6.0" | ||
|
||
[email protected], moment@^2.10.3, moment@^2.21.0, moment@^2.24.0: | ||
[email protected], moment@^2.21.0, moment@^2.24.0: | ||
version "2.24.0" | ||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" | ||
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== | ||
|