diff --git a/package.json b/package.json index bb2e8ca234..473d139eb3 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,8 @@ }, "pnpm": { "patchedDependencies": { - "@tauri-apps/api@1.2.0": "patches/@tauri-apps__api@1.2.0.patch" + "@tauri-apps/api@1.2.0": "patches/@tauri-apps__api@1.2.0.patch", + "next@13.1.0": "patches/next@13.1.0.patch" } } } diff --git a/packages/app/package.json b/packages/app/package.json index 39dcfda30e..236d8ca3b3 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -12,19 +12,19 @@ "@affine/component": "workspace:*", "@affine/datacenter": "workspace:*", "@affine/i18n": "workspace:*", - "@blocksuite/blocks": "0.4.0-alpha.2", - "@blocksuite/editor": "0.4.0-alpha.2", + "@blocksuite/blocks": "0.4.0-20230210031655-264744e", + "@blocksuite/editor": "0.4.0-20230210031655-264744e", "@blocksuite/icons": "^2.0.2", - "@blocksuite/store": "0.4.0-alpha.2", + "@blocksuite/store": "0.4.0-20230210031655-264744e", "@emotion/css": "^11.10.5", "@emotion/react": "^11.10.5", "@emotion/server": "^11.10.0", "@emotion/styled": "^11.10.5", "@fontsource/poppins": "^4.5.10", "@fontsource/space-mono": "^4.5.10", - "@mui/base": "=5.0.0-alpha.101", - "@mui/icons-material": "=5.10.9", - "@mui/material": "=5.8.6", + "@mui/base": "=5.0.0-alpha.117", + "@mui/icons-material": "=5.11.0", + "@mui/material": "=5.11.8", "@toeverything/pathfinder-logger": "workspace:@affine/logger@*", "cmdk": "^0.1.20", "css-spring": "^4.1.0", @@ -37,7 +37,8 @@ "quill-cursors": "^4.0.0", "react": "18.2.0", "react-dom": "18.2.0", - "yjs": "^13.5.45" + "yjs": "^13.5.45", + "zustand": "^4.3.2" }, "devDependencies": { "@types/node": "18.7.18", diff --git a/packages/app/src/components/editor/index.tsx b/packages/app/src/components/editor/index.tsx index 176777f86f..46ea39204c 100644 --- a/packages/app/src/components/editor/index.tsx +++ b/packages/app/src/components/editor/index.tsx @@ -22,15 +22,26 @@ export const Editor = ({ page, workspace, setEditor }: Props) => { const editorContainer = useRef(null); // const { currentWorkspace, currentPage, setEditor } = useAppState(); useEffect(() => { + let blockHubElement: HTMLElement | null = null; const ret = () => { const node = editorContainer.current; while (node?.firstChild) { node.removeChild(node.firstChild); } + + blockHubElement?.remove(); }; const editor = new EditorContainer(); editor.page = page; + editor.createBlockHub().then(blockHub => { + const toolWrapper = document.querySelector('#toolWrapper'); + if (!toolWrapper) { + throw new Error('Can not find toolWrapper'); + } + blockHubElement = blockHub; + toolWrapper.appendChild(blockHub); + }); editorContainer.current?.appendChild(editor); if (page.isEmpty) { const isFirstPage = workspace?.meta.pageMetas.length === 1; diff --git a/packages/app/src/components/header/QuickSearchButton.tsx b/packages/app/src/components/header/QuickSearchButton.tsx index 9b73c096f6..d32be2c03f 100644 --- a/packages/app/src/components/header/QuickSearchButton.tsx +++ b/packages/app/src/components/header/QuickSearchButton.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { IconButton, IconButtonProps } from '@affine/component'; import { ArrowDownIcon } from '@blocksuite/icons'; -import { useModal } from '@/providers/GlobalModalProvider'; +import { useModal } from '@/store/globalModal'; import { styled } from '@affine/component'; const StyledIconButtonWithAnimate = styled(IconButton)(({ theme }) => { diff --git a/packages/app/src/components/header/header-right-items/SyncUser.tsx b/packages/app/src/components/header/header-right-items/SyncUser.tsx index 0cedea6fec..8724f6b42b 100644 --- a/packages/app/src/components/header/header-right-items/SyncUser.tsx +++ b/packages/app/src/components/header/header-right-items/SyncUser.tsx @@ -1,5 +1,5 @@ import { CloudUnsyncedIcon } from '@blocksuite/icons'; -import { useModal } from '@/providers/GlobalModalProvider'; +import { useModal } from '@/store/globalModal'; import { useAppState } from '@/providers/app-state-provider'; import { IconButton } from '@affine/component'; diff --git a/packages/app/src/components/help-island/Icons.tsx b/packages/app/src/components/help-island/Icons.tsx index 7c8797265d..427e078dc8 100644 --- a/packages/app/src/components/help-island/Icons.tsx +++ b/packages/app/src/components/help-island/Icons.tsx @@ -1,16 +1,16 @@ export const HelpIcon = () => { return ( ); diff --git a/packages/app/src/components/help-island/index.tsx b/packages/app/src/components/help-island/index.tsx index 4f7b126843..0f01f27132 100644 --- a/packages/app/src/components/help-island/index.tsx +++ b/packages/app/src/components/help-island/index.tsx @@ -2,85 +2,71 @@ import { useState } from 'react'; import { StyledIsland, StyledIconWrapper, - StyledIslandWrapper, - StyledTransformIcon, + StyledAnimateWrapper, + StyledTriggerWrapper, } from './style'; import { CloseIcon, ContactIcon, HelpIcon, KeyboardIcon } from './Icons'; -import { MuiGrow } from '@affine/component'; import { Tooltip } from '@affine/component'; + import { useTranslation } from '@affine/i18n'; -import { useModal } from '@/providers/GlobalModalProvider'; -import { useTheme } from '@/providers/ThemeProvider'; -import useCurrentPageMeta from '@/hooks/use-current-page-meta'; +import { useModal } from '@/store/globalModal'; +import { MuiFade } from '@affine/component'; export type IslandItemNames = 'contact' | 'shortcuts'; export const HelpIsland = ({ showList = ['contact', 'shortcuts'], }: { showList?: IslandItemNames[]; }) => { - const [showContent, setShowContent] = useState(false); - const { mode } = useTheme(); - const { mode: editorMode } = useCurrentPageMeta() || {}; + const [spread, setShowSpread] = useState(false); const { triggerShortcutsModal, triggerContactModal } = useModal(); - const isEdgelessDark = mode === 'dark' && editorMode === 'edgeless'; const { t } = useTranslation(); return ( - <> - { - setShowContent(true); - }} - onMouseLeave={() => { - setShowContent(false); - }} - > - - - {showList.includes('contact') && ( - - { - setShowContent(false); - triggerContactModal(); - }} - > - - - - )} - {showList.includes('shortcuts') && ( - - { - setShowContent(false); - triggerShortcutsModal(); - }} - > - - - - )} - - + { + setShowSpread(!spread); + }} + > + + {showList.includes('contact') && ( + + { + setShowSpread(false); + triggerContactModal(); + }} + > + + + + )} + {showList.includes('shortcuts') && ( + + { + setShowSpread(false); + triggerShortcutsModal(); + }} + > + + + + )} + -
- - - - - - -
-
- + + + + + + + + + + +
); }; diff --git a/packages/app/src/components/help-island/style.ts b/packages/app/src/components/help-island/style.ts index 46b2e271ac..9095344182 100644 --- a/packages/app/src/components/help-island/style.ts +++ b/packages/app/src/components/help-island/style.ts @@ -1,71 +1,77 @@ -import { displayFlex, styled } from '@affine/component'; +import { displayFlex, positionAbsolute, styled } from '@affine/component'; -export const StyledIsland = styled('div')(({ theme }) => { +export const StyledIsland = styled('div')<{ + spread: boolean; +}>(({ theme, spread }) => { return { - width: '32px', - height: '32px', - color: theme.colors.iconColor, - position: 'fixed', - right: '30px', - bottom: '30px', - borderRadius: '50%', - zIndex: theme.zIndex.popover, - }; -}); -export const StyledTransformIcon = styled('div', { - shouldForwardProp: prop => prop !== 'in', -})<{ in: boolean }>(({ in: isIn, theme }) => ({ - height: '32px', - width: '32px', - borderRadius: '50%', - position: 'absolute', - left: '0', - right: '0', - bottom: '0', - top: '0', - margin: 'auto', - ...displayFlex('center', 'center'), - opacity: isIn ? 1 : 0, - backgroundColor: isIn - ? theme.colors.hoverBackground - : theme.colors.pageBackground, -})); -export const StyledIconWrapper = styled('div')<{ isEdgelessDark: boolean }>( - ({ theme, isEdgelessDark }) => { - return { - color: isEdgelessDark - ? theme.colors.popoverBackground - : theme.colors.iconColor, - marginBottom: '24px', - ...displayFlex('center', 'center'), - cursor: 'pointer', - backgroundColor: isEdgelessDark - ? 'transparent' - : theme.colors.pageBackground, - borderRadius: '50%', - width: '32px', - height: '32px', - transition: 'background-color 0.3s', - position: 'relative', - ':hover': { - color: isEdgelessDark - ? theme.colors.iconColor - : theme.colors.primaryColor, - backgroundColor: theme.colors.hoverBackground, - }, - }; - } -); - -export const StyledIslandWrapper = styled('div')(({ theme }) => { - return { - position: 'absolute', - bottom: '100%', - left: '0', - width: '100%', - color: theme.colors.iconColor, + transition: 'box-shadow 0.2s', + width: '44px', + position: 'relative', + boxShadow: spread + ? '4px 4px 7px rgba(58, 76, 92, 0.04), -4px -4px 13px rgba(58, 76, 92, 0.02), 6px 6px 36px rgba(58, 76, 92, 0.06)' + : 'unset', + padding: '0 4px 44px', + borderRadius: '10px', + backgroundColor: theme.colors.pageBackground, ':hover': { - color: theme.colors.popoverColor, + boxShadow: + '4px 4px 7px rgba(58, 76, 92, 0.04), -4px -4px 13px rgba(58, 76, 92, 0.02), 6px 6px 36px rgba(58, 76, 92, 0.06)', + }, + '::after': { + content: '""', + width: '36px', + height: '1px', + background: spread ? theme.colors.borderColor : 'transparent', + ...positionAbsolute({ + left: 0, + right: 0, + bottom: '44px', + }), + margin: 'auto', + transition: 'background 0.15s', + }, + }; +}); +export const StyledIconWrapper = styled('div')(({ theme }) => { + return { + color: theme.colors.iconColor, + ...displayFlex('center', 'center'), + cursor: 'pointer', + backgroundColor: theme.colors.pageBackground, + borderRadius: '5px', + width: '36px', + height: '36px', + margin: '4px auto 4px', + transition: 'background-color 0.2s', + position: 'relative', + ':hover': { + color: theme.colors.primaryColor, + backgroundColor: theme.colors.hoverBackground, + }, + }; +}); + +export const StyledAnimateWrapper = styled('div', { + shouldForwardProp: prop => prop !== 'spread', +})<{ spread: boolean }>(({ spread }) => ({ + height: spread ? '88px' : '0', + transition: 'height 0.2s cubic-bezier(0, 0, 0.55, 1.6)', + overflow: 'hidden', +})); + +export const StyledTriggerWrapper = styled('div')(({ theme }) => { + return { + width: '36px', + height: '36px', + cursor: 'pointer', + backgroundColor: theme.colors.pageBackground, + color: theme.colors.iconColor, + borderRadius: '5px', + ...displayFlex('center', 'center'), + ...positionAbsolute({ left: '4px', bottom: '4px' }), + ':hover': { + color: theme.colors.primaryColor, + backgroundColor: theme.colors.hoverBackground, }, }; }); diff --git a/packages/app/src/components/quick-search/index.tsx b/packages/app/src/components/quick-search/index.tsx index 3ca942444a..5df443c0a1 100644 --- a/packages/app/src/components/quick-search/index.tsx +++ b/packages/app/src/components/quick-search/index.tsx @@ -11,7 +11,7 @@ import { Results } from './Results'; import { Footer } from './Footer'; import { Command } from 'cmdk'; import { useEffect, useState } from 'react'; -import { useModal } from '@/providers/GlobalModalProvider'; +import { useModal } from '@/store/globalModal'; import { getUaHelper } from '@/utils'; import { useRouter } from 'next/router'; import { PublishedResults } from './PublishedResults'; diff --git a/packages/app/src/components/workspace-layout/index.tsx b/packages/app/src/components/workspace-layout/index.tsx index b77d86fada..eca2b6bbb0 100644 --- a/packages/app/src/components/workspace-layout/index.tsx +++ b/packages/app/src/components/workspace-layout/index.tsx @@ -1,7 +1,7 @@ import HelpIsland from '@/components/help-island'; import { WorkSpaceSliderBar } from '@/components/workspace-slider-bar'; import { useRouter } from 'next/router'; -import { StyledPage, StyledWrapper } from './styles'; +import { StyledPage, StyledToolWrapper, StyledWrapper } from './styles'; import { PropsWithChildren } from 'react'; import useEnsureWorkspace from '@/hooks/use-ensure-workspace'; import { PageLoading } from '@/components/loading'; @@ -19,7 +19,14 @@ export const WorkspaceLayout = ({ children }: PropsWithChildren) => { {children} - + +
+ {/* Slot for block hub */} +
+ +
); diff --git a/packages/app/src/components/workspace-layout/styles.ts b/packages/app/src/components/workspace-layout/styles.ts index 4c246db801..979f342dfd 100644 --- a/packages/app/src/components/workspace-layout/styles.ts +++ b/packages/app/src/components/workspace-layout/styles.ts @@ -16,3 +16,12 @@ export const StyledWrapper = styled('div')(() => { position: 'relative', }; }); + +export const StyledToolWrapper = styled('div')(({ theme }) => { + return { + position: 'fixed', + right: '30px', + bottom: '30px', + zIndex: theme.zIndex.popover, + }; +}); diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/LoginItem.tsx b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/LoginItem.tsx index 7ea99ecce4..a000de38f6 100644 --- a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/LoginItem.tsx +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/LoginItem.tsx @@ -1,4 +1,4 @@ -import { useModal } from '@/providers/GlobalModalProvider'; +import { useModal } from '@/store/globalModal'; import { styled } from '@affine/component'; import { AffineIcon } from '../../icons/Icons'; import { diff --git a/packages/app/src/components/workspace-slider-bar/index.tsx b/packages/app/src/components/workspace-slider-bar/index.tsx index 5c98f28ff3..7507569fd2 100644 --- a/packages/app/src/components/workspace-slider-bar/index.tsx +++ b/packages/app/src/components/workspace-slider-bar/index.tsx @@ -23,7 +23,7 @@ import { import Link from 'next/link'; import { MuiCollapse } from '@affine/component'; import { Tooltip } from '@affine/component'; -import { useModal } from '@/providers/GlobalModalProvider'; +import { useModal } from '@/store/globalModal'; import { useAppState } from '@/providers/app-state-provider'; import { IconButton } from '@affine/component'; import useLocalStorage from '@/hooks/use-local-storage'; diff --git a/packages/app/src/pages/_app.tsx b/packages/app/src/pages/_app.tsx index 00b2dcf3b2..da52f88833 100644 --- a/packages/app/src/pages/_app.tsx +++ b/packages/app/src/pages/_app.tsx @@ -12,7 +12,7 @@ import type { PropsWithChildren, ReactElement, ReactNode } from 'react'; import type { NextPage } from 'next'; import { AppStateProvider } from '@/providers/app-state-provider'; import ConfirmProvider from '@/providers/ConfirmProvider'; -import { ModalProvider } from '@/providers/GlobalModalProvider'; +import { ModalProvider } from '@/store/globalModal'; // import AppStateProvider2 from '@/providers/app-state-provider2/provider'; import { useRouter } from 'next/router'; @@ -21,6 +21,8 @@ import { useAppState } from '@/providers/app-state-provider'; import { PageLoading } from '@/components/loading'; import Head from 'next/head'; import '@affine/i18n'; +import { useTranslation } from '@affine/i18n'; +import React from 'react'; const ThemeProvider = dynamic(() => import('@/providers/ThemeProvider'), { ssr: false, @@ -39,6 +41,11 @@ type AppPropsWithLayout = AppProps & { const App = ({ Component, pageProps }: AppPropsWithLayout) => { const getLayout = Component.getLayout || (page => page); + const { i18n } = useTranslation(); + + React.useEffect(() => { + document.documentElement.lang = i18n.language; + }, [i18n.language]); return ( <> diff --git a/packages/app/src/pages/public-workspace/[workspaceId]/[pageId].tsx b/packages/app/src/pages/public-workspace/[workspaceId]/[pageId].tsx index 4ccda04b71..8411740687 100644 --- a/packages/app/src/pages/public-workspace/[workspaceId]/[pageId].tsx +++ b/packages/app/src/pages/public-workspace/[workspaceId]/[pageId].tsx @@ -11,7 +11,7 @@ import { IconButton } from '@affine/component'; import NextLink from 'next/link'; import { PaperIcon, SearchIcon } from '@blocksuite/icons'; import { WorkspaceUnitAvatar } from '@/components/workspace-avatar'; -import { useModal } from '@/providers/GlobalModalProvider'; +import { useModal } from '@/store/globalModal'; const DynamicBlocksuite = dynamic(() => import('@/components/editor'), { ssr: false, diff --git a/packages/app/src/pages/public-workspace/[workspaceId]/index.tsx b/packages/app/src/pages/public-workspace/[workspaceId]/index.tsx index 37aaa7317d..4640d595fe 100644 --- a/packages/app/src/pages/public-workspace/[workspaceId]/index.tsx +++ b/packages/app/src/pages/public-workspace/[workspaceId]/index.tsx @@ -11,7 +11,7 @@ import { import { Breadcrumbs } from '@affine/component'; import { WorkspaceUnitAvatar } from '@/components/workspace-avatar'; import { SearchIcon } from '@blocksuite/icons'; -import { useModal } from '@/providers/GlobalModalProvider'; +import { useModal } from '@/store/globalModal'; const All = () => { const { dataCenter } = useAppState(); const router = useRouter(); diff --git a/packages/app/src/pages/temporary.css b/packages/app/src/pages/temporary.css index 9bda7bdcf9..3df1e639f5 100644 --- a/packages/app/src/pages/temporary.css +++ b/packages/app/src/pages/temporary.css @@ -6,3 +6,10 @@ .affine-default-page-block-container { width: 686px !important; } + +affine-block-hub { + position: unset !important; +} +.block-hub-menu-container { + position: unset !important; +} diff --git a/packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx b/packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx index a8f6284b1d..003ec723da 100644 --- a/packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx +++ b/packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx @@ -6,7 +6,6 @@ import { useState, } from 'react'; import { EditorHeader } from '@/components/header'; -import EdgelessToolbar from '@/components/edgeless-toolbar'; import MobileModal from '@/components/mobile-modal'; import { useAppState } from '@/providers/app-state-provider'; import type { NextPageWithLayout } from '../..//_app'; @@ -43,7 +42,6 @@ const Page: NextPageWithLayout = () => { setEditor={setEditorHandler} /> )} - ); }; diff --git a/packages/app/src/providers/GlobalModalProvider.tsx b/packages/app/src/providers/GlobalModalProvider.tsx deleted file mode 100644 index 76a0365dfc..0000000000 --- a/packages/app/src/providers/GlobalModalProvider.tsx +++ /dev/null @@ -1,123 +0,0 @@ -/* eslint-disable @typescript-eslint/no-empty-function */ -import { - createContext, - useCallback, - useContext, - useEffect, - useState, -} from 'react'; -import type { PropsWithChildren } from 'react'; -import ShortcutsModal from '@/components/shortcuts-modal'; -import ContactModal from '@/components/contact-modal'; -import QuickSearch from '@/components/quick-search'; -import { ImportModal } from '@/components/import'; -import { LoginModal } from '@/components/login-modal'; - -type ModalContextValue = { - triggerShortcutsModal: () => void; - triggerContactModal: () => void; - triggerQuickSearchModal: (visible?: boolean) => void; - triggerImportModal: () => void; - triggerLoginModal: () => void; -}; -type ModalContextProps = PropsWithChildren>; -type ModalMap = { - contact: boolean; - shortcuts: boolean; - quickSearch: boolean; - import: boolean; - login: boolean; -}; - -export const ModalContext = createContext({ - triggerShortcutsModal: () => {}, - triggerContactModal: () => {}, - triggerQuickSearchModal: () => {}, - triggerImportModal: () => {}, - triggerLoginModal: () => {}, -}); - -export const useModal = () => useContext(ModalContext); - -export const ModalProvider = ({ - children, -}: PropsWithChildren) => { - const [modalMap, setModalMap] = useState({ - contact: false, - shortcuts: false, - quickSearch: false, - import: false, - login: false, - }); - - const triggerHandler = useCallback( - (key: keyof ModalMap, visible?: boolean) => { - setModalMap({ - ...modalMap, - [key]: visible ?? !modalMap[key], - }); - }, - [modalMap] - ); - useEffect(() => { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - window.triggerHandler = () => triggerHandler('login'); - }, [triggerHandler]); - - return ( - { - triggerHandler('shortcuts'); - }, - triggerContactModal: () => { - triggerHandler('contact'); - }, - triggerQuickSearchModal: (visible?) => { - triggerHandler('quickSearch', visible); - }, - triggerImportModal: () => { - triggerHandler('import'); - }, - triggerLoginModal: () => { - triggerHandler('login'); - }, - }} - > - { - triggerHandler('contact', false); - }} - > - { - triggerHandler('shortcuts', false); - }} - > - { - triggerHandler('quickSearch', false); - }} - > - { - triggerHandler('import', false); - }} - > - { - triggerHandler('login', false); - }} - /> - {children} - - ); -}; - -export default ModalProvider; diff --git a/packages/app/src/store/globalModal/index.tsx b/packages/app/src/store/globalModal/index.tsx new file mode 100644 index 0000000000..337a8fff6f --- /dev/null +++ b/packages/app/src/store/globalModal/index.tsx @@ -0,0 +1,146 @@ +import type React from 'react'; +import { createContext, useCallback, useContext, useMemo } from 'react'; +import { createStore, useStore } from 'zustand'; +import { combine, subscribeWithSelector } from 'zustand/middleware'; +import { UseBoundStore } from 'zustand/react'; +import ContactModal from '@/components/contact-modal'; +import ShortcutsModal from '@/components/shortcuts-modal'; +import QuickSearch from '@/components/quick-search'; +import { LoginModal } from '@/components/login-modal'; +import ImportModal from '@/components/import'; + +export type ModalState = { + contact: boolean; + shortcuts: boolean; + quickSearch: boolean; + import: boolean; + login: boolean; +}; + +export type ModalActions = { + triggerShortcutsModal: () => void; + triggerContactModal: () => void; + triggerQuickSearchModal: (visible?: boolean) => void; + triggerImportModal: () => void; + triggerLoginModal: () => void; +}; + +const create = () => + createStore( + subscribeWithSelector( + combine( + { + contact: false, + shortcuts: false, + quickSearch: false, + import: false, + login: false, + }, + set => ({ + triggerShortcutsModal: () => { + set(({ shortcuts }) => ({ + shortcuts: !shortcuts, + })); + }, + triggerContactModal: () => { + set(({ contact }) => ({ + contact: !contact, + })); + }, + triggerQuickSearchModal: (visible?: boolean) => { + set(({ quickSearch }) => ({ + quickSearch: visible ?? !quickSearch, + })); + }, + triggerImportModal: () => { + set(state => ({ + import: !state.import, + })); + }, + triggerLoginModal: () => { + set(({ login }) => ({ + login: !login, + })); + }, + }) + ) + ) + ); +type Store = ReturnType; + +const ModalContext = createContext(null); + +export const useModalApi = () => { + const api = useContext(ModalContext); + if (!api) { + throw new Error('cannot find modal context'); + } + return api; +}; + +export const useModal: UseBoundStore = (( + selector: Parameters>[0], + equals: Parameters>[1] +) => { + const api = useModalApi(); + return useStore(api, selector, equals); + // eslint-disable-next-line @typescript-eslint/no-explicit-any +}) as any; + +const Modals: React.FC = function Modal() { + const api = useModalApi(); + return ( + <> + state.contact)} + onClose={useCallback(() => { + api.setState({ + contact: false, + }); + }, [api])} + > + state.shortcuts)} + onClose={useCallback(() => { + api.setState({ + shortcuts: false, + }); + }, [api])} + > + state.quickSearch)} + onClose={useCallback(() => { + api.setState({ + quickSearch: false, + }); + }, [api])} + > + state.import)} + onClose={useCallback(() => { + api.setState({ + import: false, + }); + }, [api])} + > + state.login)} + onClose={useCallback(() => { + api.setState({ + login: false, + }); + }, [api])} + /> + + ); +}; + +export const ModalProvider: React.FC = + function ModelProvider({ children }) { + return ( + create(), [])}> + + {children} + + ); + }; diff --git a/packages/component/.storybook/preview.js b/packages/component/.storybook/preview.js index d3914580a7..e574a19ca1 100644 --- a/packages/component/.storybook/preview.js +++ b/packages/component/.storybook/preview.js @@ -1,3 +1,5 @@ +import { getLightTheme, ThemeProvider } from '../src'; + export const parameters = { actions: { argTypesRegex: '^on[A-Z].*' }, controls: { @@ -7,3 +9,15 @@ export const parameters = { }, }, }; + +const lightTheme = getLightTheme('page'); + +export const decorators = [ + Story => { + return ( + + + + ); + }, +]; diff --git a/packages/component/package.json b/packages/component/package.json index 4cf948d9c3..a04e1bdb40 100644 --- a/packages/component/package.json +++ b/packages/component/package.json @@ -8,13 +8,13 @@ }, "dependencies": { "@affine/i18n": "workspace:*", - "@blocksuite/editor": "0.4.0-alpha.2", + "@blocksuite/editor": "0.4.0-20230209191848-0a912e3", "@blocksuite/icons": "^2.0.2", "@emotion/react": "^11.10.5", "@emotion/styled": "^11.10.5", - "@mui/base": "=5.0.0-alpha.101", - "@mui/icons-material": "=5.10.9", - "@mui/material": "=5.8.6", + "@mui/base": "=5.0.0-alpha.117", + "@mui/icons-material": "=5.11.0", + "@mui/material": "=5.11.8", "lit": "^2.6.1", "react": "^18.2.0", "react-dom": "^18.2.0" diff --git a/packages/component/src/stories/Breadcrumbs.stories.tsx b/packages/component/src/stories/Breadcrumbs.stories.tsx index 38334b1793..6cc0ba07d4 100644 --- a/packages/component/src/stories/Breadcrumbs.stories.tsx +++ b/packages/component/src/stories/Breadcrumbs.stories.tsx @@ -1,19 +1,25 @@ -import React, { useMemo } from 'react'; +/* deepscan-disable USELESS_ARROW_FUNC_BIND */ +import React from 'react'; import { Meta, Story } from '@storybook/react'; -import { Breadcrumbs, getLightTheme, ThemeProvider } from '..'; +import { Breadcrumbs } from '..'; +import { Link, Typography } from '@mui/material'; export default { title: 'AFFiNE/Breadcrumbs', component: Breadcrumbs, } as Meta; -const Template: Story = args => ( - getLightTheme('page'), [])}> - - -); +const Template: Story = args => ; -export const Primary = Template.bind({}); +export const Primary = Template.bind(undefined); Primary.args = { - children: [1, 2, 3], + children: [ + + AFFiNE + , + + Docs + , + Introduction, + ], }; diff --git a/packages/component/src/stories/Button.stories.tsx b/packages/component/src/stories/Button.stories.tsx index 9fc32156e1..7030f37128 100644 --- a/packages/component/src/stories/Button.stories.tsx +++ b/packages/component/src/stories/Button.stories.tsx @@ -1,20 +1,46 @@ -import React, { useMemo } from 'react'; +/* deepscan-disable USELESS_ARROW_FUNC_BIND */ +import React from 'react'; import { Meta, Story } from '@storybook/react'; -import { Button, getLightTheme, ThemeProvider } from '..'; +import { Button } from '..'; +import { ButtonProps } from '../ui/button/interface'; export default { title: 'AFFiNE/Button', component: Button, -} as Meta; + argTypes: { + hoverBackground: { control: 'color' }, + hoverColor: { control: 'color' }, + }, +} as Meta; -const Template: Story = args => ( - getLightTheme('page'), [])}> -