refactor: lexical (#1954)

This commit is contained in:
Mo
2022-11-07 10:42:44 -06:00
committed by GitHub
parent 99bae83f8b
commit 2ed01a071c
182 changed files with 8525 additions and 1126 deletions

View File

@@ -0,0 +1,36 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
.Button__root {
padding-top: 10px;
padding-bottom: 10px;
padding-left: 15px;
padding-right: 15px;
border: 0px;
background-color: #eee;
border-radius: 5px;
cursor: pointer;
font-size: 14px;
}
.Button__root:hover {
background-color: #ddd;
}
.Button__small {
padding-top: 5px;
padding-bottom: 5px;
padding-left: 10px;
padding-right: 10px;
font-size: 13px;
}
.Button__disabled {
cursor: not-allowed;
}
.Button__disabled:hover {
background-color: #eee;
}

View File

@@ -0,0 +1,48 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import './Button.css';
import {ReactNode} from 'react';
import joinClasses from '../Utils/join-classes';
export default function Button({
'data-test-id': dataTestId,
children,
className,
onClick,
disabled,
small,
title,
}: {
'data-test-id'?: string;
children: ReactNode;
className?: string;
disabled?: boolean;
onClick: () => void;
small?: boolean;
title?: string;
}): JSX.Element {
return (
<button
disabled={disabled}
className={joinClasses(
'Button__root',
disabled && 'Button__disabled',
small && 'Button__small',
className,
)}
onClick={onClick}
title={title}
aria-label={title}
{...(dataTestId && {'data-test-id': dataTestId})}>
{children}
</button>
);
}

View File

@@ -0,0 +1,17 @@
.DialogActions {
display: flex;
flex-direction: row;
justify-content: right;
margin-top: 20px;
}
.DialogButtonsList {
display: flex;
flex-direction: column;
justify-content: right;
margin-top: 20px;
}
.DialogButtonsList button {
margin-bottom: 20px;
}

View File

@@ -0,0 +1,31 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import './Dialog.css';
import {ReactNode} from 'react';
type Props = Readonly<{
'data-test-id'?: string;
children: ReactNode;
}>;
export function DialogButtonsList({children}: Props): JSX.Element {
return <div className="DialogButtonsList">{children}</div>;
}
export function DialogActions({
'data-test-id': dataTestId,
children,
}: Props): JSX.Element {
return (
<div className="DialogActions" data-test-id={dataTestId}>
{children}
</div>
);
}

View File

@@ -0,0 +1,32 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
.Input__wrapper {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 10px;
}
.Input__label {
display: flex;
flex: 1;
color: #666;
}
.Input__input {
display: flex;
flex: 2;
border: 1px solid #999;
padding-top: 7px;
padding-bottom: 7px;
padding-left: 10px;
padding-right: 10px;
font-size: 16px;
border-radius: 5px;
min-width: 0;
}

View File

@@ -0,0 +1,62 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*
*/
.Modal__overlay {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
flex-direction: column;
top: 0px;
bottom: 0px;
left: 0px;
right: 0px;
background-color: rgba(40, 40, 40, 0.6);
flex-grow: 0px;
flex-shrink: 1px;
z-index: 100;
}
.Modal__modal {
padding: 20px;
min-height: 100px;
min-width: 300px;
display: flex;
flex-grow: 0px;
background-color: #fff;
flex-direction: column;
position: relative;
box-shadow: 0 0 20px 0 #444;
border-radius: 10px;
}
.Modal__title {
color: #444;
margin: 0px;
padding-bottom: 10px;
border-bottom: 1px solid #ccc;
}
.Modal__closeButton {
border: 0px;
position: absolute;
right: 20px;
border-radius: 20px;
justify-content: center;
align-items: center;
display: flex;
width: 30px;
height: 30px;
text-align: center;
cursor: pointer;
background-color: #eee;
}
.Modal__closeButton:hover {
background-color: #ddd;
}
.Modal__content {
padding-top: 20px;
}

View File

@@ -0,0 +1,104 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import './Modal.css';
import {ReactNode, useEffect, useRef} from 'react';
import {createPortal} from 'react-dom';
function PortalImpl({
onClose,
children,
title,
closeOnClickOutside,
}: {
children: ReactNode;
closeOnClickOutside: boolean;
onClose: () => void;
title: string;
}) {
const modalRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (modalRef.current !== null) {
modalRef.current.focus();
}
}, []);
useEffect(() => {
let modalOverlayElement: HTMLElement | null = null;
const handler = (event: KeyboardEvent) => {
if (event.keyCode === 27) {
onClose();
}
};
const clickOutsideHandler = (event: MouseEvent) => {
const target = event.target;
if (
modalRef.current !== null &&
!modalRef.current.contains(target as Node) &&
closeOnClickOutside
) {
onClose();
}
};
if (modalRef.current !== null) {
modalOverlayElement = modalRef.current?.parentElement;
if (modalOverlayElement !== null) {
modalOverlayElement?.addEventListener('click', clickOutsideHandler);
}
}
window.addEventListener('keydown', handler);
return () => {
window.removeEventListener('keydown', handler);
if (modalOverlayElement !== null) {
modalOverlayElement?.removeEventListener('click', clickOutsideHandler);
}
};
}, [closeOnClickOutside, onClose]);
return (
<div className="Modal__overlay" role="dialog">
<div className="Modal__modal" tabIndex={-1} ref={modalRef}>
<h2 className="Modal__title">{title}</h2>
<button
className="Modal__closeButton"
aria-label="Close modal"
type="button"
onClick={onClose}>
X
</button>
<div className="Modal__content">{children}</div>
</div>
</div>
);
}
export default function Modal({
onClose,
children,
title,
closeOnClickOutside = false,
}: {
children: ReactNode;
closeOnClickOutside?: boolean;
onClose: () => void;
title: string;
}): JSX.Element {
return createPortal(
<PortalImpl
onClose={onClose}
title={title}
closeOnClickOutside={closeOnClickOutside}>
{children}
</PortalImpl>,
document.body,
);
}

View File

@@ -0,0 +1,41 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import './Input.css';
type Props = Readonly<{
'data-test-id'?: string;
label: string;
onChange: (val: string) => void;
placeholder?: string;
value: string;
}>;
export default function TextInput({
label,
value,
onChange,
placeholder = '',
'data-test-id': dataTestId,
}: Props): JSX.Element {
return (
<div className="Input__wrapper">
<label className="Input__label">{label}</label>
<input
type="text"
className="Input__input"
placeholder={placeholder}
value={value}
onChange={(e) => {
onChange(e.target.value);
}}
data-test-id={dataTestId}
/>
</div>
);
}