Skip to content

Commit f061f53

Browse files
committed
Convert test suite to TypeScript
1 parent 5f805b5 commit f061f53

14 files changed

+229
-58
lines changed

test/LocaleOptions.jsx renamed to test/LocaleOptions.tsx

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,35 @@
1-
import React from 'react';
1+
import React, { useRef } from 'react';
22
import PropTypes from 'prop-types';
33

4-
export default function LocaleOptions({ locale, setLocale }) {
5-
function onChange(event) {
6-
let { value: nextLocale } = event.target;
4+
type LocaleOptionsProps = {
5+
locale: string | undefined;
6+
setLocale: (locale: string | undefined) => void;
7+
};
78

8-
if (nextLocale === 'null') {
9-
nextLocale = null;
10-
}
9+
export default function LocaleOptions({ locale, setLocale }: LocaleOptionsProps) {
10+
const customLocale = useRef<HTMLInputElement>(null);
1111

12-
setLocale(nextLocale);
12+
function onChange(event: React.ChangeEvent<HTMLInputElement>) {
13+
const { value: nextLocale } = event.target;
14+
15+
if (nextLocale === 'undefined') {
16+
setLocale(undefined);
17+
} else {
18+
setLocale(nextLocale);
19+
}
1320
}
1421

15-
function onCustomChange(event) {
22+
function onCustomChange(event: React.FormEvent<HTMLFormElement>) {
1623
event.preventDefault();
1724

18-
const { value: nextLocale } = event.target.customLocale;
25+
const input = customLocale.current;
26+
const { value: nextLocale } = input as HTMLInputElement;
1927

2028
setLocale(nextLocale);
2129
}
2230

2331
function resetLocale() {
24-
setLocale(null);
32+
setLocale(undefined);
2533
}
2634

2735
return (
@@ -30,12 +38,12 @@ export default function LocaleOptions({ locale, setLocale }) {
3038

3139
<div>
3240
<input
33-
checked={locale === null}
41+
checked={locale === undefined}
3442
id="localeDefault"
3543
name="locale"
3644
onChange={onChange}
3745
type="radio"
38-
value="null"
46+
value="undefined"
3947
/>
4048
<label htmlFor="localeDefault">Auto</label>
4149
</div>
@@ -81,13 +89,14 @@ export default function LocaleOptions({ locale, setLocale }) {
8189
id="customLocale"
8290
name="customLocale"
8391
pattern="^[a-z]{2}(-[A-Z0-9]{2,3})?$"
92+
ref={customLocale}
8493
type="text"
8594
/>
8695
&nbsp;
8796
<button style={{ display: 'none' }} type="submit">
8897
Set locale
8998
</button>
90-
<button disabled={locale === null} onClick={resetLocale} type="button">
99+
<button disabled={locale === undefined} onClick={resetLocale} type="button">
91100
Reset locale
92101
</button>
93102
</form>

test/MaxDetailOptions.jsx renamed to test/MaxDetailOptions.tsx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,29 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33

4-
const allViews = ['century', 'decade', 'year', 'month'];
4+
import type { Detail } from './shared/types';
55

6-
function upperCaseFirstLetter(str) {
6+
const allViews = ['century', 'decade', 'year', 'month'] as const;
7+
8+
function upperCaseFirstLetter(str: string) {
79
return str.slice(0, 1).toUpperCase() + str.slice(1);
810
}
911

10-
export default function MaxDetailOptions({ maxDetail, minDetail, setMaxDetail }) {
11-
function onChange(event) {
12+
type MaxDetailOptionsProps = {
13+
maxDetail: Detail;
14+
minDetail: Detail;
15+
setMaxDetail: (maxDetail: Detail) => void;
16+
};
17+
18+
export default function MaxDetailOptions({
19+
maxDetail,
20+
minDetail,
21+
setMaxDetail,
22+
}: MaxDetailOptionsProps) {
23+
function onChange(event: React.ChangeEvent<HTMLInputElement>) {
1224
const { value } = event.target;
1325

14-
setMaxDetail(value);
26+
setMaxDetail(value as Detail);
1527
}
1628

1729
const minDetailIndex = allViews.indexOf(minDetail);

test/MinDetailOptions.jsx renamed to test/MinDetailOptions.tsx

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,29 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33

4-
const allViews = ['century', 'decade', 'year', 'month'];
4+
import type { Detail } from './shared/types';
55

6-
function upperCaseFirstLetter(str) {
6+
const allViews = ['century', 'decade', 'year', 'month'] as const;
7+
8+
function upperCaseFirstLetter(str: string) {
79
return str.slice(0, 1).toUpperCase() + str.slice(1);
810
}
911

10-
export default function MinDetailOptions({ maxDetail, minDetail, setMinDetail }) {
11-
function onChange(event) {
12+
type MinDetailOptionsProps = {
13+
maxDetail: Detail;
14+
minDetail: Detail;
15+
setMinDetail: (maxDetail: Detail) => void;
16+
};
17+
18+
export default function MinDetailOptions({
19+
maxDetail,
20+
minDetail,
21+
setMinDetail,
22+
}: MinDetailOptionsProps) {
23+
function onChange(event: React.ChangeEvent<HTMLInputElement>) {
1224
const { value } = event.target;
1325

14-
setMinDetail(value);
26+
setMinDetail(value as Detail);
1527
}
1628

1729
const maxDetailIndex = allViews.indexOf(maxDetail);

test/Test.jsx renamed to test/Test.tsx

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import ViewOptions from './ViewOptions';
1212

1313
import './Test.css';
1414

15+
import type { Detail, LooseValue } from './shared/types';
16+
1517
const now = new Date();
1618

1719
const ariaLabelProps = {
@@ -29,26 +31,28 @@ const placeholderProps = {
2931
yearPlaceholder: 'yyyy',
3032
};
3133

32-
/* eslint-disable no-console */
33-
3434
const nineteenNinetyFive = new Date(1995, now.getUTCMonth() + 1, 15, 12);
3535
const fifteenthOfNextMonth = new Date(now.getUTCFullYear(), now.getUTCMonth() + 1, 15, 12);
3636

37+
/* eslint-disable no-console */
38+
39+
type ReturnValue = 'start' | 'end' | 'range';
40+
3741
export default function Test() {
38-
const portalContainer = useRef();
42+
const portalContainer = useRef<HTMLDivElement>(null);
3943
const [disabled, setDisabled] = useState(false);
40-
const [locale, setLocale] = useState(null);
41-
const [maxDate, setMaxDate] = useState(fifteenthOfNextMonth);
42-
const [maxDetail, setMaxDetail] = useState('month');
43-
const [minDate, setMinDate] = useState(nineteenNinetyFive);
44-
const [minDetail, setMinDetail] = useState('century');
44+
const [locale, setLocale] = useState<string>();
45+
const [maxDate, setMaxDate] = useState<Date | undefined>(fifteenthOfNextMonth);
46+
const [maxDetail, setMaxDetail] = useState<Detail>('month');
47+
const [minDate, setMinDate] = useState<Date | undefined>(nineteenNinetyFive);
48+
const [minDetail, setMinDetail] = useState<Detail>('century');
4549
const [renderInPortal, setRenderInPortal] = useState(false);
46-
const [returnValue /* , setReturnValue */] = useState('start');
50+
const [returnValue /* , setReturnValue */] = useState<ReturnValue>('start');
4751
const [required, setRequired] = useState(true);
4852
const [showLeadingZeros, setShowLeadingZeros] = useState(true);
4953
const [showNeighboringMonth, setShowNeighboringMonth] = useState(false);
5054
const [showWeekNumbers, setShowWeekNumbers] = useState(false);
51-
const [value, setValue] = useState(now);
55+
const [value, setValue] = useState<LooseValue>(now);
5256

5357
return (
5458
<div className="Test">

test/ValidityOptions.jsx renamed to test/ValidityOptions.tsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,33 @@ import React from 'react';
22
import PropTypes from 'prop-types';
33
import { getISOLocalDate } from '@wojtekmaj/date-utils';
44

5+
type ValidityOptionsProps = {
6+
maxDate?: Date;
7+
minDate?: Date;
8+
required?: boolean;
9+
setMaxDate: (maxDate: Date | undefined) => void;
10+
setMinDate: (minDate: Date | undefined) => void;
11+
setRequired: (required: boolean) => void;
12+
};
13+
514
export default function ValidityOptions({
615
maxDate,
716
minDate,
817
required,
918
setMaxDate,
1019
setMinDate,
1120
setRequired,
12-
}) {
13-
function onMinChange(event) {
21+
}: ValidityOptionsProps) {
22+
function onMinChange(event: React.ChangeEvent<HTMLInputElement>) {
1423
const { value } = event.target;
1524

16-
setMinDate(value ? new Date(value) : null);
25+
setMinDate(value ? new Date(value) : undefined);
1726
}
1827

19-
function onMaxChange(event) {
28+
function onMaxChange(event: React.ChangeEvent<HTMLInputElement>) {
2029
const { value } = event.target;
2130

22-
setMaxDate(value ? new Date(value) : null);
31+
setMaxDate(value ? new Date(value) : undefined);
2332
}
2433

2534
return (

test/ValueOptions.jsx renamed to test/ValueOptions.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,19 @@ import React from 'react';
22
import PropTypes from 'prop-types';
33
import { getISOLocalDate } from '@wojtekmaj/date-utils';
44

5-
export default function ValueOptions({ setValue, value }) {
6-
const date = [].concat(value)[0];
5+
import type { LooseValue } from './shared/types';
76

8-
function onChange(event) {
7+
type ValueOptionsProps = {
8+
setValue: (value: LooseValue) => void;
9+
value?: LooseValue;
10+
};
11+
12+
export default function ValueOptions({ setValue, value }: ValueOptionsProps) {
13+
const [date] = Array.isArray(value) ? value : [value];
14+
15+
function onChange(event: React.ChangeEvent<HTMLInputElement>) {
916
const { value: nextValue } = event.target;
17+
1018
setValue(nextValue && new Date(nextValue));
1119
}
1220

@@ -20,7 +28,7 @@ export default function ValueOptions({ setValue, value }) {
2028
id="date"
2129
onChange={onChange}
2230
type="date"
23-
value={date ? getISOLocalDate(date) : ''}
31+
value={date && date instanceof Date ? getISOLocalDate(date) : date || undefined}
2432
/>
2533
&nbsp;
2634
<button onClick={() => setValue(null)} type="button">

test/ViewOptions.jsx renamed to test/ViewOptions.tsx

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33

4+
type ViewOptionsProps = {
5+
disabled: boolean;
6+
renderInPortal: boolean;
7+
setDisabled: (disabled: boolean) => void;
8+
setRenderInPortal: (renderInPortal: boolean) => void;
9+
setShowLeadingZeros: (showLeadingZeros: boolean) => void;
10+
setShowNeighboringMonth: (showNeighboringMonth: boolean) => void;
11+
setShowWeekNumbers: (showWeekNumbers: boolean) => void;
12+
showLeadingZeros: boolean;
13+
showNeighboringMonth: boolean;
14+
showWeekNumbers: boolean;
15+
};
16+
417
export default function ViewOptions({
518
disabled,
619
renderInPortal,
@@ -12,32 +25,32 @@ export default function ViewOptions({
1225
showLeadingZeros,
1326
showNeighboringMonth,
1427
showWeekNumbers,
15-
}) {
16-
function onDisabledChange(event) {
28+
}: ViewOptionsProps) {
29+
function onDisabledChange(event: React.ChangeEvent<HTMLInputElement>) {
1730
const { checked } = event.target;
1831

1932
setDisabled(checked);
2033
}
2134

22-
function onShowLeadingZerosChange(event) {
35+
function onShowLeadingZerosChange(event: React.ChangeEvent<HTMLInputElement>) {
2336
const { checked } = event.target;
2437

2538
setShowLeadingZeros(checked);
2639
}
2740

28-
function onShowWeekNumbersChange(event) {
41+
function onShowWeekNumbersChange(event: React.ChangeEvent<HTMLInputElement>) {
2942
const { checked } = event.target;
3043

3144
setShowWeekNumbers(checked);
3245
}
3346

34-
function onShowNeighboringMonthChange(event) {
47+
function onShowNeighboringMonthChange(event: React.ChangeEvent<HTMLInputElement>) {
3548
const { checked } = event.target;
3649

3750
setShowNeighboringMonth(checked);
3851
}
3952

40-
function onRenderInPortalChange(event) {
53+
function onRenderInPortalChange(event: React.ChangeEvent<HTMLInputElement>) {
4154
const { checked } = event.target;
4255

4356
setRenderInPortal(checked);

test/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
</head>
88
<body>
99
<div id="react-root"></div>
10-
<script type="module" src="./index.jsx"></script>
10+
<script type="module" src="./index.tsx"></script>
1111
</body>
1212
</html>

test/index.jsx renamed to test/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { createRoot } from 'react-dom/client';
33

44
import Test from './Test';
55

6-
createRoot(document.getElementById('react-root')).render(
6+
createRoot(document.getElementById('react-root') as HTMLDivElement).render(
77
<StrictMode>
88
<Test />
99
</StrictMode>,

test/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
"react-dom": "^18.2.0"
2323
},
2424
"devDependencies": {
25+
"@types/babel__core": "^7.20.0",
2526
"@vitejs/plugin-react": "^3.0.0",
27+
"typescript": "^5.0.3",
2628
"vite": "^4.0.0"
2729
}
2830
}

0 commit comments

Comments
 (0)