Skip to content

Commit

Permalink
feat: implement basic components
Browse files Browse the repository at this point in the history
  • Loading branch information
fundon committed Oct 22, 2024
1 parent 1bdf67a commit 953aa36
Show file tree
Hide file tree
Showing 10 changed files with 404 additions and 52 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { ArrowDownBigIcon, PageIcon } from '@blocksuite/icons/rc';
import clsx from 'clsx';
import type { ReactElement } from 'react';

import { Button } from '../../ui/button';
import * as styles from './styles.css';

interface ErrorProps {
isPDF: boolean;
}

export const Error = (_: ErrorProps): ReactElement => {
return (
<div className={clsx([styles.body, styles.error])}>
<PageIcon />
<h3 className={styles.errorTitle}>Unable to preview this file</h3>
<p className={styles.errorMessage}>.dmg file type not supported.</p>
<div className={styles.errorBtns}>
<Button variant="primary" prefix={<ArrowDownBigIcon />}>
Download
</Button>
<Button>Retry</Button>
</div>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { type ReactElement, useState } from 'react';

import { Error } from './error';
import * as styles from './styles.css';
import { Titlebar } from './titlebar';
import { Viewer } from './viewer';

export const AttachmentViewer = (): ReactElement => {
const [isPDF] = useState(true);

return (
<div className={styles.viewerContainer}>
<Titlebar
id={'0'}
name={'AFFiNE'}
size={10}
unit={'MB'}
ext=".pdf"
zoom={100}
isPDF={isPDF}
/>
{isPDF ? <Viewer /> : <Error isPDF />}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import { cssVarV2 } from '@toeverything/theme/v2';
import { style } from '@vanilla-extract/css';

export const viewerContainer = style({
position: 'relative',
display: 'flex',
flexDirection: 'column',
width: '100%',
});

export const titlebar = style({
display: 'flex',
justifyContent: 'space-between',
height: '52px',
padding: '10px 8px',
background: cssVarV2('layer/background/primary'),
fontSize: '12px',
fontWeight: 400,
color: cssVarV2('text/secondary'),
borderTopWidth: '0.5px',
borderTopStyle: 'solid',
borderTopColor: cssVarV2('layer/insideBorder/border'),
});

export const titlebarChild = style({
selectors: {
[`${titlebar} > &`]: {
display: 'flex',
gap: '12px',
alignItems: 'center',
paddingLeft: '12px',
paddingRight: '12px',
},
'&.zoom:not(.show)': {
display: 'none',
},
},
});

export const titlebarName = style({
display: 'flex',
});

export const body = style({
display: 'flex',
flex: 1,
position: 'relative',
selectors: {
'&:before': {
position: 'absolute',
content: '',
width: '100%',
height: '100%',
zIndex: -1,
},
'&:not(.gridding):before': {
backgroundColor: cssVarV2('layer/background/secondary'),
},
'&.gridding:before': {
opacity: 0.25,
backgroundSize: '20px 20px',
backgroundImage: `linear-gradient(${cssVarV2('button/grabber/default')} 1px, transparent 1px), linear-gradient(to right, ${cssVarV2('button/grabber/default')} 1px, transparent 1px)`,
},
'&.scrollable': {
overflowY: 'auto',
},
},
});

export const error = style({
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
gap: '4px',
});

export const errorTitle = style({
fontSize: '15px',
fontWeight: 500,
lineHeight: '24px',
color: cssVarV2('text/primary'),
marginTop: '12px',
});

export const errorMessage = style({
fontSize: '12px',
fontWeight: 500,
lineHeight: '20px',
color: cssVarV2('text/tertiary'),
});

export const errorBtns = style({
display: 'flex',
flexDirection: 'column',
gap: '10px',
marginTop: '28px',
});

export const viewer = style({});

export const viewerViewport = style({});

export const viewerPage = style({
margin: '20px auto',
background: cssVarV2('layer/white'),
borderWidth: '1px',
borderStyle: 'solid',
borderColor: cssVarV2('layer/insideBorder/border'),
boxShadow:
'0px 4px 20px 0px var(--transparent-black-200, rgba(0, 0, 0, 0.10))',
});

export const thumbnails = style({
position: 'absolute',
boxSizing: 'border-box',
width: '120px',
padding: '12px',
right: '30px',
bottom: '30px',
borderRadius: '8px',
borderWidth: '1px',
borderStyle: 'solid',
borderColor: cssVarV2('layer/insideBorder/border'),
backgroundColor: cssVarV2('layer/background/primary'),
boxShadow: cssVarV2('shadow/overlayPanelShadow/2-color'),
fontSize: '12px',
fontWeight: 500,
lineHeight: '20px',
color: cssVarV2('text/secondary'),
});

export const thumbnailsPages = style({
display: 'flex',
flexDirection: 'column',
gap: '12px',
selectors: {
'&.collapsed': {
display: 'none',
},
'&:not(.collapsed)': {
marginBottom: '8px',
},
},
});

export const thumbnailsPage = style({
display: 'flex',
width: '100%',
borderRadius: '4px',
borderWidth: '1px',
borderStyle: 'solid',
borderColor: cssVarV2('layer/insideBorder/border'),
selectors: {
'&.selected': {
borderColor: '#29A3FA',
},
},
});

export const thumbnailsIndicator = style({
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { CollapseIcon, ExpandIcon } from '@blocksuite/icons/rc';
import clsx from 'clsx';
import { type ReactElement,useState } from 'react';

import { IconButton } from '../../ui/button';
import * as styles from './styles.css';

export const Thumbnails = (): ReactElement => {
const [collapsed, setCollapsed] = useState(true);

return (
<div className={styles.thumbnails}>
<div
className={clsx([
styles.thumbnailsPages,
{
collapsed,
},
])}
>
<div className={styles.thumbnailsPage} style={{ height: '80px' }}></div>
<div
className={clsx([
styles.thumbnailsPage,
{
selected: true,
},
])}
style={{ height: '80px' }}
></div>
<div className={styles.thumbnailsPage} style={{ height: '80px' }}></div>
</div>
<div className={styles.thumbnailsIndicator}>
<div>
<span>1</span>/<span>3</span>
</div>
<IconButton
icon={collapsed ? <CollapseIcon /> : <ExpandIcon />}
onClick={() => setCollapsed(state => !state)}
/>
</div>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ZoomDownIcon,
ZoomUpIcon,
} from '@blocksuite/icons/rc';
import clsx from 'clsx';
import { useState } from 'react';

import { IconButton } from '../../ui/button';
Expand All @@ -16,7 +17,9 @@ export interface TitlebarProps {
name: string;
ext: string;
size: number;
unit: string;
zoom: number;
isPDF: boolean;
}

const items = [
Expand All @@ -39,7 +42,14 @@ export const MenuItems = () =>
</MenuItem>
));

export const Titlebar = ({ name, ext, size, zoom = 100 }: TitlebarProps) => {
export const Titlebar = ({
name,
ext,
size,
unit,
isPDF = false,
zoom = 100,
}: TitlebarProps) => {
const [openMenu, setOpenMenu] = useState(false);

return (
Expand All @@ -49,7 +59,10 @@ export const Titlebar = ({ name, ext, size, zoom = 100 }: TitlebarProps) => {
<div>{name}</div>
<span>{ext}</span>
</div>
<div>{size}MB</div>
<div>
{size}
{unit}
</div>
<IconButton icon={<LocalDataIcon />}></IconButton>
<Menu
items={<MenuItems />}
Expand All @@ -59,13 +72,22 @@ export const Titlebar = ({ name, ext, size, zoom = 100 }: TitlebarProps) => {
}}
contentOptions={{
side: 'bottom',
align: 'center',
avoidCollisions: false,
}}
>
<IconButton icon={<MoreHorizontalIcon />}></IconButton>
</Menu>
</div>
<div className={styles.titlebarChild}>
<div
className={clsx([
styles.titlebarChild,
'zoom',
{
show: isPDF,
},
])}
>
<IconButton icon={<ZoomDownIcon />}></IconButton>
<div>{zoom}%</div>
<IconButton icon={<ZoomUpIcon />}></IconButton>
Expand Down
Loading

0 comments on commit 953aa36

Please sign in to comment.