Skip to content

Commit ef76bf2

Browse files
authored
Port components to ts 5 (#2724)
* Paginator & tests (plus some imports that needlessly specify .js) * progress-ring * quote component simplified and moved to body-units * Radio panel * role-selector * salesforce-form, plus finally fixed the tilde issue * select * share icons (always minimal) * Prettier
1 parent 58d7798 commit ef76bf2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+778
-547
lines changed

src/app/components/body-units/body-units.tsx

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22
import RawHTML from '~/components/jsx-helpers/raw-html';
3-
import Quote from '~/components/quote/quote.js';
3+
import Quote from './quote';
44
import JITLoad from '~/helpers/jit-load';
55

66
function Unknown({data, type}: {data: unknown; type: string}) {
@@ -19,7 +19,7 @@ type CTAData = {
1919
description: string;
2020
button_href: string;
2121
button_text: string;
22-
}
22+
};
2323

2424
function CTA({data}: {data: CTAData}) {
2525
const alignment = convertAlignment(data.alignment);
@@ -45,7 +45,7 @@ type AImageData = {
4545
original: {
4646
src: string;
4747
alt: string;
48-
}
48+
};
4949
};
5050
alignment: string;
5151
alt_text: string;
@@ -71,25 +71,25 @@ function AlignedImage({data}: {data: AImageData}) {
7171
type PQData = {
7272
quote: string;
7373
attribution: string;
74-
}
74+
};
7575

7676
function PullQuote({data}: {data: PQData}) {
7777
const model = {
78-
image: {},
7978
content: data.quote,
8079
attribution: data.attribution
8180
};
8281

8382
return <Quote model={model} />;
8483
}
8584

86-
8785
export type DocumentData = {
8886
download_url: string;
89-
}
87+
};
9088

9189
function Document({data}: {data: DocumentData}) {
92-
return <JITLoad importFn={() => import('./import-pdf-unit.js')} data={data} />;
90+
return (
91+
<JITLoad importFn={() => import('./import-pdf-unit.js')} data={data} />
92+
);
9393
}
9494

9595
// Using CMS tags, which are not camel-case
@@ -105,25 +105,39 @@ const bodyUnits = {
105105

106106
export type UnitType = {
107107
id: string;
108-
} & ({
109-
type: 'paragraph' | 'aligned_html';
110-
value: string;
111-
} | {
112-
type: 'aligned_image';
113-
value: AImageData;
114-
} | {
115-
type: 'pullquote';
116-
value: PQData;
117-
} | {
118-
type: 'document';
119-
value: DocumentData;
120-
} | {
121-
type: 'blog_cta';
122-
value: CTAData;
123-
})
108+
} & (
109+
| {
110+
type: 'paragraph' | 'aligned_html';
111+
value: string;
112+
}
113+
| {
114+
type: 'aligned_image';
115+
value: AImageData;
116+
}
117+
| {
118+
type: 'pullquote';
119+
value: PQData;
120+
}
121+
| {
122+
type: 'document';
123+
value: DocumentData;
124+
}
125+
| {
126+
type: 'blog_cta';
127+
value: CTAData;
128+
}
129+
);
124130

125131
export default function BodyUnit({unit}: {unit: UnitType}) {
126-
const Unit = bodyUnits[unit.type] as ({data}: {data: typeof unit.value}) => React.JSX.Element;
127-
128-
return Unit ? <Unit data={unit.value} /> : <Unknown data={unit.value} type={unit.type} />;
132+
const Unit = bodyUnits[unit.type] as ({
133+
data
134+
}: {
135+
data: typeof unit.value;
136+
}) => React.JSX.Element;
137+
138+
return Unit ? (
139+
<Unit data={unit.value} />
140+
) : (
141+
<Unknown data={unit.value} type={unit.type} />
142+
);
129143
}

