mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-19 07:17:00 +08:00
feat: modify styles & ui components
This commit is contained in:
@@ -9,7 +9,7 @@ import {
|
|||||||
StyledMoreMenuItem,
|
StyledMoreMenuItem,
|
||||||
IconButton,
|
IconButton,
|
||||||
} from './styles';
|
} from './styles';
|
||||||
import { Popover } from '@/components/popover';
|
import { Popover } from '@/ui/popover';
|
||||||
import { useEditor } from '@/components/editor-provider';
|
import { useEditor } from '@/components/editor-provider';
|
||||||
import EditorModeSwitch from '@/components/editor-mode-switch';
|
import EditorModeSwitch from '@/components/editor-mode-switch';
|
||||||
import { EdgelessIcon, PaperIcon } from '../editor-mode-switch/icons';
|
import { EdgelessIcon, PaperIcon } from '../editor-mode-switch/icons';
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
UndoIcon,
|
UndoIcon,
|
||||||
RedoIcon,
|
RedoIcon,
|
||||||
} from './icons';
|
} from './icons';
|
||||||
import { Tooltip } from '@/components/tooltip';
|
import { Tooltip } from '@/ui/tooltip';
|
||||||
import Slide from '@mui/material/Slide';
|
import Slide from '@mui/material/Slide';
|
||||||
import { useEditor } from '@/components/editor-provider';
|
import { useEditor } from '@/components/editor-provider';
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
} from './style';
|
} from './style';
|
||||||
import { CloseIcon, ContactIcon, HelpIcon, KeyboardIcon } from './icons';
|
import { CloseIcon, ContactIcon, HelpIcon, KeyboardIcon } from './icons';
|
||||||
import Grow from '@mui/material/Grow';
|
import Grow from '@mui/material/Grow';
|
||||||
import { Tooltip } from '../tooltip';
|
import { Tooltip } from '@/ui/tooltip';
|
||||||
import { useEditor } from '@/components/editor-provider';
|
import { useEditor } from '@/components/editor-provider';
|
||||||
import { useModal } from '@/components/global-modal-provider';
|
import { useModal } from '@/components/global-modal-provider';
|
||||||
import { useTheme } from '@/styles';
|
import { useTheme } from '@/styles';
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
import { styled } from '@/styles';
|
|
||||||
import type { ReactNode, CSSProperties } from 'react';
|
|
||||||
import type { PopoverDirection } from './interface';
|
|
||||||
export interface PopoverContainerProps {
|
|
||||||
children?: ReactNode;
|
|
||||||
/**
|
|
||||||
* The pop-up window points to. The pop-up window has three rounded corners, one is a right angle, and the right angle is the direction of the pop-up window.
|
|
||||||
*/
|
|
||||||
direction: PopoverDirection;
|
|
||||||
style?: CSSProperties;
|
|
||||||
}
|
|
||||||
const border_radius_map: Record<PopoverContainerProps['direction'], string> = {
|
|
||||||
none: '10px',
|
|
||||||
'left-top': '0 10px 10px 10px',
|
|
||||||
'left-bottom': '10px 10px 10px 0',
|
|
||||||
'right-top': '10px 0 10px 10px',
|
|
||||||
'right-bottom': '10px 10px 0 10px',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const PopoverContainer = styled('div')<
|
|
||||||
Pick<PopoverContainerProps, 'direction'>
|
|
||||||
>(({ direction, style }) => {
|
|
||||||
const borderRadius =
|
|
||||||
border_radius_map[direction] || border_radius_map['left-top'];
|
|
||||||
return {
|
|
||||||
borderRadius: borderRadius,
|
|
||||||
...style,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
import { type CSSProperties, type PropsWithChildren } from 'react';
|
|
||||||
import { PopoverContainer } from './Container';
|
|
||||||
import { Popper, type PopperProps } from '../popper';
|
|
||||||
import { useTheme } from '@/styles';
|
|
||||||
import type { PopperPlacementType, TooltipProps } from '@mui/material';
|
|
||||||
import type { PopoverDirection } from './interface';
|
|
||||||
export const placementToContainerDirection: Record<
|
|
||||||
PopperPlacementType,
|
|
||||||
PopoverDirection
|
|
||||||
> = {
|
|
||||||
top: 'none',
|
|
||||||
'top-start': 'left-bottom',
|
|
||||||
'top-end': 'right-bottom',
|
|
||||||
right: 'none',
|
|
||||||
'right-start': 'left-top',
|
|
||||||
'right-end': 'left-bottom',
|
|
||||||
bottom: 'none',
|
|
||||||
'bottom-start': 'left-top',
|
|
||||||
'bottom-end': 'right-top',
|
|
||||||
left: 'none',
|
|
||||||
'left-start': 'right-top',
|
|
||||||
'left-end': 'right-bottom',
|
|
||||||
auto: 'none',
|
|
||||||
'auto-start': 'none',
|
|
||||||
'auto-end': 'none',
|
|
||||||
};
|
|
||||||
|
|
||||||
const useTooltipStyle = (): CSSProperties => {
|
|
||||||
const { theme, mode } = useTheme();
|
|
||||||
return {
|
|
||||||
boxShadow: '1px 1px 4px rgba(0, 0, 0, 0.14)',
|
|
||||||
padding: '4px 12px',
|
|
||||||
backgroundColor:
|
|
||||||
mode === 'dark'
|
|
||||||
? theme.colors.popoverBackground
|
|
||||||
: theme.colors.primaryColor,
|
|
||||||
color: '#fff',
|
|
||||||
fontSize: theme.font.xs,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Tooltip = (
|
|
||||||
props: PropsWithChildren<PopperProps & Omit<TooltipProps, 'title'>>
|
|
||||||
) => {
|
|
||||||
const { content, placement = 'top-start' } = props;
|
|
||||||
const style = useTooltipStyle();
|
|
||||||
// If there is no content, hide forever
|
|
||||||
const visibleProp = content ? {} : { visible: false };
|
|
||||||
return (
|
|
||||||
<Popper
|
|
||||||
{...visibleProp}
|
|
||||||
placement="top"
|
|
||||||
{...props}
|
|
||||||
showArrow={false}
|
|
||||||
content={
|
|
||||||
<PopoverContainer
|
|
||||||
style={style}
|
|
||||||
direction={placementToContainerDirection[placement]}
|
|
||||||
>
|
|
||||||
{content}
|
|
||||||
</PopoverContainer>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
export type TooltipProps = {
|
|
||||||
showArrow?: boolean;
|
|
||||||
};
|
|
||||||
export type PopoverDirection =
|
|
||||||
| 'none'
|
|
||||||
| 'left-top'
|
|
||||||
| 'left-bottom'
|
|
||||||
| 'right-top'
|
|
||||||
| 'right-bottom';
|
|
||||||
@@ -5,6 +5,7 @@ const basicFontFamily =
|
|||||||
'apple-system, BlinkMacSystemFont,Helvetica Neue, Tahoma, PingFang SC, Microsoft Yahei, Arial,Hiragino Sans GB, sans-serif, Apple Color Emoji, Segoe UI Emoji,Segoe UI Symbol, Noto Color Emoji';
|
'apple-system, BlinkMacSystemFont,Helvetica Neue, Tahoma, PingFang SC, Microsoft Yahei, Arial,Hiragino Sans GB, sans-serif, Apple Color Emoji, Segoe UI Emoji,Segoe UI Symbol, Noto Color Emoji';
|
||||||
|
|
||||||
export const lightTheme: AffineTheme = {
|
export const lightTheme: AffineTheme = {
|
||||||
|
mode: 'light',
|
||||||
colors: {
|
colors: {
|
||||||
primaryColor: '#6880FF',
|
primaryColor: '#6880FF',
|
||||||
|
|
||||||
@@ -43,14 +44,19 @@ export const lightTheme: AffineTheme = {
|
|||||||
'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);',
|
'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);',
|
||||||
modal:
|
modal:
|
||||||
'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);',
|
'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);',
|
||||||
|
tooltip: '1px 1px 4px rgba(0, 0, 0, 0.14)',
|
||||||
},
|
},
|
||||||
space: {
|
space: {
|
||||||
paragraph: '8px',
|
paragraph: '8px',
|
||||||
},
|
},
|
||||||
|
radius: {
|
||||||
|
popover: '10px',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const darkTheme: AffineTheme = {
|
export const darkTheme: AffineTheme = {
|
||||||
...lightTheme,
|
...lightTheme,
|
||||||
|
mode: 'dark',
|
||||||
colors: {
|
colors: {
|
||||||
primaryColor: '#6880FF',
|
primaryColor: '#6880FF',
|
||||||
|
|
||||||
@@ -77,6 +83,7 @@ export const darkTheme: AffineTheme = {
|
|||||||
'0px 1px 10px -6px rgba(24, 39, 75, 0.08), 0px 3px 16px -6px rgba(24, 39, 75, 0.04)',
|
'0px 1px 10px -6px rgba(24, 39, 75, 0.08), 0px 3px 16px -6px rgba(24, 39, 75, 0.04)',
|
||||||
modal:
|
modal:
|
||||||
'0px 1px 10px -6px rgba(24, 39, 75, 0.08), 0px 3px 16px -6px rgba(24, 39, 75, 0.04)',
|
'0px 1px 10px -6px rgba(24, 39, 75, 0.08), 0px 3px 16px -6px rgba(24, 39, 75, 0.04)',
|
||||||
|
tooltip: '1px 1px 4px rgba(0, 0, 0, 0.14)',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -108,6 +115,7 @@ export const globalThemeVariables: (
|
|||||||
|
|
||||||
'--affine-modal-shadow': theme.shadow.modal,
|
'--affine-modal-shadow': theme.shadow.modal,
|
||||||
'--affine-popover-shadow': theme.shadow.popover,
|
'--affine-popover-shadow': theme.shadow.popover,
|
||||||
|
'--affine-tooltip-shadow': theme.shadow.tooltip,
|
||||||
|
|
||||||
'--affine-font-xs': theme.font.xs, // tiny
|
'--affine-font-xs': theme.font.xs, // tiny
|
||||||
'--affine-font-sm': theme.font.sm, // small
|
'--affine-font-sm': theme.font.sm, // small
|
||||||
@@ -121,5 +129,6 @@ export const globalThemeVariables: (
|
|||||||
'--affine-font-family2': theme.font.family2,
|
'--affine-font-family2': theme.font.family2,
|
||||||
|
|
||||||
'--affine-paragraph-space': theme.space.paragraph,
|
'--affine-paragraph-space': theme.space.paragraph,
|
||||||
|
'--affine-popover-radius': theme.radius.popover,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export type ThemeProviderValue = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export interface AffineTheme {
|
export interface AffineTheme {
|
||||||
|
mode: Theme;
|
||||||
colors: {
|
colors: {
|
||||||
primaryColor: string;
|
primaryColor: string;
|
||||||
|
|
||||||
@@ -53,10 +54,14 @@ export interface AffineTheme {
|
|||||||
shadow: {
|
shadow: {
|
||||||
modal: string;
|
modal: string;
|
||||||
popover: string;
|
popover: string;
|
||||||
|
tooltip: string;
|
||||||
};
|
};
|
||||||
space: {
|
space: {
|
||||||
paragraph: string;
|
paragraph: string;
|
||||||
};
|
};
|
||||||
|
radius: {
|
||||||
|
popover: string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AffineThemeCSSVariables {
|
export interface AffineThemeCSSVariables {
|
||||||
@@ -80,8 +85,9 @@ export interface AffineThemeCSSVariables {
|
|||||||
'--affine-selected-color': AffineTheme['colors']['selectedColor'];
|
'--affine-selected-color': AffineTheme['colors']['selectedColor'];
|
||||||
'--affine-border-color': AffineTheme['colors']['borderColor'];
|
'--affine-border-color': AffineTheme['colors']['borderColor'];
|
||||||
|
|
||||||
'--affine-modal-shadow': AffineTheme['shadow']['popover'];
|
'--affine-modal-shadow': AffineTheme['shadow']['modal'];
|
||||||
'--affine-popover-shadow': AffineTheme['shadow']['modal'];
|
'--affine-popover-shadow': AffineTheme['shadow']['popover'];
|
||||||
|
'--affine-tooltip-shadow': AffineTheme['shadow']['tooltip'];
|
||||||
|
|
||||||
'--affine-font-xs': AffineTheme['font']['xs']; // tiny
|
'--affine-font-xs': AffineTheme['font']['xs']; // tiny
|
||||||
'--affine-font-sm': AffineTheme['font']['sm']; // small
|
'--affine-font-sm': AffineTheme['font']['sm']; // small
|
||||||
@@ -95,6 +101,8 @@ export interface AffineThemeCSSVariables {
|
|||||||
'--affine-font-family2': AffineTheme['font']['family2'];
|
'--affine-font-family2': AffineTheme['font']['family2'];
|
||||||
|
|
||||||
'--affine-paragraph-space': AffineTheme['space']['paragraph'];
|
'--affine-paragraph-space': AffineTheme['space']['paragraph'];
|
||||||
|
|
||||||
|
'--affine-popover-radius': AffineTheme['radius']['popover'];
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module '@emotion/react' {
|
declare module '@emotion/react' {
|
||||||
|
|||||||
53
packages/app/src/ui/shared/Container.tsx
Normal file
53
packages/app/src/ui/shared/Container.tsx
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import { styled } from '@/styles';
|
||||||
|
import { PopperPlacementType } from '@mui/material';
|
||||||
|
|
||||||
|
export type PopperDirection =
|
||||||
|
| 'none'
|
||||||
|
| 'left-top'
|
||||||
|
| 'left-bottom'
|
||||||
|
| 'right-top'
|
||||||
|
| 'right-bottom';
|
||||||
|
|
||||||
|
const getBorderRadius = (direction: PopperDirection, radius = '0') => {
|
||||||
|
const map: Record<PopperDirection, string> = {
|
||||||
|
none: `${radius}`,
|
||||||
|
'left-top': `0 ${radius} ${radius} ${radius}`,
|
||||||
|
'left-bottom': `${radius} ${radius} ${radius} 0`,
|
||||||
|
'right-top': `${radius} 0 ${radius} ${radius}`,
|
||||||
|
'right-bottom': `${radius} ${radius} 0 ${radius}`,
|
||||||
|
};
|
||||||
|
return map[direction];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const placementToContainerDirection: Record<
|
||||||
|
PopperPlacementType,
|
||||||
|
PopperDirection
|
||||||
|
> = {
|
||||||
|
top: 'none',
|
||||||
|
'top-start': 'left-bottom',
|
||||||
|
'top-end': 'right-bottom',
|
||||||
|
right: 'none',
|
||||||
|
'right-start': 'left-top',
|
||||||
|
'right-end': 'left-bottom',
|
||||||
|
bottom: 'none',
|
||||||
|
'bottom-start': 'left-top',
|
||||||
|
'bottom-end': 'right-top',
|
||||||
|
left: 'none',
|
||||||
|
'left-start': 'right-top',
|
||||||
|
'left-end': 'right-bottom',
|
||||||
|
auto: 'none',
|
||||||
|
'auto-start': 'none',
|
||||||
|
'auto-end': 'none',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const StyledPopperContainer = styled('div')<{
|
||||||
|
placement?: PopperPlacementType;
|
||||||
|
}>(({ theme, placement = 'top' }) => {
|
||||||
|
const direction = placementToContainerDirection[placement];
|
||||||
|
const borderRadius = getBorderRadius(direction, theme.radius.popover);
|
||||||
|
return {
|
||||||
|
borderRadius,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
export default StyledPopperContainer;
|
||||||
32
packages/app/src/ui/tooltip/Tooltip.tsx
Normal file
32
packages/app/src/ui/tooltip/Tooltip.tsx
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { type PropsWithChildren } from 'react';
|
||||||
|
import StyledPopperContainer from '../shared/Container';
|
||||||
|
import { Popper, type PopperProps } from '../popper';
|
||||||
|
import { styled } from '@/styles';
|
||||||
|
import type { TooltipProps } from '@mui/material';
|
||||||
|
|
||||||
|
const StyledTooltip = styled(StyledPopperContainer)(({ theme }) => {
|
||||||
|
return {
|
||||||
|
boxShadow: theme.shadow.tooltip,
|
||||||
|
padding: '4px 12px',
|
||||||
|
backgroundColor:
|
||||||
|
theme.mode === 'dark'
|
||||||
|
? theme.colors.popoverBackground
|
||||||
|
: theme.colors.primaryColor,
|
||||||
|
color: '#fff',
|
||||||
|
fontSize: theme.font.xs,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
export const Tooltip = (
|
||||||
|
props: PropsWithChildren<PopperProps & Omit<TooltipProps, 'title'>>
|
||||||
|
) => {
|
||||||
|
const { content, placement = 'top-start' } = props;
|
||||||
|
// If there is no content, hide forever
|
||||||
|
return content ? (
|
||||||
|
<Popper
|
||||||
|
{...props}
|
||||||
|
showArrow={false}
|
||||||
|
content={<StyledTooltip placement={placement}>{content}</StyledTooltip>}
|
||||||
|
/>
|
||||||
|
) : null;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user