From 988886e8f152221525747278c06f3bb5827b7cc3 Mon Sep 17 00:00:00 2001 From: Chris Garcia Date: Mon, 13 Jul 2020 12:22:25 -0500 Subject: [PATCH] InputTime takes formatTime function for custom i18n time string formatting --- src/components/InputTime/AsString.tsx | 32 +++++++++++++------ .../InputTime/Dropdown/Dropdown.tsx | 24 +++++++++++--- src/components/InputTime/story.tsx | 11 +++++++ src/components/InputTime/utils.ts | 15 ++++++--- 4 files changed, 62 insertions(+), 20 deletions(-) diff --git a/src/components/InputTime/AsString.tsx b/src/components/InputTime/AsString.tsx index 90736899..d0d93a19 100644 --- a/src/components/InputTime/AsString.tsx +++ b/src/components/InputTime/AsString.tsx @@ -29,6 +29,7 @@ import styles from './InputTime.module.css'; export interface AsStringProps extends Omit { + formatTime?: (date: Date) => string; fuzzyInputProps?: InputProps; max?: string; min?: string; @@ -40,6 +41,7 @@ export interface AsStringProps const AsString: React.FC = ({ className = '', disabled, + formatTime, forwardedRef, fuzzyInputProps = {}, max, @@ -101,7 +103,7 @@ const AsString: React.FC = ({ // Fuzzy value is user input. const [fuzzyValue, setFuzzyValue] = useState( - value ? getLocaleTimeStringFromShortTimeString(value) : '' + value ? getLocaleTimeStringFromShortTimeString(value, { formatTime }) : '' ); const syncValidity = ( @@ -142,16 +144,21 @@ const AsString: React.FC = ({ }; const handleBlurFuzzyValue = () => { - setFuzzyValue(value ? getLocaleTimeStringFromShortTimeString(value) : ''); + setFuzzyValue( + value ? getLocaleTimeStringFromShortTimeString(value, { formatTime }) : '' + ); }; const handleSelectMenuItem = (e: { target: { value: Date } }) => { const dateTime = e.target.value; - const label = dateTime.toLocaleTimeString([], { - hour: 'numeric', - minute: '2-digit', - }); + const label = + typeof formatTime === 'function' + ? formatTime(dateTime) + : dateTime.toLocaleTimeString([], { + hour: 'numeric', + minute: '2-digit', + }); const timeString = getShortTimeString( dateTime.getHours(), @@ -170,11 +177,15 @@ const AsString: React.FC = ({ } if (localRef?.current && document.activeElement !== localRef?.current) { - setFuzzyValue(value ? getLocaleTimeStringFromShortTimeString(value) : ''); + setFuzzyValue( + value + ? getLocaleTimeStringFromShortTimeString(value, { formatTime }) + : '' + ); } syncValidity(shadowTimeInputRef, localRef); - }, [localRef, step, value]); + }, [formatTime, localRef, step, value]); // Sync validity on min/max changes useEffect(() => { @@ -212,16 +223,17 @@ const AsString: React.FC = ({ /> {showDropdown && ( )} diff --git a/src/components/InputTime/Dropdown/Dropdown.tsx b/src/components/InputTime/Dropdown/Dropdown.tsx index e1746df3..50c5367a 100644 --- a/src/components/InputTime/Dropdown/Dropdown.tsx +++ b/src/components/InputTime/Dropdown/Dropdown.tsx @@ -22,6 +22,7 @@ import styles from './Dropdown.module.css'; interface DropdownProps { className?: string; disabled?: boolean; + formatTime?: (date: Date) => string; max?: string; min?: string; onSelectMenuItem: Function; @@ -36,6 +37,7 @@ interface DropdownProps { const Dropdown: React.FC = ({ className = '', disabled, + formatTime, max, min, onSelectMenuItem, @@ -94,10 +96,13 @@ const Dropdown: React.FC = ({ do { attempts += 1; - const label = current.toLocaleTimeString([], { - hour: 'numeric', - minute: '2-digit', - }); + const label = + typeof formatTime === 'function' + ? formatTime(current) + : current.toLocaleTimeString([], { + hour: 'numeric', + minute: '2-digit', + }); if ( (maxDate === undefined || current <= maxDate) && @@ -116,7 +121,16 @@ const Dropdown: React.FC = ({ } while (attempts <= maxAttempts && current < end); return options; - }, [customStep, max, min, value, onSelectMenuItem, showDropdown, stepFrom]); + }, [ + customStep, + formatTime, + max, + min, + onSelectMenuItem, + showDropdown, + stepFrom, + value, + ]); return ( + + With a custom `formatTime` function + + `${date.getHours()}🎈:${date.getMinutes()}🐝` + } + onChange={action('onChange date')} + value={new Date().toISOString()} + /> + Requires you to pick a future date time { return date; }; -export const getLocaleTimeStringFromShortTimeString = (value: string) => - getDateTimeFromShortTimeString(value).toLocaleTimeString([], { - hour: 'numeric', - minute: '2-digit', - }); +export const getLocaleTimeStringFromShortTimeString = ( + value: string, + { formatTime } +) => + typeof formatTime === 'function' + ? formatTime(getDateTimeFromShortTimeString(value)) + : getDateTimeFromShortTimeString(value).toLocaleTimeString([], { + hour: 'numeric', + minute: '2-digit', + }); export const guessTimeFromString = (string: string) => { const invalidChars = new RegExp('[^\\d:\\spam.]', 'gi');