Skip to content

Commit

Permalink
Fixed many usability issues with the CalendarDay field (#2930)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vultraz authored May 11, 2020
1 parent 3b0f413 commit 59ed631
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 113 deletions.
15 changes: 15 additions & 0 deletions .changeset/sour-taxis-hunt.md
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.
2 changes: 1 addition & 1 deletion packages/arch/packages/day-picker/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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.10.0",
"moment": "^2.24.0",
Expand Down
111 changes: 59 additions & 52 deletions packages/arch/packages/day-picker/src/TextDayPicker.js
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}
/>
);
}
);
16 changes: 5 additions & 11 deletions packages/fields/src/types/CalendarDay/views/Filter.js
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;
4 changes: 2 additions & 2 deletions packages/fields/src/types/DateTime/views/Filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand Down Expand Up @@ -38,4 +38,4 @@ const CalendarDayFilterView = props => {
);
};

export default CalendarDayFilterView;
export default DateTimeFilterView;
59 changes: 12 additions & 47 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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==
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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==
Expand Down

0 comments on commit 59ed631

Please sign in to comment.