diff --git a/.changeset/sour-taxis-hunt.md b/.changeset/sour-taxis-hunt.md
new file mode 100644
index 00000000000..e841053daf9
--- /dev/null
+++ b/.changeset/sour-taxis-hunt.md
@@ -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.
\ No newline at end of file
diff --git a/packages/arch/packages/day-picker/package.json b/packages/arch/packages/day-picker/package.json
index df1271ec153..42e044639f2 100644
--- a/packages/arch/packages/day-picker/package.json
+++ b/packages/arch/packages/day-picker/package.json
@@ -20,7 +20,7 @@
"@babel/runtime": "^7.8.4",
"@emotion/core": "^10.0.28",
"@emotion/styled": "^10.0.27",
- "chrono-node": "^1.3.5",
+ "chrono-node": "^1.4.6",
"date-fns": "^1.30.1",
"intersection-observer": "^0.5.1",
"moment": "^2.24.0",
diff --git a/packages/arch/packages/day-picker/src/TextDayPicker.js b/packages/arch/packages/day-picker/src/TextDayPicker.js
index 002ff20fd71..0e6380d6340 100644
--- a/packages/arch/packages/day-picker/src/TextDayPicker.js
+++ b/packages/arch/packages/day-picker/src/TextDayPicker.js
@@ -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 (
-
- );
-};
-
-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 (
+
+ );
+ }
+);
diff --git a/packages/fields/src/types/CalendarDay/views/Filter.js b/packages/fields/src/types/CalendarDay/views/Filter.js
index 97e4ac19658..aadfadae16a 100644
--- a/packages/fields/src/types/CalendarDay/views/Filter.js
+++ b/packages/fields/src/types/CalendarDay/views/Filter.js
@@ -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 ;
+ return ;
};
export default CalendarDayFilterView;
diff --git a/packages/fields/src/types/DateTime/views/Filter.js b/packages/fields/src/types/DateTime/views/Filter.js
index fb24fc062f1..54a19a86d99 100644
--- a/packages/fields/src/types/DateTime/views/Filter.js
+++ b/packages/fields/src/types/DateTime/views/Filter.js
@@ -3,7 +3,7 @@ import { format } from 'date-fns';
import { DayTimePicker } from '@arch-ui/day-picker';
import { stringifyDate, parseDate } from './utils';
-const CalendarDayFilterView = props => {
+const DateTimeFilterView = props => {
const parsedDate = props.value ? parseDate(props.value) : parseDate(new Date().toISOString());
let handleDayChange = day => {
@@ -38,4 +38,4 @@ const CalendarDayFilterView = props => {
);
};
-export default CalendarDayFilterView;
+export default DateTimeFilterView;
diff --git a/yarn.lock b/yarn.lock
index da930b19f01..112de0b8612 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -421,14 +421,14 @@
"@babel/template" "^7.7.4"
"@babel/types" "^7.7.4"
-"@babel/helper-function-name@^7.8.3":
- version "7.8.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca"
- integrity sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==
+"@babel/helper-function-name@^7.8.3", "@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.8.3"
+ "@babel/types" "^7.9.5"
"@babel/helper-get-function-arity@^7.7.4":
version "7.7.4"
@@ -598,10 +598,10 @@
dependencies:
"@babel/types" "^7.8.3"
-"@babel/helper-validator-identifier@^7.9.0":
- version "7.9.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz#ad53562a7fc29b3b9a91bbf7d10397fd146346ed"
- integrity sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==
+"@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"
@@ -766,10 +766,19 @@
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-syntax-object-rest-spread" "^7.2.0"
-"@babel/plugin-proposal-object-rest-spread@^7.0.0", "@babel/plugin-proposal-object-rest-spread@^7.3.2", "@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.8.3"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz#eb5ae366118ddca67bed583b53d7554cad9951bb"
- integrity sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA==
+"@babel/plugin-proposal-object-rest-spread@7.9.5":
+ version "7.9.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.5.tgz#3fd65911306d8746014ec0d0cf78f0e39a149116"
+ integrity sha512-VP2oXvAf7KCYTthbUHwBlewbl1Iq059f6seJGsxMizaCdgHIeczOr7FBqELhSqfkIl04Fi8okzWzl63UKbQmmg==
+ 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.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==
dependencies:
"@babel/helper-plugin-utils" "^7.8.3"
"@babel/plugin-syntax-object-rest-spread" "^7.8.0"
@@ -1149,12 +1158,11 @@
"@babel/helper-plugin-utils" "^7.8.3"
"@babel/helper-replace-supers" "^7.8.3"
-"@babel/plugin-transform-parameters@^7.0.0", "@babel/plugin-transform-parameters@^7.4.4", "@babel/plugin-transform-parameters@^7.8.4":
- version "7.8.4"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.4.tgz#1d5155de0b65db0ccf9971165745d3bb990d77d3"
- integrity sha512-IsS3oTxeTsZlE5KqzTbcC2sV0P9pXdec53SU+Yxv7o/6dvGM5AkTotQKhoSffhNgZ/dftsSiOoxy7evCYJXzVA==
+"@babel/plugin-transform-parameters@^7.0.0", "@babel/plugin-transform-parameters@^7.4.4", "@babel/plugin-transform-parameters@^7.8.4", "@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-call-delegate" "^7.8.3"
"@babel/helper-get-function-arity" "^7.8.3"
"@babel/helper-plugin-utils" "^7.8.3"
@@ -1692,12 +1700,21 @@
lodash "^4.17.13"
to-fast-properties "^2.0.0"
+<<<<<<< HEAD
"@babel/types@^7.8.6", "@babel/types@^7.9.0":
version "7.9.0"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.0.tgz#00b064c3df83ad32b2dbf5ff07312b15c7f1efb5"
integrity sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==
dependencies:
"@babel/helper-validator-identifier" "^7.9.0"
+=======
+"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.4.4", "@babel/types@^7.6.0", "@babel/types@^7.7.1", "@babel/types@^7.7.2", "@babel/types@^7.7.4", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.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"
+>>>>>>> 59ed6310b... Fixed many usability issues with the CalendarDay field (#2930)
lodash "^4.17.13"
to-fast-properties "^2.0.0"
@@ -6671,12 +6688,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"
ci-info@2.0.0, ci-info@^2.0.0:
version "2.0.0"
@@ -8177,6 +8194,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"
@@ -16437,7 +16459,7 @@ mocha@^7.0.1:
yargs-parser "13.1.1"
yargs-unparser "1.6.0"
-moment@2.24.0, moment@^2.10.3, moment@^2.21.0, moment@^2.24.0:
+moment@2.24.0, 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==