Merge to master (#435)

* Fix/venus spanish (#423)

fix: update venus spanish language

Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>

* fix: can not convert url text to link after paste

* fix: double link icon size error

* feat(code): enhance markdown parse code

* fix(code): add robust

* fix: remove special menu

* chore: clean code

* fix: ime with command menu

* fix(code): langs[lang] is not a function

* fix: can't add image and delete more action button (#430)

* feat: add zh_Hant for venus (#431)

* fix: lang select in  code block is insanity

* GitHub Doc Updates (#421)

* Update types-of-contributions.md

* Update README.md

Tidy up links section

* fix: inline menu position (#433)

Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
Co-authored-by: QiShaoXuan <qishaoxuan777@gmail.com>
Co-authored-by: tzhangchi <terry.zhangchi@outlook.com>
Co-authored-by: lawvs <18554747+lawvs@users.noreply.github.com>
Co-authored-by: DiamondThree <diamond.shx@gmail.com>
Co-authored-by: CJSS <CJSS@users.noreply.github.com>
Co-authored-by: Qi <474021214@qq.com>
This commit is contained in:
zuomeng wang
2022-09-19 15:57:48 +08:00
committed by GitHub
parent 8984bedec9
commit c010e05023
24 changed files with 614 additions and 528 deletions
@@ -38,13 +38,13 @@ export const createEditor = (
views: {
[Protocol.Block.Type.page]: new PageBlock(),
[Protocol.Block.Type.reference]: new RefLinkBlock(),
[Protocol.Block.Type.code]: new CodeBlock(),
[Protocol.Block.Type.text]: new TextBlock(),
[Protocol.Block.Type.heading1]: new Heading1Block(),
[Protocol.Block.Type.heading2]: new Heading2Block(),
[Protocol.Block.Type.heading3]: new Heading3Block(),
[Protocol.Block.Type.quote]: new QuoteBlock(),
[Protocol.Block.Type.todo]: new TodoBlock(),
[Protocol.Block.Type.code]: new CodeBlock(),
// [Protocol.Block.Type.toc]: new TocBlock(),
[Protocol.Block.Type.file]: new FileBlock(),
[Protocol.Block.Type.image]: new ImageBlock(),
+2 -10
View File
@@ -39,14 +39,6 @@ type MenuItemsProps = {
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'];
const usedItems = items.filter(item => {
return !JSONUnsupportedBlockTypes.includes(item?.content?.id);
});
return (
<div className={clsx(styles('root_container'), props.className)}>
<div
@@ -55,8 +47,8 @@ export const CommonList = (props: MenuItemsProps) => {
commonListContainer,
])}
>
{usedItems?.length ? (
usedItems.map((item, idx) => {
{items?.length ? (
items.map((item, idx) => {
if (item.renderCustom) {
return item.renderCustom(item);
} else if (item.block) {
@@ -3,6 +3,7 @@ import React, { useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { Descendant } from 'slate';
import { RenderElementProps } from 'slate-react';
import { styled } from '@toeverything/components/ui';
export type DoubleLinkElement = {
type: 'link';
@@ -13,6 +14,10 @@ export type DoubleLinkElement = {
id: string;
};
const StyledLink = styled('a')({
cursor: 'pointer',
});
export const DoubleLinkComponent = (props: RenderElementProps) => {
const { attributes, children, element } = props;
const doubleLinkElement = element as DoubleLinkElement;
@@ -32,15 +37,20 @@ export const DoubleLinkComponent = (props: RenderElementProps) => {
return (
<span onClick={handleClickLinkText}>
<a {...attributes} style={{ cursor: 'pointer' }}>
<StyledLink {...attributes}>
<PagesIcon
style={{ verticalAlign: 'middle', height: '20px' }}
style={{
verticalAlign: 'middle',
height: '1em',
fontSize: 'inherit',
marginBottom: '.2em',
}}
/>
<span>
{children}
{displayValue}
</span>
</a>
</StyledLink>
</span>
);
};
+2 -1
View File
@@ -38,7 +38,8 @@
"react-window": "^1.8.7",
"slate": "^0.81.1",
"slate-react": "^0.81.0",
"style9": "^0.14.0"
"style9": "^0.14.0",
"html-escaper": "^3.0.3"
},
"devDependencies": {
"@types/codemirror": "^5.60.5",
@@ -116,7 +116,7 @@ const CodeBlock = styled('div')(({ theme }) => ({
flexWrap: 'wrap',
justifyContent: 'space-between',
opacity: 0,
transition: 'opacity 1.5s',
transition: 'opacity .15s',
},
'.copy-block': {
padding: '0px 10px',
@@ -139,10 +139,21 @@ const CodeBlock = styled('div')(({ theme }) => ({
outline: 'none !important',
},
}));
const StyledOperationalPanel = styled('div')<{ show: boolean }>(({ show }) => {
return {
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'space-between',
opacity: show ? 1 : 0,
transition: 'opacity .15s',
};
});
export const CodeView = ({ block, editor }: CreateCodeView) => {
const initValue: string = block.getProperty('text')?.value?.[0]?.text;
const langType: string = block.getProperty('lang');
const [extensions, setExtensions] = useState<Extension[]>();
const [showOperationPanel, setShowOperationPanel] = useState(false);
const isSelecting = useRef(false);
const codeMirror = useRef<ReactCodeMirrorRef>();
const focusCode = () => {
if (codeMirror.current) {
@@ -160,7 +171,7 @@ export const CodeView = ({ block, editor }: CreateCodeView) => {
};
const handleLangChange = (lang: string) => {
block.setProperty('lang', lang);
setExtensions([langs[lang]()]);
langs[lang] && setExtensions([langs[lang]()]);
};
useEffect(() => {
handleLangChange(langType ? langType : DEFAULT_LANG);
@@ -181,8 +192,15 @@ export const CodeView = ({ block, editor }: CreateCodeView) => {
onKeyDown={e => {
e.stopPropagation();
}}
onMouseEnter={() => {
isSelecting.current = false;
setShowOperationPanel(true);
}}
onMouseLeave={() => {
!isSelecting.current && setShowOperationPanel(false);
}}
>
<div className="operation">
<StyledOperationalPanel show={showOperationPanel}>
<div className="select">
<Select
width={128}
@@ -192,6 +210,9 @@ export const CodeView = ({ block, editor }: CreateCodeView) => {
onChange={(selectedValue: string) => {
handleLangChange(selectedValue);
}}
onListboxOpenChange={() => {
isSelecting.current = true;
}}
>
{Object.keys(langs).map(item => {
return (
@@ -208,7 +229,7 @@ export const CodeView = ({ block, editor }: CreateCodeView) => {
Copy
</div>
</div>
</div>
</StyledOperationalPanel>
<CodeMirror
ref={codeMirror}
@@ -5,10 +5,10 @@ import {
BlockEditor,
HTML2BlockResult,
} from '@toeverything/framework/virgo';
import { unescape } from 'html-escaper';
import {
Block2HtmlProps,
commonBlock2HtmlContent,
commonHTML2block,
} from '../../utils/commonBlockClip';
import { CodeView } from './CodeView';
@@ -34,12 +34,30 @@ export class CodeBlock extends BaseView {
element: Element;
editor: BlockEditor;
}): Promise<HTML2BlockResult> {
return commonHTML2block({
element,
editor,
type: this.type,
tagName: 'CODE',
});
// debugger;
if (element.tagName === 'CODE') {
return [
{
type: this.type,
properties: {
text: {
value: [
{
text: unescape(
(element as HTMLElement).innerText
),
},
],
},
lang:
element.classList[0] &&
element.classList[0].substr(9),
},
children: [],
},
];
}
return null;
}
override async block2html(props: Block2HtmlProps) {
@@ -168,7 +168,9 @@ export const ImageView = ({ block, editor }: ImageView) => {
<BlockPendantProvider editor={editor} block={block}>
<ImageBlock>
<div style={{ position: 'relative' }} ref={resizeBox}>
{!isSelect ? <ImageShade onClick={handleClick} /> : null}
{!isSelect && imgUrl ? (
<ImageShade onClick={handleClick} />
) : null}
{imgUrl ? (
<div
onMouseDown={e => {
@@ -1,17 +1,17 @@
import {
BaseView,
CreateView,
AsyncBlock,
HTML2BlockResult,
BlockEditor,
} from '@toeverything/framework/virgo';
import { Protocol } from '@toeverything/datasource/db-service';
import { TextView } from './TextView';
import {
AsyncBlock,
BaseView,
BlockEditor,
CreateView,
HTML2BlockResult,
} from '@toeverything/framework/virgo';
import {
Block2HtmlProps,
commonBlock2HtmlContent,
commonHTML2block,
} from '../../utils/commonBlockClip';
import { TextView } from './TextView';
export class TextBlock extends BaseView {
type = Protocol.Block.Type.text;
@@ -41,12 +41,12 @@ export class TextBlock extends BaseView {
tagName: [
'DIV',
'P',
'PRE',
// 'PRE',
'B',
'A',
'EM',
'U',
'CODE',
// 'CODE',
'S',
'DEL',
],
@@ -1,5 +1,3 @@
import { useState } from 'react';
import { CustomText, TextProps } from '@toeverything/components/common';
import {
BlockPendantProvider,
@@ -11,9 +9,11 @@ import {
import { styled } from '@toeverything/components/ui';
import { Protocol } from '@toeverything/datasource/db-service';
import { CreateView } from '@toeverything/framework/virgo';
import { useState } from 'react';
import { BlockContainer } from '../../components/BlockContainer';
import { TextManage } from '../../components/text-manage';
import { dedentBlock, tabBlock } from '../../utils/indent';
interface CreateTextView extends CreateView {
// TODO: need to optimize
containerClassName?: string;
@@ -247,6 +247,9 @@ export const TextView = ({
await block.setProperty('text', {
value: options?.['text'] as CustomText[],
});
setTimeout(async () => {
await editor.selectionManager.activeNodeByNodeId(block.id);
}, 100);
block.firstCreateFlag = true;
};
const onTab: TextProps['handleTab'] = async ({ isShiftKey }) => {
@@ -1,10 +1,15 @@
import { Protocol } from '@toeverything/datasource/db-service';
import { AsyncBlock } from '../block';
import { Editor } from '../editor';
import { SelectBlock, SelectInfo } from '../selection';
import { AsyncBlock } from '../block';
import { ClipBlockInfo, OFFICE_CLIPBOARD_MIMETYPE } from './types';
import { Clip } from './clip';
import { commonHTML2Block, commonHTML2Text } from './utils';
import { ClipBlockInfo, OFFICE_CLIPBOARD_MIMETYPE } from './types';
import {
commonHTML2Block,
commonHTML2Text,
getIsTextLink,
linkText2Block,
} from './utils';
export class ClipboardUtils {
private _editor: Editor;
constructor(editor: Editor) {
@@ -156,12 +161,37 @@ export class ClipboardUtils {
return this.convertHtml2Blocks(htmlEl);
}
async convertHtml2Blocks(element: Element): Promise<ClipBlockInfo[]> {
const editableViews = this._editor.getEditableViews();
// const editableViews = this._editor.getEditableViews();
// 如果block能够捕捉htmlElement则返回block的html2block
const CONVERT_SORT_LIST = [
Protocol.Block.Type.page,
Protocol.Block.Type.reference,
Protocol.Block.Type.code,
Protocol.Block.Type.text,
Protocol.Block.Type.heading1,
Protocol.Block.Type.heading2,
Protocol.Block.Type.heading3,
Protocol.Block.Type.quote,
Protocol.Block.Type.todo,
Protocol.Block.Type.file,
Protocol.Block.Type.image,
Protocol.Block.Type.divider,
Protocol.Block.Type.callout,
Protocol.Block.Type.youtube,
Protocol.Block.Type.figma,
Protocol.Block.Type.group,
Protocol.Block.Type.embedLink,
Protocol.Block.Type.numbered,
Protocol.Block.Type.bullet,
Protocol.Block.Type.grid,
Protocol.Block.Type.gridItem,
Protocol.Block.Type.groupDivider,
];
const [clipBlockInfos] = (
await Promise.all(
editableViews.map(editableView => {
return editableView?.html2block?.({
CONVERT_SORT_LIST.map(type => {
return this._editor.getView(type)?.html2block?.({
editor: this._editor,
element: element,
});
@@ -197,6 +227,11 @@ export class ClipboardUtils {
textToBlock(clipData = ''): ClipBlockInfo[] {
return clipData.split('\n').map((str: string) => {
const isLink = getIsTextLink(str);
if (isLink) {
return linkText2Block(clipData);
}
return {
type: 'text',
properties: {
@@ -5,6 +5,34 @@ import { ClipBlockInfo } from './types';
const getIsLink = (htmlElement: HTMLElement) => {
return ['A', 'IMG'].includes(htmlElement.tagName);
};
export const getIsTextLink = (str: string) => {
const regex = new RegExp(
/https?:\/\/(www\.)?[-a-zA-Z\d@:%._+~#=]{1,256}\.[a-zA-Z\d()]{1,6}\b([-a-zA-Z\d()@:%_+.~#?&//=]*)/gi
);
return regex.test(str);
};
export const linkText2Block = (url: string) => {
return {
type: 'text',
properties: {
text: {
value: [
{
children: [
{
text: url,
},
],
type: 'link',
url: url,
id: getRandomString('link'),
},
],
},
},
children: [],
} as unknown as ClipBlockInfo;
};
const getTextStyle = (htmlElement: HTMLElement) => {
const tagName = htmlElement.tagName;
const textStyle: { [key: string]: any } = {};
@@ -1,9 +1,8 @@
import { StrictMode } from 'react';
import { createRoot, type Root } from 'react-dom/client';
import { BasePlugin } from '../../base-plugin';
import { CommandMenu } from './Menu';
import { PluginRenderRoot } from '../../utils';
import { CommandMenu } from './Menu';
const PLUGIN_NAME = 'command-menu';
@@ -1,28 +1,24 @@
import React, {
useEffect,
useState,
useMemo,
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import style9 from 'style9';
import { BlockFlavorKeys } from '@toeverything/datasource/db-service';
import { Virgo, PluginHooks, HookType } from '@toeverything/framework/virgo';
import {
CommonList,
CommonListItem,
commonListContainer,
CommonListItem,
} from '@toeverything/components/common';
import { BlockFlavorKeys } from '@toeverything/datasource/db-service';
import { HookType, PluginHooks, Virgo } from '@toeverything/framework/virgo';
import { domToRect } from '@toeverything/utils';
import { MenuCategories } from './Categories';
import { menuItemsMap, CommandMenuCategories } from './config';
import { styled } from '@toeverything/components/ui';
import { QueryResult } from '../../search';
import {
MuiClickAwayListener as ClickAwayListener,
styled,
} from '@toeverything/components/ui';
import { MenuCategories } from './Categories';
import { CommandMenuCategories, menuItemsMap } from './config';
const RootContainer = styled('div')(({ theme }) => {
return {
@@ -134,59 +130,75 @@ export const CommandMenuContainer = ({
const handleClickUp = useCallback(
(event: React.KeyboardEvent<HTMLDivElement>) => {
if (isShow && types && event.code === 'ArrowUp') {
event.preventDefault();
if (!currentItem && types.length) {
setCurrentItem(types[types.length - 1]);
}
if (currentItem) {
const idx = types.indexOf(currentItem);
if (idx > 0) {
setNeedCheckIntoView(true);
setCurrentItem(types[idx - 1]);
}
event.preventDefault();
if (!currentItem && types.length) {
setCurrentItem(types[types.length - 1]);
}
if (currentItem) {
const idx = types.indexOf(currentItem);
if (idx > 0) {
setNeedCheckIntoView(true);
setCurrentItem(types[idx - 1]);
}
}
},
[isShow, types, currentItem]
[types, currentItem]
);
const handleClickDown = useCallback(
(event: React.KeyboardEvent<HTMLDivElement>) => {
if (isShow && types && event.code === 'ArrowDown') {
event.preventDefault();
if (!currentItem && types.length) {
setCurrentItem(types[0]);
}
if (currentItem) {
const idx = types.indexOf(currentItem);
if (idx < types.length - 1) {
setNeedCheckIntoView(true);
setCurrentItem(types[idx + 1]);
}
event.preventDefault();
if (!currentItem && types.length) {
setCurrentItem(types[0]);
}
if (currentItem) {
const idx = types.indexOf(currentItem);
if (idx < types.length - 1) {
setNeedCheckIntoView(true);
setCurrentItem(types[idx + 1]);
}
}
},
[isShow, types, currentItem]
[types, currentItem]
);
const handleClickEnter = useCallback(
async (event: React.KeyboardEvent<HTMLDivElement>) => {
if (isShow && event.code === 'Enter' && currentItem) {
event.preventDefault();
onSelected && onSelected(currentItem);
}
event.preventDefault();
onSelected && onSelected(currentItem);
},
[isShow, currentItem, onSelected]
[currentItem, onSelected]
);
const handleKeyDown = useCallback(
(event: React.KeyboardEvent<HTMLDivElement>) => {
handleClickUp(event);
handleClickDown(event);
handleClickEnter(event);
if (!isShow) {
return;
}
if (event.nativeEvent.isComposing) {
return;
}
if (types && event.code === 'ArrowUp') {
handleClickUp(event);
return;
}
if (types && event.code === 'ArrowDown') {
handleClickDown(event);
return;
}
if (event.code === 'Enter' && currentItem) {
handleClickEnter(event);
return;
}
},
[handleClickUp, handleClickDown, handleClickEnter]
[
isShow,
types,
currentItem,
handleClickUp,
handleClickDown,
handleClickEnter,
]
);
useEffect(() => {
@@ -212,7 +212,7 @@ export const CommandMenu = ({ editor, hooks, style }: CommandMenuProps) => {
const handleSelected = async (type: BlockFlavorKeys | string) => {
const text = await editor.commands.textCommands.getBlockText(blockId);
const block = await editor.getBlockById(blockId);
let textValue = block.getProperty('text').value;
const textValue = block.getProperty('text').value;
editor.blockHelper.removeSearchSlash(blockId, true);
if (type.startsWith('Virgo')) {
const handler =
@@ -261,23 +261,21 @@ export const CommandMenu = ({ editor, hooks, style }: CommandMenuProps) => {
>
{show ? (
<MuiClickAwayListener onClickAway={handleClickAway}>
<div>
<CommandMenuContainer
editor={editor}
hooks={hooks}
style={{
...commandMenuPosition,
...style,
}}
isShow={show}
blockId={blockId}
onSelected={handleSelected}
onclose={handleClose}
searchBlocks={searchBlocks}
types={types}
categories={categories}
/>
</div>
<CommandMenuContainer
editor={editor}
hooks={hooks}
style={{
...commandMenuPosition,
...style,
}}
isShow={show}
blockId={blockId}
onSelected={handleSelected}
onclose={handleClose}
searchBlocks={searchBlocks}
types={types}
categories={categories}
/>
</MuiClickAwayListener>
) : (
<></>
@@ -1,25 +1,24 @@
import {
HeadingOneIcon,
HeadingTwoIcon,
HeadingThreeIcon,
ToDoIcon,
NumberIcon,
BulletIcon,
CodeIcon,
TextIcon,
PagesIcon,
ImageIcon,
FileIcon,
QuoteIcon,
CalloutIcon,
CodeIcon,
DividerIcon,
FigmaIcon,
YoutubeIcon,
EmbedIcon,
FigmaIcon,
FileIcon,
HeadingOneIcon,
HeadingThreeIcon,
HeadingTwoIcon,
ImageIcon,
NumberIcon,
QuoteIcon,
TextIcon,
ToDoIcon,
YoutubeIcon,
} from '@toeverything/components/icons';
import { SvgIconProps } from '@toeverything/components/ui';
import { Virgo } from '@toeverything/framework/virgo';
import { BlockFlavorKeys, Protocol } from '@toeverything/datasource/db-service';
import { Virgo } from '@toeverything/framework/virgo';
import { without } from '@toeverything/utils';
export enum CommandMenuCategories {
@@ -68,11 +67,12 @@ export const menuItemsMap: {
type: Protocol.Block.Type.text,
icon: TextIcon,
},
{
text: 'Page',
type: 'page',
icon: PagesIcon,
},
// the Page block should not be inserted
// {
// text: 'Page',
// type: Protocol.Block.Type.page,
// icon: PagesIcon,
// },
{
text: 'Heading 1',
type: Protocol.Block.Type.heading1,
@@ -91,7 +91,7 @@ export const menuItemsMap: {
],
[CommandMenuCategories.lists]: [
{
text: 'To do',
text: 'Todo',
type: Protocol.Block.Type.todo,
icon: ToDoIcon,
},
@@ -1,12 +1,7 @@
import { useState, useEffect } from 'react';
import { MuiGrow as Grow, styled } from '@toeverything/components/ui';
import { Protocol } from '@toeverything/datasource/db-service';
import {
MuiClickAwayListener as ClickAwayListener,
MuiGrow as Grow,
styled,
} from '@toeverything/components/ui';
import { Virgo, SelectionInfo } from '@toeverything/framework/virgo';
import { SelectionInfo, Virgo } from '@toeverything/framework/virgo';
import { useEffect, useState } from 'react';
import { InlineMenuToolbar } from './Toolbar';
export type InlineMenuContainerProps = {
@@ -47,11 +42,18 @@ export const InlineMenuContainer = ({ editor }: InlineMenuContainerProps) => {
// This is relative to window
const rect = browserSelection.getRangeAt(0).getBoundingClientRect();
const { top, left } = editor.container.getBoundingClientRect();
const { top, left, right } =
editor.container.getBoundingClientRect();
let menuLeft = rect.left - left;
if (right - rect.right < 500) {
// If the inline-menu is further away from the right than the button itself, a scroll bar will appear
menuLeft -= 500;
}
setSelectionInfo(info);
setShowMenu(true);
setContainerStyle({
left: rect.left - left,
left: menuLeft,
top: rect.top - top - 64,
});
});
@@ -89,6 +91,6 @@ const ToolbarContainer = styled('div')(({ theme }) => ({
alignItems: 'center',
padding: '0 12px',
borderRadius: '10px',
boxShadow: theme.affine.shadows.shadow1,
boxShadow: theme.affine.shadows.shadow3,
backgroundColor: '#fff',
}));
@@ -22,7 +22,6 @@ import {
HeadingTwoIcon,
ImageIcon,
LinkIcon,
MoreIcon,
NumberIcon,
PagesIcon,
QuoteIcon,
@@ -827,13 +826,13 @@ export const getInlineMenuData = ({
nameKey: inlineMenuNamesKeys.backlinks,
onClick: common_handler_for_inline_menu,
},
{
type: INLINE_MENU_UI_TYPES.icon,
icon: MoreIcon,
name: inlineMenuNames.moreActions,
nameKey: inlineMenuNamesKeys.moreActions,
onClick: common_handler_for_inline_menu,
},
// {
// type: INLINE_MENU_UI_TYPES.icon,
// icon: MoreIcon,
// name: inlineMenuNames.moreActions,
// nameKey: inlineMenuNamesKeys.moreActions,
// onClick: common_handler_for_inline_menu,
// },
];
return inlineMenuData.filter(item => Boolean(item));
+14 -6
View File
@@ -41,7 +41,14 @@ export const Select = forwardRef(function CustomSelect<TValue>(
ref: ForwardedRef<HTMLUListElement>
) {
const [isOpen, setIsOpen] = useState(false);
const { width = '100%', style, listboxStyle, placeholder } = props;
const {
width = '100%',
style,
listboxStyle,
placeholder,
onListboxOpenChange,
onChange,
} = props;
const components: SelectUnstyledProps<TValue>['components'] = {
// Root: generateStyledRoot({ width, ...style }),
Root: forwardRef((rootProps, rootRef) => {
@@ -80,14 +87,15 @@ export const Select = forwardRef(function CustomSelect<TValue>(
return (
<SelectUnstyled
listboxOpen={isOpen}
onListboxOpenChange={() => {
setIsOpen(true);
}}
{...props}
listboxOpen={isOpen}
onListboxOpenChange={open => {
setIsOpen(open);
onListboxOpenChange?.(open);
}}
onChange={v => {
setIsOpen(false);
props.onChange && props.onChange(v);
onChange?.(v);
}}
ref={ref}
components={components}
+2
View File
@@ -237,6 +237,8 @@ export const Theme = {
'0px 1px 10px -6px rgba(24, 39, 75, 0.08), 0px 3px 16px -6px rgba(24, 39, 75, 0.04)',
shadow2:
'0px 6px 16px -8px rgba(0,0,0,0.08), 0px 9px 14px 0px rgba(0,0,0,0.05), 0px 12px 24px 16px rgba(0,0,0,0.03)',
shadow3:
'0px 1px 10px -6px rgb(24 39 75 / 50%), 0px 3px 16px -6px rgb(24 39 75 / 30%)',
},
border: ['none'],
spacing: {