mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 13:25:12 +00:00
init: the first public commit for AFFiNE
This commit is contained in:
98
libs/components/ui/src/button/IconButton.tsx
Normal file
98
libs/components/ui/src/button/IconButton.tsx
Normal file
@@ -0,0 +1,98 @@
|
||||
import type {
|
||||
FC,
|
||||
MouseEventHandler,
|
||||
CSSProperties,
|
||||
PropsWithChildren,
|
||||
} from 'react';
|
||||
import { styled } from '../styled';
|
||||
import { buttonStatus } from './constants';
|
||||
import { cx } from '../clsx';
|
||||
|
||||
/* Temporary solution, needs to be adjusted */
|
||||
const SIZE_SMALL = 'small' as const;
|
||||
const SIZE_MIDDLE = 'middle' as const;
|
||||
const SIZE_LARGE = 'large' as const;
|
||||
|
||||
const SIZE_CONFIG = {
|
||||
[SIZE_SMALL]: {
|
||||
iconSize: '14px',
|
||||
areaSize: '20px',
|
||||
},
|
||||
[SIZE_MIDDLE]: {
|
||||
iconSize: '20px',
|
||||
areaSize: '32px',
|
||||
},
|
||||
[SIZE_LARGE]: {
|
||||
iconSize: '24px',
|
||||
areaSize: '36px',
|
||||
},
|
||||
} as const;
|
||||
|
||||
type SizeType = keyof typeof SIZE_CONFIG;
|
||||
|
||||
interface IconButtonProps {
|
||||
onClick?: MouseEventHandler;
|
||||
disabled?: boolean;
|
||||
style?: CSSProperties;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const IconButton: FC<PropsWithChildren<IconButtonProps>> = ({
|
||||
children,
|
||||
disabled,
|
||||
onClick,
|
||||
className,
|
||||
...props
|
||||
}) => {
|
||||
return (
|
||||
<Container
|
||||
{...props}
|
||||
onClick={disabled ? undefined : onClick}
|
||||
disabled={disabled}
|
||||
className={cx({ [buttonStatus.disabled]: disabled }, className)}
|
||||
>
|
||||
{children}
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
const Container = styled('button')(({ theme }) => {
|
||||
return {
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
width: '32px',
|
||||
height: '32px',
|
||||
backgroundColor: theme.affine.palette.white,
|
||||
color: theme.affine.palette.icons,
|
||||
padding: theme.affine.spacing.iconPadding,
|
||||
borderRadius: '5px',
|
||||
|
||||
'& svg': {
|
||||
width: '20px',
|
||||
height: '20px',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
|
||||
'&:hover': {
|
||||
backgroundColor: theme.affine.palette.hover,
|
||||
},
|
||||
|
||||
[`&${buttonStatus.hover}`]: {
|
||||
backgroundColor: theme.affine.palette.hover,
|
||||
},
|
||||
|
||||
'&:focus': {
|
||||
color: theme.affine.palette.primary,
|
||||
},
|
||||
[`&.${buttonStatus.focus}`]: {
|
||||
color: theme.affine.palette.primary,
|
||||
},
|
||||
|
||||
[`&${buttonStatus.disabled}`]: {
|
||||
cursor: 'not-allowed',
|
||||
},
|
||||
};
|
||||
});
|
||||
31
libs/components/ui/src/button/base-button.ts
Normal file
31
libs/components/ui/src/button/base-button.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import ButtonUnstyled, {
|
||||
buttonUnstyledClasses,
|
||||
} from '@mui/base/ButtonUnstyled';
|
||||
import { styled } from '../styled';
|
||||
|
||||
export const BaseButton = styled(ButtonUnstyled)`
|
||||
fontFamily: 'Helvetica,Arial,"Microsoft Yahei",SimHei,sans-serif',
|
||||
font-size: 0.875rem;
|
||||
border-radius: 8px;
|
||||
padding: 4px 8px;
|
||||
transition: all 150ms ease;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
|
||||
&:hover {
|
||||
}
|
||||
|
||||
&.${buttonUnstyledClasses.active} {
|
||||
}
|
||||
|
||||
&.${buttonUnstyledClasses.focusVisible} {
|
||||
box-shadow: 0 4px 20px 0 rgba(61, 71, 82, 0.1),
|
||||
0 0 0 5px rgba(0, 127, 255, 0.5);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&.${buttonUnstyledClasses.disabled} {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
`;
|
||||
6
libs/components/ui/src/button/constants.ts
Normal file
6
libs/components/ui/src/button/constants.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export const buttonStatus = {
|
||||
hover: '.hover',
|
||||
focus: '.focus',
|
||||
active: '.focus',
|
||||
disabled: '.disabled',
|
||||
};
|
||||
3
libs/components/ui/src/button/index.ts
Normal file
3
libs/components/ui/src/button/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export { BaseButton } from './base-button';
|
||||
export { ListButton } from './list-button';
|
||||
export { IconButton } from './IconButton';
|
||||
60
libs/components/ui/src/button/list-button.tsx
Normal file
60
libs/components/ui/src/button/list-button.tsx
Normal file
@@ -0,0 +1,60 @@
|
||||
import React from 'react';
|
||||
import clsx from 'clsx';
|
||||
import style9 from 'style9';
|
||||
|
||||
import { BaseButton } from './base-button';
|
||||
import { SvgIconProps } from '../svg-icon';
|
||||
|
||||
const styles = style9.create({
|
||||
item: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
width: '220px',
|
||||
paddingLeft: '22px',
|
||||
paddingTop: '4px',
|
||||
paddingBottom: '4px',
|
||||
marginTop: '6px',
|
||||
marginBottom: '6px',
|
||||
borderRadius: '5px',
|
||||
color: '#98ACBD',
|
||||
},
|
||||
item_hover: {
|
||||
backgroundColor: 'rgba(152, 172, 189, 0.1)',
|
||||
},
|
||||
item_text: {
|
||||
fontSize: '15px',
|
||||
lineHeight: '17px',
|
||||
textAlign: 'justify',
|
||||
letterSpacing: '1.5px',
|
||||
marginLeft: '21px',
|
||||
color: '#4C6275',
|
||||
},
|
||||
});
|
||||
|
||||
type ListButtonProps = {
|
||||
className?: string;
|
||||
onClick: () => void;
|
||||
onMouseOver?: () => void;
|
||||
content?: string;
|
||||
children?: () => JSX.Element;
|
||||
hover?: boolean;
|
||||
icon?: React.FC<SvgIconProps>;
|
||||
};
|
||||
|
||||
export const ListButton = (props: ListButtonProps) => {
|
||||
const MenuIcon = props.icon;
|
||||
return (
|
||||
<BaseButton
|
||||
onClick={props.onClick}
|
||||
onMouseOver={props.onMouseOver}
|
||||
className={clsx(
|
||||
styles('item', { item_hover: props.hover }),
|
||||
props.className
|
||||
)}
|
||||
>
|
||||
{MenuIcon && <MenuIcon sx={{ width: 20, height: 20 }} />}
|
||||
<span className={styles('item_text')}>{props.content}</span>
|
||||
{props.children}
|
||||
</BaseButton>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user