feat: new import page component (#3277)
This commit is contained in:
@@ -1,9 +1,14 @@
|
|||||||
import { toast } from '@affine/component';
|
import { toast, Tooltip } from '@affine/component';
|
||||||
import { BlockCard } from '@affine/component/card/block-card';
|
import { BlockCard } from '@affine/component/card/block-card';
|
||||||
import { WorkspaceCard } from '@affine/component/card/workspace-card';
|
import { WorkspaceCard } from '@affine/component/card/workspace-card';
|
||||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
import { WorkspaceFlavour } from '@affine/env/workspace';
|
||||||
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||||
import { EdgelessIcon, PageIcon } from '@blocksuite/icons';
|
import {
|
||||||
|
EdgelessIcon,
|
||||||
|
ExportToHtmlIcon,
|
||||||
|
HelpIcon,
|
||||||
|
PageIcon,
|
||||||
|
} from '@blocksuite/icons';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: 'AFFiNE/Card',
|
title: 'AFFiNE/Card',
|
||||||
@@ -48,6 +53,17 @@ export const AffineBlockCard = () => {
|
|||||||
right={<EdgelessIcon width={20} height={20} />}
|
right={<EdgelessIcon width={20} height={20} />}
|
||||||
onClick={() => toast('clicked edgeless')}
|
onClick={() => toast('clicked edgeless')}
|
||||||
/>
|
/>
|
||||||
|
<BlockCard
|
||||||
|
left={<ExportToHtmlIcon width={20} height={20} />}
|
||||||
|
title="HTML"
|
||||||
|
disabled
|
||||||
|
right={
|
||||||
|
<Tooltip content={'Learn how to Import pages into AFFiNE.'}>
|
||||||
|
<HelpIcon />
|
||||||
|
</Tooltip>
|
||||||
|
}
|
||||||
|
onClick={() => toast('click HTML')}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
19
apps/storybook/src/stories/import-page.stories.tsx
Normal file
19
apps/storybook/src/stories/import-page.stories.tsx
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/* deepscan-disable USELESS_ARROW_FUNC_BIND */
|
||||||
|
import { toast } from '@affine/component';
|
||||||
|
import { ImportPage } from '@affine/component/import-page';
|
||||||
|
import type { StoryFn } from '@storybook/react';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'AFFiNE/ImportPage',
|
||||||
|
component: ImportPage,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Template: StoryFn<typeof ImportPage> = args => <ImportPage {...args} />;
|
||||||
|
|
||||||
|
export const Basic = Template.bind(undefined);
|
||||||
|
Basic.args = {
|
||||||
|
importHtml: () => toast('Click importHtml'),
|
||||||
|
importMarkdown: () => toast('Click importMarkdown'),
|
||||||
|
importNotion: () => toast('Click importNotion'),
|
||||||
|
onClose: () => toast('Click onClose'),
|
||||||
|
};
|
||||||
@@ -9,10 +9,18 @@ export const BlockCard = forwardRef<
|
|||||||
title: string;
|
title: string;
|
||||||
desc?: string;
|
desc?: string;
|
||||||
right?: ReactNode;
|
right?: ReactNode;
|
||||||
|
disabled?: boolean;
|
||||||
} & HTMLAttributes<HTMLDivElement>
|
} & HTMLAttributes<HTMLDivElement>
|
||||||
>(({ left, title, desc, right, ...props }, ref) => {
|
>(({ left, title, desc, right, disabled, onClick, ...props }, ref) => {
|
||||||
return (
|
return (
|
||||||
<div ref={ref} className={styles.blockCard} {...props}>
|
<div
|
||||||
|
ref={ref}
|
||||||
|
className={styles.blockCard}
|
||||||
|
role="button"
|
||||||
|
aria-disabled={disabled}
|
||||||
|
onClick={disabled ? undefined : onClick}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
{left && <div className={styles.blockCardAround}>{left}</div>}
|
{left && <div className={styles.blockCardAround}>{left}</div>}
|
||||||
<div className={styles.blockCardContent}>
|
<div className={styles.blockCardContent}>
|
||||||
<div>{title}</div>
|
<div>{title}</div>
|
||||||
|
|||||||
@@ -14,6 +14,13 @@ export const blockCard = style({
|
|||||||
'&:hover': {
|
'&:hover': {
|
||||||
boxShadow: 'var(--affine-shadow-1)',
|
boxShadow: 'var(--affine-shadow-1)',
|
||||||
},
|
},
|
||||||
|
'&[aria-disabled]': {
|
||||||
|
color: 'var(--affine-text-disable-color)',
|
||||||
|
},
|
||||||
|
'&[aria-disabled]:hover': {
|
||||||
|
cursor: 'not-allowed',
|
||||||
|
boxShadow: 'none',
|
||||||
|
},
|
||||||
// TODO active styles
|
// TODO active styles
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
43
packages/component/src/components/import-page/index.css.ts
Normal file
43
packages/component/src/components/import-page/index.css.ts
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import { globalStyle, style } from '@vanilla-extract/css';
|
||||||
|
|
||||||
|
export const importPageContainerStyle = style({
|
||||||
|
position: 'relative',
|
||||||
|
display: 'flex',
|
||||||
|
width: '480px',
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
borderRadius: '16px',
|
||||||
|
boxShadow: 'var(--affine-shadow-1)',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const importPageBodyStyle = style({
|
||||||
|
display: 'flex',
|
||||||
|
padding: '32px 40px 20px 40px',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: '20px',
|
||||||
|
alignSelf: 'stretch',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const importPageButtonContainerStyle = style({
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: '1fr 1fr',
|
||||||
|
padding: '0px 40px 36px',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '20px',
|
||||||
|
alignSelf: 'stretch',
|
||||||
|
});
|
||||||
|
|
||||||
|
globalStyle(`${importPageBodyStyle} .title`, {
|
||||||
|
fontSize: 'var(--affine-font-h-6)',
|
||||||
|
fontWeight: 600,
|
||||||
|
});
|
||||||
|
|
||||||
|
globalStyle(`${importPageBodyStyle} a`, {
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
wordBreak: 'break-word',
|
||||||
|
color: 'var(--affine-link-color)',
|
||||||
|
textDecoration: 'none',
|
||||||
|
cursor: 'pointer',
|
||||||
|
});
|
||||||
76
packages/component/src/components/import-page/index.tsx
Normal file
76
packages/component/src/components/import-page/index.tsx
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import {
|
||||||
|
ExportToHtmlIcon,
|
||||||
|
ExportToMarkdownIcon,
|
||||||
|
HelpIcon,
|
||||||
|
NewIcon,
|
||||||
|
NotionIcon,
|
||||||
|
} from '@blocksuite/icons';
|
||||||
|
|
||||||
|
import { ModalCloseButton } from '../../ui/modal';
|
||||||
|
import { Tooltip } from '../../ui/tooltip';
|
||||||
|
import { BlockCard } from '../card/block-card';
|
||||||
|
import {
|
||||||
|
importPageBodyStyle,
|
||||||
|
importPageButtonContainerStyle,
|
||||||
|
importPageContainerStyle,
|
||||||
|
} from './index.css';
|
||||||
|
|
||||||
|
export const ImportPage = ({
|
||||||
|
importMarkdown,
|
||||||
|
importHtml,
|
||||||
|
importNotion,
|
||||||
|
onClose,
|
||||||
|
}: {
|
||||||
|
importMarkdown: () => void;
|
||||||
|
importHtml: () => void;
|
||||||
|
importNotion: () => void;
|
||||||
|
onClose: () => void;
|
||||||
|
}) => (
|
||||||
|
<div className={importPageContainerStyle}>
|
||||||
|
<ModalCloseButton top={6} right={6} onClick={onClose} />
|
||||||
|
<div className={importPageBodyStyle}>
|
||||||
|
<div className="title">Import</div>
|
||||||
|
<span>
|
||||||
|
AFFiNE will gradually support more and more file types for import.
|
||||||
|
<a
|
||||||
|
href="https://community.affine.pro/c/feature-requests/import-export"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>
|
||||||
|
Provide feedback.
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className={importPageButtonContainerStyle}>
|
||||||
|
<BlockCard
|
||||||
|
left={<ExportToMarkdownIcon width={20} height={20} />}
|
||||||
|
title="Markdown"
|
||||||
|
onClick={importMarkdown}
|
||||||
|
/>
|
||||||
|
<BlockCard
|
||||||
|
left={<ExportToHtmlIcon width={20} height={20} />}
|
||||||
|
title="HTML"
|
||||||
|
onClick={importHtml}
|
||||||
|
/>
|
||||||
|
<BlockCard
|
||||||
|
left={<NotionIcon width={20} height={20} />}
|
||||||
|
title="Notion"
|
||||||
|
right={
|
||||||
|
<Tooltip
|
||||||
|
content={'Learn how to Import your Notion pages into AFFiNE.'}
|
||||||
|
placement="top-start"
|
||||||
|
>
|
||||||
|
<HelpIcon width={20} height={20} />
|
||||||
|
</Tooltip>
|
||||||
|
}
|
||||||
|
onClick={importNotion}
|
||||||
|
/>
|
||||||
|
<BlockCard
|
||||||
|
left={<NewIcon width={20} height={20} />}
|
||||||
|
title="Coming soon..."
|
||||||
|
disabled
|
||||||
|
onClick={importHtml}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
Reference in New Issue
Block a user