Merge pull request #17 from fantasticit/feat/format

This commit is contained in:
fantasticit 2022-03-28 21:55:35 +08:00 committed by GitHub
commit 19b8f3eb97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
308 changed files with 2090 additions and 2075 deletions

110
.stylelintrc.js Normal file
View File

@ -0,0 +1,110 @@
module.exports = {
processors: [],
plugins: ['stylelint-order'],
extends: ['stylelint-config-standard', 'stylelint-config-css-modules'],
rules: {
'selector-class-pattern': [
// 命名规范 -
'(.)+$',
{
message: 'Expected class selector to be kebab-case',
},
],
'string-quotes': 'single', // 单引号
'at-rule-empty-line-before': null,
'at-rule-no-unknown': null,
'at-rule-name-case': 'lower', // 指定@规则名的大小写
'length-zero-no-unit': true, // 禁止零长度的单位(可自动修复)
'shorthand-property-no-redundant-values': true, // 简写属性
'number-leading-zero': 'never', // 小数不带0
'declaration-block-no-duplicate-properties': true, // 禁止声明快重复属性
'no-descending-specificity': true, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器。
'selector-max-id': 3, // 限制一个选择器中 ID 选择器的数量
'max-nesting-depth': 5,
'indentation': [
2,
{
// 指定缩进 warning 提醒
severity: 'warning',
},
],
'order/properties-order': [
// 规则顺序
'position',
'top',
'right',
'bottom',
'left',
'z-index',
'display',
'float',
'width',
'height',
'max-width',
'max-height',
'min-width',
'min-height',
'padding',
'padding-top',
'padding-right',
'padding-bottom',
'padding-left',
'margin',
'margin-top',
'margin-right',
'margin-bottom',
'margin-left',
'margin-collapse',
'margin-top-collapse',
'margin-right-collapse',
'margin-bottom-collapse',
'margin-left-collapse',
'overflow',
'overflow-x',
'overflow-y',
'clip',
'clear',
'font',
'font-family',
'font-size',
'font-smoothing',
'osx-font-smoothing',
'font-style',
'font-weight',
'line-height',
'letter-spacing',
'word-spacing',
'color',
'text-align',
'text-decoration',
'text-indent',
'text-overflow',
'text-rendering',
'text-size-adjust',
'text-shadow',
'text-transform',
'word-break',
'word-wrap',
'white-space',
'vertical-align',
'list-style',
'list-style-type',
'list-style-position',
'list-style-image',
'pointer-events',
'cursor',
'background',
'background-color',
'border',
'border-radius',
'content',
'outline',
'outline-offset',
'opacity',
'filter',
'visibility',
'size',
'transform',
],
},
};

View File

@ -7,5 +7,5 @@ git pull
pnpm install
pnpm run build
pm2 restart @think/server
pm2 restart @think/client
pm2 reload @think/server
pm2 reload @think/client

View File

@ -20,7 +20,9 @@
"pm2": "pnpm run pm2:server && pnpm run pm2:client",
"pm2:server": "pnpm run --dir packages/server pm2",
"pm2:client": "pnpm run --dir packages/client pm2",
"format": "prettier --write --parser typescript \"packages/**/*.ts?(x)\""
"format": "concurrently \"pnpm:format:*\"",
"format:ts": "prettier --write --parser typescript \"packages/**/*.ts?(x)\"",
"format:css": "stylelint --fix --formatter verbose --allow-empty-input \"packages/**/*.{css,scss,sass}\""
},
"dependencies": {
"concurrently": "^7.0.0",
@ -32,18 +34,14 @@
"node": ">=16.5.0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"eslint": "^8.11.0",
"eslint-config-next": "12.0.10",
"eslint-config-prettier": "^8.3.0",
"eslint-import-resolver-typescript": "^2.5.0",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jest": "^26.1.1",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.29.3",
"eslint-plugin-react-hooks": "^4.3.0",
"prettier": "^2.3.2",
"stylelint": "^14.6.1",
"stylelint-config-css-modules": "^4.1.0",
"stylelint-config-prettier": "^9.0.3",
"stylelint-config-standard": "^25.0.0",
"stylelint-config-standard-scss": "^3.0.0",
"stylelint-order": "^5.0.0",
"stylelint-prettier": "^2.0.0",
"typescript": "^4.5.5"
}
}

View File

