feat(editor): update edgeless color palette (#9243)

Closes: [BS-1475](https://linear.app/affine-design/issue/BS-1475/颜色主题更新) [BS-1803](https://linear.app/affine-design/issue/BS-1803/fill-color色板影响的yuan素) [BS-1804](https://linear.app/affine-design/issue/BS-1804/border-color色板影响的yuan素) [BS-1815](https://linear.app/affine-design/issue/BS-1815/连线文字配色略瞎)

### What's Changed

* refactor `EdgelessLineWidthPanel` component, the previous width is fixed and cannot be used in the new design
* refactor `EdgelessColorPanel` and `EdgelessColorButton` components, make them simple and reusable
* delete redundant `EdgelessOneRowColorPanel` component
* unity and update color palette, if the previously set color is not in the latest color palette, the custom color button will be selected
This commit is contained in:
fundon
2024-12-30 03:36:33 +00:00
parent 6b1865ff92
commit a5641ae608
250 changed files with 952 additions and 964 deletions

View File

@@ -26,7 +26,7 @@
"@floating-ui/dom": "^1.6.10", "@floating-ui/dom": "^1.6.10",
"@lit/context": "^1.1.2", "@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"file-type": "^19.5.0", "file-type": "^19.5.0",
"lit": "^3.2.0", "lit": "^3.2.0",
"minimatch": "^10.0.1", "minimatch": "^10.0.1",

View File

@@ -25,7 +25,7 @@
"@floating-ui/dom": "^1.6.10", "@floating-ui/dom": "^1.6.10",
"@lit/context": "^1.1.2", "@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"lit": "^3.2.0", "lit": "^3.2.0",
"minimatch": "^10.0.1", "minimatch": "^10.0.1",
"zod": "^3.23.8" "zod": "^3.23.8"

View File

@@ -23,7 +23,7 @@
"@floating-ui/dom": "^1.6.10", "@floating-ui/dom": "^1.6.10",
"@lit/context": "^1.1.2", "@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"@types/mdast": "^4.0.4", "@types/mdast": "^4.0.4",
"lit": "^3.2.0", "lit": "^3.2.0",
"minimatch": "^10.0.1", "minimatch": "^10.0.1",

View File

@@ -23,7 +23,7 @@
"@floating-ui/dom": "^1.6.10", "@floating-ui/dom": "^1.6.10",
"@lit/context": "^1.1.2", "@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"@types/mdast": "^4.0.4", "@types/mdast": "^4.0.4",
"lit": "^3.2.0", "lit": "^3.2.0",
"minimatch": "^10.0.1", "minimatch": "^10.0.1",

View File

@@ -25,7 +25,7 @@
"@floating-ui/dom": "^1.6.10", "@floating-ui/dom": "^1.6.10",
"@lit/context": "^1.1.2", "@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"lit": "^3.2.0", "lit": "^3.2.0",
"minimatch": "^10.0.1", "minimatch": "^10.0.1",
"zod": "^3.23.8" "zod": "^3.23.8"

View File

@@ -25,7 +25,7 @@
"@floating-ui/dom": "^1.6.10", "@floating-ui/dom": "^1.6.10",
"@lit/context": "^1.1.2", "@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"lit": "^3.2.0", "lit": "^3.2.0",
"minimatch": "^10.0.1", "minimatch": "^10.0.1",
"zod": "^3.23.8" "zod": "^3.23.8"

View File

@@ -23,7 +23,7 @@
"@floating-ui/dom": "^1.6.10", "@floating-ui/dom": "^1.6.10",
"@lit/context": "^1.1.2", "@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"@types/mdast": "^4.0.4", "@types/mdast": "^4.0.4",
"lit": "^3.2.0", "lit": "^3.2.0",
"minimatch": "^10.0.1", "minimatch": "^10.0.1",

View File

@@ -24,7 +24,7 @@
"@floating-ui/dom": "^1.6.10", "@floating-ui/dom": "^1.6.10",
"@lit/context": "^1.1.2", "@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"file-type": "^19.5.0", "file-type": "^19.5.0",
"lit": "^3.2.0", "lit": "^3.2.0",
"minimatch": "^10.0.1", "minimatch": "^10.0.1",

View File

@@ -24,7 +24,7 @@
"@floating-ui/dom": "^1.6.10", "@floating-ui/dom": "^1.6.10",
"@lit/context": "^1.1.2", "@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"@types/katex": "^0.16.7", "@types/katex": "^0.16.7",
"@types/mdast": "^4.0.4", "@types/mdast": "^4.0.4",
"katex": "^0.16.11", "katex": "^0.16.11",

View File

@@ -23,7 +23,7 @@
"@floating-ui/dom": "^1.6.10", "@floating-ui/dom": "^1.6.10",
"@lit/context": "^1.1.2", "@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"@types/mdast": "^4.0.4", "@types/mdast": "^4.0.4",
"lit": "^3.2.0", "lit": "^3.2.0",
"minimatch": "^10.0.1", "minimatch": "^10.0.1",

View File

@@ -26,7 +26,7 @@
"@floating-ui/dom": "^1.6.10", "@floating-ui/dom": "^1.6.10",
"@lit/context": "^1.1.2", "@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"lit": "^3.2.0", "lit": "^3.2.0",
"minimatch": "^10.0.1", "minimatch": "^10.0.1",
"zod": "^3.23.8" "zod": "^3.23.8"

View File

@@ -23,7 +23,7 @@
"@floating-ui/dom": "^1.6.10", "@floating-ui/dom": "^1.6.10",
"@lit/context": "^1.1.2", "@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"@types/mdast": "^4.0.4", "@types/mdast": "^4.0.4",
"lit": "^3.2.0", "lit": "^3.2.0",
"minimatch": "^10.0.1", "minimatch": "^10.0.1",

View File

@@ -22,7 +22,7 @@
"@blocksuite/store": "workspace:*", "@blocksuite/store": "workspace:*",
"@lit/context": "^1.1.2", "@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"fractional-indexing": "^3.2.0", "fractional-indexing": "^3.2.0",
"lit": "^3.2.0", "lit": "^3.2.0",
"lodash.chunk": "^4.2.0", "lodash.chunk": "^4.2.0",

View File

@@ -24,7 +24,7 @@
"@lit/context": "^1.1.2", "@lit/context": "^1.1.2",
"@lottiefiles/dotlottie-wc": "^0.4.0", "@lottiefiles/dotlottie-wc": "^0.4.0",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"date-fns": "^4.0.0", "date-fns": "^4.0.0",
"katex": "^0.16.11", "katex": "^0.16.11",
"lit": "^3.2.0", "lit": "^3.2.0",

View File

@@ -427,21 +427,6 @@ export const ViewBarIcon = icons.ViewBarIcon({
height: '24', height: '24',
}); });
export const TransparentIcon = html`<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M-0.939238 4.14286C-0.979281 4.4228 -1 4.70898 -1 5V6.71429H1.57143V9.28571H-1V11C-1 11.291 -0.979281 11.5772 -0.939238 11.8571H1.57143V14.4286H0.0754482C0.481795 15.0111 0.988871 15.5182 1.57143 15.9246V14.4286L4.14286 14.4286V16.9392C4.4228 16.9793 4.70898 17 5 17H6.71429V14.4286H9.28571V17H11C11.291 17 11.5772 16.9793 11.8571 16.9392V14.4286H14.4286L14.4286 15.9246C15.0111 15.5182 15.5182 15.0111 15.9246 14.4286L14.4286 14.4286V11.8571H16.9392C16.9793 11.5772 17 11.291 17 11V9.28571H14.4286V6.71429H17V5C17 4.70898 16.9793 4.4228 16.9392 4.14286H14.4286V1.57143H15.9246C15.5182 0.988871 15.0111 0.481795 14.4286 0.075448L14.4286 1.57143H11.8571V-0.939238C11.5772 -0.979281 11.291 -1 11 -1H9.28571V1.57143H6.71429V-1H5C4.70898 -1 4.4228 -0.979281 4.14286 -0.939238V1.57143H1.57143V0.0754479C0.988871 0.481795 0.481795 0.988871 0.0754479 1.57143H1.57143V4.14286H-0.939238ZM4.14286 4.14286V1.57143H6.71429V4.14286H4.14286ZM4.14286 6.71429H1.57143V4.14286H4.14286V6.71429ZM6.71429 6.71429V4.14286H9.28571V6.71429H6.71429ZM6.71429 9.28571V6.71429H4.14286V9.28571H1.57143V11.8571H4.14286V14.4286H6.71429V11.8571H9.28571V14.4286H11.8571V11.8571H14.4286V9.28571H11.8571V6.71429H14.4286V4.14286H11.8571V1.57143H9.28571V4.14286H11.8571V6.71429H9.28571V9.28571H6.71429ZM6.71429 9.28571V11.8571H4.14286V9.28571H6.71429ZM9.28571 9.28571H11.8571V11.8571H9.28571V9.28571Z"
fill="#D9D9D9"
/>
</svg>`;
export const MoreHorizontalIcon = icons.MoreHorizontalIcon({ export const MoreHorizontalIcon = icons.MoreHorizontalIcon({
width: '24', width: '24',
height: '24', height: '24',

View File

@@ -23,7 +23,7 @@
"@floating-ui/dom": "^1.6.10", "@floating-ui/dom": "^1.6.10",
"@lit/context": "^1.1.2", "@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"date-fns": "^4.0.0", "date-fns": "^4.0.0",
"lit": "^3.2.0", "lit": "^3.2.0",
"zod": "^3.23.8" "zod": "^3.23.8"

View File

@@ -30,7 +30,7 @@ export const FrameBlockSchema = defineBlockSchema({
flavour: 'affine:frame', flavour: 'affine:frame',
props: (internal): FrameBlockProps => ({ props: (internal): FrameBlockProps => ({
title: internal.Text(), title: internal.Text(),
background: '--affine-palette-transparent', background: 'transparent',
xywh: `[0,0,100,100]`, xywh: `[0,0,100,100]`,
index: 'a0', index: 'a0',
childElementIds: Object.create(null), childElementIds: Object.create(null),

View File

@@ -1,3 +1,3 @@
import { LineColor } from './line.js'; import { StrokeColor } from './color.js';
export const DEFAULT_BRUSH_COLOR = LineColor.Blue; export const DEFAULT_BRUSH_COLOR = StrokeColor.Blue;

View File

@@ -0,0 +1,97 @@
import { themeToVar } from '@toeverything/theme/v2';
import { z } from 'zod';
import { createEnumMap } from '../utils/enum.js';
export const Transparent = 'transparent';
export const White = themeToVar('edgeless/palette/white');
export const Black = themeToVar('edgeless/palette/black');
export const Light = {
Red: themeToVar('edgeless/palette/light/redLight'),
Orange: themeToVar('edgeless/palette/light/orangeLight'),
Yellow: themeToVar('edgeless/palette/light/yellowLight'),
Green: themeToVar('edgeless/palette/light/greenLight'),
Blue: themeToVar('edgeless/palette/light/blueLight'),
Purple: themeToVar('edgeless/palette/light/purpleLight'),
Magenta: themeToVar('edgeless/palette/light/magentaLight'),
Grey: themeToVar('edgeless/palette/light/greyLight'),
} as const;
export const LIGHT_PALETTES = [
Light.Red,
Light.Orange,
Light.Yellow,
Light.Green,
Light.Blue,
Light.Purple,
Light.Magenta,
Light.Grey,
] as const;
export const Medium = {
Red: themeToVar('edgeless/palette/medium/redMedium'),
Orange: themeToVar('edgeless/palette/medium/orangeMedium'),
Yellow: themeToVar('edgeless/palette/medium/yellowMedium'),
Green: themeToVar('edgeless/palette/medium/greenMedium'),
Blue: themeToVar('edgeless/palette/medium/blueMedium'),
Purple: themeToVar('edgeless/palette/medium/purpleMedium'),
Magenta: themeToVar('edgeless/palette/medium/magentaMedium'),
Grey: themeToVar('edgeless/palette/medium/greyMedium'),
} as const;
export const MEDIUM_PALETTES = [
Medium.Red,
Medium.Orange,
Medium.Yellow,
Medium.Green,
Medium.Blue,
Medium.Purple,
Medium.Magenta,
Medium.Grey,
] as const;
export const Heavy = {
Red: themeToVar('edgeless/palette/heavy/red'),
Orange: themeToVar('edgeless/palette/heavy/orange'),
Yellow: themeToVar('edgeless/palette/heavy/yellow'),
Green: themeToVar('edgeless/palette/heavy/green'),
Blue: themeToVar('edgeless/palette/heavy/blue'),
Purple: themeToVar('edgeless/palette/heavy/purple'),
Magenta: themeToVar('edgeless/palette/heavy/magenta'),
} as const;
export const HEAVY_PALETTES = [
Heavy.Red,
Heavy.Orange,
Heavy.Yellow,
Heavy.Green,
Heavy.Blue,
Heavy.Purple,
Heavy.Magenta,
] as const;
export const PALETTES = [
// Light
...LIGHT_PALETTES,
Transparent,
// Medium
...MEDIUM_PALETTES,
White,
// Heavy
...HEAVY_PALETTES,
Black,
] as const;
export const PaletteEnum = z.enum(PALETTES);
export const StrokeColor = { Black, White, ...Medium } as const;
export const StrokeColorMap = createEnumMap(StrokeColor);
export const STROKE_COLORS = [...MEDIUM_PALETTES, Black, White] as const;

View File

@@ -1,5 +1,5 @@
import { createEnumMap } from '../utils/enum.js'; import { createEnumMap } from '../utils/enum.js';
import { LineColor } from './line.js'; import { StrokeColor } from './color.js';
export enum ConnectorEndpoint { export enum ConnectorEndpoint {
Front = 'Front', Front = 'Front',
@@ -16,9 +16,9 @@ export enum PointStyle {
export const PointStyleMap = createEnumMap(PointStyle); export const PointStyleMap = createEnumMap(PointStyle);
export const DEFAULT_CONNECTOR_COLOR = LineColor.Grey; export const DEFAULT_CONNECTOR_COLOR = StrokeColor.Grey;
export const DEFAULT_CONNECTOR_TEXT_COLOR = LineColor.Black; export const DEFAULT_CONNECTOR_TEXT_COLOR = StrokeColor.Black;
export const DEFAULT_FRONT_END_POINT_STYLE = PointStyle.None; export const DEFAULT_FRONT_END_POINT_STYLE = PointStyle.None;

View File

@@ -1,27 +1,3 @@
import { z } from 'zod'; import { Light } from './color.js';
export enum FrameBackgroundColor { export const FrameBackgroundColor = Light;
Blue = '--affine-tag-blue',
Gray = '--affine-tag-gray',
Green = '--affine-tag-green',
Orange = '--affine-tag-orange',
Pink = '--affine-tag-pink',
Purple = '--affine-tag-purple',
Red = '--affine-tag-red',
Teal = '--affine-tag-teal',
Yellow = '--affine-tag-yellow',
}
export const FRAME_BACKGROUND_COLORS = [
FrameBackgroundColor.Gray,
FrameBackgroundColor.Red,
FrameBackgroundColor.Orange,
FrameBackgroundColor.Yellow,
FrameBackgroundColor.Green,
FrameBackgroundColor.Teal,
FrameBackgroundColor.Blue,
FrameBackgroundColor.Purple,
FrameBackgroundColor.Pink,
];
export const FrameBackgroundColorsSchema = z.nativeEnum(FrameBackgroundColor);

View File

@@ -1,4 +1,5 @@
export * from './brush.js'; export * from './brush.js';
export * from './color.js';
export * from './connector.js'; export * from './connector.js';
export * from './doc.js'; export * from './doc.js';
export * from './frame.js'; export * from './frame.js';

View File

@@ -13,6 +13,20 @@ export enum LineWidth {
Two = 2, Two = 2,
} }
export const LINE_WIDTHS = [
LineWidth.Two,
LineWidth.Four,
LineWidth.Six,
LineWidth.Eight,
LineWidth.Ten,
LineWidth.Twelve,
];
/**
* Use `StrokeColor` instead.
*
* @deprecated
*/
export enum LineColor { export enum LineColor {
Black = '--affine-palette-line-black', Black = '--affine-palette-line-black',
Blue = '--affine-palette-line-blue', Blue = '--affine-palette-line-blue',

View File

@@ -1,3 +1,4 @@
import { themeToVar } from '@toeverything/theme/v2';
import { z } from 'zod'; import { z } from 'zod';
import { createEnumMap } from '../utils/enum.js'; import { createEnumMap } from '../utils/enum.js';
@@ -8,23 +9,23 @@ export const NOTE_MIN_HEIGHT = 92;
export const DEFAULT_NOTE_WIDTH = NOTE_MIN_WIDTH; export const DEFAULT_NOTE_WIDTH = NOTE_MIN_WIDTH;
export const DEFAULT_NOTE_HEIGHT = NOTE_MIN_HEIGHT; export const DEFAULT_NOTE_HEIGHT = NOTE_MIN_HEIGHT;
export enum NoteBackgroundColor { export const NoteBackgroundColor = {
Black = '--affine-note-background-black', Yellow: themeToVar('edgeless/note/yellow'),
Blue = '--affine-note-background-blue', Orange: themeToVar('edgeless/note/orange'),
Green = '--affine-note-background-green', Red: themeToVar('edgeless/note/red'),
Grey = '--affine-note-background-grey', Magenta: themeToVar('edgeless/note/magenta'),
Magenta = '--affine-note-background-magenta', Purple: themeToVar('edgeless/note/purple'),
Orange = '--affine-note-background-orange', Blue: themeToVar('edgeless/note/blue'),
Purple = '--affine-note-background-purple', Teal: themeToVar('edgeless/note/teal'),
Red = '--affine-note-background-red', Green: themeToVar('edgeless/note/green'),
Teal = '--affine-note-background-teal', Black: themeToVar('edgeless/note/black'),
White = '--affine-note-background-white', Grey: themeToVar('edgeless/note/grey'),
Yellow = '--affine-note-background-yellow', White: themeToVar('edgeless/note/white'),
} } as const;
export const NoteBackgroundColorMap = createEnumMap(NoteBackgroundColor); export const NoteBackgroundColorMap = createEnumMap(NoteBackgroundColor);
export const NOTE_BACKGROUND_COLORS = [ export const NOTE_BACKGROUND_PALETTES = [
NoteBackgroundColor.Yellow, NoteBackgroundColor.Yellow,
NoteBackgroundColor.Orange, NoteBackgroundColor.Orange,
NoteBackgroundColor.Red, NoteBackgroundColor.Red,
@@ -38,9 +39,9 @@ export const NOTE_BACKGROUND_COLORS = [
NoteBackgroundColor.White, NoteBackgroundColor.White,
] as const; ] as const;
export const DEFAULT_NOTE_BACKGROUND_COLOR = NoteBackgroundColor.White; export const NoteBackgroundPaletteEnum = z.enum(NOTE_BACKGROUND_PALETTES);
export const NoteBackgroundColorsSchema = z.nativeEnum(NoteBackgroundColor); export const DEFAULT_NOTE_BACKGROUND_COLOR = NoteBackgroundColor.White;
export enum NoteShadow { export enum NoteShadow {
Box = '--affine-note-shadow-box', Box = '--affine-note-shadow-box',

View File

@@ -1,6 +1,4 @@
import { z } from 'zod'; import { Black, Light, LIGHT_PALETTES, StrokeColor, White } from './color.js';
import { LINE_COLORS, LineColor } from './line.js';
export const DEFAULT_ROUGHNESS = 1.4; export const DEFAULT_ROUGHNESS = 1.4;
@@ -49,42 +47,12 @@ export enum ShapeStyle {
Scribbled = 'Scribbled', Scribbled = 'Scribbled',
} }
export enum ShapeFillColor { export const ShapeFillColor = { Black, White, ...Light } as const;
Black = '--affine-palette-shape-black',
Blue = '--affine-palette-shape-blue',
Green = '--affine-palette-shape-green',
Grey = '--affine-palette-shape-grey',
Magenta = '--affine-palette-shape-magenta',
Orange = '--affine-palette-shape-orange',
Purple = '--affine-palette-shape-purple',
Red = '--affine-palette-shape-red',
Teal = '--affine-palette-shape-teal',
White = '--affine-palette-shape-white',
Yellow = '--affine-palette-shape-yellow',
}
export const SHAPE_FILL_COLORS = [ export const SHAPE_FILL_COLORS = [...LIGHT_PALETTES, Black, White];
ShapeFillColor.Yellow,
ShapeFillColor.Orange,
ShapeFillColor.Red,
ShapeFillColor.Magenta,
ShapeFillColor.Purple,
ShapeFillColor.Blue,
ShapeFillColor.Teal,
ShapeFillColor.Green,
ShapeFillColor.Black,
ShapeFillColor.Grey,
ShapeFillColor.White,
] as const;
export const DEFAULT_SHAPE_FILL_COLOR = ShapeFillColor.Yellow; export const DEFAULT_SHAPE_FILL_COLOR = Light.Yellow;
export const FillColorsSchema = z.nativeEnum(ShapeFillColor); export const DEFAULT_SHAPE_STROKE_COLOR = StrokeColor.Yellow;
export const SHAPE_STROKE_COLORS = LINE_COLORS; export const DEFAULT_SHAPE_TEXT_COLOR = StrokeColor.Black;
export const DEFAULT_SHAPE_STROKE_COLOR = LineColor.Yellow;
export const DEFAULT_SHAPE_TEXT_COLOR = LineColor.Black;
export const StrokeColorsSchema = z.nativeEnum(LineColor);

View File

@@ -1,5 +1,5 @@
import { createEnumMap } from '../utils/enum.js'; import { createEnumMap } from '../utils/enum.js';
import { LineColor } from './line.js'; import { StrokeColor } from './color.js';
export enum ColorScheme { export enum ColorScheme {
Dark = 'dark', Dark = 'dark',
@@ -67,4 +67,4 @@ export enum TextResizing {
AUTO_HEIGHT, AUTO_HEIGHT,
} }
export const DEFAULT_TEXT_COLOR = LineColor.Blue; export const DEFAULT_TEXT_COLOR = StrokeColor.Blue;

View File

@@ -24,11 +24,11 @@ import {
FontFamily, FontFamily,
FontStyle, FontStyle,
FontWeight, FontWeight,
LineColor,
ShapeFillColor, ShapeFillColor,
ShapeStyle, ShapeStyle,
ShapeTextFontSize, ShapeTextFontSize,
ShapeType, ShapeType,
StrokeColor,
StrokeStyle, StrokeStyle,
TextAlign, TextAlign,
TextResizing, TextResizing,
@@ -160,7 +160,7 @@ export class ShapeElementModel extends GfxPrimitiveElementModel<ShapeProps> {
accessor shapeType: ShapeType = ShapeType.Rect; accessor shapeType: ShapeType = ShapeType.Rect;
@field() @field()
accessor strokeColor: Color = LineColor.Yellow; accessor strokeColor: Color = StrokeColor.Yellow;
@field() @field()
accessor strokeStyle: StrokeStyle = StrokeStyle.Solid; accessor strokeStyle: StrokeStyle = StrokeStyle.Solid;
@@ -246,7 +246,7 @@ export class LocalShapeElementModel extends GfxLocalElementModel {
accessor shapeType: ShapeType = ShapeType.Rect; accessor shapeType: ShapeType = ShapeType.Rect;
@prop() @prop()
accessor strokeColor: Color = LineColor.Yellow; accessor strokeColor: Color = StrokeColor.Yellow;
@prop() @prop()
accessor strokeStyle: StrokeStyle = StrokeStyle.Solid; accessor strokeStyle: StrokeStyle = StrokeStyle.Solid;

View File

@@ -22,7 +22,7 @@
"@floating-ui/dom": "^1.6.10", "@floating-ui/dom": "^1.6.10",
"@lit/context": "^1.1.2", "@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"@types/hast": "^3.0.4", "@types/hast": "^3.0.4",
"@types/mdast": "^4.0.4", "@types/mdast": "^4.0.4",
"lit": "^3.2.0", "lit": "^3.2.0",

View File

@@ -1,6 +1,6 @@
/* CSS variables. You need to handle all places where `CSS variables` are marked. */ /* CSS variables. You need to handle all places where `CSS variables` are marked. */
import { LINE_COLORS, SHAPE_FILL_COLORS } from '@blocksuite/affine-model'; import { LINE_COLORS } from '@blocksuite/affine-model';
import { import {
type AffineCssVariables, type AffineCssVariables,
type AffineTheme, type AffineTheme,
@@ -66,7 +66,6 @@ export const ColorVariables = [
'--affine-tag-orange', '--affine-tag-orange',
'--affine-tag-gray', '--affine-tag-gray',
...LINE_COLORS, ...LINE_COLORS,
...SHAPE_FILL_COLORS,
'--affine-tooltip', '--affine-tooltip',
'--affine-blue', '--affine-blue',
]; ];

View File

@@ -14,22 +14,20 @@ import {
DEFAULT_SHAPE_STROKE_COLOR, DEFAULT_SHAPE_STROKE_COLOR,
DEFAULT_SHAPE_TEXT_COLOR, DEFAULT_SHAPE_TEXT_COLOR,
DEFAULT_TEXT_COLOR, DEFAULT_TEXT_COLOR,
FillColorsSchema,
FontFamily, FontFamily,
FontStyle, FontStyle,
FontWeight, FontWeight,
FrameBackgroundColorsSchema,
LayoutType, LayoutType,
LineColor,
LineColorsSchema, LineColorsSchema,
LineWidth, LineWidth,
MindmapStyle, MindmapStyle,
NoteBackgroundColorsSchema, NoteBackgroundPaletteEnum,
NoteDisplayMode, NoteDisplayMode,
NoteShadowsSchema, NoteShadowsSchema,
PaletteEnum,
PointStyle, PointStyle,
ShapeStyle, ShapeStyle,
StrokeColorsSchema, StrokeColor,
StrokeStyle, StrokeStyle,
TextAlign, TextAlign,
TextVerticalAlign, TextVerticalAlign,
@@ -59,17 +57,12 @@ export const ColorSchema = z.union([
dark: z.string(), dark: z.string(),
}), }),
]); ]);
const LineColorSchema = z.union([LineColorsSchema, ColorSchema]); const ColorPaletteSchema = z.union([ColorSchema, PaletteEnum]);
const ShapeFillColorSchema = z.union([FillColorsSchema, ColorSchema]); const LineColorSchema = z.union([LineColorsSchema, ColorPaletteSchema]);
const ShapeStrokeColorSchema = z.union([StrokeColorsSchema, ColorSchema]); const TextColorSchema = z.union([LineColorsSchema, ColorPaletteSchema]);
const TextColorSchema = z.union([LineColorsSchema, ColorSchema]);
const NoteBackgroundColorSchema = z.union([ const NoteBackgroundColorSchema = z.union([
NoteBackgroundColorsSchema,
ColorSchema,
]);
const FrameBackgroundColorSchema = z.union([
FrameBackgroundColorsSchema,
ColorSchema, ColorSchema,
NoteBackgroundPaletteEnum,
]); ]);
export const ConnectorSchema = z export const ConnectorSchema = z
@@ -110,13 +103,13 @@ export const ConnectorSchema = z
export const BrushSchema = z export const BrushSchema = z
.object({ .object({
color: LineColorSchema, color: ColorPaletteSchema,
lineWidth: LineWidthSchema, lineWidth: LineWidthSchema,
}) })
.default({ .default({
color: { color: {
dark: LineColor.White, dark: StrokeColor.White,
light: LineColor.Black, light: StrokeColor.Black,
}, },
lineWidth: LineWidth.Four, lineWidth: LineWidth.Four,
}); });
@@ -140,8 +133,8 @@ const DEFAULT_SHAPE = {
const ShapeObject = { const ShapeObject = {
color: TextColorSchema, color: TextColorSchema,
fillColor: ShapeFillColorSchema, fillColor: ColorPaletteSchema,
strokeColor: ShapeStrokeColorSchema, strokeColor: ColorPaletteSchema,
strokeStyle: StrokeStyleSchema, strokeStyle: StrokeStyleSchema,
strokeWidth: z.number(), strokeWidth: z.number(),
shapeStyle: ShapeStyleSchema, shapeStyle: ShapeStyleSchema,
@@ -235,7 +228,7 @@ export const MindmapSchema = z
export const FrameSchema = z export const FrameSchema = z
.object({ .object({
background: FrameBackgroundColorSchema.optional(), background: ColorPaletteSchema.optional(),
}) })
.default({}); .default({});

View File

@@ -28,7 +28,7 @@
"@floating-ui/dom": "^1.6.10", "@floating-ui/dom": "^1.6.10",
"@lit/context": "^1.1.2", "@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"lit": "^3.2.0", "lit": "^3.2.0",
"minimatch": "^10.0.1", "minimatch": "^10.0.1",
"zod": "^3.23.8" "zod": "^3.23.8"

View File

@@ -18,7 +18,7 @@
"@blocksuite/block-std": "workspace:*", "@blocksuite/block-std": "workspace:*",
"@blocksuite/global": "workspace:*", "@blocksuite/global": "workspace:*",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"lit": "^3.2.0" "lit": "^3.2.0"
}, },
"exports": { "exports": {

View File

@@ -18,7 +18,7 @@
"@blocksuite/block-std": "workspace:*", "@blocksuite/block-std": "workspace:*",
"@blocksuite/global": "workspace:*", "@blocksuite/global": "workspace:*",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"lit": "^3.2.0" "lit": "^3.2.0"
}, },
"exports": { "exports": {

View File

@@ -42,7 +42,7 @@
"@floating-ui/dom": "^1.6.10", "@floating-ui/dom": "^1.6.10",
"@lit/context": "^1.1.2", "@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"@types/hast": "^3.0.4", "@types/hast": "^3.0.4",
"@types/mdast": "^4.0.4", "@types/mdast": "^4.0.4",
"collapse-white-space": "^2.1.0", "collapse-white-space": "^2.1.0",

View File

@@ -3673,7 +3673,7 @@ hhh
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: '--affine-note-background-white', background: DEFAULT_NOTE_BACKGROUND_COLOR,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: 'both', displayMode: 'both',

View File

@@ -84,7 +84,6 @@ import { EdgelessFontWeightAndStylePanel } from './root-block/edgeless/component
import { EdgelessLineWidthPanel } from './root-block/edgeless/components/panel/line-width-panel.js'; import { EdgelessLineWidthPanel } from './root-block/edgeless/components/panel/line-width-panel.js';
import { NoteDisplayModePanel } from './root-block/edgeless/components/panel/note-display-mode-panel.js'; import { NoteDisplayModePanel } from './root-block/edgeless/components/panel/note-display-mode-panel.js';
import { EdgelessNoteShadowPanel } from './root-block/edgeless/components/panel/note-shadow-panel.js'; import { EdgelessNoteShadowPanel } from './root-block/edgeless/components/panel/note-shadow-panel.js';
import { EdgelessOneRowColorPanel } from './root-block/edgeless/components/panel/one-row-color-panel.js';
import { EdgelessScalePanel } from './root-block/edgeless/components/panel/scale-panel.js'; import { EdgelessScalePanel } from './root-block/edgeless/components/panel/scale-panel.js';
import { EdgelessShapePanel } from './root-block/edgeless/components/panel/shape-panel.js'; import { EdgelessShapePanel } from './root-block/edgeless/components/panel/shape-panel.js';
import { EdgelessShapeStylePanel } from './root-block/edgeless/components/panel/shape-style-panel.js'; import { EdgelessShapeStylePanel } from './root-block/edgeless/components/panel/shape-style-panel.js';
@@ -437,10 +436,6 @@ export function effects() {
'edgeless-frame-title-editor', 'edgeless-frame-title-editor',
EdgelessFrameTitleEditor EdgelessFrameTitleEditor
); );
customElements.define(
'edgeless-one-row-color-panel',
EdgelessOneRowColorPanel
);
customElements.define('edgeless-text-editor', EdgelessTextEditor); customElements.define('edgeless-text-editor', EdgelessTextEditor);
customElements.define('affine-image-toolbar', AffineImageToolbar); customElements.define('affine-image-toolbar', AffineImageToolbar);
customElements.define('mini-mindmap-root-block', MindmapRootBlock); customElements.define('mini-mindmap-root-block', MindmapRootBlock);

View File

@@ -3,6 +3,7 @@ import { WithDisposable } from '@blocksuite/global/utils';
import { html, LitElement } from 'lit'; import { html, LitElement } from 'lit';
import { property, query, state } from 'lit/decorators.js'; import { property, query, state } from 'lit/decorators.js';
import { choose } from 'lit/directives/choose.js'; import { choose } from 'lit/directives/choose.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { styleMap } from 'lit/directives/style-map.js'; import { styleMap } from 'lit/directives/style-map.js';
import type { ColorEvent } from '../panel/color-panel.js'; import type { ColorEvent } from '../panel/color-panel.js';
@@ -12,7 +13,7 @@ import type {
PickColorEvent, PickColorEvent,
PickColorType, PickColorType,
} from './types.js'; } from './types.js';
import { keepColor, preprocessColor } from './utils.js'; import { keepColor, preprocessColor, rgbaToHex8 } from './utils.js';
type Type = 'normal' | 'custom'; type Type = 'normal' | 'custom';
@@ -38,10 +39,28 @@ export class EdgelessColorPickerButton extends WithDisposable(LitElement) {
get customButtonStyle() { get customButtonStyle() {
let b = 'transparent'; let b = 'transparent';
let c = 'transparent'; let c = 'transparent';
if (!this.isCSSVariable) {
if (!this.isCustomColor) {
return { '--b': b, '--c': c };
}
if (this.isCSSVariable) {
if (!this.color.endsWith('transparent')) {
b = 'var(--affine-background-overlay-panel-color)';
c = keepColor(
rgbaToHex8(
preprocessColor(window.getComputedStyle(this))({
type: 'normal',
value: this.color,
}).rgba
)
);
}
} else {
b = 'var(--affine-background-overlay-panel-color)'; b = 'var(--affine-background-overlay-panel-color)';
c = keepColor(this.color); c = keepColor(this.color);
} }
return { '--b': b, '--c': c }; return { '--b': b, '--c': c };
} }
@@ -49,6 +68,10 @@ export class EdgelessColorPickerButton extends WithDisposable(LitElement) {
return this.color.startsWith('--'); return this.color.startsWith('--');
} }
get isCustomColor() {
return !this.palettes.includes(this.color);
}
get tabContentPadding() { get tabContentPadding() {
return `${this.tabType === 'custom' ? 0 : 8}px`; return `${this.tabType === 'custom' ? 0 : 8}px`;
} }
@@ -101,7 +124,9 @@ export class EdgelessColorPickerButton extends WithDisposable(LitElement) {
<slot name="separator"></slot> <slot name="separator"></slot>
<edgeless-color-panel <edgeless-color-panel
role="listbox" role="listbox"
class=${ifDefined(this.colorPanelClass)}
.value=${this.color} .value=${this.color}
.palettes=${this.palettes}
.options=${this.palettes} .options=${this.palettes}
.hollowCircle=${this.hollowCircle} .hollowCircle=${this.hollowCircle}
.openColorPicker=${this.switchToCustomTab} .openColorPicker=${this.switchToCustomTab}
@@ -111,7 +136,7 @@ export class EdgelessColorPickerButton extends WithDisposable(LitElement) {
<edgeless-color-custom-button <edgeless-color-custom-button
slot="custom" slot="custom"
style=${styleMap(this.customButtonStyle)} style=${styleMap(this.customButtonStyle)}
.active=${!this.isCSSVariable} ?active=${this.isCustomColor}
@click=${this.switchToCustomTab} @click=${this.switchToCustomTab}
></edgeless-color-custom-button> ></edgeless-color-custom-button>
</edgeless-color-panel> </edgeless-color-panel>
@@ -142,6 +167,9 @@ export class EdgelessColorPickerButton extends WithDisposable(LitElement) {
@property() @property()
accessor color!: string; accessor color!: string;
@property()
accessor colorPanelClass: string | undefined = undefined;
@property({ attribute: false }) @property({ attribute: false })
accessor colors: { type: ModeType; value: string }[] = []; accessor colors: { type: ModeType; value: string }[] = [];

View File

@@ -1,18 +1,35 @@
import { css, html, LitElement } from 'lit'; import { css, html, LitElement } from 'lit';
import { property } from 'lit/decorators.js'; import { property } from 'lit/decorators.js';
import { colorContainerStyles } from '../panel/color-panel.js';
export class EdgelessColorCustomButton extends LitElement { export class EdgelessColorCustomButton extends LitElement {
static override styles = css` static override styles = css`
${colorContainerStyles} :host {
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
cursor: pointer;
}
:host([active]):after {
position: absolute;
display: block;
content: '';
width: 27px;
height: 27px;
border: 1.5px solid var(--affine-primary-color);
border-radius: 50%;
box-sizing: border-box;
overflow: hidden;
pointer-events: none;
}
.color-custom { .color-custom {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: 16px; width: 21px;
height: 16px; height: 21px;
border-radius: 50%; border-radius: 50%;
box-sizing: border-box; box-sizing: border-box;
overflow: hidden; overflow: hidden;
@@ -43,15 +60,11 @@ export class EdgelessColorCustomButton extends LitElement {
`; `;
override render() { override render() {
return html` return html`<div class="color-unit color-custom"></div>`;
<div class="color-container" ?active=${this.active}>
<div class="color-unit color-custom"></div>
</div>
`;
} }
@property({ attribute: false }) @property({ attribute: true, type: Boolean })
accessor active!: boolean; accessor active: boolean = false;
} }
declare global { declare global {

View File

@@ -1,15 +1,9 @@
import { TransparentIcon } from '@blocksuite/affine-components/icons'; import { Black, ColorScheme, PALETTES, White } from '@blocksuite/affine-model';
import { import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
ColorScheme, import { css, html, LitElement, nothing, svg, type TemplateResult } from 'lit';
LINE_COLORS,
LineColor,
NoteBackgroundColor,
ShapeFillColor,
} from '@blocksuite/affine-model';
import { css, html, LitElement, nothing } from 'lit';
import { property } from 'lit/decorators.js'; import { property } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { repeat } from 'lit/directives/repeat.js'; import { repeat } from 'lit/directives/repeat.js';
import { styleMap } from 'lit/directives/style-map.js';
export class ColorEvent extends Event { export class ColorEvent extends Event {
detail: string; detail: string;
@@ -28,70 +22,64 @@ export class ColorEvent extends Event {
} }
export const GET_DEFAULT_LINE_COLOR = (theme: ColorScheme) => { export const GET_DEFAULT_LINE_COLOR = (theme: ColorScheme) => {
return theme === ColorScheme.Dark ? LineColor.White : LineColor.Black; return theme === ColorScheme.Dark ? White : Black;
}; };
export function isTransparent(color: string) { export function isTransparent(color: string) {
return color.toLowerCase().endsWith('transparent'); return color.toLowerCase().endsWith('transparent');
} }
function isSameColorWithBackground(color: string) { function TransparentIcon(hollowCircle = false) {
const colors: string[] = [ const CircleIcon: TemplateResult | typeof nothing = hollowCircle
LineColor.Black, ? svg`<circle cx="10" cy="10" r="8" fill="white" />`
LineColor.White,
NoteBackgroundColor.Black,
NoteBackgroundColor.White,
ShapeFillColor.Black,
ShapeFillColor.White,
];
return colors.includes(color.toLowerCase());
}
function TransparentColor(hollowCircle = false) {
const containerStyle = {
position: 'relative',
width: '16px',
height: '16px',
stroke: 'none',
};
const maskStyle = {
position: 'absolute',
width: '10px',
height: '10px',
left: '3px',
top: '3.5px',
borderRadius: '50%',
background: 'var(--affine-background-overlay-panel-color)',
};
const mask = hollowCircle
? html`<div style=${styleMap(maskStyle)}></div>`
: nothing; : nothing;
return html` return html`
<div style=${styleMap(containerStyle)}>${TransparentIcon} ${mask}</div> <svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M-1.17405 5.17857C-1.2241 5.5285 -1.25 5.88623 -1.25 6.25V8.39286H1.96429V11.6071H-1.25V13.75C-1.25 14.1138 -1.2241 14.4715 -1.17405 14.8214H1.96429V18.0357H0.0943102C0.602244 18.7639 1.23609 19.3978 1.96429 19.9057V18.0357L5.17857 18.0357V21.174C5.5285 21.2241 5.88623 21.25 6.25 21.25H8.39286V18.0357H11.6071V21.25H13.75C14.1138 21.25 14.4715 21.2241 14.8214 21.174V18.0357H18.0357L18.0357 19.9057C18.7639 19.3978 19.3978 18.7639 19.9057 18.0357L18.0357 18.0357V14.8214H21.174C21.2241 14.4715 21.25 14.1138 21.25 13.75V11.6071H18.0357V8.39286H21.25V6.25C21.25 5.88623 21.2241 5.5285 21.174 5.17857H18.0357V1.96429H19.9057C19.3978 1.23609 18.7639 0.602244 18.0357 0.09431L18.0357 1.96429H14.8214V-1.17405C14.4715 -1.2241 14.1138 -1.25 13.75 -1.25H11.6071V1.96429H8.39286V-1.25H6.25C5.88623 -1.25 5.5285 -1.2241 5.17857 -1.17405V1.96429H1.96429V0.0943099C1.23609 0.602244 0.602244 1.23609 0.0943099 1.96429H1.96429V5.17857H-1.17405ZM5.17857 5.17857V1.96429H8.39286V5.17857H5.17857ZM5.17857 8.39286H1.96429V5.17857H5.17857V8.39286ZM8.39286 8.39286V5.17857H11.6071V8.39286H8.39286ZM8.39286 11.6071V8.39286H5.17857V11.6071H1.96429V14.8214H5.17857V18.0357H8.39286V14.8214H11.6071V18.0357H14.8214V14.8214H18.0357V11.6071H14.8214V8.39286H18.0357V5.17857H14.8214V1.96429H11.6071V5.17857H14.8214V8.39286H11.6071V11.6071H8.39286ZM8.39286 11.6071V14.8214H5.17857V11.6071H8.39286ZM11.6071 11.6071H14.8214V14.8214H11.6071V11.6071Z"
fill="#D9D9D9"
/>
${CircleIcon}
</svg>
`; `;
} }
function BorderedHollowCircle(color: string) { function CircleIcon(color: string) {
const valid = color.startsWith('--');
const strokeWidth = valid && isSameColorWithBackground(color) ? 1 : 0;
const style = {
fill: valid ? `var(${color})` : color,
stroke: 'var(--affine-border-color)',
};
return html` return html`
<svg <svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 20 20"
fill="${color}"
>
<circle cx="10" cy="10" r="10" />
</svg>
`;
}
function HollowCircleIcon(color: string) {
return html`
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
viewBox="0 0 20 20"
fill="${color}"
> >
<path <path
d="M12.3125 8C12.3125 10.3817 10.3817 12.3125 8 12.3125C5.61827 12.3125 3.6875 10.3817 3.6875 8C3.6875 5.61827 5.61827 3.6875 8 3.6875C10.3817 3.6875 12.3125 5.61827 12.3125 8ZM8 15.5C12.1421 15.5 15.5 12.1421 15.5 8C15.5 3.85786 12.1421 0.5 8 0.5C3.85786 0.5 0.5 3.85786 0.5 8C0.5 12.1421 3.85786 15.5 8 15.5Z" fill-rule="evenodd"
stroke-width="${strokeWidth}" clip-rule="evenodd"
style=${styleMap(style)} d="M10 17C13.866 17 17 13.866 17 10C17 6.13401 13.866 3 10 3C6.13401 3 3 6.13401 3 10C3 13.866 6.13401 17 10 17ZM10 20C15.5228 20 20 15.5228 20 10C20 4.47715 15.5228 0 10 0C4.47715 0 0 4.47715 0 10C0 15.5228 4.47715 20 10 20Z"
/> />
</svg> </svg>
`; `;
@@ -99,76 +87,82 @@ function BorderedHollowCircle(color: string) {
function AdditionIcon(color: string, hollowCircle: boolean) { function AdditionIcon(color: string, hollowCircle: boolean) {
if (isTransparent(color)) { if (isTransparent(color)) {
return TransparentColor(hollowCircle); return TransparentIcon(hollowCircle);
} }
if (hollowCircle) { if (hollowCircle) {
return BorderedHollowCircle(color); return HollowCircleIcon(color);
}
return nothing;
} }
export function ColorUnit( return CircleIcon(color);
color: string,
{
hollowCircle,
letter,
}: {
hollowCircle?: boolean;
letter?: boolean;
} = {}
) {
const additionIcon = AdditionIcon(color, !!hollowCircle);
const colorStyle =
!hollowCircle && !isTransparent(color)
? { background: `var(${color})` }
: {};
const borderStyle =
isSameColorWithBackground(color) && !hollowCircle
? {
border: '0.5px solid var(--affine-border-color)',
}
: {};
const style = {
width: '16px',
height: '16px',
borderRadius: '50%',
boxSizing: 'border-box',
overflow: 'hidden',
...borderStyle,
...colorStyle,
};
return html`
<div
class="color-unit"
style=${styleMap(style)}
aria-label=${color.toLowerCase()}
data-letter=${letter ? 'A' : ''}
>
${additionIcon}
</div>
`;
} }
export class EdgelessColorButton extends LitElement { export class EdgelessColorButton extends LitElement {
static override styles = css` static override styles = css`
:host { :host {
position: relative;
width: 20px;
height: 20px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
cursor: pointer;
}
.color-unit {
position: relative;
width: 16px;
height: 16px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
box-sizing: border-box;
}
.color-unit svg {
width: 100%;
height: 100%;
border-radius: 50%;
overflow: hidden;
}
:host .color-unit:after {
position: absolute;
display: block;
content: '';
width: 100%;
height: 100%;
border-radius: 50%;
box-sizing: border-box;
overflow: hidden;
pointer-events: none;
border-width: 0.5px;
border-style: solid;
border-color: ${unsafeCSSVarV2('layer/insideBorder/blackBorder')};
}
:host(.black) .color-unit:after {
border-color: ${unsafeCSSVarV2('layer/insideBorder/border')};
}
:host(.large) {
width: 24px;
height: 24px;
}
:host(.large) .color-unit {
width: 20px; width: 20px;
height: 20px; height: 20px;
} }
.color-unit { :host([active]):after {
width: 16px; position: absolute;
height: 16px; display: block;
content: '';
width: 27px;
height: 27px;
border: 1.5px solid var(--affine-primary-color);
border-radius: 50%; border-radius: 50%;
box-sizing: border-box; box-sizing: border-box;
overflow: hidden; overflow: hidden;
pointer-events: none;
} }
`; `;
@@ -178,86 +172,55 @@ export class EdgelessColorButton extends LitElement {
} }
override render() { override render() {
const { color, hollowCircle, letter } = this; const { color, preprocessColor, hollowCircle, letter } = this;
const additionIcon = AdditionIcon(color, !!hollowCircle); const additionIcon = AdditionIcon(preprocessColor, !!hollowCircle);
const style: Record<string, string> = {};
if (!hollowCircle) {
style.background = this.preprocessColor;
if (isSameColorWithBackground(color)) {
style.border = '0.5px solid var(--affine-border-color)';
}
}
return html`<div return html`<div
class="color-unit" class="color-unit"
aria-label=${color.toLowerCase()} aria-label=${color}
data-letter=${letter ? 'A' : nothing} data-letter=${letter ? 'A' : nothing}
style=${styleMap(style)}
> >
${additionIcon} ${additionIcon}
</div>`; </div>`;
} }
@property({ attribute: true, type: Boolean })
accessor active: boolean = false;
@property({ attribute: false }) @property({ attribute: false })
accessor color!: string; accessor color!: string;
@property({ attribute: false }) @property({ attribute: false })
accessor hollowCircle: boolean | undefined = undefined; accessor hollowCircle: boolean = false;
@property({ attribute: false }) @property({ attribute: false })
accessor letter: boolean | undefined = undefined; accessor letter: boolean | undefined = undefined;
} }
export const colorContainerStyles = css`
.color-container {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
border-radius: 50%;
box-sizing: border-box;
overflow: hidden;
cursor: pointer;
padding: 2px;
}
.color-unit::before {
content: attr(data-letter);
display: block;
font-size: 12px;
}
.color-container[active]:after {
position: absolute;
width: 20px;
height: 20px;
border: 0.5px solid var(--affine-primary-color);
border-radius: 50%;
box-sizing: border-box;
content: attr(data-letter);
}
`;
export class EdgelessColorPanel extends LitElement { export class EdgelessColorPanel extends LitElement {
static override styles = css` static override styles = css`
:host { :host {
display: grid;
grid-gap: 4px;
grid-template-columns: repeat(9, 1fr);
}
/* note */
:host(.small) {
grid-template-columns: repeat(6, 1fr);
grid-gap: 8px;
}
/* edgeless toolbar */
:host(.one-way) {
display: flex; display: flex;
flex-direction: row; flex-wrap: nowrap;
flex-wrap: wrap; padding: 0 2px;
width: 184px; gap: 14px;
gap: 8px; box-sizing: border-box;
background: var(--affine-background-overlay-panel-color);
} }
${colorContainerStyles}
`; `;
get palettes() {
return this.hasTransparent
? ['--affine-palette-transparent', ...this.options]
: this.options;
}
onSelect(value: string) { onSelect(value: string) {
this.dispatchEvent( this.dispatchEvent(
new ColorEvent('select', { new ColorEvent('select', {
@@ -274,24 +237,20 @@ export class EdgelessColorPanel extends LitElement {
${repeat( ${repeat(
this.palettes, this.palettes,
color => color, color => color,
color => { color =>
const unit = ColorUnit(color, { html`<edgeless-color-button
hollowCircle: this.hollowCircle, class=${classMap({
letter: this.showLetterMark, large: true,
}); black: color.startsWith('--') && color.endsWith('black'),
})}
return html` .color=${color}
<div .letter=${this.showLetterMark}
class="color-container" .hollowCircle=${this.hollowCircle}
?active=${color === this.value} ?active=${color === this.value}
@click=${() => this.onSelect(color)} @click=${() => this.onSelect(color)}
> >
${unit} </edgeless-color-button>`
</div>
`;
}
)} )}
</div>
<slot name="custom"></slot> <slot name="custom"></slot>
`; `;
} }
@@ -306,7 +265,7 @@ export class EdgelessColorPanel extends LitElement {
accessor openColorPicker!: (e: MouseEvent) => void; accessor openColorPicker!: (e: MouseEvent) => void;
@property({ type: Array }) @property({ type: Array })
accessor options: readonly string[] = LINE_COLORS; accessor palettes: readonly string[] = PALETTES;
@property({ attribute: false }) @property({ attribute: false })
accessor showLetterMark = false; accessor showLetterMark = false;
@@ -334,11 +293,11 @@ export class EdgelessTextColorIcon extends LitElement {
override render() { override render() {
return html` return html`
<svg <svg
xmlns="http://www.w3.org/2000/svg"
width="20" width="20"
height="20" height="20"
viewBox="0 0 20 20" viewBox="0 0 20 20"
fill="none" fill="none"
xmlns="http://www.w3.org/2000/svg"
> >
<path <path
fill-rule="evenodd" fill-rule="evenodd"

View File

@@ -1,15 +1,17 @@
import { LineWidth } from '@blocksuite/affine-model'; import { LINE_WIDTHS, LineWidth } from '@blocksuite/affine-model';
import { requestConnectedFrame } from '@blocksuite/affine-shared/utils'; import { clamp, on, once } from '@blocksuite/affine-shared/utils';
import { WithDisposable } from '@blocksuite/global/utils'; import { WithDisposable } from '@blocksuite/global/utils';
import { css, html, LitElement, nothing, type PropertyValues } from 'lit'; import { css, html, LitElement, nothing, type PropertyValues } from 'lit';
import { property, query, queryAll } from 'lit/decorators.js'; import { property, query } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
type DragConfig = { interface Config {
stepWidth: number; width: number;
boundLeft: number; itemSize: number;
containerWidth: number; itemIconSize: number;
bottomLineWidth: number; dragHandleSize: number;
}; count: number;
}
export class LineWidthEvent extends Event { export class LineWidthEvent extends Event {
detail: LineWidth; detail: LineWidth;
@@ -34,10 +36,28 @@ export class EdgelessLineWidthPanel extends WithDisposable(LitElement) {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
align-self: stretch; align-self: stretch;
--width: 140px;
--item-size: 16px;
--item-icon-size: 8px;
--drag-handle-size: 14px;
--cursor: 0;
--count: 6;
/* (16 - 14) / 2 + (cursor / (count - 1)) * (140 - 16) */
--drag-handle-center-x: calc(
(var(--item-size) - var(--drag-handle-size)) / 2 +
(var(--cursor) / (var(--count) - 1)) *
(var(--width) - var(--item-size))
);
}
:host([disabled]) {
opacity: 0.5;
pointer-events: none;
} }
.line-width-panel { .line-width-panel {
width: 108px; width: var(--width);
height: 24px; height: 24px;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@@ -51,165 +71,70 @@ export class EdgelessLineWidthPanel extends WithDisposable(LitElement) {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: 16px; width: var(--item-size);
height: 16px; height: var(--item-size);
z-index: 2; z-index: 2;
} }
.line-width-icon { .line-width-icon {
width: 4px; width: var(--item-icon-size);
height: 4px; height: var(--item-icon-size);
border-radius: 50%;
background-color: var(--affine-border-color); background-color: var(--affine-border-color);
border-radius: 50%;
} }
.line-width-button:nth-child(1) { .line-width-button[data-selected] .line-width-icon {
margin-right: 0; background-color: var(--affine-icon-color);
}
.line-width-button:nth-child(6) {
margin-left: 0;
} }
.drag-handle { .drag-handle {
position: absolute; position: absolute;
left: 0; width: var(--drag-handle-size);
top: 50%; height: var(--drag-handle-size);
width: 8px;
height: 8px;
transform: translateY(-50%) translateX(4px);
border-radius: 50%; border-radius: 50%;
background-color: var(--affine-icon-color); background-color: var(--affine-icon-color);
z-index: 3; z-index: 3;
transform: translateX(var(--drag-handle-center-x));
} }
.bottom-line, .bottom-line,
.line-width-overlay { .line-width-overlay {
left: 8px;
top: 50%;
transform: translateY(-50%);
height: 1px;
background-color: var(--affine-border-color);
position: absolute; position: absolute;
height: 1px;
left: calc(var(--item-size) / 2);
} }
.bottom-line { .bottom-line {
width: calc(100% - 16px); width: calc(100% - var(--item-size));
background-color: var(--affine-border-color); background-color: var(--affine-border-color);
} }
.line-width-overlay { .line-width-overlay {
width: 0;
background-color: var(--affine-icon-color); background-color: var(--affine-icon-color);
z-index: 1; z-index: 1;
width: var(--drag-handle-center-x);
} }
`; `;
private _dragConfig: DragConfig | null = null; private readonly _getDragHandlePosition = (e: PointerEvent) => {
return clamp(e.offsetX, 0, this.config.width);
private readonly _getDragHandlePosition = (
e: PointerEvent,
config: DragConfig
) => {
const x = e.clientX;
const { boundLeft, bottomLineWidth, stepWidth, containerWidth } = config;
let steps: number;
if (x <= boundLeft) {
steps = 0;
} else if (x - boundLeft >= containerWidth) {
steps = 100;
} else {
steps = Math.floor((x - boundLeft) / stepWidth);
}
// The drag handle should not be dragged to the left of the first icon or right of the last icon.
// Calculate the drag handle position based on the steps.
const bottomLineOffsetX = 4;
const bottomLineStepWidth = (bottomLineWidth - bottomLineOffsetX) / 100;
const dragHandlerPosition = steps * bottomLineStepWidth;
return dragHandlerPosition;
}; };
private readonly _onPointerDown = (e: PointerEvent) => { private readonly _onPointerDown = (e: PointerEvent) => {
e.preventDefault(); e.preventDefault();
if (this.disable) return;
const { left, width } = this._lineWidthPanel.getBoundingClientRect();
const bottomLineWidth = this._bottomLine.getBoundingClientRect().width;
this._dragConfig = {
stepWidth: width / 100,
boundLeft: left,
containerWidth: width,
bottomLineWidth,
};
this._onPointerMove(e); this._onPointerMove(e);
const dispose = on(this, 'pointermove', this._onPointerMove);
this._disposables.add(once(this, 'pointerup', dispose));
this._disposables.add(once(this, 'pointerout', dispose));
}; };
private readonly _onPointerMove = (e: PointerEvent) => { private readonly _onPointerMove = (e: PointerEvent) => {
e.preventDefault(); e.preventDefault();
if (!this._dragConfig) return;
const dragHandlerPosition = this._getDragHandlePosition(
e,
this._dragConfig
);
this._dragHandle.style.left = `${dragHandlerPosition}%`;
this._lineWidthOverlay.style.width = `${dragHandlerPosition}%`;
this._updateIconsColor();
};
private readonly _onPointerOut = (e: PointerEvent) => { const x = this._getDragHandlePosition(e);
// If the pointer is out of the line width panel
// Stop dragging and update the selected size by nearest size.
e.preventDefault();
if (!this._dragConfig) return;
const dragHandlerPosition = this._getDragHandlePosition(
e,
this._dragConfig
);
this._updateLineWidthPanelByDragHandlePosition(dragHandlerPosition);
this._dragConfig = null;
};
private readonly _onPointerUp = (e: PointerEvent) => { this._updateLineWidthPanelByDragHandlePosition(x);
e.preventDefault();
if (!this._dragConfig) return;
const dragHandlerPosition = this._getDragHandlePosition(
e,
this._dragConfig
);
this._updateLineWidthPanelByDragHandlePosition(dragHandlerPosition);
this._dragConfig = null;
};
private readonly _updateIconsColor = () => {
if (!this._dragHandle.offsetParent) {
requestConnectedFrame(() => this._updateIconsColor(), this);
return;
}
const dragHandleRect = this._dragHandle.getBoundingClientRect();
const dragHandleCenterX = dragHandleRect.left + dragHandleRect.width / 2;
// All the icons located at the left of the drag handle should be filled with the icon color.
const leftIcons = [];
// All the icons located at the right of the drag handle should be filled with the border color.
const rightIcons = [];
for (const icon of this._lineWidthIcons) {
const { left, width } = icon.getBoundingClientRect();
const centerX = left + width / 2;
if (centerX < dragHandleCenterX) {
leftIcons.push(icon);
} else {
rightIcons.push(icon);
}
}
leftIcons.forEach(
icon => (icon.style.backgroundColor = 'var(--affine-icon-color)')
);
rightIcons.forEach(
icon => (icon.style.backgroundColor = 'var(--affine-border-color)')
);
}; };
private _onSelect(lineWidth: LineWidth) { private _onSelect(lineWidth: LineWidth) {
@@ -227,103 +152,66 @@ export class EdgelessLineWidthPanel extends WithDisposable(LitElement) {
private _updateLineWidthPanel(selectedSize: LineWidth) { private _updateLineWidthPanel(selectedSize: LineWidth) {
if (!this._lineWidthOverlay) return; if (!this._lineWidthOverlay) return;
let width = 0; const index = this.lineWidths.findIndex(w => w === selectedSize);
let dragHandleOffsetX = 0; if (index === -1) return;
switch (selectedSize) {
case LineWidth.Two: this.style.setProperty('--cursor', `${index}`);
width = 0;
break;
case LineWidth.Four:
width = 16;
dragHandleOffsetX = 1;
break;
case LineWidth.Six:
width = 32;
dragHandleOffsetX = 2;
break;
case LineWidth.Eight:
width = 48;
dragHandleOffsetX = 3;
break;
case LineWidth.Ten:
width = 64;
dragHandleOffsetX = 4;
break;
default:
width = 80;
dragHandleOffsetX = 4;
} }
dragHandleOffsetX += 4; private _updateLineWidthPanelByDragHandlePosition(x: number) {
this._lineWidthOverlay.style.width = `${width}%`;
this._dragHandle.style.left = `${width}%`;
this._dragHandle.style.transform = `translateY(-50%) translateX(${dragHandleOffsetX}px)`;
this._updateIconsColor();
}
private _updateLineWidthPanelByDragHandlePosition(
dragHandlerPosition: number
) {
// Calculate the selected size based on the drag handle position. // Calculate the selected size based on the drag handle position.
// Need to select the nearest size. // Need to select the nearest size.
let selectedSize = this.selectedSize;
if (dragHandlerPosition <= 12) { const {
selectedSize = LineWidth.Two; config: { width, itemSize, count },
} else if (dragHandlerPosition > 12 && dragHandlerPosition <= 26) { lineWidths,
selectedSize = LineWidth.Four; } = this;
} else if (dragHandlerPosition > 26 && dragHandlerPosition <= 40) { const targetWidth = width - itemSize;
selectedSize = LineWidth.Six; const halfItemSize = itemSize / 2;
} else if (dragHandlerPosition > 40 && dragHandlerPosition <= 54) { const offsetX = halfItemSize + (width - itemSize * count) / (count - 1) / 2;
selectedSize = LineWidth.Eight; const selectedSize = lineWidths.findLast((_, n) => {
} else if (dragHandlerPosition > 54 && dragHandlerPosition <= 68) { const cx = halfItemSize + (n / (count - 1)) * targetWidth;
selectedSize = LineWidth.Ten; return x >= cx - offsetX && x < cx + offsetX;
} else { });
selectedSize = LineWidth.Twelve; if (!selectedSize) return;
}
this._updateLineWidthPanel(selectedSize); this._updateLineWidthPanel(selectedSize);
this._onSelect(selectedSize); this._onSelect(selectedSize);
} }
override disconnectedCallback(): void { override connectedCallback() {
this._disposables.dispose(); super.connectedCallback();
const {
style,
config: { width, itemSize, itemIconSize, dragHandleSize, count },
} = this;
style.setProperty('--width', `${width}px`);
style.setProperty('--item-size', `${itemSize}px`);
style.setProperty('--item-icon-size', `${itemIconSize}px`);
style.setProperty('--drag-handle-size', `${dragHandleSize}px`);
style.setProperty('--count', `${count}`);
} }
override firstUpdated(): void { override firstUpdated() {
this._updateLineWidthPanel(this.selectedSize); this._updateLineWidthPanel(this.selectedSize);
this._disposables.addFromEvent(this, 'pointerdown', this._onPointerDown); this._disposables.addFromEvent(this, 'pointerdown', this._onPointerDown);
this._disposables.addFromEvent(this, 'pointermove', this._onPointerMove);
this._disposables.addFromEvent(this, 'pointerup', this._onPointerUp);
this._disposables.addFromEvent(this, 'pointerout', this._onPointerOut);
} }
override render() { override render() {
return html`<style> return html`<div class="line-width-panel">
.line-width-panel { ${repeat(
opacity: ${this.disable ? '0.5' : '1'}; this.lineWidths,
} w => w,
</style> (w, n) =>
<div html`<div
class="line-width-panel" class="line-width-button"
@mousedown="${(e: Event) => e.preventDefault()}" aria-label=${w}
data-index=${n}
?data-selected=${w <= this.selectedSize}
> >
<div class="line-width-button">
<div class="line-width-icon"></div> <div class="line-width-icon"></div>
</div> </div>`
<div class="line-width-button"> )}
<div class="line-width-icon"></div>
</div>
<div class="line-width-button">
<div class="line-width-icon"></div>
</div>
<div class="line-width-button">
<div class="line-width-icon"></div>
</div>
<div class="line-width-button">
<div class="line-width-icon"></div>
</div>
<div class="line-width-button">
<div class="line-width-icon"></div>
</div>
<div class="drag-handle"></div> <div class="drag-handle"></div>
<div class="bottom-line"></div> <div class="bottom-line"></div>
<div class="line-width-overlay"></div> <div class="line-width-overlay"></div>
@@ -339,27 +227,26 @@ export class EdgelessLineWidthPanel extends WithDisposable(LitElement) {
} }
} }
@query('.bottom-line')
private accessor _bottomLine!: HTMLElement;
@query('.drag-handle')
private accessor _dragHandle!: HTMLElement;
@queryAll('.line-width-icon')
private accessor _lineWidthIcons!: NodeListOf<HTMLElement>;
@query('.line-width-overlay') @query('.line-width-overlay')
private accessor _lineWidthOverlay!: HTMLElement; private accessor _lineWidthOverlay!: HTMLElement;
@query('.line-width-panel') accessor config: Config = {
private accessor _lineWidthPanel!: HTMLElement; width: 140,
itemSize: 16,
itemIconSize: 8,
dragHandleSize: 14,
count: LINE_WIDTHS.length,
};
@property({ attribute: false }) @property({ attribute: false, type: Boolean })
accessor disable = false; accessor disabled = false;
@property({ attribute: false }) @property({ attribute: false })
accessor hasTooltip = true; accessor hasTooltip = true;
@property({ attribute: false })
accessor lineWidths: LineWidth[] = LINE_WIDTHS;
@property({ attribute: false }) @property({ attribute: false })
accessor selectedSize: LineWidth = LineWidth.Two; accessor selectedSize: LineWidth = LineWidth.Two;
} }

View File

@@ -1,38 +0,0 @@
import { css } from 'lit';
import { colorContainerStyles, EdgelessColorPanel } from './color-panel.js';
export class EdgelessOneRowColorPanel extends EdgelessColorPanel {
static override styles = css`
:host {
display: flex;
flex-wrap: nowrap;
padding: 0 2px;
gap: 14px;
box-sizing: border-box;
background: var(--affine-background-overlay-panel-color);
}
${colorContainerStyles}
.color-container {
width: 20px;
height: 20px;
}
.color-container::before {
content: '';
position: absolute;
width: 2px;
right: calc(100% + 7px);
height: 100%;
// FIXME: not working
scroll-snap-align: start;
}
`;
}
declare global {
interface HTMLElementTagNameMap {
'edgeless-one-row-color-panel': EdgelessOneRowColorPanel;
}
}

View File

@@ -1,4 +1,4 @@
import { SHAPE_STROKE_COLORS, StrokeStyle } from '@blocksuite/affine-model'; import { PALETTES, type StrokeStyle } from '@blocksuite/affine-model';
import { WithDisposable } from '@blocksuite/global/utils'; import { WithDisposable } from '@blocksuite/global/utils';
import { css, html, LitElement } from 'lit'; import { css, html, LitElement } from 'lit';
import { property } from 'lit/decorators.js'; import { property } from 'lit/decorators.js';
@@ -30,7 +30,6 @@ export class StrokeStylePanel extends WithDisposable(LitElement) {
selectedLineSize: this.strokeWidth, selectedLineSize: this.strokeWidth,
selectedLineStyle: this.strokeStyle, selectedLineStyle: this.strokeStyle,
onClick: e => this.setStrokeStyle(e), onClick: e => this.setStrokeStyle(e),
lineStyles: [StrokeStyle.Solid, StrokeStyle.Dash],
})} })}
</div> </div>
<editor-toolbar-separator <editor-toolbar-separator
@@ -39,7 +38,7 @@ export class StrokeStylePanel extends WithDisposable(LitElement) {
<edgeless-color-panel <edgeless-color-panel
role="listbox" role="listbox"
aria-label="Border colors" aria-label="Border colors"
.options=${SHAPE_STROKE_COLORS} .palettes=${PALETTES}
.value=${this.strokeColor} .value=${this.strokeColor}
.hollowCircle=${this.hollowCircle} .hollowCircle=${this.hollowCircle}
@select=${(e: ColorEvent) => this.setStrokeColor(e)} @select=${(e: ColorEvent) => this.setStrokeColor(e)}

View File

@@ -1,3 +1,4 @@
import { STROKE_COLORS } from '@blocksuite/affine-model';
import { import {
EditPropsStore, EditPropsStore,
ThemeProvider, ThemeProvider,
@@ -63,13 +64,15 @@ export class EdgelessBrushMenu extends EdgelessToolbarToolMixin(
> >
</edgeless-line-width-panel> </edgeless-line-width-panel>
<menu-divider .vertical=${true}></menu-divider> <menu-divider .vertical=${true}></menu-divider>
<edgeless-one-row-color-panel <edgeless-color-panel
class="one-way"
.value=${color} .value=${color}
.palettes=${STROKE_COLORS}
.hasTransparent=${!this.edgeless.doc.awarenessStore.getFlag( .hasTransparent=${!this.edgeless.doc.awarenessStore.getFlag(
'enable_color_picker' 'enable_color_picker'
)} )}
@select=${(e: ColorEvent) => this.onChange({ color: e.detail })} @select=${(e: ColorEvent) => this.onChange({ color: e.detail })}
></edgeless-one-row-color-panel> ></edgeless-color-panel>
</div> </div>
</edgeless-slide-menu> </edgeless-slide-menu>
`; `;

View File

@@ -6,6 +6,7 @@ import {
import { import {
ConnectorMode, ConnectorMode,
DEFAULT_CONNECTOR_COLOR, DEFAULT_CONNECTOR_COLOR,
STROKE_COLORS,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
import { import {
EditPropsStore, EditPropsStore,
@@ -127,13 +128,15 @@ export class EdgelessConnectorMenu extends EdgelessToolbarToolMixin(
> >
</edgeless-line-width-panel> </edgeless-line-width-panel>
<div class="submenu-divider"></div> <div class="submenu-divider"></div>
<edgeless-one-row-color-panel <edgeless-color-panel
class="one-way"
.value=${color} .value=${color}
.palettes=${STROKE_COLORS}
.hasTransparent=${!this.edgeless.doc.awarenessStore.getFlag( .hasTransparent=${!this.edgeless.doc.awarenessStore.getFlag(
'enable_color_picker' 'enable_color_picker'
)} )}
@select=${(e: ColorEvent) => this.onChange({ stroke: e.detail })} @select=${(e: ColorEvent) => this.onChange({ stroke: e.detail })}
></edgeless-one-row-color-panel> ></edgeless-color-panel>
</div> </div>
</edgeless-slide-menu> </edgeless-slide-menu>
`; `;

View File

@@ -68,6 +68,3 @@ export const ShapeComponentConfigMap = ShapeComponentConfig.reduce(
}, },
{} as Record<Config['name'], Config> {} as Record<Config['name'], Config>
); );
export const SHAPE_COLOR_PREFIX = '--affine-palette-shape-';
export const LINE_COLOR_PREFIX = '--affine-palette-line-';

View File

@@ -4,12 +4,13 @@ import {
} from '@blocksuite/affine-components/icons'; } from '@blocksuite/affine-components/icons';
import { import {
DEFAULT_SHAPE_FILL_COLOR, DEFAULT_SHAPE_FILL_COLOR,
LineColor, LIGHT_PALETTES,
MEDIUM_PALETTES,
SHAPE_FILL_COLORS, SHAPE_FILL_COLORS,
type ShapeFillColor,
type ShapeName, type ShapeName,
ShapeStyle, ShapeStyle,
ShapeType, ShapeType,
StrokeColor,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
import { import {
EditPropsStore, EditPropsStore,
@@ -23,11 +24,7 @@ import { property } from 'lit/decorators.js';
import type { EdgelessRootBlockComponent } from '../../../edgeless-root-block.js'; import type { EdgelessRootBlockComponent } from '../../../edgeless-root-block.js';
import { type ColorEvent, isTransparent } from '../../panel/color-panel.js'; import { type ColorEvent, isTransparent } from '../../panel/color-panel.js';
import { import { ShapeComponentConfig } from './shape-menu-config.js';
LINE_COLOR_PREFIX,
SHAPE_COLOR_PREFIX,
ShapeComponentConfig,
} from './shape-menu-config.js';
export class EdgelessShapeMenu extends SignalWatcher( export class EdgelessShapeMenu extends SignalWatcher(
WithDisposable(LitElement) WithDisposable(LitElement)
@@ -79,15 +76,19 @@ export class EdgelessShapeMenu extends SignalWatcher(
}; };
}); });
private readonly _setFillColor = (fillColor: ShapeFillColor) => { private readonly _setFillColor = (fillColor: string) => {
const filled = !isTransparent(fillColor); const filled = !isTransparent(fillColor);
let strokeColor = fillColor.replace( let strokeColor = fillColor; // white or black
SHAPE_COLOR_PREFIX,
LINE_COLOR_PREFIX if (filled) {
) as LineColor; const index = LIGHT_PALETTES.findIndex(color => color === fillColor);
if (index !== -1) {
strokeColor = MEDIUM_PALETTES[index];
}
}
if (strokeColor.endsWith('transparent')) { if (strokeColor.endsWith('transparent')) {
strokeColor = LineColor.Grey; strokeColor = StrokeColor.Grey;
} }
const { shapeName } = this._props$.value; const { shapeName } = this._props$.value;
@@ -176,15 +177,15 @@ export class EdgelessShapeMenu extends SignalWatcher(
)} )}
</div> </div>
<menu-divider .vertical=${true}></menu-divider> <menu-divider .vertical=${true}></menu-divider>
<edgeless-one-row-color-panel <edgeless-color-panel
class="one-way"
.value=${color} .value=${color}
.options=${SHAPE_FILL_COLORS} .palettes=${SHAPE_FILL_COLORS}
.hasTransparent=${!this.edgeless.doc.awarenessStore.getFlag( .hasTransparent=${!this.edgeless.doc.awarenessStore.getFlag(
'enable_color_picker' 'enable_color_picker'
)} )}
@select=${(e: ColorEvent) => @select=${(e: ColorEvent) => this._setFillColor(e.detail)}
this._setFillColor(e.detail as ShapeFillColor)} ></edgeless-color-panel>
></edgeless-one-row-color-panel>
</div> </div>
</edgeless-slide-menu> </edgeless-slide-menu>
`; `;

View File

@@ -1,3 +1,4 @@
import { STROKE_COLORS } from '@blocksuite/affine-model';
import type { GfxToolsFullOptionValue } from '@blocksuite/block-std/gfx'; import type { GfxToolsFullOptionValue } from '@blocksuite/block-std/gfx';
import { css, html, LitElement, nothing } from 'lit'; import { css, html, LitElement, nothing } from 'lit';
import { property } from 'lit/decorators.js'; import { property } from 'lit/decorators.js';
@@ -22,10 +23,12 @@ export class EdgelessTextMenu extends EdgelessToolbarToolMixin(LitElement) {
return html` return html`
<edgeless-slide-menu> <edgeless-slide-menu>
<div class="menu-content"> <div class="menu-content">
<edgeless-one-row-color-panel <edgeless-color-panel
class="one-way"
.value=${this.color} .value=${this.color}
.palettes=${STROKE_COLORS}
@select=${(e: ColorEvent) => this.onChange({ color: e.detail })} @select=${(e: ColorEvent) => this.onChange({ color: e.detail })}
></edgeless-one-row-color-panel> ></edgeless-color-panel>
</div> </div>
</edgeless-slide-menu> </edgeless-slide-menu>
`; `;

View File

@@ -1,9 +1,9 @@
import { import {
Black,
DEFAULT_ROUGHNESS, DEFAULT_ROUGHNESS,
LineColor,
LineWidth, LineWidth,
ShapeFillColor,
StrokeStyle, StrokeStyle,
White,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
export const NOTE_OVERLAY_OFFSET_X = 6; export const NOTE_OVERLAY_OFFSET_X = 6;
@@ -48,9 +48,9 @@ export const SurfaceColor = '#6046FE';
export const NoteColor = '#1E96EB'; export const NoteColor = '#1E96EB';
export const BlendColor = '#7D91FF'; export const BlendColor = '#7D91FF';
export const SHAPE_TEXT_COLOR_PURE_WHITE = LineColor.White; export const SHAPE_TEXT_COLOR_PURE_WHITE = White;
export const SHAPE_TEXT_COLOR_PURE_BLACK = LineColor.Black; export const SHAPE_TEXT_COLOR_PURE_BLACK = Black;
export const SHAPE_FILL_COLOR_BLACK = ShapeFillColor.Black; export const SHAPE_FILL_COLOR_BLACK = Black;
export const AI_CHAT_BLOCK_MIN_WIDTH = 260; export const AI_CHAT_BLOCK_MIN_WIDTH = 260;
export const AI_CHAT_BLOCK_MIN_HEIGHT = 160; export const AI_CHAT_BLOCK_MIN_HEIGHT = 160;

View File

@@ -4,7 +4,7 @@ import type {
BrushProps, BrushProps,
ColorScheme, ColorScheme,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
import { LINE_COLORS, LineWidth } from '@blocksuite/affine-model'; import { LineWidth, PALETTES } from '@blocksuite/affine-model';
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils'; import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
import { html, LitElement, nothing } from 'lit'; import { html, LitElement, nothing } from 'lit';
import { property, query, state } from 'lit/decorators.js'; import { property, query, state } from 'lit/decorators.js';
@@ -138,7 +138,7 @@ export class EdgelessChangeBrushButton extends WithDisposable(LitElement) {
.color=${selectedColor} .color=${selectedColor}
.colors=${colors} .colors=${colors}
.colorType=${type} .colorType=${type}
.palettes=${LINE_COLORS} .palettes=${PALETTES}
> >
</edgeless-color-picker-button> </edgeless-color-picker-button>
`; `;

View File

@@ -28,8 +28,8 @@ import {
ConnectorMode, ConnectorMode,
DEFAULT_FRONT_END_POINT_STYLE, DEFAULT_FRONT_END_POINT_STYLE,
DEFAULT_REAR_END_POINT_STYLE, DEFAULT_REAR_END_POINT_STYLE,
LINE_COLORS,
LineWidth, LineWidth,
PALETTES,
PointStyle, PointStyle,
StrokeStyle, StrokeStyle,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
@@ -373,7 +373,7 @@ export class EdgelessChangeConnectorButton extends WithDisposable(LitElement) {
.color=${selectedColor} .color=${selectedColor}
.colors=${colors} .colors=${colors}
.colorType=${type} .colorType=${type}
.palettes=${LINE_COLORS} .palettes=${PALETTES}
.hollowCircle=${true} .hollowCircle=${true}
> >
<div <div
@@ -390,7 +390,6 @@ export class EdgelessChangeConnectorButton extends WithDisposable(LitElement) {
selectedLineSize: selectedLineSize, selectedLineSize: selectedLineSize,
selectedLineStyle: selectedLineStyle, selectedLineStyle: selectedLineStyle,
onClick: (e: LineStyleEvent) => this._setConnectorStroke(e), onClick: (e: LineStyleEvent) => this._setConnectorStroke(e),
lineStyles: [StrokeStyle.Solid, StrokeStyle.Dash],
})} })}
</div> </div>
<editor-toolbar-separator <editor-toolbar-separator

View File

@@ -9,9 +9,9 @@ import { renderToolbarSeparator } from '@blocksuite/affine-components/toolbar';
import { import {
type ColorScheme, type ColorScheme,
DEFAULT_NOTE_HEIGHT, DEFAULT_NOTE_HEIGHT,
FRAME_BACKGROUND_COLORS,
type FrameBlockModel, type FrameBlockModel,
NoteDisplayMode, NoteDisplayMode,
PALETTES,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
import { matchFlavours } from '@blocksuite/affine-shared/utils'; import { matchFlavours } from '@blocksuite/affine-shared/utils';
import { GfxExtensionIdentifier } from '@blocksuite/block-std/gfx'; import { GfxExtensionIdentifier } from '@blocksuite/block-std/gfx';
@@ -130,8 +130,7 @@ export class EdgelessChangeFrameButton extends WithDisposable(LitElement) {
const len = frames.length; const len = frames.length;
const onlyOne = len === 1; const onlyOne = len === 1;
const colorScheme = this.edgeless.surface.renderer.getColorScheme(); const colorScheme = this.edgeless.surface.renderer.getColorScheme();
const background = const background = getMostCommonColor(frames, colorScheme) ?? 'transparent';
getMostCommonColor(frames, colorScheme) ?? '--affine-palette-transparent';
return join( return join(
[ [
@@ -204,7 +203,7 @@ export class EdgelessChangeFrameButton extends WithDisposable(LitElement) {
.color=${background} .color=${background}
.colors=${colors} .colors=${colors}
.colorType=${type} .colorType=${type}
.palettes=${FRAME_BACKGROUND_COLORS} .palettes=${PALETTES}
> >
</edgeless-color-picker-button> </edgeless-color-picker-button>
`; `;
@@ -225,7 +224,7 @@ export class EdgelessChangeFrameButton extends WithDisposable(LitElement) {
> >
<edgeless-color-panel <edgeless-color-panel
.value=${background} .value=${background}
.options=${FRAME_BACKGROUND_COLORS} .palettes=${PALETTES}
@select=${(e: ColorEvent) => this._setFrameBackground(e.detail)} @select=${(e: ColorEvent) => this._setFrameBackground(e.detail)}
> >
</edgeless-color-panel> </edgeless-color-panel>

View File

@@ -15,7 +15,7 @@ import {
import { import {
type ColorScheme, type ColorScheme,
DEFAULT_NOTE_BACKGROUND_COLOR, DEFAULT_NOTE_BACKGROUND_COLOR,
NOTE_BACKGROUND_COLORS, NOTE_BACKGROUND_PALETTES,
type NoteBlockModel, type NoteBlockModel,
NoteDisplayMode, NoteDisplayMode,
type StrokeStyle, type StrokeStyle,
@@ -319,7 +319,7 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
.color=${background} .color=${background}
.colorType=${type} .colorType=${type}
.colors=${colors} .colors=${colors}
.palettes=${NOTE_BACKGROUND_COLORS} .palettes=${NOTE_BACKGROUND_PALETTES}
> >
</edgeless-color-picker-button> </edgeless-color-picker-button>
`; `;
@@ -340,7 +340,7 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
> >
<edgeless-color-panel <edgeless-color-panel
.value=${background} .value=${background}
.options=${NOTE_BACKGROUND_COLORS} .options=${NOTE_BACKGROUND_PALETTES}
@select=${(e: ColorEvent) => this._setBackground(e.detail)} @select=${(e: ColorEvent) => this._setBackground(e.detail)}
> >
</edgeless-color-panel> </edgeless-color-panel>

View File

@@ -21,8 +21,7 @@ import {
getShapeType, getShapeType,
LineWidth, LineWidth,
MindmapElementModel, MindmapElementModel,
SHAPE_FILL_COLORS, PALETTES,
SHAPE_STROKE_COLORS,
ShapeStyle, ShapeStyle,
StrokeStyle, StrokeStyle,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
@@ -96,7 +95,7 @@ function getMostCommonFillColor(
? (ele.fillColor[colorScheme] ?? ele.fillColor.normal ?? null) ? (ele.fillColor[colorScheme] ?? ele.fillColor.normal ?? null)
: ele.fillColor; : ele.fillColor;
} }
return '--affine-palette-transparent'; return 'transparent';
}); });
const max = maxBy(Object.entries(colors), ([_k, count]) => count); const max = maxBy(Object.entries(colors), ([_k, count]) => count);
return max ? (max[0] as string) : null; return max ? (max[0] as string) : null;
@@ -345,7 +344,7 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
.color=${selectedFillColor} .color=${selectedFillColor}
.colors=${colors} .colors=${colors}
.colorType=${type} .colorType=${type}
.palettes=${SHAPE_FILL_COLORS} .palettes=${PALETTES}
> >
</edgeless-color-picker-button> </edgeless-color-picker-button>
`; `;
@@ -368,7 +367,7 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
role="listbox" role="listbox"
aria-label="Fill colors" aria-label="Fill colors"
.value=${selectedFillColor} .value=${selectedFillColor}
.options=${SHAPE_FILL_COLORS} .palettes=${PALETTES}
@select=${(e: ColorEvent) => this._setShapeFillColor(e.detail)} @select=${(e: ColorEvent) => this._setShapeFillColor(e.detail)}
> >
</edgeless-color-panel> </edgeless-color-panel>
@@ -393,7 +392,7 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
.color=${selectedStrokeColor} .color=${selectedStrokeColor}
.colors=${colors} .colors=${colors}
.colorType=${type} .colorType=${type}
.palettes=${SHAPE_STROKE_COLORS} .palettes=${PALETTES}
.hollowCircle=${true} .hollowCircle=${true}
> >
<div <div

View File

@@ -18,7 +18,7 @@ import {
FontFamily, FontFamily,
FontStyle, FontStyle,
FontWeight, FontWeight,
LINE_COLORS, PALETTES,
ShapeElementModel, ShapeElementModel,
TextAlign, TextAlign,
TextElementModel, TextElementModel,
@@ -391,7 +391,7 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
.color=${selectedColor} .color=${selectedColor}
.colors=${colors} .colors=${colors}
.colorType=${type} .colorType=${type}
.palettes=${LINE_COLORS} .palettes=${PALETTES}
> >
</edgeless-color-picker-button> </edgeless-color-picker-button>
`; `;
@@ -412,6 +412,7 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
> >
<edgeless-color-panel <edgeless-color-panel
.value=${selectedColor} .value=${selectedColor}
.palettes=${PALETTES}
@select=${this._setTextColor} @select=${this._setTextColor}
></edgeless-color-panel> ></edgeless-color-panel>
</editor-menu-button> </editor-menu-button>

View File

@@ -23,7 +23,7 @@
"@floating-ui/dom": "^1.6.10", "@floating-ui/dom": "^1.6.10",
"@lottiefiles/dotlottie-wc": "^0.4.0", "@lottiefiles/dotlottie-wc": "^0.4.0",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1", "@toeverything/theme": "^1.1.3",
"lit": "^3.2.0", "lit": "^3.2.0",
"zod": "^3.23.8" "zod": "^3.23.8"
}, },

View File

@@ -13,7 +13,6 @@ import {
type FrameBlockModel, type FrameBlockModel,
getSurfaceBlock, getSurfaceBlock,
LayoutType, LayoutType,
LineColor,
type MindmapElementModel, type MindmapElementModel,
MindmapStyle, MindmapStyle,
NoteBackgroundColor, NoteBackgroundColor,
@@ -22,6 +21,7 @@ import {
type ShapeElementModel, type ShapeElementModel,
ShapeFillColor, ShapeFillColor,
ShapeType, ShapeType,
StrokeColor,
type TextElementModel, type TextElementModel,
} from '@blocksuite/blocks'; } from '@blocksuite/blocks';
import { assertExists } from '@blocksuite/global/utils'; import { assertExists } from '@blocksuite/global/utils';
@@ -128,7 +128,7 @@ describe('apply last props', () => {
const id = service.crud.addElement('connector', { mode: 0 }); const id = service.crud.addElement('connector', { mode: 0 });
assertExists(id); assertExists(id);
const connector = service.crud.getElementById(id) as ConnectorElementModel; const connector = service.crud.getElementById(id) as ConnectorElementModel;
expect(connector.stroke).toBe(LineColor.Grey); expect(connector.stroke).toBe(StrokeColor.Grey);
expect(connector.strokeWidth).toBe(2); expect(connector.strokeWidth).toBe(2);
expect(connector.strokeStyle).toBe('solid'); expect(connector.strokeStyle).toBe('solid');
expect(connector.frontEndpointStyle).toBe('None'); expect(connector.frontEndpointStyle).toBe('None');
@@ -143,7 +143,7 @@ describe('apply last props', () => {
expect(connector2.strokeWidth).toBe(10); expect(connector2.strokeWidth).toBe(10);
service.crud.updateElement(id2, { service.crud.updateElement(id2, {
labelStyle: { labelStyle: {
color: LineColor.Magenta, color: StrokeColor.Magenta,
fontFamily: FontFamily.Kalam, fontFamily: FontFamily.Kalam,
}, },
}); });
@@ -154,7 +154,7 @@ describe('apply last props', () => {
id3 id3
) as ConnectorElementModel; ) as ConnectorElementModel;
expect(connector3.strokeWidth).toBe(10); expect(connector3.strokeWidth).toBe(10);
expect(connector3.labelStyle.color).toBe(LineColor.Magenta); expect(connector3.labelStyle.color).toBe(StrokeColor.Magenta);
expect(connector3.labelStyle.fontFamily).toBe(FontFamily.Kalam); expect(connector3.labelStyle.fontFamily).toBe(FontFamily.Kalam);
}); });
@@ -163,8 +163,8 @@ describe('apply last props', () => {
assertExists(id); assertExists(id);
const brush = service.crud.getElementById(id) as BrushElementModel; const brush = service.crud.getElementById(id) as BrushElementModel;
expect(brush.color).toEqual({ expect(brush.color).toEqual({
dark: LineColor.White, dark: StrokeColor.White,
light: LineColor.Black, light: StrokeColor.Black,
}); });
expect(brush.lineWidth).toBe(4); expect(brush.lineWidth).toBe(4);
service.crud.updateElement(id, { lineWidth: 10 }); service.crud.updateElement(id, { lineWidth: 10 });
@@ -212,14 +212,14 @@ describe('apply last props', () => {
expect(text.color).toBe(DEFAULT_TEXT_COLOR); expect(text.color).toBe(DEFAULT_TEXT_COLOR);
expect(text.fontFamily).toBe(FontFamily.Inter); expect(text.fontFamily).toBe(FontFamily.Inter);
service.crud.updateElement(id, { service.crud.updateElement(id, {
color: LineColor.Green, color: StrokeColor.Green,
fontFamily: FontFamily.OrelegaOne, fontFamily: FontFamily.OrelegaOne,
}); });
const id2 = service.crud.addBlock('affine:edgeless-text', {}, surface!.id); const id2 = service.crud.addBlock('affine:edgeless-text', {}, surface!.id);
assertExists(id2); assertExists(id2);
const text2 = service.crud.getElementById(id2) as EdgelessTextBlockModel; const text2 = service.crud.getElementById(id2) as EdgelessTextBlockModel;
expect(text2.color).toBe(LineColor.Green); expect(text2.color).toBe(StrokeColor.Green);
expect(text2.fontFamily).toBe(FontFamily.OrelegaOne); expect(text2.fontFamily).toBe(FontFamily.OrelegaOne);
}); });
@@ -250,7 +250,7 @@ describe('apply last props', () => {
const id = service.crud.addBlock('affine:frame', {}, surface!.id); const id = service.crud.addBlock('affine:frame', {}, surface!.id);
assertExists(id); assertExists(id);
const note = service.crud.getElementById(id) as FrameBlockModel; const note = service.crud.getElementById(id) as FrameBlockModel;
expect(note.background).toBe('--affine-palette-transparent'); expect(note.background).toBe('transparent');
service.crud.updateElement(id, { service.crud.updateElement(id, {
background: FrameBackgroundColor.Purple, background: FrameBackgroundColor.Purple,
}); });

View File

@@ -4,6 +4,7 @@ import type {
ShapeElementModel, ShapeElementModel,
SurfaceBlockModel, SurfaceBlockModel,
} from '@blocksuite/blocks'; } from '@blocksuite/blocks';
import { StrokeColor } from '@blocksuite/blocks';
import { beforeEach, describe, expect, test, vi } from 'vitest'; import { beforeEach, describe, expect, test, vi } from 'vitest';
import { wait } from '../utils/common.js'; import { wait } from '../utils/common.js';
@@ -71,7 +72,7 @@ describe('element model', () => {
const element = model.getElementById(id)! as ShapeElementModel; const element = model.getElementById(id)! as ShapeElementModel;
expect(element.index).toBe('a0'); expect(element.index).toBe('a0');
expect(element.strokeColor).toBe('--affine-palette-line-yellow'); expect(element.strokeColor).toBe(StrokeColor.Yellow);
expect(element.strokeWidth).toBe(4); expect(element.strokeWidth).toBe(4);
}); });
@@ -93,9 +94,7 @@ describe('element model', () => {
const element = model.getElementById(id)! as ShapeElementModel; const element = model.getElementById(id)! as ShapeElementModel;
expect(element.yMap.get('strokeColor')).toBe( expect(element.yMap.get('strokeColor')).toBe(StrokeColor.Yellow);
'--affine-palette-line-yellow'
);
element.strokeColor = '--affine-palette-line-black'; element.strokeColor = '--affine-palette-line-black';
expect(element.yMap.get('strokeColor')).toBe('--affine-palette-line-black'); expect(element.yMap.get('strokeColor')).toBe('--affine-palette-line-black');

View File

@@ -144,7 +144,7 @@ test('can insert attachment from slash menu', async ({ page }) => {
page, page,
` `
<affine:note <affine:note
prop:background="--affine-note-background-white" prop:background="--affine-v2-edgeless-note-white"
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -191,7 +191,7 @@ test('should undo/redo works for attachment', async ({ page }) => {
await assertStoreMatchJSX( await assertStoreMatchJSX(
page, page,
` <affine:note ` <affine:note
prop:background="--affine-note-background-white" prop:background="--affine-v2-edgeless-note-white"
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -229,7 +229,7 @@ test('should undo/redo works for attachment', async ({ page }) => {
page, page,
` `
<affine:note <affine:note
prop:background="--affine-note-background-white" prop:background="--affine-v2-edgeless-note-white"
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -260,7 +260,7 @@ test('should undo/redo works for attachment', async ({ page }) => {
page, page,
` `
<affine:note <affine:note
prop:background="--affine-note-background-white" prop:background="--affine-v2-edgeless-note-white"
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -348,7 +348,7 @@ test('should turn attachment to image works', async ({ page }) => {
page, page,
` `
<affine:note <affine:note
prop:background="--affine-note-background-white" prop:background="--affine-v2-edgeless-note-white"
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -382,7 +382,7 @@ test('should turn attachment to image works', async ({ page }) => {
page, page,
` `
<affine:note <affine:note
prop:background="--affine-note-background-white" prop:background="--affine-v2-edgeless-note-white"
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -431,7 +431,7 @@ test('should attachment can be deleted', async ({ page }) => {
page, page,
` `
<affine:note <affine:note
prop:background="--affine-note-background-white" prop:background="--affine-v2-edgeless-note-white"
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -475,7 +475,7 @@ test.fixme(`support dragging attachment block directly`, async ({ page }) => {
await assertStoreMatchJSX( await assertStoreMatchJSX(
page, page,
` <affine:note ` <affine:note
prop:background="--affine-note-background-white" prop:background="--affine-v2-edgeless-note-white"
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -531,7 +531,7 @@ test.fixme(`support dragging attachment block directly`, async ({ page }) => {
page, page,
/*xml*/ `<affine:page> /*xml*/ `<affine:page>
<affine:note <affine:note
prop:background="--affine-note-background-white" prop:background="--affine-v2-edgeless-note-white"
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -589,7 +589,7 @@ test.fixme(`support dragging attachment block directly`, async ({ page }) => {
page, page,
/*xml*/ `<affine:page> /*xml*/ `<affine:page>
<affine:note <affine:note
prop:background="--affine-note-background-white" prop:background="--affine-v2-edgeless-note-white"
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {

View File

@@ -441,7 +441,7 @@ test(scoped`should copy and paste of database work`, async ({ page }) => {
/*xml*/ ` /*xml*/ `
<affine:page> <affine:page>
<affine:note <affine:note
prop:background="--affine-note-background-white" prop:background="--affine-v2-edgeless-note-white"
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -491,7 +491,7 @@ test(scoped`should copy and paste of database work`, async ({ page }) => {
/*xml*/ ` /*xml*/ `
<affine:page> <affine:page>
<affine:note <affine:note
prop:background="--affine-note-background-white" prop:background="--affine-v2-edgeless-note-white"
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -574,7 +574,7 @@ test(scoped`paste note block with background`, async ({ page }) => {
await selectNoteInEdgeless(page, ids.noteId); await selectNoteInEdgeless(page, ids.noteId);
await triggerComponentToolbarAction(page, 'changeNoteColor'); await triggerComponentToolbarAction(page, 'changeNoteColor');
const color = '--affine-note-background-grey'; const color = '--affine-v2-edgeless-note-grey';
await changeEdgelessNoteBackground(page, color); await changeEdgelessNoteBackground(page, color);
await assertEdgelessNoteBackground(page, ids.noteId, color); await assertEdgelessNoteBackground(page, ids.noteId, color);

View File

@@ -1,4 +1,8 @@
import { DEFAULT_NOTE_BACKGROUND_COLOR } from '@blocksuite/affine-model'; import {
DEFAULT_NOTE_BACKGROUND_COLOR,
ShapeFillColor,
StrokeColor,
} from '@blocksuite/affine-model';
import { expect, type Page } from '@playwright/test'; import { expect, type Page } from '@playwright/test';
import { clickView, moveView } from '../utils/actions/click.js'; import { clickView, moveView } from '../utils/actions/click.js';
@@ -135,10 +139,10 @@ test.describe('auto-complete', () => {
await createShapeElement(page, [0, 0], [100, 100], Shape.Square); await createShapeElement(page, [0, 0], [100, 100], Shape.Square);
await assertSelectedBound(page, [0, 0, 100, 100]); await assertSelectedBound(page, [0, 0, 100, 100]);
await triggerComponentToolbarAction(page, 'changeShapeStrokeColor'); await triggerComponentToolbarAction(page, 'changeShapeStrokeColor');
const lineColor = '--affine-palette-line-red'; const lineColor = StrokeColor.Red;
await changeShapeStrokeColor(page, lineColor); await changeShapeStrokeColor(page, lineColor);
await triggerComponentToolbarAction(page, 'changeShapeFillColor'); await triggerComponentToolbarAction(page, 'changeShapeFillColor');
const color = '--affine-palette-shape-green'; const color = ShapeFillColor.Green;
await changeShapeFillColor(page, color); await changeShapeFillColor(page, color);
await dragBetweenViewCoords(page, [120, 50], [200, 0]); await dragBetweenViewCoords(page, [120, 50], [200, 0]);
@@ -184,7 +188,7 @@ test.describe('auto-complete', () => {
await waitNextFrame(page); await waitNextFrame(page);
await triggerComponentToolbarAction(page, 'changeNoteColor'); await triggerComponentToolbarAction(page, 'changeNoteColor');
const noteColor = '--affine-note-background-red'; const noteColor = '--affine-v2-edgeless-note-red';
await changeEdgelessNoteBackground(page, noteColor); await changeEdgelessNoteBackground(page, noteColor);
// move to arrow icon // move to arrow icon

View File

@@ -1,3 +1,4 @@
import { StrokeColor } from '@blocksuite/affine-model';
import { expect } from '@playwright/test'; import { expect } from '@playwright/test';
import { import {
@@ -79,7 +80,7 @@ test('add brush element with color', async ({ page }) => {
await switchEditorMode(page); await switchEditorMode(page);
await setEdgelessTool(page, 'brush'); await setEdgelessTool(page, 'brush');
const color = '--affine-palette-line-blue'; const color = StrokeColor.Blue;
await selectBrushColor(page, color); await selectBrushColor(page, color);
const start = { x: 100, y: 100 }; const start = { x: 100, y: 100 };
@@ -100,7 +101,7 @@ test('keep same color when mouse mode switched back to brush', async ({
await deleteAll(page); await deleteAll(page);
await setEdgelessTool(page, 'brush'); await setEdgelessTool(page, 'brush');
const color = '--affine-palette-line-blue'; const color = StrokeColor.Blue;
await selectBrushColor(page, color); await selectBrushColor(page, color);
const start = { x: 200, y: 200 }; const start = { x: 200, y: 200 };
const end = { x: 300, y: 300 }; const end = { x: 300, y: 300 };
@@ -123,7 +124,7 @@ test('add brush element with different size', async ({ page }) => {
await setEdgelessTool(page, 'brush'); await setEdgelessTool(page, 'brush');
await selectBrushSize(page, 'ten'); await selectBrushSize(page, 'ten');
const color = '--affine-palette-line-blue'; const color = StrokeColor.Blue;
await selectBrushColor(page, color); await selectBrushColor(page, color);
const start = { x: 100, y: 100 }; const start = { x: 100, y: 100 };
@@ -144,8 +145,8 @@ test('add brush element with different size', async ({ page }) => {
await assertEdgelessColorSameWithHexColor(page, color, topEdge); await assertEdgelessColorSameWithHexColor(page, color, topEdge);
await assertEdgelessColorSameWithHexColor(page, color, bottomEdge); await assertEdgelessColorSameWithHexColor(page, color, bottomEdge);
assertSameColor(nearTopEdge, '#4f90ff'); assertSameColor(nearTopEdge, '#84cfff');
assertSameColor(nearBottomEdge, '#4f90ff'); assertSameColor(nearBottomEdge, '#84cfff');
}); });
test('change brush element size by component-toolbar', async ({ page }) => { test('change brush element size by component-toolbar', async ({ page }) => {

View File

@@ -25,12 +25,12 @@ function getColorPickerButtonWithClass(page: Page, classes: string) {
} }
function getCurrentColorUnitButton(locator: Locator) { function getCurrentColorUnitButton(locator: Locator) {
return locator.locator('edgeless-color-button').locator('.color-unit'); return locator.locator('edgeless-color-button').locator('.color-unit').nth(0);
} }
function getCurrentColor(locator: Locator) { function getCurrentColor(locator: Locator) {
return locator.evaluate(ele => return locator.evaluate(ele =>
getComputedStyle(ele).getPropertyValue('background-color') getComputedStyle(ele.querySelector('svg')!).getPropertyValue('fill')
); );
} }
@@ -116,7 +116,7 @@ test.describe('basic functions', () => {
const currentColorUnit = getCurrentColorUnitButton(fillColorButton); const currentColorUnit = getCurrentColorUnitButton(fillColorButton);
const value = await getCurrentColor(currentColorUnit); const value = await getCurrentColor(currentColorUnit);
await expect(currentColorUnit).toHaveCSS('background-color', value); await expect(currentColorUnit.locator('svg')).toHaveCSS('fill', value);
const customButton = getCustomButton(fillColorButton); const customButton = getCustomButton(fillColorButton);

View File

@@ -1,3 +1,4 @@
import { StrokeColor } from '@blocksuite/affine-model';
import { expect } from '@playwright/test'; import { expect } from '@playwright/test';
import { import {
@@ -148,7 +149,7 @@ test('change connector line width', async ({ page }) => {
await page.mouse.click(start.x + 5, start.y); await page.mouse.click(start.x + 5, start.y);
await triggerComponentToolbarAction(page, 'changeConnectorStrokeColor'); await triggerComponentToolbarAction(page, 'changeConnectorStrokeColor');
await changeConnectorStrokeColor(page, '--affine-palette-line-teal'); await changeConnectorStrokeColor(page, StrokeColor.Grey);
await triggerComponentToolbarAction(page, 'changeConnectorStrokeStyles'); await triggerComponentToolbarAction(page, 'changeConnectorStrokeStyles');
await changeConnectorStrokeWidth(page, 5); await changeConnectorStrokeWidth(page, 5);
@@ -173,7 +174,7 @@ test('change connector stroke style', async ({ page }) => {
await page.mouse.click(start.x + 5, start.y); await page.mouse.click(start.x + 5, start.y);
await triggerComponentToolbarAction(page, 'changeConnectorStrokeColor'); await triggerComponentToolbarAction(page, 'changeConnectorStrokeColor');
await changeConnectorStrokeColor(page, '--affine-palette-line-teal'); await changeConnectorStrokeColor(page, StrokeColor.Grey);
await triggerComponentToolbarAction(page, 'changeConnectorStrokeStyles'); await triggerComponentToolbarAction(page, 'changeConnectorStrokeStyles');
await changeConnectorStrokeStyle(page, 'dash'); await changeConnectorStrokeStyle(page, 'dash');

View File

@@ -304,12 +304,12 @@ test('change note color', async ({ page }) => {
await assertEdgelessNoteBackground( await assertEdgelessNoteBackground(
page, page,
noteId, noteId,
'--affine-note-background-white' '--affine-v2-edgeless-note-white'
); );
await selectNoteInEdgeless(page, noteId); await selectNoteInEdgeless(page, noteId);
await triggerComponentToolbarAction(page, 'changeNoteColor'); await triggerComponentToolbarAction(page, 'changeNoteColor');
const color = '--affine-note-background-green'; const color = '--affine-v2-edgeless-note-green';
await changeEdgelessNoteBackground(page, color); await changeEdgelessNoteBackground(page, color);
await assertEdgelessNoteBackground(page, noteId, color); await assertEdgelessNoteBackground(page, noteId, color);
}); });

View File

@@ -1,3 +1,4 @@
import { ShapeFillColor, StrokeColor } from '@blocksuite/affine-model';
import { expect, type Page } from '@playwright/test'; import { expect, type Page } from '@playwright/test';
import { import {
@@ -167,7 +168,7 @@ test.skip('change shape fill color', async ({ page }) => {
await page.mouse.click(rect.start.x + 5, rect.start.y + 5); await page.mouse.click(rect.start.x + 5, rect.start.y + 5);
await triggerComponentToolbarAction(page, 'changeShapeFillColor'); await triggerComponentToolbarAction(page, 'changeShapeFillColor');
const color = '--affine-palette-shape-teal'; const color = ShapeFillColor.Grey;
await changeShapeFillColor(page, color); await changeShapeFillColor(page, color);
await page.waitForTimeout(50); await page.waitForTimeout(50);
const [picked] = await pickColorAtPoints(page, [ const [picked] = await pickColorAtPoints(page, [
@@ -190,7 +191,7 @@ test('change shape stroke color', async ({ page }) => {
await page.mouse.click(rect.start.x + 5, rect.start.y + 5); await page.mouse.click(rect.start.x + 5, rect.start.y + 5);
await triggerComponentToolbarAction(page, 'changeShapeStrokeColor'); await triggerComponentToolbarAction(page, 'changeShapeStrokeColor');
const color = '--affine-palette-line-teal'; const color = StrokeColor.Grey;
await changeShapeStrokeColor(page, color); await changeShapeStrokeColor(page, color);
await page.waitForTimeout(50); await page.waitForTimeout(50);
const [picked] = await pickColorAtPoints(page, [ const [picked] = await pickColorAtPoints(page, [
@@ -338,7 +339,7 @@ test('change shape stroke width', async ({ page }) => {
await page.mouse.click(start.x + 5, start.y + 5); await page.mouse.click(start.x + 5, start.y + 5);
await triggerComponentToolbarAction(page, 'changeShapeStrokeColor'); await triggerComponentToolbarAction(page, 'changeShapeStrokeColor');
await changeShapeStrokeColor(page, '--affine-palette-line-teal'); await changeShapeStrokeColor(page, StrokeColor.Magenta);
await triggerComponentToolbarAction(page, 'changeShapeStrokeStyles'); await triggerComponentToolbarAction(page, 'changeShapeStrokeStyles');
await changeShapeStrokeWidth(page); await changeShapeStrokeWidth(page);
@@ -361,7 +362,7 @@ test('change shape stroke style', async ({ page }) => {
await page.mouse.click(start.x + 5, start.y + 5); await page.mouse.click(start.x + 5, start.y + 5);
await triggerComponentToolbarAction(page, 'changeShapeStrokeColor'); await triggerComponentToolbarAction(page, 'changeShapeStrokeColor');
await changeShapeStrokeColor(page, '--affine-palette-line-teal'); await changeShapeStrokeColor(page, StrokeColor.Blue);
await triggerComponentToolbarAction(page, 'changeShapeStrokeStyles'); await triggerComponentToolbarAction(page, 'changeShapeStrokeStyles');
await changeShapeStrokeStyle(page, 'dash'); await changeShapeStrokeStyle(page, 'dash');
@@ -548,7 +549,7 @@ test('change shape style', async ({ page }) => {
await page.mouse.click(start.x + 5, start.y + 5); await page.mouse.click(start.x + 5, start.y + 5);
await triggerComponentToolbarAction(page, 'changeShapeStrokeColor'); await triggerComponentToolbarAction(page, 'changeShapeStrokeColor');
const color = '--affine-palette-line-teal'; const color = StrokeColor.Purple;
await changeShapeStrokeColor(page, color); await changeShapeStrokeColor(page, color);
await page.waitForTimeout(50); await page.waitForTimeout(50);
const [picked] = await pickColorAtPoints(page, [[start.x + 1, start.y + 1]]); const [picked] = await pickColorAtPoints(page, [[start.x + 1, start.y + 1]]);

View File

@@ -476,7 +476,7 @@ test.skip('convert link to embed', async ({ page }) => {
` `
<affine:page> <affine:page>
<affine:note <affine:note
prop:background="--affine-note-background-blue" prop:background="--affine-v2-edgeless-note-white"
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -27,7 +27,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,234]", "xywh": "[0,0,498,234]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"hidden": false, "hidden": false,
"displayMode": "both", "displayMode": "both",

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"hidden": false, "hidden": false,
"displayMode": "both", "displayMode": "both",

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"hidden": false, "hidden": false,
"displayMode": "both", "displayMode": "both",

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"hidden": false, "hidden": false,
"displayMode": "both", "displayMode": "both",

View File

@@ -17,7 +17,7 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-note-background-white", "background": "--affine-v2-edgeless-note-white",
"index": "a0", "index": "a0",
"hidden": false, "hidden": false,
"displayMode": "both", "displayMode": "both",

Some files were not shown because too many files have changed in this diff Show More