init: the first public commit for AFFiNE
12
libs/components/common/src/lib/Logo/LogoImg.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import type { CSSProperties } from 'react';
|
||||
|
||||
export const LogoImg = ({ style = {} }: { style: CSSProperties }) => {
|
||||
return (
|
||||
<img
|
||||
style={style}
|
||||
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABzJJREFUeNrs3T1SHEcUAOAxpQOQON/EOcpdFpwAfAKhE0ikToBEqawTCG6ATiDkUu7NnaxjJXsET0uDDOiHfrM9fzvfV7VFMgzN9Mzr1z3dvVUFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBhP5U82c+//rGofyweOGz18cPLlUsPw3tU+Hyn9ef4gWOW9edxX/9gHZRSeZ6O7Lqf1EFwObEyP/tR4P7t+T9nTf3nOP/r9S9nGXW3X/94l3G+VK7HdfnWBe+b9Hf3Mw8/qP/2dcY5X9U/9rY5ABxlHLOXMoUes4BFoCL7sPrRwz/iMo85a0vX60X9OavGbW9k9XqxUzBipod/N/Pw5zPOus6VuROn9T24VxGq152CJ4ukrEczveCpJb1Q5s688kznt/4pqysSAOrIuxt8qBczjdZa/27tN+MnZNZrqQygTYv+dGYXXOvfUxbQNEg80PqXDACHLX5nbpFa69+PXV2B/HrdOAA07/7bZAC7zcCh1l+ZSztuXiHyg9a/VAawyUN8OJOLrvUfoCvgWX+4XksEgE368nPIALT+w0jzTc48799v/ZONJgI16f8mo/mpG3A8opstleOy8DnXEyzzaktu+Of1/XUx0annJ9XnWbOd1uumMwFLtOCHzU08Bv/mTOkcmSmWuS9pQPBN/TmYYNmXfdTrpgGgxIy+o/TapuQ8bvrXzO0fY8qd5gYc1ffXlVr6WusxgGYiz6JQOY5UBR0yN6B0AKjKTuQ5VBV0KDVUpy5D2QBQstU+agYUoSsvLBYqFACaSRalH1jdADrvCrgEZTKASPq/7uCc0EYaEHzhMmweAHJb61X9yR193dMNoAenBgT/F34NGNz4Iz3876v8hT/puDPVMj3NrLvsLcE+fng5VD3fLBZ6ptbaZQCREfvL4PtX3QD6YLFQmwDQpE65rfntve9yg8DCSC09eeMSxDOAyEj97Yf+rSyAkVlYLBQfA4ik/+/vBYPciJuCzMlA1+PJSG6KJyMo8/XE1hjclDWS2p+OeLHQu7psXZz3zhbm2QEguO/f+nbfP83zr3//KvP3FwPO3d6vxrVt85Blvphgg5Yajr9bdAWmuFio9y7AceDYbz28kW6AqcHDmuQS2mbMKbqRyf6MdqbaKABE+uZvM4NCibEGypvybkB/VvH9DN7MdW5AVgAIbvyx/lb63iz3zQ0Cu3OOylr/jbKAdRUfQ0oP/6kAUKZFvgpmBiUyDsp5PfV/oGmAomNIs1wstNPBw/i2ZXD4KuiYstm764zvLZyKlAVEN5l5IwB8nf7vbZr+30vPIjeYboC+f9ssYNUim9mb22KhnAwg0vpfZxwT2cDS24B+W//rbfqHmvUG0YxmVouFcuYBRFrhnD5+yhBy12XbL1DrX6Ir8C5w/O5IugLLqpsdpdfZAaDFvn8P9vFTalafdxnoVhxXn1/t9NIKVndnMA4lzQTc77HM623dWTj9X2m2XxWbx3JUdb+d+4OBawy7Akd2/b0KtNSXgQDwtMcA8H7AZaq3A+9ZIACMoswTyAIiy9ir4LFbOwZQOv3PzhRusVEIm2YBbeYGVLMOAMGNP0IPdTNC620AfQaBiypvkFoAaERG4K9aDNRF3gY8V1UU6grwUAAIrvyLpv83ItHYRiGUyALaLBaaZQbQWfp/rzJWgV8xNZgS2iwWml0AiKT/yw3e01shSN9ZQLpXbQj6vQDQIv3f5KupI7+7sJEjhYLAdZusdS4ZQLSlvdqgInQDGEqbxUKzCACRh2xZYO24bgBDZAHpvj0XAO6m/4sqtr/cZYEyRM5hoxBKBoE0ILgUAAZI/zfoBlghSOmuwGw9Gjj9vx1Ictdhp291ObFCkEJZQFos9Gfg/utLV9uC37beuZf+RybbXBYsSHQikW4AJaWxgDk2KFe3uwDR6bbFXqM0r2UiFaAbQMksYK6Lhc53Wraqqw52jrVfIEMGgYtqXouFPu3+vNOk/8U3/tANYILmNEPw0yvQmwwgOsHmsnRpms1EI90AKwQpfQ+uqnnMDfjy3Q83AeA4mP539e7URiEMbQ6Lhb4EuZ0uN/7QDWCCWcC2Lxa6881PKQOIjqhfdnjxo90AawPo4j68rrZ3sdCdLs5OFR/973rqZLQbYKMQurCNi4W++t7HNBPw98AJ+rgg58EsY/VAND+rf5xNrAWaXJnTzVXlv0bL7WOnxuZgiHuz2b7+ILN7vMw850EFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMC2+0+AAQDgljs/XVSdVAAAAABJRU5ErkJggg=="
|
||||
alt="Affine Logo"
|
||||
/>
|
||||
);
|
||||
};
|
||||
17
libs/components/common/src/lib/Logo/LogoLink.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import { Link } from 'react-router-dom';
|
||||
import { LogoImg } from './LogoImg';
|
||||
import { styled } from '@toeverything/components/ui';
|
||||
|
||||
export const LogoLink = () => {
|
||||
return (
|
||||
<StyledLink to="/">
|
||||
<LogoImg style={{ width: 56, height: 56 }} />
|
||||
</StyledLink>
|
||||
);
|
||||
};
|
||||
|
||||
const StyledLink = styled(Link)`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
`;
|
||||
8
libs/components/common/src/lib/Logo/affine-logo.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<svg width="100" height="22" viewBox="0 0 100 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M77.4929 0.10376V13.3534L69.3559 0.10376H65.563V21.9999H69.7957V8.75276L77.9197 21.9999H81.7255V0.10376H77.4929Z" fill="#153C7A"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.71004 0L0 22H4.5159L9.42021 6.78417L14.3267 22H18.8273L11.1161 0H7.71004Z" fill="#153C7A"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M39.6845 0.148682V9.30504H26.3638V3.94645H34.5655L36.4257 0.148682H22.127V21.9552H26.3638V13.1041H39.6845V21.9552H43.9214V13.1041H50.0647H50.6301L52.489 9.30504H51.9237H43.9214V3.94645H52.123L53.9832 0.148682H39.6845Z" fill="#153C7A"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M85.7012 0.148682V21.9552H98.1397L99.9999 18.1559H89.938V12.8571H98.507V9.06163H89.938V3.94645H98.1397L99.9999 0.148682H85.7012Z" fill="#153C7A"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M57.2695 22.0001H61.5022V7.49414H57.2695V22.0001Z" fill="#153C7A"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M57.2695 4.6581H61.5022V0.103882H57.2695V4.6581Z" fill="#3E6FDB"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
2
libs/components/common/src/lib/Logo/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { LogoLink } from './LogoLink';
|
||||
export { LogoImg } from './LogoImg';
|
||||
@@ -0,0 +1,27 @@
|
||||
import { PagesIcon } from '@toeverything/components/icons';
|
||||
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
|
||||
import { BlockSearchItem } from '@toeverything/datasource/jwt';
|
||||
import { ListButton } from '@toeverything/components/ui';
|
||||
|
||||
type BlockPreviewProps = {
|
||||
block: BlockSearchItem;
|
||||
className?: string;
|
||||
onClick?: () => void;
|
||||
onMouseOver?: () => void;
|
||||
hover?: boolean;
|
||||
};
|
||||
|
||||
export const BlockPreview = (props: BlockPreviewProps) => {
|
||||
const { block } = props;
|
||||
|
||||
return (
|
||||
<ListButton
|
||||
className={props.className}
|
||||
onClick={props.onClick}
|
||||
onMouseOver={props.onMouseOver}
|
||||
hover={props.hover}
|
||||
content={block.content}
|
||||
icon={PagesIcon}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,142 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { PagesIcon } from '@toeverything/components/icons';
|
||||
import { styled } from '@toeverything/components/ui';
|
||||
|
||||
type PreviewSize = 'sm' | 'md' | 'lg';
|
||||
|
||||
type StyledBlockPreviewProps = {
|
||||
title: string;
|
||||
children: JSX.Element;
|
||||
className?: string;
|
||||
onClick?: () => void;
|
||||
onMouseOver?: () => void;
|
||||
hover?: boolean;
|
||||
};
|
||||
|
||||
const BaseContainer = styled('div')<{ size: PreviewSize }>(({ size }) => {
|
||||
const append =
|
||||
size === 'sm'
|
||||
? {}
|
||||
: {
|
||||
maxWidth: '18em',
|
||||
|
||||
lineHeight: '1.5em',
|
||||
overflowWrap: 'anywhere',
|
||||
};
|
||||
return {
|
||||
background: '#3E6FDB',
|
||||
display: 'flex',
|
||||
flexDirection: size === 'sm' ? 'column' : 'row',
|
||||
rowGap: '0.5em',
|
||||
height: size === 'sm' ? '182px' : size === 'md' ? '180px' : '174px',
|
||||
padding: '1em',
|
||||
paddingBottom: '0',
|
||||
marginBottom: size !== 'lg' ? '20px' : '0',
|
||||
append,
|
||||
};
|
||||
});
|
||||
|
||||
const PreviewContainer = styled('div')<{ size: PreviewSize }>(({ size }) => {
|
||||
return {
|
||||
minWidth: '272px',
|
||||
position: 'absolute',
|
||||
bottom: '0',
|
||||
overflow: 'hidden',
|
||||
...(size === 'sm'
|
||||
? { top: '2.5em', left: '0', right: '0' }
|
||||
: { top: '0.5em', right: '2em' }),
|
||||
};
|
||||
});
|
||||
|
||||
const Preview = styled('div')<{ size: PreviewSize }>({
|
||||
backgroundColor: 'white',
|
||||
borderRadius: '10px 10px 0 0',
|
||||
boxShadow: '1px 1px 0.5em 0 #000a',
|
||||
margin: '1em auto',
|
||||
height: '100%',
|
||||
width: '256px',
|
||||
});
|
||||
|
||||
const Title = styled('div')<{ size: PreviewSize }>(({ size }) => {
|
||||
const append =
|
||||
size === 'sm'
|
||||
? {}
|
||||
: {
|
||||
maxWidth: '50%',
|
||||
alignItems: 'top',
|
||||
};
|
||||
|
||||
return {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
columnGap: '0.5em',
|
||||
margin: size === 'sm' ? '0.25em 0.5em' : '0.5em 1em',
|
||||
color: 'white',
|
||||
...append,
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
'&>span': {
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const ScopedEditorWrapper = styled('div')<{ size: PreviewSize }>(({ size }) => {
|
||||
return {
|
||||
width: '750px',
|
||||
height: '750px',
|
||||
transform: 'scale(32%) translate(-102%, -104%)',
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
'&>:first-child': {
|
||||
margin: 'auto',
|
||||
marginTop: 0,
|
||||
overflow: 'hidden',
|
||||
userSelect: 'none',
|
||||
pointerEvents: 'none',
|
||||
padding: 0,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
export const StyledBlockPreview = (props: StyledBlockPreviewProps) => {
|
||||
const { title } = props;
|
||||
const container = useRef<HTMLDivElement>();
|
||||
const [size, setSize] = useState<PreviewSize>();
|
||||
|
||||
useEffect(() => {
|
||||
if (container?.current) {
|
||||
const element = container?.current;
|
||||
const resizeObserver = new ResizeObserver(entries => {
|
||||
const width = entries?.[0]?.contentRect.width;
|
||||
if (width > 726) setSize('lg');
|
||||
else if (width > 440) setSize('md');
|
||||
else setSize('sm');
|
||||
});
|
||||
|
||||
resizeObserver.observe(element);
|
||||
return () => resizeObserver.unobserve(element);
|
||||
}
|
||||
return undefined;
|
||||
}, [container]);
|
||||
|
||||
return (
|
||||
<BaseContainer ref={container} style={{ width: '100%' }} size={size}>
|
||||
{size ? (
|
||||
<>
|
||||
<Title size={size}>
|
||||
<PagesIcon />
|
||||
<span>{title}</span>
|
||||
</Title>
|
||||
<PreviewContainer size={size}>
|
||||
<Preview size={size}>
|
||||
<ScopedEditorWrapper size={size}>
|
||||
{(container?.current && props.children) || null}
|
||||
</ScopedEditorWrapper>
|
||||
</Preview>
|
||||
</PreviewContainer>
|
||||
</>
|
||||
) : null}
|
||||
</BaseContainer>
|
||||
);
|
||||
};
|
||||
2
libs/components/common/src/lib/block-preview/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { BlockPreview } from './BlockPreview';
|
||||
export { StyledBlockPreview } from './StyledBlockPreview';
|
||||
61
libs/components/common/src/lib/button/index.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import clsx from 'clsx';
|
||||
import style9 from 'style9';
|
||||
|
||||
const styles = style9.create({
|
||||
ligoButton: {
|
||||
border: 'none',
|
||||
outline: 'none',
|
||||
// backgroundColor: 'white',
|
||||
cursor: 'pointer',
|
||||
':hover': {
|
||||
backgroundColor: '#edeef0',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export type ButtonType =
|
||||
| 'default'
|
||||
| 'primary'
|
||||
| 'ghost'
|
||||
| 'dashed'
|
||||
| 'link'
|
||||
| 'text';
|
||||
|
||||
export type SizeType = 'small' | 'medium' | 'large';
|
||||
|
||||
export type ButtonProps = {
|
||||
type?: ButtonType;
|
||||
size?: SizeType;
|
||||
icon?: React.ReactNode;
|
||||
className?: string;
|
||||
children?: React.ReactNode;
|
||||
onClick?: React.MouseEventHandler<HTMLElement>;
|
||||
style?: React.CSSProperties;
|
||||
};
|
||||
|
||||
export default function Button(props: ButtonProps) {
|
||||
const { className, type, style, size, children } = props;
|
||||
const classes = clsx(
|
||||
styles('ligoButton'),
|
||||
{
|
||||
[`${styles('ligoButton')}-${type}`]: type,
|
||||
[`${styles('ligoButton')}-icon-only`]: !children && children !== 0,
|
||||
},
|
||||
className
|
||||
);
|
||||
const handleClick = (
|
||||
e: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement, MouseEvent>
|
||||
) => {
|
||||
const { onClick } = props;
|
||||
(
|
||||
onClick as React.MouseEventHandler<
|
||||
HTMLButtonElement | HTMLAnchorElement
|
||||
>
|
||||
)?.(e);
|
||||
};
|
||||
return (
|
||||
<button className={classes} style={style || {}} onClick={handleClick}>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
59
libs/components/common/src/lib/collapsible-title/index.tsx
Normal file
@@ -0,0 +1,59 @@
|
||||
import { useState } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import style9 from 'style9';
|
||||
import {
|
||||
MuiButton as Button,
|
||||
MuiCollapse as Collapse,
|
||||
} from '@toeverything/components/ui';
|
||||
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
|
||||
import ArrowRightIcon from '@mui/icons-material/ArrowRight';
|
||||
|
||||
const styles = style9.create({
|
||||
ligoButton: {
|
||||
textTransform: 'none',
|
||||
},
|
||||
});
|
||||
|
||||
export type CollapsibleTitleProps = {
|
||||
title?: string;
|
||||
initialOpen?: boolean;
|
||||
icon?: React.ReactNode;
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
};
|
||||
|
||||
export function CollapsibleTitle(props: CollapsibleTitleProps) {
|
||||
const { className, style, children, title, initialOpen = true } = props;
|
||||
|
||||
const [open, setOpen] = useState(initialOpen);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
startIcon={
|
||||
open ? (
|
||||
<ArrowDropDownIcon sx={{ color: '#566B7D' }} />
|
||||
) : (
|
||||
<ArrowRightIcon sx={{ color: '#566B7D' }} />
|
||||
)
|
||||
}
|
||||
onClick={() => setOpen(prev => !prev)}
|
||||
sx={{ color: '#566B7D', textTransform: 'none' }}
|
||||
className={clsx(styles('ligoButton'), className)}
|
||||
style={style}
|
||||
disableElevation
|
||||
disableRipple
|
||||
>
|
||||
{title}
|
||||
</Button>
|
||||
{children ? (
|
||||
<Collapse in={open} timeout="auto" unmountOnExit>
|
||||
{children}
|
||||
</Collapse>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default CollapsibleTitle;
|
||||
517
libs/components/common/src/lib/colors/color-src.ts
Normal file
@@ -0,0 +1,517 @@
|
||||
import tinycolor from 'tinycolor2';
|
||||
|
||||
// return rgba based on hex & transparency
|
||||
const rgbaString = (hex: string, alpha: number) => {
|
||||
const color = tinycolor(hex);
|
||||
return color.setAlpha(alpha).toString();
|
||||
};
|
||||
|
||||
// base color, non-semantic
|
||||
export const colorBase = {
|
||||
// light theme
|
||||
light: {
|
||||
// gray
|
||||
Gray01: '#000000',
|
||||
Gray02: '#333333',
|
||||
Gray03: '#666666',
|
||||
Gray04: '#999999',
|
||||
Gray05: '#cccccc',
|
||||
Gray06: '#e1e1e1',
|
||||
Gray07: '#eaeaea',
|
||||
Gray08: '#F5F5F5',
|
||||
Gray09: '#FBFAFA',
|
||||
Gray10: '#FFFFFF',
|
||||
|
||||
// gray-vc
|
||||
GrayVc07: '#e8eaed',
|
||||
GrayVc09: '#787b80',
|
||||
|
||||
// blue
|
||||
Blue01: '#1851b3',
|
||||
Blue02: '#0050db',
|
||||
Blue03: '#0c63fa',
|
||||
Blue04: '#337eff',
|
||||
Blue05: '#80aeff',
|
||||
Blue06: '#a5c4fe',
|
||||
Blue07: '#bbd2fe',
|
||||
Blue08: '#d0e0fe',
|
||||
Blue09: '#edf3ff',
|
||||
Blue10: '#f5f8ff',
|
||||
// blue-vc
|
||||
BlueVc09: '#e0ebff',
|
||||
|
||||
// cyan
|
||||
Cyan01: '#0190D8',
|
||||
Cyan02: '#58BFF3',
|
||||
Cyan03: '#88D2F5',
|
||||
Cyan04: '#B7E3F9',
|
||||
Cyan05: '#D0EEFD',
|
||||
Cyan06: '#E7F6FC',
|
||||
|
||||
// green
|
||||
Green01: '#017547',
|
||||
Green02: '#018550',
|
||||
Green03: '#03a363',
|
||||
Green04: '#06cc7d',
|
||||
Green05: '#0ccf81',
|
||||
Green06: '#31e097',
|
||||
Green07: '#75ebbc',
|
||||
Green08: '#b6f0d9',
|
||||
Green09: '#d3f6e8',
|
||||
Green10: '#e8faf3',
|
||||
Green11: '#f2fcf8',
|
||||
|
||||
// grass-green
|
||||
GrassGreen01: '#02661b',
|
||||
GrassGreen02: '#038523',
|
||||
GrassGreen03: '#02a32a',
|
||||
GrassGreen04: '#06bf34',
|
||||
GrassGreen05: '#2fd656',
|
||||
GrassGreen06: '#50de71',
|
||||
GrassGreen07: '#7ceb96',
|
||||
GrassGreen08: '#b4f0c2',
|
||||
GrassGreen09: '#d2f6da',
|
||||
GrassGreen10: '#e8faec',
|
||||
GrassGreen11: '#f2fcf5',
|
||||
|
||||
// orange
|
||||
Orange01: '#fca10d',
|
||||
Orange02: '#fff0e0',
|
||||
|
||||
// orange-vc
|
||||
OrangeVc04: '#fc7f00',
|
||||
|
||||
// orange-calendar
|
||||
OrangeCalendar01: '#944b01',
|
||||
OrangeCalendar02: '#ba5f04',
|
||||
OrangeCalendar03: '#d9730d',
|
||||
OrangeCalendar04: '#fc860f',
|
||||
OrangeCalendar05: '#fc9c42',
|
||||
OrangeCalendar06: '#fcad62',
|
||||
OrangeCalendar07: '#fcbf86',
|
||||
OrangeCalendar08: '#fcdcbd',
|
||||
OrangeCalendar09: '#faf1e8',
|
||||
OrangeCalendar10: '#fcf7f2',
|
||||
|
||||
// yellow
|
||||
Yellow01: '#fcc036',
|
||||
Yellow02: '#fcca26',
|
||||
Yellow03: '#fff7e0',
|
||||
|
||||
// yellow-calendar
|
||||
YellowCalendar01: '#6b4f01',
|
||||
YellowCalendar02: '#9c7202',
|
||||
YellowCalendar03: '#c7950a',
|
||||
YellowCalendar04: '#fabc11',
|
||||
YellowCalendar05: '#fac641',
|
||||
YellowCalendar06: '#fad26b',
|
||||
YellowCalendar07: '#fce19a',
|
||||
YellowCalendar08: '#fcedc7',
|
||||
YellowCalendar09: '#faf5e8',
|
||||
YellowCalendar10: '#fcfaf2',
|
||||
|
||||
// red
|
||||
Red01: '#9e0202',
|
||||
Red02: '#b50707',
|
||||
Red03: '#db1d1d',
|
||||
Red04: '#fc3232',
|
||||
Red05: '#fc5656',
|
||||
Red06: '#fc8b8b',
|
||||
Red07: '#fcb3b3',
|
||||
Red08: '#fcd9da',
|
||||
Red09: '#fae8e9',
|
||||
Red10: '#fff5f5',
|
||||
|
||||
// red-vc
|
||||
RedVc09: '#ffebec',
|
||||
|
||||
// carmine
|
||||
Carmine01: '#9e025a',
|
||||
Carmine02: '#ba076d',
|
||||
Carmine03: '#d90d81',
|
||||
Carmine04: '#f72d9f',
|
||||
Carmine05: '#fa46af',
|
||||
Carmine06: '#fc74c4',
|
||||
Carmine07: '#fca9da',
|
||||
Carmine08: '#fccce8',
|
||||
Carmine09: '#fae8f3',
|
||||
Carmine10: '#fcf2f8',
|
||||
|
||||
// purple
|
||||
Purple01: '#502EC4',
|
||||
Purple02: '#A086FA',
|
||||
Purple03: '#BBA9FB',
|
||||
Purple04: '#BBA9FB',
|
||||
Purple05: '#E5DDFD',
|
||||
Purple06: '#F1ECFE',
|
||||
|
||||
// brown
|
||||
Brown01: '#8a2608',
|
||||
Brown02: '#9c3313',
|
||||
Brown03: '#b04828',
|
||||
Brown04: '#b86044',
|
||||
Brown05: '#db7d60',
|
||||
Brown06: '#ed9277',
|
||||
Brown07: '#f5ad98',
|
||||
Brown08: '#fcd6ca',
|
||||
Brown09: '#faece8',
|
||||
Brown10: '#fcf5f2',
|
||||
|
||||
// gray-blue
|
||||
GrayBlue01: '#3d5c80',
|
||||
GrayBlue02: '#476c96',
|
||||
GrayBlue03: '#587fad',
|
||||
GrayBlue04: '#658fbf',
|
||||
GrayBlue05: '#7ca2cf',
|
||||
GrayBlue06: '#94b9e3',
|
||||
GrayBlue07: '#abc9eb',
|
||||
GrayBlue08: '#c8def7',
|
||||
GrayBlue09: '#EDF5FF',
|
||||
GrayBlue10: '#F2F7FC',
|
||||
|
||||
// docs new colors:
|
||||
// Red - Docs Red
|
||||
DocsRed01: '#7E0101',
|
||||
// Orange - Docs Orange
|
||||
DocsOrange01: '#7A3D00',
|
||||
// Lemon Yellow - Docs Lemon
|
||||
DocsLemon01: '#6B4C00',
|
||||
DocsLemon03: '#B38F00',
|
||||
DocsLemon05: '#FCE303',
|
||||
DocsLemon06: '#FCEE4C',
|
||||
DocsLemon08: '#FFF88F',
|
||||
DocsLemon09: '#FFFABA',
|
||||
// Green - Docs Green
|
||||
DocsGreen01: '#285215',
|
||||
DocsGreen03: '#4C8A29',
|
||||
DocsGreen05: '#71B842',
|
||||
DocsGreen06: '#91CC66',
|
||||
DocsGreen08: '#BDE9A5',
|
||||
DocsGreen09: '#E2FAD4',
|
||||
// sky blue - Docs Sky
|
||||
DocsSky01: '#004587',
|
||||
DocsSky03: '#016DCB',
|
||||
DocsSky05: '#0C87FA',
|
||||
DocsSky06: '#37ACFF',
|
||||
DocsSky08: '#86D9FF',
|
||||
DocsSky09: '#D1F2FF',
|
||||
// Gray Blue - Docs Gray Blue
|
||||
DocsGrayBlue01: '#30445C',
|
||||
DocsGrayBlue09: '#DEECFC',
|
||||
// Purple - Docs Purple
|
||||
DocsPurple01: '#360990',
|
||||
// Magenta - Docs Carmine
|
||||
DocsCarmine01: '#88014E',
|
||||
// Gray - Docs Gray
|
||||
DocsGray10: '#3B3F44',
|
||||
DocsGray11: '#2C2F33',
|
||||
},
|
||||
// dark theme
|
||||
dark: {
|
||||
// gray
|
||||
Gray01: '#17181A',
|
||||
Gray02: '#121314',
|
||||
Gray03: '#101112',
|
||||
Gray04: '#27292b',
|
||||
Gray05: '#2d2f32',
|
||||
Gray06: '#303134',
|
||||
Gray07: '#45474a',
|
||||
Gray08: '#515155',
|
||||
Gray09: '#65676a',
|
||||
Gray10: '#88898C',
|
||||
Gray12: '#f7f7f7',
|
||||
Gray13: '#fafafa',
|
||||
// gray-vc
|
||||
GrayVc07: '#e3e5e8',
|
||||
GrayVc09: '#88898c',
|
||||
|
||||
// blue
|
||||
Blue01: '#134BE0',
|
||||
Blue02: '#1E6FFF',
|
||||
Blue03: '#5D98FF',
|
||||
Blue04: '#98BEFF',
|
||||
Blue05: '#C2D8FF',
|
||||
Blue06: '#EDF3FF',
|
||||
Blue07: '#EDF3FF',
|
||||
Blue08: '#EDF3FF',
|
||||
Blue09: '#EDF3FF',
|
||||
// blue-vc
|
||||
BlueVc09: '#1A2741',
|
||||
|
||||
// cyan
|
||||
Cyan01: '#046B7A',
|
||||
Cyan02: '#058599',
|
||||
Cyan03: '#049dbf',
|
||||
Cyan04: '#0AB7D1',
|
||||
Cyan05: '#2DCEE3',
|
||||
Cyan06: '#52E0F2',
|
||||
Cyan07: '#45B3C4',
|
||||
Cyan08: '#368A96',
|
||||
Cyan09: '#275F69',
|
||||
Cyan10: '#17363c',
|
||||
Cyan11: '#0F2226',
|
||||
|
||||
// green
|
||||
Green01: '#68BB0B',
|
||||
Green02: '#A3E163',
|
||||
Green03: '#BDE98F',
|
||||
Green04: '#D8F0BD',
|
||||
Green05: '#E6F7D3',
|
||||
Green06: '#F2FCE9',
|
||||
|
||||
// grass-green
|
||||
GrassGreen01: '#046B1E',
|
||||
GrassGreen02: '#068C27',
|
||||
GrassGreen03: '#00942c',
|
||||
GrassGreen04: '#09BA36',
|
||||
GrassGreen05: '#33CC57',
|
||||
GrassGreen06: '#52D972',
|
||||
GrassGreen07: '#3EA356',
|
||||
GrassGreen08: '#2B703B',
|
||||
GrassGreen09: '#1D4D2A',
|
||||
GrassGreen10: '#163820',
|
||||
GrassGreen11: '#112918',
|
||||
|
||||
// orange
|
||||
Orange01: '#E96800',
|
||||
Orange02: '#FEA94B',
|
||||
Orange03: '#FDC17F',
|
||||
Orange04: '#FFDAB2',
|
||||
Orange05: '#FFE7CD',
|
||||
Orange06: '#FFF1E3',
|
||||
|
||||
// orange-vc
|
||||
OrangeVc04: '#fc850d',
|
||||
|
||||
// orange-calendar
|
||||
OrangeCalendar01: '#99530C',
|
||||
OrangeCalendar02: '#BD660F',
|
||||
OrangeCalendar03: '#DA7918',
|
||||
OrangeCalendar04: '#e0760b',
|
||||
OrangeCalendar05: '#B86818',
|
||||
OrangeCalendar06: '#8F561E',
|
||||
OrangeCalendar07: '#66411E',
|
||||
OrangeCalendar08: '#3D2917',
|
||||
OrangeCalendar09: '#3d2a17',
|
||||
OrangeCalendar10: '#261C12',
|
||||
|
||||
// yellow
|
||||
Yellow01: '#F59800',
|
||||
Yellow02: '#FFDA4E',
|
||||
Yellow03: '#FFE480',
|
||||
Yellow04: '#FFF0B3',
|
||||
Yellow05: '#FFF4CD',
|
||||
Yellow06: '#FFF9E7',
|
||||
|
||||
// yellow-calendar
|
||||
YellowCalendar01: '#705302',
|
||||
YellowCalendar02: '#A17705',
|
||||
YellowCalendar03: '#d19704',
|
||||
YellowCalendar04: '#b88702',
|
||||
YellowCalendar05: '#FCC947',
|
||||
YellowCalendar06: '#BD983A',
|
||||
YellowCalendar07: '#7D662A',
|
||||
YellowCalendar08: '#54451E',
|
||||
YellowCalendar09: '#3d3417',
|
||||
YellowCalendar10: '#26200E',
|
||||
|
||||
// red
|
||||
Red01: '#9e0505',
|
||||
Red02: '#b50b0b',
|
||||
Red03: '#db272d',
|
||||
Red04: '#fc3c3c',
|
||||
Red05: '#fc5e5e',
|
||||
Red06: '#7a2525',
|
||||
Red07: '#632122',
|
||||
Red08: '#4c1d1d',
|
||||
Red09: '#421d1e',
|
||||
Red10: '#2e1c1c',
|
||||
|
||||
// red-vc
|
||||
RedVc09: '#ffebec',
|
||||
|
||||
// carmine
|
||||
Carmine01: '#A3055F',
|
||||
Carmine02: '#BF0B71',
|
||||
Carmine03: '#DE1285',
|
||||
Carmine04: '#e32998',
|
||||
Carmine05: '#FC4CB3',
|
||||
Carmine06: '#CF4294',
|
||||
Carmine07: '#A13774',
|
||||
Carmine08: '#702A53',
|
||||
Carmine09: '#401a31',
|
||||
Carmine10: '#26101E',
|
||||
|
||||
// purple
|
||||
Purple01: '#480FBA',
|
||||
Purple02: '#6021DE',
|
||||
Purple03: '#7E3DFF',
|
||||
Purple04: '#8c56ff',
|
||||
Purple05: '#9d6dfc',
|
||||
Purple06: '#b797fc',
|
||||
Purple07: '#977BD1',
|
||||
Purple08: '#7660A6',
|
||||
Purple09: '#342a4a',
|
||||
Purple10: '#1B1526',
|
||||
|
||||
// brown
|
||||
Brown01: '#8F2A0B',
|
||||
Brown02: '#9E3616',
|
||||
Brown03: '#b85944',
|
||||
Brown04: '#BA6449',
|
||||
Brown05: '#DB8165',
|
||||
Brown06: '#B5705B',
|
||||
Brown07: '#8F5E4F',
|
||||
Brown08: '#69483F',
|
||||
Brown09: '#3B2A26',
|
||||
Brown10: '#261D1A',
|
||||
|
||||
// gray-blue
|
||||
GrayBlue01: '#81868c',
|
||||
GrayBlue02: '#50739B',
|
||||
GrayBlue03: '#5F85B3',
|
||||
GrayBlue04: '#4F81C7',
|
||||
GrayBlue05: '#496280',
|
||||
GrayBlue06: '#3F5269',
|
||||
GrayBlue07: '#334152',
|
||||
GrayBlue08: '#27303B',
|
||||
GrayBlue09: '#28303b',
|
||||
GrayBlue10: '#252C36',
|
||||
|
||||
// docs new colors:
|
||||
// Red - Docs Red
|
||||
DocsRed01: '#7E0101',
|
||||
// Orange - Docs Orange
|
||||
DocsOrange01: '#7A3D00',
|
||||
// Lemon Yellow - Docs Lemon
|
||||
DocsLemon01: '#6B4C00',
|
||||
DocsLemon03: '#B38F00',
|
||||
DocsLemon05: '#FCE303',
|
||||
DocsLemon06: '#FCEE4C',
|
||||
DocsLemon08: '#FFF88F',
|
||||
DocsLemon09: '#FFFABA',
|
||||
// Green - Docs Green
|
||||
DocsGreen01: '#285215',
|
||||
DocsGreen03: '#4C8A29',
|
||||
DocsGreen05: '#71B842',
|
||||
DocsGreen06: '#91CC66',
|
||||
DocsGreen08: '#BDE9A5',
|
||||
DocsGreen09: '#E2FAD4',
|
||||
// sky blue - Docs Sky
|
||||
DocsSky01: '#004587',
|
||||
DocsSky03: '#016DCB',
|
||||
DocsSky05: '#1889F2',
|
||||
DocsSky06: '#329BE6',
|
||||
DocsSky08: '#86D9FF',
|
||||
DocsSky09: '#D1F2FF',
|
||||
// Gray Blue - Docs Gray Blue
|
||||
DocsGrayBlue01: '#30445C',
|
||||
DocsGrayBlue09: '#DEECFC',
|
||||
// Purple - Docs Purple
|
||||
DocsPurple01: '#360990',
|
||||
// Magenta - Docs Carmine
|
||||
DocsCarmine01: '#88014E',
|
||||
// Gray - Docs Gray
|
||||
DocsGray10: '#3B3F44',
|
||||
DocsGray11: '#2C2F33',
|
||||
},
|
||||
};
|
||||
|
||||
// scene color, semantic
|
||||
export const colorScenes = {
|
||||
light: {
|
||||
// main color (@Blue03)
|
||||
PrimaryColor: colorBase.light.Blue03,
|
||||
CardBg: colorBase.light.Gray01, // Card background color
|
||||
CardNestedBg: colorBase.light.Gray02, // Background color of the nested area in the card
|
||||
// primary button - primary
|
||||
ButtonPrimaryBg: colorBase.light.Blue03, // primary button background color
|
||||
ButtonPrimaryText: colorBase.light.Gray01, // primary button text color
|
||||
ButtonPrimaryBgHover: colorBase.light.Blue04, // background color - hover
|
||||
ButtonPrimaryTextHover: colorBase.light.Gray01, // Text color - hover
|
||||
ButtonPrimaryBgActive: colorBase.light.Blue02, // background color - active
|
||||
ButtonPrimaryTextActive: colorBase.light.Gray01, // Text color - active
|
||||
ButtonPrimaryBgDisabled: colorBase.light.Blue05, // background color - disabled
|
||||
ButtonPrimaryTextDisabled: colorBase.light.Gray01, // Text color - disabled
|
||||
// secondary button - secondary
|
||||
ButtonSecondaryBg: colorBase.light.Gray01, // secondary button background color
|
||||
ButtonSecondaryText: colorBase.light.Gray03, // Secondary button text color
|
||||
ButtonSecondaryBgHover: colorBase.light.Gray02, // background color - hover
|
||||
ButtonSecondaryTextHover: colorBase.light.Gray03, // Text color - hover
|
||||
ButtonSecondaryBgActive: colorBase.light.Gray03, // background color - active
|
||||
ButtonSecondaryTextActive: colorBase.light.Gray03, // Text color - active
|
||||
ButtonSecondaryBgDisabled: colorBase.light.Gray03, // background color - disabled
|
||||
ButtonSecondaryTextDisabled: colorBase.light.Gray09, // Text color - disabled
|
||||
// ghost button - ghost
|
||||
ButtonGhostBg: colorBase.light.Gray01, // Ghost button background color
|
||||
ButtonGhostText: colorBase.light.Blue03, // Ghost button text color
|
||||
ButtonGhostBgHover: colorBase.light.Blue09, // background color - hover
|
||||
ButtonGhostTextHover: colorBase.light.Blue03, // Text color - hover
|
||||
ButtonGhostBgActive: colorBase.light.Blue08, // background color - active
|
||||
ButtonGhostTextActive: colorBase.light.Blue03, // Text color - active
|
||||
ButtonGhostBgDisabled: colorBase.light.Gray03, // background color - disabled
|
||||
ButtonGhostTextDisabled: colorBase.light.Gray09, // text color - disabled
|
||||
|
||||
ContainerBorder: rgbaString(colorBase.light.Gray03, 0.12), // item hover // container border
|
||||
DividerColor: rgbaString(colorBase.light.Gray03, 0.08), // global divider
|
||||
SelectColor: rgbaString(colorBase.light.GrayBlue01, 0.08), // item select
|
||||
HoverColor: rgbaString(colorBase.light.GrayBlue01, 0.05), // item hover
|
||||
ModalMaskBg: rgbaString(colorBase.light.Gray03, 0.45), // modal translucent mask
|
||||
CardBoxShadow: rgbaString(colorBase.light.Gray03, 0.04), // card shadow
|
||||
TooltipBg: colorBase.light.Gray03, // tooltip background color
|
||||
TooltipText: colorBase.light.Gray01, // tooltip text color
|
||||
},
|
||||
dark: {
|
||||
// main color (@Blue03)
|
||||
PrimaryColor: colorBase.dark.Blue03,
|
||||
CardBg: colorBase.dark.Gray04,
|
||||
CardNestedBg: colorBase.dark.Gray06,
|
||||
// main button
|
||||
ButtonPrimaryBg: colorBase.dark.Blue03,
|
||||
ButtonPrimaryText: colorBase.dark.Gray03,
|
||||
ButtonPrimaryBgHover: colorBase.dark.Blue04, // background color - hover
|
||||
ButtonPrimaryTextHover: colorBase.dark.Gray03, // Text color - hover
|
||||
ButtonPrimaryBgActive: colorBase.dark.Blue02, // background color - active
|
||||
ButtonPrimaryTextActive: colorBase.dark.Gray03, // Text color - active
|
||||
ButtonPrimaryBgDisabled: colorBase.dark.Blue05, // background color - disabled
|
||||
ButtonPrimaryTextDisabled: colorBase.dark.Gray03, // Text color - disabled
|
||||
// The dark mode secondary button has the same style as the ghost button
|
||||
// secondary button
|
||||
ButtonSecondaryBg: rgbaString(colorBase.dark.Gray03, 0.1),
|
||||
ButtonSecondaryText: colorBase.dark.Gray03,
|
||||
ButtonSecondaryBgHover: rgbaString(colorBase.dark.Gray03, 0.15), // background color - hover
|
||||
ButtonSecondaryTextHover: colorBase.dark.Gray03, // Text color - hover
|
||||
ButtonSecondaryBgActive: rgbaString(colorBase.dark.Gray03, 0.07), // background color - active
|
||||
ButtonSecondaryTextActive: colorBase.dark.Gray03, // Text color - active
|
||||
ButtonSecondaryBgDisabled: rgbaString(colorBase.dark.Gray03, 0.07), // background color - disabled
|
||||
ButtonSecondaryTextDisabled: colorBase.dark.Gray09, // Text color - disabled
|
||||
// ghost button
|
||||
ButtonGhostBg: rgbaString(colorBase.dark.Gray03, 0.1),
|
||||
ButtonGhostText: colorBase.dark.Gray03,
|
||||
ButtonGhostBgHover: rgbaString(colorBase.dark.Gray03, 0.15), // background color - hover
|
||||
ButtonGhostTextHover: colorBase.dark.Gray03, // Text color - hover
|
||||
ButtonGhostBgActive: rgbaString(colorBase.dark.Gray03, 0.07), // background color - active
|
||||
ButtonGhostTextActive: colorBase.dark.Gray03, // Text color - active
|
||||
ButtonGhostBgDisabled: rgbaString(colorBase.dark.Gray03, 0.07), // background color - disabled
|
||||
ButtonGhostTextDisabled: colorBase.dark.Gray09, // Text color - disabled
|
||||
ContainerBorder: rgbaString(colorBase.dark.Gray03, 0.12),
|
||||
DividerColor: rgbaString(colorBase.dark.Gray03, 0.08),
|
||||
SelectColor: rgbaString(colorBase.dark.GrayBlue01, 0.2),
|
||||
HoverColor: rgbaString(colorBase.dark.GrayBlue01, 0.1),
|
||||
ModalMaskBg: rgbaString(colorBase.light.Gray03, 0.5),
|
||||
CardBoxShadow: rgbaString(colorBase.light.Gray03, 0.3),
|
||||
TooltipBg: colorBase.dark.Gray05,
|
||||
TooltipText: colorBase.dark.Gray03,
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
light: {
|
||||
...colorBase.light,
|
||||
...colorScenes.light,
|
||||
},
|
||||
dark: {
|
||||
...colorBase.dark,
|
||||
...colorScenes.dark,
|
||||
},
|
||||
};
|
||||
378
libs/components/common/src/lib/colors/colors.ts
Normal file
@@ -0,0 +1,378 @@
|
||||
import themes from './color-src';
|
||||
const mode = 'light';
|
||||
const themeColors = themes[mode];
|
||||
|
||||
export const Gray01 = themeColors.Gray01;
|
||||
export const Gray02 = themeColors.Gray02;
|
||||
export const Gray03 = themeColors.Gray03;
|
||||
export const Gray04 = themeColors.Gray04;
|
||||
export const Gray05 = themeColors.Gray05;
|
||||
export const Gray06 = themeColors.Gray06;
|
||||
export const Gray07 = themeColors.Gray07;
|
||||
export const Gray08 = themeColors.Gray08;
|
||||
export const Gray09 = themeColors.Gray09;
|
||||
export const Gray10 = themeColors.Gray10;
|
||||
export const GrayVc07 = themeColors.GrayVc07;
|
||||
export const GrayVc09 = themeColors.GrayVc09;
|
||||
export const Blue01 = themeColors.Blue01;
|
||||
export const Blue02 = themeColors.Blue02;
|
||||
export const Blue03 = themeColors.Blue03;
|
||||
export const Blue04 = themeColors.Blue04;
|
||||
export const Blue05 = themeColors.Blue05;
|
||||
export const Blue06 = themeColors.Blue06;
|
||||
export const Blue07 = themeColors.Blue07;
|
||||
export const Blue08 = themeColors.Blue08;
|
||||
export const Blue09 = themeColors.Blue09;
|
||||
export const Blue10 = themeColors.Blue10;
|
||||
export const BlueVc09 = themeColors.BlueVc09;
|
||||
export const Cyan01 = themeColors.Cyan01;
|
||||
export const Cyan02 = themeColors.Cyan02;
|
||||
export const Cyan03 = themeColors.Cyan03;
|
||||
export const Cyan04 = themeColors.Cyan04;
|
||||
export const Cyan05 = themeColors.Cyan05;
|
||||
export const Cyan06 = themeColors.Cyan06;
|
||||
export const Green01 = themeColors.Green01;
|
||||
export const Green02 = themeColors.Green02;
|
||||
export const Green03 = themeColors.Green03;
|
||||
export const Green04 = themeColors.Green04;
|
||||
export const Green05 = themeColors.Green05;
|
||||
export const Green06 = themeColors.Green06;
|
||||
export const Green07 = themeColors.Green07;
|
||||
export const Green08 = themeColors.Green08;
|
||||
export const Green09 = themeColors.Green09;
|
||||
export const Green10 = themeColors.Green10;
|
||||
export const Green11 = themeColors.Green11;
|
||||
export const GrassGreen01 = themeColors.GrassGreen01;
|
||||
export const GrassGreen02 = themeColors.GrassGreen02;
|
||||
export const GrassGreen03 = themeColors.GrassGreen03;
|
||||
export const GrassGreen04 = themeColors.GrassGreen04;
|
||||
export const GrassGreen05 = themeColors.GrassGreen05;
|
||||
export const GrassGreen06 = themeColors.GrassGreen06;
|
||||
export const GrassGreen07 = themeColors.GrassGreen07;
|
||||
export const GrassGreen08 = themeColors.GrassGreen08;
|
||||
export const GrassGreen09 = themeColors.GrassGreen09;
|
||||
export const GrassGreen10 = themeColors.GrassGreen10;
|
||||
export const GrassGreen11 = themeColors.GrassGreen11;
|
||||
export const Orange01 = themeColors.Orange01;
|
||||
export const Orange02 = themeColors.Orange02;
|
||||
export const OrangeVc04 = themeColors.OrangeVc04;
|
||||
export const OrangeCalendar01 = themeColors.OrangeCalendar01;
|
||||
export const OrangeCalendar02 = themeColors.OrangeCalendar02;
|
||||
export const OrangeCalendar03 = themeColors.OrangeCalendar03;
|
||||
export const OrangeCalendar04 = themeColors.OrangeCalendar04;
|
||||
export const OrangeCalendar05 = themeColors.OrangeCalendar05;
|
||||
export const OrangeCalendar06 = themeColors.OrangeCalendar06;
|
||||
export const OrangeCalendar07 = themeColors.OrangeCalendar07;
|
||||
export const OrangeCalendar08 = themeColors.OrangeCalendar08;
|
||||
export const OrangeCalendar09 = themeColors.OrangeCalendar09;
|
||||
export const OrangeCalendar10 = themeColors.OrangeCalendar10;
|
||||
export const Yellow01 = themeColors.Yellow01;
|
||||
export const Yellow02 = themeColors.Yellow02;
|
||||
export const Yellow03 = themeColors.Yellow03;
|
||||
export const YellowCalendar01 = themeColors.YellowCalendar01;
|
||||
export const YellowCalendar02 = themeColors.YellowCalendar02;
|
||||
export const YellowCalendar03 = themeColors.YellowCalendar03;
|
||||
export const YellowCalendar04 = themeColors.YellowCalendar04;
|
||||
export const YellowCalendar05 = themeColors.YellowCalendar05;
|
||||
export const YellowCalendar06 = themeColors.YellowCalendar06;
|
||||
export const YellowCalendar07 = themeColors.YellowCalendar07;
|
||||
export const YellowCalendar08 = themeColors.YellowCalendar08;
|
||||
export const YellowCalendar09 = themeColors.YellowCalendar09;
|
||||
export const YellowCalendar10 = themeColors.YellowCalendar10;
|
||||
export const Red01 = themeColors.Red01;
|
||||
export const Red02 = themeColors.Red02;
|
||||
export const Red03 = themeColors.Red03;
|
||||
export const Red04 = themeColors.Red04;
|
||||
export const Red05 = themeColors.Red05;
|
||||
export const Red06 = themeColors.Red06;
|
||||
export const Red07 = themeColors.Red07;
|
||||
export const Red08 = themeColors.Red08;
|
||||
export const Red09 = themeColors.Red09;
|
||||
export const Red10 = themeColors.Red10;
|
||||
export const RedVc09 = themeColors.RedVc09;
|
||||
export const Carmine01 = themeColors.Carmine01;
|
||||
export const Carmine02 = themeColors.Carmine02;
|
||||
export const Carmine03 = themeColors.Carmine03;
|
||||
export const Carmine04 = themeColors.Carmine04;
|
||||
export const Carmine05 = themeColors.Carmine05;
|
||||
export const Carmine06 = themeColors.Carmine06;
|
||||
export const Carmine07 = themeColors.Carmine07;
|
||||
export const Carmine08 = themeColors.Carmine08;
|
||||
export const Carmine09 = themeColors.Carmine09;
|
||||
export const Carmine10 = themeColors.Carmine10;
|
||||
export const Purple01 = themeColors.Purple01;
|
||||
export const Purple02 = themeColors.Purple02;
|
||||
export const Purple03 = themeColors.Purple03;
|
||||
export const Purple04 = themeColors.Purple04;
|
||||
export const Purple05 = themeColors.Purple05;
|
||||
export const Purple06 = themeColors.Purple06;
|
||||
export const Brown01 = themeColors.Brown01;
|
||||
export const Brown02 = themeColors.Brown02;
|
||||
export const Brown03 = themeColors.Brown03;
|
||||
export const Brown04 = themeColors.Brown04;
|
||||
export const Brown05 = themeColors.Brown05;
|
||||
export const Brown06 = themeColors.Brown06;
|
||||
export const Brown07 = themeColors.Brown07;
|
||||
export const Brown08 = themeColors.Brown08;
|
||||
export const Brown09 = themeColors.Brown09;
|
||||
export const Brown10 = themeColors.Brown10;
|
||||
export const GrayBlue01 = themeColors.GrayBlue01;
|
||||
export const GrayBlue02 = themeColors.GrayBlue02;
|
||||
export const GrayBlue03 = themeColors.GrayBlue03;
|
||||
export const GrayBlue04 = themeColors.GrayBlue04;
|
||||
export const GrayBlue05 = themeColors.GrayBlue05;
|
||||
export const GrayBlue06 = themeColors.GrayBlue06;
|
||||
export const GrayBlue07 = themeColors.GrayBlue07;
|
||||
export const GrayBlue08 = themeColors.GrayBlue08;
|
||||
export const GrayBlue09 = themeColors.GrayBlue09;
|
||||
export const GrayBlue10 = themeColors.GrayBlue10;
|
||||
export const DocsRed01 = themeColors.DocsRed01;
|
||||
export const DocsOrange01 = themeColors.DocsOrange01;
|
||||
export const DocsLemon01 = themeColors.DocsLemon01;
|
||||
export const DocsLemon03 = themeColors.DocsLemon03;
|
||||
export const DocsLemon05 = themeColors.DocsLemon05;
|
||||
export const DocsLemon06 = themeColors.DocsLemon06;
|
||||
export const DocsLemon08 = themeColors.DocsLemon08;
|
||||
export const DocsLemon09 = themeColors.DocsLemon09;
|
||||
export const DocsGreen01 = themeColors.DocsGreen01;
|
||||
export const DocsGreen03 = themeColors.DocsGreen03;
|
||||
export const DocsGreen05 = themeColors.DocsGreen05;
|
||||
export const DocsGreen06 = themeColors.DocsGreen06;
|
||||
export const DocsGreen08 = themeColors.DocsGreen08;
|
||||
export const DocsGreen09 = themeColors.DocsGreen09;
|
||||
export const DocsSky01 = themeColors.DocsSky01;
|
||||
export const DocsSky03 = themeColors.DocsSky03;
|
||||
export const DocsSky05 = themeColors.DocsSky05;
|
||||
export const DocsSky06 = themeColors.DocsSky06;
|
||||
export const DocsSky08 = themeColors.DocsSky08;
|
||||
export const DocsSky09 = themeColors.DocsSky09;
|
||||
export const DocsGrayBlue01 = themeColors.DocsGrayBlue01;
|
||||
export const DocsGrayBlue09 = themeColors.DocsGrayBlue09;
|
||||
export const DocsPurple01 = themeColors.DocsPurple01;
|
||||
export const DocsCarmine01 = themeColors.DocsCarmine01;
|
||||
export const DocsGray10 = themeColors.DocsGray10;
|
||||
export const DocsGray11 = themeColors.DocsGray11;
|
||||
export const PrimaryColor = themeColors.PrimaryColor;
|
||||
export const CardBg = themeColors.CardBg;
|
||||
export const CardNestedBg = themeColors.CardNestedBg;
|
||||
export const ButtonPrimaryBg = themeColors.ButtonPrimaryBg;
|
||||
export const ButtonPrimaryText = themeColors.ButtonPrimaryText;
|
||||
export const ButtonPrimaryBgHover = themeColors.ButtonPrimaryBgHover;
|
||||
export const ButtonPrimaryTextHover = themeColors.ButtonPrimaryTextHover;
|
||||
export const ButtonPrimaryBgActive = themeColors.ButtonPrimaryBgActive;
|
||||
export const ButtonPrimaryTextActive = themeColors.ButtonPrimaryTextActive;
|
||||
export const ButtonPrimaryBgDisabled = themeColors.ButtonPrimaryBgDisabled;
|
||||
export const ButtonPrimaryTextDisabled = themeColors.ButtonPrimaryTextDisabled;
|
||||
export const ButtonSecondaryBg = themeColors.ButtonSecondaryBg;
|
||||
export const ButtonSecondaryText = themeColors.ButtonSecondaryText;
|
||||
export const ButtonSecondaryBgHover = themeColors.ButtonSecondaryBgHover;
|
||||
export const ButtonSecondaryTextHover = themeColors.ButtonSecondaryTextHover;
|
||||
export const ButtonSecondaryBgActive = themeColors.ButtonSecondaryBgActive;
|
||||
export const ButtonSecondaryTextActive = themeColors.ButtonSecondaryTextActive;
|
||||
export const ButtonSecondaryBgDisabled = themeColors.ButtonSecondaryBgDisabled;
|
||||
export const ButtonSecondaryTextDisabled =
|
||||
themeColors.ButtonSecondaryTextDisabled;
|
||||
export const ButtonGhostBg = themeColors.ButtonGhostBg;
|
||||
export const ButtonGhostText = themeColors.ButtonGhostText;
|
||||
export const ButtonGhostBgHover = themeColors.ButtonGhostBgHover;
|
||||
export const ButtonGhostTextHover = themeColors.ButtonGhostTextHover;
|
||||
export const ButtonGhostBgActive = themeColors.ButtonGhostBgActive;
|
||||
export const ButtonGhostTextActive = themeColors.ButtonGhostTextActive;
|
||||
export const ButtonGhostBgDisabled = themeColors.ButtonGhostBgDisabled;
|
||||
export const ButtonGhostTextDisabled = themeColors.ButtonGhostTextDisabled;
|
||||
export const ContainerBorder = themeColors.ContainerBorder;
|
||||
export const DividerColor = themeColors.DividerColor;
|
||||
export const SelectColor = themeColors.SelectColor;
|
||||
export const HoverColor = themeColors.HoverColor;
|
||||
export const ModalMaskBg = themeColors.ModalMaskBg;
|
||||
export const CardBoxShadow = themeColors.CardBoxShadow;
|
||||
export const TooltipBg = themeColors.TooltipBg;
|
||||
export const TooltipText = themeColors.TooltipText;
|
||||
|
||||
export const colors = {
|
||||
Gray01: themeColors.Gray01,
|
||||
Gray02: themeColors.Gray02,
|
||||
Gray03: themeColors.Gray03,
|
||||
Gray04: themeColors.Gray04,
|
||||
Gray05: themeColors.Gray05,
|
||||
Gray06: themeColors.Gray06,
|
||||
Gray07: themeColors.Gray07,
|
||||
Gray08: themeColors.Gray08,
|
||||
Gray09: themeColors.Gray09,
|
||||
Gray10: themeColors.Gray10,
|
||||
GrayVc07: themeColors.GrayVc07,
|
||||
GrayVc09: themeColors.GrayVc09,
|
||||
Blue01: themeColors.Blue01,
|
||||
Blue02: themeColors.Blue02,
|
||||
Blue03: themeColors.Blue03,
|
||||
Blue04: themeColors.Blue04,
|
||||
Blue05: themeColors.Blue05,
|
||||
Blue06: themeColors.Blue06,
|
||||
Blue07: themeColors.Blue07,
|
||||
Blue08: themeColors.Blue08,
|
||||
Blue09: themeColors.Blue09,
|
||||
Blue10: themeColors.Blue10,
|
||||
BlueVc09: themeColors.BlueVc09,
|
||||
Cyan01: themeColors.Cyan01,
|
||||
Cyan02: themeColors.Cyan02,
|
||||
Cyan03: themeColors.Cyan03,
|
||||
Cyan04: themeColors.Cyan04,
|
||||
Cyan05: themeColors.Cyan05,
|
||||
Cyan06: themeColors.Cyan06,
|
||||
Green01: themeColors.Green01,
|
||||
Green02: themeColors.Green02,
|
||||
Green03: themeColors.Green03,
|
||||
Green04: themeColors.Green04,
|
||||
Green05: themeColors.Green05,
|
||||
Green06: themeColors.Green06,
|
||||
Green07: themeColors.Green07,
|
||||
Green08: themeColors.Green08,
|
||||
Green09: themeColors.Green09,
|
||||
Green10: themeColors.Green10,
|
||||
Green11: themeColors.Green11,
|
||||
GrassGreen01: themeColors.GrassGreen01,
|
||||
GrassGreen02: themeColors.GrassGreen02,
|
||||
GrassGreen03: themeColors.GrassGreen03,
|
||||
GrassGreen04: themeColors.GrassGreen04,
|
||||
GrassGreen05: themeColors.GrassGreen05,
|
||||
GrassGreen06: themeColors.GrassGreen06,
|
||||
GrassGreen07: themeColors.GrassGreen07,
|
||||
GrassGreen08: themeColors.GrassGreen08,
|
||||
GrassGreen09: themeColors.GrassGreen09,
|
||||
GrassGreen10: themeColors.GrassGreen10,
|
||||
GrassGreen11: themeColors.GrassGreen11,
|
||||
Orange01: themeColors.Orange01,
|
||||
Orange02: themeColors.Orange02,
|
||||
OrangeVc04: themeColors.OrangeVc04,
|
||||
OrangeCalendar01: themeColors.OrangeCalendar01,
|
||||
OrangeCalendar02: themeColors.OrangeCalendar02,
|
||||
OrangeCalendar03: themeColors.OrangeCalendar03,
|
||||
OrangeCalendar04: themeColors.OrangeCalendar04,
|
||||
OrangeCalendar05: themeColors.OrangeCalendar05,
|
||||
OrangeCalendar06: themeColors.OrangeCalendar06,
|
||||
OrangeCalendar07: themeColors.OrangeCalendar07,
|
||||
OrangeCalendar08: themeColors.OrangeCalendar08,
|
||||
OrangeCalendar09: themeColors.OrangeCalendar09,
|
||||
OrangeCalendar10: themeColors.OrangeCalendar10,
|
||||
Yellow01: themeColors.Yellow01,
|
||||
Yellow02: themeColors.Yellow02,
|
||||
Yellow03: themeColors.Yellow03,
|
||||
YellowCalendar01: themeColors.YellowCalendar01,
|
||||
YellowCalendar02: themeColors.YellowCalendar02,
|
||||
YellowCalendar03: themeColors.YellowCalendar03,
|
||||
YellowCalendar04: themeColors.YellowCalendar04,
|
||||
YellowCalendar05: themeColors.YellowCalendar05,
|
||||
YellowCalendar06: themeColors.YellowCalendar06,
|
||||
YellowCalendar07: themeColors.YellowCalendar07,
|
||||
YellowCalendar08: themeColors.YellowCalendar08,
|
||||
YellowCalendar09: themeColors.YellowCalendar09,
|
||||
YellowCalendar10: themeColors.YellowCalendar10,
|
||||
Red01: themeColors.Red01,
|
||||
Red02: themeColors.Red02,
|
||||
Red03: themeColors.Red03,
|
||||
Red04: themeColors.Red04,
|
||||
Red05: themeColors.Red05,
|
||||
Red06: themeColors.Red06,
|
||||
Red07: themeColors.Red07,
|
||||
Red08: themeColors.Red08,
|
||||
Red09: themeColors.Red09,
|
||||
Red10: themeColors.Red10,
|
||||
RedVc09: themeColors.RedVc09,
|
||||
Carmine01: themeColors.Carmine01,
|
||||
Carmine02: themeColors.Carmine02,
|
||||
Carmine03: themeColors.Carmine03,
|
||||
Carmine04: themeColors.Carmine04,
|
||||
Carmine05: themeColors.Carmine05,
|
||||
Carmine06: themeColors.Carmine06,
|
||||
Carmine07: themeColors.Carmine07,
|
||||
Carmine08: themeColors.Carmine08,
|
||||
Carmine09: themeColors.Carmine09,
|
||||
Carmine10: themeColors.Carmine10,
|
||||
Purple01: themeColors.Purple01,
|
||||
Purple02: themeColors.Purple02,
|
||||
Purple03: themeColors.Purple03,
|
||||
Purple04: themeColors.Purple04,
|
||||
Purple05: themeColors.Purple05,
|
||||
Purple06: themeColors.Purple06,
|
||||
Brown01: themeColors.Brown01,
|
||||
Brown02: themeColors.Brown02,
|
||||
Brown03: themeColors.Brown03,
|
||||
Brown04: themeColors.Brown04,
|
||||
Brown05: themeColors.Brown05,
|
||||
Brown06: themeColors.Brown06,
|
||||
Brown07: themeColors.Brown07,
|
||||
Brown08: themeColors.Brown08,
|
||||
Brown09: themeColors.Brown09,
|
||||
Brown10: themeColors.Brown10,
|
||||
GrayBlue01: themeColors.GrayBlue01,
|
||||
GrayBlue02: themeColors.GrayBlue02,
|
||||
GrayBlue03: themeColors.GrayBlue03,
|
||||
GrayBlue04: themeColors.GrayBlue04,
|
||||
GrayBlue05: themeColors.GrayBlue05,
|
||||
GrayBlue06: themeColors.GrayBlue06,
|
||||
GrayBlue07: themeColors.GrayBlue07,
|
||||
GrayBlue08: themeColors.GrayBlue08,
|
||||
GrayBlue09: themeColors.GrayBlue09,
|
||||
GrayBlue10: themeColors.GrayBlue10,
|
||||
DocsRed01: themeColors.DocsRed01,
|
||||
DocsOrange01: themeColors.DocsOrange01,
|
||||
DocsLemon01: themeColors.DocsLemon01,
|
||||
DocsLemon03: themeColors.DocsLemon03,
|
||||
DocsLemon05: themeColors.DocsLemon05,
|
||||
DocsLemon06: themeColors.DocsLemon06,
|
||||
DocsLemon08: themeColors.DocsLemon08,
|
||||
DocsLemon09: themeColors.DocsLemon09,
|
||||
DocsGreen01: themeColors.DocsGreen01,
|
||||
DocsGreen03: themeColors.DocsGreen03,
|
||||
DocsGreen05: themeColors.DocsGreen05,
|
||||
DocsGreen06: themeColors.DocsGreen06,
|
||||
DocsGreen08: themeColors.DocsGreen08,
|
||||
DocsGreen09: themeColors.DocsGreen09,
|
||||
DocsSky01: themeColors.DocsSky01,
|
||||
DocsSky03: themeColors.DocsSky03,
|
||||
DocsSky05: themeColors.DocsSky05,
|
||||
DocsSky06: themeColors.DocsSky06,
|
||||
DocsSky08: themeColors.DocsSky08,
|
||||
DocsSky09: themeColors.DocsSky09,
|
||||
DocsGrayBlue01: themeColors.DocsGrayBlue01,
|
||||
DocsGrayBlue09: themeColors.DocsGrayBlue09,
|
||||
DocsPurple01: themeColors.DocsPurple01,
|
||||
DocsCarmine01: themeColors.DocsCarmine01,
|
||||
DocsGray10: themeColors.DocsGray10,
|
||||
DocsGray11: themeColors.DocsGray11,
|
||||
PrimaryColor: themeColors.PrimaryColor,
|
||||
CardBg: themeColors.CardBg,
|
||||
CardNestedBg: themeColors.CardNestedBg,
|
||||
ButtonPrimaryBg: themeColors.ButtonPrimaryBg,
|
||||
ButtonPrimaryText: themeColors.ButtonPrimaryText,
|
||||
ButtonPrimaryBgHover: themeColors.ButtonPrimaryBgHover,
|
||||
ButtonPrimaryTextHover: themeColors.ButtonPrimaryTextHover,
|
||||
ButtonPrimaryBgActive: themeColors.ButtonPrimaryBgActive,
|
||||
ButtonPrimaryTextActive: themeColors.ButtonPrimaryTextActive,
|
||||
ButtonPrimaryBgDisabled: themeColors.ButtonPrimaryBgDisabled,
|
||||
ButtonPrimaryTextDisabled: themeColors.ButtonPrimaryTextDisabled,
|
||||
ButtonSecondaryBg: themeColors.ButtonSecondaryBg,
|
||||
ButtonSecondaryText: themeColors.ButtonSecondaryText,
|
||||
ButtonSecondaryBgHover: themeColors.ButtonSecondaryBgHover,
|
||||
ButtonSecondaryTextHover: themeColors.ButtonSecondaryTextHover,
|
||||
ButtonSecondaryBgActive: themeColors.ButtonSecondaryBgActive,
|
||||
ButtonSecondaryTextActive: themeColors.ButtonSecondaryTextActive,
|
||||
ButtonSecondaryBgDisabled: themeColors.ButtonSecondaryBgDisabled,
|
||||
ButtonSecondaryTextDisabled: themeColors.ButtonSecondaryTextDisabled,
|
||||
ButtonGhostBg: themeColors.ButtonGhostBg,
|
||||
ButtonGhostText: themeColors.ButtonGhostText,
|
||||
ButtonGhostBgHover: themeColors.ButtonGhostBgHover,
|
||||
ButtonGhostTextHover: themeColors.ButtonGhostTextHover,
|
||||
ButtonGhostBgActive: themeColors.ButtonGhostBgActive,
|
||||
ButtonGhostTextActive: themeColors.ButtonGhostTextActive,
|
||||
ButtonGhostBgDisabled: themeColors.ButtonGhostBgDisabled,
|
||||
ButtonGhostTextDisabled: themeColors.ButtonGhostTextDisabled,
|
||||
ContainerBorder: themeColors.ContainerBorder,
|
||||
DividerColor: themeColors.DividerColor,
|
||||
SelectColor: themeColors.SelectColor,
|
||||
HoverColor: themeColors.HoverColor,
|
||||
ModalMaskBg: themeColors.ModalMaskBg,
|
||||
CardBoxShadow: themeColors.CardBoxShadow,
|
||||
TooltipBg: themeColors.TooltipBg,
|
||||
TooltipText: themeColors.TooltipText,
|
||||
};
|
||||
1
libs/components/common/src/lib/colors/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { colors } from './colors';
|
||||
4
libs/components/common/src/lib/icon/Add/Add.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 20.4C16.6392 20.4 20.4 16.6392 20.4 12C20.4 7.36081 16.6392 3.6 12 3.6C7.36081 3.6 3.6 7.36081 3.6 12C3.6 16.6392 7.36081 20.4 12 20.4ZM12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 13L11 17H13V13H17V11H13V7H11L11 11H7V13H11Z" fill="#98ACBD"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 546 B |
11
libs/components/common/src/lib/icon/Add/Add.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import { FC } from 'react';
|
||||
import { SvgIcon, SvgIconProps } from '@mui/material';
|
||||
|
||||
export const AddIcon: FC<SvgIconProps> = props => (
|
||||
<SvgIcon {...props}>
|
||||
<g clipPath="url(#a)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 20.4C16.6392 20.4 20.4 16.6392 20.4 12C20.4 7.36081 16.6392 3.6 12 3.6C7.36081 3.6 3.6 7.36081 3.6 12C3.6 16.6392 7.36081 20.4 12 20.4ZM12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 13L11 17H13V13H17V11H13V7H11L11 11H7V13H11Z" fill="#98ACBD"/>
|
||||
</g>
|
||||
</SvgIcon>
|
||||
);
|
||||
1
libs/components/common/src/lib/icon/Clock/Clock.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g fill-rule="evenodd" clip-path="url(#a)" clip-rule="evenodd"><path d="M11.746 2.29C6.13 2.29 1.558 6.86 1.558 12.476c0 5.617 4.571 10.187 10.188 10.187 5.617 0 10.188-4.57 10.188-10.187 0-5.618-4.57-10.188-10.188-10.188Zm0 21.874C5.302 24.164.058 18.921.058 12.477.058 6.032 5.302.79 11.746.79c6.444 0 11.688 5.243 11.688 11.688 0 6.444-5.244 11.687-11.688 11.687Z"/><path d="M15.424 14.55H9.799V6.615h1.5v6.437h4.125v1.5Z"/></g><defs><clipPath id="a"><path d="M0 0H24V24H0z"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 563 B |
18
libs/components/common/src/lib/icon/Clock/Clock.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import { FC } from 'react';
|
||||
import { SvgIcon, SvgIconProps } from '@mui/material';
|
||||
/**
|
||||
* @deprecated Please use the icon from @toeverything/components/ui. If it does not exist, contact the designer to add。
|
||||
*/
|
||||
export const ClockIcon: FC<SvgIconProps> = props => (
|
||||
<SvgIcon {...props}>
|
||||
<g fillRule="evenodd" clipPath="url(#a)" clipRule="evenodd">
|
||||
<path d="M11.746 2.29C6.13 2.29 1.558 6.86 1.558 12.476c0 5.617 4.571 10.187 10.188 10.187 5.617 0 10.188-4.57 10.188-10.187 0-5.618-4.57-10.188-10.188-10.188Zm0 21.874C5.302 24.164.058 18.921.058 12.477.058 6.032 5.302.79 11.746.79c6.444 0 11.688 5.243 11.688 11.688 0 6.444-5.244 11.687-11.688 11.687Z" />
|
||||
<path d="M15.424 14.55H9.799V6.615h1.5v6.437h4.125v1.5Z" />
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="a">
|
||||
<path d="M0 0H24V24H0z" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</SvgIcon>
|
||||
);
|
||||
1
libs/components/common/src/lib/icon/Close/Close.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M20.468 21.383 2.491 3.404l1.061-1.06L21.53 20.322l-1.06 1.06Z" clip-rule="evenodd"/><path fill-rule="evenodd" d="m3.15 21.516-1.06-1.06L20.067 2.478l1.06 1.06L3.152 21.516Z" clip-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 291 B |
19
libs/components/common/src/lib/icon/Close/Close.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import { FC } from 'react';
|
||||
import { SvgIcon, SvgIconProps } from '@mui/material';
|
||||
/**
|
||||
* @deprecated Please use the icon from @toeverything/components/ui. If it does not exist, contact the designer to add。
|
||||
*/
|
||||
export const CloseIcon: FC<SvgIconProps> = props => (
|
||||
<SvgIcon {...props}>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M20.468 21.383 2.491 3.404l1.061-1.06L21.53 20.322l-1.06 1.06Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="m3.15 21.516-1.06-1.06L20.067 2.478l1.06 1.06L3.152 21.516Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</SvgIcon>
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M5.863 17.201.337 11.676l5.526-5.524 1.053 1.053-4.472 4.471 4.472 4.472-1.053 1.053ZM17.813 17.201l-1.053-1.053 4.47-4.472-4.47-4.471 1.053-1.053 5.524 5.524-5.524 5.525ZM10.319 16.26l-1.29-.745 4.848-8.4 1.29.746-4.848 8.398Z" clip-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 345 B |
@@ -0,0 +1,14 @@
|
||||
import { FC } from 'react';
|
||||
import { SvgIcon, SvgIconProps } from '@mui/material';
|
||||
/**
|
||||
* @deprecated Please use the icon from @toeverything/components/ui. If it does not exist, contact the designer to add。
|
||||
*/
|
||||
export const CodeBlockInlineIcon: FC<SvgIconProps> = props => (
|
||||
<SvgIcon {...props}>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M5.863 17.201.337 11.676l5.526-5.524 1.053 1.053-4.472 4.471 4.472 4.472-1.053 1.053ZM17.813 17.201l-1.053-1.053 4.47-4.472-4.47-4.471 1.053-1.053 5.524 5.524-5.524 5.525ZM10.319 16.26l-1.29-.745 4.848-8.4 1.29.746-4.848 8.398Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</SvgIcon>
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M4 4v16h15V8.616L14.055 4H4Zm1.28 1.253h7.879v4.26h4.561v9.234H5.28V5.253Zm9.159.837 2.323 2.169h-2.324v-2.17Z" clip-rule="evenodd"/><path fill-rule="evenodd" d="M7.053 8.758h4.162V7.505H7.053v1.253ZM7.053 12.835h8.723V11.58H7.053v1.254ZM7.053 16.836h8.723v-1.253H7.053v1.253Z" clip-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 394 B |
19
libs/components/common/src/lib/icon/Document/Document.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import { FC } from 'react';
|
||||
import { SvgIcon, SvgIconProps } from '@mui/material';
|
||||
/**
|
||||
* @deprecated Please use the icon from @toeverything/components/ui. If it does not exist, contact the designer to add。
|
||||
*/
|
||||
export const DocumentIcon: FC<SvgIconProps> = props => (
|
||||
<SvgIcon {...props}>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M4 4v16h15V8.616L14.055 4H4Zm1.28 1.253h7.879v4.26h4.561v9.234H5.28V5.253Zm9.159.837 2.323 2.169h-2.324v-2.17Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M7.053 8.758h4.162V7.505H7.053v1.253ZM7.053 12.835h8.723V11.58H7.053v1.254ZM7.053 16.836h8.723v-1.253H7.053v1.253Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</SvgIcon>
|
||||
);
|
||||
3
libs/components/common/src/lib/icon/Filter/Filter.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.6 10.8207V18.6373L13.4 15.8373V10.8208L18.584 4.6H5.41609L10.6 10.8207ZM15 16.5L10.5 21H8.99997V11.3999L3.36684 4.64018C2.82407 3.98886 3.28722 3 4.13506 3H19.865C20.7128 3 21.176 3.98886 20.6332 4.64019L15 11.4001V16.5Z" fill="#98ACBD"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 399 B |
10
libs/components/common/src/lib/icon/Filter/Filter.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import { FC } from 'react';
|
||||
import { SvgIcon, SvgIconProps } from '@mui/material';
|
||||
|
||||
export const FilterIcon: FC<SvgIconProps> = props => (
|
||||
<SvgIcon {...props}>
|
||||
<g clipPath="url(#a)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.6 10.8207V18.6373L13.4 15.8373V10.8208L18.584 4.6H5.41609L10.6 10.8207ZM15 16.5L10.5 21H8.99997V11.3999L3.36684 4.64018C2.82407 3.98886 3.28722 3 4.13506 3H19.865C20.7128 3 21.176 3.98886 20.6332 4.64019L15 11.4001V16.5Z" fill="#98ACBD"/>
|
||||
</g>
|
||||
</SvgIcon>
|
||||
);
|
||||
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6 3C4.34315 3 3 4.34315 3 6V18C3 19.6569 4.34315 21 6 21H18C19.6569 21 21 19.6569 21 18V6C21 4.34315 19.6569 3 18 3H6ZM16.2 6.79995H13V5.19995H18.8V11H17.2V8.0627L13.7174 11.5453L12.586 10.4139L16.2 6.79995ZM10.4808 12.5191L11.6122 13.6504L8.0626 17.2H11V18.8L5.19995 18.8V13H6.79995L6.79995 16.2L10.4808 12.5191Z" fill="#98ACBD"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 489 B |
@@ -0,0 +1,10 @@
|
||||
import { FC } from 'react';
|
||||
import { SvgIcon, SvgIconProps } from '@mui/material';
|
||||
|
||||
export const FullScreenIcon: FC<SvgIconProps> = props => (
|
||||
<SvgIcon {...props}>
|
||||
<g clipPath="url(#a)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6 3C4.34315 3 3 4.34315 3 6V18C3 19.6569 4.34315 21 6 21H18C19.6569 21 21 19.6569 21 18V6C21 4.34315 19.6569 3 18 3H6ZM16.2 6.79995H13V5.19995H18.8V11H17.2V8.0627L13.7174 11.5453L12.586 10.4139L16.2 6.79995ZM10.4808 12.5191L11.6122 13.6504L8.0626 17.2H11V18.8L5.19995 18.8V13H6.79995L6.79995 16.2L10.4808 12.5191Z" fill="#98ACBD"/>
|
||||
</g>
|
||||
</SvgIcon>
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#FF9F65" d="M6 15.004H18V17.003999999999998H6z"/><path fill="#3A4C5C" d="m7.656 16.445 2.908-.825 6.772-5.197a1.905 1.905 0 0 0 .287-2.624 1.938 1.938 0 0 0-1.189-.767 1.698 1.698 0 0 0-1.363.316l-6.75 5.197-1.594 2.624-.7.566.937 1.269.692-.56Zm8.163-8.08a.49.49 0 0 1 .385-.078.65.65 0 0 1 .412.28.612.612 0 0 1-.042.838l-6.57 5.018-.503.144-.524-.717.273-.452 6.57-5.032Z"/></svg>
|
||||
|
After Width: | Height: | Size: 467 B |
@@ -0,0 +1,17 @@
|
||||
import { FC } from 'react';
|
||||
import { SvgIcon, SvgIconProps } from '@mui/material';
|
||||
/**
|
||||
* @deprecated Please use the icon from @toeverything/components/ui. If it does not exist, contact the designer to add。
|
||||
*/
|
||||
export const HighlighterDuotoneIcon: FC<SvgIconProps> = props => (
|
||||
<SvgIcon {...props}>
|
||||
<path
|
||||
style={{ fill: 'var(--color-0)' }}
|
||||
d="M6 15.004H18V17.003999999999998H6z"
|
||||
/>
|
||||
<path
|
||||
style={{ fill: 'var(--color-1)' }}
|
||||
d="m7.656 16.445 2.908-.825 6.772-5.197a1.905 1.905 0 0 0 .287-2.624 1.938 1.938 0 0 0-1.189-.767 1.698 1.698 0 0 0-1.363.316l-6.75 5.197-1.594 2.624-.7.566.937 1.269.692-.56Zm8.163-8.08a.49.49 0 0 1 .385-.078.65.65 0 0 1 .412.28.612.612 0 0 1-.042.838l-6.57 5.018-.503.144-.524-.717.273-.452 6.57-5.032Z"
|
||||
/>
|
||||
</SvgIcon>
|
||||
);
|
||||
6
libs/components/common/src/lib/icon/Kanban/Kanban.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M21 3.79998C21 4.2418 20.6418 4.59998 20.2 4.59998L13.8 4.59997C13.3582 4.59997 13 4.2418 13 3.79997C13 3.35815 13.3582 2.99997 13.8 2.99997L20.2 2.99998C20.6418 2.99998 21 3.35815 21 3.79998Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 3.79998C11 4.2418 10.6418 4.59998 10.2 4.59998L3.8 4.59998C3.35817 4.59998 3 4.2418 3 3.79997C3 3.35815 3.35817 2.99997 3.8 2.99998L10.2 2.99998C10.6418 2.99998 11 3.35815 11 3.79998Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 8.6H5C4.77909 8.6 4.6 8.77909 4.6 9V19C4.6 19.2209 4.77909 19.4 5 19.4H9C9.22091 19.4 9.4 19.2209 9.4 19V9C9.4 8.77909 9.22091 8.6 9 8.6ZM5 7C3.89543 7 3 7.89543 3 9V19C3 20.1046 3.89543 21 5 21H9C10.1046 21 11 20.1046 11 19V9C11 7.89543 10.1046 7 9 7H5Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M19 8.6H15C14.7791 8.6 14.6 8.77909 14.6 9V14C14.6 14.2209 14.7791 14.4 15 14.4H19C19.2209 14.4 19.4 14.2209 19.4 14V9C19.4 8.77909 19.2209 8.6 19 8.6ZM15 7C13.8954 7 13 7.89543 13 9V14C13 15.1046 13.8954 16 15 16H19C20.1046 16 21 15.1046 21 14V9C21 7.89543 20.1046 7 19 7H15Z" fill="#98ACBD"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
13
libs/components/common/src/lib/icon/Kanban/Kanban.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import { FC } from 'react';
|
||||
import { SvgIcon, SvgIconProps } from '@mui/material';
|
||||
|
||||
export const KanbanIcon: FC<SvgIconProps> = props => (
|
||||
<SvgIcon {...props}>
|
||||
<g clipPath="url(#a)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M21 3.79998C21 4.2418 20.6418 4.59998 20.2 4.59998L13.8 4.59997C13.3582 4.59997 13 4.2418 13 3.79997C13 3.35815 13.3582 2.99997 13.8 2.99997L20.2 2.99998C20.6418 2.99998 21 3.35815 21 3.79998Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 3.79998C11 4.2418 10.6418 4.59998 10.2 4.59998L3.8 4.59998C3.35817 4.59998 3 4.2418 3 3.79997C3 3.35815 3.35817 2.99997 3.8 2.99998L10.2 2.99998C10.6418 2.99998 11 3.35815 11 3.79998Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 8.6H5C4.77909 8.6 4.6 8.77909 4.6 9V19C4.6 19.2209 4.77909 19.4 5 19.4H9C9.22091 19.4 9.4 19.2209 9.4 19V9C9.4 8.77909 9.22091 8.6 9 8.6ZM5 7C3.89543 7 3 7.89543 3 9V19C3 20.1046 3.89543 21 5 21H9C10.1046 21 11 20.1046 11 19V9C11 7.89543 10.1046 7 9 7H5Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M19 8.6H15C14.7791 8.6 14.6 8.77909 14.6 9V14C14.6 14.2209 14.7791 14.4 15 14.4H19C19.2209 14.4 19.4 14.2209 19.4 14V9C19.4 8.77909 19.2209 8.6 19 8.6ZM15 7C13.8954 7 13 7.89543 13 9V14C13 15.1046 13.8954 16 15 16H19C20.1046 16 21 15.1046 21 14V9C21 7.89543 20.1046 7 19 7H15Z" fill="#98ACBD"/>
|
||||
</g>
|
||||
</SvgIcon>
|
||||
);
|
||||
1
libs/components/common/src/lib/icon/List/List.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5.98 10.86v1.78h4.45v-1.78H5.98ZM5.98 15.52v1.78h7.55v-1.78H5.98ZM5.98 6.2v1.78h11.55V6.2H5.98Z"/><path fill-rule="evenodd" d="M1 22.5V1h21.5v21.5H1ZM2.5 21H21V2.5H2.5V21Z" clip-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 270 B |
15
libs/components/common/src/lib/icon/List/List.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import { FC } from 'react';
|
||||
import { SvgIcon, SvgIconProps } from '@mui/material';
|
||||
/**
|
||||
* @deprecated Please use the icon from @toeverything/components/ui. If it does not exist, contact the designer to add。
|
||||
*/
|
||||
export const ListIcon: FC<SvgIconProps> = props => (
|
||||
<SvgIcon {...props}>
|
||||
<path d="M5.98 10.86v1.78h4.45v-1.78H5.98ZM5.98 15.52v1.78h7.55v-1.78H5.98ZM5.98 6.2v1.78h11.55V6.2H5.98Z" />
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M1 22.5V1h21.5v21.5H1ZM2.5 21H21V2.5H2.5V21Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</SvgIcon>
|
||||
);
|
||||
1
libs/components/common/src/lib/icon/Newpage/Newpage.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g fill-rule="evenodd" clip-path="url(#a)" clip-rule="evenodd"><path d="M18.662 21.85H-.008V2.03h18.67v1.497l-17.17.002v16.82h15.67v-1.896h1.5v3.396Z"/><path d="M17.162 15.984h1.5V5.06h-1.5v10.923Z"/><path d="M12.676 11.272h10.66v-1.5h-10.66v1.5Z"/></g><defs><clipPath id="a"><path d="M0 0H24V24H0z"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 385 B |
19
libs/components/common/src/lib/icon/Newpage/Newpage.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import { FC } from 'react';
|
||||
import { SvgIcon, SvgIconProps } from '@mui/material';
|
||||
/**
|
||||
* @deprecated Please use the icon from @toeverything/components/ui. If it does not exist, contact the designer to add。
|
||||
*/
|
||||
export const NewpageIcon: FC<SvgIconProps> = props => (
|
||||
<SvgIcon {...props}>
|
||||
<g fillRule="evenodd" clipPath="url(#a)" clipRule="evenodd">
|
||||
<path d="M18.662 21.85H-.008V2.03h18.67v1.497l-17.17.002v16.82h15.67v-1.896h1.5v3.396Z" />
|
||||
<path d="M17.162 15.984h1.5V5.06h-1.5v10.923Z" />
|
||||
<path d="M12.676 11.272h10.66v-1.5h-10.66v1.5Z" />
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="a">
|
||||
<path d="M0 0H24V24H0z" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</SvgIcon>
|
||||
);
|
||||
1
libs/components/common/src/lib/icon/Pages/Pages.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M13.233 9.68h1.5V4.583h-1.5V9.68Z" clip-rule="evenodd"/><path fill-rule="evenodd" d="M13.45 10.43h5.5v-1.5h-5.5v1.5Z" clip-rule="evenodd"/><path fill-rule="evenodd" d="M3.996 21.482H18.58v-11.48l-4.896-4.668H3.996v16.148Zm16.084 1.5H2.496V3.834h11.787l5.797 5.525v13.623Z" clip-rule="evenodd"/><path fill-rule="evenodd" d="M17.12 8.324h3.993v-1.5H17.12v1.5ZM15.395 6.696h1.5V2.477h-1.5v4.219Z" clip-rule="evenodd"/><path fill-rule="evenodd" d="M22.242 20.877H18.95v-1.5h1.79V7.896l-4.895-4.668H6.159v1.797h-1.5V1.728h11.786l5.797 5.525v13.624Z" clip-rule="evenodd"/><path fill-rule="evenodd" d="M6.075 9.527h4.879v-1.5h-4.88v1.5ZM6.075 14.405H16.3v-1.5H6.075v1.5ZM6.075 19.195H16.3v-1.5H6.075v1.5Z" clip-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 815 B |
39
libs/components/common/src/lib/icon/Pages/Pages.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import { FC } from 'react';
|
||||
import { SvgIcon, SvgIconProps } from '@mui/material';
|
||||
/**
|
||||
* @deprecated Please use the icon from @toeverything/components/ui. If it does not exist, contact the designer to add。
|
||||
*/
|
||||
export const PagesIcon: FC<SvgIconProps> = props => (
|
||||
<SvgIcon {...props}>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M13.233 9.68h1.5V4.583h-1.5V9.68Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M13.45 10.43h5.5v-1.5h-5.5v1.5Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M3.996 21.482H18.58v-11.48l-4.896-4.668H3.996v16.148Zm16.084 1.5H2.496V3.834h11.787l5.797 5.525v13.623Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M17.12 8.324h3.993v-1.5H17.12v1.5ZM15.395 6.696h1.5V2.477h-1.5v4.219Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M22.242 20.877H18.95v-1.5h1.79V7.896l-4.895-4.668H6.159v1.797h-1.5V1.728h11.786l5.797 5.525v13.624Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M6.075 9.527h4.879v-1.5h-4.88v1.5ZM6.075 14.405H16.3v-1.5H6.075v1.5ZM6.075 19.195H16.3v-1.5H6.075v1.5Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</SvgIcon>
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#3A4C5C" d="M17.315 10.76c.417-.382.664-.911.685-1.472a2.101 2.101 0 0 0-.57-1.518 2.25 2.25 0 0 0-1.452-.754 2.04 2.04 0 0 0-1.576.47L9.78 11.084l-1.65 3.104a.933.933 0 0 0 .14 1.07.966.966 0 0 0 .429.291c.206.069.43.069.635 0l3.351-1.183 4.63-3.606Zm-1.948-2.196a.607.607 0 0 1 .446-.122.83.83 0 0 1 .512.276.682.682 0 0 1 0 .956l-4.416 3.42-.586.203-.677-.81.281-.527 4.44-3.396Z"/><path fill="#FF9F65" d="M6.825 17a.818.818 0 0 0 .826-.81c0-.448-.37-.81-.826-.81a.818.818 0 0 0-.825.81c0 .447.37.81.825.81Z"/></svg>
|
||||
|
After Width: | Height: | Size: 603 B |
@@ -0,0 +1,17 @@
|
||||
import { FC } from 'react';
|
||||
import { SvgIcon, SvgIconProps } from '@mui/material';
|
||||
/**
|
||||
* @deprecated Please use the icon from @toeverything/components/ui. If it does not exist, contact the designer to add。
|
||||
*/
|
||||
export const PencilDotDuotoneIcon: FC<SvgIconProps> = props => (
|
||||
<SvgIcon {...props}>
|
||||
<path
|
||||
style={{ fill: 'var(--color-0)' }}
|
||||
d="M17.315 10.76c.417-.382.664-.911.685-1.472a2.101 2.101 0 0 0-.57-1.518 2.25 2.25 0 0 0-1.452-.754 2.04 2.04 0 0 0-1.576.47L9.78 11.084l-1.65 3.104a.933.933 0 0 0 .14 1.07.966.966 0 0 0 .429.291c.206.069.43.069.635 0l3.351-1.183 4.63-3.606Zm-1.948-2.196a.607.607 0 0 1 .446-.122.83.83 0 0 1 .512.276.682.682 0 0 1 0 .956l-4.416 3.42-.586.203-.677-.81.281-.527 4.44-3.396Z"
|
||||
/>
|
||||
<path
|
||||
style={{ fill: 'var(--color-1)' }}
|
||||
d="M6.825 17a.818.818 0 0 0 .826-.81c0-.448-.37-.81-.826-.81a.818.818 0 0 0-.825.81c0 .447.37.81.825.81Z"
|
||||
/>
|
||||
</SvgIcon>
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#FF9F65" d="M8 14.779H20V15.779H8z" transform="rotate(-40.407 8 14.779)"/><path fill="#3A4C5C" d="M17.357 9.615A2.026 2.026 0 0 0 18 8.204a2.05 2.05 0 0 0-.534-1.457 2.069 2.069 0 0 0-1.354-.733 1.853 1.853 0 0 0-1.46.452l-7.007 6.19-1.538 2.985a.923.923 0 0 0 .123 1.036.945.945 0 0 0 .4.273c.192.067.4.067.592 0l3.13-1.138 7.006-6.197Zm-1.815-2.104a.497.497 0 0 1 .416-.117.708.708 0 0 1 .484.265.652.652 0 0 1 0 .912l-6.806 6.017-.546.203-.63-.78.26-.514 6.822-5.986Z"/></svg>
|
||||
|
After Width: | Height: | Size: 563 B |
@@ -0,0 +1,18 @@
|
||||
import { FC } from 'react';
|
||||
import { SvgIcon, SvgIconProps } from '@mui/material';
|
||||
/**
|
||||
* @deprecated Please use the icon from @toeverything/components/ui. If it does not exist, contact the designer to add。
|
||||
*/
|
||||
export const PencilDuotoneIcon: FC<SvgIconProps> = props => (
|
||||
<SvgIcon {...props}>
|
||||
<path
|
||||
style={{ fill: 'var(--color-0)' }}
|
||||
d="M8 14.779H20V15.779H8z"
|
||||
transform="rotate(-40.407 8 14.779)"
|
||||
/>
|
||||
<path
|
||||
style={{ fill: 'var(--color-1)' }}
|
||||
d="M17.357 9.615A2.026 2.026 0 0 0 18 8.204a2.05 2.05 0 0 0-.534-1.457 2.069 2.069 0 0 0-1.354-.733 1.853 1.853 0 0 0-1.46.452l-7.007 6.19-1.538 2.985a.923.923 0 0 0 .123 1.036.945.945 0 0 0 .4.273c.192.067.4.067.592 0l3.13-1.138 7.006-6.197Zm-1.815-2.104a.497.497 0 0 1 .416-.117.708.708 0 0 1 .484.265.652.652 0 0 1 0 .912l-6.806 6.017-.546.203-.63-.78.26-.514 6.822-5.986Z"
|
||||
/>
|
||||
</SvgIcon>
|
||||
);
|
||||
5
libs/components/common/src/lib/icon/Sorter/Sorter.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 4.6H5C4.77909 4.6 4.6 4.77909 4.6 5V9C4.6 9.22091 4.77909 9.4 5 9.4H9C9.22091 9.4 9.4 9.22091 9.4 9V5C9.4 4.77909 9.22091 4.6 9 4.6ZM5 3C3.89543 3 3 3.89543 3 5V9C3 10.1046 3.89543 11 5 11H9C10.1046 11 11 10.1046 11 9V5C11 3.89543 10.1046 3 9 3H5Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5 13C3.89543 13 3 13.8954 3 15V19C3 20.1046 3.89543 21 5 21H9C10.1046 21 11 20.1046 11 19V15C11 13.8954 10.1046 13 9 13H5ZM6.16661 19.3819L9.92421 15.6243L9.07568 14.7758L6.16661 17.6848L4.92421 16.4424L4.07568 17.291L6.16661 19.3819Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M18 17.8687L20.4343 15.4343L21.5657 16.5657L17 21.1314L12.4343 16.5657L13.5657 15.4343L16 17.8686L16 3H18L18 17.8687Z" fill="#98ACBD"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 921 B |
12
libs/components/common/src/lib/icon/Sorter/Sorter.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import { FC } from 'react';
|
||||
import { SvgIcon, SvgIconProps } from '@mui/material';
|
||||
|
||||
export const SorterIcon: FC<SvgIconProps> = props => (
|
||||
<SvgIcon {...props}>
|
||||
<g clipPath="url(#a)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 4.6H5C4.77909 4.6 4.6 4.77909 4.6 5V9C4.6 9.22091 4.77909 9.4 5 9.4H9C9.22091 9.4 9.4 9.22091 9.4 9V5C9.4 4.77909 9.22091 4.6 9 4.6ZM5 3C3.89543 3 3 3.89543 3 5V9C3 10.1046 3.89543 11 5 11H9C10.1046 11 11 10.1046 11 9V5C11 3.89543 10.1046 3 9 3H5Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5 13C3.89543 13 3 13.8954 3 15V19C3 20.1046 3.89543 21 5 21H9C10.1046 21 11 20.1046 11 19V15C11 13.8954 10.1046 13 9 13H5ZM6.16661 19.3819L9.92421 15.6243L9.07568 14.7758L6.16661 17.6848L4.92421 16.4424L4.07568 17.291L6.16661 19.3819Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M18 17.8687L20.4343 15.4343L21.5657 16.5657L17 21.1314L12.4343 16.5657L13.5657 15.4343L16 17.8686L16 3H18L18 17.8687Z" fill="#98ACBD"/>
|
||||
</g>
|
||||
</SvgIcon>
|
||||
);
|
||||
1
libs/components/common/src/lib/icon/Space/Space.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g clip-path="url(#a)"><path fill-rule="evenodd" d="M12.001 5.211a6.67 6.67 0 0 0-6.663 6.663 6.67 6.67 0 0 0 6.663 6.663 6.67 6.67 0 0 0 6.663-6.663A6.67 6.67 0 0 0 12 5.211Zm0 14.537c-4.342 0-7.874-3.532-7.874-7.874S7.659 4 12.001 4s7.874 3.532 7.874 7.874-3.532 7.874-7.874 7.874Z" clip-rule="evenodd"/><path stroke-width=".3" d="M12.001 5.211a6.67 6.67 0 0 0-6.663 6.663 6.67 6.67 0 0 0 6.663 6.663 6.67 6.67 0 0 0 6.663-6.663A6.67 6.67 0 0 0 12 5.211m0 14.537c-4.342 0-7.874-3.532-7.874-7.874S7.659 4 12.001 4s7.874 3.532 7.874 7.874-3.532 7.874-7.874 7.874"/><path fill-rule="evenodd" d="M3.636 16.083c-1.878 0-3.366-.326-3.603-1.304-.26-1.065 1.065-1.955 2.085-2.533a.605.605 0 1 1 .596 1.054c-1.403.795-1.501 1.218-1.501 1.222.392.513 4.49.712 11.208-.918 6.704-1.629 10.255-3.678 10.369-4.373-.046-.004-.413-.354-2.399-.357a.605.605 0 0 1 0-1.212h.002c2.225.004 3.362.42 3.576 1.307.697 2.873-10.774 5.693-11.263 5.812-.322.078-5.429 1.302-9.07 1.302Z" clip-rule="evenodd"/><path stroke-width=".3" d="M3.636 16.083c-1.878 0-3.366-.326-3.603-1.304-.26-1.065 1.065-1.955 2.085-2.533a.605.605 0 1 1 .596 1.054c-1.403.795-1.501 1.218-1.501 1.222.392.513 4.49.712 11.208-.918 6.704-1.629 10.255-3.678 10.369-4.373-.046-.004-.413-.354-2.399-.357a.605.605 0 0 1 0-1.212h.002c2.225.004 3.362.42 3.576 1.307.697 2.873-10.774 5.693-11.263 5.812-.322.078-5.429 1.302-9.07 1.302"/></g><defs><clipPath id="a"><path d="M0 0H24V24H0z"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
34
libs/components/common/src/lib/icon/Space/Space.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
import { FC } from 'react';
|
||||
import { SvgIcon, SvgIconProps } from '@mui/material';
|
||||
/**
|
||||
* @deprecated Please use the icon from @toeverything/components/ui. If it does not exist, contact the designer to add。
|
||||
*/
|
||||
export const SpaceIcon: FC<SvgIconProps> = props => (
|
||||
<SvgIcon {...props}>
|
||||
<g clipPath="url(#a)">
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M12.001 5.211a6.67 6.67 0 0 0-6.663 6.663 6.67 6.67 0 0 0 6.663 6.663 6.67 6.67 0 0 0 6.663-6.663A6.67 6.67 0 0 0 12 5.211Zm0 14.537c-4.342 0-7.874-3.532-7.874-7.874S7.659 4 12.001 4s7.874 3.532 7.874 7.874-3.532 7.874-7.874 7.874Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
<path
|
||||
strokeWidth={0.3}
|
||||
d="M12.001 5.211a6.67 6.67 0 0 0-6.663 6.663 6.67 6.67 0 0 0 6.663 6.663 6.67 6.67 0 0 0 6.663-6.663A6.67 6.67 0 0 0 12 5.211m0 14.537c-4.342 0-7.874-3.532-7.874-7.874S7.659 4 12.001 4s7.874 3.532 7.874 7.874-3.532 7.874-7.874 7.874"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M3.636 16.083c-1.878 0-3.366-.326-3.603-1.304-.26-1.065 1.065-1.955 2.085-2.533a.605.605 0 1 1 .596 1.054c-1.403.795-1.501 1.218-1.501 1.222.392.513 4.49.712 11.208-.918 6.704-1.629 10.255-3.678 10.369-4.373-.046-.004-.413-.354-2.399-.357a.605.605 0 0 1 0-1.212h.002c2.225.004 3.362.42 3.576 1.307.697 2.873-10.774 5.693-11.263 5.812-.322.078-5.429 1.302-9.07 1.302Z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
<path
|
||||
strokeWidth={0.3}
|
||||
d="M3.636 16.083c-1.878 0-3.366-.326-3.603-1.304-.26-1.065 1.065-1.955 2.085-2.533a.605.605 0 1 1 .596 1.054c-1.403.795-1.501 1.218-1.501 1.222.392.513 4.49.712 11.208-.918 6.704-1.629 10.255-3.678 10.369-4.373-.046-.004-.413-.354-2.399-.357a.605.605 0 0 1 0-1.212h.002c2.225.004 3.362.42 3.576 1.307.697 2.873-10.774 5.693-11.263 5.812-.322.078-5.429 1.302-9.07 1.302"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="a">
|
||||
<path d="M0 0H24V24H0z" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</SvgIcon>
|
||||
);
|
||||
3
libs/components/common/src/lib/icon/Table/Table.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6 4.6H18C18.7732 4.6 19.4 5.2268 19.4 6V7.99998L4.6 7.99997V6C4.6 5.2268 5.2268 4.6 6 4.6ZM9.6001 9.59997L19.4 9.59998V13.8L9.6001 13.8V9.59997ZM8.0001 13.8V9.59997L4.6 9.59997V13.8H8.0001ZM4.6 15.4H8.0001V19.4H6C5.2268 19.4 4.6 18.7732 4.6 18V15.4ZM9.6001 15.4L19.4 15.4V18C19.4 18.7732 18.7732 19.4 18 19.4H9.6001V15.4ZM3 6C3 4.34315 4.34315 3 6 3H18C19.6569 3 21 4.34315 21 6V18C21 19.6569 19.6569 21 18 21H6C4.34315 21 3 19.6569 3 18V6Z" fill="#98ACBD"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 616 B |
10
libs/components/common/src/lib/icon/Table/Table.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import { FC } from 'react';
|
||||
import { SvgIcon, SvgIconProps } from '@mui/material';
|
||||
|
||||
export const TableIcon: FC<SvgIconProps> = props => (
|
||||
<SvgIcon {...props}>
|
||||
<g clipPath="url(#a)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6 4.6H18C18.7732 4.6 19.4 5.2268 19.4 6V7.99998L4.6 7.99997V6C4.6 5.2268 5.2268 4.6 6 4.6ZM9.6001 9.59997L19.4 9.59998V13.8L9.6001 13.8V9.59997ZM8.0001 13.8V9.59997L4.6 9.59997V13.8H8.0001ZM4.6 15.4H8.0001V19.4H6C5.2268 19.4 4.6 18.7732 4.6 18V15.4ZM9.6001 15.4L19.4 15.4V18C19.4 18.7732 18.7732 19.4 18 19.4H9.6001V15.4ZM3 6C3 4.34315 4.34315 3 6 3H18C19.6569 3 21 4.34315 21 6V18C21 19.6569 19.6569 21 18 21H6C4.34315 21 3 19.6569 3 18V6Z" fill="#98ACBD"/>
|
||||
</g>
|
||||
</SvgIcon>
|
||||
);
|
||||
@@ -0,0 +1,8 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 4.19999L21 4.19999L21 5.79999L10 5.79999L10 4.19999Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 18.2L21 18.2L21 19.8L10 19.8L10 18.2Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 11.2L21 11.2L21 12.8L10 12.8L10 11.2Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.57574 2.77576L8.42426 3.62428L5 7.04855L3.07574 5.12428L3.92426 4.27576L5 5.35149L7.57574 2.77576Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.57574 16.7758L8.42426 17.6243L5 21.0485L3.07574 19.1243L3.92426 18.2758L5 19.3515L7.57574 16.7758Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.57574 9.77576L8.42426 10.6243L5 14.0485L3.07574 12.1243L3.92426 11.2758L5 12.3515L7.57574 9.77576Z" fill="#98ACBD"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 976 B |
15
libs/components/common/src/lib/icon/TodoList/TodoList.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import { FC } from 'react';
|
||||
import { SvgIcon, SvgIconProps } from '@mui/material';
|
||||
|
||||
export const TodoListIcon: FC<SvgIconProps> = props => (
|
||||
<SvgIcon {...props}>
|
||||
<g clipPath="url(#a)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 4.19999L21 4.19999L21 5.79999L10 5.79999L10 4.19999Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 18.2L21 18.2L21 19.8L10 19.8L10 18.2Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 11.2L21 11.2L21 12.8L10 12.8L10 11.2Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.57574 2.77576L8.42426 3.62428L5 7.04855L3.07574 5.12428L3.92426 4.27576L5 5.35149L7.57574 2.77576Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.57574 16.7758L8.42426 17.6243L5 21.0485L3.07574 19.1243L3.92426 18.2758L5 19.3515L7.57574 16.7758Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.57574 9.77576L8.42426 10.6243L5 14.0485L3.07574 12.1243L3.92426 11.2758L5 12.3515L7.57574 9.77576Z" fill="#98ACBD"/>
|
||||
</g>
|
||||
</SvgIcon>
|
||||
);
|
||||
4
libs/components/common/src/lib/icon/UnGroup/UnGroup.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 3C3.44772 3 3 3.44772 3 4V7C3 7.55228 3.44772 8 4 8H4.70005L4.70005 16H4C3.44772 16 3 16.4477 3 17V20C3 20.5523 3.44772 21 4 21H7C7.55229 21 8 20.5523 8 20L8 19.3H16V20C16 20.5523 16.4477 21 17 21H20C20.5523 21 21 20.5523 21 20V17C21 16.4477 20.5523 16 20 16H19.3V8H20C20.5523 8 21 7.55228 21 7V4C21 3.44772 20.5523 3 20 3H17C16.4477 3 16 3.44772 16 4V4.70005L8 4.70005V4C8 3.93096 7.993 3.86356 7.97968 3.79847C7.88644 3.34278 7.48325 3 7 3H4ZM8 6.30005V7C8 7.55228 7.55228 8 7 8H6.30005L6.30005 16H7C7.55229 16 8 16.4477 8 17L8 17.7H16V17C16 16.4477 16.4477 16 17 16H17.7L17.7 8H17C16.4477 8 16 7.55228 16 7V6.30005L8 6.30005Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 8C8.44772 8 8 8.44772 8 9V12.3333C8 12.8856 8.44772 13.3333 9 13.3333H10.6667V15C10.6667 15.5523 11.1144 16 11.6667 16H15C15.5523 16 16 15.5523 16 15V11.6667C16 11.1144 15.5523 10.6667 15 10.6667H13.3333V9C13.3333 8.44772 12.8856 8 12.3333 8H9Z" fill="#98ACBD"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
11
libs/components/common/src/lib/icon/UnGroup/UnGroup.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import { FC } from 'react';
|
||||
import { SvgIcon, SvgIconProps } from '@mui/material';
|
||||
|
||||
export const UnGroupIcon: FC<SvgIconProps> = props => (
|
||||
<SvgIcon {...props}>
|
||||
<g clipPath="url(#a)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 3C3.44772 3 3 3.44772 3 4V7C3 7.55228 3.44772 8 4 8H4.70005L4.70005 16H4C3.44772 16 3 16.4477 3 17V20C3 20.5523 3.44772 21 4 21H7C7.55229 21 8 20.5523 8 20L8 19.3H16V20C16 20.5523 16.4477 21 17 21H20C20.5523 21 21 20.5523 21 20V17C21 16.4477 20.5523 16 20 16H19.3V8H20C20.5523 8 21 7.55228 21 7V4C21 3.44772 20.5523 3 20 3H17C16.4477 3 16 3.44772 16 4V4.70005L8 4.70005V4C8 3.93096 7.993 3.86356 7.97968 3.79847C7.88644 3.34278 7.48325 3 7 3H4ZM8 6.30005V7C8 7.55228 7.55228 8 7 8H6.30005L6.30005 16H7C7.55229 16 8 16.4477 8 17L8 17.7H16V17C16 16.4477 16.4477 16 17 16H17.7L17.7 8H17C16.4477 8 16 7.55228 16 7V6.30005L8 6.30005Z" fill="#98ACBD"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 8C8.44772 8 8 8.44772 8 9V12.3333C8 12.8856 8.44772 13.3333 9 13.3333H10.6667V15C10.6667 15.5523 11.1144 16 11.6667 16H15C15.5523 16 16 15.5523 16 15V11.6667C16 11.1144 15.5523 10.6667 15 10.6667H13.3333V9C13.3333 8.44772 12.8856 8 12.3333 8H9Z" fill="#98ACBD"/>
|
||||
</g>
|
||||
</SvgIcon>
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g clip-path="url(#a)"><path d="M2 22.5V1h21.5v21.5H2ZM3.66 2.662v18.177h18.177V2.662H3.661Z"/><path d="M17.842 21.369V1h-1.698v20.369h1.698Z"/></g><defs><clipPath id="a"><path d="M0 0H24V24H0z" transform="rotate(90 12 12)"/></clipPath></defs></svg>
|
||||
|
After Width: | Height: | Size: 309 B |
@@ -0,0 +1,18 @@
|
||||
import { FC } from 'react';
|
||||
import { SvgIcon, SvgIconProps } from '@mui/material';
|
||||
/**
|
||||
* @deprecated Please use the icon from @toeverything/components/ui. If it does not exist, contact the designer to add。
|
||||
*/
|
||||
export const ViewSidebarIcon: FC<SvgIconProps> = props => (
|
||||
<SvgIcon {...props}>
|
||||
<g clipPath="url(#a)">
|
||||
<path d="M2 22.5V1h21.5v21.5H2ZM3.66 2.662v18.177h18.177V2.662H3.661Z" />
|
||||
<path d="M17.842 21.369V1h-1.698v20.369h1.698Z" />
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="a">
|
||||
<path d="M0 0H24V24H0z" transform="rotate(90 12 12)" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</SvgIcon>
|
||||
);
|
||||
21
libs/components/common/src/lib/icon/index.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
export const timestamp = 1650018884367;
|
||||
export * from './CodeBlockInline/CodeBlockInline';
|
||||
export * from './Newpage/Newpage';
|
||||
export * from './Pages/Pages';
|
||||
export * from './Clock/Clock';
|
||||
export * from './Space/Space';
|
||||
export * from './Close/Close';
|
||||
export * from './ViewSidebar/ViewSidebar';
|
||||
export * from './List/List';
|
||||
export * from './Document/Document';
|
||||
export * from './HighlighterDuotone/HighlighterDuotone';
|
||||
export * from './PencilDotDuotone/PencilDotDuotone';
|
||||
export * from './PencilDuotone/PencilDuotone';
|
||||
export * from './TodoList/TodoList';
|
||||
export * from './Kanban/Kanban';
|
||||
export * from './Table/Table';
|
||||
export * from './Add/Add';
|
||||
export * from './Filter/Filter';
|
||||
export * from './Sorter/Sorter';
|
||||
export * from './FullScreen/FullScreen';
|
||||
export * from './UnGroup/UnGroup';
|
||||
51
libs/components/common/src/lib/index.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { BaseEditor } from 'slate';
|
||||
import { ReactEditor } from 'slate-react';
|
||||
import { LinkElement } from './text/plugins/link';
|
||||
import { RefLinkElement } from './text/plugins/reflink';
|
||||
|
||||
export type CustomText = { text: string };
|
||||
export type CustomElement =
|
||||
| { type: string; children: CustomElement[] }
|
||||
| CustomText
|
||||
| LinkElement
|
||||
| RefLinkElement;
|
||||
declare module 'slate' {
|
||||
interface CustomTypes {
|
||||
Editor: BaseEditor & ReactEditor;
|
||||
Element: CustomElement;
|
||||
Text: CustomText;
|
||||
}
|
||||
}
|
||||
|
||||
export { BlockPreview, StyledBlockPreview } from './block-preview';
|
||||
export { default as Button } from './button';
|
||||
export type { CommonListItem } from './list';
|
||||
export { CommonList, BackLink, commonListContainer } from './list';
|
||||
export * from './Logo';
|
||||
export { default as Toolbar } from './toolbar';
|
||||
export { CollapsibleTitle } from './collapsible-title';
|
||||
|
||||
export * from './text';
|
||||
|
||||
export {
|
||||
NewpageIcon,
|
||||
ClockIcon,
|
||||
ViewSidebarIcon,
|
||||
ListIcon,
|
||||
SpaceIcon,
|
||||
PencilDotDuotoneIcon,
|
||||
PencilDuotoneIcon,
|
||||
HighlighterDuotoneIcon,
|
||||
CodeBlockInlineIcon,
|
||||
PagesIcon,
|
||||
CloseIcon,
|
||||
DocumentIcon,
|
||||
TodoListIcon,
|
||||
KanbanIcon,
|
||||
TableIcon,
|
||||
AddIcon,
|
||||
FilterIcon,
|
||||
SorterIcon,
|
||||
FullScreenIcon,
|
||||
UnGroupIcon,
|
||||
} from './icon';
|
||||
202
libs/components/common/src/lib/list/index.tsx
Normal file
@@ -0,0 +1,202 @@
|
||||
import { FC, useState } from 'react';
|
||||
import { useNavigate, useParams } from 'react-router';
|
||||
import clsx from 'clsx';
|
||||
import style9 from 'style9';
|
||||
|
||||
import {
|
||||
BaseButton,
|
||||
ListButton,
|
||||
MuiClickAwayListener,
|
||||
Popover,
|
||||
SvgIconProps,
|
||||
} from '@toeverything/components/ui';
|
||||
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
|
||||
import { BlockSearchItem } from '@toeverything/datasource/jwt';
|
||||
|
||||
import { BlockPreview } from '../block-preview';
|
||||
import { BackwardUndoIcon } from '@toeverything/components/icons';
|
||||
|
||||
export const commonListContainer = 'commonListContainer';
|
||||
import { useFlag } from '@toeverything/datasource/feature-flags';
|
||||
|
||||
type Content = {
|
||||
id: string;
|
||||
content: string;
|
||||
icon: FC<SvgIconProps>;
|
||||
};
|
||||
|
||||
export type CommonListItem = {
|
||||
divider?: string;
|
||||
content?: Content;
|
||||
block?: BlockSearchItem;
|
||||
};
|
||||
|
||||
type MenuItemsProps = {
|
||||
className?: string;
|
||||
items: CommonListItem[];
|
||||
currentItem: string;
|
||||
setCurrentItem: (itemType: string) => void;
|
||||
onSelected?: (item: string) => void;
|
||||
};
|
||||
|
||||
export const CommonList = (props: MenuItemsProps) => {
|
||||
const { items, currentItem, setCurrentItem, onSelected } = props;
|
||||
// const JSONUnsupportedBlockTypes = useFlag('JSONUnsupportedBlockTypes', [
|
||||
// 'page',
|
||||
// ]);
|
||||
// TODO Insert bidirectional link to be developed
|
||||
const JSONUnsupportedBlockTypes = ['page'];
|
||||
let usedItems = items.filter(item => {
|
||||
return !JSONUnsupportedBlockTypes.includes(item?.content?.id);
|
||||
});
|
||||
return (
|
||||
<div className={clsx(styles('root_container'), props.className)}>
|
||||
<div
|
||||
className={clsx([
|
||||
styles('scroll_container'),
|
||||
commonListContainer,
|
||||
])}
|
||||
>
|
||||
{usedItems?.length ? (
|
||||
usedItems.map((item, idx) => {
|
||||
if (item.block) {
|
||||
return (
|
||||
<BlockPreview
|
||||
className={clsx(
|
||||
styles('button'),
|
||||
`item-${item.block.id}`
|
||||
)}
|
||||
key={item.block.id}
|
||||
block={item.block}
|
||||
onClick={() => onSelected?.(item.block.id)}
|
||||
onMouseOver={() =>
|
||||
setCurrentItem?.(item.block.id)
|
||||
}
|
||||
hover={currentItem === item.block.id}
|
||||
/>
|
||||
);
|
||||
} else if (item.content) {
|
||||
const { id, content, icon } = item.content;
|
||||
return (
|
||||
<ListButton
|
||||
key={id}
|
||||
className={clsx(
|
||||
styles('button'),
|
||||
`item-${id}`
|
||||
)}
|
||||
onClick={() => onSelected?.(id)}
|
||||
onMouseOver={() => setCurrentItem?.(id)}
|
||||
hover={currentItem === id}
|
||||
content={content}
|
||||
icon={icon}
|
||||
/>
|
||||
);
|
||||
} else if (item.divider) {
|
||||
return (
|
||||
<hr
|
||||
className={styles('separator')}
|
||||
key={`${item.divider}${idx}-separator`}
|
||||
tabIndex={-1}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
})
|
||||
) : (
|
||||
<span className={styles('empty')}>no search result</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
type BackLinkProps = {
|
||||
blocks?: BlockSearchItem[];
|
||||
workspaceId: string;
|
||||
};
|
||||
|
||||
export const BackLink = (props: BackLinkProps) => {
|
||||
const { blocks } = props;
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [item, set_item] = useState<string>();
|
||||
const [visible, set_visible] = useState(false);
|
||||
|
||||
return blocks?.length ? (
|
||||
<MuiClickAwayListener onClickAway={() => set_visible(false)}>
|
||||
<Popover
|
||||
defaultVisible={visible}
|
||||
placement="bottom-start"
|
||||
content={
|
||||
<CommonList
|
||||
items={blocks.map(block => ({ block }))}
|
||||
currentItem={item}
|
||||
setCurrentItem={set_item}
|
||||
onSelected={id =>
|
||||
navigate(`/${props.workspaceId}/${id}`)
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<BaseButton
|
||||
className={styles('backlinks_button')}
|
||||
onClick={() => set_visible(bool => !bool)}
|
||||
>
|
||||
<BackwardUndoIcon sx={{ width: 20, height: 20 }} />
|
||||
<span>Backlinks ({blocks.length})</span>
|
||||
</BaseButton>
|
||||
</Popover>
|
||||
</MuiClickAwayListener>
|
||||
) : null;
|
||||
};
|
||||
|
||||
const styles = style9.create({
|
||||
root_container: {
|
||||
width: '228px',
|
||||
overflowX: 'hidden',
|
||||
overflowY: 'hidden',
|
||||
marginTop: '6px',
|
||||
marginLeft: '5px',
|
||||
},
|
||||
scroll_container: {
|
||||
width: 'calc(100% + 25px)',
|
||||
height: '100%',
|
||||
overflowY: 'scroll',
|
||||
},
|
||||
button: {
|
||||
width: '220px',
|
||||
borderRadius: '5px!important',
|
||||
marginTop: '0px!important',
|
||||
},
|
||||
empty: {
|
||||
display: 'inline-flex',
|
||||
width: '220px',
|
||||
height: '100%',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
fontSize: '15px',
|
||||
lineHeight: '17px',
|
||||
textAlign: 'justify',
|
||||
letterSpacing: '1.5px',
|
||||
color: '#4C6275',
|
||||
},
|
||||
separator: {
|
||||
height: '1px',
|
||||
border: 0,
|
||||
marginTop: '8px',
|
||||
marginBottom: '8px',
|
||||
backgroundColor: 'rgba(152, 172, 189, 0.6)',
|
||||
borderColor: 'rgba(152, 172, 189, 0.6)',
|
||||
},
|
||||
backlinks_container: {
|
||||
borderRadius: '10px',
|
||||
boxShadow: '0px 1px 10px rgba(152, 172, 189, 0.6)',
|
||||
backgroundColor: '#fff',
|
||||
},
|
||||
backlinks_button: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
},
|
||||
});
|
||||
940
libs/components/common/src/lib/text/EditableText.tsx
Normal file
@@ -0,0 +1,940 @@
|
||||
/* eslint-disable max-lines */
|
||||
import React, {
|
||||
KeyboardEvent,
|
||||
KeyboardEventHandler,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
forwardRef,
|
||||
MouseEventHandler,
|
||||
useLayoutEffect,
|
||||
CSSProperties,
|
||||
MouseEvent,
|
||||
DragEvent,
|
||||
} from 'react';
|
||||
import isHotkey from 'is-hotkey';
|
||||
import {
|
||||
createEditor,
|
||||
Descendant,
|
||||
Range,
|
||||
Element as SlateElement,
|
||||
Editor,
|
||||
Transforms,
|
||||
Node,
|
||||
Path,
|
||||
} from 'slate';
|
||||
import {
|
||||
Editable,
|
||||
withReact,
|
||||
Slate,
|
||||
ReactEditor,
|
||||
useSlateStatic,
|
||||
} from 'slate-react';
|
||||
|
||||
import { ErrorBoundary, isEqual, uaHelper } from '@toeverything/utils';
|
||||
|
||||
import { Contents, SlateUtils, isSelectAll } from './slate-utils';
|
||||
import {
|
||||
getCommentsIdsOnTextNode,
|
||||
getExtraPropertiesFromEditorOutmostNode,
|
||||
isInterceptCharacter,
|
||||
matchMarkdown,
|
||||
} from './utils';
|
||||
import { HOTKEYS, INLINE_STYLES } from './constants';
|
||||
import { LinkComponent, LinkModal, withLinks, wrapLink } from './plugins/link';
|
||||
import { withDate, InlineDate } from './plugins/date';
|
||||
import { CustomElement } from '..';
|
||||
import isUrl from 'is-url';
|
||||
import { InlineRefLink } from './plugins/reflink';
|
||||
import { TextWithComments } from './element-leaf/TextWithComments';
|
||||
|
||||
export interface TextProps {
|
||||
/** read only */
|
||||
readonly?: boolean;
|
||||
/** current value */
|
||||
currentValue?: CustomElement[];
|
||||
/** extra props at editor top level; it's stored at the parent of currentValue */
|
||||
textStyle?: Record<string, unknown>;
|
||||
/** auto focus */
|
||||
autoFocus?: boolean;
|
||||
/** id */
|
||||
id?: string;
|
||||
/** keyDown event, return true, cancel the default behavior */
|
||||
handleKeyDown?: (e: KeyboardEvent<HTMLDivElement>) => boolean | undefined;
|
||||
/** enter event, return true, cancel the default behavior */
|
||||
handleEnter?: ({
|
||||
splitContents,
|
||||
isShiftKey,
|
||||
}: {
|
||||
splitContents: Contents;
|
||||
isShiftKey: boolean;
|
||||
}) => Promise<boolean | undefined> | boolean | undefined;
|
||||
/** select event */
|
||||
handleSelectAll?: () => void;
|
||||
/** select event */
|
||||
handleSelect?: (selection: Range) => void;
|
||||
/** After text change event, generally used to synchronize model */
|
||||
handleChange?: (
|
||||
value: SlateElement[],
|
||||
textStyle?: Record<string, unknown>
|
||||
) => void;
|
||||
/** tab event, return true, cancel the default behavior */
|
||||
handleTab?: ({
|
||||
isShiftKey,
|
||||
}: {
|
||||
isShiftKey: boolean;
|
||||
}) => boolean | undefined | Promise<boolean | undefined>;
|
||||
/** Backspace event */
|
||||
handleBackSpace?: ({
|
||||
isCollAndStart,
|
||||
}: {
|
||||
isCollAndStart: boolean;
|
||||
}) => boolean | undefined | Promise<boolean | undefined>;
|
||||
/** Whether markdown is supported */
|
||||
supportMarkdown?: boolean;
|
||||
/** Whether to support inline linking */
|
||||
supportLink?: boolean;
|
||||
/** Whether to show placeholder all the time */
|
||||
alwaysShowPlaceholder?: boolean;
|
||||
/** placeholder */
|
||||
placeholder?: string;
|
||||
/** Convert Block API */
|
||||
handleConvert?: (type: string, options?: Record<string, unknown>) => void;
|
||||
/** undo */
|
||||
handleUndo?: () => void;
|
||||
/** redo */
|
||||
handleRedo?: () => void;
|
||||
/** up button */
|
||||
handleUp?: (event: KeyboardEvent) => boolean | undefined | Promise<boolean>;
|
||||
/** down button */
|
||||
handleDown?: (
|
||||
event: KeyboardEvent
|
||||
) => boolean | undefined | Promise<boolean>;
|
||||
/** left button */
|
||||
handleLeft?: () => boolean | undefined | Promise<boolean>;
|
||||
/** right button */
|
||||
handleRight?: () => boolean | undefined | Promise<boolean>;
|
||||
/** press / */
|
||||
handleSlash?: () => void;
|
||||
/** Click event, fired after select */
|
||||
handleClick?: MouseEventHandler<HTMLDivElement>;
|
||||
handleMouseDown?: MouseEventHandler<HTMLDivElement>;
|
||||
/** No need to synchronize the model's change event */
|
||||
handleTextChange?: (value: SlateElement[]) => void;
|
||||
/** esc */
|
||||
handleEsc?: () => void;
|
||||
/** focus */
|
||||
handleFocus?: (selection: Range) => void;
|
||||
handleBlur?: (selection: Range) => void;
|
||||
/** hide inlinemenu */
|
||||
hideInlineMenu?: () => void;
|
||||
/** Whether as a pure controlled component */
|
||||
isControlled?: boolean;
|
||||
/** The dataset that needs to be added to the text-paragraph dom is initialized and used, and changes are not supported */
|
||||
paragraphDataSets?: string[];
|
||||
/** class */
|
||||
className?: string;
|
||||
style?: CSSProperties;
|
||||
/** if return true prevent the default slate copy */
|
||||
handleCopy?: () => boolean | undefined | Promise<boolean>;
|
||||
}
|
||||
type ExtendedTextUtils = SlateUtils & {
|
||||
setLinkModalVisible: (visible: boolean) => void;
|
||||
};
|
||||
|
||||
// @refresh reset
|
||||
export const Text = forwardRef<ExtendedTextUtils, TextProps>((props, ref) => {
|
||||
const {
|
||||
currentValue = [],
|
||||
textStyle = {},
|
||||
readonly = false,
|
||||
id,
|
||||
handleKeyDown,
|
||||
handleEnter,
|
||||
handleSelectAll,
|
||||
handleSelect,
|
||||
handleChange,
|
||||
handleTab,
|
||||
handleBackSpace,
|
||||
handleConvert,
|
||||
handleRedo,
|
||||
handleUndo,
|
||||
handleUp,
|
||||
handleLeft,
|
||||
handleRight,
|
||||
handleTextChange,
|
||||
handleDown,
|
||||
handleClick,
|
||||
handleMouseDown,
|
||||
handleEsc,
|
||||
handleSlash,
|
||||
handleFocus,
|
||||
handleBlur,
|
||||
handleCopy,
|
||||
hideInlineMenu,
|
||||
className,
|
||||
supportMarkdown = true,
|
||||
supportLink = true,
|
||||
alwaysShowPlaceholder = false,
|
||||
placeholder = '',
|
||||
autoFocus = false,
|
||||
isControlled = false,
|
||||
paragraphDataSets = [],
|
||||
style,
|
||||
} = props;
|
||||
|
||||
/** forceupdate */
|
||||
const [updateTimes, forceUpdate] = useState<number>(0);
|
||||
|
||||
/** placeholder */
|
||||
const [showPlaceholder, setShowPlaceholder] = useState<boolean>(
|
||||
() => alwaysShowPlaceholder
|
||||
);
|
||||
|
||||
/** Whether linkModal is displayed */
|
||||
const [linkModalVisible, setLinkModalVisible] = useState<boolean>(false);
|
||||
|
||||
/** linkUrl */
|
||||
const [linkUrl, setLinkUrl] = useState<string>('');
|
||||
|
||||
/** The selection area through blur deselect is used to restore the selection area */
|
||||
const previous_selection_from_on_blur_ref = useRef<Range>(null);
|
||||
|
||||
const focused = useRef(false);
|
||||
|
||||
const editor = useMemo(
|
||||
() => withDate(withLinks(withReact(createEditor() as ReactEditor))),
|
||||
[]
|
||||
);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const newVal = createSlateText(currentValue, textStyle);
|
||||
if (!isEqual(editor.children, newVal)) {
|
||||
editor.children = newVal;
|
||||
forceUpdate(v => v + 1);
|
||||
}
|
||||
}, [currentValue, editor, textStyle]);
|
||||
|
||||
const onLinkModalVisibleChange = useCallback(
|
||||
(visible: boolean, isInsertLink?: boolean, url?: string) => {
|
||||
setLinkModalVisible(visible);
|
||||
if (url) {
|
||||
setLinkUrl(url);
|
||||
}
|
||||
if (!isInsertLink && previous_selection_from_on_blur_ref.current) {
|
||||
Transforms.select(
|
||||
editor,
|
||||
previous_selection_from_on_blur_ref.current
|
||||
);
|
||||
requestAnimationFrame(() => {
|
||||
ReactEditor.focus(editor);
|
||||
});
|
||||
}
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const renderElement = useCallback(
|
||||
(props: any) => {
|
||||
return (
|
||||
<EditorElement
|
||||
{...props}
|
||||
editor={editor}
|
||||
onLinkModalVisibleChange={onLinkModalVisibleChange}
|
||||
hideInlineMenu={hideInlineMenu}
|
||||
paragraphDataSets={paragraphDataSets}
|
||||
id={id}
|
||||
/>
|
||||
);
|
||||
},
|
||||
[
|
||||
editor,
|
||||
hideInlineMenu,
|
||||
id,
|
||||
onLinkModalVisibleChange,
|
||||
paragraphDataSets,
|
||||
]
|
||||
);
|
||||
|
||||
const renderLeaf = useCallback((props: any) => {
|
||||
return <EditorLeaf {...props} />;
|
||||
}, []);
|
||||
|
||||
const utils = useRef<SlateUtils>(null);
|
||||
|
||||
const resetSelectionIfNeeded = () => {
|
||||
if (
|
||||
currentValue &&
|
||||
Array.isArray(currentValue) &&
|
||||
utils.current &&
|
||||
editor.selection
|
||||
) {
|
||||
const { selectionEnd } = utils.current.getSelectionStartAndEnd();
|
||||
const end = currentValue[currentValue.length - 1];
|
||||
if ('text' in end) {
|
||||
const endOffset = end.text.length;
|
||||
if (selectionEnd.offset > end.text.length) {
|
||||
utils.current.setSelection({
|
||||
focus: {
|
||||
path: selectionEnd.path,
|
||||
offset: endOffset,
|
||||
},
|
||||
anchor: {
|
||||
path: selectionEnd.path,
|
||||
offset: endOffset,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!utils.current) {
|
||||
utils.current = new SlateUtils(editor);
|
||||
if (ref && 'current' in ref) {
|
||||
ref.current = utils.current as ExtendedTextUtils;
|
||||
ref.current.setLinkModalVisible = setLinkModalVisible;
|
||||
}
|
||||
}
|
||||
if (autoFocus) {
|
||||
utils.current.focus();
|
||||
}
|
||||
return () => {
|
||||
utils.current.dispose();
|
||||
utils.current = null;
|
||||
};
|
||||
}, []);
|
||||
|
||||
const onKeyDown: KeyboardEventHandler<HTMLDivElement> = e => {
|
||||
const shouldPreventDefault = handleKeyDown && handleKeyDown(e);
|
||||
if (shouldPreventDefault) {
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
if (e.metaKey && e.key === 'a') {
|
||||
e.stopPropagation();
|
||||
if (isSelectAll(editor)) {
|
||||
e.preventDefault();
|
||||
handleSelectAll && handleSelectAll();
|
||||
}
|
||||
}
|
||||
|
||||
if (e.metaKey && e.key === 'z') {
|
||||
if (e.shiftKey) {
|
||||
// redo
|
||||
handleRedo && handleRedo();
|
||||
} else {
|
||||
// undo
|
||||
handleUndo && handleUndo();
|
||||
}
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
if (e.code === 'ShiftLeft') {
|
||||
return;
|
||||
}
|
||||
// https://github.com/facebook/react/issues/13104
|
||||
if (!e.nativeEvent.isComposing) {
|
||||
switch (e.code) {
|
||||
case 'Enter': {
|
||||
onEnter(e);
|
||||
break;
|
||||
}
|
||||
case 'Tab': {
|
||||
onTab(e);
|
||||
break;
|
||||
}
|
||||
case 'Backspace': {
|
||||
onBackSpace(e);
|
||||
break;
|
||||
}
|
||||
case 'ArrowUp': {
|
||||
e.stopPropagation();
|
||||
onUp(e);
|
||||
break;
|
||||
}
|
||||
case 'ArrowDown': {
|
||||
e.stopPropagation();
|
||||
onDown(e);
|
||||
break;
|
||||
}
|
||||
case 'ArrowRight': {
|
||||
e.stopPropagation();
|
||||
onRight(e);
|
||||
break;
|
||||
}
|
||||
case 'ArrowLeft': {
|
||||
e.stopPropagation();
|
||||
onLeft(e);
|
||||
break;
|
||||
}
|
||||
case 'Digit2': {
|
||||
break;
|
||||
}
|
||||
case 'Escape': {
|
||||
e.stopPropagation();
|
||||
handleEsc?.();
|
||||
}
|
||||
}
|
||||
}
|
||||
handle_hotkey_if_needed(e);
|
||||
};
|
||||
|
||||
const handle_hotkey_if_needed = (e: KeyboardEvent) => {
|
||||
for (const hotkey in HOTKEYS) {
|
||||
if (isHotkey(hotkey, e)) {
|
||||
e.preventDefault();
|
||||
const mark = HOTKEYS[hotkey as keyof typeof HOTKEYS];
|
||||
if (mark === 'link' && supportLink) {
|
||||
setLinkModalVisible(true);
|
||||
hideInlineMenu?.();
|
||||
return;
|
||||
}
|
||||
toggleMark(editor, mark);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const isMarkActive = (editor: ReactEditor, format: string) => {
|
||||
const marks: any = Editor.marks(editor);
|
||||
return marks ? marks[format] === true : false;
|
||||
};
|
||||
|
||||
const toggleMark = (editor: ReactEditor, format: string) => {
|
||||
const isActive = isMarkActive(editor, format);
|
||||
|
||||
if (isActive) {
|
||||
Editor.removeMark(editor, format);
|
||||
} else {
|
||||
Editor.addMark(editor, format, true);
|
||||
}
|
||||
};
|
||||
|
||||
const onSlash = () => {
|
||||
handleSlash && handleSlash();
|
||||
};
|
||||
|
||||
const onDown = (e: KeyboardEvent) => {
|
||||
e.stopPropagation();
|
||||
preventBindIfNeeded(handleDown)(e, e);
|
||||
};
|
||||
|
||||
const onUp = (e: KeyboardEvent) => {
|
||||
e.stopPropagation();
|
||||
preventBindIfNeeded(handleUp)(e, e);
|
||||
};
|
||||
const onRight = (e: KeyboardEvent) => {
|
||||
preventBindIfNeeded(handleRight)(e);
|
||||
};
|
||||
const onLeft = (e: KeyboardEvent) => {
|
||||
preventBindIfNeeded(handleLeft)(e);
|
||||
};
|
||||
|
||||
const onEnter = (e: KeyboardEvent) => {
|
||||
if (!editor.selection) {
|
||||
return;
|
||||
}
|
||||
if (!e.isDefaultPrevented()) {
|
||||
const splitContents = utils.current.getSplitContentsBySelection();
|
||||
preventBindIfNeeded(handleEnter)(e, {
|
||||
splitContents,
|
||||
isShiftKey: !!e.shiftKey,
|
||||
});
|
||||
// TODO: When re-rendering, onSelect will be triggered again, resulting in the wrong cursor position in the list after carriage return, so manual blur is required, but some cases cannot be manually blurred
|
||||
if (
|
||||
!Range.equals(
|
||||
editor.selection,
|
||||
utils.current.getStartSelection()
|
||||
) &&
|
||||
!e.shiftKey
|
||||
) {
|
||||
ReactEditor.blur(editor);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onBackSpace = (e: KeyboardEvent) => {
|
||||
if (!editor.selection) {
|
||||
return;
|
||||
}
|
||||
const isCool = utils.current.isCollapsed();
|
||||
const isCollAndStart = utils.current.isStart() && isCool;
|
||||
if (!isCool) {
|
||||
hideInlineMenu && hideInlineMenu();
|
||||
}
|
||||
preventBindIfNeeded(handleBackSpace)(e, { isCollAndStart });
|
||||
};
|
||||
|
||||
const onTab = (e: KeyboardEvent) => {
|
||||
if (!editor.selection) {
|
||||
return;
|
||||
}
|
||||
preventBindIfNeeded(handleTab)(e, { isShiftKey: !!e.shiftKey });
|
||||
};
|
||||
|
||||
const onSelect = () => {
|
||||
handleSelect && handleSelect(editor.selection);
|
||||
};
|
||||
|
||||
const onChange = (newValue: Descendant[]) => {
|
||||
if (newValue?.[0] && 'children' in newValue[0]) {
|
||||
const children = [...newValue[0].children];
|
||||
handleChange &&
|
||||
handleChange(
|
||||
children,
|
||||
getExtraPropertiesFromEditorOutmostNode(newValue[0])
|
||||
);
|
||||
if (!isEqual(children, currentValue)) {
|
||||
handleTextChange && handleTextChange(children);
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/ianstormtaylor/slate/issues/2434
|
||||
const nowFocus = ReactEditor.isFocused(editor);
|
||||
|
||||
if (!focused.current && nowFocus) {
|
||||
if (!alwaysShowPlaceholder) {
|
||||
setShowPlaceholder(true);
|
||||
}
|
||||
handleFocus?.(editor.selection);
|
||||
}
|
||||
|
||||
focused.current = nowFocus;
|
||||
};
|
||||
|
||||
const onBeforeInput = (e: InputEvent): boolean => {
|
||||
// Paste does not follow the default logic
|
||||
if (e.inputType === 'insertFromPaste') {
|
||||
e.preventDefault();
|
||||
return true;
|
||||
}
|
||||
if (isControlled) {
|
||||
// TODO: must be changed to controlled component
|
||||
return false;
|
||||
}
|
||||
if (e.data === '/') {
|
||||
onSlash && onSlash();
|
||||
return false;
|
||||
}
|
||||
// link interception
|
||||
if (
|
||||
supportLink &&
|
||||
e.dataTransfer != null &&
|
||||
e.dataTransfer.files.length === 0
|
||||
) {
|
||||
const { selection } = editor;
|
||||
const text = e.dataTransfer.getData('text');
|
||||
if (
|
||||
isUrl(text) &&
|
||||
selection.anchor.offset !== selection.focus.offset
|
||||
) {
|
||||
insertLink(text);
|
||||
e.preventDefault();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// markdown interception
|
||||
if (supportMarkdown && !!handleMarkdown(e)) {
|
||||
const start_selection = utils.current.getStartSelection();
|
||||
utils.current.setSelection(start_selection);
|
||||
e.preventDefault();
|
||||
return true;
|
||||
}
|
||||
if (handleSoftEnter(e)) {
|
||||
e.preventDefault();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const handleSoftEnter = (e: InputEvent) => {
|
||||
if (e.inputType === 'insertLineBreak') {
|
||||
// slate directly insertBreak inserts a new paragraph here, we need to insert a real linebreaker
|
||||
Editor.insertText(editor, '\n');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const handleMarkdown = (e: InputEvent) => {
|
||||
/**
|
||||
* 1. Detected that a suspected markdown logo was entered
|
||||
* 2. Further detect whether the line contains markdown syntax, whether or not a newline
|
||||
* 3. If it contains markdown syntax, find out the path that should be converted
|
||||
* 4. Convert the content of path to the corresponding format
|
||||
*/
|
||||
if (supportMarkdown && isInterceptCharacter(e.data)) {
|
||||
const strToBeTested = `${utils.current.getStringBetweenStartAndSelection()}`;
|
||||
const matchRes = matchMarkdown(strToBeTested);
|
||||
if (matchRes) {
|
||||
if (INLINE_STYLES.includes(matchRes.style)) {
|
||||
const pointsRes = utils.current.getPathOfString(matchRes);
|
||||
if (pointsRes) {
|
||||
const { startLength } = matchRes;
|
||||
const { startPoint, endPoint, style } = pointsRes;
|
||||
utils.current.turnStyleBetweenPoints(
|
||||
startPoint,
|
||||
endPoint,
|
||||
style,
|
||||
startLength
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// get rid of the syntax first
|
||||
const { style, startLength } = matchRes;
|
||||
console.log('startLength', startLength);
|
||||
const start = Editor.after(
|
||||
editor,
|
||||
utils.current.getStart(),
|
||||
{ distance: startLength }
|
||||
);
|
||||
// Conversion logic, pop out
|
||||
handleConvert &&
|
||||
handleConvert(style, {
|
||||
text: utils.current.getContentBetween(
|
||||
start,
|
||||
utils.current.getEnd()
|
||||
),
|
||||
});
|
||||
}
|
||||
e.preventDefault();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
const insertLink = (url: string) => {
|
||||
wrapLink(editor, url, previous_selection_from_on_blur_ref.current);
|
||||
};
|
||||
|
||||
const isSelectionError = (error: Error) => {
|
||||
return (
|
||||
error.message.indexOf(
|
||||
'Cannot resolve a DOM point from Slate point:'
|
||||
) !== -1
|
||||
);
|
||||
};
|
||||
|
||||
const errorHandler = (error: Error, info: { componentStack: string }) => {
|
||||
if (!isSelectionError(error)) {
|
||||
console.error(`rendering error`, error, info);
|
||||
}
|
||||
};
|
||||
|
||||
const ErrorFallback = ({ error, resetErrorBoundary }: any): null => {
|
||||
if (isSelectionError(error)) {
|
||||
resetErrorBoundary();
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const onClick: MouseEventHandler<HTMLDivElement> = e => {
|
||||
handleClick && handleClick(e);
|
||||
};
|
||||
|
||||
const onDrop = (event: DragEvent) => {
|
||||
return true;
|
||||
};
|
||||
|
||||
const onDragStart = (event: DragEvent) => {
|
||||
return false;
|
||||
};
|
||||
|
||||
const onCopy = () => {
|
||||
if (handleCopy) {
|
||||
return Boolean(handleCopy());
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const onBlur = () => {
|
||||
if (!alwaysShowPlaceholder) {
|
||||
setShowPlaceholder(false);
|
||||
}
|
||||
|
||||
if (
|
||||
editor.selection &&
|
||||
editor.selection !== previous_selection_from_on_blur_ref.current
|
||||
) {
|
||||
// / ❓ make previous_selection not null, will it affect other features?
|
||||
previous_selection_from_on_blur_ref.current = editor.selection;
|
||||
utils.current?.setPreviousSelection(editor.selection);
|
||||
}
|
||||
|
||||
Transforms.deselect(editor);
|
||||
|
||||
handleBlur?.(editor.selection);
|
||||
focused.current = false;
|
||||
};
|
||||
|
||||
const onMouseDown = (e: MouseEvent<HTMLDivElement>) => {
|
||||
handleMouseDown?.(e);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ErrorBoundary
|
||||
onReset={resetSelectionIfNeeded}
|
||||
FallbackComponent={ErrorFallback}
|
||||
onError={errorHandler}
|
||||
>
|
||||
<Slate editor={editor} value={currentValue} onChange={onChange}>
|
||||
<Editable
|
||||
readOnly={readonly}
|
||||
renderElement={renderElement}
|
||||
renderLeaf={renderLeaf}
|
||||
className={`${className} text-manage`}
|
||||
style={style}
|
||||
placeholder={
|
||||
alwaysShowPlaceholder
|
||||
? placeholder
|
||||
: showPlaceholder
|
||||
? placeholder
|
||||
: ''
|
||||
}
|
||||
onKeyDown={onKeyDown}
|
||||
onSelect={onSelect}
|
||||
onClick={onClick}
|
||||
onMouseDown={onMouseDown}
|
||||
onDOMBeforeInput={onBeforeInput}
|
||||
spellCheck={false}
|
||||
scrollSelectionIntoView={() => {}}
|
||||
onDragStart={onDragStart}
|
||||
onDrop={onDrop}
|
||||
onCopy={onCopy}
|
||||
onBlur={onBlur}
|
||||
/>
|
||||
</Slate>
|
||||
</ErrorBoundary>
|
||||
|
||||
{supportLink && linkModalVisible && (
|
||||
<LinkModal
|
||||
visible={linkModalVisible}
|
||||
onVisibleChange={onLinkModalVisibleChange}
|
||||
insertLink={insertLink}
|
||||
url={linkUrl}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
const EditorElement = (props: any) => {
|
||||
const {
|
||||
attributes,
|
||||
children,
|
||||
element,
|
||||
editor,
|
||||
onLinkModalVisibleChange,
|
||||
hideInlineMenu,
|
||||
paragraphDataSets = [],
|
||||
id,
|
||||
} = props;
|
||||
const defaultElementStyles = {
|
||||
textAlign: element['textAlign'],
|
||||
} as React.CSSProperties;
|
||||
|
||||
switch (element.type) {
|
||||
case 'link': {
|
||||
return (
|
||||
<LinkComponent
|
||||
{...props}
|
||||
editor={editor}
|
||||
onLinkModalVisibleChange={onLinkModalVisibleChange}
|
||||
hideInlineMenu={hideInlineMenu}
|
||||
/>
|
||||
);
|
||||
}
|
||||
case 'date': {
|
||||
return <InlineDate {...props} />;
|
||||
}
|
||||
case 'reflink': {
|
||||
return <InlineRefLink block={null} pageId={element.reference} />;
|
||||
}
|
||||
default: {
|
||||
for (let i = 0; i < paragraphDataSets.length; i++) {
|
||||
attributes[paragraphDataSets] = 'true';
|
||||
}
|
||||
return (
|
||||
<div
|
||||
style={defaultElementStyles}
|
||||
key={id}
|
||||
className="text-paragraph"
|
||||
{...attributes}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const EditorLeaf = ({ attributes, children, leaf }: any) => {
|
||||
const textStyles = useMemo(() => {
|
||||
const styles = {} as { color?: string; backgroundColor?: string };
|
||||
if (leaf.fontColor) {
|
||||
styles.color = leaf.fontColor as string;
|
||||
}
|
||||
if (leaf.fontBgColor) {
|
||||
styles.backgroundColor = leaf.fontBgColor as string;
|
||||
}
|
||||
return styles as React.CSSProperties;
|
||||
}, [leaf.fontBgColor, leaf.fontColor]);
|
||||
|
||||
const commentsIds = useMemo(
|
||||
() => [...getCommentsIdsOnTextNode(leaf)],
|
||||
[leaf]
|
||||
);
|
||||
|
||||
if (leaf.placeholder) {
|
||||
return <span {...attributes}>{children}</span>;
|
||||
}
|
||||
let customChildren = <String {...children.props} />;
|
||||
|
||||
if (leaf.inlinecode) {
|
||||
customChildren = (
|
||||
<span {...attributes}>
|
||||
<code
|
||||
style={{
|
||||
backgroundColor: 'rgba(135,131,120,0.15)',
|
||||
borderRadius: '3px',
|
||||
color: '#EB5757',
|
||||
fontSize: '0.875em',
|
||||
padding: '0.25em 0.375em',
|
||||
}}
|
||||
>
|
||||
{customChildren}
|
||||
</code>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
if (leaf.bold) {
|
||||
customChildren = <strong>{customChildren}</strong>;
|
||||
}
|
||||
|
||||
if (leaf.italic) {
|
||||
customChildren = <em>{customChildren}</em>;
|
||||
}
|
||||
|
||||
if (leaf.underline) {
|
||||
attributes.style = {
|
||||
...attributes.style,
|
||||
borderBottom: '1px solid rgba(204, 204, 204, 0.9)',
|
||||
};
|
||||
}
|
||||
|
||||
if (leaf.strikethrough) {
|
||||
if (attributes.style) {
|
||||
attributes.style = {
|
||||
...attributes.style,
|
||||
textDecoration: 'line-through',
|
||||
};
|
||||
} else {
|
||||
attributes.style = {
|
||||
textDecoration: 'line-through',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
customChildren = (
|
||||
<TextWithComments commentsIds={commentsIds}>
|
||||
{customChildren}
|
||||
</TextWithComments>
|
||||
);
|
||||
|
||||
return (
|
||||
<span style={textStyles} {...attributes}>
|
||||
{customChildren}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
const String = (props: {
|
||||
isLast: boolean;
|
||||
leaf: Text;
|
||||
parent: Element;
|
||||
text: Text;
|
||||
}) => {
|
||||
const { isLast, leaf, parent, text } = props;
|
||||
const editor = useSlateStatic();
|
||||
const path = ReactEditor.findPath(
|
||||
editor as ReactEditor,
|
||||
text as unknown as Node
|
||||
);
|
||||
const parentPath = Path.parent(path);
|
||||
|
||||
if (editor.isVoid(parent as any)) {
|
||||
return <ZeroWidthString length={Node.string(parent as any).length} />;
|
||||
}
|
||||
|
||||
if (
|
||||
(leaf as any).text === '' &&
|
||||
// @ts-ignore
|
||||
parent.children[parent.children.length - 1] === text &&
|
||||
!editor.isInline(parent as any) &&
|
||||
Editor.string(editor, parentPath) === ''
|
||||
) {
|
||||
return <ZeroWidthString isLineBreak />;
|
||||
}
|
||||
|
||||
if ((leaf as any).text === '') {
|
||||
return <ZeroWidthString />;
|
||||
}
|
||||
|
||||
if (isLast && (leaf as any).text.slice(-1) === '\n') {
|
||||
return <TextString isTrailing text={(leaf as any).text} />;
|
||||
}
|
||||
|
||||
return <TextString text={(leaf as any).text} />;
|
||||
};
|
||||
|
||||
const TextString = (props: { text: string; isTrailing?: boolean }) => {
|
||||
const { text, isTrailing = false } = props;
|
||||
|
||||
const textWithTrailing = useMemo(() => {
|
||||
return `${text ?? ''}${isTrailing ? '\n' : ''}`;
|
||||
}, [text, isTrailing]);
|
||||
|
||||
return <span data-slate-string>{textWithTrailing}</span>;
|
||||
};
|
||||
|
||||
const ZeroWidthString = (props: { length?: number; isLineBreak?: boolean }) => {
|
||||
const { length = 0, isLineBreak = false } = props;
|
||||
return (
|
||||
<span
|
||||
data-slate-zero-width={isLineBreak ? 'n' : 'z'}
|
||||
data-slate-length={length}
|
||||
>
|
||||
{'\uFEFF'}
|
||||
{isLineBreak ? <br /> : null}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
const preventBindIfNeeded = (cb: any) => {
|
||||
return async (e: any, ...args: any[]) => {
|
||||
const shouldPreventDefault =
|
||||
cb && (args.length ? await cb(args[0]) : await cb());
|
||||
if (shouldPreventDefault) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const createSlateText = (
|
||||
text: CustomElement[],
|
||||
textStyle: Record<string, unknown>
|
||||
): Descendant[] => {
|
||||
const slateText = [
|
||||
{
|
||||
type: 'paragraph',
|
||||
children: [...text],
|
||||
...textStyle,
|
||||
},
|
||||
];
|
||||
return slateText;
|
||||
};
|
||||
192
libs/components/common/src/lib/text/constants.ts
Normal file
@@ -0,0 +1,192 @@
|
||||
import { Protocol } from '@toeverything/datasource/db-service';
|
||||
const InnerTextStyle = {
|
||||
FONT_FAMILY: 'FONT_FAMILY',
|
||||
FONT_SIZE: 'FONT_SIZE',
|
||||
COLOR: 'FOREGROUND_COLOR',
|
||||
BACKGROUND_COLOR: 'BACKGROUND_COLOR',
|
||||
BOLD: 'BOLD',
|
||||
ITALIC: 'ITALIC',
|
||||
UNDERLINE: 'UNDERLINE',
|
||||
STRIKETHROUGH: 'STRIKETHROUGH',
|
||||
VERTICAL_ALIGN: 'VERTICAL_ALIGN',
|
||||
UNDER_LINE: 'UNDER_LINE',
|
||||
};
|
||||
export const MARKDOWN_REGS = [
|
||||
{
|
||||
type: InnerTextStyle.BOLD,
|
||||
reg: /\*{2}.+\*{2}$/,
|
||||
start: '**',
|
||||
end: '**',
|
||||
},
|
||||
{
|
||||
type: InnerTextStyle.ITALIC,
|
||||
reg: /\*.+\*$/,
|
||||
start: '*',
|
||||
end: '*',
|
||||
},
|
||||
{
|
||||
type: InnerTextStyle.STRIKETHROUGH,
|
||||
reg: /[~~]{2}.+[~~]{2}$/,
|
||||
start: '~~',
|
||||
end: '~~',
|
||||
},
|
||||
{
|
||||
type: InnerTextStyle.UNDER_LINE,
|
||||
reg: /[~~].+[~~]$/,
|
||||
start: '~',
|
||||
end: '~',
|
||||
},
|
||||
{
|
||||
type: Protocol.Block.Type.heading3,
|
||||
reg: /^#{3}$/,
|
||||
start: '###',
|
||||
},
|
||||
{
|
||||
type: Protocol.Block.Type.heading2,
|
||||
reg: /^#{2}$/,
|
||||
start: '##',
|
||||
},
|
||||
{
|
||||
type: Protocol.Block.Type.heading1,
|
||||
reg: /^#$/,
|
||||
start: '#',
|
||||
},
|
||||
{
|
||||
type: Protocol.Block.Type.numbered,
|
||||
reg: /^1\.$/,
|
||||
start: '1.',
|
||||
},
|
||||
{
|
||||
type: Protocol.Block.Type.bullet,
|
||||
reg: /^(-|\*|\+)$/,
|
||||
start: '*',
|
||||
},
|
||||
{
|
||||
type: Protocol.Block.Type.todo,
|
||||
reg: /^(\[]|【】)$/,
|
||||
start: '[]',
|
||||
},
|
||||
{
|
||||
type: Protocol.Block.Type.code,
|
||||
reg: /^`{3}$/,
|
||||
start: '```',
|
||||
},
|
||||
// {
|
||||
// type: Protocol.Block.Type.toc,
|
||||
// reg: /^\[toc\]$/,
|
||||
// start: '[t'
|
||||
// },
|
||||
{
|
||||
type: Protocol.Block.Type.quote,
|
||||
reg: /^[>》]$/,
|
||||
start: '>',
|
||||
},
|
||||
{
|
||||
type: Protocol.Block.Type.groupDivider,
|
||||
reg: /^(={3}|\*{3})$/,
|
||||
start: '===',
|
||||
},
|
||||
// divider
|
||||
{
|
||||
type: Protocol.Block.Type.divider,
|
||||
reg: /^(-{3}|\*{3})$/,
|
||||
start: '---',
|
||||
},
|
||||
// callout
|
||||
{
|
||||
type: Protocol.Block.Type.callout,
|
||||
reg: /^!-$/,
|
||||
start: '!-',
|
||||
},
|
||||
{
|
||||
type: Protocol.Block.Type.file,
|
||||
reg: /^file$/,
|
||||
start: 'file',
|
||||
},
|
||||
{
|
||||
type: Protocol.Block.Type.image,
|
||||
reg: /^img$/,
|
||||
start: 'img',
|
||||
},
|
||||
{
|
||||
type: Protocol.Block.Type.youtube,
|
||||
reg: /^youtube$/,
|
||||
start: 'youtube',
|
||||
},
|
||||
{
|
||||
type: Protocol.Block.Type.figma,
|
||||
reg: /^figma$/,
|
||||
start: 'figma',
|
||||
},
|
||||
{
|
||||
type: Protocol.Block.Type.embedLink,
|
||||
reg: /^embedLink$/,
|
||||
start: 'embedLink',
|
||||
},
|
||||
];
|
||||
|
||||
export const HOTKEYS = {
|
||||
'mod+b': 'bold',
|
||||
'mod+i': 'italic',
|
||||
'mod+u': 'underline',
|
||||
'mod+k': 'link',
|
||||
'mod+shift+s': 'strikethrough',
|
||||
'mod+e': 'inlinecode',
|
||||
} as const;
|
||||
|
||||
export const fontColorPalette = {
|
||||
default: 'rgb(0,0,0)',
|
||||
affineGray: 'rgb(155, 154, 151)',
|
||||
affineBrown: 'rgb(100, 71, 58)',
|
||||
affineOrange: 'rgb(217, 115, 13)',
|
||||
affineYellow: 'rgb(223, 171, 1)',
|
||||
affineGreen: 'rgb(77, 100, 97)',
|
||||
affineBlue: 'rgb(11, 110, 153)',
|
||||
affinePurple: 'rgb(105, 64, 165)',
|
||||
affinePink: 'rgb(173, 26, 114)',
|
||||
affineRed: 'rgb(224, 62, 62)',
|
||||
} as const;
|
||||
|
||||
export const fontBgColorPalette = {
|
||||
default: 'rgb(255,255,255)',
|
||||
affineGray: 'rgb(235, 236, 237)',
|
||||
affineBrown: 'rgb(233, 229, 227)',
|
||||
affineOrange: 'rgb(250, 235, 221)',
|
||||
affineYellow: 'rgb(251, 243, 219)',
|
||||
affineGreen: 'rgb(221, 237, 234)',
|
||||
affineBlue: 'rgb(221, 235, 241)',
|
||||
affinePurple: 'rgb(234, 228, 242)',
|
||||
affinePink: 'rgb(244, 223, 235)',
|
||||
affineRed: 'rgb(251, 228, 228)',
|
||||
} as const;
|
||||
|
||||
export const fontColorPaletteKeys = Object.keys(fontColorPalette).reduce(
|
||||
(aac, curr) => ({ [curr]: curr, ...aac }),
|
||||
{}
|
||||
) as Record<keyof typeof fontColorPalette, keyof typeof fontColorPalette>;
|
||||
|
||||
export const fontBgColorPaletteKeys = Object.keys(fontBgColorPalette).reduce(
|
||||
(aac, curr) => ({ [curr]: curr, ...aac }),
|
||||
{}
|
||||
) as Record<keyof typeof fontBgColorPalette, keyof typeof fontBgColorPalette>;
|
||||
|
||||
export type TextStyleMark =
|
||||
| typeof HOTKEYS[keyof typeof HOTKEYS]
|
||||
| 'fontColor'
|
||||
| 'fontBgColor';
|
||||
|
||||
export type TextAlignOptions =
|
||||
| 'left'
|
||||
| 'center'
|
||||
| 'right'
|
||||
| 'justify'
|
||||
| undefined;
|
||||
|
||||
export const interceptMarks = ['\u0020'];
|
||||
|
||||
export const INLINE_STYLES = [
|
||||
InnerTextStyle.BOLD,
|
||||
InnerTextStyle.STRIKETHROUGH,
|
||||
InnerTextStyle.UNDER_LINE,
|
||||
InnerTextStyle.ITALIC,
|
||||
];
|
||||
@@ -0,0 +1,55 @@
|
||||
import { useState, type ReactNode } from 'react';
|
||||
import { styled, MuiClickAwayListener } from '@toeverything/components/ui';
|
||||
|
||||
type TextWithCommentsProps = {
|
||||
commentsIds: string[];
|
||||
isActive?: boolean;
|
||||
children?: ReactNode;
|
||||
[p: string]: unknown;
|
||||
};
|
||||
|
||||
export const TextWithComments = (props: TextWithCommentsProps) => {
|
||||
const { children, ...restProps } = props;
|
||||
// const [isActive, setIsActive] = useState(false);
|
||||
// console.log(';; isActive ', isActive, props.commentsIds);
|
||||
|
||||
return <StyledText {...restProps}>{children}</StyledText>;
|
||||
|
||||
// return props.commentsIds.length > 0 ? (
|
||||
// <MuiClickAwayListener
|
||||
// onClickAway={() => {
|
||||
// setIsActive(false);
|
||||
// }}
|
||||
// >
|
||||
// <StyledText
|
||||
// isActive={isActive}
|
||||
// onClick={() => {
|
||||
// setIsActive(true);
|
||||
// }}
|
||||
// {...restProps}
|
||||
// >
|
||||
// {children}
|
||||
// </StyledText>
|
||||
// </MuiClickAwayListener>
|
||||
// ) : (
|
||||
// <StyledText {...restProps}>{children}</StyledText>
|
||||
// );
|
||||
};
|
||||
|
||||
const StyledText = styled('span', {
|
||||
shouldForwardProp: (prop: string) =>
|
||||
!['commentsIds', 'isActive'].includes(prop),
|
||||
})<TextWithCommentsProps>(({ theme, commentsIds, isActive }) => {
|
||||
return {
|
||||
width: 20,
|
||||
height: 20,
|
||||
// color: '',
|
||||
backgroundColor:
|
||||
commentsIds.length > 1
|
||||
? 'rgba(19, 217, 227, 0.4)'
|
||||
: commentsIds.length === 1
|
||||
? 'rgba(19, 217, 227, 0.2)'
|
||||
: '',
|
||||
border: isActive ? '2px solid rgba(19, 217, 227, 0.3)' : '',
|
||||
};
|
||||
});
|
||||
8
libs/components/common/src/lib/text/index.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export type { TextProps } from './EditableText';
|
||||
export { Text } from './EditableText';
|
||||
export type { Contents } from './slate-utils';
|
||||
export { SlateUtils } from './slate-utils';
|
||||
export * from './constants';
|
||||
export { getRandomString, getEditorMarkForCommentId } from './utils';
|
||||
|
||||
export { InlineRefLink } from './plugins/reflink';
|
||||
59
libs/components/common/src/lib/text/plugins/date.tsx
Normal file
@@ -0,0 +1,59 @@
|
||||
import { useMemo } from 'react';
|
||||
import { ReactEditor } from 'slate-react';
|
||||
import { useRichStyle } from './hooks';
|
||||
|
||||
export const withDate = (editor: ReactEditor) => {
|
||||
const { isInline, isVoid } = editor;
|
||||
|
||||
editor.isInline = element => {
|
||||
// @ts-ignore
|
||||
return element.type === 'date' ? true : isInline(element);
|
||||
};
|
||||
|
||||
editor.isVoid = element => {
|
||||
// @ts-ignore
|
||||
return element.type === 'date' ? true : isVoid(element);
|
||||
};
|
||||
|
||||
return editor;
|
||||
};
|
||||
|
||||
export const InlineDate = ({ attributes, children, element }: any) => {
|
||||
const onClick = () => {
|
||||
console.log('date click');
|
||||
};
|
||||
|
||||
const richStyles = useRichStyle(element);
|
||||
|
||||
const time = useMemo(() => {
|
||||
const { timeStamp } = element;
|
||||
const date = new Date(timeStamp);
|
||||
return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`;
|
||||
}, [element]);
|
||||
|
||||
return (
|
||||
<span
|
||||
{...attributes}
|
||||
contentEditable={false}
|
||||
data-cy={`${element.timeStamp}`}
|
||||
style={{
|
||||
padding: '0 2px',
|
||||
margin: '0 1px',
|
||||
verticalAlign: 'baseline',
|
||||
display: 'inline-block',
|
||||
color: 'darkgray',
|
||||
cursor: 'pointer',
|
||||
fontStyle: richStyles['italic'] ? 'italic' : 'none',
|
||||
textDecoration: `${
|
||||
richStyles['strikethrough'] ? 'line-through' : ''
|
||||
} ${richStyles['underline'] ? 'underline' : ''}`,
|
||||
fontWeight: richStyles['bold'] ? 'bolder' : 'normal',
|
||||
}}
|
||||
onClick={onClick}
|
||||
>
|
||||
<span style={{ opacity: 0.6 }}>@</span>
|
||||
{time}
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
22
libs/components/common/src/lib/text/plugins/hooks.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { useMemo } from 'react';
|
||||
|
||||
export const useRichStyle = function (element: any) {
|
||||
const richStyles = useMemo(() => {
|
||||
const richStyles: { [key: string]: boolean } = {};
|
||||
if (element.bold) {
|
||||
richStyles['bold'] = true;
|
||||
}
|
||||
if (element.italic) {
|
||||
richStyles['italic'] = true;
|
||||
}
|
||||
if (element.underline) {
|
||||
richStyles['underline'] = true;
|
||||
}
|
||||
if (element.strikethrough) {
|
||||
richStyles['strikethrough'] = true;
|
||||
}
|
||||
return richStyles;
|
||||
}, [element]);
|
||||
|
||||
return richStyles;
|
||||
};
|
||||
572
libs/components/common/src/lib/text/plugins/link.tsx
Normal file
@@ -0,0 +1,572 @@
|
||||
import React, {
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
useCallback,
|
||||
KeyboardEvent,
|
||||
MouseEvent,
|
||||
memo,
|
||||
} from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import isUrl from 'is-url';
|
||||
import style9 from 'style9';
|
||||
import {
|
||||
Editor,
|
||||
Transforms,
|
||||
Element as SlateElement,
|
||||
Descendant,
|
||||
Range as SlateRange,
|
||||
Node,
|
||||
} from 'slate';
|
||||
import { ReactEditor } from 'slate-react';
|
||||
import OpenInNewIcon from '@mui/icons-material/OpenInNew';
|
||||
import EditIcon from '@mui/icons-material/Edit';
|
||||
import LinkOffIcon from '@mui/icons-material/LinkOff';
|
||||
import AttachmentIcon from '@mui/icons-material/Attachment';
|
||||
import {
|
||||
MuiTooltip as Tooltip,
|
||||
styled,
|
||||
muiTooltipClasses,
|
||||
type MuiTooltipProps,
|
||||
} from '@toeverything/components/ui';
|
||||
import {
|
||||
getRelativeUrlForInternalPageUrl,
|
||||
isInternalPageUrl,
|
||||
} from '@toeverything/utils';
|
||||
|
||||
import { getRandomString } from '../utils';
|
||||
import { colors } from '../../colors';
|
||||
|
||||
export type LinkElement = {
|
||||
type: 'link';
|
||||
url: string;
|
||||
children: Descendant[];
|
||||
id: string;
|
||||
};
|
||||
|
||||
export const withLinks = (editor: ReactEditor) => {
|
||||
const { isInline } = editor;
|
||||
|
||||
editor.isInline = element => {
|
||||
// @ts-ignore
|
||||
return element.type === 'link' ? true : isInline(element);
|
||||
};
|
||||
|
||||
return editor;
|
||||
};
|
||||
|
||||
const unwrapLink = (editor: Editor) => {
|
||||
Transforms.unwrapNodes(editor, {
|
||||
match: n => {
|
||||
return (
|
||||
!Editor.isEditor(n) &&
|
||||
SlateElement.isElement(n) &&
|
||||
// @ts-expect-error
|
||||
n.type === 'link'
|
||||
);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const wrapLink = (
|
||||
editor: ReactEditor,
|
||||
url: string,
|
||||
preSelection?: SlateRange
|
||||
) => {
|
||||
if (!ReactEditor.isFocused(editor) && preSelection) {
|
||||
Transforms.select(editor, preSelection);
|
||||
}
|
||||
if (isLinkActive(editor)) {
|
||||
unwrapLink(editor);
|
||||
}
|
||||
const realUrl = normalizeUrl(url);
|
||||
const { selection } = editor;
|
||||
const isCollapsed = selection && SlateRange.isCollapsed(selection);
|
||||
const link: LinkElement = {
|
||||
type: 'link',
|
||||
url: realUrl,
|
||||
children: isCollapsed ? [{ text: realUrl }] : [],
|
||||
id: getRandomString('link'),
|
||||
};
|
||||
|
||||
if (isCollapsed) {
|
||||
Transforms.insertNodes(editor, link as Node);
|
||||
} else {
|
||||
Transforms.wrapNodes(editor, link, { split: true });
|
||||
Transforms.collapse(editor, { edge: 'end' });
|
||||
}
|
||||
requestAnimationFrame(() => {
|
||||
ReactEditor.focus(editor);
|
||||
});
|
||||
};
|
||||
|
||||
const normalizeUrl = (url: string) => {
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
return /^https?/.test(url) ? url : `${location.protocol}//${url}`;
|
||||
};
|
||||
|
||||
const isLinkActive = (editor: ReactEditor) => {
|
||||
const [link] = Editor.nodes(editor, {
|
||||
match: n =>
|
||||
!Editor.isEditor(n) &&
|
||||
SlateElement.isElement(n) &&
|
||||
// @ts-expect-error
|
||||
n.type === 'link',
|
||||
});
|
||||
return !!link;
|
||||
};
|
||||
|
||||
const LinkStyledTooltip = styled(({ className, ...props }: MuiTooltipProps) => (
|
||||
<Tooltip {...props} classes={{ popper: className }} />
|
||||
))(() => ({
|
||||
[`& .${muiTooltipClasses.tooltip}`]: {
|
||||
backgroundColor: '#fff',
|
||||
color: '#4C6275',
|
||||
boxShadow: '0px 1px 10px rgba(152, 172, 189, 0.6)',
|
||||
fontSize: '14px',
|
||||
},
|
||||
[`& .MuiTooltip-tooltipPlacementBottom`]: {
|
||||
// prevent tooltip disappear as soon as mouse moves
|
||||
// margin: 0
|
||||
},
|
||||
}));
|
||||
|
||||
export const LinkComponent = ({
|
||||
attributes,
|
||||
children,
|
||||
element,
|
||||
editor,
|
||||
onLinkModalVisibleChange,
|
||||
hideInlineMenu,
|
||||
}: any) => {
|
||||
const navigate = useNavigate();
|
||||
const [tooltip_visible, set_tooltip_visible] = useState(false);
|
||||
|
||||
const handle_tooltip_visible_change = useCallback((visible: boolean) => {
|
||||
set_tooltip_visible(visible);
|
||||
}, []);
|
||||
|
||||
const handle_link_modal_visible_change = useCallback(
|
||||
(visible: boolean, url?: string) => {
|
||||
onLinkModalVisibleChange(visible, undefined, url);
|
||||
},
|
||||
[onLinkModalVisibleChange]
|
||||
);
|
||||
|
||||
const handle_click_link_text = useCallback(
|
||||
(event: React.MouseEvent<HTMLAnchorElement>) => {
|
||||
// prevent route to href url
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
const { url } = element;
|
||||
|
||||
if (isInternalPageUrl(url)) {
|
||||
navigate(getRelativeUrlForInternalPageUrl(url));
|
||||
} else {
|
||||
const new_window = window.open(url, '_blank');
|
||||
if (new_window) {
|
||||
new_window.focus();
|
||||
}
|
||||
}
|
||||
},
|
||||
[element, navigate]
|
||||
);
|
||||
|
||||
return (
|
||||
<LinkStyledTooltip
|
||||
open={tooltip_visible}
|
||||
onOpen={() => handle_tooltip_visible_change(true)}
|
||||
onClose={() => handle_tooltip_visible_change(false)}
|
||||
placement="bottom-start"
|
||||
title={
|
||||
<LinkTooltips
|
||||
url={element.url}
|
||||
id={element.id}
|
||||
editor={editor}
|
||||
onLinkModalVisibleChange={handle_link_modal_visible_change}
|
||||
onVisibleChange={handle_tooltip_visible_change}
|
||||
hideInlineMenu={hideInlineMenu}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<a
|
||||
{...attributes}
|
||||
className={styles({
|
||||
linkWrapper: true,
|
||||
linkWrapperHover: tooltip_visible,
|
||||
})}
|
||||
href={element.url}
|
||||
>
|
||||
{/* <InlineChromiumBugfix /> */}
|
||||
<span onClick={handle_click_link_text}>{children}</span>
|
||||
{/* <InlineChromiumBugfix /> */}
|
||||
</a>
|
||||
</LinkStyledTooltip>
|
||||
);
|
||||
};
|
||||
|
||||
type LinkTooltipsProps = {
|
||||
/** Uniquely identifies */
|
||||
id: string;
|
||||
/** The url to which the hyperlink points */
|
||||
url: string;
|
||||
/** slate instance */
|
||||
editor: Editor;
|
||||
/** Used to display linkModal */
|
||||
onLinkModalVisibleChange: (visible: boolean, url?: string) => void;
|
||||
/** used to hide inlinemenu */
|
||||
hideInlineMenu: () => void;
|
||||
/** visibleChange of the entire tooltips */
|
||||
onVisibleChange: (visible: boolean) => void;
|
||||
};
|
||||
|
||||
const LinkTooltips = (props: LinkTooltipsProps) => {
|
||||
const {
|
||||
id,
|
||||
url,
|
||||
editor,
|
||||
onLinkModalVisibleChange,
|
||||
hideInlineMenu,
|
||||
onVisibleChange,
|
||||
} = props;
|
||||
|
||||
const select_link = useCallback(() => {
|
||||
const { children } = editor;
|
||||
// @ts-ignore
|
||||
const realChildren = children[0]?.children;
|
||||
const path = [0];
|
||||
let offset = 0;
|
||||
if (realChildren && Array.isArray(realChildren)) {
|
||||
for (let i = 0; i < realChildren.length; i++) {
|
||||
const child = realChildren[i];
|
||||
if (child.type === 'link' && child.id === id) {
|
||||
path.push(i);
|
||||
const linkChildren = child.children;
|
||||
path.push(linkChildren.length - 1);
|
||||
offset = linkChildren[linkChildren.length - 1].text.length;
|
||||
}
|
||||
}
|
||||
if (path.length === 3 && offset) {
|
||||
const anchor = Editor.before(
|
||||
editor,
|
||||
{
|
||||
path,
|
||||
offset: 0,
|
||||
},
|
||||
{
|
||||
unit: 'offset',
|
||||
}
|
||||
);
|
||||
const focus = Editor.after(
|
||||
editor,
|
||||
{
|
||||
path,
|
||||
offset,
|
||||
},
|
||||
{
|
||||
unit: 'offset',
|
||||
}
|
||||
);
|
||||
Transforms.select(editor, { anchor, focus });
|
||||
ReactEditor.focus(editor as ReactEditor);
|
||||
onVisibleChange(false);
|
||||
requestAnimationFrame(() => {
|
||||
hideInlineMenu?.();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}, [editor, hideInlineMenu, id, onVisibleChange]);
|
||||
|
||||
const handle_edit_link_url = useCallback(() => {
|
||||
const selectSuccess = select_link();
|
||||
|
||||
if (selectSuccess) {
|
||||
onVisibleChange(false);
|
||||
requestAnimationFrame(() => {
|
||||
onLinkModalVisibleChange(true, url);
|
||||
});
|
||||
}
|
||||
}, [onLinkModalVisibleChange, onVisibleChange, select_link, url]);
|
||||
|
||||
const handle_unlink = useCallback(() => {
|
||||
const selectSuccess = select_link();
|
||||
if (selectSuccess) {
|
||||
requestAnimationFrame(() => {
|
||||
unwrapLink(editor);
|
||||
ReactEditor.deselect(editor);
|
||||
});
|
||||
}
|
||||
}, [editor, select_link]);
|
||||
|
||||
return (
|
||||
<div className={styles('linkTooltipContainer')}>
|
||||
<span className={styles('linkModalIcon')}>
|
||||
<OpenInNewIcon style={{ fontSize: 15 }} />
|
||||
</span>
|
||||
<span className={styles('linkModalUrl')}>{url}</span>
|
||||
<div className={styles('linkModalStick')} />
|
||||
<div
|
||||
onClick={handle_edit_link_url}
|
||||
className={styles('linkModalBtn')}
|
||||
>
|
||||
<EditIcon style={{ fontSize: 16 }} />
|
||||
</div>
|
||||
<div onClick={handle_unlink} className={styles('linkModalBtn')}>
|
||||
<LinkOffIcon style={{ fontSize: 16 }} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const InlineChromiumBugfix = () => (
|
||||
<span contentEditable={false} style={{ fontSize: 0 }}>
|
||||
${String.fromCodePoint(160)}
|
||||
</span>
|
||||
);
|
||||
|
||||
function useBody() {
|
||||
const [div] = useState(document.createElement('div'));
|
||||
|
||||
useEffect(() => {
|
||||
document.body.appendChild(div);
|
||||
return () => {
|
||||
div.remove();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return div;
|
||||
}
|
||||
|
||||
const GAP_BETWEEN_CONTENT_AND_MODAL = 4;
|
||||
|
||||
type LinkModalProps = {
|
||||
visible: boolean;
|
||||
url?: string;
|
||||
/** Hide display callback */
|
||||
onVisibleChange: (visible: boolean, isInsertLink?: boolean) => void;
|
||||
/** Insert link to slate */
|
||||
insertLink: (url: string) => void;
|
||||
};
|
||||
|
||||
/**
|
||||
* modal for adding and editing link url, input element as content.
|
||||
*/
|
||||
export const LinkModal = memo((props: LinkModalProps) => {
|
||||
const body = useBody();
|
||||
const { visible, onVisibleChange, url = '', insertLink } = props;
|
||||
|
||||
const inputEl = useRef<HTMLInputElement>(null);
|
||||
|
||||
const rect = useMemo(() => {
|
||||
return window.getSelection().getRangeAt(0).getClientRects()[0];
|
||||
}, []);
|
||||
|
||||
const rects = useMemo(() => {
|
||||
return window.getSelection().getRangeAt(0).getClientRects();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (visible) {
|
||||
requestAnimationFrame(() => {
|
||||
if (url) {
|
||||
inputEl.current.value = url;
|
||||
}
|
||||
inputEl.current?.focus();
|
||||
});
|
||||
}
|
||||
}, [visible, url]);
|
||||
|
||||
const add_link_url_to_text = () => {
|
||||
const newUrl = inputEl.current.value;
|
||||
if (newUrl && newUrl !== url && isUrl(normalizeUrl(newUrl))) {
|
||||
insertLink(newUrl);
|
||||
onVisibleChange(false, true);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const handle_key_down = (e: KeyboardEvent<HTMLInputElement>) => {
|
||||
// console.log(';; link input keydown ', e.key, e);
|
||||
if (e.key === 'Enter') {
|
||||
add_link_url_to_text();
|
||||
}
|
||||
// TODO: FIX unable to catch ESCAPE key down
|
||||
if (e.key === 'Escape') {
|
||||
onVisibleChange(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handle_mouse_down = () => {
|
||||
onVisibleChange(false);
|
||||
};
|
||||
|
||||
const { top, left, height } = rect;
|
||||
|
||||
return createPortal(
|
||||
visible && (
|
||||
<>
|
||||
<LinkBehavior onMousedown={handle_mouse_down} rects={rects} />
|
||||
<div
|
||||
className={styles('linkModalContainer')}
|
||||
style={{
|
||||
top: top + height + GAP_BETWEEN_CONTENT_AND_MODAL,
|
||||
left,
|
||||
}}
|
||||
>
|
||||
<div className={styles('linkModalContainerIcon')}>
|
||||
<AttachmentIcon
|
||||
style={{ color: colors.Gray04, fontSize: 16 }}
|
||||
/>
|
||||
</div>
|
||||
<input
|
||||
className={styles('linkModalContainerInput')}
|
||||
onKeyDown={handle_key_down}
|
||||
placeholder="Paste link url, like https://affine.pro"
|
||||
autoComplete="off"
|
||||
ref={inputEl}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
),
|
||||
body
|
||||
);
|
||||
});
|
||||
|
||||
const LinkBehavior = (props: {
|
||||
onMousedown: (e: MouseEvent) => void;
|
||||
rects: DOMRectList;
|
||||
}) => {
|
||||
const { onMousedown, rects } = props;
|
||||
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
|
||||
const prevent = useCallback((e: any) => {
|
||||
// console.log(e);
|
||||
// e.preventDefault();
|
||||
// e.stopPropagation();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
document.addEventListener('mousemove', prevent, { capture: true });
|
||||
return () => {
|
||||
document.removeEventListener('mousemove', prevent, {
|
||||
capture: true,
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
const renderFakeSelection = useCallback(() => {
|
||||
const rectsArr = Array.from(rects);
|
||||
if (rectsArr.length) {
|
||||
return rectsArr.map((rect, i) => {
|
||||
const { top, left, width, height } = rect;
|
||||
return (
|
||||
<div
|
||||
key={`fake-selection-${i}`}
|
||||
className={styles('fakeSelection')}
|
||||
style={{ top, left, width, height }}
|
||||
/>
|
||||
);
|
||||
});
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}, [rects]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
ref={ref}
|
||||
className={styles('linkMask')}
|
||||
onMouseDown={onMousedown}
|
||||
/>
|
||||
{renderFakeSelection()}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = style9.create({
|
||||
linkModalContainer: {
|
||||
position: 'fixed',
|
||||
width: '354px',
|
||||
height: '40px',
|
||||
padding: '12px',
|
||||
display: 'flex',
|
||||
borderRadius: '4px',
|
||||
boxShadow: '0px 1px 10px rgba(152, 172, 189, 0.6)',
|
||||
backgroundColor: '#fff',
|
||||
alignItems: 'center',
|
||||
zIndex: '1',
|
||||
},
|
||||
linkModalContainerIcon: {
|
||||
width: '16px',
|
||||
margin: '0 16px 0 4px',
|
||||
},
|
||||
linkModalContainerInput: {
|
||||
flex: '1',
|
||||
outline: 'none',
|
||||
border: 'none',
|
||||
padding: '0',
|
||||
fontFamily: 'Helvetica,Arial,"Microsoft Yahei",SimHei,sans-serif',
|
||||
'::-webkit-input-placeholder': {
|
||||
color: '#98acbd',
|
||||
},
|
||||
},
|
||||
linkMask: {
|
||||
position: 'fixed',
|
||||
top: '0',
|
||||
left: '0',
|
||||
width: '100vw',
|
||||
height: '100vh',
|
||||
zIndex: '1',
|
||||
},
|
||||
fakeSelection: {
|
||||
pointerEvents: 'none',
|
||||
position: 'fixed',
|
||||
// backgroundColor: 'rgba(80, 46, 196, 0.1)',
|
||||
zIndex: '1',
|
||||
},
|
||||
linkWrapper: {
|
||||
cursor: 'pointer',
|
||||
textDecorationLine: 'none',
|
||||
},
|
||||
linkWrapperHover: {},
|
||||
linkTooltipContainer: {
|
||||
// color: 'var(--ligo-Gray04)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
},
|
||||
linkModalIcon: {},
|
||||
linkModalStick: {
|
||||
width: '1px',
|
||||
height: '20px',
|
||||
margin: '0 10px 0 16px',
|
||||
},
|
||||
linkModalUrl: {
|
||||
marginLeft: '8px',
|
||||
maxWidth: '261px',
|
||||
textOverflow: 'ellipsis',
|
||||
overflowX: 'hidden',
|
||||
overflowY: 'hidden',
|
||||
whiteSpace: 'nowrap',
|
||||
},
|
||||
linkModalBtn: {
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
width: '28px',
|
||||
height: '28px',
|
||||
transitionProperty: 'background-color',
|
||||
transitionDuration: '0.3s',
|
||||
borderRadius: '4px',
|
||||
':hover': {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
},
|
||||
});
|
||||
41
libs/components/common/src/lib/text/plugins/reflink.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { Descendant } from 'slate';
|
||||
|
||||
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
|
||||
import { BlockSearchItem } from '@toeverything/datasource/jwt';
|
||||
import { styled } from '@toeverything/components/ui';
|
||||
|
||||
import { BlockPreview } from '../../block-preview';
|
||||
|
||||
export type RefLinkElement = {
|
||||
type: 'reflink';
|
||||
reference: string;
|
||||
children: Descendant[];
|
||||
};
|
||||
|
||||
const BlockPreviewContainer = styled(BlockPreview)({
|
||||
width: '100%',
|
||||
margin: '0px!important',
|
||||
paddingLeft: '0px!important',
|
||||
paddingRight: '0px!important',
|
||||
});
|
||||
|
||||
type InlineRefLinkProps = {
|
||||
block?: BlockSearchItem;
|
||||
pageId: string;
|
||||
};
|
||||
|
||||
export const InlineRefLink = ({ block, pageId }: InlineRefLinkProps) => {
|
||||
const { workspace_id } = useParams();
|
||||
const navigate = useNavigate();
|
||||
|
||||
if (block) {
|
||||
return (
|
||||
<BlockPreviewContainer
|
||||
block={block}
|
||||
onClick={() => navigate(`/${workspace_id}/${pageId}`)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return <span>Loading...</span>;
|
||||
};
|
||||
1089
libs/components/common/src/lib/text/slate-utils.ts
Normal file
76
libs/components/common/src/lib/text/utils.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import type { CustomElement } from '..';
|
||||
import { interceptMarks, MARKDOWN_REGS } from './constants';
|
||||
|
||||
export const isInterceptCharacter = (str: string) => {
|
||||
return interceptMarks.indexOf(str) > -1;
|
||||
};
|
||||
|
||||
export enum MARKDOWN_STYLE_MAP {
|
||||
BOLD = 'bold',
|
||||
ITALIC = 'italic',
|
||||
STRIKETHROUGH = 'strikethrough',
|
||||
UNDER_LINE = 'underline',
|
||||
}
|
||||
|
||||
export type MatchRes = {
|
||||
start: string;
|
||||
end: string;
|
||||
style: string;
|
||||
startLength: number;
|
||||
};
|
||||
|
||||
export const matchMarkdown = (str: string) => {
|
||||
const regs = MARKDOWN_REGS;
|
||||
for (let i = 0; i < regs.length; i++) {
|
||||
const matchResult = str.match(regs[i].reg);
|
||||
if (matchResult && matchResult[0]) {
|
||||
return {
|
||||
start: regs[i].start,
|
||||
end: regs[i].end,
|
||||
style: regs[i].type,
|
||||
startLength: regs[i].start.length,
|
||||
} as MatchRes;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const getRandomString = function (prefix: string) {
|
||||
const x = 2147483648;
|
||||
return `${prefix}.${Math.floor(Math.random() * x).toString(36)}${Math.abs(
|
||||
Math.floor(Math.random() * x) ^ +new Date()
|
||||
).toString(36)}`;
|
||||
};
|
||||
|
||||
const COMMENT_PREFIX_FOR_MARK = 'comment_id_';
|
||||
|
||||
export const getEditorMarkForCommentId = (commentId: string) => {
|
||||
return `${COMMENT_PREFIX_FOR_MARK}${commentId}`;
|
||||
};
|
||||
|
||||
export const getCommentsIdsOnTextNode = (textNode: Record<string, unknown>) => {
|
||||
const ids = Object.keys(textNode)
|
||||
.filter(
|
||||
maybeCommentMarkProp =>
|
||||
maybeCommentMarkProp.startsWith(COMMENT_PREFIX_FOR_MARK) &&
|
||||
textNode[maybeCommentMarkProp] !== 'resolved'
|
||||
)
|
||||
.map(commentMark => commentMark.replace(COMMENT_PREFIX_FOR_MARK, ''));
|
||||
return new Set(ids);
|
||||
};
|
||||
|
||||
const _usefulEditorLevelProps = ['textAlign'];
|
||||
/** get extra props from editor top level node; it's usually user custom props */
|
||||
export const getExtraPropertiesFromEditorOutmostNode = (
|
||||
editorNode: CustomElement
|
||||
) => {
|
||||
const textStyle = {} as Record<string, string>;
|
||||
_usefulEditorLevelProps.forEach(p => {
|
||||
if (p in editorNode) {
|
||||
// @ts-ignore
|
||||
textStyle[p] = editorNode[p] as string;
|
||||
}
|
||||
});
|
||||
|
||||
return textStyle;
|
||||
};
|
||||
70
libs/components/common/src/lib/toolbar/index.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
import { MuiTooltip as Tooltip } from '@toeverything/components/ui';
|
||||
|
||||
import style9 from 'style9';
|
||||
|
||||
const styles = style9.create({
|
||||
toolbarContainer: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
lineHeight: 1,
|
||||
zIndex: 1,
|
||||
padding: '0 8px',
|
||||
backgroundColor: '#ffffff',
|
||||
border: '1px solid #e1e1e1',
|
||||
boxShadow: '0px 14px 24px rgba(51, 51, 51, 0.08)',
|
||||
borderRadius: '4px',
|
||||
color: '#333',
|
||||
fontSize: '16px',
|
||||
cursor: 'pointer',
|
||||
},
|
||||
toolbarItem: {
|
||||
padding: '6px',
|
||||
margin: '6px 2px',
|
||||
':hover': {
|
||||
backgroundColor: '#f4f4f4',
|
||||
borderRadius: '4px',
|
||||
},
|
||||
},
|
||||
toolbarItemActive: {
|
||||
color: '#502ec4',
|
||||
},
|
||||
line: {
|
||||
margin: '0 8px',
|
||||
width: '1px',
|
||||
backgroundColor: '#e1e1e1',
|
||||
},
|
||||
});
|
||||
|
||||
interface Props {
|
||||
data: any[];
|
||||
}
|
||||
|
||||
export default function Toolbar({ data }: Props) {
|
||||
return (
|
||||
<div className={styles('toolbarContainer')}>
|
||||
{data.map((item, index) => {
|
||||
const { icon: Icon } = item;
|
||||
return item.child ? (
|
||||
<span key={item.key} className={styles('toolbarItem')}>
|
||||
{item.child}
|
||||
</span>
|
||||
) : item.line ? (
|
||||
<div className={styles('line')} key={index}></div>
|
||||
) : (
|
||||
<Tooltip title={item.text} placement="top" key={item.key}>
|
||||
<span
|
||||
key={item.key}
|
||||
className={styles({
|
||||
toolbarItem: true,
|
||||
toolbarItemActive: !!item?.active,
|
||||
})}
|
||||
onClick={() => item?.action(item.key)}
|
||||
>
|
||||
<Icon />
|
||||
</span>
|
||||
</Tooltip>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||