From fb88ef4f3e0dd2703042e2157212ef8da41928d8 Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Sat, 1 May 2021 23:41:37 +0000 Subject: [PATCH] Implemented findFuzzyTz, allowing for (valid) non-dropdown timezones to be passed --- src/__tests__/TimezoneSelect.test.tsx | 15 ++++++++++++ src/index.tsx | 34 ++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/__tests__/TimezoneSelect.test.tsx b/src/__tests__/TimezoneSelect.test.tsx index fa6a303..37713a5 100644 --- a/src/__tests__/TimezoneSelect.test.tsx +++ b/src/__tests__/TimezoneSelect.test.tsx @@ -119,6 +119,21 @@ test('load and passes react-select props', async () => { expect(getByText('Please Select a Timezone')).toBeInTheDocument() }) +test('can determine timezone by approximate match', async () => { + const { getByText } = render( + e} + /> + ) + + expect( + getByText( + /\(GMT\+[1-2]:00\) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna$/ + ) + ).toBeInTheDocument() +}) + test('select drop-downs must use the fireEvent.change', () => { const onChangeSpy = jest.fn() const { container } = render( diff --git a/src/index.tsx b/src/index.tsx index a97063f..acea996 100755 --- a/src/index.tsx +++ b/src/index.tsx @@ -172,10 +172,42 @@ const TimezoneSelect = ({ onChange && onChange(tz) } + const findFuzzyTz = (zone: string): ITimezoneOption => { + let currentTime; + try { + currentTime = spacetime.now(zone); + } + catch (err) { + return; + } + return getOptions.filter( (tz: ITimezoneOption) => (tz.offset === currentTime.timezone().current.offset)) + .map( (tz: ITimezoneOption) => { + let score = 0; + if (currentTime.timezones[ tz.value.toLowerCase() ] && !!currentTime.timezones[ tz.value.toLowerCase() ].dst === currentTime.timezone().hasDst) { + + if (tz.value.toLowerCase().indexOf(currentTime.tz.substr(currentTime.tz.indexOf('/') + 1)) !== -1) { + score += 8; + } + if (tz.label.toLowerCase().indexOf(currentTime.tz.substr(currentTime.tz.indexOf('/') + 1)) !== -1) { + score += 4; + } + if (tz.value.toLowerCase().indexOf(currentTime.tz.substr(0, currentTime.tz.indexOf('/')))) { + score += 2; + } + score += 1; + } else if (tz.value === 'GMT') { + score += 1; + } + return { tz, score }; + }) + .sort( (a, b) => b.score - a.score ) + .map( ({ tz, score }) => tz )[0]; + }; + const parseTimezone = (zone: ITimezone) => { if (typeof zone === 'object' && zone.value && zone.label) return zone if (typeof zone === 'string') { - return getOptions.find(tz => tz.value === zone) + return getOptions.find(tz => tz.value === zone) || ( zone.indexOf('/') !== -1 && findFuzzyTz(zone) ) } else if (zone.value && !zone.label) { return getOptions.find(tz => tz.value === zone.value) }