From ef61f1bdf3bc657e6f82baec11370db73be1180a Mon Sep 17 00:00:00 2001 From: fantasticit Date: Wed, 4 May 2022 14:50:58 +0800 Subject: [PATCH] refactor: improve mobile ux --- .eslintrc.client.js | 2 +- .../document/collaboration/index.tsx | 1 - .../document/editor/index.module.scss | 6 +- .../src/components/document/editor/index.tsx | 37 ++- .../document/reader/index.module.scss | 18 ++ .../src/components/document/reader/index.tsx | 61 ++-- .../src/components/document/share/index.tsx | 2 - .../document/version/index.module.scss | 52 +--- .../src/components/document/version/index.tsx | 41 ++- .../src/components/emoji-picker/index.tsx | 87 +++--- .../client/src/components/message/index.tsx | 158 ++++++----- .../client/src/components/theme/index.tsx | 3 +- .../client/src/components/tooltip/index.tsx | 2 +- packages/client/src/components/user/index.tsx | 2 +- .../wiki-or-document-creator/index.tsx | 8 +- .../components/wiki/tocs/index.module.scss | 4 +- .../client/src/components/wiki/tocs/tree.tsx | 1 + .../client/src/hooks/use-dragable-width.ts | 2 +- packages/client/src/hooks/use-window-size.tsx | 5 + .../layouts/router-header/index.module.scss | 13 + .../src/layouts/router-header/index.tsx | 106 ++++--- .../src/layouts/router-header/recent.tsx | 165 ++++++----- .../client/src/layouts/router-header/wiki.tsx | 261 ++++++++++-------- .../tiptap/components/color-picker/index.tsx | 84 ++++-- .../components/color-picker/style.module.scss | 15 +- .../collaboration/collaboration/editor.tsx | 12 +- .../collaboration/index.module.scss | 18 ++ .../editor/menus/background-color/index.tsx | 8 +- .../tiptap/editor/menus/countdown/modal.tsx | 9 +- .../src/tiptap/editor/menus/iframe/bubble.tsx | 1 + .../src/tiptap/editor/menus/link/modal.tsx | 9 +- .../src/tiptap/editor/menus/search/index.tsx | 138 +++++---- .../tiptap/editor/menus/text-color/index.tsx | 8 +- 33 files changed, 813 insertions(+), 526 deletions(-) diff --git a/.eslintrc.client.js b/.eslintrc.client.js index 22bd7626..3cc8f37e 100644 --- a/.eslintrc.client.js +++ b/.eslintrc.client.js @@ -36,7 +36,7 @@ module.exports = { '@typescript-eslint/explicit-module-boundary-types': 0, '@typescript-eslint/ban-types': 0, 'react-hooks/rules-of-hooks': 2, - 'react-hooks/exhaustive-deps': 1, + 'react-hooks/exhaustive-deps': 2, 'react/prop-types': 0, 'testing-library/no-unnecessary-act': 0, 'react/react-in-jsx-scope': 0, diff --git a/packages/client/src/components/document/collaboration/index.tsx b/packages/client/src/components/document/collaboration/index.tsx index 3efb130c..95c5b939 100644 --- a/packages/client/src/components/document/collaboration/index.tsx +++ b/packages/client/src/components/document/collaboration/index.tsx @@ -128,7 +128,6 @@ export const DocumentCollaboration: React.FC = ({ wikiId, documentId }) visible={visible} onOk={handleOk} onCancel={() => toggleVisible(false)} - maskClosable={false} style={{ maxWidth: '96vw' }} footer={null} > diff --git a/packages/client/src/components/document/editor/index.module.scss b/packages/client/src/components/document/editor/index.module.scss index 45308925..637c96d6 100644 --- a/packages/client/src/components/document/editor/index.module.scss +++ b/packages/client/src/components/document/editor/index.module.scss @@ -8,12 +8,14 @@ > header { position: relative; z-index: 110; - height: 60px; background-color: var(--semi-color-nav-bg); user-select: none; - > div { + .mobileToolbar { + padding: 12px 16px; overflow: auto; + text-align: center; + border-bottom: 1px solid var(--semi-color-border); } } diff --git a/packages/client/src/components/document/editor/index.tsx b/packages/client/src/components/document/editor/index.tsx index 20679587..53b767e6 100644 --- a/packages/client/src/components/document/editor/index.tsx +++ b/packages/client/src/components/document/editor/index.tsx @@ -28,7 +28,7 @@ interface IProps { } export const DocumentEditor: React.FC = ({ documentId }) => { - const { width: windowWith } = useWindowSize(); + const { width: windowWith, isMobile } = useWindowSize(); const { width, fontSize } = useDocumentStyle(); const editorWrapClassNames = useMemo(() => { return width === 'standardWidth' ? styles.isStandardWidth : styles.isFullWidth; @@ -44,6 +44,20 @@ export const DocumentEditor: React.FC = ({ documentId }) => { }); }, [document, documentId]); + const actions = ( + + {document && authority.readable && ( + + )} + + + + }> + )} - toggleVisible(false)} - maskClosable={false} style={{ maxWidth: '96vw' }} footer={ <> diff --git a/packages/client/src/components/document/version/index.module.scss b/packages/client/src/components/document/version/index.module.scss index 0df60de4..82df9f66 100644 --- a/packages/client/src/components/document/version/index.module.scss +++ b/packages/client/src/components/document/version/index.module.scss @@ -21,51 +21,23 @@ margin: 0 -24px; flex-wrap: nowrap; - > aside { - width: 240px; - height: 100%; - padding: 12px 0; - flex-shrink: 0; - border-right: 1px solid var(--semi-color-border); - overflow: auto; + :global { + .semi-navigation-inner { + flex-direction: column; - > ul { - padding: 0; - margin: 0; - list-style: none; + .semi-navigation-header-list-outer { + flex: 1; + height: calc(100% - 64px); + } - > li { - width: 100%; - padding: 12px 16px; - font-size: 14px; - color: var(--semi-color-text-0); - text-align: center; - cursor: pointer; - border-radius: var(--semi-border-radius-small); - - &:hover { - background-color: var(--semi-color-primary-light-default); - } - - &.selected { - color: var(--semi-color-primary); - background-color: var(--semi-color-primary-light-default); - } + .semi-navigation-footer { + height: 64px; } } } - > main { - padding: 24px 0; - overflow: auto; - background-color: var(--semi-color-nav-bg); - flex: 1; - - .editorWrap { - min-height: 100%; - padding: 12px 24px; - background-color: var(--semi-color-bg-2); - border: 1px solid var(--semi-color-border); - } + .selected { + color: var(--semi-color-primary); + background-color: var(--semi-color-primary-light-default); } } diff --git a/packages/client/src/components/document/version/index.tsx b/packages/client/src/components/document/version/index.tsx index 3227f81a..51d8b68c 100644 --- a/packages/client/src/components/document/version/index.tsx +++ b/packages/client/src/components/document/version/index.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect, useCallback } from 'react'; -import { Button, Modal, Typography } from '@douyinfe/semi-ui'; +import { Button, Modal, Typography, Layout, Nav } from '@douyinfe/semi-ui'; import { IconChevronLeft } from '@douyinfe/semi-icons'; import { useEditor, EditorContent } from '@tiptap/react'; import cls from 'classnames'; @@ -16,6 +16,7 @@ interface IProps { onSelect?: (data) => void; } +const { Sider, Content } = Layout; const { Title } = Typography; export const DocumentVersion: React.FC = ({ documentId, onSelect }) => { @@ -105,28 +106,40 @@ export const DocumentVersion: React.FC = ({ documentId, onSelect }) => { error={error} empty={!loading && !data.length} normalContent={() => ( -
- -
-
+ + + +
-
-
+ + )} />
diff --git a/packages/client/src/components/emoji-picker/index.tsx b/packages/client/src/components/emoji-picker/index.tsx index 8688fd6a..2886f37d 100644 --- a/packages/client/src/components/emoji-picker/index.tsx +++ b/packages/client/src/components/emoji-picker/index.tsx @@ -1,9 +1,10 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import { Popover, Typography } from '@douyinfe/semi-ui'; +import { Popover, Typography, Modal } from '@douyinfe/semi-ui'; import { EXPRESSIONES, GESTURES, SYMBOLS, OBJECTS, ACTIVITIES, SKY_WEATHER } from './constants'; import { createKeysLocalStorageLRUCache } from 'helpers/lru-cache'; import { useToggle } from 'hooks/use-toggle'; import styles from './index.module.scss'; +import { useWindowSize } from 'hooks/use-window-size'; const { Title } = Typography; @@ -41,6 +42,7 @@ interface IProps { } export const EmojiPicker: React.FC = ({ onSelectEmoji, children }) => { + const { isMobile } = useWindowSize(); const [recentUsed, setRecentUsed] = useState([]); const [visible, toggleVisible] = useToggle(false); const renderedList = useMemo( @@ -57,6 +59,30 @@ export const EmojiPicker: React.FC = ({ onSelectEmoji, children }) => { [onSelectEmoji] ); + const content = useMemo( + () => ( +
+ {renderedList.map((item, index) => { + return ( +
+ + {item.title} + +
    + {(item.data || []).map((ex) => ( +
  • selectEmoji(ex)}> + {ex} +
  • + ))} +
+
+ ); + })} +
+ ), + [isMobile, renderedList, selectEmoji] + ); + useEffect(() => { if (!visible) return; emojiLocalStorageLRUCache.syncFromStorage(); @@ -64,35 +90,34 @@ export const EmojiPicker: React.FC = ({ onSelectEmoji, children }) => { }, [visible]); return ( - - {renderedList.map((item, index) => { - return ( -
- - {item.title} - -
    - {(item.data || []).map((ex) => ( -
  • selectEmoji(ex)}> - {ex} -
  • - ))} -
-
- ); - })} - - } - > - {children} -
+ + {isMobile ? ( + <> + toggleVisible(false)} + style={{ maxWidth: '96vw' }} + > + {content} + + toggleVisible(true)}>{children} + + ) : ( + + {children} + + )} + ); }; diff --git a/packages/client/src/components/message/index.tsx b/packages/client/src/components/message/index.tsx index 90fe1ddb..357c30fa 100644 --- a/packages/client/src/components/message/index.tsx +++ b/packages/client/src/components/message/index.tsx @@ -1,6 +1,6 @@ -import React, { useEffect } from 'react'; +import React, { useCallback, useEffect } from 'react'; import Link from 'next/link'; -import { Typography, Dropdown, Badge, Button, Tabs, TabPane, Pagination, Notification } from '@douyinfe/semi-ui'; +import { Typography, Dropdown, Badge, Button, Tabs, TabPane, Pagination, Notification, Modal } from '@douyinfe/semi-ui'; import { IconMessage } from 'components/icons/IconMessage'; import { useAllMessages, useReadMessages, useUnreadMessages } from 'data/message'; import { EmptyBoxIllustration } from 'illustrations/empty-box'; @@ -9,6 +9,8 @@ import { Empty } from 'components/empty'; import { Placeholder } from './placeholder'; import styles from './index.module.scss'; import { useUser } from 'data/user'; +import { useWindowSize } from 'hooks/use-window-size'; +import { useToggle } from 'hooks/use-toggle'; const { Text } = Typography; const PAGE_SIZE = 6; @@ -84,6 +86,8 @@ const MessagesRender = ({ messageData, loading, error, onClick = null, page = 1, }; const MessageBox = () => { + const { isMobile } = useWindowSize(); + const [visible, toggleVisible] = useToggle(false); const { data: allMsgs, loading: allLoading, error: allError, page: allPage, setPage: allSetPage } = useAllMessages(); const { data: readMsgs, @@ -109,6 +113,11 @@ const MessageBox = () => { ); }; + const openModalOnMobile = useCallback(() => { + if (!isMobile) return; + toggleVisible(true); + }, [isMobile, toggleVisible]); + useEffect(() => { if (!unreadMsgs || !unreadMsgs.total) return; @@ -149,69 +158,92 @@ const MessageBox = () => { }); }, [unreadMsgs, readMessage]); - return ( - - 0 ? ( - - 全部已读 - - ) : null - } - > - - - - - - - - - - - + const content = ( + 0 ? ( + + 全部已读 + + ) : null } > - - + + + + + + + + + + + ); + + const btn = ( + diff --git a/packages/client/src/components/wiki/tocs/index.module.scss b/packages/client/src/components/wiki/tocs/index.module.scss index 952e7b6f..f8b9529d 100644 --- a/packages/client/src/components/wiki/tocs/index.module.scss +++ b/packages/client/src/components/wiki/tocs/index.module.scss @@ -13,6 +13,7 @@ .treeInnerWrap { :global { .semi-tree-option-list-block .semi-tree-option-selected { + font-weight: 600; color: var(--semi-color-primary); background-color: var(--semi-color-primary-light-default); } @@ -55,6 +56,7 @@ } &.isActive { + font-weight: 600; color: var(--semi-color-primary); background-color: var(--semi-color-primary-light-default); } @@ -90,7 +92,7 @@ .title { overflow: hidden; - color: var(--semi-color-text-0); + color: inherit; text-overflow: ellipsis; white-space: nowrap; flex: 1; diff --git a/packages/client/src/components/wiki/tocs/tree.tsx b/packages/client/src/components/wiki/tocs/tree.tsx index 485497f0..31558ba1 100644 --- a/packages/client/src/components/wiki/tocs/tree.tsx +++ b/packages/client/src/components/wiki/tocs/tree.tsx @@ -77,6 +77,7 @@ export const Tree = ({ data, docAsLink, getDocLink, parentIds, activeId, isShare ellipsis={{ showTooltip: { opts: { content: label, style: { wordBreak: 'break-all' }, position: 'right' } }, }} + style={{ color: 'inherit' }} > {label} diff --git a/packages/client/src/hooks/use-dragable-width.ts b/packages/client/src/hooks/use-dragable-width.ts index 285e6158..78e0cd5b 100644 --- a/packages/client/src/hooks/use-dragable-width.ts +++ b/packages/client/src/hooks/use-dragable-width.ts @@ -66,7 +66,7 @@ export const useDragableWidth = () => { setStorage(key, nextWidth); } mutate(); - }, [mutate, currentWidth, minWidth]); + }, [mutate, currentWidth, minWidth, maxWidth]); useEffect(() => { const min = windowWidth <= PC_MOBILE_CRITICAL_WIDTH ? DEFAULT_MOBILE_MIN_WIDTH : DEFAULT_PC_MIN_WIDTH; diff --git a/packages/client/src/hooks/use-window-size.tsx b/packages/client/src/hooks/use-window-size.tsx index 101d2631..365c4d63 100644 --- a/packages/client/src/hooks/use-window-size.tsx +++ b/packages/client/src/hooks/use-window-size.tsx @@ -3,12 +3,16 @@ import { useState, useEffect } from 'react'; interface Size { width: number | undefined; height: number | undefined; + isMobile: boolean; } +const PC_MOBILE_CRITICAL_WIDTH = 765; + export function useWindowSize(): Size { const [windowSize, setWindowSize] = useState({ width: undefined, height: undefined, + isMobile: false, }); useEffect(() => { @@ -16,6 +20,7 @@ export function useWindowSize(): Size { setWindowSize({ width: window.innerWidth, height: window.innerHeight, + isMobile: window.innerWidth <= PC_MOBILE_CRITICAL_WIDTH, }); } window.addEventListener('resize', handleResize); diff --git a/packages/client/src/layouts/router-header/index.module.scss b/packages/client/src/layouts/router-header/index.module.scss index d6929757..4d31ec37 100644 --- a/packages/client/src/layouts/router-header/index.module.scss +++ b/packages/client/src/layouts/router-header/index.module.scss @@ -40,3 +40,16 @@ } } } + +.mobileHeader { + display: flex; + width: 100%; + height: 60px; + padding-right: 24px; + padding-left: 24px; + border-right: none; + border-bottom: 1px solid var(--semi-color-border); + flex-wrap: nowrap; + align-items: center; + justify-content: space-between; +} diff --git a/packages/client/src/layouts/router-header/index.tsx b/packages/client/src/layouts/router-header/index.tsx index c1d1abf1..cfd44071 100644 --- a/packages/client/src/layouts/router-header/index.tsx +++ b/packages/client/src/layouts/router-header/index.tsx @@ -1,7 +1,7 @@ import React from 'react'; -import { Layout as SemiLayout, Nav, Space } from '@douyinfe/semi-ui'; +import { Layout as SemiLayout, Nav, Space, Typography, Dropdown, Button } from '@douyinfe/semi-ui'; +import { IconMenu } from '@douyinfe/semi-icons'; import Router, { useRouter } from 'next/router'; -import Link from 'next/link'; import { User } from 'components/user'; import { WikiOrDocumentCreator } from 'components/wiki-or-document-creator'; import { LogoImage, LogoText } from 'components/logo'; @@ -9,19 +9,18 @@ import { Theme } from 'components/theme'; import { Message } from 'components/message'; import { Search } from 'components/search'; import { useWindowSize } from 'hooks/use-window-size'; -import { Recent } from './recent'; -import { Wiki } from './wiki'; +import { useToggle } from 'hooks/use-toggle'; +import { Recent, RecentModal } from './recent'; +import { Wiki, WikiModal } from './wiki'; +import styles from './index.module.scss'; const { Header: SemiHeader } = SemiLayout; +const { Text } = Typography; const menus = [ { itemKey: '/', - text: ( - - 主页 - - ), + text: '主页', onClick: () => { Router.push({ pathname: `/`, @@ -38,11 +37,7 @@ const menus = [ }, { itemKey: '/star', - text: ( - - 收藏 - - ), + text: '收藏', onClick: () => { Router.push({ pathname: `/star`, @@ -51,11 +46,7 @@ const menus = [ }, { itemKey: '/template', - text: ( - - 模板 - - ), + text: '模板', onClick: () => { Router.push({ pathname: `/template`, @@ -64,11 +55,7 @@ const menus = [ }, { itemKey: '/find', - text: ( - - 发现 - - ), + text: '发现', onClick: () => { Router.push({ pathname: `/find`, @@ -79,22 +66,47 @@ const menus = [ export const RouterHeader: React.FC = () => { const { pathname } = useRouter(); - const windowSize = useWindowSize(); + const { width, isMobile } = useWindowSize(); + const [recentModalVisible, toggleRecentModalVisible] = useToggle(false); + const [wikiModalVisible, toggleWikiModalVisible] = useToggle(false); return ( - + + ) : ( + + )} ); }; diff --git a/packages/client/src/layouts/router-header/recent.tsx b/packages/client/src/layouts/router-header/recent.tsx index d1bb52b5..40045b66 100644 --- a/packages/client/src/layouts/router-header/recent.tsx +++ b/packages/client/src/layouts/router-header/recent.tsx @@ -1,8 +1,9 @@ import React from 'react'; import Link from 'next/link'; -import { Typography, Space, Dropdown, Tabs, TabPane } from '@douyinfe/semi-ui'; +import { Typography, Space, Dropdown, Tabs, TabPane, Modal } from '@douyinfe/semi-ui'; import { IconChevronDown } from '@douyinfe/semi-icons'; import { useRecentDocuments } from 'data/document'; +import { useToggle } from 'hooks/use-toggle'; import { Empty } from 'components/empty'; import { DataRender } from 'components/data-render'; import { LocaleTime } from 'components/locale-time'; @@ -13,78 +14,104 @@ import styles from './index.module.scss'; const { Text } = Typography; -export const Recent = () => { +export const RecentDocs = () => { const { data: recentDocs, loading, error } = useRecentDocuments(); return ( - - - - } - error={error} - normalContent={() => { - return ( -
- {recentDocs.length ? ( - recentDocs.map((doc) => { - return ( - + ); + }) + ) : ( + + )} +
+ ); + }} + /> +
+
+ ); +}; + +export const RecentModal = ({ visible, toggleVisible }) => { + return ( + + + + ); +}; + +export const RecentMobileTrigger = ({ toggleVisible }) => { + return 最近; +}; + +export const Recent = () => { + return ( + + + + + } + > + + + 最近 + + + + + ); }; diff --git a/packages/client/src/layouts/router-header/wiki.tsx b/packages/client/src/layouts/router-header/wiki.tsx index 7a313499..ba637493 100644 --- a/packages/client/src/layouts/router-header/wiki.tsx +++ b/packages/client/src/layouts/router-header/wiki.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { useRouter } from 'next/router'; import Link from 'next/link'; -import { Avatar, Typography, Space, Dropdown } from '@douyinfe/semi-ui'; +import { Avatar, Typography, Space, Dropdown, Modal } from '@douyinfe/semi-ui'; import { IconChevronDown } from '@douyinfe/semi-icons'; import { useStaredWikis, useWikiDetail } from 'data/wiki'; import { Empty } from 'components/empty'; @@ -12,11 +12,150 @@ import styles from './index.module.scss'; const { Text } = Typography; -export const Wiki = () => { +const WikiContent = () => { const { query } = useRouter(); const { data: starWikis, loading, error, refresh: refreshStarWikis } = useStaredWikis(); const { data: currentWiki } = useWikiDetail(query.wikiId); + return ( + <> + {currentWiki && ( + <> +
+ + 当前 + +
+ + + )} +
+ + 已收藏 + +
+ } + error={error} + normalContent={() => { + return ( +
+ {starWikis.length ? ( + starWikis.map((wiki) => { + return ( + + ); + }) + ) : ( + + )} +
+ ); + }} + /> + + + + ); +}; + +export const WikiModal = ({ visible, toggleVisible }) => { + return ( + + + + ); +}; + +export const Wiki = () => { return ( { paddingBottom: 8, }} > - {currentWiki && ( - <> -
- - 当前 - -
- - - )} -
- - 已收藏 - -
- } - error={error} - normalContent={() => { - return ( -
- {starWikis.length ? ( - starWikis.map((wiki) => { - return ( - - ); - }) - ) : ( - - )} -
- ); - }} - /> - - + } > diff --git a/packages/client/src/tiptap/components/color-picker/index.tsx b/packages/client/src/tiptap/components/color-picker/index.tsx index 5f6924f6..6a04ce7a 100644 --- a/packages/client/src/tiptap/components/color-picker/index.tsx +++ b/packages/client/src/tiptap/components/color-picker/index.tsx @@ -1,6 +1,8 @@ -import React from 'react'; -import { Dropdown, Typography } from '@douyinfe/semi-ui'; +import React, { useMemo } from 'react'; +import { Dropdown, Typography, Modal } from '@douyinfe/semi-ui'; import styles from './style.module.scss'; +import { useWindowSize } from 'hooks/use-window-size'; +import { useToggle } from 'hooks/use-toggle'; const { Text } = Typography; @@ -78,36 +80,60 @@ const colors = [ ]; export const ColorPicker: React.FC<{ - onSetColor; + title?: string; + onSetColor: (arg: string) => void; disabled?: boolean; -}> = ({ children, onSetColor, disabled = false }) => { +}> = ({ children, title = '颜色管理', onSetColor, disabled = false }) => { + const { isMobile } = useWindowSize(); + const [visible, toggleVisible] = useToggle(false); + + const content = useMemo( + () => ( +
+
onSetColor(null)}> + + 无颜色 +
+ +
+ {colors.map((color) => { + return ( +
onSetColor(color)}> + +
+ ); + })} +
+
+ ), + [onSetColor, isMobile] + ); + if (disabled) return {children}; return ( - -
onSetColor(null)}> - - 无颜色 -
- -
- {colors.map((color) => { - return ( -
onSetColor(color)}> - -
- ); - })} -
- - } - > - {children} -
+ + {isMobile ? ( + <> + toggleVisible(false)} + style={{ maxWidth: '96vw', width: 288 }} + > + {content} + + toggleVisible(true)}> + {children} + + + ) : ( + + {children} + + )} + ); }; diff --git a/packages/client/src/tiptap/components/color-picker/style.module.scss b/packages/client/src/tiptap/components/color-picker/style.module.scss index 336c2dcf..f9f54a70 100644 --- a/packages/client/src/tiptap/components/color-picker/style.module.scss +++ b/packages/client/src/tiptap/components/color-picker/style.module.scss @@ -1,8 +1,9 @@ .emptyWrap { display: flex; - flex-wrap: nowrap; - padding: 8px 10px; + width: 240px; cursor: pointer; + border: 1px solid transparent; + flex-wrap: nowrap; &:hover { background-color: var(--semi-color-fill-1); @@ -11,9 +12,9 @@ > span:first-child { position: relative; display: block; - width: 18px; - height: 18px; - margin-right: 8px; + width: 20px; + height: 20px; + margin: 0 8px 0 1px; border: 1px solid #e8e8e8; border-radius: 2px; @@ -34,8 +35,8 @@ .colorWrap { display: flex; flex-wrap: wrap; - width: 256px; - padding: 8px; + width: 240px; + margin-top: 8px; .colorItem { display: flex; diff --git a/packages/client/src/tiptap/editor/collaboration/collaboration/editor.tsx b/packages/client/src/tiptap/editor/collaboration/collaboration/editor.tsx index 5b3cfc27..40206ffc 100644 --- a/packages/client/src/tiptap/editor/collaboration/collaboration/editor.tsx +++ b/packages/client/src/tiptap/editor/collaboration/collaboration/editor.tsx @@ -1,18 +1,21 @@ import React, { useEffect, forwardRef, useImperativeHandle, useRef, useMemo } from 'react'; import { Toast, BackTop } from '@douyinfe/semi-ui'; import { HocuspocusProvider } from '@hocuspocus/provider'; +import cls from 'classnames'; import { debounce } from 'helpers/debounce'; import { useNetwork } from 'hooks/use-network'; import { useToggle } from 'hooks/use-toggle'; +import { useWindowSize } from 'hooks/use-window-size'; import { LogoName } from 'components/logo'; import { Banner } from 'components/banner'; -import { useEditor, EditorContent } from '../../react'; import { Collaboration } from 'tiptap/core/extensions/collaboration'; import { CollaborationCursor } from 'tiptap/core/extensions/collaboration-cursor'; import { getRandomColor } from 'helpers/color'; +import { useEditor, EditorContent } from '../../react'; import { CollaborationKit } from '../kit'; import { MenuBar } from './menubar'; import { ICollaborationEditorProps, ProviderStatus } from './type'; +import styles from './index.module.scss'; type IProps = Pick< ICollaborationEditorProps, @@ -25,6 +28,7 @@ type IProps = Pick< export const EditorInstance = forwardRef((props: IProps, ref) => { const { hocuspocusProvider, editable, user, onTitleUpdate, status, menubar, renderInEditorPortal } = props; const $mainContainer = useRef(); + const { isMobile } = useWindowSize(); const { online } = useNetwork(); const [created, toggleCreated] = useToggle(false); const editor = useEditor( @@ -98,7 +102,7 @@ export const EditorInstance = forwardRef((props: IProps, ref) => { )} {menubar && ( -
+
)} @@ -107,7 +111,9 @@ export const EditorInstance = forwardRef((props: IProps, ref) => { {protals} - {editable && menubar && $mainContainer.current} visibilityHeight={200} />} + {editable && menubar && ( + $mainContainer.current} style={{ right: 16, bottom: 65 }} visibilityHeight={200} /> + )} ); }); diff --git a/packages/client/src/tiptap/editor/collaboration/collaboration/index.module.scss b/packages/client/src/tiptap/editor/collaboration/collaboration/index.module.scss index 92d2e0ab..21398560 100644 --- a/packages/client/src/tiptap/editor/collaboration/collaboration/index.module.scss +++ b/packages/client/src/tiptap/editor/collaboration/collaboration/index.module.scss @@ -17,6 +17,24 @@ align-items: center; border-bottom: 1px solid var(--semi-color-border); user-select: none; + + &.mobileToolbar { + position: fixed; + right: 0; + bottom: 0; + left: 0; + z-index: 999; + display: flex; + height: 49px; + padding-right: env(safe-area-inset-right); + padding-bottom: env(safe-area-inset-bottom); + padding-left: env(safe-area-inset-left); + background: var(--semi-color-bg-1); + box-sizing: content-box; + justify-content: space-around; + align-items: center; + border-top: 1px solid var(--semi-color-border); + } } > main { diff --git a/packages/client/src/tiptap/editor/menus/background-color/index.tsx b/packages/client/src/tiptap/editor/menus/background-color/index.tsx index 1107ea09..7d04ed21 100644 --- a/packages/client/src/tiptap/editor/menus/background-color/index.tsx +++ b/packages/client/src/tiptap/editor/menus/background-color/index.tsx @@ -9,7 +9,7 @@ import { Title } from 'tiptap/core/extensions/title'; import { ColorPicker } from 'tiptap/components/color-picker'; const FlexStyle: React.CSSProperties = { - display: 'flex', + display: 'inline-flex', flexDirection: 'column', alignItems: 'center', }; @@ -33,16 +33,16 @@ export const BackgroundColor: React.FC<{ editor: Editor }> = ({ editor }) => { ); return ( - + + + + + + + + + + + ); + + const btn = ( + + - - - - - - - - - - } - > - - -