Skip to content

Commit db34425

Browse files
authored
Merge branch 'main' into cookieyes
2 parents 19fefa8 + a8c5c19 commit db34425

22 files changed

+1283
-1088
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@openstax/os-webview",
3-
"version": "2.138.0",
3+
"version": "2.140.0",
44
"description": "OpenStax webview",
55
"scripts": {
66
"test": "jest --coverage ./test/src",

src/app/components/contact-info/contact-info.js renamed to src/app/components/contact-info/contact-info.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import {useIntl} from 'react-intl';
44
import SchoolSelector from '~/components/school-selector/school-selector';
55
import './contact-info.scss';
66

7-
export default function ContactInfo({children}) {
7+
export default function ContactInfo({
8+
children
9+
}: React.PropsWithChildren<Record<never, never>>) {
810
const {formatMessage} = useIntl();
911

1012
return (

src/app/components/dialog/dialog.d.ts

-30
This file was deleted.

src/app/components/dialog/dialog.js renamed to src/app/components/dialog/dialog.tsx

+28-34
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,44 @@
11
import React from 'react';
2-
import ReactModal from 'react-modal';
2+
import ReactModal, {Aria} from 'react-modal';
33
import RawHTML from '~/components/jsx-helpers/raw-html';
44
import cn from 'classnames';
55
import './dialog.scss';
66

7-
function PutAway({noTitle, onClick}) {
7+
function PutAway({
8+
noTitle,
9+
onClick
10+
}: {
11+
noTitle?: boolean;
12+
onClick?: () => void;
13+
}) {
814
return (
915
<button
1016
className={cn('put-away', {'no-title-bar': noTitle})}
1117
hidden={!onClick}
12-
onClick={() => onClick()}
18+
onClick={() => onClick?.()}
1319
aria-label="close"
1420
>
1521
×
1622
</button>
1723
);
1824
}
1925

20-
export function FooterDialog({isOpen, title, children, className}) {
21-
React.useLayoutEffect(() => {
22-
const footerEl = document.getElementById('footer');
23-
24-
footerEl?.style.setProperty('z-index', 1);
25-
26-
return () => footerEl?.style.removeProperty('z-index');
27-
}, []);
28-
29-
if (!isOpen) {
30-
return null;
31-
}
32-
33-
return (
34-
<dialog className={cn('footer-dialog', className)}>
35-
{title && (
36-
<div className="title-bar">
37-
<RawHTML Tag="span" html={title} />
38-
</div>
39-
)}
40-
{children}
41-
</dialog>
42-
);
43-
}
44-
45-
// eslint-disable-next-line complexity
4626
export default function Dialog({
4727
isOpen,
4828
title,
4929
onPutAway,
5030
children,
51-
className = undefined,
31+
className,
5232
closeOnOutsideClick = false,
5333
aria = title ? {labelledby: 'modal-dialog-title'} : {label: 'missing label'}
54-
}) {
34+
}: React.PropsWithChildren<{
35+
isOpen: boolean;
36+
title?: string;
37+
onPutAway?: () => void;
38+
className?: string;
39+
closeOnOutsideClick?: boolean;
40+
aria?: Aria & {label?: string};
41+
}>) {
5542
const overlayClassName = className ? `modal-overlay-${className}` : '';
5643

5744
return (
@@ -94,7 +81,14 @@ export function useDialog(initiallyOpen = false) {
9481
afterClose = () => null,
9582
aria,
9683
...otherProps
97-
}) {
84+
}: React.PropsWithChildren<{
85+
title?: string;
86+
modal?: boolean;
87+
className?: string;
88+
showPutAway?: boolean;
89+
afterClose?: () => void;
90+
aria?: Aria;
91+
}>) {
9892
const Modal = modal ? ReactModal : React.Fragment;
9993
const closeAndAfterClose = () => {
10094
close();
@@ -113,7 +107,7 @@ export function useDialog(initiallyOpen = false) {
113107
title={title}
114108
className={className}
115109
isOpen={showDialog}
116-
onPutAway={showPutAway && closeAndAfterClose}
110+
onPutAway={showPutAway ? closeAndAfterClose : undefined}
117111
aria={aria}
118112
>
119113
{children}
@@ -122,6 +116,6 @@ export function useDialog(initiallyOpen = false) {
122116
);
123117
}
124118

125-
return [BoundDialog, open, close, showDialog];
119+
return [BoundDialog, open, close, showDialog] as const;
126120
}, [showDialog]);
127121
}

src/app/components/faq-section/faq-section.js renamed to src/app/components/faq-section/faq-section.tsx

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
import React from 'react';
22
import AccordionGroup from '~/components/accordion-group/accordion-group';
33

4-
export default function FAQ({heading, items}) {
4+
export default function FAQ({
5+
heading,
6+
items
7+
}: {
8+
heading: string;
9+
items: Parameters<typeof AccordionGroup>[0]['items'];
10+
}) {
511
return (
6-
<div className='boxed'>
12+
<div className="boxed">
713
<h1>{heading}</h1>
814
<div className="articles">
915
<AccordionGroup items={items} noScroll />

src/app/components/form-checkboxgroup/form-checkboxgroup.js

-51
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import React from 'react';
2+
3+
type Item = {
4+
label: string;
5+
value: string;
6+
};
7+
8+
function Option({
9+
item,
10+
name,
11+
onChange,
12+
checked
13+
}: {
14+
item: Item;
15+
name: string;
16+
onChange?: React.ChangeEventHandler<HTMLInputElement>;
17+
checked: boolean;
18+
}) {
19+
const inputProps = item.value
20+
? {
21+
name,
22+
value: item.value
23+
}
24+
: {};
25+
26+
return (
27+
<div className="checkbox-control-group">
28+
<label>
29+
<input
30+
type="checkbox"
31+
{...inputProps}
32+
checked={checked}
33+
onChange={onChange}
34+
/>
35+
{item.label}
36+
</label>
37+
</div>
38+
);
39+
}
40+
41+
export default function FormCheckboxgroup({
42+
name,
43+
label,
44+
longLabel,
45+
instructions,
46+
options,
47+
onChange
48+
}: {
49+
name: string;
50+
label?: string;
51+
longLabel?: string;
52+
instructions?: string;
53+
options: Item[];
54+
onChange?: (arr: unknown[]) => void;
55+
}) {
56+
const checkedItems = React.useMemo(() => new window.Set(), []);
57+
const onItemChange = React.useCallback(
58+
({target: {value, checked}}: React.ChangeEvent<HTMLInputElement>) => {
59+
const method = checked ? 'add' : 'delete';
60+
61+
checkedItems[method](value);
62+
onChange?.(Array.from(checkedItems.values()));
63+
},
64+
[checkedItems, onChange]
65+
);
66+
67+
return (
68+
<div className="form-checkboxgroup">
69+
{label && <label className="field-label">{label}</label>}
70+
{longLabel && (
71+
<label className="field-long-label">{longLabel}</label>
72+
)}
73+
{instructions && <label className="hint">{instructions}</label>}
74+
{options.map((item) => (
75+
<Option
76+
item={item}
77+
name={name}
78+
key={item.value}
79+
checked={checkedItems.has(item.value)}
80+
onChange={onItemChange}
81+
/>
82+
))}
83+
</div>
84+
);
85+
}

0 commit comments

Comments
 (0)