@ -1,13 +1,13 @@
import React, { useEffect, useRef } from 'react';
import { Banner as SemiBanner } from '@douyinfe/semi-ui';
import { BannerProps } from '@douyinfe/semi-ui/banner';
import { useToggle } from 'hooks/useToggle';
import { useToggle } from 'hooks/use-toggle';
interface IProps extends BannerProps {
duration?: number;
}
export const Banner: React.FC<IProps> = ({ type, description, duration }) => {
export const Banner: React.FC<IProps> = ({ type, description, duration = 0 }) => {
const timer = useRef<ReturnType<typeof setTimeout>>();
const [visible, toggleVisible] = useToggle(true);
@ -26,5 +26,5 @@ export const Banner: React.FC<IProps> = ({ type, description, duration }) => {
if (!visible) return null;
return <SemiBanner type="success" description="以为您恢复上一次离线时编辑数据。 " />;
return <SemiBanner type={type} description={description} />;
};

View File

@ -1,5 +1,5 @@
import React from 'react';
import { Empty, Spin, Typography } from '@douyinfe/semi-ui';
import { Spin, Typography } from '@douyinfe/semi-ui';
type RenderProps = React.ReactNode | (() => React.ReactNode);

View File

@ -1,7 +1,7 @@
import React from 'react';
import { Button } from '@douyinfe/semi-ui';
import { useToggle } from 'hooks/useToggle';
import { useQuery } from 'hooks/useQuery';
import { useToggle } from 'hooks/use-toggle';
import { useQuery } from 'hooks/use-query';
import { DocumentCreator as DocumenCreatorForm } from 'components/document/create';
interface IProps {

View File

@ -5,7 +5,7 @@ import { DocumentLinkCopyer } from 'components/document/link';
import { DocumentDeletor } from 'components/document/delete';
import { DocumentCreator } from 'components/document/create';
import { DocumentStar } from 'components/document/star';
import { useToggle } from 'hooks/useToggle';
import { useToggle } from 'hooks/use-toggle';
interface IProps {
wikiId: string;

View File

@ -2,23 +2,22 @@
width: 100%;
> a {
margin: 8px 0;
display: flex;
flex-direction: column;
width: 100%;
max-height: 260px;
padding: 12px 16px 16px;
border-radius: 5px;
border: 1px solid var(--semi-color-border);
margin: 8px 0;
cursor: pointer;
border: 1px solid var(--semi-color-border);
border-radius: 5px;
flex-direction: column;
> header {
display: flex;
justify-content: space-between;
align-items: center;
color: var(--semi-color-primary);
margin-bottom: 12px;
color: var(--semi-color-primary);
.rightWrap {
opacity: 0;

View File

@ -18,7 +18,7 @@ import {
import { IconUserAdd, IconDelete } from '@douyinfe/semi-icons';
import { useUser } from 'data/user';
import { EventEmitter } from 'helpers/event-emitter';
import { useToggle } from 'hooks/useToggle';
import { useToggle } from 'hooks/use-toggle';
import { useCollaborationDocument } from 'data/document';
import { DataRender } from 'components/data-render';
import { DocumentLinkCopyer } from 'components/document/link';

View File

@ -1,6 +1,6 @@
.wrap {
display: flex;
padding: 9px 0px 9px 0;
padding: 9px 0;
+ .wrap {
margin-top: 16px;
@ -17,20 +17,9 @@
}
> footer {
// height: 0;
// transition: all ease-in-out 0.3s;
span {
cursor: pointer;
}
}
}
// &:hover {
// .rightWrap {
// > footer {
// height: 40px;
// }
// }
// }
}

View File

@ -10,8 +10,8 @@
}
.editorOuterWrap {
padding-top: 24px;
display: flex;
padding-top: 24px;
.rightWrap {
flex: 1;

View File

@ -1,8 +1,8 @@
import React, { useRef, useState } from 'react';
import { useEditor, EditorContent } from '@tiptap/react';
import { Avatar, Button, Space, Typography, Banner, Pagination } from '@douyinfe/semi-ui';
import { useToggle } from 'hooks/useToggle';
import { DEFAULT_EXTENSION, Document, History, CommentMenuBar } from 'components/tiptap';
import { useToggle } from 'hooks/use-toggle';
import { DEFAULT_EXTENSION, Document, History, CommentMenuBar } from 'tiptap';
import { DataRender } from 'components/data-render';
import { useUser } from 'data/user';
import { useComments } from 'data/comment';

View File

@ -3,7 +3,8 @@ import cls from 'classnames';
import { useEditor, EditorContent } from '@tiptap/react';
import { BackTop } from '@douyinfe/semi-ui';
import { ILoginUser, IAuthority } from '@think/domains';
import { useToggle } from 'hooks/useToggle';
import { useToggle } from 'hooks/use-toggle';
import { useNetwork } from 'hooks/use-network';
import {
MenuBar,
DEFAULT_EXTENSION,
@ -15,7 +16,7 @@ import {
ProviderStatus,
getIndexdbProvider,
destoryIndexdbProvider,
} from 'components/tiptap';
} from 'tiptap';
import { DataRender } from 'components/data-render';
import { joinUser } from 'components/document/collaboration';
import { Banner } from 'components/banner';
@ -34,6 +35,7 @@ interface IProps {
export const Editor: React.FC<IProps> = ({ user, documentId, authority, className, style }) => {
if (!user) return null;
const [status, setStatus] = useState<ProviderStatus>('connecting');
const { online } = useNetwork();
const provider = useMemo(() => {
return getProvider({
targetId: documentId,
@ -94,11 +96,10 @@ export const Editor: React.FC<IProps> = ({ user, documentId, authority, classNam
normalContent={() => {
return (
<div className={styles.editorWrap}>
{status === 'disconnected' && (
{(!online || status === 'disconnected') && (
<Banner
type="warning"
description="
"
description="我们已与您断开连接,您可以继续编辑文档。一旦重新连接,我们会自动重新提交数据。"
/>
)}
<header className={className}>

View File

@ -1,14 +1,14 @@
.wrap {
height: 100%;
overflow: hidden;
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
> header {
position: relative;
z-index: 110;
background-color: var(--semi-color-nav-bg);
height: 60px;
background-color: var(--semi-color-nav-bg);
user-select: none;
> div {
@ -18,27 +18,27 @@
> main {
height: calc(100% - 60px);
flex: 1;
overflow: hidden;
background-color: var(--semi-color-nav-bg);
flex: 1;
}
}
.editorWrap {
height: 100%;
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
> header {
position: relative;
z-index: 110;
display: flex;
height: 50px;
padding: 0 24px;
display: flex;
align-items: center;
overflow: hidden;
background-color: var(--semi-color-nav-bg);
align-items: center;
border-bottom: 1px solid var(--semi-color-border);
user-select: none;

View File

@ -4,7 +4,7 @@ import { Nav, Skeleton, Typography, Space, Button, Tooltip, Spin, Popover } from
import { IconChevronLeft, IconArticle } from '@douyinfe/semi-icons';
import { useUser } from 'data/user';
import { useDocumentDetail } from 'data/document';
import { useWindowSize } from 'hooks/useWindowSize';
import { useWindowSize } from 'hooks/use-window-size';
import { Seo } from 'components/seo';
import { Theme } from 'components/theme';
import { DataRender } from 'components/data-render';
@ -12,7 +12,7 @@ import { DocumentShare } from 'components/document/share';
import { DocumentStar } from 'components/document/star';
import { DocumentCollaboration } from 'components/document/collaboration';
import { DocumentStyle } from 'components/document/style';
import { useDocumentStyle } from 'hooks/useDocumentStyle';
import { useDocumentStyle } from 'hooks/use-document-style';
import { EventEmitter } from 'helpers/event-emitter';
import { Editor } from './editor';
import styles from './index.module.scss';

View File

@ -2,7 +2,7 @@ import React, { useMemo, useEffect, useRef } from 'react';
import { useEditor, EditorContent } from '@tiptap/react';
import { Layout } from '@douyinfe/semi-ui';
import { IDocument, ILoginUser } from '@think/domains';
import { useToggle } from 'hooks/useToggle';
import { useToggle } from 'hooks/use-toggle';
import {
DEFAULT_EXTENSION,
DocumentWithTitle,
@ -10,7 +10,7 @@ import {
getCollaborationCursorExtension,
getProvider,
destoryProvider,
} from 'components/tiptap';
} from 'tiptap';
import { DataRender } from 'components/data-render';
import { ImageViewer } from 'components/image-viewer';
import { joinUser } from 'components/document/collaboration';
@ -28,7 +28,6 @@ interface IProps {
export const Editor: React.FC<IProps> = ({ user, documentId, document }) => {
if (!user) return null;
const $ref = useRef();
const provider = useMemo(() => {
return getProvider({
targetId: documentId,
@ -70,18 +69,16 @@ export const Editor: React.FC<IProps> = ({ user, documentId, document }) => {
error={null}
normalContent={() => {
return (
<>
<Content className={styles.editorWrap}>
<div id="js-reader-container">
<ImageViewer containerSelector="#js-reader-container" />
<EditorContent editor={editor} />
</div>
<CreateUser
document={document}
container={() => window.document.querySelector('#js-reader-container .ProseMirror .title')}
/>
</Content>
</>
<Content className={styles.editorWrap}>
<div id="js-reader-container">
<ImageViewer containerSelector="#js-reader-container" />
<EditorContent editor={editor} />
</div>
<CreateUser
document={document}
container={() => window.document.querySelector('#js-reader-container .ProseMirror .title')}
/>
</Content>
);
}}
/>

View File

@ -1,6 +1,6 @@
.wrap {
margin-top: -16px;
height: 100%;
margin-top: -16px;
.headerWrap {
position: sticky;

View File

@ -10,11 +10,11 @@ import { DocumentStar } from 'components/document/star';
import { DocumentCollaboration } from 'components/document/collaboration';
import { DocumentStyle } from 'components/document/style';
import { CommentEditor } from 'components/document/comments';
import { useDocumentStyle } from 'hooks/useDocumentStyle';
import { useWindowSize } from 'hooks/useWindowSize';
import { useDocumentStyle } from 'hooks/use-document-style';
import { useWindowSize } from 'hooks/use-window-size';
import { useUser } from 'data/user';
import { useDocumentDetail } from 'data/document';
import { DocumentSkeleton } from 'components/tiptap';
import { DocumentSkeleton } from 'tiptap';
import { Editor } from './editor';
import { CreateUser } from './user';
import styles from './index.module.scss';

View File

@ -1,8 +1,7 @@
import React from 'react';
import { useEditor, EditorContent } from '@tiptap/react';
import { Layout } from '@douyinfe/semi-ui';
import { IDocument } from '@think/domains';
import { DEFAULT_EXTENSION, DocumentWithTitle } from 'components/tiptap';
import { DEFAULT_EXTENSION, DocumentWithTitle } from 'tiptap';
import { safeJSONParse } from 'helpers/json';
import { CreateUser } from '../user';
@ -15,13 +14,6 @@ export const DocumentContent: React.FC<IProps> = ({ document, createUserContaine
const c = safeJSONParse(document.content);
let json = c.default || c;
// if (json && json.content) {
// json = {
// type: 'doc',
// content: json.content.slice(1),
// };
// }
const editor = useEditor({
editable: false,
extensions: [...DEFAULT_EXTENSION, DocumentWithTitle],

View File

@ -1,7 +1,7 @@
.wrap {
height: 100%;
display: flex;
flex-direction: column;
height: 100%;
background-color: var(--semi-color-nav-bg);
.headerWrap {
@ -9,8 +9,8 @@
}
.contentWrap {
padding: 24px 24px 48px;
flex: 1;
padding: 24px 24px 48px;
overflow: auto;
.editorWrap {

View File

@ -9,15 +9,15 @@ import { DocumentStyle } from 'components/document/style';
import { User } from 'components/user';
import { Theme } from 'components/theme';
import { ImageViewer } from 'components/image-viewer';
import { useDocumentStyle } from 'hooks/useDocumentStyle';
import { useWindowSize } from 'hooks/useWindowSize';
import { useDocumentStyle } from 'hooks/use-document-style';
import { useWindowSize } from 'hooks/use-window-size';
import { usePublicDocument } from 'data/document';
import { DocumentSkeleton } from 'components/tiptap';
import { DocumentSkeleton } from 'tiptap';
import { DocumentContent } from './content';
import styles from './index.module.scss';
const { Header, Content } = Layout;
const { Text, Title } = Typography;
const { Text } = Typography;
interface IProps {
documentId: string;

View File

@ -5,7 +5,7 @@ import { isPublicDocument } from '@think/domains';
import { getDocumentShareURL } from 'helpers/url';
import { ShareIllustration } from 'illustrations/share';
import { DataRender } from 'components/data-render';
import { useToggle } from 'hooks/useToggle';
import { useToggle } from 'hooks/use-toggle';
import { useDocumentDetail } from 'data/document';
interface IProps {

View File

@ -1,5 +1,5 @@
import React from 'react';
import { Typography, Tooltip, Button } from '@douyinfe/semi-ui';
import { Tooltip, Button } from '@douyinfe/semi-ui';
import { IconStar } from '@douyinfe/semi-icons';
import { useDocumentStar } from 'data/document';
@ -8,8 +8,6 @@ interface IProps {
render?: (arg: { star: boolean; text: string; toggleStar: () => Promise<void> }) => React.ReactNode;
}
const { Text } = Typography;
export const DocumentStar: React.FC<IProps> = ({ documentId, render }) => {
const { data, toggleStar } = useDocumentStar(documentId);
const text = data ? '取消收藏' : '收藏文档';

View File

@ -1,6 +1,6 @@
import React from 'react';
import { RadioGroup, Radio, Typography, Slider } from '@douyinfe/semi-ui';
import { useDocumentStyle } from 'hooks/useDocumentStyle';
import { useDocumentStyle } from 'hooks/use-document-style';
import styles from './index.module.scss';
const { Text } = Typography;

View File

@ -52,13 +52,6 @@ export const GridSelect = ({
const onClick = useCallback(
({ x, y, isCellDisabled }) => {
// if (isCellDisabled) {
// return null;
// }
// if (activeCell.x === x && activeCell.y === y) {
// return null;
// }
// setActiveCell({ x, y });
onSelect({
rows: y + 1,
cols: x + 1,
@ -67,7 +60,6 @@ export const GridSelect = ({
[onSelect]
);
// eslint-disable-next-line react-hooks/exhaustive-deps
const onHover = useCallback(
debounce(({ x, y, isCellDisabled }) => {
if (isCellDisabled) {

View File

@ -6,7 +6,7 @@ export const IconCodeBlock: React.FC<{ style?: React.CSSProperties }> = ({ style
style={style}
svg={
<svg width="16" height="16" viewBox="0 0 256 256" role="presentation">
<g fill="currentColor" fill-rule="evenodd">
<g fill="currentColor" fillRule="evenodd">
<path
d="M64 40c5.523 0 10 4.477 10 10 0 5.43-4.327 9.848-9.72 9.996L64 60H54a6 6 0 0 0-5.996 5.775L48 66v42.5a10 10 0 0 1-1.667 5.529l-.21.303L36.31 128l9.813 13.668a10 10 0 0 1 1.87 5.463l.007.369V190a6 6 0 0 0 5.775 5.996L54 196h10c5.523 0 10 4.477 10 10 0 5.43-4.327 9.848-9.72 9.996L64 216H54c-14.216 0-25.767-11.409-25.997-25.57L28 190v-39.281l-12.123-16.887a10 10 0 0 1-.179-11.407l.179-.257L28 105.28V66c0-14.216 11.409-25.767 25.57-25.997L54 40h10ZM192 40c-5.523 0-10 4.477-10 10 0 5.43 4.327 9.848 9.72 9.996L192 60h10a6 6 0 0 1 5.996 5.775L208 66v42.5a10 10 0 0 0 1.667 5.529l.21.303L219.69 128l-9.813 13.668a10 10 0 0 0-1.87 5.463l-.007.369V190a6 6 0 0 1-5.775 5.996L202 196h-10c-5.523 0-10 4.477-10 10 0 5.43 4.327 9.848 9.72 9.996l.28.004h10c14.216 0 25.767-11.409 25.997-25.57L228 190v-39.281l12.123-16.887a10 10 0 0 0 .179-11.407l-.179-.257L228 105.28V66c0-14.216-11.409-25.767-25.57-25.997L202 40h-10Z"
fillRule="nonzero"

View File

@ -6,7 +6,7 @@ export const IconHorizontalRule: React.FC<{ style?: React.CSSProperties }> = ({
style={style}
svg={
<svg width="16" height="16" viewBox="0 0 256 256" role="presentation">
<g fill="none" fill-rule="evenodd">
<g fill="none" fillRule="evenodd">
<rect fill="currentColor" x="17" y="116" width="223" height="24" rx="12"></rect>
</g>
</svg>

View File

@ -6,8 +6,8 @@ export const IconList: React.FC<{ style?: React.CSSProperties }> = ({ style = {}
style={style}
svg={
<svg width="16" height="16" viewBox="0 0 256 256" role="presentation">
<g fill="currentColor" fill-rule="evenodd">
<g fill-rule="nonzero">
<g fill="currentColor" fillRule="evenodd">
<g fillRule="nonzero">
<path d="M215 118c5.523 0 10 4.477 10 10 0 5.43-4.327 9.848-9.72 9.996L215 138H96c-5.523 0-10-4.477-10-10 0-5.43 4.327-9.848 9.72-9.996L96 118h119ZM215 35c5.523 0 10 4.477 10 10 0 5.43-4.327 9.848-9.72 9.996L215 55H96c-5.523 0-10-4.477-10-10 0-5.43 4.327-9.848 9.72-9.996L96 35h119ZM215 201c5.523 0 10 4.477 10 10 0 5.43-4.327 9.848-9.72 9.996L215 221H96c-5.523 0-10-4.477-10-10 0-5.43 4.327-9.848 9.72-9.996L96 201h119Z"></path>
</g>
<circle cx="44" cy="45" r="16"></circle>

View File

@ -6,7 +6,7 @@ export const IconMind: React.FC<{ style?: React.CSSProperties }> = ({ style = {}
style={style}
svg={
<svg width="16" height="16" viewBox="0 0 256 256" role="presentation">
<g fill="currentColor" fill-rule="nonzero">
<g fill="currentColor" fillRule="nonzero">
<path d="M214 35h-46c-14.36 0-26 11.64-26 26v10c0 14.36 11.64 26 26 26h46c14.36 0 26-11.64 26-26V61c0-14.36-11.64-26-26-26Zm-46 20h46a6 6 0 0 1 6 6v10a6 6 0 0 1-6 6h-46a6 6 0 0 1-6-6V61a6 6 0 0 1 6-6ZM214 159h-46c-14.36 0-26 11.64-26 26v10c0 14.36 11.64 26 26 26h46c14.36 0 26-11.64 26-26v-10c0-14.36-11.64-26-26-26Zm-46 20h46a6 6 0 0 1 6 6v10a6 6 0 0 1-6 6h-46a6 6 0 0 1-6-6v-10a6 6 0 0 1 6-6Z"></path>
<path d="M73.55 147.305c7.858 20.517 27.486 34.415 49.774 34.69L124 182h26.207v16H124c-28.957 0-54.586-17.747-65.078-44.17l-.313-.803 14.942-5.722ZM158 58v16h-34c-22.645 0-42.63 14.068-50.511 34.857l-.235.632-15.03-5.484c9.897-27.128 35.606-45.632 64.888-46L124 58h34Z"></path>
<path d="M88 97H42c-14.36 0-26 11.64-26 26v10c0 14.36 11.64 26 26 26h46c14.36 0 26-11.64 26-26v-10c0-14.36-11.64-26-26-26Zm-46 20h46a6 6 0 0 1 6 6v10a6 6 0 0 1-6 6H42a6 6 0 0 1-6-6v-10a6 6 0 0 1 6-6Z"></path>

View File

@ -6,7 +6,7 @@ export const IconOrderedList: React.FC<{ style?: React.CSSProperties }> = ({ sty
style={style}
svg={
<svg width="16" height="16" viewBox="0 0 256 256" role="presentation">
<g fill="currentColor" fill-rule="nonzero">
<g fill="currentColor" fillRule="nonzero">
<path d="M215 118c5.523 0 10 4.477 10 10 0 5.43-4.327 9.848-9.72 9.996L215 138H101c-5.523 0-10-4.477-10-10 0-5.43 4.327-9.848 9.72-9.996L101 118h114ZM215 35c5.523 0 10 4.477 10 10 0 5.43-4.327 9.848-9.72 9.996L215 55H101c-5.523 0-10-4.477-10-10 0-5.43 4.327-9.848 9.72-9.996L101 35h114ZM215 201c5.523 0 10 4.477 10 10 0 5.43-4.327 9.848-9.72 9.996L215 221H101c-5.523 0-10-4.477-10-10 0-5.43 4.327-9.848 9.72-9.996L101 201h114ZM65.988 190.061l-.739.79-1.88 2.061-4.394 4.885-6.435 7.205h13.852a9 9 0 0 1 8.996 8.736l.004.265a9 9 0 0 1-8.735 8.996l-.265.004H32.5c-7.762 0-11.883-9.167-6.732-14.973l15.666-17.621 6.446-7.197 3.323-3.665 1.424-1.54.623-.653.408-.407.042-.039c1.203-1.106 1.855-2.536 1.855-4.05 0-3.128-2.87-5.855-6.637-5.855-3.681 0-6.508 2.607-6.632 5.647l-.004.208a9 9 0 1 1-18 0c0-13.281 11.13-23.855 24.636-23.855 13.507 0 24.637 10.574 24.637 23.855 0 6.497-2.703 12.572-7.355 17.003l-.212.2ZM43.206 25.413c5.694-5.302 14.934-1.363 15.13 6.337l.003.25v73a9 9 0 0 1-17.996.265L40.34 105V52.583c-3.556 2.568-8.513 2.208-11.653-.96l-.198-.207a9 9 0 0 1 .247-12.522l.206-.198 14.265-13.283Z"></path>
</g>
</svg>

View File

@ -6,12 +6,12 @@ export const IconQuote: React.FC<{ style?: React.CSSProperties }> = ({ style = {
style={style}
svg={
<svg width="16" height="16" viewBox="0 0 256 256" role="presentation">
<g fill="none" fill-rule="evenodd">
<g fill="none" fillRule="evenodd">
<g fill="currentColor">
<path d="M36 143h44c6.627 0 12 5.373 12 12v44c0 6.627-5.373 12-12 12H36c-6.627 0-12-5.373-12-12v-44c0-6.627 5.373-12 12-12Z"></path>
<path
d="M84.144 53.257c5.502-.485 10.355 3.582 10.84 9.084.476 5.408-3.447 10.19-8.806 10.81l-.279.029c-23.384 2.06-41.533 21.544-41.894 45.105L44 119v41.723c0 5.523-4.477 10-10 10-5.43 0-9.848-4.326-9.996-9.72l-.004-.28V119c0-34.269 26.22-62.755 60.144-65.743Z"
fill-rule="nonzero"
fillRule="nonzero"
></path>
<path d="M43.272 120.769 38.56 142.58a9.567 9.567 0 0 0 13.93 10.42l11.401-6.216a2.015 2.015 0 0 0-.964-3.784h-2.933c-8.837 0-16-7.164-16-16v-6.155a.365.365 0 0 0-.722-.077Z"></path>
</g>
@ -19,7 +19,7 @@ export const IconQuote: React.FC<{ style?: React.CSSProperties }> = ({ style = {
<path d="M176 143h44c6.627 0 12 5.373 12 12v44c0 6.627-5.373 12-12 12h-44c-6.627 0-12-5.373-12-12v-44c0-6.627 5.373-12 12-12Z"></path>
<path
d="M224.144 53.257c5.502-.485 10.355 3.582 10.84 9.084.476 5.408-3.447 10.19-8.806 10.81l-.279.029c-23.384 2.06-41.533 21.544-41.894 45.105L184 119v41.723c0 5.523-4.477 10-10 10-5.43 0-9.848-4.326-9.996-9.72l-.004-.28V119c0-34.269 26.22-62.755 60.144-65.743Z"
fill-rule="nonzero"
fillRule="nonzero"
></path>
<path d="m183.272 120.769-4.712 21.812a9.567 9.567 0 0 0 13.93 10.42l11.401-6.216a2.015 2.015 0 0 0-.964-3.784h-2.933c-8.837 0-16-7.164-16-16v-6.155a.365.365 0 0 0-.722-.077Z"></path>
</g>

View File

@ -6,8 +6,8 @@ export const IconSearchReplace: React.FC<{ style?: React.CSSProperties }> = ({ s
style={style}
svg={
<svg width="16" height="16" viewBox="0 0 256 256" role="presentation">
<g fill="currentColor" fill-rule="evenodd">
<g fill-rule="nonzero">
<g fill="currentColor" fillRule="evenodd">
<g fillRule="nonzero">
<path d="M191.527 15c18.302 0 33.173 14.688 33.469 32.919l.004.554v65.424c0 5.523-4.477 10-10 10-5.43 0-9.848-4.327-9.996-9.72l-.004-.28V48.473c0-7.338-5.865-13.305-13.163-13.47l-.31-.003H64.473c-7.338 0-13.305 5.865-13.47 13.163l-.003.31v159.054c0 7.338 5.865 13.305 13.163 13.47l.31.003H99c5.523 0 10 4.477 10 10 0 5.43-4.327 9.848-9.72 9.996L99 241H64.473c-18.302 0-33.173-14.688-33.469-32.919l-.004-.554V48.473C31 30.17 45.688 15.3 63.919 15.004l.554-.004h127.054Z"></path>
<path d="M147.385 150.885c-17.964 17.964-17.964 47.09 0 65.054s47.09 17.964 65.054 0c17.964-17.965 17.964-47.09 0-65.054-17.965-17.964-47.09-17.964-65.054 0Zm14.142 14.142c10.154-10.154 26.616-10.154 36.77 0 10.153 10.154 10.153 26.616 0 36.77-10.154 10.153-26.616 10.153-36.77 0-10.154-10.154-10.154-26.616 0-36.77Z"></path>
<path d="M234.545 241.752c-3.839 3.84-10.023 3.904-13.941.196l-.2-.196-21.921-21.92c-3.905-3.905-3.905-10.237 0-14.142 3.839-3.84 10.023-3.904 13.941-.195l.2.195 21.921 21.92c3.905 3.905 3.905 10.237 0 14.142Z"></path>

View File

@ -6,10 +6,10 @@ export const IconStatus: React.FC<{ style?: React.CSSProperties }> = ({ style =
style={style}
svg={
<svg width="16" height="16" viewBox="0 0 256 256" role="presentation">
<g transform="rotate(-45 100.071 47.645)" fill="currentColor" fill-rule="evenodd">
<g transform="rotate(-45 100.071 47.645)" fill="currentColor" fillRule="evenodd">
<path
d="m44.625 4.22-47 46.951A26 26 0 0 0-10 69.566V190c0 14.36 11.64 26 26 26h94c14.36 0 26-11.64 26-26V69.566a26 26 0 0 0-7.625-18.395l-47-46.95c-10.151-10.14-26.599-10.14-36.75 0ZM67.24 18.37l47 46.95a6 6 0 0 1 1.76 4.246V190a6 6 0 0 1-6 6H16a6 6 0 0 1-6-6V69.566a6 6 0 0 1 1.76-4.245l47-46.95a6 6 0 0 1 8.48 0Z"
fill-rule="nonzero"
fillRule="nonzero"
></path>
<circle cx="63.172" cy="67.586" r="14"></circle>
</g>

View File

@ -6,8 +6,8 @@ export const IconSub: React.FC<{ style?: React.CSSProperties }> = ({ style = {}
style={style}
svg={
<svg width="16" height="16" viewBox="0 0 256 256" role="presentation">
<g stroke="currentColor" fill="none" fill-rule="evenodd">
<path stroke-width="20" stroke-linecap="round" d="m40 50 114 168M154 50 40 218"></path>
<g stroke="currentColor" fill="none" fillRule="evenodd">
<path strokeWidth="20" strokeLinecap="round" d="m40 50 114 168M154 50 40 218"></path>
<path
d="M231.92 225.48c2.72 0 4.08-1.48 4.08-4.44 0-2.88-1.36-4.32-4.08-4.32H198.8c6.48-5.52 12.28-11.24 17.4-17.16 2.16-2.48 4.28-5.16 6.36-8.04 2.08-2.88 3.94-5.82 5.58-8.82 1.64-3 2.96-6.04 3.96-9.12 1-3.08 1.5-6.14 1.5-9.18 0-3.36-.48-6.42-1.44-9.18s-2.38-5.12-4.26-7.08-4.2-3.48-6.96-4.56c-2.76-1.08-5.9-1.62-9.42-1.62-7.92 0-13.8 2.26-17.64 6.78-3.84 4.52-5.76 10.66-5.76 18.42 0 2.24.32 3.74.96 4.5.64.76 1.96 1.14 3.96 1.14 1.76 0 2.98-.44 3.66-1.32.68-.88 1.02-2.32 1.02-4.32 0-4.8 1.04-8.74 3.12-11.82s5.4-4.62 9.96-4.62c4 0 7.16 1.32 9.48 3.96 2.32 2.64 3.48 6.12 3.48 10.44 0 3.2-.64 6.42-1.92 9.66-1.28 3.24-2.94 6.4-4.98 9.48a84.099 84.099 0 0 1-6.84 8.94c-2.52 2.88-5.04 5.6-7.56 8.16-2.52 2.56-4.92 4.94-7.2 7.14-2.28 2.2-4.18 4.1-5.7 5.7-.64 1.04-.96 2.04-.96 3-.56 1.04-.86 2.06-.9 3.06-.04 1 .1 1.88.42 2.64.32.76.8 1.38 1.44 1.86.64.48 1.36.72 2.16.72h40.2Z"
strokeWidth="5"

View File

@ -6,8 +6,8 @@ export const IconSup: React.FC<{ style?: React.CSSProperties }> = ({ style = {}
style={style}
svg={
<svg width="16" height="16" viewBox="0 0 256 256" role="presentation">
<g stroke="currentColor" fill="none" fill-rule="evenodd">
<path stroke-width="20" stroke-linecap="round" d="m40 50 114 168M154 50 40 218"></path>
<g stroke="currentColor" fill="none" fillRule="evenodd">
<path strokeWidth="20" strokeLinecap="round" d="m40 50 114 168M154 50 40 218"></path>
<path
d="M231.92 103.48c2.72 0 4.08-1.48 4.08-4.44 0-2.88-1.36-4.32-4.08-4.32H198.8c6.48-5.52 12.28-11.24 17.4-17.16 2.16-2.48 4.28-5.16 6.36-8.04 2.08-2.88 3.94-5.82 5.58-8.82 1.64-3 2.96-6.04 3.96-9.12 1-3.08 1.5-6.14 1.5-9.18 0-3.36-.48-6.42-1.44-9.18s-2.38-5.12-4.26-7.08-4.2-3.48-6.96-4.56c-2.76-1.08-5.9-1.62-9.42-1.62-7.92 0-13.8 2.26-17.64 6.78-3.84 4.52-5.76 10.66-5.76 18.42 0 2.24.32 3.74.96 4.5.64.76 1.96 1.14 3.96 1.14 1.76 0 2.98-.44 3.66-1.32.68-.88 1.02-2.32 1.02-4.32 0-4.8 1.04-8.74 3.12-11.82s5.4-4.62 9.96-4.62c4 0 7.16 1.32 9.48 3.96 2.32 2.64 3.48 6.12 3.48 10.44 0 3.2-.64 6.42-1.92 9.66-1.28 3.24-2.94 6.4-4.98 9.48a84.099 84.099 0 0 1-6.84 8.94c-2.52 2.88-5.04 5.6-7.56 8.16-2.52 2.56-4.92 4.94-7.2 7.14-2.28 2.2-4.18 4.1-5.7 5.7-.64 1.04-.96 2.04-.96 3-.56 1.04-.86 2.06-.9 3.06-.04 1 .1 1.88.42 2.64.32.76.8 1.38 1.44 1.86.64.48 1.36.72 2.16.72h40.2Z"
strokeWidth="5"

View File

@ -6,7 +6,7 @@ export const IconTable: React.FC<{ style?: React.CSSProperties }> = ({ style = {
style={style}
svg={
<svg width="16" height="16" viewBox="0 0 256 256" role="presentation">
<g fill="currentColor" fill-rule="evenodd">
<g fill="currentColor" fillRule="evenodd">
<path
d="M208 40c17.673 0 32 14.327 32 32v112c0 17.673-14.327 32-32 32H48c-17.673 0-32-14.327-32-32V72c0-17.673 14.327-32 32-32h160Zm0 20H48c-6.525 0-11.834 5.209-11.996 11.695L36 72v112c0 6.525 5.209 11.834 11.695 11.996L48 196h160c6.525 0 11.834-5.209 11.996-11.695L220 184V72c0-6.525-5.209-11.834-11.695-11.996L208 60Z"
fillRule="nonzero"

View File

@ -6,16 +6,16 @@ export const IconTask: React.FC<{ style?: React.CSSProperties }> = ({ style = {}
style={style}
svg={
<svg width="16" height="16" viewBox="0 0 256 256" role="presentation">
<g fill="none" fill-rule="evenodd">
<g fill="none" fillRule="evenodd">
<path
d="M169.002 89.757c3.945-3.865 10.276-3.8 14.141.145 3.795 3.873 3.801 10.047.067 13.928l-.212.213-63.285 62a10 10 0 0 1-13.776.209l-.219-.208-32.715-32.041c-3.946-3.865-4.012-10.196-.147-14.142 3.794-3.873 9.966-4.007 13.924-.354l.217.207 25.717 25.187 56.288-55.144Z"
fill="currentColor"
fill-rule="nonzero"
fillRule="nonzero"
></path>
<path
d="M201 23c17.673 0 32 14.327 32 32v146c0 17.673-14.327 32-32 32H55c-17.673 0-32-14.327-32-32V55c0-17.673 14.327-32 32-32h146Zm0 20H55c-6.525 0-11.834 5.209-11.996 11.695L43 55v146c0 6.525 5.209 11.834 11.695 11.996L55 213h146c6.525 0 11.834-5.209 11.996-11.695L213 201V55c0-6.525-5.209-11.834-11.695-11.996L201 43Z"
fill="currentColor"
fill-rule="nonzero"
fillRule="nonzero"
></path>
</g>
</svg>

View File

@ -35,7 +35,7 @@ const getTimeago = (date: number | string | Date) => {
};
export const LocaleTime: React.FC<Props> = ({ date, timeago, format = 'yyyy-MM-dd HH:mm:ss' }) => {
const [_, setMinutesMounted] = useState(0); // eslint-disable-line no-unused-vars
const [, setMinutesMounted] = useState(0);
const callback = useRef<() => void>();
useEffect(() => {

View File

@ -9,9 +9,9 @@
}
> span {
margin-left: 4px;
font-size: 1.2rem;
font-weight: 500;
margin-left: 4px;
}
}

View File

@ -11,25 +11,25 @@
border-radius: var(--semi-border-radius-small);
&:hover {
background-color: var(--semi-color-fill-0);
color: var(--semi-color-text-0);
background-color: var(--semi-color-fill-0);
}
.item {
display: flex;
align-items: center;
justify-content: space-between;
align-items: center;
width: 100%;
height: 32px;
padding: 4px 16px;
.leftWrap {
display: flex;
align-items: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: var(--semi-color-primary);
text-overflow: ellipsis;
white-space: nowrap;
align-items: center;
> span {
word-break: break-all;
@ -51,5 +51,4 @@
.paginationWrap {
display: flex;
justify-content: center;
// padding: 16px 0 0;
}

View File

@ -6,7 +6,7 @@ import { useAllMessages, useReadMessages, useUnreadMessages } from 'data/message
import { EmptyBoxIllustration } from 'illustrations/empty-box';
import { DataRender } from 'components/data-render';
import { Empty } from 'components/empty';
import { Placeholder } from './Placeholder';
import { Placeholder } from './placeholder';
import styles from './index.module.scss';
const { Text } = Typography;

View File

@ -1,38 +1,38 @@
.resizable {
box-sizing: border-box;
position: relative;
display: inline-block;
width: 100px;
height: 100px;
max-width: 100%;
box-sizing: border-box;
.resizer {
box-sizing: border-box;
position: absolute;
z-index: 9999;
width: 10px;
height: 10px;
border-radius: 50%;
background: white;
border: 3px solid #4286f4;
border-radius: 50%;
opacity: 0;
box-sizing: border-box;
}
.resizer.topLeft {
left: -5px;
top: -5px;
left: -5px;
cursor: nwse-resize;
}
.resizer.topRight {
right: -5px;
top: -5px;
right: -5px;
cursor: nesw-resize;
}
.resizer.bottomLeft {
left: -5px;
bottom: -5px;
left: -5px;
cursor: nesw-resize;
}

View File

@ -1,29 +1,26 @@
.itemsWrap {
}
.itemWrap {
margin-top: 8px;
border-radius: var(--semi-border-radius-small);
&:hover {
background-color: var(--semi-color-fill-0);
color: var(--semi-color-text-0);
background-color: var(--semi-color-fill-0);
}
.item {
display: flex;
align-items: center;
justify-content: space-between;
align-items: center;
width: 100%;
padding: 4px 8px;
.leftWrap {
display: flex;
align-items: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: var(--semi-color-primary);
text-overflow: ellipsis;
white-space: nowrap;
align-items: center;
> span {
word-break: break-all;

View File

@ -6,8 +6,8 @@ import { IconSearch as SemiIconSearch } from '@douyinfe/semi-icons';
import { IconSearch } from 'components/icons';
import { IDocument } from '@think/domains';
import { useRecentDocuments } from 'data/document';
import { useToggle } from 'hooks/useToggle';
import { useAsyncLoading } from 'hooks/useAsyncLoading';
import { useToggle } from 'hooks/use-toggle';
import { useAsyncLoading } from 'hooks/use-async-loading';
import { searchDocument } from 'services/document';
import { Empty } from 'components/empty';
import { DataRender } from 'components/data-render';

View File

@ -1,67 +1,64 @@
.cardWrap {
position: relative;
transform: translateZ(0);
margin: 8px 0;
display: flex;
flex-direction: column;
width: 100%;
height: 161px;
padding: 12px 16px 16px;
border-radius: var(--border-radius);
border: 1px solid var(--semi-color-border);
cursor: pointer;
margin: 8px 0;
overflow: hidden;
cursor: pointer;
border: 1px solid var(--semi-color-border);
border-radius: var(--border-radius);
transform: translateZ(0);
flex-direction: column;
header {
display: flex;
justify-content: space-between;
align-items: center;
color: var(--semi-color-primary);
margin-bottom: 12px;
color: var(--semi-color-primary);
.rightWrap {
opacity: 0;
}
}
.actions {
position: absolute;
bottom: -1px;
left: 0;
z-index: 10;
display: flex;
width: 100%;
padding: 8px;
background-color: var(--semi-color-fill-2);
border-radius: 0 0 var(--border-radius) var(--border-radius);
opacity: 0;
justify-content: space-around;
transition: all ease-in-out .2s;
button {
width: 40%;
}
}
&:hover {
box-shadow: var(--semi-color-shadow);
header .rightWrap {
opacity: 1;
}
}
footer {
margin-top: 12px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.actions {
position: absolute;
bottom: -1px;
left: 0;
z-index: 10;
transition: all ease-in-out 0.2s;
width: 100%;
display: flex;
justify-content: space-around;
padding: 8px;
border-radius: 0 0 var(--border-radius) var(--border-radius);
background-color: var(--semi-color-fill-2);
opacity: 0;
button {
width: 40%;
}
}
&:hover {
.actions {
opacity: 1;
}
}
footer {
margin-top: 12px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}

View File

@ -6,9 +6,9 @@ import { Button, Space, Typography, Tooltip, Avatar, Skeleton, Modal } from '@do
import { IconEdit, IconUser, IconPlus } from '@douyinfe/semi-icons';
import { IconDocument } from 'components/icons/IconDocument';
import { TemplateReader } from 'components/template/reader';
import { useToggle } from 'hooks/use-toggle';
import { useUser } from 'data/user';
import styles from './index.module.scss';
import { useToggle } from 'hooks/useToggle';
const { Text } = Typography;

View File

@ -18,18 +18,12 @@ import {
import { IconChevronLeft, IconArticle } from '@douyinfe/semi-icons';
import { ILoginUser, ITemplate } from '@think/domains';
import { Theme } from 'components/theme';
import {
DEFAULT_EXTENSION,
DocumentWithTitle,
getCollaborationExtension,
getProvider,
MenuBar,
} from 'components/tiptap';
import { DEFAULT_EXTENSION, DocumentWithTitle, getCollaborationExtension, getProvider, MenuBar } from 'tiptap';
import { DataRender } from 'components/data-render';
import { User } from 'components/user';
import { DocumentStyle } from 'components/document/style';
import { useDocumentStyle } from 'hooks/useDocumentStyle';
import { useWindowSize } from 'hooks/useWindowSize';
import { useDocumentStyle } from 'hooks/use-document-style';
import { useWindowSize } from 'hooks/use-window-size';
import { safeJSONParse } from 'helpers/json';
import styles from './index.module.scss';

View File

@ -1,14 +1,14 @@
.wrap {
height: 100%;
overflow: hidden;
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
> header {
position: relative;
z-index: 110;
background-color: var(--semi-color-nav-bg);
height: 60px;
background-color: var(--semi-color-nav-bg);
user-select: none;
> div {
@ -18,30 +18,37 @@
> main {
height: calc(100% - 60px);
flex: 1;
overflow: hidden;
background-color: var(--semi-color-nav-bg);
flex: 1;
}
}
.editorWrap {
height: 100%;
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
> header {
position: relative;
z-index: 110;
display: flex;
height: 50px;
padding: 0 24px;
display: flex;
align-items: center;
overflow: hidden;
background-color: var(--semi-color-nav-bg);
align-items: center;
border-bottom: 1px solid var(--semi-color-border);
user-select: none;
> div {
display: inline-flex;
align-items: center;
height: 100%;
overflow: auto;
}
&.isStandardWidth {
> div {
margin: 0 auto;
@ -53,14 +60,6 @@
margin: 0;
}
}
> div {
display: inline-flex;
align-items: center;
// width: 100%;
height: 100%;
overflow: auto;
}
}
> main {

View File

@ -3,10 +3,10 @@ import cls from 'classnames';
import { useEditor, EditorContent } from '@tiptap/react';
import { Layout, Spin, Typography } from '@douyinfe/semi-ui';
import { IUser, ITemplate } from '@think/domains';
import { DEFAULT_EXTENSION, DocumentWithTitle } from 'components/tiptap';
import { DEFAULT_EXTENSION, DocumentWithTitle } from 'tiptap';
import { DataRender } from 'components/data-render';
import { ImageViewer } from 'components/image-viewer';
import { useDocumentStyle } from 'hooks/useDocumentStyle';
import { useDocumentStyle } from 'hooks/use-document-style';
import { safeJSONParse } from 'helpers/json';
import styles from './index.module.scss';

View File

@ -1,7 +1,6 @@
.wrap {
display: flex;
flex-direction: column;
height: 100%;
.contentWrap {

View File

@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react';
import React from 'react';
import { Button, Tooltip } from '@douyinfe/semi-ui';
import { IconSun, IconMoon } from '@douyinfe/semi-icons';
import { useTheme } from 'hooks/useTheme';
import { useTheme } from 'hooks/use-theme';
export const Theme = () => {
const { theme, toggle } = useTheme();

View File

@ -1,2 +0,0 @@
export * from './collaboration';
export * from './helpers/isChangeOrigin';

View File

@ -1,187 +0,0 @@
import * as Y from 'yjs';
import { Decoration, DecorationSet } from 'prosemirror-view'; // eslint-disable-line
import { Plugin } from 'prosemirror-state'; // eslint-disable-line
import * as math from 'lib0/math';
import {
absolutePositionToRelativePosition,
relativePositionToAbsolutePosition,
setMeta,
yCursorPluginKey,
ySyncPluginKey,
} from 'y-prosemirror';
/**
* Default generator for a cursor element
*
* @param {any} user user data
* @return HTMLElement
*/
export const defaultCursorBuilder = (user) => {
const cursor = document.createElement('span');
cursor.classList.add('ProseMirror-yjs-cursor');
cursor.setAttribute('style', `border-color: ${user.color}`);
const userDiv = document.createElement('div');
userDiv.setAttribute('style', `background-color: ${user.color}`);
userDiv.insertBefore(document.createTextNode(user.name), null);
cursor.insertBefore(userDiv, null);
return cursor;
};
const rxValidColor = /^#[0-9a-fA-F]{6}$/;
/**
* @param {any} state
* @param {Awareness} awareness
* @return {any} DecorationSet
*/
export const createDecorations = (state, awareness, createCursor) => {
const ystate = ySyncPluginKey.getState(state) || state['y-sync$'];
const y = ystate.doc;
const decorations = [];
if (ystate.snapshot != null || ystate.prevSnapshot != null || ystate.binding === null) {
// do not render cursors while snapshot is active
return DecorationSet.create(state.doc, []);
}
awareness.getStates().forEach((aw, clientId) => {
if (clientId === y.clientID) {
return;
}
if (aw.cursor != null) {
const user = aw.user || {};
if (user.color == null) {
user.color = '#ffa500';
} else if (!rxValidColor.test(user.color)) {
// We only support 6-digit RGB colors in y-prosemirror
console.warn('A user uses an unsupported color format', user);
}
if (user.name == null) {
user.name = `User: ${clientId}`;
}
let anchor = relativePositionToAbsolutePosition(
y,
ystate.type,
Y.createRelativePositionFromJSON(aw.cursor.anchor),
ystate.binding.mapping
);
let head = relativePositionToAbsolutePosition(
y,
ystate.type,
Y.createRelativePositionFromJSON(aw.cursor.head),
ystate.binding.mapping
);
if (anchor !== null && head !== null) {
const maxsize = math.max(state.doc.content.size - 1, 0);
anchor = math.min(anchor, maxsize);
head = math.min(head, maxsize);
decorations.push(Decoration.widget(head, () => createCursor(user), { key: clientId + '', side: 10 }));
const from = math.min(anchor, head);
const to = math.max(anchor, head);
decorations.push(
Decoration.inline(
from,
to,
{ style: `background-color: ${user.color}70` },
{ inclusiveEnd: true, inclusiveStart: false }
)
);
}
}
});
return DecorationSet.create(state.doc, decorations);
};
/**
* A prosemirror plugin that listens to awareness information on Yjs.
* This requires that a `prosemirrorPlugin` is also bound to the prosemirror.
*
* @public
* @param {Awareness} awareness
* @param {object} [opts]
* @param {function(any):HTMLElement} [opts.cursorBuilder]
* @param {function(any):any} [opts.getSelection]
* @param {string} [opts.cursorStateField] By default all editor bindings use the awareness 'cursor' field to propagate cursor information.
* @return {any}
*/
export const yCursorPlugin = (
awareness,
{ cursorBuilder = defaultCursorBuilder, getSelection = (state) => state.selection } = {},
cursorStateField = 'cursor'
) =>
new Plugin({
key: yCursorPluginKey,
state: {
init(_, state) {
return createDecorations(state, awareness, cursorBuilder);
},
apply(tr, prevState, oldState, newState) {
const ystate = ySyncPluginKey.getState(newState);
const yCursorState = tr.getMeta(yCursorPluginKey);
if ((ystate && ystate.isChangeOrigin) || (yCursorState && yCursorState.awarenessUpdated)) {
return createDecorations(newState, awareness, cursorBuilder);
}
return prevState.map(tr.mapping, tr.doc);
},
},
props: {
decorations: (state) => {
return yCursorPluginKey.getState(state);
},
},
view: (view) => {
const awarenessListener = () => {
// @ts-ignore
if (view.docView) {
setMeta(view, yCursorPluginKey, { awarenessUpdated: true });
}
};
const updateCursorInfo = () => {
const ystate = ySyncPluginKey.getState(view.state) || view.state['y-sync$'];
// @note We make implicit checks when checking for the cursor property
const current = awareness.getLocalState() || {};
if (view.hasFocus() && ystate.binding !== null) {
const selection = getSelection(view.state);
/**
* @type {Y.RelativePosition}
*/
const anchor = absolutePositionToRelativePosition(selection.anchor, ystate.type, ystate.binding.mapping);
/**
* @type {Y.RelativePosition}
*/
const head = absolutePositionToRelativePosition(selection.head, ystate.type, ystate.binding.mapping);
if (
current.cursor == null ||
!Y.compareRelativePositions(Y.createRelativePositionFromJSON(current.cursor.anchor), anchor) ||
!Y.compareRelativePositions(Y.createRelativePositionFromJSON(current.cursor.head), head)
) {
awareness.setLocalStateField(cursorStateField, {
anchor,
head,
});
}
} else if (
current.cursor != null &&
relativePositionToAbsolutePosition(
ystate.doc,
ystate.type,
Y.createRelativePositionFromJSON(current.cursor.anchor),
ystate.binding.mapping
) !== null
) {
// delete cursor information if current cursor information is owned by this editor binding
awareness.setLocalStateField(cursorStateField, null);
}
};
awareness.on('change', awarenessListener);
view.dom.addEventListener('focusin', updateCursorInfo);
view.dom.addEventListener('focusout', updateCursorInfo);
return {
update: updateCursorInfo,
destroy: () => {
view.dom.removeEventListener('focusin', updateCursorInfo);
view.dom.removeEventListener('focusout', updateCursorInfo);
awareness.off('change', awarenessListener);
awareness.setLocalStateField(cursorStateField, null);
},
};
},
});

View File

@ -1,9 +1,7 @@
import React from 'react';
import { Tooltip as SemiTooltip } from '@douyinfe/semi-ui';
import { Position } from '@douyinfe/semi-ui/tooltip';
import { useToggle } from 'hooks/useToggle';
let id = 0;
import { useToggle } from 'hooks/use-toggle';
interface IProps {
content: React.ReactNode;

View File

@ -1,7 +1,7 @@
import React from 'react';
import { Upload as SemiUpload, Button, Toast } from '@douyinfe/semi-ui';
import { IconUpload } from '@douyinfe/semi-icons';
import { useAsyncLoading } from 'hooks/useAsyncLoading';
import { useAsyncLoading } from 'hooks/use-async-loading';
import { uploadFile } from 'services/file';
interface IProps {

View File

@ -2,7 +2,7 @@ import React from 'react';
import { Dropdown, Typography, Avatar, Button } from '@douyinfe/semi-ui';
import { IconSpin } from '@douyinfe/semi-icons';
import { useUser } from 'data/user';
import { useToggle } from 'hooks/useToggle';
import { useToggle } from 'hooks/use-toggle';
import { UserSetting } from './setting';
const { Text } = Typography;

View File

@ -1,6 +1,6 @@
import React from 'react';
import { Button } from '@douyinfe/semi-ui';
import { useToggle } from 'hooks/useToggle';
import { useToggle } from 'hooks/use-toggle';
import { WikiCreator as WikiCreatorForm } from 'components/wiki/create';
export const WikiCreator: React.FC = ({ children }) => {

View File

@ -1,8 +1,8 @@
import React from 'react';
import { Dropdown, Button } from '@douyinfe/semi-ui';
import { IconChevronDown } from '@douyinfe/semi-icons';
import { useToggle } from 'hooks/useToggle';
import { useQuery } from 'hooks/useQuery';
import { useToggle } from 'hooks/use-toggle';
import { useQuery } from 'hooks/use-query';
import { WikiCreator } from 'components/wiki/create';
import { DocumentCreator } from 'components/document/create';

View File

@ -2,23 +2,22 @@
width: 100%;
> a {
margin: 8px 0;
display: flex;
flex-direction: column;
width: 100%;
max-height: 260px;
padding: 12px 16px 16px;
border-radius: 5px;
border: 1px solid var(--semi-color-border);
margin: 8px 0;
cursor: pointer;
border: 1px solid var(--semi-color-border);
border-radius: 5px;
flex-direction: column;
> header {
display: flex;
justify-content: space-between;
align-items: center;
color: var(--semi-color-primary);
margin-bottom: 12px;
color: var(--semi-color-primary);
.rightWrap {
opacity: 0;

View File

@ -2,23 +2,22 @@
width: 100%;
> a {
margin: 8px 0;
display: flex;
flex-direction: column;
width: 100%;
max-height: 260px;
padding: 12px 16px 16px;
border-radius: 5px;
border: 1px solid var(--semi-color-border);
margin: 8px 0;
cursor: pointer;
border: 1px solid var(--semi-color-border);
border-radius: 5px;
flex-direction: column;
> header {
display: flex;
justify-content: space-between;
align-items: center;
color: var(--semi-color-primary);
margin-bottom: 12px;
color: var(--semi-color-primary);
.rightWrap {
opacity: 0;

View File

@ -8,14 +8,14 @@
img {
width: 104px;
height: 96px;
border-radius: 4px;
margin-bottom: 16px;
border-radius: 4px;
}
}
.right {
flex: 1;
display: flex;
flex: 1;
flex-direction: column;
justify-content: space-between;
overflow: auto;
@ -59,8 +59,8 @@
.placeholderWrapper {
width: 100%;
overflow: auto;
margin: 16px 0;
overflow: auto;
.coverPlaceholder {
flex-shrink: 0;

View File

@ -1,6 +1,7 @@
/* stylelint-disable */
.statusWrap {
margin-top: 16px;
padding: 10px 12px;
margin-top: 16px;
border: 1px solid var(--semi-color-border);
border-radius: 4px;
@ -9,30 +10,13 @@
}
}
.selectedItem {
:global {
.semi-icon-close {
visibility: hidden;
color: var(--semi-color-tertiary);
}
}
&:hover {
:global {
.semi-icon-close {
visibility: visible;
}
}
}
}
.selectedItem,
.sourceItem {
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
height: 36px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 12px;
&:hover {
@ -40,8 +24,8 @@
}
.info {
margin-left: 8px;
flex-grow: 1;
margin-left: 8px;
}
.name {
@ -56,6 +40,23 @@
}
}
.selectedItem {
:global {
.semi-icon-close {
color: var(--semi-color-tertiary);
visibility: hidden;
}
}
&:hover {
:global {
.semi-icon-close {
visibility: visible;
}
}
}
}
.transferWrap {
width: 100%;
overflow: auto;

View File

@ -5,7 +5,7 @@ import { useWikiUsers } from 'data/wiki';
import { DataRender } from 'components/data-render';
import { LocaleTime } from 'components/locale-time';
import { getWikiUserRoleText } from '@think/domains';
import { useToggle } from 'hooks/useToggle';
import { useToggle } from 'hooks/use-toggle';
import { Placeholder } from './placeholder';
import { AddUser } from './add';
import { EditUser } from './edit';

View File

@ -10,76 +10,11 @@
}
}
.navItemWrap {
display: flex;
align-items: center;
justify-content: space-between;
color: var(--semi-color-text-0);
&.hoverable {
&:hover {
background-color: var(--semi-color-fill-0);
color: var(--semi-color-text-0);
}
}
&.isActive {
background-color: var(--semi-color-primary-light-default);
color: var(--semi-color-primary);
}
.navItem {
display: flex;
align-items: center;
width: 100%;
padding: 12px 16px;
font-size: 14px;
border-radius: var(--semi-border-radius-small);
cursor: pointer;
> span {
display: flex;
align-items: center;
}
.icon {
display: flex;
align-items: center;
justify-content: center;
min-width: 24px;
min-height: 24px;
margin: 0 6px 0 0;
:global {
.semi-icon-default {
font-size: 24px;
}
}
}
.title {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: var(--semi-color-text-0);
}
}
.rightWrap {
padding-right: 4px;
}
}
.docListTitle {
margin: 12px 0.5rem;
}
.treeInnerWrap {
:global {
.semi-tree-option-list-block .semi-tree-option-selected {
background-color: var(--semi-color-primary-light-default);
color: var(--semi-color-primary);
background-color: var(--semi-color-primary-light-default);
}
}
@ -103,3 +38,68 @@
}
}
}
.navItemWrap {
display: flex;
justify-content: space-between;
align-items: center;
color: var(--semi-color-text-0);
&.hoverable {
&:hover {
color: var(--semi-color-text-0);
background-color: var(--semi-color-fill-0);
}
}
&.isActive {
color: var(--semi-color-primary);
background-color: var(--semi-color-primary-light-default);
}
.navItem {
display: flex;
width: 100%;
padding: 12px 16px;
font-size: 14px;
cursor: pointer;
border-radius: var(--semi-border-radius-small);
align-items: center;
> span {
display: flex;
align-items: center;
}
.icon {
display: flex;
justify-content: center;
align-items: center;
min-width: 24px;
min-height: 24px;
margin: 0 6px 0 0;
:global {
.semi-icon-default {
font-size: 24px;
}
}
}
.title {
overflow: hidden;
color: var(--semi-color-text-0);
text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
}
}
.rightWrap {
padding-right: 4px;
}
}
.docListTitle {
margin: 12px .5rem;
}

View File

@ -3,7 +3,7 @@ import { useEffect, useState } from 'react';
import { Avatar, Button, Typography, Skeleton } from '@douyinfe/semi-ui';
import { IconPlus } from '@douyinfe/semi-icons';
import { useWikiDetail, useWikiTocs } from 'data/wiki';
import { useToggle } from 'hooks/useToggle';
import { useToggle } from 'hooks/use-toggle';
import { Seo } from 'components/seo';
import { findParents } from 'components/wiki/tocs/utils';
import { IconDocument, IconSetting, IconOverview } from 'components/icons';

View File

@ -3,9 +3,9 @@
.tocsWrap {
height: 420px;
overflow: auto;
border: 1px solid var(--semi-color-border);
border-radius: var(--border-radius);
overflow: auto;
}
.btnWrap {

View File

@ -2,7 +2,7 @@ import React, { useEffect, useState, useCallback } from 'react';
import Link from 'next/link';
import { Tree as SemiTree, Button, Typography } from '@douyinfe/semi-ui';
import { IconMore, IconPlus } from '@douyinfe/semi-icons';
import { useToggle } from 'hooks/useToggle';
import { useToggle } from 'hooks/use-toggle';
import { DocumentActions } from 'components/document/actions';
import { DocumentCreator as DocumenCreatorForm } from 'components/document/create';
import { EventEmitter } from 'helpers/event-emitter';

View File

@ -1,7 +1,7 @@
import type { IUser, IDocument } from '@think/domains';
import useSWR from 'swr';
import { useState, useCallback, useEffect } from 'react';
import { useAsyncLoading } from 'hooks/useAsyncLoading';
import { useAsyncLoading } from 'hooks/use-async-loading';
import { HttpClient } from 'services/HttpClient';
import { getPublicDocumentDetail } from 'services/document';

View File

@ -1,6 +1,6 @@
import { useEffect, useRef } from 'react';
import useSWR from 'swr';
import { useWindowSize } from 'hooks/useWindowSize';
import { useWindowSize } from 'hooks/use-window-size';
import { setStorage, getStorage } from 'helpers/storage';
const key = 'dragable-menu-width';

View File

@ -0,0 +1,35 @@
import React, { useEffect, useState } from 'react';
interface INetworkStatus {
online: boolean;
}
export const useNetwork = () => {
const [networkState, setNetworkState] = useState<INetworkStatus>({ online: navigator.onLine });
useEffect(() => {
const handleOnline = () => {
setNetworkState((prevState) => ({
...prevState,
online: true,
}));
};
const handleOffline = () => {
setNetworkState((prevState) => ({
...prevState,
online: false,
}));
};
window.addEventListener('online', handleOnline);
window.addEventListener('offline', handleOffline);
return () => {
window.removeEventListener('online', handleOnline);
window.removeEventListener('offline', handleOffline);
};
}, []);
return networkState;
};

View File

@ -1,5 +0,0 @@
import { useEffect, useLayoutEffect } from 'react';
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
export default useIsomorphicLayoutEffect;

View File

@ -1,13 +1,12 @@
.wrap {
display: flex;
flex-direction: column;
height: 100%;
background-color: var(--semi-color-nav-bg);
.contentWrap {
flex: 1;
display: flex;
flex: 1;
flex-wrap: nowrap;
overflow: hidden;
@ -32,11 +31,11 @@
.collapseBtn {
position: absolute;
z-index: 100;
top: 1rem;
right: 0;
transform: translate(50%);
z-index: 100;
opacity: 0;
transform: translate(50%);
&.isCollapsed {
opacity: 1;

View File

@ -3,7 +3,7 @@ import cls from 'classnames';
import { Layout as SemiLayout, Button } from '@douyinfe/semi-ui';
import { IconChevronLeft, IconChevronRight } from '@douyinfe/semi-icons';
import SplitPane from 'react-split-pane';
import { useDragableWidth, MIN_WIDTH, MAX_WIDTH } from 'hooks/useDragableWidth';
import { useDragableWidth, MIN_WIDTH, MAX_WIDTH } from 'hooks/use-dragable-width';
import { RouterHeader } from '../router-header';
import styles from './index.module.scss';

View File

@ -23,11 +23,11 @@
.collapseBtn {
position: absolute;
z-index: 100;
top: 1rem;
right: 0;
transform: translate(50%);
z-index: 100;
opacity: 0;
transform: translate(50%);
&.isCollapsed {
opacity: 1;

View File

@ -3,7 +3,7 @@ import cls from 'classnames';
import { Layout as SemiLayout, Button } from '@douyinfe/semi-ui';
import { IconChevronLeft, IconChevronRight } from '@douyinfe/semi-icons';
import SplitPane from 'react-split-pane';
import { useDragableWidth, MIN_WIDTH, MAX_WIDTH } from 'hooks/useDragableWidth';
import { useDragableWidth, MIN_WIDTH, MAX_WIDTH } from 'hooks/use-dragable-width';
import styles from './index.module.scss';
const { Sider, Content } = SemiLayout;

View File

@ -8,7 +8,7 @@ import { DataRender } from 'components/data-render';
import { LocaleTime } from 'components/locale-time';
import { DocumentStar } from 'components/document/star';
import { IconDocumentFill } from 'components/icons/IconDocumentFill';
import { Placeholder } from './Placeholder';
import { Placeholder } from './placeholder';
import styles from './index.module.scss';
const { Text } = Typography;

View File

@ -7,7 +7,7 @@ import { useStaredWikis, useWikiDetail } from 'data/wiki';
import { Empty } from 'components/empty';
import { DataRender } from 'components/data-render';
import { WikiStar } from 'components/wiki/star';
import { Placeholder } from './Placeholder';
import { Placeholder } from './placeholder';
import styles from './index.module.scss';
const { Text } = Typography;

View File

@ -11,22 +11,22 @@
border-radius: var(--semi-border-radius-small);
&:hover {
background-color: var(--semi-color-fill-0);
color: var(--semi-color-text-0);
background-color: var(--semi-color-fill-0);
}
.item {
display: flex;
align-items: center;
justify-content: space-between;
align-items: center;
width: 100%;
padding: 8px 16px;
.leftWrap {
display: flex;
align-items: center;
color: var(--semi-color-primary);
padding-left: 8px;
color: var(--semi-color-primary);
svg {
fill: var(--semi-color-primary);

View File

@ -8,12 +8,75 @@ import { LogoImage, LogoText } from 'components/logo';
import { Theme } from 'components/theme';
import { Message } from 'components/message';
import { Search } from 'components/search';
import { useWindowSize } from 'hooks/useWindowSize';
import { Recent } from './Recent';
import { Wiki } from './Wiki';
import { useWindowSize } from 'hooks/use-window-size';
import { Recent } from './recent';
import { Wiki } from './wiki';
const { Header: SemiHeader } = SemiLayout;
const menus = [
{
itemKey: '/',
text: (
<Link href="/">
<a></a>
</Link>
),
onClick: () => {
Router.push({
pathname: `/`,
});
},
},
{
itemKey: '/recent',
text: <Recent />,
},
{
itemKey: '/wiki',
text: <Wiki />,
},
{
itemKey: '/star',
text: (
<Link href="/star">
<a></a>
</Link>
),
onClick: () => {
Router.push({
pathname: `/star`,
});
},
},
{
itemKey: '/template',
text: (
<Link href="/template">
<a></a>
</Link>
),
onClick: () => {
Router.push({
pathname: `/template`,
});
},
},
{
itemKey: '/find',
text: (
<Link href="/find">
<a></a>
</Link>
),
onClick: () => {
Router.push({
pathname: `/find`,
});
},
},
];
export const RouterHeader: React.FC = () => {
const { pathname } = useRouter();
const windowSize = useWindowSize();
@ -30,68 +93,7 @@ export const RouterHeader: React.FC = () => {
</Space>
}
selectedKeys={[pathname || '/']}
items={[
{
itemKey: '/',
text: (
<Link href="/">
<a></a>
</Link>
),
onClick: () => {
Router.push({
pathname: `/`,
});
},
},
{
itemKey: '/recent',
text: <Recent />,
},
{
itemKey: '/wiki',
text: <Wiki />,
},
{
itemKey: '/star',
text: (
<Link href="/star">
<a></a>
</Link>
),
onClick: () => {
Router.push({
pathname: `/star`,
});
},
},
{
itemKey: '/template',
text: (
<Link href="/template">
<a></a>
</Link>
),
onClick: () => {
Router.push({
pathname: `/template`,
});
},
},
{
itemKey: '/find',
text: (
<Link href="/find">
<a></a>
</Link>
),
onClick: () => {
Router.push({
pathname: `/find`,
});
},
},
]}
items={menus}
footer={
<Space>
<WikiOrDocumentCreator />

View File

@ -2,6 +2,7 @@ import type { AppProps } from 'next/app';
import { useSafari100vh } from 'hooks/use-safari-100vh';
import 'viewerjs/dist/viewer.css';
import 'styles/globals.scss';
import 'tiptap/styles/index.scss';
function MyApp({ Component, pageProps }: AppProps) {
useSafari100vh();

View File

@ -1,9 +1,9 @@
.wikiItemWrap {
cursor: pointer;
border: 1px solid var(--semi-color-border) !important;
background-color: var(--semi-color-bg-2);
padding: 12px 16px !important;
margin: 8px 2px;
cursor: pointer;
background-color: var(--semi-color-bg-2);
border: 1px solid var(--semi-color-border) !important;
}
.titleWrap {

View File

@ -3,7 +3,7 @@ import type { IDocument } from '@think/domains';
import Link from 'next/link';
import React from 'react';
import { Typography, Button, Table, Spin, List } from '@douyinfe/semi-ui';
import { useToggle } from 'hooks/useToggle';
import { useToggle } from 'hooks/use-toggle';
import { Seo } from 'components/seo';
import { DataRender } from 'components/data-render';
import { SingleColumnLayout } from 'layouts/single-column';

View File

@ -1,30 +1,30 @@
.wrap {
position: relative;
height: 100%;
display: flex;
flex-direction: column;
height: 100%;
background-color: var(--semi-color-bg-0);
.content {
position: relative;
z-index: 10;
flex: 1;
padding: 10vh 24px;
flex: 1;
.form {
width: 100%;
max-width: 400px;
margin: 0 auto;
padding: 32px 24px;
margin: 0 auto;
border: 1px solid var(--semi-color-border);
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
footer {
margin-top: 12px;
padding-top: 16px;
text-align: center;
border-top: 1px solid var(--semi-color-border);
margin-top: 12px;
text-align: center;
}
}
}

View File

@ -1,30 +1,30 @@
.wrap {
position: relative;
height: 100%;
display: flex;
flex-direction: column;
height: 100%;
background-color: var(--semi-color-bg-0);
.content {
position: relative;
z-index: 10;
flex: 1;
padding: 10vh 24px;
flex: 1;
.form {
width: 100%;
max-width: 400px;
margin: 0 auto;
padding: 32px 24px;
margin: 0 auto;
border: 1px solid var(--semi-color-border);
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
footer {
margin-top: 12px;
padding-top: 16px;
text-align: center;
border-top: 1px solid var(--semi-color-border);
margin-top: 12px;
text-align: center;
}
}
}

View File

@ -4,7 +4,7 @@ import { Form, Button, Layout, Space, Typography, Modal } from '@douyinfe/semi-u
import { Seo } from 'components/seo';
import { LogoImage, LogoText } from 'components/logo';
import { Author } from 'components/author';
import { useAsyncLoading } from 'hooks/useAsyncLoading';
import { useAsyncLoading } from 'hooks/use-async-loading';
import { register as registerApi } from 'services/user';
import styles from './index.module.scss';

View File

@ -4,15 +4,15 @@
height: 100%;
.form {
margin: 0 auto;
width: 400px;
padding: 48px 0;
margin: 0 auto;
}
.content {
flex: 1;
overflow: hidden;
background-color: var(--semi-color-bg-0);
flex: 1;
> div {
height: 100%;

View File

@ -4,15 +4,15 @@
height: 100%;
.form {
margin: 0 auto;
width: 400px;
padding: 48px 0;
margin: 0 auto;
}
.content {
flex: 1;
overflow: hidden;
background-color: var(--semi-color-bg-0);
flex: 1;
> div {
height: 100%;

View File

@ -1,9 +1,9 @@
.wikiItemWrap {
cursor: pointer;
border: 1px solid var(--semi-color-border) !important;
background-color: var(--semi-color-bg-2);
padding: 12px 16px !important;
margin: 8px 2px;
cursor: pointer;
background-color: var(--semi-color-bg-2);
border: 1px solid var(--semi-color-border) !important;
}
.titleWrap {

View File

@ -1,13 +1,13 @@
.itemWrap {
cursor: pointer;
border: 1px solid var(--semi-color-border) !important;
background-color: var(--semi-color-bg-2);
padding: 12px 16px !important;
margin: 8px 2px;
cursor: pointer;
background-color: var(--semi-color-bg-2);
border: 1px solid var(--semi-color-border) !important;
}
.titleWrap {
display: flex;
align-items: center;
justify-content: space-between;
align-items: center;
}

View File

@ -1,21 +1,20 @@
.cardWrap {
margin: 8px 0;
display: flex;
flex-direction: column;
width: 100%;
max-height: 260px;
padding: 12px 16px 16px;
border-radius: 5px;
border: 1px solid var(--semi-color-border);
margin: 8px 0;
cursor: pointer;
border: 1px solid var(--semi-color-border);
border-radius: 5px;
flex-direction: column;
> header {
display: flex;
justify-content: space-between;
align-items: center;
color: var(--semi-color-primary);
margin-bottom: 12px;
color: var(--semi-color-primary);
.rightWrap {
opacity: 0;

View File

@ -1,24 +1,24 @@
.navItemWrap {
padding: 0 0.5rem;
padding: 0 .5rem;
.navItem {
display: flex;
align-items: center;
width: 100%;
height: 36px;
font-size: 14px;
color: var(--semi-color-text-0);
border-radius: var(--semi-border-radius-small);
cursor: pointer;
border-radius: var(--semi-border-radius-small);
align-items: center;
&:hover {
background-color: var(--semi-color-fill-0);
color: var(--semi-color-text-0);
background-color: var(--semi-color-fill-0);
}
&.isActive {
background-color: var(--semi-color-primary-light-default);
color: var(--semi-color-text-0);
background-color: var(--semi-color-primary-light-default);
}
> span {
@ -31,11 +31,11 @@
}
.title {
flex: 1;
overflow: hidden;
color: var(--semi-color-text-0);
text-overflow: ellipsis;
white-space: nowrap;
color: var(--semi-color-text-0);
flex: 1;
}
}
}

View File

@ -1,9 +1,9 @@
.wikiItemWrap {
cursor: pointer;
border: 1px solid var(--semi-color-border) !important;
background-color: var(--semi-color-bg-2);
padding: 12px 16px !important;
margin: 8px 2px;
cursor: pointer;
background-color: var(--semi-color-bg-2);
border: 1px solid var(--semi-color-border) !important;
}
.titleWrap {

Some files were not shown because too many files have changed in this diff Show More