src/app/components/body-units/pdf-unit.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ function toggleFullscreen(
6666
if (!fsFn) {
6767
return;
6868
}
69-
elem.requestFullscreen = elem[fsFn as keyof typeof elem] as () => Promise<void>;
69+
elem.requestFullscreen = elem[
70+
fsFn as keyof typeof elem
71+
] as () => Promise<void>;
7072

7173
if (!document.fullscreenElement) {
7274
elem.requestFullscreen().catch((err) => {
@@ -123,7 +125,9 @@ export default function Document({data}: {data: DocumentData}) {
123125
>
124126
<PDF
125127
file={data.download_url}
126-
onLoadSuccess={({numPages: n}: {numPages: number}) => setNumPages(n)}
128+
onLoadSuccess={({numPages: n}: {numPages: number}) =>
129+
setNumPages(n)
130+
}
127131
inputRef={ref}
128132
>
129133
<div className="pages-side-by-side">
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import React from 'react';
2+
import RawHTML from '~/components/jsx-helpers/raw-html';
3+
4+
export default function Quote({
5+
model
6+
}: {
7+
model: {
8+
content: string;
9+
attribution: string;
10+
};
11+
}) {
12+
return (
13+
<div className="quote">
14+
<blockquote>
15+
<RawHTML html={model.content} />
16+
{Boolean(model.attribution) && (
17+
<div className="attribution">{model.attribution}</div>
18+
)}
19+
</blockquote>
20+
</div>
21+
);
22+
}

src/app/components/form-select/form-select.tsx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,28 @@
11
import React from 'react';
22
import DropdownSelect from '~/components/select/drop-down/drop-down';
3+
import {SelectItem} from '../select/select-context';
34

45
export default function FormSelect({
5-
label, name, selectAttributes, options=[], onValueUpdate
6+
label,
7+
name,
8+
selectAttributes,
9+
options = [],
10+
onValueUpdate
611
}: {
712
label: string;
813
name: string;
914
selectAttributes: object;
10-
options: unknown[];
11-
onValueUpdate?: unknown;
15+
options: SelectItem[];
16+
onValueUpdate?: (v: string) => void;
1217
}) {
1318
return (
1419
<div className="control-group">
1520
{label && <label className="field-label">{label}</label>}
1621
<DropdownSelect
17-
name={name} {...selectAttributes}
18-
options={options} onValueUpdate={onValueUpdate}
22+
name={name}
23+
{...selectAttributes}
24+
options={options}
25+
onValueUpdate={onValueUpdate}
1926
/>
2027
</div>
2128
);

src/app/components/paginator/paginator-context.js

Lines changed: 0 additions & 26 deletions
This file was deleted.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import {useState, useCallback} from 'react';
2+
import buildContext from '~/components/jsx-helpers/build-context';
3+
4+
type ContextParams = {
5+
resultsPerPage?: number;
6+
initialPage?: number;
7+
};
8+
9+
function useContextValue(params: ContextParams = {}) {
10+
const {resultsPerPage = 1, initialPage = 1} = params;
11+
const [currentPage, setCurrentPage] = useState(initialPage);
12+
const firstOnPage = (currentPage - 1) * resultsPerPage;
13+
const lastOnPage = firstOnPage + resultsPerPage - 1;
14+
const isVisible = useCallback(
15+
(childIndex: number) =>
16+
childIndex >= firstOnPage && childIndex <= lastOnPage,
17+
[firstOnPage, lastOnPage]
18+
);
19+
const visibleChildren = useCallback(
20+
(children: React.ReactNode[]) =>
21+
children.slice(firstOnPage, lastOnPage + 1),
22+
[firstOnPage, lastOnPage]
23+
);
24+
25+
return {
26+
currentPage,
27+
setCurrentPage,
28+
resultsPerPage,
29+
firstOnPage,
30+
lastOnPage,
31+
isVisible,
32+
visibleChildren
33+
};
34+
}
35+
36+
const {useContext, ContextProvider} = buildContext({useContextValue});
37+
38+
export {useContext as default, ContextProvider as PaginatorContextProvider};

src/app/components/paginator/search-results/paginator.js renamed to src/app/components/paginator/search-results/paginator.tsx

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,28 @@ import React from 'react';
22
import usePaginatorContext from '../paginator-context';
33
import './paginator.scss';
44

5-
function getPageIndicators(pages, currentPage) {
5+
function getPageIndicators(pages: number, currentPage: number) {
66
const indicatorCount = Math.min(pages, 5);
7-
const propsFor = (label) => ({
7+
const propsFor = (label: number) => ({
88
label,
99
page: `page ${label}`,
1010
disabled: label === currentPage,
1111
selected: label === currentPage
1212
});
13-
const result = Array(indicatorCount).fill();
13+
const result = Array(indicatorCount).fill(0);
1414

1515
if (pages - currentPage < 3) {
1616
result[0] = pages - indicatorCount + 1;
1717
} else {
18-
result[0] = (currentPage > 3) ? currentPage - 2 : 1;
18+
result[0] = currentPage > 3 ? currentPage - 2 : 1;
1919
}
2020
for (let i = 1; i < indicatorCount; ++i) {
21-
result[i] = result[i-1] + 1;
21+
result[i] = result[i - 1] + 1;
2222
}
2323
return result.map(propsFor);
2424
}
2525

26-
function PageButtonBar({pages}) {
26+
function PageButtonBar({pages}: {pages: number}) {
2727
const {currentPage, setCurrentPage} = usePaginatorContext();
2828
const disablePrevious = currentPage === 1;
2929
const disableNext = currentPage === pages;
@@ -37,32 +37,44 @@ function PageButtonBar({pages}) {
3737
}
3838

3939
return (
40-
<nav aria-label='pagination'>
41-
<ul className='no-bullets button-bar'>
42-
<li><button disabled={disablePrevious} onClick={prevPage}>Previous</button></li>
43-
{
44-
pageIndicators.map((indicator) =>
45-
<li key={indicator.page}><button
40+
<nav aria-label="pagination">
41+
<ul className="no-bullets button-bar">
42+
<li>
43+
<button disabled={disablePrevious} onClick={prevPage}>
44+
Previous
45+
</button>
46+
</li>
47+
{pageIndicators.map((indicator) => (
48+
<li key={indicator.page}>
49+
<button
4650
disabled={indicator.disabled}
4751
aria-current={indicator.selected ? 'page' : 'false'}
4852
aria-label={indicator.page}
4953
onClick={() => setCurrentPage(indicator.label)}
50-
>{indicator.label}</button></li>
51-
)
52-
}
53-
<li><button disabled={disableNext} onClick={nextPage}>Next</button></li>
54+
>
55+
{indicator.label}
56+
</button>
57+
</li>
58+
))}
59+
<li>
60+
<button disabled={disableNext} onClick={nextPage}>
61+
Next
62+
</button>
63+
</li>
5464
</ul>
5565
</nav>
5666
);
5767
}
5868

59-
export function PaginatorControls({items}) {
69+
export function PaginatorControls({items}: {items: number}) {
6070
const {currentPage, resultsPerPage} = usePaginatorContext();
6171
const pages = Math.ceil(items / resultsPerPage);
6272
const firstIndex = (currentPage - 1) * resultsPerPage;
6373
const endBefore = Math.min(firstIndex + resultsPerPage, items);
6474
const resultRange = `${firstIndex + 1}-${endBefore}`;
65-
const searchTerm = new window.URLSearchParams(window.location.search).get('q');
75+
const searchTerm = new window.URLSearchParams(window.location.search).get(
76+
'q'
77+
);
6678

6779
return (
6880
<div className="paginator">

0 commit comments

Comments
 (0)