mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 21:27:20 +00:00
feat: support set frame background color
This commit is contained in:
@@ -11,6 +11,7 @@ import { StrokeLineStyleConfig } from './stroke-line-style-config';
|
||||
import { Group, UnGroup } from './GroupOperation';
|
||||
import { DeleteShapes } from './DeleteOperation';
|
||||
import { Lock, Unlock } from './LockOperation';
|
||||
import { FrameFillColorConfig } from './FrameFillColorConfig';
|
||||
|
||||
export const CommandPanel: FC<{ app: TldrawApp }> = ({ app }) => {
|
||||
const state = app.useStore();
|
||||
@@ -51,6 +52,13 @@ export const CommandPanel: FC<{ app: TldrawApp }> = ({ app }) => {
|
||||
shapes={config.fill.selectedShapes}
|
||||
/>
|
||||
) : null,
|
||||
frameFill: config.frameFill.selectedShapes.length ? (
|
||||
<FrameFillColorConfig
|
||||
key="fill"
|
||||
app={app}
|
||||
shapes={config.frameFill.selectedShapes}
|
||||
/>
|
||||
) : null,
|
||||
font: config.font.selectedShapes.length ? (
|
||||
<FontSizeConfig
|
||||
key="font"
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
import type { FC } from 'react';
|
||||
import type { TldrawApp } from '@toeverything/components/board-state';
|
||||
import type { TDShape } from '@toeverything/components/board-types';
|
||||
import {
|
||||
Popover,
|
||||
Tooltip,
|
||||
IconButton,
|
||||
useTheme,
|
||||
} from '@toeverything/components/ui';
|
||||
import {
|
||||
ShapeColorNoneIcon,
|
||||
ShapeColorDuotoneIcon,
|
||||
} from '@toeverything/components/icons';
|
||||
import { countBy, maxBy } from '@toeverything/utils';
|
||||
import { getShapeIds } from './utils';
|
||||
import { Palette } from '../palette';
|
||||
|
||||
interface BorderColorConfigProps {
|
||||
app: TldrawApp;
|
||||
shapes: TDShape[];
|
||||
}
|
||||
|
||||
type ColorType = 'none' | string;
|
||||
|
||||
const _colors: ColorType[] = [
|
||||
'rgba(255, 133, 137, 0.5)',
|
||||
'rgba(255, 159, 101, 0.5)',
|
||||
'rgba(255, 251, 69, 0.5)',
|
||||
'rgba(64, 255, 138, 0.5)',
|
||||
'rgba(26, 252, 255, 0.5)',
|
||||
'rgba(198, 156, 255, 0.5)',
|
||||
'rgba(255, 143, 224, 0.5)',
|
||||
'rgba(152, 172, 189, 0.5)',
|
||||
'rgba(216, 226, 248, 0.5)',
|
||||
];
|
||||
|
||||
const _getIconRenderColor = (shapes: TDShape[]) => {
|
||||
const counted = countBy(shapes, shape => shape.style.fill);
|
||||
const max = maxBy(Object.entries(counted), ([c, n]) => n);
|
||||
return max[0];
|
||||
};
|
||||
|
||||
export const FrameFillColorConfig: FC<BorderColorConfigProps> = ({
|
||||
app,
|
||||
shapes,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const setFillColor = (color: ColorType) => {
|
||||
app.style(
|
||||
{ fill: color, isFilled: color !== 'none' },
|
||||
getShapeIds(shapes)
|
||||
);
|
||||
};
|
||||
|
||||
const iconColor = _getIconRenderColor(shapes);
|
||||
|
||||
return (
|
||||
<Popover
|
||||
trigger="hover"
|
||||
placement="bottom-start"
|
||||
content={
|
||||
<Palette
|
||||
colors={_colors}
|
||||
selected={iconColor}
|
||||
onSelect={setFillColor}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Tooltip content="Frame Background Color" placement="top-start">
|
||||
<IconButton>
|
||||
{iconColor === 'none' ? (
|
||||
<ShapeColorNoneIcon />
|
||||
) : (
|
||||
<ShapeColorDuotoneIcon
|
||||
style={{
|
||||
color: iconColor,
|
||||
border:
|
||||
iconColor === '#FFFFFF'
|
||||
? `1px solid ${theme.affine.palette.tagHover}`
|
||||
: 0,
|
||||
borderRadius: '5px',
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
@@ -7,6 +7,7 @@ interface Config {
|
||||
type:
|
||||
| 'stroke'
|
||||
| 'fill'
|
||||
| 'frameFill'
|
||||
| 'font'
|
||||
| 'group'
|
||||
| 'ungroup'
|
||||
@@ -22,6 +23,10 @@ const _createInitConfig = (): Record<Config['type'], Config> => {
|
||||
type: 'fill',
|
||||
selectedShapes: [],
|
||||
},
|
||||
frameFill: {
|
||||
type: 'frameFill',
|
||||
selectedShapes: [],
|
||||
},
|
||||
stroke: {
|
||||
type: 'stroke',
|
||||
selectedShapes: [],
|
||||
@@ -91,6 +96,10 @@ const _isSupportFont = (shape: TDShape): boolean => {
|
||||
].some(type => type === shape.type);
|
||||
};
|
||||
|
||||
const _isSupportFrameFill = (shape: TDShape): boolean => {
|
||||
return shape.type === TDShapeType.Frame;
|
||||
};
|
||||
|
||||
export const useConfig = (app: TldrawApp): Record<Config['type'], Config> => {
|
||||
const state = app.useStore();
|
||||
const selectedShapes = TLDR.get_selected_shapes(state, app.currentPageId);
|
||||
@@ -105,6 +114,9 @@ export const useConfig = (app: TldrawApp): Record<Config['type'], Config> => {
|
||||
if (_isSupportFont(cur)) {
|
||||
acc.font.selectedShapes.push(cur);
|
||||
}
|
||||
if (_isSupportFrameFill(cur)) {
|
||||
acc.frameFill.selectedShapes.push(cur);
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
_createInitConfig()
|
||||
|
||||
Reference in New Issue
Block a user