refactor: lexical (#1954)
This commit is contained in:
36
packages/blocks-editor/src/Lexical/UI/Button.css
Normal file
36
packages/blocks-editor/src/Lexical/UI/Button.css
Normal 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;
|
||||
}
|
||||
48
packages/blocks-editor/src/Lexical/UI/Button.tsx
Normal file
48
packages/blocks-editor/src/Lexical/UI/Button.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
17
packages/blocks-editor/src/Lexical/UI/Dialog.css
Normal file
17
packages/blocks-editor/src/Lexical/UI/Dialog.css
Normal 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;
|
||||
}
|
||||
31
packages/blocks-editor/src/Lexical/UI/Dialog.tsx
Normal file
31
packages/blocks-editor/src/Lexical/UI/Dialog.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
32
packages/blocks-editor/src/Lexical/UI/Input.css
Normal file
32
packages/blocks-editor/src/Lexical/UI/Input.css
Normal 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;
|
||||
}
|
||||
62
packages/blocks-editor/src/Lexical/UI/Modal.css
Normal file
62
packages/blocks-editor/src/Lexical/UI/Modal.css
Normal 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;
|
||||
}
|
||||
104
packages/blocks-editor/src/Lexical/UI/Modal.tsx
Normal file
104
packages/blocks-editor/src/Lexical/UI/Modal.tsx
Normal 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,
|
||||
);
|
||||
}
|
||||
41
packages/blocks-editor/src/Lexical/UI/TextInput.tsx
Normal file
41
packages/blocks-editor/src/Lexical/UI/TextInput.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user