Merge pull request #432 from toeverything/fix/bugs

Fix/bugs
This commit is contained in:
Qi
2022-09-19 11:31:18 +08:00
committed by GitHub
5 changed files with 90 additions and 13 deletions
@@ -3,6 +3,7 @@ import React, { useCallback } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { Descendant } from 'slate'; import { Descendant } from 'slate';
import { RenderElementProps } from 'slate-react'; import { RenderElementProps } from 'slate-react';
import { styled } from '@toeverything/components/ui';
export type DoubleLinkElement = { export type DoubleLinkElement = {
type: 'link'; type: 'link';
@@ -13,6 +14,10 @@ export type DoubleLinkElement = {
id: string; id: string;
}; };
const StyledLink = styled('a')({
cursor: 'pointer',
});
export const DoubleLinkComponent = (props: RenderElementProps) => { export const DoubleLinkComponent = (props: RenderElementProps) => {
const { attributes, children, element } = props; const { attributes, children, element } = props;
const doubleLinkElement = element as DoubleLinkElement; const doubleLinkElement = element as DoubleLinkElement;
@@ -32,15 +37,20 @@ export const DoubleLinkComponent = (props: RenderElementProps) => {
return ( return (
<span onClick={handleClickLinkText}> <span onClick={handleClickLinkText}>
<a {...attributes} style={{ cursor: 'pointer' }}> <StyledLink {...attributes}>
<PagesIcon <PagesIcon
style={{ verticalAlign: 'middle', height: '20px' }} style={{
verticalAlign: 'middle',
height: '1em',
fontSize: 'inherit',
marginBottom: '.2em',
}}
/> />
<span> <span>
{children} {children}
{displayValue} {displayValue}
</span> </span>
</a> </StyledLink>
</span> </span>
); );
}; };
@@ -116,7 +116,7 @@ const CodeBlock = styled('div')(({ theme }) => ({
flexWrap: 'wrap', flexWrap: 'wrap',
justifyContent: 'space-between', justifyContent: 'space-between',
opacity: 0, opacity: 0,
transition: 'opacity 1.5s', transition: 'opacity .15s',
}, },
'.copy-block': { '.copy-block': {
padding: '0px 10px', padding: '0px 10px',
@@ -139,10 +139,21 @@ const CodeBlock = styled('div')(({ theme }) => ({
outline: 'none !important', 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) => { export const CodeView = ({ block, editor }: CreateCodeView) => {
const initValue: string = block.getProperty('text')?.value?.[0]?.text; const initValue: string = block.getProperty('text')?.value?.[0]?.text;
const langType: string = block.getProperty('lang'); const langType: string = block.getProperty('lang');
const [extensions, setExtensions] = useState<Extension[]>(); const [extensions, setExtensions] = useState<Extension[]>();
const [showOperationPanel, setShowOperationPanel] = useState(false);
const isSelecting = useRef(false);
const codeMirror = useRef<ReactCodeMirrorRef>(); const codeMirror = useRef<ReactCodeMirrorRef>();
const focusCode = () => { const focusCode = () => {
if (codeMirror.current) { if (codeMirror.current) {
@@ -181,8 +192,15 @@ export const CodeView = ({ block, editor }: CreateCodeView) => {
onKeyDown={e => { onKeyDown={e => {
e.stopPropagation(); e.stopPropagation();
}} }}
onMouseEnter={() => {
isSelecting.current = false;
setShowOperationPanel(true);
}}
onMouseLeave={() => {
!isSelecting.current && setShowOperationPanel(false);
}}
> >
<div className="operation"> <StyledOperationalPanel show={showOperationPanel}>
<div className="select"> <div className="select">
<Select <Select
width={128} width={128}
@@ -192,6 +210,9 @@ export const CodeView = ({ block, editor }: CreateCodeView) => {
onChange={(selectedValue: string) => { onChange={(selectedValue: string) => {
handleLangChange(selectedValue); handleLangChange(selectedValue);
}} }}
onListboxOpenChange={() => {
isSelecting.current = true;
}}
> >
{Object.keys(langs).map(item => { {Object.keys(langs).map(item => {
return ( return (
@@ -208,7 +229,7 @@ export const CodeView = ({ block, editor }: CreateCodeView) => {
Copy Copy
</div> </div>
</div> </div>
</div> </StyledOperationalPanel>
<CodeMirror <CodeMirror
ref={codeMirror} ref={codeMirror}
@@ -4,7 +4,12 @@ import { Editor } from '../editor';
import { SelectBlock, SelectInfo } from '../selection'; import { SelectBlock, SelectInfo } from '../selection';
import { Clip } from './clip'; import { Clip } from './clip';
import { ClipBlockInfo, OFFICE_CLIPBOARD_MIMETYPE } from './types'; import { ClipBlockInfo, OFFICE_CLIPBOARD_MIMETYPE } from './types';
import { commonHTML2Block, commonHTML2Text } from './utils'; import {
commonHTML2Block,
commonHTML2Text,
getIsTextLink,
linkText2Block,
} from './utils';
export class ClipboardUtils { export class ClipboardUtils {
private _editor: Editor; private _editor: Editor;
constructor(editor: Editor) { constructor(editor: Editor) {
@@ -222,6 +227,11 @@ export class ClipboardUtils {
textToBlock(clipData = ''): ClipBlockInfo[] { textToBlock(clipData = ''): ClipBlockInfo[] {
return clipData.split('\n').map((str: string) => { return clipData.split('\n').map((str: string) => {
const isLink = getIsTextLink(str);
if (isLink) {
return linkText2Block(clipData);
}
return { return {
type: 'text', type: 'text',
properties: { properties: {
@@ -5,6 +5,34 @@ import { ClipBlockInfo } from './types';
const getIsLink = (htmlElement: HTMLElement) => { const getIsLink = (htmlElement: HTMLElement) => {
return ['A', 'IMG'].includes(htmlElement.tagName); 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 getTextStyle = (htmlElement: HTMLElement) => {
const tagName = htmlElement.tagName; const tagName = htmlElement.tagName;
const textStyle: { [key: string]: any } = {}; const textStyle: { [key: string]: any } = {};
+14 -6
View File
@@ -41,7 +41,14 @@ export const Select = forwardRef(function CustomSelect<TValue>(
ref: ForwardedRef<HTMLUListElement> ref: ForwardedRef<HTMLUListElement>
) { ) {
const [isOpen, setIsOpen] = useState(false); 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'] = { const components: SelectUnstyledProps<TValue>['components'] = {
// Root: generateStyledRoot({ width, ...style }), // Root: generateStyledRoot({ width, ...style }),
Root: forwardRef((rootProps, rootRef) => { Root: forwardRef((rootProps, rootRef) => {
@@ -80,14 +87,15 @@ export const Select = forwardRef(function CustomSelect<TValue>(
return ( return (
<SelectUnstyled <SelectUnstyled
listboxOpen={isOpen}
onListboxOpenChange={() => {
setIsOpen(true);
}}
{...props} {...props}
listboxOpen={isOpen}
onListboxOpenChange={open => {
setIsOpen(open);
onListboxOpenChange?.(open);
}}
onChange={v => { onChange={v => {
setIsOpen(false); setIsOpen(false);
props.onChange && props.onChange(v); onChange?.(v);
}} }}
ref={ref} ref={ref}
components={components} components={components}