feat(editor): store real color values in edgeless (#9254)

### What's Changed!

* adds theme type: `ThemeSchema`
* adds default theme: `DefaultTheme`
* stores real color values
This commit is contained in:
fundon committed 2024-12-30 03:36:35 +00:00
1 parent a5641ae608
commit b9f2650369
287 files changed
+2209 -1510

No files matched your search

@@ -1,4 +1,4 @@
import type { FrameBlockModel } from '@blocksuite/affine-model'; import { DefaultTheme, type FrameBlockModel } from '@blocksuite/affine-model';
import { ThemeProvider } from '@blocksuite/affine-shared/services'; import { ThemeProvider } from '@blocksuite/affine-shared/services';
import { GfxBlockComponent } from '@blocksuite/block-std'; import { GfxBlockComponent } from '@blocksuite/block-std';
import { Bound } from '@blocksuite/global/utils'; import { Bound } from '@blocksuite/global/utils';
@@ -56,7 +56,7 @@ export class FrameBlockComponent extends GfxBlockComponent<FrameBlockModel> {
const { model, showBorder, std } = this; const { model, showBorder, std } = this;
const backgroundColor = std const backgroundColor = std
.get(ThemeProvider) .get(ThemeProvider)
.generateColorProperty(model.background, '--affine-platte-transparent'); .generateColorProperty(model.background, DefaultTheme.transparent);
const _isNavigator = const _isNavigator =
this.gfx.tool.currentToolName$.value === 'frameNavigator'; this.gfx.tool.currentToolName$.value === 'frameNavigator';
const frameIndex = this.gfx.layer.getZIndex(model); const frameIndex = this.gfx.layer.getZIndex(model);
@@ -2,7 +2,7 @@ import { EdgelessLegacySlotIdentifier } from '@blocksuite/affine-block-surface';
import { MoreIndicatorIcon } from '@blocksuite/affine-components/icons'; import { MoreIndicatorIcon } from '@blocksuite/affine-components/icons';
import type { NoteBlockModel } from '@blocksuite/affine-model'; import type { NoteBlockModel } from '@blocksuite/affine-model';
import { import {
DEFAULT_NOTE_BACKGROUND_COLOR, DefaultTheme,
NoteDisplayMode, NoteDisplayMode,
StrokeStyle, StrokeStyle,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
@@ -24,6 +24,7 @@ import {
WithDisposable, WithDisposable,
} from '@blocksuite/global/utils'; } from '@blocksuite/global/utils';
import type { BlockModel } from '@blocksuite/store'; import type { BlockModel } from '@blocksuite/store';
import { computed } from '@preact/signals-core';
import { css, html, nothing } from 'lit'; import { css, html, nothing } from 'lit';
import { property, query, state } from 'lit/decorators.js'; import { property, query, state } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js'; import { classMap } from 'lit/directives/class-map.js';
@@ -141,6 +142,16 @@ export class EdgelessNoteBlockComponent extends toGfxBlockComponent(
} }
`; `;
private readonly _backgroundColor$ = computed(() => {
const themeProvider = this.std.get(ThemeProvider);
const theme = themeProvider.theme$.value;
return themeProvider.generateColorProperty(
this.model.background$.value,
DefaultTheme.noteBackgrounColor,
theme
);
});
private get _isShowCollapsedContent() { private get _isShowCollapsedContent() {
return this.model.edgeless.collapse && (this._isResizing || this._isHover); return this.model.edgeless.collapse && (this._isResizing || this._isHover);
} }
@@ -406,9 +417,6 @@ export class EdgelessNoteBlockComponent extends toGfxBlockComponent(
}; };
const extra = this._editing ? ACTIVE_NOTE_EXTRA_PADDING : 0; const extra = this._editing ? ACTIVE_NOTE_EXTRA_PADDING : 0;
const backgroundColor = this.std
.get(ThemeProvider)
.generateColorProperty(model.background, DEFAULT_NOTE_BACKGROUND_COLOR);
const backgroundStyle = { const backgroundStyle = {
position: 'absolute', position: 'absolute',
@@ -420,7 +428,7 @@ export class EdgelessNoteBlockComponent extends toGfxBlockComponent(
transition: this._editing transition: this._editing
? 'left 0.3s, top 0.3s, width 0.3s, height 0.3s' ? 'left 0.3s, top 0.3s, width 0.3s, height 0.3s'
: 'none', : 'none',
backgroundColor, backgroundColor: this._backgroundColor$.value,
border: `${borderSize}px ${ border: `${borderSize}px ${
borderStyle === StrokeStyle.Dash ? 'dashed' : borderStyle borderStyle === StrokeStyle.Dash ? 'dashed' : borderStyle
} var(--affine-black-10)`, } var(--affine-black-10)`,
@@ -21,9 +21,9 @@ import type { ElementRenderer } from './elements/index.js';
import type { Overlay } from './overlay.js'; import type { Overlay } from './overlay.js';
type EnvProvider = { type EnvProvider = {
generateColorProperty: (color: Color, fallback: string) => string; generateColorProperty: (color: Color, fallback?: Color) => string;
getColorScheme: () => ColorScheme; getColorScheme: () => ColorScheme;
getColorValue: (color: Color, fallback?: string, real?: boolean) => string; getColorValue: (color: Color, fallback?: Color, real?: boolean) => string;
getPropertyValue: (property: string) => string; getPropertyValue: (property: string) => string;
selectedElements?: () => string[]; selectedElements?: () => string[];
}; };
@@ -368,10 +368,9 @@ export class CanvasRenderer {
this._disposables.dispose(); this._disposables.dispose();
} }
generateColorProperty(color: Color, fallback: string) { generateColorProperty(color: Color, fallback?: Color) {
return ( return (
this.provider.generateColorProperty?.(color, fallback) ?? this.provider.generateColorProperty?.(color, fallback) ?? 'transparent'
(fallback.startsWith('--') ? `var(${fallback})` : fallback)
); );
} }
@@ -409,7 +408,7 @@ export class CanvasRenderer {
return this.provider.getColorScheme?.() ?? ColorScheme.Light; return this.provider.getColorScheme?.() ?? ColorScheme.Light;
} }
getColorValue(color: Color, fallback?: string, real?: boolean) { getColorValue(color: Color, fallback?: Color, real?: boolean) {
return ( return (
this.provider.getColorValue?.(color, fallback, real) ?? 'transparent' this.provider.getColorValue?.(color, fallback, real) ?? 'transparent'
); );
@@ -1,4 +1,4 @@
import type { BrushElementModel } from '@blocksuite/affine-model'; import { type BrushElementModel, DefaultTheme } from '@blocksuite/affine-model';
import type { CanvasRenderer } from '../../canvas-renderer.js'; import type { CanvasRenderer } from '../../canvas-renderer.js';
@@ -17,7 +17,7 @@ export function brush(
matrix.translateSelf(cx, cy).rotateSelf(rotate).translateSelf(-cx, -cy) matrix.translateSelf(cx, cy).rotateSelf(rotate).translateSelf(-cx, -cy)
); );
const color = renderer.getColorValue(model.color, '#000000', true); const color = renderer.getColorValue(model.color, DefaultTheme.black, true);
ctx.fillStyle = color; ctx.fillStyle = color;
@@ -1,6 +1,7 @@
import { import {
type ConnectorElementModel, type ConnectorElementModel,
ConnectorMode, ConnectorMode,
DefaultTheme,
type LocalConnectorElementModel, type LocalConnectorElementModel,
type PointStyle, type PointStyle,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
@@ -75,7 +76,11 @@ export function connector(
ctx.clip(path, 'evenodd'); ctx.clip(path, 'evenodd');
} }
const strokeColor = renderer.getColorValue(model.stroke, '#000000', true); const strokeColor = renderer.getColorValue(
model.stroke,
DefaultTheme.connectorColor,
true
);
renderPoints( renderPoints(
model, model,
@@ -249,7 +254,7 @@ function renderLabel(
ctx.font = font; ctx.font = font;
ctx.textAlign = textAlign; ctx.textAlign = textAlign;
ctx.textBaseline = 'middle'; ctx.textBaseline = 'middle';
ctx.fillStyle = renderer.getColorValue(color, '#000000', true); ctx.fillStyle = renderer.getColorValue(color, DefaultTheme.black, true);
let textMaxWidth = textAlign === 'center' ? 0 : getMaxTextWidth(lines, font); let textMaxWidth = textAlign === 'center' ? 0 : getMaxTextWidth(lines, font);
if (hasMaxWidth && maxWidth > 0) { if (hasMaxWidth && maxWidth > 0) {
@@ -3,12 +3,7 @@ import type {
ShapeElementModel, ShapeElementModel,
ShapeType, ShapeType,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
import { import { DefaultTheme, TextAlign } from '@blocksuite/affine-model';
DEFAULT_SHAPE_FILL_COLOR,
DEFAULT_SHAPE_STROKE_COLOR,
DEFAULT_SHAPE_TEXT_COLOR,
TextAlign,
} from '@blocksuite/affine-model';
import type { IBound } from '@blocksuite/global/utils'; import type { IBound } from '@blocksuite/global/utils';
import { Bound } from '@blocksuite/global/utils'; import { Bound } from '@blocksuite/global/utils';
import { deltaInsertsToChunks } from '@blocksuite/inline'; import { deltaInsertsToChunks } from '@blocksuite/inline';
@@ -55,17 +50,17 @@ export function shape(
) { ) {
const color = renderer.getColorValue( const color = renderer.getColorValue(
model.color, model.color,
DEFAULT_SHAPE_TEXT_COLOR, DefaultTheme.shapeTextColor,
true true
); );
const fillColor = renderer.getColorValue( const fillColor = renderer.getColorValue(
model.fillColor, model.fillColor,
DEFAULT_SHAPE_FILL_COLOR, DefaultTheme.shapeFillColor,
true true
); );
const strokeColor = renderer.getColorValue( const strokeColor = renderer.getColorValue(
model.strokeColor, model.strokeColor,
DEFAULT_SHAPE_STROKE_COLOR, DefaultTheme.shapeStrokeColor,
true true
); );
const colors = { color, fillColor, strokeColor }; const colors = { color, fillColor, strokeColor };
@@ -1,4 +1,4 @@
import type { TextElementModel } from '@blocksuite/affine-model'; import { DefaultTheme, type TextElementModel } from '@blocksuite/affine-model';
import { deltaInsertsToChunks } from '@blocksuite/inline'; import { deltaInsertsToChunks } from '@blocksuite/inline';
import type { CanvasRenderer } from '../../canvas-renderer.js'; import type { CanvasRenderer } from '../../canvas-renderer.js';
@@ -39,7 +39,11 @@ export function text(
const horizontalOffset = const horizontalOffset =
textAlign === 'center' ? w / 2 : textAlign === 'right' ? w : 0; textAlign === 'center' ? w / 2 : textAlign === 'right' ? w : 0;
const color = renderer.getColorValue(model.color, '#000000', true); const color = renderer.getColorValue(
model.color,
DefaultTheme.textColor,
true
);
ctx.font = font; ctx.font = font;
ctx.fillStyle = color; ctx.fillStyle = color;
@@ -160,13 +160,13 @@ export class SurfaceBlockComponent extends BlockComponent<
gridManager: gfx.grid, gridManager: gfx.grid,
enableStackingCanvas: true, enableStackingCanvas: true,
provider: { provider: {
generateColorProperty: (color: Color, fallback: string) => generateColorProperty: (color: Color, fallback?: Color) =>
themeService.generateColorProperty( themeService.generateColorProperty(
color, color,
fallback, fallback,
themeService.edgelessTheme themeService.edgelessTheme
), ),
getColorValue: (color: Color, fallback?: string, real?: boolean) => getColorValue: (color: Color, fallback?: Color, real?: boolean) =>
themeService.getColorValue( themeService.getColorValue(
color, color,
fallback, fallback,
@@ -8,6 +8,7 @@ import { unsafeCSS } from 'lit';
const toolbarColorKeys: Array<keyof AffineCssVariables> = [ const toolbarColorKeys: Array<keyof AffineCssVariables> = [
'--affine-background-overlay-panel-color', '--affine-background-overlay-panel-color',
'--affine-v2-layer-background-overlayPanel' as never, '--affine-v2-layer-background-overlayPanel' as never,
'--affine-v2-layer-insideBorder-blackBorder' as never,
'--affine-background-error-color', '--affine-background-error-color',
'--affine-background-primary-color', '--affine-background-primary-color',
'--affine-background-tertiary-color', '--affine-background-tertiary-color',
@@ -17,7 +17,7 @@ import {
import { Bound } from '@blocksuite/global/utils'; import { Bound } from '@blocksuite/global/utils';
import { BlockModel, defineBlockSchema, type Text } from '@blocksuite/store'; import { BlockModel, defineBlockSchema, type Text } from '@blocksuite/store';
import type { Color } from '../../consts/index.js'; import type { Color } from '../../themes/index.js';
export type FrameBlockProps = { export type FrameBlockProps = {
title: Text; title: Text;
@@ -7,8 +7,6 @@ import { Bound } from '@blocksuite/global/utils';
import { BlockModel, defineBlockSchema } from '@blocksuite/store'; import { BlockModel, defineBlockSchema } from '@blocksuite/store';
import { import {
type Color,
DEFAULT_NOTE_BACKGROUND_COLOR,
DEFAULT_NOTE_BORDER_SIZE, DEFAULT_NOTE_BORDER_SIZE,
DEFAULT_NOTE_BORDER_STYLE, DEFAULT_NOTE_BORDER_STYLE,
DEFAULT_NOTE_CORNER, DEFAULT_NOTE_CORNER,
@@ -18,12 +16,13 @@ import {
NoteDisplayMode, NoteDisplayMode,
type StrokeStyle, type StrokeStyle,
} from '../../consts/index.js'; } from '../../consts/index.js';
import { type Color, DefaultTheme } from '../../themes/index.js';
export const NoteBlockSchema = defineBlockSchema({ export const NoteBlockSchema = defineBlockSchema({
flavour: 'affine:note', flavour: 'affine:note',
props: (): NoteProps => ({ props: (): NoteProps => ({
xywh: `[0,0,${DEFAULT_NOTE_WIDTH},${DEFAULT_NOTE_HEIGHT}]`, xywh: `[0,0,${DEFAULT_NOTE_WIDTH},${DEFAULT_NOTE_HEIGHT}]`,
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
lockedBySelf: false, lockedBySelf: false,
hidden: false, hidden: false,
@@ -1,3 +0,0 @@
import { StrokeColor } from './color.js';
export const DEFAULT_BRUSH_COLOR = StrokeColor.Blue;
@@ -1,97 +0,0 @@
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;
@@ -1,5 +1,4 @@
import { createEnumMap } from '../utils/enum.js'; import { createEnumMap } from '../utils/enum.js';
import { StrokeColor } from './color.js';
export enum ConnectorEndpoint { export enum ConnectorEndpoint {
Front = 'Front', Front = 'Front',
@@ -16,10 +15,6 @@ export enum PointStyle {
export const PointStyleMap = createEnumMap(PointStyle); export const PointStyleMap = createEnumMap(PointStyle);
export const DEFAULT_CONNECTOR_COLOR = StrokeColor.Grey;
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;
export const DEFAULT_REAR_END_POINT_STYLE = PointStyle.Arrow; export const DEFAULT_REAR_END_POINT_STYLE = PointStyle.Arrow;
@@ -1,3 +0,0 @@
import { Light } from './color.js';
export const FrameBackgroundColor = Light;
@@ -1,8 +1,5 @@
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 './image.js'; export * from './image.js';
export * from './line.js'; export * from './line.js';
export * from './mindmap.js'; export * from './mindmap.js';
+8 -3
View File
@@ -3,14 +3,14 @@ import { z } from 'zod';
import { createEnumMap } from '../utils/enum.js'; import { createEnumMap } from '../utils/enum.js';
export enum LineWidth { export enum LineWidth {
Eight = 8, Two = 2,
// Thin // Thin
Four = 4, Four = 4,
Six = 6, Six = 6,
Eight = 8,
// Thick // Thick
Ten = 10, Ten = 10,
Twelve = 12, Twelve = 12,
Two = 2,
} }
export const LINE_WIDTHS = [ export const LINE_WIDTHS = [
@@ -23,7 +23,7 @@ export const LINE_WIDTHS = [
]; ];
/** /**
* Use `StrokeColor` instead. * Use `DefaultTheme.StrokeColorMap` instead.
* *
* @deprecated * @deprecated
*/ */
@@ -43,6 +43,11 @@ export enum LineColor {
export const LineColorMap = createEnumMap(LineColor); export const LineColorMap = createEnumMap(LineColor);
/**
* Use `DefaultTheme.StrokeColorPalettes` instead.
*
* @deprecated
*/
export const LINE_COLORS = [ export const LINE_COLORS = [
LineColor.Yellow, LineColor.Yellow,
LineColor.Orange, LineColor.Orange,
@@ -1,4 +1,3 @@
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';
@@ -9,40 +8,6 @@ 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 const NoteBackgroundColor = {
Yellow: themeToVar('edgeless/note/yellow'),
Orange: themeToVar('edgeless/note/orange'),
Red: themeToVar('edgeless/note/red'),
Magenta: themeToVar('edgeless/note/magenta'),
Purple: themeToVar('edgeless/note/purple'),
Blue: themeToVar('edgeless/note/blue'),
Teal: themeToVar('edgeless/note/teal'),
Green: themeToVar('edgeless/note/green'),
Black: themeToVar('edgeless/note/black'),
Grey: themeToVar('edgeless/note/grey'),
White: themeToVar('edgeless/note/white'),
} as const;
export const NoteBackgroundColorMap = createEnumMap(NoteBackgroundColor);
export const NOTE_BACKGROUND_PALETTES = [
NoteBackgroundColor.Yellow,
NoteBackgroundColor.Orange,
NoteBackgroundColor.Red,
NoteBackgroundColor.Magenta,
NoteBackgroundColor.Purple,
NoteBackgroundColor.Blue,
NoteBackgroundColor.Teal,
NoteBackgroundColor.Green,
NoteBackgroundColor.Black,
NoteBackgroundColor.Grey,
NoteBackgroundColor.White,
] as const;
export const NoteBackgroundPaletteEnum = z.enum(NOTE_BACKGROUND_PALETTES);
export const DEFAULT_NOTE_BACKGROUND_COLOR = NoteBackgroundColor.White;
export enum NoteShadow { export enum NoteShadow {
Box = '--affine-note-shadow-box', Box = '--affine-note-shadow-box',
Film = '--affine-note-shadow-film', Film = '--affine-note-shadow-film',
@@ -1,5 +1,3 @@
import { Black, Light, LIGHT_PALETTES, StrokeColor, White } from './color.js';
export const DEFAULT_ROUGHNESS = 1.4; export const DEFAULT_ROUGHNESS = 1.4;
// TODO: need to check the default central area ratio // TODO: need to check the default central area ratio
@@ -46,13 +44,3 @@ export enum ShapeStyle {
General = 'General', General = 'General',
Scribbled = 'Scribbled', Scribbled = 'Scribbled',
} }
export const ShapeFillColor = { Black, White, ...Light } as const;
export const SHAPE_FILL_COLORS = [...LIGHT_PALETTES, Black, White];
export const DEFAULT_SHAPE_FILL_COLOR = Light.Yellow;
export const DEFAULT_SHAPE_STROKE_COLOR = StrokeColor.Yellow;
export const DEFAULT_SHAPE_TEXT_COLOR = StrokeColor.Black;
+1 -10
View File
@@ -1,12 +1,5 @@
import type { Color } from '../themes/color.js';
import { createEnumMap } from '../utils/enum.js'; import { createEnumMap } from '../utils/enum.js';
import { StrokeColor } from './color.js';
export enum ColorScheme {
Dark = 'dark',
Light = 'light',
}
export type Color = string | Partial<Record<ColorScheme | 'normal', string>>;
export enum TextAlign { export enum TextAlign {
Center = 'center', Center = 'center',
@@ -66,5 +59,3 @@ export enum TextResizing {
AUTO_WIDTH_AND_HEIGHT, AUTO_WIDTH_AND_HEIGHT,
AUTO_HEIGHT, AUTO_HEIGHT,
} }
export const DEFAULT_TEXT_COLOR = StrokeColor.Blue;
@@ -28,7 +28,7 @@ import {
Vec, Vec,
} from '@blocksuite/global/utils'; } from '@blocksuite/global/utils';
import type { Color } from '../../consts/index.js'; import type { Color } from '../../themes/index.js';
export type BrushProps = BaseElementProps & { export type BrushProps = BaseElementProps & {
/** /**
@@ -26,7 +26,6 @@ import {
import { DocCollection, type Y } from '@blocksuite/store'; import { DocCollection, type Y } from '@blocksuite/store';
import { import {
type Color,
CONNECTOR_LABEL_MAX_WIDTH, CONNECTOR_LABEL_MAX_WIDTH,
ConnectorLabelOffsetAnchor, ConnectorLabelOffsetAnchor,
ConnectorMode, ConnectorMode,
@@ -39,6 +38,7 @@ import {
TextAlign, TextAlign,
type TextStyleProps, type TextStyleProps,
} from '../../consts/index.js'; } from '../../consts/index.js';
import type { Color } from '../../themes/index.ts';
export type SerializedConnection = { export type SerializedConnection = {
id?: string; id?: string;
@@ -2,12 +2,12 @@ import { GfxLocalElementModel } from '@blocksuite/block-std/gfx';
import type { PointLocation } from '@blocksuite/global/utils'; import type { PointLocation } from '@blocksuite/global/utils';
import { import {
type Color,
ConnectorMode, ConnectorMode,
DEFAULT_ROUGHNESS, DEFAULT_ROUGHNESS,
type PointStyle, type PointStyle,
StrokeStyle, StrokeStyle,
} from '../../consts/index.js'; } from '../../consts/index.js';
import type { Color } from '../../themes/index.ts';
import type { Connection } from './connector.js'; import type { Connection } from './connector.js';
export class LocalConnectorElementModel extends GfxLocalElementModel { export class LocalConnectorElementModel extends GfxLocalElementModel {
@@ -1,11 +1,10 @@
import { isEqual, last } from '@blocksuite/global/utils'; import { isEqual, last } from '@blocksuite/global/utils';
import { ConnectorMode } from '../../consts/connector.js'; import { ConnectorMode } from '../../consts/connector.js';
import { LineColor } from '../../consts/line.js';
import { MindmapStyle } from '../../consts/mindmap.js'; import { MindmapStyle } from '../../consts/mindmap.js';
import { StrokeStyle } from '../../consts/note.js'; import { StrokeStyle } from '../../consts/note.js';
import { ShapeFillColor } from '../../consts/shape.js';
import { FontFamily, FontWeight, TextResizing } from '../../consts/text.js'; import { FontFamily, FontWeight, TextResizing } from '../../consts/text.js';
import { type Color, DefaultTheme } from '../../themes/index.js';
import type { MindmapNode } from './mindmap.js'; import type { MindmapNode } from './mindmap.js';
export type CollapseButton = { export type CollapseButton = {
@@ -14,9 +13,9 @@ export type CollapseButton = {
radius: number; radius: number;
filled: boolean; filled: boolean;
fillColor: string; fillColor: Color;
strokeColor: string; strokeColor: Color;
strokeWidth: number; strokeWidth: number;
}; };
@@ -25,24 +24,24 @@ export type ExpandButton = CollapseButton & {
fontSize: number; fontSize: number;
fontWeight: FontWeight; fontWeight: FontWeight;
color: string; color: Color;
}; };
export type NodeStyle = { export type NodeStyle = {
radius: number; radius: number;
strokeWidth: number; strokeWidth: number;
strokeColor: string; strokeColor: Color;
textResizing: TextResizing; textResizing: TextResizing;
fontSize: number; fontSize: number;
fontFamily: string; fontFamily: string;
fontWeight: FontWeight; fontWeight: FontWeight;
color: string; color: Color;
filled: boolean; filled: boolean;
fillColor: string; fillColor: Color;
padding: [number, number]; padding: [number, number];
@@ -56,7 +55,7 @@ export type NodeStyle = {
export type ConnectorStyle = { export type ConnectorStyle = {
strokeStyle: StrokeStyle; strokeStyle: StrokeStyle;
stroke: string; stroke: Color;
strokeWidth: number; strokeWidth: number;
mode: ConnectorMode; mode: ConnectorMode;
@@ -78,11 +77,11 @@ export abstract class MindmapStyleGetter {
export class StyleOne extends MindmapStyleGetter { export class StyleOne extends MindmapStyleGetter {
private readonly _colorOrders = [ private readonly _colorOrders = [
LineColor.Purple, DefaultTheme.StrokeColorMap.Purple,
LineColor.Magenta, DefaultTheme.StrokeColorMap.Magenta,
LineColor.Orange, DefaultTheme.StrokeColorMap.Orange,
LineColor.Yellow, DefaultTheme.StrokeColorMap.Yellow,
LineColor.Green, DefaultTheme.StrokeColorMap.Green,
'#7ae2d5', '#7ae2d5',
]; ];
@@ -92,15 +91,15 @@ export class StyleOne extends MindmapStyleGetter {
textResizing: TextResizing.AUTO_WIDTH_AND_HEIGHT, textResizing: TextResizing.AUTO_WIDTH_AND_HEIGHT,
strokeWidth: 4, strokeWidth: 4,
strokeColor: '#84CFFF', strokeColor: '#84cfff',
fontFamily: FontFamily.Poppins, fontFamily: FontFamily.Poppins,
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.SemiBold, fontWeight: FontWeight.SemiBold,
color: '--affine-black', color: DefaultTheme.pureBlack,
filled: true, filled: true,
fillColor: '--affine-white', fillColor: DefaultTheme.pureWhite,
padding: [11, 22] as [number, number], padding: [11, 22] as [number, number],
@@ -133,7 +132,7 @@ export class StyleOne extends MindmapStyleGetter {
radius: 0.5, radius: 0.5,
filled: true, filled: true,
fillColor: '--affine-white', fillColor: DefaultTheme.pureWhite,
strokeColor: color, strokeColor: color,
strokeWidth: 3, strokeWidth: 3,
@@ -151,7 +150,7 @@ export class StyleOne extends MindmapStyleGetter {
padding: [4, 0], padding: [4, 0],
color: '--affine-white', color: DefaultTheme.pureWhite,
fontFamily: FontFamily.Inter, fontFamily: FontFamily.Inter,
fontWeight: FontWeight.Bold, fontWeight: FontWeight.Bold,
@@ -168,10 +167,10 @@ export class StyleOne extends MindmapStyleGetter {
fontFamily: FontFamily.Poppins, fontFamily: FontFamily.Poppins,
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.Medium, fontWeight: FontWeight.Medium,
color: '--affine-black', color: DefaultTheme.pureBlack,
filled: true, filled: true,
fillColor: '--affine-white', fillColor: DefaultTheme.pureWhite,
padding: [6, 22] as [number, number], padding: [6, 22] as [number, number],
@@ -189,9 +188,9 @@ export const styleOne = new StyleOne();
export class StyleTwo extends MindmapStyleGetter { export class StyleTwo extends MindmapStyleGetter {
private readonly _colorOrders = [ private readonly _colorOrders = [
ShapeFillColor.Blue, DefaultTheme.StrokeColorMap.Blue,
'#7ae2d5', '#7ae2d5',
ShapeFillColor.Yellow, DefaultTheme.StrokeColorMap.Yellow,
]; ];
readonly root = { readonly root = {
@@ -200,15 +199,15 @@ export class StyleTwo extends MindmapStyleGetter {
textResizing: TextResizing.AUTO_WIDTH_AND_HEIGHT, textResizing: TextResizing.AUTO_WIDTH_AND_HEIGHT,
strokeWidth: 3, strokeWidth: 3,
strokeColor: '--affine-black', strokeColor: DefaultTheme.pureBlack,
fontFamily: FontFamily.Poppins, fontFamily: FontFamily.Poppins,
fontSize: 18, fontSize: 18,
fontWeight: FontWeight.SemiBold, fontWeight: FontWeight.SemiBold,
color: ShapeFillColor.Black, color: DefaultTheme.pureBlack,
filled: true, filled: true,
fillColor: ShapeFillColor.Orange, fillColor: DefaultTheme.StrokeColorMap.Yellow,
padding: [11, 22] as [number, number], padding: [11, 22] as [number, number],
@@ -216,7 +215,7 @@ export class StyleTwo extends MindmapStyleGetter {
blur: 0, blur: 0,
offsetX: 3, offsetX: 3,
offsetY: 3, offsetY: 3,
color: '--affine-black', color: DefaultTheme.pureBlack,
}, },
}; };
@@ -232,7 +231,7 @@ export class StyleTwo extends MindmapStyleGetter {
return { return {
connector: { connector: {
strokeStyle: StrokeStyle.Solid, strokeStyle: StrokeStyle.Solid,
stroke: '--affine-black', stroke: DefaultTheme.pureBlack,
strokeWidth: 3, strokeWidth: 3,
mode: ConnectorMode.Orthogonal, mode: ConnectorMode.Orthogonal,
@@ -243,9 +242,9 @@ export class StyleTwo extends MindmapStyleGetter {
radius: 0.5, radius: 0.5,
filled: true, filled: true,
fillColor: '--affine-white', fillColor: DefaultTheme.pureWhite,
strokeColor: '--affine-black', strokeColor: DefaultTheme.pureBlack,
strokeWidth: 3, strokeWidth: 3,
}, },
expandButton: { expandButton: {
@@ -254,14 +253,14 @@ export class StyleTwo extends MindmapStyleGetter {
radius: 2, radius: 2,
filled: true, filled: true,
fillColor: '--affine-black', fillColor: DefaultTheme.pureBlack,
padding: [4, 0], padding: [4, 0],
strokeColor: '--affine-black', strokeColor: DefaultTheme.pureBlack,
strokeWidth: 0, strokeWidth: 0,
color: '--affine-white', color: DefaultTheme.pureWhite,
fontFamily: FontFamily.Inter, fontFamily: FontFamily.Inter,
fontWeight: FontWeight.Bold, fontWeight: FontWeight.Bold,
@@ -273,12 +272,12 @@ export class StyleTwo extends MindmapStyleGetter {
textResizing: TextResizing.AUTO_WIDTH_AND_HEIGHT, textResizing: TextResizing.AUTO_WIDTH_AND_HEIGHT,
strokeWidth: 3, strokeWidth: 3,
strokeColor: '--affine-black', strokeColor: DefaultTheme.pureBlack,
fontFamily: FontFamily.Poppins, fontFamily: FontFamily.Poppins,
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.SemiBold, fontWeight: FontWeight.SemiBold,
color: ShapeFillColor.Black, color: DefaultTheme.pureBlack,
filled: true, filled: true,
fillColor: color, fillColor: color,
@@ -289,7 +288,7 @@ export class StyleTwo extends MindmapStyleGetter {
blur: 0, blur: 0,
offsetX: 3, offsetX: 3,
offsetY: 3, offsetY: 3,
color: '--affine-black', color: DefaultTheme.pureBlack,
}, },
}, },
}; };
@@ -299,9 +298,9 @@ export const styleTwo = new StyleTwo();
export class StyleThree extends MindmapStyleGetter { export class StyleThree extends MindmapStyleGetter {
private readonly _strokeColor = [ private readonly _strokeColor = [
LineColor.Yellow, DefaultTheme.StrokeColorMap.Yellow,
LineColor.Green, DefaultTheme.StrokeColorMap.Green,
LineColor.Teal, DefaultTheme.StrokeColorMap.Teal,
]; ];
readonly root = { readonly root = {
@@ -315,10 +314,10 @@ export class StyleThree extends MindmapStyleGetter {
fontFamily: FontFamily.Poppins, fontFamily: FontFamily.Poppins,
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.Medium, fontWeight: FontWeight.Medium,
color: ShapeFillColor.Black, color: DefaultTheme.pureBlack,
filled: true, filled: true,
fillColor: ShapeFillColor.Yellow, fillColor: DefaultTheme.StrokeColorMap.Yellow,
padding: [10, 22] as [number, number], padding: [10, 22] as [number, number],
@@ -349,10 +348,10 @@ export class StyleThree extends MindmapStyleGetter {
fontFamily: FontFamily.Poppins, fontFamily: FontFamily.Poppins,
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.Medium, fontWeight: FontWeight.Medium,
color: ShapeFillColor.Black, color: DefaultTheme.pureBlack,
filled: true, filled: true,
fillColor: ShapeFillColor.White, fillColor: DefaultTheme.pureWhite,
padding: [6, 22] as [number, number], padding: [6, 22] as [number, number],
@@ -369,9 +368,9 @@ export class StyleThree extends MindmapStyleGetter {
radius: 0.5, radius: 0.5,
filled: true, filled: true,
fillColor: '--affine-white', fillColor: DefaultTheme.pureWhite,
strokeColor: '#3CBC36', strokeColor: '#3cbc36',
strokeWidth: 3, strokeWidth: 3,
}, },
expandButton: { expandButton: {
@@ -380,11 +379,11 @@ export class StyleThree extends MindmapStyleGetter {
radius: 8, radius: 8,
filled: true, filled: true,
fillColor: '#3CBC36', fillColor: '#3cbc36',
padding: [4, 0], padding: [4, 0],
strokeColor: '#3CBC36', strokeColor: '#3cbc36',
strokeWidth: 0, strokeWidth: 0,
color: '#fff', color: '#fff',
@@ -407,12 +406,12 @@ export const styleThree = new StyleThree();
export class StyleFour extends MindmapStyleGetter { export class StyleFour extends MindmapStyleGetter {
private readonly _colors = [ private readonly _colors = [
ShapeFillColor.Purple, DefaultTheme.StrokeColorMap.Purple,
ShapeFillColor.Magenta, DefaultTheme.StrokeColorMap.Magenta,
ShapeFillColor.Orange, DefaultTheme.StrokeColorMap.Orange,
ShapeFillColor.Yellow, DefaultTheme.StrokeColorMap.Yellow,
ShapeFillColor.Green, DefaultTheme.StrokeColorMap.Green,
ShapeFillColor.Blue, DefaultTheme.StrokeColorMap.Blue,
]; ];
readonly root = { readonly root = {
@@ -426,7 +425,7 @@ export class StyleFour extends MindmapStyleGetter {
fontFamily: FontFamily.Kalam, fontFamily: FontFamily.Kalam,
fontSize: 22, fontSize: 22,
fontWeight: FontWeight.Bold, fontWeight: FontWeight.Bold,
color: '--affine-black', color: DefaultTheme.black,
filled: true, filled: true,
fillColor: 'transparent', fillColor: 'transparent',
@@ -455,7 +454,7 @@ export class StyleFour extends MindmapStyleGetter {
radius: 0.5, radius: 0.5,
filled: true, filled: true,
fillColor: '--affine-white', fillColor: DefaultTheme.pureWhite,
strokeColor: stroke, strokeColor: stroke,
strokeWidth: 3, strokeWidth: 3,
@@ -473,7 +472,7 @@ export class StyleFour extends MindmapStyleGetter {
strokeColor: stroke, strokeColor: stroke,
strokeWidth: 0, strokeWidth: 0,
color: '--affine-white', color: DefaultTheme.pureWhite,
fontFamily: FontFamily.Inter, fontFamily: FontFamily.Inter,
fontWeight: FontWeight.Bold, fontWeight: FontWeight.Bold,
@@ -19,22 +19,20 @@ import type {
import { DocCollection, type Y } from '@blocksuite/store'; import { DocCollection, type Y } from '@blocksuite/store';
import { import {
type Color,
DEFAULT_ROUGHNESS, DEFAULT_ROUGHNESS,
FontFamily, FontFamily,
FontStyle, FontStyle,
FontWeight, FontWeight,
ShapeFillColor,
ShapeStyle, ShapeStyle,
ShapeTextFontSize, ShapeTextFontSize,
ShapeType, ShapeType,
StrokeColor,
StrokeStyle, StrokeStyle,
TextAlign, TextAlign,
TextResizing, TextResizing,
type TextStyleProps, type TextStyleProps,
TextVerticalAlign, TextVerticalAlign,
} from '../../consts/index.js'; } from '../../consts/index.js';
import { type Color, DefaultTheme } from '../../themes/index.js';
import { shapeMethods } from './api/index.js'; import { shapeMethods } from './api/index.js';
export type ShapeProps = BaseElementProps & { export type ShapeProps = BaseElementProps & {
@@ -104,7 +102,7 @@ export class ShapeElementModel extends GfxPrimitiveElementModel<ShapeProps> {
accessor color!: Color; accessor color!: Color;
@field() @field()
accessor fillColor: Color = ShapeFillColor.Yellow; accessor fillColor: Color = DefaultTheme.shapeFillColor;
@field() @field()
accessor filled: boolean = false; accessor filled: boolean = false;
@@ -160,7 +158,7 @@ export class ShapeElementModel extends GfxPrimitiveElementModel<ShapeProps> {
accessor shapeType: ShapeType = ShapeType.Rect; accessor shapeType: ShapeType = ShapeType.Rect;
@field() @field()
accessor strokeColor: Color = StrokeColor.Yellow; accessor strokeColor: Color = DefaultTheme.shapeStrokeColor;
@field() @field()
accessor strokeStyle: StrokeStyle = StrokeStyle.Solid; accessor strokeStyle: StrokeStyle = StrokeStyle.Solid;
@@ -205,7 +203,7 @@ export class LocalShapeElementModel extends GfxLocalElementModel {
accessor color: Color = '#000000'; accessor color: Color = '#000000';
@prop() @prop()
accessor fillColor: Color = ShapeFillColor.Yellow; accessor fillColor: Color = DefaultTheme.shapeFillColor;
@prop() @prop()
accessor filled: boolean = false; accessor filled: boolean = false;
@@ -246,7 +244,7 @@ export class LocalShapeElementModel extends GfxLocalElementModel {
accessor shapeType: ShapeType = ShapeType.Rect; accessor shapeType: ShapeType = ShapeType.Rect;
@prop() @prop()
accessor strokeColor: Color = StrokeColor.Yellow; accessor strokeColor: Color = DefaultTheme.shapeStrokeColor;
@prop() @prop()
accessor strokeStyle: StrokeStyle = StrokeStyle.Solid; accessor strokeStyle: StrokeStyle = StrokeStyle.Solid;
@@ -11,13 +11,13 @@ import {
import { DocCollection, type Y } from '@blocksuite/store'; import { DocCollection, type Y } from '@blocksuite/store';
import { import {
type Color,
FontFamily, FontFamily,
FontStyle, FontStyle,
FontWeight, FontWeight,
TextAlign, TextAlign,
type TextStyleProps, type TextStyleProps,
} from '../../consts/index.js'; } from '../../consts/index.js';
import type { Color } from '../../themes/index.js';
export type TextElementProps = BaseElementProps & { export type TextElementProps = BaseElementProps & {
text: Y.Text; text: Y.Text;
+1
View File
@@ -1,4 +1,5 @@
export * from './blocks/index.js'; export * from './blocks/index.js';
export * from './consts/index.js'; export * from './consts/index.js';
export * from './elements/index.js'; export * from './elements/index.js';
export * from './themes/index.js';
export * from './utils/index.js'; export * from './utils/index.js';
@@ -0,0 +1,54 @@
import { z } from 'zod';
export enum ColorScheme {
Dark = 'dark',
Light = 'light',
}
const ColorNormalSchema = z.object({
normal: z.string(),
});
const ColorDarkLightSchema = z.object({
[ColorScheme.Dark]: z.string(),
[ColorScheme.Light]: z.string(),
});
export const ColorSchema = z.union([
z.string(),
ColorNormalSchema,
ColorDarkLightSchema,
]);
export type Color = z.infer<typeof ColorSchema>;
// Converts `Color` type to string.
export function resolveColor(
color: Color,
colorScheme: ColorScheme,
fallback = 'transparent'
): string {
let value = fallback;
if (typeof color === 'object') {
if (ColorScheme.Dark in color && ColorScheme.Light in color) {
value = color[colorScheme];
} else if ('normal' in color) {
value = color.normal;
}
} else {
value = color;
}
if (!value) {
value = fallback;
}
return value;
}
export function isTransparent(color: Color) {
return (
typeof color === 'string' && color.toLowerCase().endsWith('transparent')
);
}
@@ -0,0 +1,104 @@
import type { Palette, Theme } from './types.js';
import { buildPalettes, getColorByKey, pureBlack, pureWhite } from './utils.js';
const Transparent = 'transparent';
const White = getColorByKey('edgeless/palette/white');
const Black = getColorByKey('edgeless/palette/black');
const Light = {
Red: getColorByKey('edgeless/palette/light/redLight'),
Orange: getColorByKey('edgeless/palette/light/orangeLight'),
Yellow: getColorByKey('edgeless/palette/light/yellowLight'),
Green: getColorByKey('edgeless/palette/light/greenLight'),
Blue: getColorByKey('edgeless/palette/light/blueLight'),
Purple: getColorByKey('edgeless/palette/light/purpleLight'),
Magenta: getColorByKey('edgeless/palette/light/magentaLight'),
Grey: getColorByKey('edgeless/palette/light/greyLight'),
} as const;
const Medium = {
Red: getColorByKey('edgeless/palette/medium/redMedium'),
Orange: getColorByKey('edgeless/palette/medium/orangeMedium'),
Yellow: getColorByKey('edgeless/palette/medium/yellowMedium'),
Green: getColorByKey('edgeless/palette/medium/greenMedium'),
Blue: getColorByKey('edgeless/palette/medium/blueMedium'),
Purple: getColorByKey('edgeless/palette/medium/purpleMedium'),
Magenta: getColorByKey('edgeless/palette/medium/magentaMedium'),
Grey: getColorByKey('edgeless/palette/medium/greyMedium'),
} as const;
const Heavy = {
Red: getColorByKey('edgeless/palette/heavy/red'),
Orange: getColorByKey('edgeless/palette/heavy/orange'),
Yellow: getColorByKey('edgeless/palette/heavy/yellow'),
Green: getColorByKey('edgeless/palette/heavy/green'),
Blue: getColorByKey('edgeless/palette/heavy/blue'),
Purple: getColorByKey('edgeless/palette/heavy/purple'),
Magenta: getColorByKey('edgeless/palette/heavy/magenta'),
} as const;
const NoteBackgroundColorMap = {
Yellow: getColorByKey('edgeless/note/yellow'),
Orange: getColorByKey('edgeless/note/orange'),
Red: getColorByKey('edgeless/note/red'),
Magenta: getColorByKey('edgeless/note/magenta'),
Purple: getColorByKey('edgeless/note/purple'),
Blue: getColorByKey('edgeless/note/blue'),
Teal: getColorByKey('edgeless/note/teal'),
Green: getColorByKey('edgeless/note/green'),
Black: getColorByKey('edgeless/note/black'),
Grey: getColorByKey('edgeless/note/grey'),
White: getColorByKey('edgeless/note/white'),
} as const;
const Palettes: Palette[] = [
// Light
...buildPalettes(Light, 'Light'),
{ key: 'Transparent', value: Transparent },
// Medium
...buildPalettes(Medium, 'Medium'),
{ key: 'White', value: White },
// Heavy
...buildPalettes(Heavy, 'Heavy'),
{ key: 'Black', value: Black },
] as const;
const NoteBackgroundColorPalettes: Palette[] = [
...buildPalettes(NoteBackgroundColorMap),
] as const;
const StrokeColorMap = { ...Medium, Black, White } as const;
const StrokeColorPalettes: Palette[] = [
...buildPalettes(StrokeColorMap),
] as const;
const FillColorMap = { ...Light, Black, White } as const;
const FillColorPalettes: Palette[] = [...buildPalettes(FillColorMap)] as const;
export const DefaultTheme: Theme = {
pureBlack,
pureWhite,
black: Black,
white: White,
transparent: Transparent,
textColor: Medium.Blue,
shapeTextColor: Black,
shapeStrokeColor: Medium.Yellow,
shapeFillColor: Light.Yellow,
connectorColor: Medium.Grey,
noteBackgrounColor: NoteBackgroundColorMap.White,
Palettes,
StrokeColorMap,
StrokeColorPalettes,
FillColorMap,
FillColorPalettes,
NoteBackgroundColorMap,
NoteBackgroundColorPalettes,
} as const;
@@ -0,0 +1,10 @@
import { DefaultTheme } from './default.js';
import type { Theme } from './types.js';
export * from './color.js';
export { DefaultTheme } from './default.js';
export * from './types.js';
export const Themes: Record<string, Theme> = {
default: DefaultTheme,
};
@@ -0,0 +1,36 @@
import { z } from 'zod';
import { ColorSchema } from './color.js';
export const PaletteSchema = z.object({
key: z.string(),
value: ColorSchema,
});
export type Palette = z.infer<typeof PaletteSchema>;
export const ThemeSchema = z.object({
pureBlack: z.string(),
pureWhite: z.string(),
black: ColorSchema,
white: ColorSchema,
transparent: z.literal('transparent'),
textColor: ColorSchema,
shapeTextColor: ColorSchema,
shapeStrokeColor: ColorSchema,
shapeFillColor: ColorSchema,
connectorColor: ColorSchema,
noteBackgrounColor: ColorSchema,
// Universal color palette
Palettes: z.array(PaletteSchema),
StrokeColorMap: z.record(z.string(), ColorSchema),
// Usually used in global toolbar and editor preview
StrokeColorPalettes: z.array(PaletteSchema),
FillColorMap: z.record(z.string(), ColorSchema),
// Usually used in global toolbar and editor preview
FillColorPalettes: z.array(PaletteSchema),
NoteBackgroundColorMap: z.record(z.string(), ColorSchema),
NoteBackgroundColorPalettes: z.array(PaletteSchema),
});
export type Theme = z.infer<typeof ThemeSchema>;
@@ -0,0 +1,29 @@
import {
type AffineThemeKeyV2,
darkThemeV2,
lightThemeV2,
} from '@toeverything/theme/v2';
import type { Color } from './color.js';
import type { Palette } from './types.js';
// Converts a color map to color list.
export function buildPalettes(
obj: Record<string, Color>,
prefix = ''
): Palette[] {
return Object.entries<Color>(obj).map(([key, value]) => ({
key: `${prefix}${key}`,
value,
}));
}
export function getColorByKey(key: AffineThemeKeyV2): Color {
const dark = darkThemeV2[key];
const light = lightThemeV2[key];
if (dark === light) return dark;
return { dark, light };
}
export const pureBlack = lightThemeV2['edgeless/palette/black'];
export const pureWhite = lightThemeV2['edgeless/palette/white'];
@@ -1,7 +1,4 @@
import { import { DefaultTheme, NoteDisplayMode } from '@blocksuite/affine-model';
DEFAULT_NOTE_BACKGROUND_COLOR,
NoteDisplayMode,
} from '@blocksuite/affine-model';
import type { ExtensionType } from '@blocksuite/block-std'; import type { ExtensionType } from '@blocksuite/block-std';
import type { ServiceProvider } from '@blocksuite/global/di'; import type { ServiceProvider } from '@blocksuite/global/di';
import { import {
@@ -272,7 +269,7 @@ export class HtmlAdapter extends BaseAdapter<Html> {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -297,7 +294,7 @@ export class HtmlAdapter extends BaseAdapter<Html> {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -357,7 +354,7 @@ export class HtmlAdapter extends BaseAdapter<Html> {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1,7 +1,4 @@
import { import { DefaultTheme, NoteDisplayMode } from '@blocksuite/affine-model';
DEFAULT_NOTE_BACKGROUND_COLOR,
NoteDisplayMode,
} from '@blocksuite/affine-model';
import type { ExtensionType } from '@blocksuite/block-std'; import type { ExtensionType } from '@blocksuite/block-std';
import type { ServiceProvider } from '@blocksuite/global/di'; import type { ServiceProvider } from '@blocksuite/global/di';
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions'; import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
@@ -176,7 +173,7 @@ export class NotionHtmlAdapter extends BaseAdapter<NotionHtml> {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -207,7 +204,7 @@ export class NotionHtmlAdapter extends BaseAdapter<NotionHtml> {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -268,7 +265,7 @@ export class NotionHtmlAdapter extends BaseAdapter<NotionHtml> {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1,4 +1,4 @@
import { DEFAULT_NOTE_BACKGROUND_COLOR } from '@blocksuite/affine-model'; import { DefaultTheme } from '@blocksuite/affine-model';
import type { ExtensionType } from '@blocksuite/block-std'; import type { ExtensionType } from '@blocksuite/block-std';
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions'; import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
import type { DeltaInsert } from '@blocksuite/inline'; import type { DeltaInsert } from '@blocksuite/inline';
@@ -127,7 +127,7 @@ export class NotionTextAdapter extends BaseAdapter<NotionText> {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: 'both', displayMode: 'both',
@@ -1,7 +1,4 @@
import { import { DefaultTheme, NoteDisplayMode } from '@blocksuite/affine-model';
DEFAULT_NOTE_BACKGROUND_COLOR,
NoteDisplayMode,
} from '@blocksuite/affine-model';
import type { ExtensionType } from '@blocksuite/block-std'; import type { ExtensionType } from '@blocksuite/block-std';
import type { ServiceProvider } from '@blocksuite/global/di'; import type { ServiceProvider } from '@blocksuite/global/di';
import { import {
@@ -175,7 +172,7 @@ export class PlainTextAdapter extends BaseAdapter<PlainText> {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -242,7 +239,7 @@ export class PlainTextAdapter extends BaseAdapter<PlainText> {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -285,7 +282,7 @@ export class PlainTextAdapter extends BaseAdapter<PlainText> {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1,3 +1,4 @@
import { ColorSchema } from '@blocksuite/affine-model';
import { type BlockStdScope, LifeCycleWatcher } from '@blocksuite/block-std'; import { type BlockStdScope, LifeCycleWatcher } from '@blocksuite/block-std';
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions'; import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
import { import {
@@ -11,11 +12,7 @@ import clonedeep from 'lodash.clonedeep';
import mergeWith from 'lodash.mergewith'; import mergeWith from 'lodash.mergewith';
import { z } from 'zod'; import { z } from 'zod';
import { import { makeDeepOptional, NodePropsSchema } from '../utils/index.js';
ColorSchema,
makeDeepOptional,
NodePropsSchema,
} from '../utils/index.js';
import { EditorSettingProvider } from './editor-setting-service.js'; import { EditorSettingProvider } from './editor-setting-service.js';
const LastPropsSchema = NodePropsSchema; const LastPropsSchema = NodePropsSchema;
@@ -1,4 +1,9 @@
import { type Color, ColorScheme } from '@blocksuite/affine-model'; import {
type Color,
ColorScheme,
DefaultTheme,
resolveColor,
} from '@blocksuite/affine-model';
import { import {
type BlockStdScope, type BlockStdScope,
Extension, Extension,
@@ -15,8 +20,6 @@ import {
import { isInsideEdgelessEditor } from '../utils/index.js'; import { isInsideEdgelessEditor } from '../utils/index.js';
const TRANSPARENT = 'transparent';
export const ThemeExtensionIdentifier = createIdentifier<ThemeExtension>( export const ThemeExtensionIdentifier = createIdentifier<ThemeExtension>(
'AffineThemeExtension' 'AffineThemeExtension'
); );
@@ -52,9 +55,7 @@ export class ThemeService extends Extension {
} }
get theme() { get theme() {
return isInsideEdgelessEditor(this.std.host) return this.theme$.peek();
? this.edgelessTheme
: this.appTheme;
} }
get theme$() { get theme$() {
@@ -94,24 +95,19 @@ export class ThemeService extends Extension {
*/ */
generateColorProperty( generateColorProperty(
color: Color, color: Color,
fallback = 'transparent', fallback: Color = DefaultTheme.transparent,
theme = this.theme theme = this.theme
) { ) {
let result: string | undefined = undefined; const result = resolveColor(color, theme, resolveColor(fallback, theme));
if (typeof color === 'object') { // Compatible old data
result = color[theme] ?? color.normal;
} else {
result = color;
}
if (!result) {
result = fallback;
}
if (result.startsWith('--')) { if (result.startsWith('--')) {
return result.endsWith(TRANSPARENT) ? TRANSPARENT : `var(${result})`; return result.endsWith('transparent')
? DefaultTheme.transparent
: `var(${result})`;
} }
return result ?? TRANSPARENT; return result;
} }
/** /**
@@ -132,35 +128,30 @@ export class ThemeService extends Extension {
*/ */
getColorValue( getColorValue(
color: Color, color: Color,
fallback = TRANSPARENT, fallback: Color = DefaultTheme.transparent,
real = false, real = false,
theme = this.theme theme = this.theme
) { ) {
let result: string | undefined = undefined; let result = resolveColor(color, theme, resolveColor(fallback, theme));
if (typeof color === 'object') { // Compatible old data
result = color[theme] ?? color.normal;
} else {
result = color;
}
if (!result) {
result = fallback;
}
if (real && result.startsWith('--')) { if (real && result.startsWith('--')) {
result = result.endsWith(TRANSPARENT) result = result.endsWith('transparent')
? TRANSPARENT ? DefaultTheme.transparent
: this.getCssVariableColor(result, theme); : this.getCssVariableColor(result, theme);
} }
return result ?? TRANSPARENT; return result ?? DefaultTheme.transparent;
} }
getCssVariableColor(property: string, theme = this.theme) { getCssVariableColor(property: string, theme = this.theme) {
// Compatible old data
if (property.startsWith('--')) { if (property.startsWith('--')) {
if (property.endsWith(TRANSPARENT)) { if (property.endsWith('transparent')) {
return TRANSPARENT; return DefaultTheme.transparent;
} }
const key = property as keyof AffineCssVariables; const key = property as keyof AffineCssVariables;
// V1 theme
const color = const color =
theme === ColorScheme.Dark theme === ColorScheme.Dark
? combinedDarkCssVariables[key] ? combinedDarkCssVariables[key]
@@ -1,33 +1,24 @@
import { import {
ColorSchema,
ConnectorMode, ConnectorMode,
DEFAULT_CONNECTOR_COLOR,
DEFAULT_CONNECTOR_TEXT_COLOR,
DEFAULT_FRONT_END_POINT_STYLE, DEFAULT_FRONT_END_POINT_STYLE,
DEFAULT_NOTE_BACKGROUND_COLOR,
DEFAULT_NOTE_BORDER_SIZE, DEFAULT_NOTE_BORDER_SIZE,
DEFAULT_NOTE_BORDER_STYLE, DEFAULT_NOTE_BORDER_STYLE,
DEFAULT_NOTE_CORNER, DEFAULT_NOTE_CORNER,
DEFAULT_NOTE_SHADOW, DEFAULT_NOTE_SHADOW,
DEFAULT_REAR_END_POINT_STYLE, DEFAULT_REAR_END_POINT_STYLE,
DEFAULT_ROUGHNESS, DEFAULT_ROUGHNESS,
DEFAULT_SHAPE_FILL_COLOR, DefaultTheme,
DEFAULT_SHAPE_STROKE_COLOR,
DEFAULT_SHAPE_TEXT_COLOR,
DEFAULT_TEXT_COLOR,
FontFamily, FontFamily,
FontStyle, FontStyle,
FontWeight, FontWeight,
LayoutType, LayoutType,
LineColorsSchema,
LineWidth, LineWidth,
MindmapStyle, MindmapStyle,
NoteBackgroundPaletteEnum,
NoteDisplayMode, NoteDisplayMode,
NoteShadowsSchema, NoteShadowsSchema,
PaletteEnum,
PointStyle, PointStyle,
ShapeStyle, ShapeStyle,
StrokeColor,
StrokeStyle, StrokeStyle,
TextAlign, TextAlign,
TextVerticalAlign, TextVerticalAlign,
@@ -48,34 +39,17 @@ const ConnectorModeSchema = z.nativeEnum(ConnectorMode);
const LayoutTypeSchema = z.nativeEnum(LayoutType); const LayoutTypeSchema = z.nativeEnum(LayoutType);
const MindmapStyleSchema = z.nativeEnum(MindmapStyle); const MindmapStyleSchema = z.nativeEnum(MindmapStyle);
export const ColorSchema = z.union([
z.object({
normal: z.string(),
}),
z.object({
light: z.string(),
dark: z.string(),
}),
]);
const ColorPaletteSchema = z.union([ColorSchema, PaletteEnum]);
const LineColorSchema = z.union([LineColorsSchema, ColorPaletteSchema]);
const TextColorSchema = z.union([LineColorsSchema, ColorPaletteSchema]);
const NoteBackgroundColorSchema = z.union([
ColorSchema,
NoteBackgroundPaletteEnum,
]);
export const ConnectorSchema = z export const ConnectorSchema = z
.object({ .object({
frontEndpointStyle: ConnectorEndpointSchema, frontEndpointStyle: ConnectorEndpointSchema,
rearEndpointStyle: ConnectorEndpointSchema, rearEndpointStyle: ConnectorEndpointSchema,
stroke: LineColorSchema, stroke: ColorSchema,
strokeStyle: StrokeStyleSchema, strokeStyle: StrokeStyleSchema,
strokeWidth: LineWidthSchema, strokeWidth: LineWidthSchema,
rough: z.boolean(), rough: z.boolean(),
mode: ConnectorModeSchema, mode: ConnectorModeSchema,
labelStyle: z.object({ labelStyle: z.object({
color: TextColorSchema, color: ColorSchema,
fontSize: z.number(), fontSize: z.number(),
fontFamily: FontFamilySchema, fontFamily: FontFamilySchema,
fontWeight: FontWeightSchema, fontWeight: FontWeightSchema,
@@ -86,13 +60,13 @@ export const ConnectorSchema = z
.default({ .default({
frontEndpointStyle: DEFAULT_FRONT_END_POINT_STYLE, frontEndpointStyle: DEFAULT_FRONT_END_POINT_STYLE,
rearEndpointStyle: DEFAULT_REAR_END_POINT_STYLE, rearEndpointStyle: DEFAULT_REAR_END_POINT_STYLE,
stroke: DEFAULT_CONNECTOR_COLOR, stroke: DefaultTheme.connectorColor,
strokeStyle: StrokeStyle.Solid, strokeStyle: StrokeStyle.Solid,
strokeWidth: LineWidth.Two, strokeWidth: LineWidth.Two,
rough: false, rough: false,
mode: ConnectorMode.Curve, mode: ConnectorMode.Curve,
labelStyle: { labelStyle: {
color: DEFAULT_CONNECTOR_TEXT_COLOR, color: DefaultTheme.black,
fontSize: 16, fontSize: 16,
fontFamily: FontFamily.Inter, fontFamily: FontFamily.Inter,
fontWeight: FontWeight.Regular, fontWeight: FontWeight.Regular,
@@ -103,21 +77,18 @@ export const ConnectorSchema = z
export const BrushSchema = z export const BrushSchema = z
.object({ .object({
color: ColorPaletteSchema, color: ColorSchema,
lineWidth: LineWidthSchema, lineWidth: LineWidthSchema,
}) })
.default({ .default({
color: { color: DefaultTheme.black,
dark: StrokeColor.White,
light: StrokeColor.Black,
},
lineWidth: LineWidth.Four, lineWidth: LineWidth.Four,
}); });
const DEFAULT_SHAPE = { const DEFAULT_SHAPE = {
color: DEFAULT_SHAPE_TEXT_COLOR, color: DefaultTheme.shapeTextColor,
fillColor: DEFAULT_SHAPE_FILL_COLOR, fillColor: DefaultTheme.shapeFillColor,
strokeColor: DEFAULT_SHAPE_STROKE_COLOR, strokeColor: DefaultTheme.shapeStrokeColor,
strokeStyle: StrokeStyle.Solid, strokeStyle: StrokeStyle.Solid,
strokeWidth: LineWidth.Two, strokeWidth: LineWidth.Two,
shapeStyle: ShapeStyle.General, shapeStyle: ShapeStyle.General,
@@ -132,9 +103,9 @@ const DEFAULT_SHAPE = {
}; };
const ShapeObject = { const ShapeObject = {
color: TextColorSchema, color: ColorSchema,
fillColor: ColorPaletteSchema, fillColor: ColorSchema,
strokeColor: ColorPaletteSchema, strokeColor: ColorSchema,
strokeStyle: StrokeStyleSchema, strokeStyle: StrokeStyleSchema,
strokeWidth: z.number(), strokeWidth: z.number(),
shapeStyle: ShapeStyleSchema, shapeStyle: ShapeStyleSchema,
@@ -158,7 +129,7 @@ export const RoundedShapeSchema = z
export const TextSchema = z export const TextSchema = z
.object({ .object({
color: TextColorSchema, color: ColorSchema,
fontSize: z.number(), fontSize: z.number(),
fontFamily: FontFamilySchema, fontFamily: FontFamilySchema,
fontWeight: FontWeightSchema, fontWeight: FontWeightSchema,
@@ -166,7 +137,7 @@ export const TextSchema = z
textAlign: TextAlignSchema, textAlign: TextAlignSchema,
}) })
.default({ .default({
color: DEFAULT_TEXT_COLOR, color: DefaultTheme.textColor,
fontSize: 24, fontSize: 24,
fontFamily: FontFamily.Inter, fontFamily: FontFamily.Inter,
fontWeight: FontWeight.Regular, fontWeight: FontWeight.Regular,
@@ -176,14 +147,14 @@ export const TextSchema = z
export const EdgelessTextSchema = z export const EdgelessTextSchema = z
.object({ .object({
color: TextColorSchema, color: ColorSchema,
fontFamily: FontFamilySchema, fontFamily: FontFamilySchema,
fontWeight: FontWeightSchema, fontWeight: FontWeightSchema,
fontStyle: FontStyleSchema, fontStyle: FontStyleSchema,
textAlign: TextAlignSchema, textAlign: TextAlignSchema,
}) })
.default({ .default({
color: DEFAULT_TEXT_COLOR, color: DefaultTheme.textColor,
fontFamily: FontFamily.Inter, fontFamily: FontFamily.Inter,
fontWeight: FontWeight.Regular, fontWeight: FontWeight.Regular,
fontStyle: FontStyle.Normal, fontStyle: FontStyle.Normal,
@@ -192,7 +163,7 @@ export const EdgelessTextSchema = z
export const NoteSchema = z export const NoteSchema = z
.object({ .object({
background: NoteBackgroundColorSchema, background: ColorSchema,
displayMode: NoteDisplayModeSchema, displayMode: NoteDisplayModeSchema,
edgeless: z.object({ edgeless: z.object({
style: z.object({ style: z.object({
@@ -204,7 +175,7 @@ export const NoteSchema = z
}), }),
}) })
.default({ .default({
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
displayMode: NoteDisplayMode.EdgelessOnly, displayMode: NoteDisplayMode.EdgelessOnly,
edgeless: { edgeless: {
style: { style: {
@@ -228,7 +199,7 @@ export const MindmapSchema = z
export const FrameSchema = z export const FrameSchema = z
.object({ .object({
background: ColorPaletteSchema.optional(), background: ColorSchema.optional(),
}) })
.default({}); .default({});
+4 -3
View File
@@ -54,6 +54,7 @@
"html2canvas": "^1.4.1", "html2canvas": "^1.4.1",
"katex": "^0.16.11", "katex": "^0.16.11",
"lit": "^3.2.0", "lit": "^3.2.0",
"lodash.isequal": "^4.5.0",
"lz-string": "^1.5.0", "lz-string": "^1.5.0",
"mdast-util-gfm-autolink-literal": "^2.0.1", "mdast-util-gfm-autolink-literal": "^2.0.1",
"mdast-util-gfm-strikethrough": "^2.0.0", "mdast-util-gfm-strikethrough": "^2.0.0",
@@ -92,7 +93,7 @@
], ],
"devDependencies": { "devDependencies": {
"@types/dompurify": "^3.0.5", "@types/dompurify": "^3.0.5",
"@types/katex": "^0.16.7" "@types/katex": "^0.16.7",
}, "@types/lodash.isequal": "^4.5.8"
"version": "0.19.0" }
} }
@@ -1,7 +1,4 @@
import { import { DefaultTheme, NoteDisplayMode } from '@blocksuite/affine-model';
DEFAULT_NOTE_BACKGROUND_COLOR,
NoteDisplayMode,
} from '@blocksuite/affine-model';
import { HtmlAdapter } from '@blocksuite/affine-shared/adapters'; import { HtmlAdapter } from '@blocksuite/affine-shared/adapters';
import { Container } from '@blocksuite/global/di'; import { Container } from '@blocksuite/global/di';
import type { import type {
@@ -108,7 +105,7 @@ describe('snapshot to html', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -174,7 +171,7 @@ describe('snapshot to html', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -240,7 +237,7 @@ describe('snapshot to html', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -306,7 +303,7 @@ describe('snapshot to html', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -492,7 +489,7 @@ describe('snapshot to html', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -637,7 +634,7 @@ describe('snapshot to html', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -742,7 +739,7 @@ describe('snapshot to html', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -816,7 +813,7 @@ describe('snapshot to html', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -890,7 +887,7 @@ describe('snapshot to html', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -965,7 +962,7 @@ describe('snapshot to html', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1040,7 +1037,7 @@ describe('snapshot to html', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1160,7 +1157,7 @@ describe('snapshot to html', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1221,7 +1218,7 @@ describe('snapshot to html', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1485,7 +1482,7 @@ describe('snapshot to html', () => {
version: 1, version: 1,
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1576,7 +1573,7 @@ describe('snapshot to html', () => {
version: 1, version: 1,
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: 'both', displayMode: 'both',
@@ -1969,7 +1966,7 @@ describe('html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -2011,7 +2008,7 @@ describe('html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -2121,7 +2118,7 @@ describe('html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -2187,7 +2184,7 @@ describe('html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -2234,7 +2231,7 @@ describe('html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -2270,7 +2267,7 @@ describe('html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -2382,7 +2379,7 @@ describe('html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -2426,7 +2423,7 @@ describe('html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -2470,7 +2467,7 @@ describe('html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -2523,7 +2520,7 @@ describe('html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -2573,7 +2570,7 @@ describe('html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1,7 +1,4 @@
import { import { DefaultTheme, NoteDisplayMode } from '@blocksuite/affine-model';
DEFAULT_NOTE_BACKGROUND_COLOR,
NoteDisplayMode,
} from '@blocksuite/affine-model';
import type { import type {
BlockSnapshot, BlockSnapshot,
DocSnapshot, DocSnapshot,
@@ -44,7 +41,7 @@ describe('snapshot to markdown', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -108,7 +105,7 @@ describe('snapshot to markdown', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -307,7 +304,7 @@ hhh
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -455,7 +452,7 @@ hhh
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -607,7 +604,7 @@ hhh
version: 1, version: 1,
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: 'both', displayMode: 'both',
@@ -750,7 +747,7 @@ hhh
version: 1, version: 1,
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: 'both', displayMode: 'both',
@@ -911,7 +908,7 @@ hhh
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -983,7 +980,7 @@ hhh
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1055,7 +1052,7 @@ hhh
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1111,7 +1108,7 @@ hhh
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1183,7 +1180,7 @@ hhh
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1252,7 +1249,7 @@ hhh
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1325,7 +1322,7 @@ hhh
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1398,7 +1395,7 @@ hhh
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1707,7 +1704,7 @@ hhh
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1975,7 +1972,7 @@ hhh
version: 1, version: 1,
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: 'both', displayMode: 'both',
@@ -2348,7 +2345,7 @@ describe('markdown to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -2393,7 +2390,7 @@ describe('markdown to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: 'both', displayMode: 'both',
@@ -2444,7 +2441,7 @@ describe('markdown to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: 'both', displayMode: 'both',
@@ -2495,7 +2492,7 @@ describe('markdown to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: 'both', displayMode: 'both',
@@ -2558,7 +2555,7 @@ hhh
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -2728,7 +2725,7 @@ hhh
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -2864,7 +2861,7 @@ hhh
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -2998,7 +2995,7 @@ bbb
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -3099,7 +3096,7 @@ bbb
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -3153,7 +3150,7 @@ bbb
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: 'both', displayMode: 'both',
@@ -3206,7 +3203,7 @@ bbb
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -3256,7 +3253,7 @@ bbb
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -3307,7 +3304,7 @@ bbb
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -3358,7 +3355,7 @@ bbb
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -3412,7 +3409,7 @@ bbb
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -3530,7 +3527,7 @@ bbb
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -3571,7 +3568,7 @@ bbb
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -3622,7 +3619,7 @@ bbb
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -3673,7 +3670,7 @@ hhh
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: 'both', displayMode: 'both',
@@ -1,7 +1,4 @@
import { import { DefaultTheme, NoteDisplayMode } from '@blocksuite/affine-model';
DEFAULT_NOTE_BACKGROUND_COLOR,
NoteDisplayMode,
} from '@blocksuite/affine-model';
import { NotionHtmlAdapter } from '@blocksuite/affine-shared/adapters'; import { NotionHtmlAdapter } from '@blocksuite/affine-shared/adapters';
import { Container } from '@blocksuite/global/di'; import { Container } from '@blocksuite/global/di';
import { import {
@@ -42,7 +39,7 @@ describe('notion html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -97,7 +94,7 @@ describe('notion html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -212,7 +209,7 @@ describe('notion html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -378,7 +375,7 @@ describe('notion html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -823,7 +820,7 @@ describe('notion html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -952,7 +949,7 @@ describe('notion html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1053,7 +1050,7 @@ describe('notion html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1102,7 +1099,7 @@ describe('notion html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1171,7 +1168,7 @@ describe('notion html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1220,7 +1217,7 @@ describe('notion html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1267,7 +1264,7 @@ describe('notion html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1311,7 +1308,7 @@ describe('notion html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1435,7 +1432,7 @@ describe('notion html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1714,7 +1711,7 @@ describe('notion html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: 'both', displayMode: 'both',
@@ -1907,7 +1904,7 @@ describe('notion html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1948,7 +1945,7 @@ describe('notion html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -2000,7 +1997,7 @@ describe('notion html to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1,4 +1,4 @@
import { DEFAULT_NOTE_BACKGROUND_COLOR } from '@blocksuite/affine-model'; import { DefaultTheme } from '@blocksuite/affine-model';
import { NotionTextAdapter } from '@blocksuite/affine-shared/adapters'; import { NotionTextAdapter } from '@blocksuite/affine-shared/adapters';
import type { SliceSnapshot } from '@blocksuite/store'; import type { SliceSnapshot } from '@blocksuite/store';
import { describe, expect, test } from 'vitest'; import { describe, expect, test } from 'vitest';
@@ -20,7 +20,7 @@ describe('notion-text to snapshot', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: 'both', displayMode: 'both',
@@ -1,7 +1,4 @@
import { import { DefaultTheme, NoteDisplayMode } from '@blocksuite/affine-model';
DEFAULT_NOTE_BACKGROUND_COLOR,
NoteDisplayMode,
} from '@blocksuite/affine-model';
import { PlainTextAdapter } from '@blocksuite/affine-shared/adapters'; import { PlainTextAdapter } from '@blocksuite/affine-shared/adapters';
import { Container } from '@blocksuite/global/di'; import { Container } from '@blocksuite/global/di';
import type { import type {
@@ -53,7 +50,7 @@ describe('snapshot to plain text', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -206,7 +203,7 @@ describe('snapshot to plain text', () => {
version: 1, version: 1,
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -362,7 +359,7 @@ describe('snapshot to plain text', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -432,7 +429,7 @@ describe('snapshot to plain text', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -495,7 +492,7 @@ describe('snapshot to plain text', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -664,7 +661,7 @@ describe('snapshot to plain text', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -727,7 +724,7 @@ describe('snapshot to plain text', () => {
version: 1, version: 1,
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -820,7 +817,7 @@ describe('snapshot to plain text', () => {
version: 1, version: 1,
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: 'both', displayMode: 'both',
@@ -1179,7 +1176,7 @@ describe('snapshot to plain text', () => {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1,7 +1,4 @@
import { import { DefaultTheme, NoteDisplayMode } from '@blocksuite/affine-model';
DEFAULT_NOTE_BACKGROUND_COLOR,
NoteDisplayMode,
} from '@blocksuite/affine-model';
import { import {
type AdapterContext, type AdapterContext,
AdapterFactoryIdentifier, AdapterFactoryIdentifier,
@@ -270,7 +267,7 @@ export class MarkdownAdapter extends BaseAdapter<Markdown> {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -294,7 +291,7 @@ export class MarkdownAdapter extends BaseAdapter<Markdown> {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -413,7 +410,7 @@ export class MarkdownAdapter extends BaseAdapter<Markdown> {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -1,7 +1,4 @@
import { import { DefaultTheme, NoteDisplayMode } from '@blocksuite/affine-model';
DEFAULT_NOTE_BACKGROUND_COLOR,
NoteDisplayMode,
} from '@blocksuite/affine-model';
import { AdapterFactoryIdentifier } from '@blocksuite/affine-shared/adapters'; import { AdapterFactoryIdentifier } from '@blocksuite/affine-shared/adapters';
import type { ExtensionType } from '@blocksuite/block-std'; import type { ExtensionType } from '@blocksuite/block-std';
import type { DeltaInsert } from '@blocksuite/inline'; import type { DeltaInsert } from '@blocksuite/inline';
@@ -164,7 +161,7 @@ export class MixTextAdapter extends BaseAdapter<MixText> {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -231,7 +228,7 @@ export class MixTextAdapter extends BaseAdapter<MixText> {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -284,7 +281,7 @@ export class MixTextAdapter extends BaseAdapter<MixText> {
flavour: 'affine:note', flavour: 'affine:note',
props: { props: {
xywh: '[0,0,800,95]', xywh: '[0,0,800,95]',
background: DEFAULT_NOTE_BACKGROUND_COLOR, background: DefaultTheme.noteBackgrounColor,
index: 'a0', index: 'a0',
hidden: false, hidden: false,
displayMode: NoteDisplayMode.DocAndEdgeless, displayMode: NoteDisplayMode.DocAndEdgeless,
@@ -14,11 +14,8 @@ import type {
ShapeElementModel, ShapeElementModel,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
import { import {
DEFAULT_NOTE_BACKGROUND_COLOR,
DEFAULT_NOTE_WIDTH, DEFAULT_NOTE_WIDTH,
DEFAULT_SHAPE_FILL_COLOR, DefaultTheme,
DEFAULT_SHAPE_STROKE_COLOR,
DEFAULT_TEXT_COLOR,
FontFamily, FontFamily,
FontStyle, FontStyle,
FontWeight, FontWeight,
@@ -282,7 +279,7 @@ export class EdgelessAutoCompletePanel extends WithDisposable(LitElement) {
textAlign: 'left', textAlign: 'left',
fontSize: 24, fontSize: 24,
fontFamily: FontFamily.Inter, fontFamily: FontFamily.Inter,
color: DEFAULT_TEXT_COLOR, color: DefaultTheme.textColor,
fontWeight: FontWeight.Regular, fontWeight: FontWeight.Regular,
fontStyle: FontStyle.Normal, fontStyle: FontStyle.Normal,
}); });
@@ -474,7 +471,7 @@ export class EdgelessAutoCompletePanel extends WithDisposable(LitElement) {
.getColorValue( .getColorValue(
this.edgeless.std.get(EditPropsStore).lastProps$.value['affine:note'] this.edgeless.std.get(EditPropsStore).lastProps$.value['affine:note']
.background, .background,
DEFAULT_NOTE_BACKGROUND_COLOR, DefaultTheme.noteBackgrounColor,
true true
); );
this._overlay = new AutoCompleteNoteOverlay(this.gfx, xywh, background); this._overlay = new AutoCompleteNoteOverlay(this.gfx, xywh, background);
@@ -515,10 +512,10 @@ export class EdgelessAutoCompletePanel extends WithDisposable(LitElement) {
const stroke = this.edgeless.std const stroke = this.edgeless.std
.get(ThemeProvider) .get(ThemeProvider)
.getColorValue(strokeColor, DEFAULT_SHAPE_STROKE_COLOR, true); .getColorValue(strokeColor, DefaultTheme.shapeStrokeColor, true);
const fill = this.edgeless.std const fill = this.edgeless.std
.get(ThemeProvider) .get(ThemeProvider)
.getColorValue(fillColor, DEFAULT_SHAPE_FILL_COLOR, true); .getColorValue(fillColor, DefaultTheme.shapeFillColor, true);
const options = { const options = {
seed: 666, seed: 666,
@@ -21,7 +21,7 @@ import type {
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
import { import {
DEFAULT_NOTE_HEIGHT, DEFAULT_NOTE_HEIGHT,
DEFAULT_SHAPE_STROKE_COLOR, DefaultTheme,
LayoutType, LayoutType,
MindmapElementModel, MindmapElementModel,
ShapeElementModel, ShapeElementModel,
@@ -643,7 +643,7 @@ export class EdgelessAutoComplete extends WithDisposable(LitElement) {
this._autoCompleteOverlay.stroke = surface.renderer.getColorValue( this._autoCompleteOverlay.stroke = surface.renderer.getColorValue(
current.strokeColor, current.strokeColor,
DEFAULT_SHAPE_STROKE_COLOR, DefaultTheme.shapeStrokeColor,
true true
); );
this._autoCompleteOverlay.linePoints = path; this._autoCompleteOverlay.linePoints = path;
@@ -1,4 +1,6 @@
import type { EditorMenuButton } from '@blocksuite/affine-components/toolbar'; import type { EditorMenuButton } from '@blocksuite/affine-components/toolbar';
import type { ColorScheme, Palette } from '@blocksuite/affine-model';
import { resolveColor } from '@blocksuite/affine-model';
import { WithDisposable } from '@blocksuite/global/utils'; 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';
@@ -7,19 +9,14 @@ 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';
import type { import type { ModeType, PickColorEvent, PickColorType } from './types.js';
ModeType,
PickColorDetail,
PickColorEvent,
PickColorType,
} from './types.js';
import { keepColor, preprocessColor, rgbaToHex8 } from './utils.js'; import { keepColor, preprocessColor, rgbaToHex8 } from './utils.js';
type Type = 'normal' | 'custom'; type Type = 'normal' | 'custom';
export class EdgelessColorPickerButton extends WithDisposable(LitElement) { export class EdgelessColorPickerButton extends WithDisposable(LitElement) {
readonly #select = (e: ColorEvent) => { readonly #select = (e: ColorEvent) => {
this.#pick({ palette: e.detail }); this.#pick(e.detail);
}; };
switchToCustomTab = (e: MouseEvent) => { switchToCustomTab = (e: MouseEvent) => {
@@ -69,14 +66,16 @@ export class EdgelessColorPickerButton extends WithDisposable(LitElement) {
} }
get isCustomColor() { get isCustomColor() {
return !this.palettes.includes(this.color); return !this.palettes
.map(({ value }) => resolveColor(value, this.theme))
.includes(this.color);
} }
get tabContentPadding() { get tabContentPadding() {
return `${this.tabType === 'custom' ? 0 : 8}px`; return `${this.tabType === 'custom' ? 0 : 8}px`;
} }
#pick(detail: PickColorDetail) { #pick(detail: Palette) {
this.pick?.({ type: 'start' }); this.pick?.({ type: 'start' });
this.pick?.({ type: 'pick', detail }); this.pick?.({ type: 'pick', detail });
this.pick?.({ type: 'end' }); this.pick?.({ type: 'end' });
@@ -126,8 +125,8 @@ export class EdgelessColorPickerButton extends WithDisposable(LitElement) {
role="listbox" role="listbox"
class=${ifDefined(this.colorPanelClass)} class=${ifDefined(this.colorPanelClass)}
.value=${this.color} .value=${this.color}
.theme=${this.theme}
.palettes=${this.palettes} .palettes=${this.palettes}
.options=${this.palettes}
.hollowCircle=${this.hollowCircle} .hollowCircle=${this.hollowCircle}
.openColorPicker=${this.switchToCustomTab} .openColorPicker=${this.switchToCustomTab}
.hasTransparent=${false} .hasTransparent=${false}
@@ -189,7 +188,7 @@ export class EdgelessColorPickerButton extends WithDisposable(LitElement) {
accessor menuButton!: EditorMenuButton; accessor menuButton!: EditorMenuButton;
@property({ attribute: false }) @property({ attribute: false })
accessor palettes: string[] = []; accessor palettes: Palette[] = [];
@property({ attribute: false }) @property({ attribute: false })
accessor pick!: (event: PickColorEvent) => void; accessor pick!: (event: PickColorEvent) => void;
@@ -197,6 +196,9 @@ export class EdgelessColorPickerButton extends WithDisposable(LitElement) {
@state() @state()
accessor tabType: Type = 'normal'; accessor tabType: Type = 'normal';
@property({ attribute: false })
accessor theme!: ColorScheme;
@property() @property()
accessor tooltip: string | undefined = undefined; accessor tooltip: string | undefined = undefined;
} }
@@ -1,3 +1,4 @@
import type { Color } from '@blocksuite/affine-model';
import { on, once, stopPropagation } from '@blocksuite/affine-shared/utils'; import { on, once, stopPropagation } from '@blocksuite/affine-shared/utils';
import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils'; import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils';
import { batch, computed, signal } from '@preact/signals-core'; import { batch, computed, signal } from '@preact/signals-core';
@@ -111,15 +112,15 @@ export class EdgelessColorPicker extends SignalWatcher(
#pick() { #pick() {
const hsva = this.hsva$.peek(); const hsva = this.hsva$.peek();
const type = this.modeType$.peek(); const type = this.modeType$.peek();
const detail = { [type]: hsvaToHex8(hsva) }; const value = { [type]: hsvaToHex8(hsva) };
const key = 'Custom';
if (type !== 'normal') { if (type !== 'normal') {
const another = type === 'light' ? 'dark' : 'light'; const another = type === 'light' ? 'dark' : 'light';
const { hsva } = this[`${another}$`].peek(); const { hsva } = this[`${another}$`].peek();
detail[another] = hsvaToHex8(hsva); value[another] = hsvaToHex8(hsva);
} }
this.pick?.({ type: 'pick', detail: { key, value: value as Color } });
this.pick?.({ type: 'pick', detail });
} }
#pickEnd() { #pickEnd() {
@@ -398,12 +399,12 @@ export class EdgelessColorPicker extends SignalWatcher(
// Updates modes // Updates modes
if (modes?.length) { if (modes?.length) {
batches.push(() => { batches.push(() => {
// eslint-disable-next-line sonarjs/no-ignored-return let value = defaultHsva();
this.modes$.value.reduce((fallback, curr, n) => { this.modes$.value.forEach((curr, n) => {
const m = modes[n]; const m = modes[n];
curr.hsva = m ? rgbaToHsva(m.rgba) : fallback; curr.hsva = m ? rgbaToHsva(m.rgba) : value;
return { ...curr.hsva }; value = curr.hsva;
}, defaultHsva()); });
}); });
} }
@@ -11,8 +11,7 @@ export const COLORS: [Rgb, number][] = [
[{ r: 0, g: 1, b: 1 }, 3 / 6], [{ r: 0, g: 1, b: 1 }, 3 / 6],
[{ r: 0, g: 0, b: 1 }, 4 / 6], [{ r: 0, g: 0, b: 1 }, 4 / 6],
[{ r: 1, g: 0, b: 1 }, 5 / 6], [{ r: 1, g: 0, b: 1 }, 5 / 6],
// eslint-disable-next-line sonarjs/no-identical-expressions [{ r: 1, g: 0, b: 0 }, 1],
[{ r: 1, g: 0, b: 0 }, 6 / 6],
]; ];
export const FIRST_COLOR = COLORS[0][0]; export const FIRST_COLOR = COLORS[0][0];
@@ -11,6 +11,7 @@ export class EdgelessColorCustomButton extends LitElement {
height: 24px; height: 24px;
cursor: pointer; cursor: pointer;
} }
:host([active]):after { :host([active]):after {
position: absolute; position: absolute;
display: block; display: block;
@@ -1,6 +1,6 @@
// https://www.w3.org/TR/css-color-4/ // https://www.w3.org/TR/css-color-4/
import type { ColorScheme } from '@blocksuite/affine-model'; import type { ColorScheme, Palette } from '@blocksuite/affine-model';
// Red, green, blue. All in the range [0, 1]. // Red, green, blue. All in the range [0, 1].
export type Rgb = { export type Rgb = {
@@ -48,8 +48,6 @@ export type ModeRgba = { type: ModeType; rgba: Rgba };
export type PickColorType = 'palette' | ModeType; export type PickColorType = 'palette' | ModeType;
export type PickColorDetail = Partial<Record<PickColorType, string>>;
export type PickColorEvent = export type PickColorEvent =
| { type: 'start' | 'end' } | { type: 'start' | 'end' }
| { type: 'pick'; detail: PickColorDetail }; | { type: 'pick'; detail: Palette };
@@ -7,7 +7,6 @@ import type {
Hsv, Hsv,
Hsva, Hsva,
ModeType, ModeType,
PickColorDetail,
PickColorType, PickColorType,
Point, Point,
Rgb, Rgb,
@@ -269,12 +268,13 @@ export const preprocessColor = (style: CSSStyleDeclaration) => {
* *
* ```json * ```json
* { 'fillColor': '--affine-palette-shape-yellow' } * { 'fillColor': '--affine-palette-shape-yellow' }
* { 'fillColor': '#ffffff' }
* { 'fillColor': { normal: '#ffffffff' }} * { 'fillColor': { normal: '#ffffffff' }}
* { 'fillColor': { light: '#fff000ff', 'dark': '#0000fff00' }} * { 'fillColor': { light: '#fff000ff', 'dark': '#0000fff00' }}
* ``` * ```
*/ */
export const packColor = (key: string, detail: PickColorDetail) => { export const packColor = (key: string, color: Color) => {
return { [key]: detail.palette ?? detail }; return { [key]: typeof color === 'object' ? { ...color } : color };
}; };
/** /**
@@ -298,11 +298,15 @@ export const packColorsWithColorScheme = (
let type: PickColorType = 'palette'; let type: PickColorType = 'palette';
if (typeof oldColor === 'object') { if (typeof oldColor === 'object') {
type = colorScheme in oldColor ? colorScheme : 'normal'; if ('normal' in oldColor) {
type = 'normal';
colors[0].value = oldColor.normal ?? value; colors[0].value = oldColor.normal ?? value;
} else {
type = colorScheme;
colors[1].value = oldColor.light ?? value; colors[1].value = oldColor.light ?? value;
colors[2].value = oldColor.dark ?? value; colors[2].value = oldColor.dark ?? value;
} }
}
return { type, colors }; return { type, colors };
}; };
@@ -1,12 +1,15 @@
import { Black, ColorScheme, PALETTES, White } from '@blocksuite/affine-model'; import type { Color, ColorScheme, Palette } from '@blocksuite/affine-model';
import { isTransparent, resolveColor } from '@blocksuite/affine-model';
import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme'; import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
import { css, html, LitElement, nothing, svg, type TemplateResult } from 'lit'; import { css, html, LitElement, nothing, svg, type TemplateResult } from 'lit';
import { property } from 'lit/decorators.js'; import { property } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js'; import { classMap } from 'lit/directives/class-map.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { repeat } from 'lit/directives/repeat.js'; import { repeat } from 'lit/directives/repeat.js';
import isEqual from 'lodash.isequal';
export class ColorEvent extends Event { export class ColorEvent extends Event {
detail: string; detail: Palette;
constructor( constructor(
type: string, type: string,
@@ -14,21 +17,13 @@ export class ColorEvent extends Event {
detail, detail,
composed, composed,
bubbles, bubbles,
}: { detail: string; composed: boolean; bubbles: boolean } }: { detail: Palette; composed: boolean; bubbles: boolean }
) { ) {
super(type, { bubbles, composed }); super(type, { bubbles, composed });
this.detail = detail; this.detail = detail;
} }
} }
export const GET_DEFAULT_LINE_COLOR = (theme: ColorScheme) => {
return theme === ColorScheme.Dark ? White : Black;
};
export function isTransparent(color: string) {
return color.toLowerCase().endsWith('transparent');
}
function TransparentIcon(hollowCircle = false) { function TransparentIcon(hollowCircle = false) {
const CircleIcon: TemplateResult | typeof nothing = hollowCircle const CircleIcon: TemplateResult | typeof nothing = hollowCircle
? svg`<circle cx="10" cy="10" r="8" fill="white" />` ? svg`<circle cx="10" cy="10" r="8" fill="white" />`
@@ -125,7 +120,7 @@ export class EdgelessColorButton extends LitElement {
border-radius: 50%; border-radius: 50%;
overflow: hidden; overflow: hidden;
} }
:host .color-unit:after { :host .color-unit::after {
position: absolute; position: absolute;
display: block; display: block;
content: ''; content: '';
@@ -134,7 +129,6 @@ export class EdgelessColorButton extends LitElement {
border-radius: 50%; border-radius: 50%;
box-sizing: border-box; box-sizing: border-box;
overflow: hidden; overflow: hidden;
pointer-events: none;
border-width: 0.5px; border-width: 0.5px;
border-style: solid; border-style: solid;
border-color: ${unsafeCSSVarV2('layer/insideBorder/blackBorder')}; border-color: ${unsafeCSSVarV2('layer/insideBorder/blackBorder')};
@@ -151,34 +145,32 @@ export class EdgelessColorButton extends LitElement {
width: 20px; width: 20px;
height: 20px; height: 20px;
} }
:host::after {
:host([active]):after {
position: absolute; position: absolute;
display: block; display: block;
content: ''; content: '';
width: 27px; width: 27px;
height: 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; pointer-events: none;
} }
:host([active])::after {
border: 1.5px solid var(--affine-primary-color);
}
`; `;
get preprocessColor() { get preprocessColor() {
const color = this.color; const value = resolveColor(this.color, this.theme);
return color.startsWith('--') ? `var(${color})` : color; return value.startsWith('--') ? `var(${value})` : value;
} }
override render() { override render() {
const { color, preprocessColor, hollowCircle, letter } = this; const { label, preprocessColor, hollowCircle } = this;
const additionIcon = AdditionIcon(preprocessColor, !!hollowCircle); const additionIcon = AdditionIcon(preprocessColor, !!hollowCircle);
return html`<div return html`<div class="color-unit" aria-label=${ifDefined(label)}>
class="color-unit"
aria-label=${color}
data-letter=${letter ? 'A' : nothing}
>
${additionIcon} ${additionIcon}
</div>`; </div>`;
} }
@@ -187,13 +179,16 @@ export class EdgelessColorButton extends LitElement {
accessor active: boolean = false; accessor active: boolean = false;
@property({ attribute: false }) @property({ attribute: false })
accessor color!: string; accessor color!: Color;
@property({ attribute: false }) @property({ attribute: false })
accessor hollowCircle: boolean = false; accessor hollowCircle: boolean = false;
@property({ attribute: false }) @property({ attribute: false })
accessor letter: boolean | undefined = undefined; accessor label: string | undefined = undefined;
@property({ attribute: false })
accessor theme!: ColorScheme;
} }
export class EdgelessColorPanel extends LitElement { export class EdgelessColorPanel extends LitElement {
@@ -221,35 +216,42 @@ export class EdgelessColorPanel extends LitElement {
} }
`; `;
onSelect(value: string) { onSelect(palette: Palette) {
this.dispatchEvent( this.dispatchEvent(
new ColorEvent('select', { new ColorEvent('select', {
detail: value, detail: palette,
composed: true, composed: true,
bubbles: true, bubbles: true,
}) })
); );
this.value = value; }
get resolvedValue() {
return this.value && resolveColor(this.value, this.theme);
} }
override render() { override render() {
const resolvedValue = this.resolvedValue;
return html` return html`
${repeat( ${repeat(
this.palettes, this.palettes,
color => color, palette => palette.key,
color => palette => {
html`<edgeless-color-button const resolvedColor = resolveColor(palette.value, this.theme);
class=${classMap({ return html`<edgeless-color-button
large: true, class=${classMap({ large: true })}
black: color.startsWith('--') && color.endsWith('black'), .label=${palette.key}
})} .color=${palette.value}
.color=${color} .theme=${this.theme}
.letter=${this.showLetterMark}
.hollowCircle=${this.hollowCircle} .hollowCircle=${this.hollowCircle}
?active=${color === this.value} ?active=${isEqual(resolvedColor, resolvedValue)}
@click=${() => this.onSelect(color)} @click=${() => {
this.onSelect(palette);
this.value = resolvedColor;
}}
> >
</edgeless-color-button>` </edgeless-color-button>`;
}
)} )}
<slot name="custom"></slot> <slot name="custom"></slot>
`; `;
@@ -265,13 +267,13 @@ export class EdgelessColorPanel extends LitElement {
accessor openColorPicker!: (e: MouseEvent) => void; accessor openColorPicker!: (e: MouseEvent) => void;
@property({ type: Array }) @property({ type: Array })
accessor palettes: readonly string[] = PALETTES; accessor palettes: readonly Palette[] = [];
@property({ attribute: false }) @property({ attribute: false })
accessor showLetterMark = false; accessor theme!: ColorScheme;
@property({ attribute: false }) @property({ attribute: false })
accessor value: string | null = null; accessor value: Color | null = null;
} }
export class EdgelessTextColorIcon extends LitElement { export class EdgelessTextColorIcon extends LitElement {
@@ -3,7 +3,7 @@ import {
DashLineIcon, DashLineIcon,
StraightLineIcon, StraightLineIcon,
} from '@blocksuite/affine-components/icons'; } from '@blocksuite/affine-components/icons';
import { type LineWidth, StrokeStyle } from '@blocksuite/affine-model'; import { LineWidth, StrokeStyle } from '@blocksuite/affine-model';
import { html } from 'lit'; import { html } from 'lit';
import { classMap } from 'lit/directives/class-map.js'; import { classMap } from 'lit/directives/class-map.js';
import { repeat } from 'lit/directives/repeat.js'; import { repeat } from 'lit/directives/repeat.js';
@@ -47,14 +47,14 @@ const LINE_STYLE_LIST = [
export function LineStylesPanel({ export function LineStylesPanel({
onClick, onClick,
selectedLineSize,
selectedLineStyle, selectedLineStyle,
selectedLineSize = LineWidth.Two,
lineStyles = [StrokeStyle.Solid, StrokeStyle.Dash, StrokeStyle.None], lineStyles = [StrokeStyle.Solid, StrokeStyle.Dash, StrokeStyle.None],
}: LineStylesPanelProps = {}) { }: LineStylesPanelProps = {}) {
const lineSizePanel = html` const lineSizePanel = html`
<edgeless-line-width-panel <edgeless-line-width-panel
.selectedSize=${selectedLineSize as LineWidth} ?disabled=${selectedLineStyle === StrokeStyle.None}
.disable=${selectedLineStyle === StrokeStyle.None} .selectedSize=${selectedLineSize}
@select=${(e: LineWidthEvent) => { @select=${(e: LineWidthEvent) => {
onClick?.({ onClick?.({
type: 'size', type: 'size',
@@ -69,15 +69,15 @@ export function LineStylesPanel({
item => item.value, item => item.value,
({ name, icon, value }) => { ({ name, icon, value }) => {
const active = selectedLineStyle === value; const active = selectedLineStyle === value;
const classes: Record<string, boolean> = { const classInfo = {
'line-style-button': true, 'line-style-button': true,
[`mode-${value}`]: true, [`mode-${value}`]: true,
}; };
if (active) classes['active'] = true; if (active) classInfo['active'] = true;
return html` return html`
<edgeless-tool-icon-button <edgeless-tool-icon-button
class=${classMap(classes)} class=${classMap(classInfo)}
.active=${active} .active=${active}
.activeMode=${'background'} .activeMode=${'background'}
.tooltip=${name} .tooltip=${name}
@@ -1,4 +1,8 @@
import { PALETTES, type StrokeStyle } from '@blocksuite/affine-model'; import {
type ColorScheme,
DefaultTheme,
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';
@@ -38,8 +42,9 @@ export class StrokeStylePanel extends WithDisposable(LitElement) {
<edgeless-color-panel <edgeless-color-panel
role="listbox" role="listbox"
aria-label="Border colors" aria-label="Border colors"
.palettes=${PALETTES}
.value=${this.strokeColor} .value=${this.strokeColor}
.theme=${this.theme}
.palettes=${DefaultTheme.Palettes}
.hollowCircle=${this.hollowCircle} .hollowCircle=${this.hollowCircle}
@select=${(e: ColorEvent) => this.setStrokeColor(e)} @select=${(e: ColorEvent) => this.setStrokeColor(e)}
> >
@@ -64,6 +69,9 @@ export class StrokeStylePanel extends WithDisposable(LitElement) {
@property({ attribute: false }) @property({ attribute: false })
accessor strokeWidth!: number; accessor strokeWidth!: number;
@property({ attribute: false })
accessor theme!: ColorScheme;
} }
declare global { declare global {
@@ -1,4 +1,4 @@
import { STROKE_COLORS } from '@blocksuite/affine-model'; import { DefaultTheme } from '@blocksuite/affine-model';
import { import {
EditPropsStore, EditPropsStore,
ThemeProvider, ThemeProvider,
@@ -9,10 +9,7 @@ import { computed } from '@preact/signals-core';
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 { import type { ColorEvent } from '../../panel/color-panel.js';
type ColorEvent,
GET_DEFAULT_LINE_COLOR,
} from '../../panel/color-panel.js';
import type { LineWidthEvent } from '../../panel/line-width-panel.js'; import type { LineWidthEvent } from '../../panel/line-width-panel.js';
import { EdgelessToolbarToolMixin } from '../mixins/tool.mixin.js'; import { EdgelessToolbarToolMixin } from '../mixins/tool.mixin.js';
@@ -46,14 +43,13 @@ export class EdgelessBrushMenu extends EdgelessToolbarToolMixin(
}; };
}); });
private readonly _theme$ = computed(() => {
return this.edgeless.std.get(ThemeProvider).theme$.value;
});
type: GfxToolsFullOptionValue['type'] = 'brush'; type: GfxToolsFullOptionValue['type'] = 'brush';
override render() { override render() {
const theme = this.edgeless.std.get(ThemeProvider).theme;
const color = this.edgeless.std
.get(ThemeProvider)
.getColorValue(this._props$.value.color, GET_DEFAULT_LINE_COLOR(theme));
return html` return html`
<edgeless-slide-menu> <edgeless-slide-menu>
<div class="menu-content"> <div class="menu-content">
@@ -66,12 +62,14 @@ export class EdgelessBrushMenu extends EdgelessToolbarToolMixin(
<menu-divider .vertical=${true}></menu-divider> <menu-divider .vertical=${true}></menu-divider>
<edgeless-color-panel <edgeless-color-panel
class="one-way" class="one-way"
.value=${color} .value=${this._props$.value.color}
.palettes=${STROKE_COLORS} .theme=${this._theme$.value}
.palettes=${DefaultTheme.StrokeColorPalettes}
.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.value })}
></edgeless-color-panel> ></edgeless-color-panel>
</div> </div>
</edgeless-slide-menu> </edgeless-slide-menu>
@@ -3,11 +3,7 @@ import {
ConnectorLWithArrowIcon, ConnectorLWithArrowIcon,
ConnectorXWithArrowIcon, ConnectorXWithArrowIcon,
} from '@blocksuite/affine-components/icons'; } from '@blocksuite/affine-components/icons';
import { import { ConnectorMode, DefaultTheme } from '@blocksuite/affine-model';
ConnectorMode,
DEFAULT_CONNECTOR_COLOR,
STROKE_COLORS,
} from '@blocksuite/affine-model';
import { import {
EditPropsStore, EditPropsStore,
ThemeProvider, ThemeProvider,
@@ -104,6 +100,10 @@ export class EdgelessConnectorMenu extends EdgelessToolbarToolMixin(
return { mode, stroke, strokeWidth }; return { mode, stroke, strokeWidth };
}); });
private readonly _theme$ = computed(() => {
return this.edgeless.std.get(ThemeProvider).theme$.value;
});
override type: GfxToolsFullOptionValue['type'] = 'connector'; override type: GfxToolsFullOptionValue['type'] = 'connector';
override render() { override render() {
@@ -112,9 +112,6 @@ export class EdgelessConnectorMenu extends EdgelessToolbarToolMixin(
mode, mode,
this.onChange this.onChange
); );
const color = this.edgeless.std
.get(ThemeProvider)
.getColorValue(stroke, DEFAULT_CONNECTOR_COLOR);
return html` return html`
<edgeless-slide-menu> <edgeless-slide-menu>
@@ -130,12 +127,14 @@ export class EdgelessConnectorMenu extends EdgelessToolbarToolMixin(
<div class="submenu-divider"></div> <div class="submenu-divider"></div>
<edgeless-color-panel <edgeless-color-panel
class="one-way" class="one-way"
.value=${color} .value=${stroke}
.palettes=${STROKE_COLORS} .theme=${this._theme$.value}
.palettes=${DefaultTheme.StrokeColorPalettes}
.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.value })}
></edgeless-color-panel> ></edgeless-color-panel>
</div> </div>
</edgeless-slide-menu> </edgeless-slide-menu>
@@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */ /* oxlint-disable @typescript-eslint/no-non-null-assertion */
import { import {
type MenuHandler, type MenuHandler,
popMenu, popMenu,
@@ -25,6 +25,7 @@ import { debounce } from '@blocksuite/global/utils';
import { Slot } from '@blocksuite/store'; import { Slot } from '@blocksuite/store';
import { autoPlacement, offset } from '@floating-ui/dom'; import { autoPlacement, offset } from '@floating-ui/dom';
import { ContextProvider } from '@lit/context'; import { ContextProvider } from '@lit/context';
import { computed } from '@preact/signals-core';
import { baseTheme, cssVar } from '@toeverything/theme'; import { baseTheme, cssVar } from '@toeverything/theme';
import { css, html, nothing, unsafeCSS } from 'lit'; import { css, html, nothing, unsafeCSS } from 'lit';
import { query, state } from 'lit/decorators.js'; import { query, state } from 'lit/decorators.js';
@@ -222,6 +223,10 @@ export class EdgelessToolbarWidget extends WidgetComponent<
} }
`; `;
private readonly _appTheme$ = computed(() => {
return this.std.get(ThemeProvider).app$.value;
});
private _moreQuickToolsMenu: MenuHandler | null = null; private _moreQuickToolsMenu: MenuHandler | null = null;
private _moreQuickToolsMenuRef: HTMLElement | null = null; private _moreQuickToolsMenuRef: HTMLElement | null = null;
@@ -625,9 +630,11 @@ export class EdgelessToolbarWidget extends WidgetComponent<
return nothing; return nothing;
} }
const appTheme = this.std.get(ThemeProvider).app$.value;
return html` return html`
<div class="edgeless-toolbar-wrapper" data-app-theme=${appTheme}> <div
class="edgeless-toolbar-wrapper"
data-app-theme=${this._appTheme$.value}
>
<div <div
class="edgeless-toolbar-toggle-control" class="edgeless-toolbar-toggle-control"
data-enable=${this._enableAutoHide} data-enable=${this._enableAutoHide}
@@ -166,7 +166,7 @@ export class EdgelessNoteSeniorButton extends EdgelessToolbarToolMixin(
}> }>
) => { ) => {
this._states.forEach(key => { this._states.forEach(key => {
// eslint-disable-next-line eqeqeq // oxlint-disable-next-line eqeqeq
if (props[key] != undefined) { if (props[key] != undefined) {
Object.assign(this, { [key]: props[key] }); Object.assign(this, { [key]: props[key] });
} }
@@ -60,7 +60,7 @@ export class EdgelessNoteToolButton extends QuickToolMixin(LitElement) {
}> }>
) => { ) => {
this._states.forEach(key => { this._states.forEach(key => {
// eslint-disable-next-line eqeqeq // oxlint-disable-next-line eqeqeq
if (props[key] != undefined) { if (props[key] != undefined) {
Object.assign(this, { [key]: props[key] }); Object.assign(this, { [key]: props[key] });
} }
@@ -3,27 +3,24 @@ import {
ScribbledStyleIcon, ScribbledStyleIcon,
} from '@blocksuite/affine-components/icons'; } from '@blocksuite/affine-components/icons';
import { import {
DEFAULT_SHAPE_FILL_COLOR, DefaultTheme,
LIGHT_PALETTES, isTransparent,
MEDIUM_PALETTES, type Palette,
SHAPE_FILL_COLORS,
type ShapeName, type ShapeName,
ShapeStyle, ShapeStyle,
ShapeType, ShapeType,
StrokeColor,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
import { import {
EditPropsStore, EditPropsStore,
ThemeProvider, ThemeProvider,
} from '@blocksuite/affine-shared/services'; } from '@blocksuite/affine-shared/services';
import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils'; import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils';
import type { Signal } from '@preact/signals-core'; import { computed, effect, type Signal, signal } from '@preact/signals-core';
import { computed, effect, signal } from '@preact/signals-core';
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 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 } from '../../panel/color-panel.js';
import { ShapeComponentConfig } from './shape-menu-config.js'; import { ShapeComponentConfig } from './shape-menu-config.js';
export class EdgelessShapeMenu extends SignalWatcher( export class EdgelessShapeMenu extends SignalWatcher(
@@ -76,20 +73,13 @@ export class EdgelessShapeMenu extends SignalWatcher(
}; };
}); });
private readonly _setFillColor = (fillColor: string) => { private readonly _setFillColor = ({ key, value }: Palette) => {
const filled = !isTransparent(fillColor); const filled = !isTransparent(value);
let strokeColor = fillColor; // white or black const fillColor = value;
const strokeColor = filled
if (filled) { ? DefaultTheme.StrokeColorPalettes.find(palette => palette.key === key)
const index = LIGHT_PALETTES.findIndex(color => color === fillColor); ?.value
if (index !== -1) { : DefaultTheme.StrokeColorMap.Grey;
strokeColor = MEDIUM_PALETTES[index];
}
}
if (strokeColor.endsWith('transparent')) {
strokeColor = StrokeColor.Grey;
}
const { shapeName } = this._props$.value; const { shapeName } = this._props$.value;
this.edgeless.std this.edgeless.std
@@ -112,6 +102,10 @@ export class EdgelessShapeMenu extends SignalWatcher(
this.onChange(shapeName); this.onChange(shapeName);
}; };
private readonly _theme$ = computed(() => {
return this.edgeless.std.get(ThemeProvider).theme$.value;
});
override connectedCallback(): void { override connectedCallback(): void {
super.connectedCallback(); super.connectedCallback();
@@ -128,9 +122,6 @@ export class EdgelessShapeMenu extends SignalWatcher(
override render() { override render() {
const { fillColor, shapeStyle, shapeName } = this._props$.value; const { fillColor, shapeStyle, shapeName } = this._props$.value;
const color = this.edgeless.std
.get(ThemeProvider)
.getColorValue(fillColor, DEFAULT_SHAPE_FILL_COLOR);
return html` return html`
<edgeless-slide-menu> <edgeless-slide-menu>
@@ -179,8 +170,9 @@ export class EdgelessShapeMenu extends SignalWatcher(
<menu-divider .vertical=${true}></menu-divider> <menu-divider .vertical=${true}></menu-divider>
<edgeless-color-panel <edgeless-color-panel
class="one-way" class="one-way"
.value=${color} .value=${fillColor}
.palettes=${SHAPE_FILL_COLORS} .theme=${this._theme$.value}
.palettes=${DefaultTheme.FillColorPalettes}
.hasTransparent=${!this.edgeless.doc.awarenessStore.getFlag( .hasTransparent=${!this.edgeless.doc.awarenessStore.getFlag(
'enable_color_picker' 'enable_color_picker'
)} )}
@@ -1,5 +1,7 @@
import { STROKE_COLORS } from '@blocksuite/affine-model'; import { DefaultTheme } from '@blocksuite/affine-model';
import { ThemeProvider } from '@blocksuite/affine-shared/services';
import type { GfxToolsFullOptionValue } from '@blocksuite/block-std/gfx'; import type { GfxToolsFullOptionValue } from '@blocksuite/block-std/gfx';
import { computed } from '@preact/signals-core';
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';
@@ -15,6 +17,10 @@ export class EdgelessTextMenu extends EdgelessToolbarToolMixin(LitElement) {
} }
`; `;
private readonly _theme$ = computed(() => {
return this.edgeless.std.get(ThemeProvider).theme$.value;
});
override type: GfxToolsFullOptionValue['type'] = 'text'; override type: GfxToolsFullOptionValue['type'] = 'text';
override render() { override render() {
@@ -26,7 +32,8 @@ export class EdgelessTextMenu extends EdgelessToolbarToolMixin(LitElement) {
<edgeless-color-panel <edgeless-color-panel
class="one-way" class="one-way"
.value=${this.color} .value=${this.color}
.palettes=${STROKE_COLORS} .theme=${this._theme$.value}
.palettes=${DefaultTheme.StrokeColorPalettes}
@select=${(e: ColorEvent) => this.onChange({ color: e.detail })} @select=${(e: ColorEvent) => this.onChange({ color: e.detail })}
></edgeless-color-panel> ></edgeless-color-panel>
</div> </div>
@@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */ /* oxlint-disable @typescript-eslint/no-non-null-assertion */
import type { PointerEventState } from '@blocksuite/block-std'; import type { PointerEventState } from '@blocksuite/block-std';
import { BaseTool, MouseButton } from '@blocksuite/block-std/gfx'; import { BaseTool, MouseButton } from '@blocksuite/block-std/gfx';
import { IS_MAC } from '@blocksuite/global/env'; import { IS_MAC } from '@blocksuite/global/env';
@@ -3,11 +3,7 @@ import {
type SurfaceBlockComponent, type SurfaceBlockComponent,
} from '@blocksuite/affine-block-surface'; } from '@blocksuite/affine-block-surface';
import type { ShapeElementModel, ShapeName } from '@blocksuite/affine-model'; import type { ShapeElementModel, ShapeName } from '@blocksuite/affine-model';
import { import { DefaultTheme, getShapeType } from '@blocksuite/affine-model';
DEFAULT_SHAPE_FILL_COLOR,
DEFAULT_SHAPE_STROKE_COLOR,
getShapeType,
} from '@blocksuite/affine-model';
import { import {
EditPropsStore, EditPropsStore,
TelemetryProvider, TelemetryProvider,
@@ -202,10 +198,14 @@ export class ShapeTool extends BaseTool<ShapeToolOption> {
options.stroke = this.std options.stroke = this.std
.get(ThemeProvider) .get(ThemeProvider)
.getColorValue(attributes.strokeColor, DEFAULT_SHAPE_STROKE_COLOR, true); .getColorValue(
attributes.strokeColor,
DefaultTheme.shapeStrokeColor,
true
);
options.fill = this.std options.fill = this.std
.get(ThemeProvider) .get(ThemeProvider)
.getColorValue(attributes.fillColor, DEFAULT_SHAPE_FILL_COLOR, true); .getColorValue(attributes.fillColor, DefaultTheme.shapeFillColor, true);
switch (attributes.strokeStyle!) { switch (attributes.strokeStyle!) {
case 'dash': case 'dash':
@@ -1,9 +1,7 @@
import { import {
Black,
DEFAULT_ROUGHNESS, DEFAULT_ROUGHNESS,
LineWidth, LineWidth,
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,10 +46,6 @@ 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 = White;
export const SHAPE_TEXT_COLOR_PURE_BLACK = 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;
export const AI_CHAT_BLOCK_MAX_WIDTH = 320; export const AI_CHAT_BLOCK_MAX_WIDTH = 320;
@@ -6,9 +6,7 @@ import {
} from '@blocksuite/affine-block-surface'; } from '@blocksuite/affine-block-surface';
import { import {
type Color, type Color,
DEFAULT_NOTE_BACKGROUND_COLOR, DefaultTheme,
DEFAULT_SHAPE_FILL_COLOR,
DEFAULT_SHAPE_STROKE_COLOR,
shapeMethods, shapeMethods,
type ShapeStyle, type ShapeStyle,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
@@ -286,10 +284,10 @@ export class ShapeOverlay extends ToolOverlay {
const { shapeStyle, fillColor, strokeColor } = style; const { shapeStyle, fillColor, strokeColor } = style;
const fill = this.gfx.std const fill = this.gfx.std
.get(ThemeProvider) .get(ThemeProvider)
.getColorValue(fillColor, DEFAULT_SHAPE_FILL_COLOR, true); .getColorValue(fillColor, DefaultTheme.shapeFillColor, true);
const stroke = this.gfx.std const stroke = this.gfx.std
.get(ThemeProvider) .get(ThemeProvider)
.getColorValue(strokeColor, DEFAULT_SHAPE_STROKE_COLOR, true); .getColorValue(strokeColor, DefaultTheme.shapeStrokeColor, true);
options.fill = fill; options.fill = fill;
options.stroke = stroke; options.stroke = stroke;
@@ -356,7 +354,7 @@ export class NoteOverlay extends ToolOverlay {
this.globalAlpha = 0; this.globalAlpha = 0;
this.backgroundColor = gfx.std this.backgroundColor = gfx.std
.get(ThemeProvider) .get(ThemeProvider)
.getColorValue(background, DEFAULT_NOTE_BACKGROUND_COLOR, true); .getColorValue(background, DefaultTheme.noteBackgrounColor, true);
this.disposables.add( this.disposables.add(
effect(() => { effect(() => {
// when change note child type, update overlay text // when change note child type, update overlay text
@@ -4,10 +4,14 @@ import type {
BrushProps, BrushProps,
ColorScheme, ColorScheme,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
import { LineWidth, PALETTES } from '@blocksuite/affine-model'; import {
DefaultTheme,
LineWidth,
resolveColor,
} 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 } from 'lit/decorators.js';
import { when } from 'lit/directives/when.js'; import { when } from 'lit/directives/when.js';
import type { EdgelessColorPickerButton } from '../../edgeless/components/color-picker/button.js'; import type { EdgelessColorPickerButton } from '../../edgeless/components/color-picker/button.js';
@@ -17,7 +21,6 @@ import {
packColorsWithColorScheme, packColorsWithColorScheme,
} from '../../edgeless/components/color-picker/utils.js'; } from '../../edgeless/components/color-picker/utils.js';
import type { ColorEvent } from '../../edgeless/components/panel/color-panel.js'; import type { ColorEvent } from '../../edgeless/components/panel/color-panel.js';
import { GET_DEFAULT_LINE_COLOR } from '../../edgeless/components/panel/color-panel.js';
import type { LineWidthEvent } from '../../edgeless/components/panel/line-width-panel.js'; import type { LineWidthEvent } from '../../edgeless/components/panel/line-width-panel.js';
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js'; import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
@@ -25,13 +28,13 @@ function getMostCommonColor(
elements: BrushElementModel[], elements: BrushElementModel[],
colorScheme: ColorScheme colorScheme: ColorScheme
): string { ): string {
const colors = countBy(elements, (ele: BrushElementModel) => { const colors = countBy(elements, (ele: BrushElementModel) =>
return typeof ele.color === 'object' resolveColor(ele.color, colorScheme)
? (ele.color[colorScheme] ?? ele.color.normal ?? null) );
: ele.color;
});
const max = maxBy(Object.entries(colors), ([_k, count]) => count); const max = maxBy(Object.entries(colors), ([_k, count]) => count);
return max ? (max[0] as string) : GET_DEFAULT_LINE_COLOR(colorScheme); return max
? (max[0] as string)
: resolveColor(DefaultTheme.black, colorScheme);
} }
function getMostCommonSize(elements: BrushElementModel[]): LineWidth { function getMostCommonSize(elements: BrushElementModel[]): LineWidth {
@@ -45,26 +48,29 @@ function notEqual<K extends keyof BrushProps>(key: K, value: BrushProps[K]) {
} }
export class EdgelessChangeBrushButton extends WithDisposable(LitElement) { export class EdgelessChangeBrushButton extends WithDisposable(LitElement) {
private readonly _setBrushColor = ({ detail: color }: ColorEvent) => { private readonly _setBrushColor = ({ detail }: ColorEvent) => {
const color = detail.value;
this._setBrushProp('color', color); this._setBrushProp('color', color);
this._selectedColor = color;
}; };
private readonly _setLineWidth = ({ detail: lineWidth }: LineWidthEvent) => { private readonly _setLineWidth = ({ detail: lineWidth }: LineWidthEvent) => {
this._setBrushProp('lineWidth', lineWidth); this._setBrushProp('lineWidth', lineWidth);
this._selectedSize = lineWidth;
}; };
pickColor = (event: PickColorEvent) => { pickColor = (e: PickColorEvent) => {
if (event.type === 'pick') { const field = 'color';
this.elements.forEach(ele =>
this.crud.updateElement(ele.id, packColor('color', { ...event.detail })) if (e.type === 'pick') {
); const color = e.detail.value;
this.elements.forEach(ele => {
const props = packColor(field, color);
this.crud.updateElement(ele.id, props);
});
return; return;
} }
this.elements.forEach(ele => this.elements.forEach(ele =>
ele[event.type === 'start' ? 'stash' : 'pop']('color') ele[e.type === 'start' ? 'stash' : 'pop'](field)
); );
}; };
@@ -72,17 +78,6 @@ export class EdgelessChangeBrushButton extends WithDisposable(LitElement) {
return this.edgeless.doc; return this.edgeless.doc;
} }
get selectedColor() {
const colorScheme = this.edgeless.surface.renderer.getColorScheme();
return (
this._selectedColor ?? getMostCommonColor(this.elements, colorScheme)
);
}
get selectedSize() {
return this._selectedSize ?? getMostCommonSize(this.elements);
}
get service() { get service() {
return this.edgeless.service; return this.edgeless.service;
} }
@@ -110,7 +105,8 @@ export class EdgelessChangeBrushButton extends WithDisposable(LitElement) {
override render() { override render() {
const colorScheme = this.edgeless.surface.renderer.getColorScheme(); const colorScheme = this.edgeless.surface.renderer.getColorScheme();
const elements = this.elements; const elements = this.elements;
const { selectedSize, selectedColor } = this; const selectedColor = getMostCommonColor(elements, colorScheme);
const selectedSize = getMostCommonSize(elements);
return html` return html`
<edgeless-line-width-panel <edgeless-line-width-panel
@@ -138,7 +134,8 @@ export class EdgelessChangeBrushButton extends WithDisposable(LitElement) {
.color=${selectedColor} .color=${selectedColor}
.colors=${colors} .colors=${colors}
.colorType=${type} .colorType=${type}
.palettes=${PALETTES} .theme=${colorScheme}
.palettes=${DefaultTheme.Palettes}
> >
</edgeless-color-picker-button> </edgeless-color-picker-button>
`; `;
@@ -156,6 +153,8 @@ export class EdgelessChangeBrushButton extends WithDisposable(LitElement) {
> >
<edgeless-color-panel <edgeless-color-panel
.value=${selectedColor} .value=${selectedColor}
.theme=${colorScheme}
.palettes=${DefaultTheme.Palettes}
@select=${this._setBrushColor} @select=${this._setBrushColor}
> >
</edgeless-color-panel> </edgeless-color-panel>
@@ -165,12 +164,6 @@ export class EdgelessChangeBrushButton extends WithDisposable(LitElement) {
`; `;
} }
@state()
private accessor _selectedColor: string | null = null;
@state()
private accessor _selectedSize: LineWidth | null = null;
@query('edgeless-color-picker-button.color') @query('edgeless-color-picker-button.color')
accessor colorButton!: EdgelessColorPickerButton; accessor colorButton!: EdgelessColorPickerButton;
@@ -28,9 +28,10 @@ import {
ConnectorMode, ConnectorMode,
DEFAULT_FRONT_END_POINT_STYLE, DEFAULT_FRONT_END_POINT_STYLE,
DEFAULT_REAR_END_POINT_STYLE, DEFAULT_REAR_END_POINT_STYLE,
DefaultTheme,
LineWidth, LineWidth,
PALETTES,
PointStyle, PointStyle,
resolveColor,
StrokeStyle, StrokeStyle,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils'; import { countBy, maxBy, WithDisposable } from '@blocksuite/global/utils';
@@ -48,10 +49,7 @@ import {
packColor, packColor,
packColorsWithColorScheme, packColorsWithColorScheme,
} from '../../edgeless/components/color-picker/utils.js'; } from '../../edgeless/components/color-picker/utils.js';
import { import type { ColorEvent } from '../../edgeless/components/panel/color-panel.js';
type ColorEvent,
GET_DEFAULT_LINE_COLOR,
} from '../../edgeless/components/panel/color-panel.js';
import { import {
type LineStyleEvent, type LineStyleEvent,
LineStylesPanel, LineStylesPanel,
@@ -62,14 +60,14 @@ import { mountConnectorLabelEditor } from '../../edgeless/utils/text.js';
function getMostCommonColor( function getMostCommonColor(
elements: ConnectorElementModel[], elements: ConnectorElementModel[],
colorScheme: ColorScheme colorScheme: ColorScheme
): string | null { ): string {
const colors = countBy(elements, (ele: ConnectorElementModel) => { const colors = countBy(elements, (ele: ConnectorElementModel) =>
return typeof ele.stroke === 'object' resolveColor(ele.stroke, colorScheme)
? (ele.stroke[colorScheme] ?? ele.stroke.normal ?? null) );
: ele.stroke;
});
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)
: resolveColor(DefaultTheme.connectorColor, colorScheme);
} }
function getMostCommonMode( function getMostCommonMode(
@@ -88,10 +86,10 @@ function getMostCommonLineWidth(elements: ConnectorElementModel[]): LineWidth {
export function getMostCommonLineStyle( export function getMostCommonLineStyle(
elements: ConnectorElementModel[] elements: ConnectorElementModel[]
): StrokeStyle | null { ): StrokeStyle {
const sizes = countBy(elements, ele => ele.strokeStyle); const sizes = countBy(elements, ele => ele.strokeStyle);
const max = maxBy(Object.entries(sizes), ([_k, count]) => count); const max = maxBy(Object.entries(sizes), ([_k, count]) => count);
return max ? (max[0] as StrokeStyle) : null; return max ? (max[0] as StrokeStyle) : StrokeStyle.Solid;
} }
function getMostCommonRough(elements: ConnectorElementModel[]): boolean { function getMostCommonRough(elements: ConnectorElementModel[]): boolean {
@@ -112,15 +110,16 @@ function getMostCommonRough(elements: ConnectorElementModel[]): boolean {
function getMostCommonEndpointStyle( function getMostCommonEndpointStyle(
elements: ConnectorElementModel[], elements: ConnectorElementModel[],
endpoint: ConnectorEndpoint endpoint: ConnectorEndpoint,
): PointStyle | null { fallback: PointStyle
): PointStyle {
const field = const field =
endpoint === ConnectorEndpoint.Front endpoint === ConnectorEndpoint.Front
? 'frontEndpointStyle' ? 'frontEndpointStyle'
: 'rearEndpointStyle'; : 'rearEndpointStyle';
const modes = countBy(elements, ele => ele[field]); const modes = countBy(elements, ele => ele[field]);
const max = maxBy(Object.entries(modes), ([_k, count]) => count); const max = maxBy(Object.entries(modes), ([_k, count]) => count);
return max ? (max[0] as PointStyle) : null; return max ? (max[0] as PointStyle) : fallback;
} }
function notEqual< function notEqual<
@@ -227,19 +226,33 @@ export class EdgelessChangeConnectorButton extends WithDisposable(LitElement) {
return this.edgeless.std.get(EdgelessCRUDIdentifier); return this.edgeless.std.get(EdgelessCRUDIdentifier);
} }
pickColor = (event: PickColorEvent) => { private readonly _setConnectorColor = (e: ColorEvent) => {
if (event.type === 'pick') { const stroke = e.detail.value;
this.elements.forEach(ele => this._setConnectorProp('stroke', stroke);
this.crud.updateElement( };
ele.id,
packColor('stroke', { ...event.detail }) private readonly _setConnectorStroke = ({ type, value }: LineStyleEvent) => {
) if (type === 'size') {
); this._setConnectorStrokeWidth(value);
return;
}
this._setConnectorStrokeStyle(value);
};
pickColor = (e: PickColorEvent) => {
const field = 'stroke';
if (e.type === 'pick') {
const color = e.detail.value;
this.elements.forEach(ele => {
const props = packColor(field, color);
this.crud.updateElement(ele.id, props);
});
return; return;
} }
this.elements.forEach(ele => this.elements.forEach(ele =>
ele[event.type === 'start' ? 'stash' : 'pop']('stroke') ele[e.type === 'start' ? 'stash' : 'pop'](field)
); );
}; };
@@ -276,10 +289,6 @@ export class EdgelessChangeConnectorButton extends WithDisposable(LitElement) {
); );
} }
private _setConnectorColor(stroke: string) {
this._setConnectorProp('stroke', stroke);
}
private _setConnectorMode(mode: ConnectorMode) { private _setConnectorMode(mode: ConnectorMode) {
this._setConnectorProp('mode', mode); this._setConnectorProp('mode', mode);
} }
@@ -310,14 +319,6 @@ export class EdgelessChangeConnectorButton extends WithDisposable(LitElement) {
this._setConnectorProp('rough', rough); this._setConnectorProp('rough', rough);
} }
private _setConnectorStroke({ type, value }: LineStyleEvent) {
if (type === 'size') {
this._setConnectorStrokeWidth(value);
return;
}
this._setConnectorStrokeStyle(value);
}
private _setConnectorStrokeStyle(strokeStyle: StrokeStyle) { private _setConnectorStrokeStyle(strokeStyle: StrokeStyle) {
this._setConnectorProp('strokeStyle', strokeStyle); this._setConnectorProp('strokeStyle', strokeStyle);
} }
@@ -339,20 +340,21 @@ export class EdgelessChangeConnectorButton extends WithDisposable(LitElement) {
override render() { override render() {
const colorScheme = this.edgeless.surface.renderer.getColorScheme(); const colorScheme = this.edgeless.surface.renderer.getColorScheme();
const elements = this.elements; const elements = this.elements;
const selectedColor = const selectedColor = getMostCommonColor(elements, colorScheme);
getMostCommonColor(elements, colorScheme) ??
GET_DEFAULT_LINE_COLOR(colorScheme);
const selectedMode = getMostCommonMode(elements); const selectedMode = getMostCommonMode(elements);
const selectedLineSize = getMostCommonLineWidth(elements) ?? LineWidth.Four; const selectedLineSize = getMostCommonLineWidth(elements);
const selectedRough = getMostCommonRough(elements); const selectedRough = getMostCommonRough(elements);
const selectedLineStyle = const selectedLineStyle = getMostCommonLineStyle(elements);
getMostCommonLineStyle(elements) ?? StrokeStyle.Solid; const selectedStartPointStyle = getMostCommonEndpointStyle(
const selectedStartPointStyle = elements,
getMostCommonEndpointStyle(elements, ConnectorEndpoint.Front) ?? ConnectorEndpoint.Front,
DEFAULT_FRONT_END_POINT_STYLE; DEFAULT_FRONT_END_POINT_STYLE
const selectedEndPointStyle = );
getMostCommonEndpointStyle(elements, ConnectorEndpoint.Rear) ?? const selectedEndPointStyle = getMostCommonEndpointStyle(
DEFAULT_REAR_END_POINT_STYLE; elements,
ConnectorEndpoint.Rear,
DEFAULT_REAR_END_POINT_STYLE
);
return join( return join(
[ [
@@ -373,7 +375,8 @@ export class EdgelessChangeConnectorButton extends WithDisposable(LitElement) {
.color=${selectedColor} .color=${selectedColor}
.colors=${colors} .colors=${colors}
.colorType=${type} .colorType=${type}
.palettes=${PALETTES} .theme=${colorScheme}
.palettes=${DefaultTheme.Palettes}
.hollowCircle=${true} .hollowCircle=${true}
> >
<div <div
@@ -389,7 +392,7 @@ export class EdgelessChangeConnectorButton extends WithDisposable(LitElement) {
${LineStylesPanel({ ${LineStylesPanel({
selectedLineSize: selectedLineSize, selectedLineSize: selectedLineSize,
selectedLineStyle: selectedLineStyle, selectedLineStyle: selectedLineStyle,
onClick: (e: LineStyleEvent) => this._setConnectorStroke(e), onClick: this._setConnectorStroke,
})} })}
</div> </div>
<editor-toolbar-separator <editor-toolbar-separator
@@ -414,13 +417,12 @@ export class EdgelessChangeConnectorButton extends WithDisposable(LitElement) {
`} `}
> >
<stroke-style-panel <stroke-style-panel
.theme=${colorScheme}
.strokeWidth=${selectedLineSize} .strokeWidth=${selectedLineSize}
.strokeStyle=${selectedLineStyle} .strokeStyle=${selectedLineStyle}
.strokeColor=${selectedColor} .strokeColor=${selectedColor}
.setStrokeStyle=${(e: LineStyleEvent) => .setStrokeStyle=${this._setConnectorStroke}
this._setConnectorStroke(e)} .setStrokeColor=${this._setConnectorColor}
.setStrokeColor=${(e: ColorEvent) =>
this._setConnectorColor(e.detail)}
> >
</stroke-style-panel> </stroke-style-panel>
</editor-menu-button> </editor-menu-button>
@@ -9,9 +9,10 @@ import { renderToolbarSeparator } from '@blocksuite/affine-components/toolbar';
import { import {
type ColorScheme, type ColorScheme,
DEFAULT_NOTE_HEIGHT, DEFAULT_NOTE_HEIGHT,
DefaultTheme,
type FrameBlockModel, type FrameBlockModel,
NoteDisplayMode, NoteDisplayMode,
PALETTES, resolveColor,
} 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';
@@ -41,14 +42,12 @@ import { mountFrameTitleEditor } from '../../edgeless/utils/text.js';
function getMostCommonColor( function getMostCommonColor(
elements: FrameBlockModel[], elements: FrameBlockModel[],
colorScheme: ColorScheme colorScheme: ColorScheme
): string | null { ): string {
const colors = countBy(elements, (ele: FrameBlockModel) => { const colors = countBy(elements, (ele: FrameBlockModel) =>
return typeof ele.background === 'object' resolveColor(ele.background, colorScheme)
? (ele.background[colorScheme] ?? ele.background.normal ?? null) );
: ele.background;
});
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) : 'transparent';
} }
export class EdgelessChangeFrameButton extends WithDisposable(LitElement) { export class EdgelessChangeFrameButton extends WithDisposable(LitElement) {
@@ -56,19 +55,27 @@ export class EdgelessChangeFrameButton extends WithDisposable(LitElement) {
return this.edgeless.std.get(EdgelessCRUDIdentifier); return this.edgeless.std.get(EdgelessCRUDIdentifier);
} }
pickColor = (event: PickColorEvent) => { private readonly _setFrameBackground = (e: ColorEvent) => {
if (event.type === 'pick') { const background = e.detail.value;
this.frames.forEach(ele => this.frames.forEach(frame => {
this.crud.updateElement( this.crud.updateElement(frame.id, { background });
ele.id, });
packColor('background', { ...event.detail }) };
)
); pickColor = (e: PickColorEvent) => {
const field = 'background';
if (e.type === 'pick') {
const color = e.detail.value;
this.frames.forEach(ele => {
const props = packColor(field, color);
this.crud.updateElement(ele.id, props);
});
return; return;
} }
this.frames.forEach(ele => this.frames.forEach(ele =>
ele[event.type === 'start' ? 'stash' : 'pop']('background') ele[e.type === 'start' ? 'stash' : 'pop'](field)
); );
}; };
@@ -119,18 +126,12 @@ export class EdgelessChangeFrameButton extends WithDisposable(LitElement) {
toast(this.edgeless.host, 'Frame has been inserted into doc'); toast(this.edgeless.host, 'Frame has been inserted into doc');
} }
private _setFrameBackground(color: string) {
this.frames.forEach(frame => {
this.crud.updateElement(frame.id, { background: color });
});
}
protected override render() { protected override render() {
const { frames } = this; const { frames } = this;
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 = getMostCommonColor(frames, colorScheme) ?? 'transparent'; const background = getMostCommonColor(frames, colorScheme);
return join( return join(
[ [
@@ -203,7 +204,8 @@ export class EdgelessChangeFrameButton extends WithDisposable(LitElement) {
.color=${background} .color=${background}
.colors=${colors} .colors=${colors}
.colorType=${type} .colorType=${type}
.palettes=${PALETTES} .theme=${colorScheme}
.palettes=${DefaultTheme.Palettes}
> >
</edgeless-color-picker-button> </edgeless-color-picker-button>
`; `;
@@ -224,8 +226,9 @@ export class EdgelessChangeFrameButton extends WithDisposable(LitElement) {
> >
<edgeless-color-panel <edgeless-color-panel
.value=${background} .value=${background}
.palettes=${PALETTES} .theme=${colorScheme}
@select=${(e: ColorEvent) => this._setFrameBackground(e.detail)} .palettes=${DefaultTheme.Palettes}
@select=${this._setFrameBackground}
> >
</edgeless-color-panel> </edgeless-color-panel>
</editor-menu-button> </editor-menu-button>
@@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */ /* oxlint-disable @typescript-eslint/no-non-null-assertion */
import { import {
MindmapBalanceLayoutIcon, MindmapBalanceLayoutIcon,
MindmapLeftLayoutIcon, MindmapLeftLayoutIcon,
@@ -14,10 +14,10 @@ import {
} from '@blocksuite/affine-components/toolbar'; } from '@blocksuite/affine-components/toolbar';
import { import {
type ColorScheme, type ColorScheme,
DEFAULT_NOTE_BACKGROUND_COLOR, DefaultTheme,
NOTE_BACKGROUND_PALETTES,
type NoteBlockModel, type NoteBlockModel,
NoteDisplayMode, NoteDisplayMode,
resolveColor,
type StrokeStyle, type StrokeStyle,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
import { ThemeProvider } from '@blocksuite/affine-shared/services'; import { ThemeProvider } from '@blocksuite/affine-shared/services';
@@ -43,7 +43,6 @@ import {
packColor, packColor,
packColorsWithColorScheme, packColorsWithColorScheme,
} from '../../edgeless/components/color-picker/utils.js'; } from '../../edgeless/components/color-picker/utils.js';
import type { ColorEvent } from '../../edgeless/components/panel/color-panel.js';
import { import {
type LineStyleEvent, type LineStyleEvent,
LineStylesPanel, LineStylesPanel,
@@ -68,14 +67,14 @@ const DisplayModeMap = {
function getMostCommonBackground( function getMostCommonBackground(
elements: NoteBlockModel[], elements: NoteBlockModel[],
colorScheme: ColorScheme colorScheme: ColorScheme
): string | null { ): string {
const colors = countBy(elements, (ele: NoteBlockModel) => { const colors = countBy(elements, (ele: NoteBlockModel) =>
return typeof ele.background === 'object' resolveColor(ele.background, colorScheme)
? (ele.background[colorScheme] ?? ele.background.normal ?? null) );
: ele.background;
});
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)
: resolveColor(DefaultTheme.noteBackgrounColor, colorScheme);
} }
export class EdgelessChangeNoteButton extends WithDisposable(LitElement) { export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
@@ -83,6 +82,12 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
return this.edgeless.std.get(EdgelessCRUDIdentifier); return this.edgeless.std.get(EdgelessCRUDIdentifier);
} }
private readonly _setBackground = (background: string) => {
this.notes.forEach(element => {
this.crud.updateElement(element.id, { background });
});
};
private readonly _setBorderRadius = (borderRadius: number) => { private readonly _setBorderRadius = (borderRadius: number) => {
this.notes.forEach(note => { this.notes.forEach(note => {
const props = { const props = {
@@ -112,18 +117,19 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
}); });
}; };
pickColor = (event: PickColorEvent) => { pickColor = (e: PickColorEvent) => {
if (event.type === 'pick') { const field = 'background';
if (e.type === 'pick') {
const color = e.detail.value;
this.notes.forEach(element => { this.notes.forEach(element => {
const props = packColor('background', { ...event.detail }); const props = packColor(field, color);
this.crud.updateElement(element.id, props); this.crud.updateElement(element.id, props);
}); });
return; return;
} }
this.notes.forEach(ele => this.notes.forEach(ele => ele[e.type === 'start' ? 'stash' : 'pop'](field));
ele[event.type === 'start' ? 'stash' : 'pop']('background')
);
}; };
private get _advancedVisibilityEnabled() { private get _advancedVisibilityEnabled() {
@@ -145,12 +151,6 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
this.edgeless.slots.toggleNoteSlicer.emit(); this.edgeless.slots.toggleNoteSlicer.emit();
} }
private _setBackground(background: string) {
this.notes.forEach(element => {
this.crud.updateElement(element.id, { background });
});
}
private _setCollapse() { private _setCollapse() {
this.notes.forEach(note => { this.notes.forEach(note => {
const { collapse, collapsedHeight } = note.edgeless; const { collapse, collapsedHeight } = note.edgeless;
@@ -262,9 +262,7 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
const { shadowType, borderRadius, borderSize, borderStyle } = const { shadowType, borderRadius, borderSize, borderStyle } =
edgeless.style; edgeless.style;
const colorScheme = this.edgeless.surface.renderer.getColorScheme(); const colorScheme = this.edgeless.surface.renderer.getColorScheme();
const background = const background = getMostCommonBackground(this.notes, colorScheme);
getMostCommonBackground(this.notes, colorScheme) ??
DEFAULT_NOTE_BACKGROUND_COLOR;
const { collapse } = edgeless; const { collapse } = edgeless;
const scale = edgeless.scale ?? 1; const scale = edgeless.scale ?? 1;
@@ -317,9 +315,11 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
.label=${'Background'} .label=${'Background'}
.pick=${this.pickColor} .pick=${this.pickColor}
.color=${background} .color=${background}
.colorPanelClass=${'small'}
.colorType=${type} .colorType=${type}
.colors=${colors} .colors=${colors}
.palettes=${NOTE_BACKGROUND_PALETTES} .theme=${colorScheme}
.palettes=${DefaultTheme.NoteBackgroundColorPalettes}
> >
</edgeless-color-picker-button> </edgeless-color-picker-button>
`; `;
@@ -339,9 +339,11 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
`} `}
> >
<edgeless-color-panel <edgeless-color-panel
class="small"
.value=${background} .value=${background}
.options=${NOTE_BACKGROUND_PALETTES} .theme=${colorScheme}
@select=${(e: ColorEvent) => this._setBackground(e.detail)} .palettes=${DefaultTheme.NoteBackgroundColorPalettes}
@select=${this._setBackground}
> >
</edgeless-color-panel> </edgeless-color-panel>
</editor-menu-button> </editor-menu-button>
@@ -8,20 +8,21 @@ import {
} from '@blocksuite/affine-components/icons'; } from '@blocksuite/affine-components/icons';
import { renderToolbarSeparator } from '@blocksuite/affine-components/toolbar'; import { renderToolbarSeparator } from '@blocksuite/affine-components/toolbar';
import type { import type {
Color,
ColorScheme, ColorScheme,
ShapeElementModel, ShapeElementModel,
ShapeProps, ShapeProps,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
import { import {
DEFAULT_SHAPE_FILL_COLOR, DefaultTheme,
DEFAULT_SHAPE_STROKE_COLOR,
FontFamily, FontFamily,
getShapeName, getShapeName,
getShapeRadius, getShapeRadius,
getShapeType, getShapeType,
isTransparent,
LineWidth, LineWidth,
MindmapElementModel, MindmapElementModel,
PALETTES, resolveColor,
ShapeStyle, ShapeStyle,
StrokeStyle, StrokeStyle,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
@@ -33,6 +34,7 @@ import { choose } from 'lit/directives/choose.js';
import { join } from 'lit/directives/join.js'; import { join } from 'lit/directives/join.js';
import { styleMap } from 'lit/directives/style-map.js'; import { styleMap } from 'lit/directives/style-map.js';
import { when } from 'lit/directives/when.js'; import { when } from 'lit/directives/when.js';
import isEqual from 'lodash.isequal';
import type { EdgelessColorPickerButton } from '../../edgeless/components/color-picker/button.js'; import type { EdgelessColorPickerButton } from '../../edgeless/components/color-picker/button.js';
import type { PickColorEvent } from '../../edgeless/components/color-picker/types.js'; import type { PickColorEvent } from '../../edgeless/components/color-picker/types.js';
@@ -40,11 +42,7 @@ import {
packColor, packColor,
packColorsWithColorScheme, packColorsWithColorScheme,
} from '../../edgeless/components/color-picker/utils.js'; } from '../../edgeless/components/color-picker/utils.js';
import { import type { ColorEvent } from '../../edgeless/components/panel/color-panel.js';
type ColorEvent,
GET_DEFAULT_LINE_COLOR,
isTransparent,
} from '../../edgeless/components/panel/color-panel.js';
import { import {
type LineStyleEvent, type LineStyleEvent,
LineStylesPanel, LineStylesPanel,
@@ -52,11 +50,6 @@ import {
import type { EdgelessShapePanel } from '../../edgeless/components/panel/shape-panel.js'; import type { EdgelessShapePanel } from '../../edgeless/components/panel/shape-panel.js';
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js'; import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
import type { ShapeToolOption } from '../../edgeless/gfx-tool/shape-tool.js'; import type { ShapeToolOption } from '../../edgeless/gfx-tool/shape-tool.js';
import {
SHAPE_FILL_COLOR_BLACK,
SHAPE_TEXT_COLOR_PURE_BLACK,
SHAPE_TEXT_COLOR_PURE_WHITE,
} from '../../edgeless/utils/consts.js';
import { mountShapeTextEditor } from '../../edgeless/utils/text.js'; import { mountShapeTextEditor } from '../../edgeless/utils/text.js';
const changeShapeButtonStyles = [ const changeShapeButtonStyles = [
@@ -88,62 +81,56 @@ const changeShapeButtonStyles = [
function getMostCommonFillColor( function getMostCommonFillColor(
elements: ShapeElementModel[], elements: ShapeElementModel[],
colorScheme: ColorScheme colorScheme: ColorScheme
): string | null { ): string {
const colors = countBy(elements, (ele: ShapeElementModel) => { const colors = countBy(elements, (ele: ShapeElementModel) =>
if (ele.filled) { ele.filled ? resolveColor(ele.fillColor, colorScheme) : 'transparent'
return typeof ele.fillColor === 'object' );
? (ele.fillColor[colorScheme] ?? ele.fillColor.normal ?? null)
: ele.fillColor;
}
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)
: resolveColor(DefaultTheme.shapeFillColor, colorScheme);
} }
function getMostCommonStrokeColor( function getMostCommonStrokeColor(
elements: ShapeElementModel[], elements: ShapeElementModel[],
colorScheme: ColorScheme colorScheme: ColorScheme
): string | null { ): string {
const colors = countBy(elements, (ele: ShapeElementModel) => { const colors = countBy(elements, (ele: ShapeElementModel) =>
return typeof ele.strokeColor === 'object' resolveColor(ele.strokeColor, colorScheme)
? (ele.strokeColor[colorScheme] ?? ele.strokeColor.normal ?? null) );
: ele.strokeColor;
});
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)
: resolveColor(DefaultTheme.shapeStrokeColor, colorScheme);
} }
function getMostCommonShape( function getMostCommonShape(
elements: ShapeElementModel[] elements: ShapeElementModel[]
): ShapeToolOption['shapeName'] | null { ): ShapeToolOption['shapeName'] | null {
const shapeTypes = countBy(elements, (ele: ShapeElementModel) => { const shapeTypes = countBy(elements, (ele: ShapeElementModel) =>
return getShapeName(ele.shapeType, ele.radius); getShapeName(ele.shapeType, ele.radius)
}); );
const max = maxBy(Object.entries(shapeTypes), ([_k, count]) => count); const max = maxBy(Object.entries(shapeTypes), ([_k, count]) => count);
return max ? (max[0] as ShapeToolOption['shapeName']) : null; return max ? (max[0] as ShapeToolOption['shapeName']) : null;
} }
function getMostCommonLineSize(elements: ShapeElementModel[]): LineWidth { function getMostCommonLineSize(elements: ShapeElementModel[]): LineWidth {
const sizes = countBy(elements, (ele: ShapeElementModel) => { const sizes = countBy(elements, (ele: ShapeElementModel) => ele.strokeWidth);
return ele.strokeWidth;
});
const max = maxBy(Object.entries(sizes), ([_k, count]) => count); const max = maxBy(Object.entries(sizes), ([_k, count]) => count);
return max ? (Number(max[0]) as LineWidth) : LineWidth.Four; return max ? (Number(max[0]) as LineWidth) : LineWidth.Four;
} }
function getMostCommonLineStyle( function getMostCommonLineStyle(elements: ShapeElementModel[]): StrokeStyle {
elements: ShapeElementModel[]
): StrokeStyle | null {
const sizes = countBy(elements, (ele: ShapeElementModel) => ele.strokeStyle); const sizes = countBy(elements, (ele: ShapeElementModel) => ele.strokeStyle);
const max = maxBy(Object.entries(sizes), ([_k, count]) => count); const max = maxBy(Object.entries(sizes), ([_k, count]) => count);
return max ? (max[0] as StrokeStyle) : null; return max ? (max[0] as StrokeStyle) : StrokeStyle.Solid;
} }
function getMostCommonShapeStyle(elements: ShapeElementModel[]): ShapeStyle { function getMostCommonShapeStyle(elements: ShapeElementModel[]): ShapeStyle {
const roughnesses = countBy(elements, (ele: ShapeElementModel) => { const roughnesses = countBy(
return ele.shapeStyle; elements,
}); (ele: ShapeElementModel) => ele.shapeStyle
);
const max = maxBy(Object.entries(roughnesses), ([_k, count]) => count); const max = maxBy(Object.entries(roughnesses), ([_k, count]) => count);
return max ? (max[0] as ShapeStyle) : ShapeStyle.Scribbled; return max ? (max[0] as ShapeStyle) : ShapeStyle.Scribbled;
} }
@@ -151,6 +138,32 @@ function getMostCommonShapeStyle(elements: ShapeElementModel[]): ShapeStyle {
export class EdgelessChangeShapeButton extends WithDisposable(LitElement) { export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
static override styles = [changeShapeButtonStyles]; static override styles = [changeShapeButtonStyles];
private readonly _setShapeFillColor = (e: ColorEvent) => {
const fillColor = e.detail.value;
const filled = !isTransparent(fillColor);
const color = this._getTextColor(fillColor, filled);
this.elements.forEach(ele =>
this.crud.updateElement(ele.id, { filled, fillColor, color })
);
};
private readonly _setShapeStrokeColor = (e: ColorEvent) => {
const strokeColor = e.detail.value;
this.elements.forEach(ele =>
this.crud.updateElement(ele.id, { strokeColor })
);
};
private readonly _setShapeStyles = ({ type, value }: LineStyleEvent) => {
if (type === 'size') {
this._setShapeStrokeWidth(value);
return;
}
if (type === 'lineStyle') {
this._setShapeStrokeStyle(value);
}
};
get service() { get service() {
return this.edgeless.service; return this.edgeless.service;
} }
@@ -159,58 +172,24 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
return this.edgeless.std.get(EdgelessCRUDIdentifier); return this.edgeless.std.get(EdgelessCRUDIdentifier);
} }
#pickColor<K extends keyof Pick<ShapeProps, 'fillColor' | 'strokeColor'>>(
key: K
) {
return (event: PickColorEvent) => {
if (event.type === 'pick') {
this.elements.forEach(ele => {
const props = packColor(key, { ...event.detail });
// If `filled` can be set separately, this logic can be removed
if (key === 'fillColor' && !ele.filled) {
Object.assign(props, { filled: true });
}
this.crud.updateElement(ele.id, props);
});
return;
}
this.elements.forEach(ele =>
ele[event.type === 'start' ? 'stash' : 'pop'](key)
);
};
}
private _addText() { private _addText() {
mountShapeTextEditor(this.elements[0], this.edgeless); mountShapeTextEditor(this.elements[0], this.edgeless);
} }
private _getTextColor(fillColor: string) { private _getTextColor(fillColor: Color, isNotTransparent = false) {
const colorScheme = this.edgeless.surface.renderer.getColorScheme();
// When the shape is filled with black color, the text color should be white. // When the shape is filled with black color, the text color should be white.
// When the shape is transparent, the text color should be set according to the theme. // When the shape is transparent, the text color should be set according to the theme.
// Otherwise, the text color should be black. // Otherwise, the text color should be black.
const textColor = isTransparent(fillColor)
? GET_DEFAULT_LINE_COLOR(colorScheme)
: fillColor === SHAPE_FILL_COLOR_BLACK
? SHAPE_TEXT_COLOR_PURE_WHITE
: SHAPE_TEXT_COLOR_PURE_BLACK;
return textColor; if (isNotTransparent) {
if (isEqual(fillColor, DefaultTheme.black)) {
return DefaultTheme.white;
} else if (isEqual(fillColor, DefaultTheme.white)) {
return DefaultTheme.black;
}
} }
private _setShapeFillColor(fillColor: string) { return DefaultTheme.black;
const filled = !isTransparent(fillColor);
const color = this._getTextColor(fillColor);
this.elements.forEach(ele =>
this.crud.updateElement(ele.id, { filled, fillColor, color })
);
}
private _setShapeStrokeColor(strokeColor: string) {
this.elements.forEach(ele =>
this.crud.updateElement(ele.id, { strokeColor })
);
} }
private _setShapeStrokeStyle(strokeStyle: StrokeStyle) { private _setShapeStrokeStyle(strokeStyle: StrokeStyle) {
@@ -234,16 +213,6 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
}); });
} }
private _setShapeStyles({ type, value }: LineStyleEvent) {
if (type === 'size') {
this._setShapeStrokeWidth(value);
return;
}
if (type === 'lineStyle') {
this._setShapeStrokeStyle(value);
}
}
private _showAddButtonOrTextMenu() { private _showAddButtonOrTextMenu() {
if (this.elements.length === 1 && !this.elements[0].text) { if (this.elements.length === 1 && !this.elements[0].text) {
return 'button'; return 'button';
@@ -270,20 +239,38 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
); );
} }
pickColor<K extends keyof Pick<ShapeProps, 'fillColor' | 'strokeColor'>>(
field: K
) {
return (e: PickColorEvent) => {
if (e.type === 'pick') {
const color = e.detail.value;
this.elements.forEach(ele => {
const props = packColor(field, color);
// If `filled` can be set separately, this logic can be removed
if (field === 'fillColor' && !ele.filled) {
Object.assign(props, { filled: true });
}
this.crud.updateElement(ele.id, props);
});
return;
}
this.elements.forEach(ele =>
ele[e.type === 'start' ? 'stash' : 'pop'](field)
);
};
}
override render() { override render() {
const colorScheme = this.edgeless.surface.renderer.getColorScheme(); const colorScheme = this.edgeless.surface.renderer.getColorScheme();
const elements = this.elements; const elements = this.elements;
const selectedShape = getMostCommonShape(elements); const selectedShape = getMostCommonShape(elements);
const selectedFillColor = const selectedFillColor = getMostCommonFillColor(elements, colorScheme);
getMostCommonFillColor(elements, colorScheme) ?? DEFAULT_SHAPE_FILL_COLOR; const selectedStrokeColor = getMostCommonStrokeColor(elements, colorScheme);
const selectedStrokeColor = const selectedLineSize = getMostCommonLineSize(elements);
getMostCommonStrokeColor(elements, colorScheme) ?? const selectedLineStyle = getMostCommonLineStyle(elements);
DEFAULT_SHAPE_STROKE_COLOR; const selectedShapeStyle = getMostCommonShapeStyle(elements);
const selectedLineSize = getMostCommonLineSize(elements) ?? LineWidth.Four;
const selectedLineStyle =
getMostCommonLineStyle(elements) ?? StrokeStyle.Solid;
const selectedShapeStyle =
getMostCommonShapeStyle(elements) ?? ShapeStyle.Scribbled;
return join( return join(
[ [
@@ -340,11 +327,12 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
<edgeless-color-picker-button <edgeless-color-picker-button
class="fill-color" class="fill-color"
.label=${'Fill color'} .label=${'Fill color'}
.pick=${this.#pickColor('fillColor')} .pick=${this.pickColor('fillColor')}
.color=${selectedFillColor} .color=${selectedFillColor}
.colors=${colors} .colors=${colors}
.colorType=${type} .colorType=${type}
.palettes=${PALETTES} .theme=${colorScheme}
.palettes=${DefaultTheme.Palettes}
> >
</edgeless-color-picker-button> </edgeless-color-picker-button>
`; `;
@@ -367,8 +355,9 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
role="listbox" role="listbox"
aria-label="Fill colors" aria-label="Fill colors"
.value=${selectedFillColor} .value=${selectedFillColor}
.palettes=${PALETTES} .theme=${colorScheme}
@select=${(e: ColorEvent) => this._setShapeFillColor(e.detail)} .palettes=${DefaultTheme.Palettes}
@select=${this._setShapeFillColor}
> >
</edgeless-color-panel> </edgeless-color-panel>
</editor-menu-button> </editor-menu-button>
@@ -388,11 +377,12 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
<edgeless-color-picker-button <edgeless-color-picker-button
class="border-style" class="border-style"
.label=${'Border style'} .label=${'Border style'}
.pick=${this.#pickColor('strokeColor')} .pick=${this.pickColor('strokeColor')}
.color=${selectedStrokeColor} .color=${selectedStrokeColor}
.colors=${colors} .colors=${colors}
.colorType=${type} .colorType=${type}
.palettes=${PALETTES} .theme=${colorScheme}
.palettes=${DefaultTheme.Palettes}
.hollowCircle=${true} .hollowCircle=${true}
> >
<div <div
@@ -408,8 +398,7 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
${LineStylesPanel({ ${LineStylesPanel({
selectedLineSize: selectedLineSize, selectedLineSize: selectedLineSize,
selectedLineStyle: selectedLineStyle, selectedLineStyle: selectedLineStyle,
onClick: (e: LineStyleEvent) => this._setShapeStyles(e), onClick: this._setShapeStyles,
lineStyles: [StrokeStyle.Solid, StrokeStyle.Dash],
})} })}
</div> </div>
<editor-toolbar-separator <editor-toolbar-separator
@@ -435,14 +424,13 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
`} `}
> >
<stroke-style-panel <stroke-style-panel
.theme=${colorScheme}
.hollowCircle=${true} .hollowCircle=${true}
.strokeWidth=${selectedLineSize} .strokeWidth=${selectedLineSize}
.strokeStyle=${selectedLineStyle} .strokeStyle=${selectedLineStyle}
.strokeColor=${selectedStrokeColor} .strokeColor=${selectedStrokeColor}
.setStrokeStyle=${(e: LineStyleEvent) => .setStrokeStyle=${this._setShapeStyles}
this._setShapeStyles(e)} .setStrokeColor=${this._setShapeStrokeColor}
.setStrokeColor=${(e: ColorEvent) =>
this._setShapeStrokeColor(e.detail)}
> >
</stroke-style-panel> </stroke-style-panel>
</editor-menu-button> </editor-menu-button>
@@ -14,11 +14,12 @@ import { renderToolbarSeparator } from '@blocksuite/affine-components/toolbar';
import { import {
type ColorScheme, type ColorScheme,
ConnectorElementModel, ConnectorElementModel,
DefaultTheme,
EdgelessTextBlockModel, EdgelessTextBlockModel,
FontFamily, FontFamily,
FontStyle, FontStyle,
FontWeight, FontWeight,
PALETTES, resolveColor,
ShapeElementModel, ShapeElementModel,
TextAlign, TextAlign,
TextElementModel, TextElementModel,
@@ -44,10 +45,7 @@ import {
packColor, packColor,
packColorsWithColorScheme, packColorsWithColorScheme,
} from '../../edgeless/components/color-picker/utils.js'; } from '../../edgeless/components/color-picker/utils.js';
import { import type { ColorEvent } from '../../edgeless/components/panel/color-panel.js';
type ColorEvent,
GET_DEFAULT_LINE_COLOR,
} from '../../edgeless/components/panel/color-panel.js';
import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js'; import type { EdgelessRootBlockComponent } from '../../edgeless/edgeless-root-block.js';
const FONT_SIZE_LIST = [ const FONT_SIZE_LIST = [
@@ -121,12 +119,12 @@ function getMostCommonColor(
const colors = countBy(elements, (ele: BlockSuite.EdgelessTextModelType) => { const colors = countBy(elements, (ele: BlockSuite.EdgelessTextModelType) => {
const color = const color =
ele instanceof ConnectorElementModel ? ele.labelStyle.color : ele.color; ele instanceof ConnectorElementModel ? ele.labelStyle.color : ele.color;
return typeof color === 'object' return resolveColor(color, colorScheme);
? (color[colorScheme] ?? color.normal ?? null)
: color;
}); });
const max = maxBy(Object.entries(colors), ([_k, count]) => count); const max = maxBy(Object.entries(colors), ([_k, count]) => count);
return max ? (max[0] as string) : GET_DEFAULT_LINE_COLOR(colorScheme); return max
? (max[0] as string)
: resolveColor(DefaultTheme.textColor, colorScheme);
} }
function getMostCommonFontFamily(elements: BlockSuite.EdgelessTextModelType[]) { function getMostCommonFontFamily(elements: BlockSuite.EdgelessTextModelType[]) {
@@ -229,7 +227,8 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
}); });
}; };
private readonly _setTextColor = ({ detail: color }: ColorEvent) => { private readonly _setTextColor = (e: ColorEvent) => {
const color = e.detail.value;
const props = { color }; const props = { color };
this.elements.forEach(element => { this.elements.forEach(element => {
this.crud.updateElement(element.id, buildProps(element, props)); this.crud.updateElement(element.id, buildProps(element, props));
@@ -307,10 +306,11 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
// no need to update the bound of edgeless text block, which updates itself using ResizeObserver // no need to update the bound of edgeless text block, which updates itself using ResizeObserver
}; };
pickColor = (event: PickColorEvent) => { pickColor = (e: PickColorEvent) => {
if (event.type === 'pick') { if (e.type === 'pick') {
const color = e.detail.value;
this.elements.forEach(element => { this.elements.forEach(element => {
const props = packColor('color', { ...event.detail }); const props = packColor('color', color);
this.crud.updateElement(element.id, buildProps(element, props)); this.crud.updateElement(element.id, buildProps(element, props));
this._updateElementBound(element); this._updateElementBound(element);
}); });
@@ -319,7 +319,7 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
const key = this.elementType === 'connector' ? 'labelStyle' : 'color'; const key = this.elementType === 'connector' ? 'labelStyle' : 'color';
this.elements.forEach(ele => { this.elements.forEach(ele => {
ele[event.type === 'start' ? 'stash' : 'pop'](key as 'color'); ele[e.type === 'start' ? 'stash' : 'pop'](key as 'color');
}); });
}; };
@@ -391,7 +391,8 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
.color=${selectedColor} .color=${selectedColor}
.colors=${colors} .colors=${colors}
.colorType=${type} .colorType=${type}
.palettes=${PALETTES} .theme=${colorScheme}
.palettes=${DefaultTheme.Palettes}
> >
</edgeless-color-picker-button> </edgeless-color-picker-button>
`; `;
@@ -412,7 +413,8 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
> >
<edgeless-color-panel <edgeless-color-panel
.value=${selectedColor} .value=${selectedColor}
.palettes=${PALETTES} .theme=${colorScheme}
.palettes=${DefaultTheme.Palettes}
@select=${this._setTextColor} @select=${this._setTextColor}
></edgeless-color-panel> ></edgeless-color-panel>
</editor-menu-button> </editor-menu-button>
@@ -1,4 +1,8 @@
import { ColorScheme, FrameBlockModel } from '@blocksuite/affine-model'; import {
ColorScheme,
FrameBlockModel,
isTransparent,
} from '@blocksuite/affine-model';
import { ThemeProvider } from '@blocksuite/affine-shared/services'; import { ThemeProvider } from '@blocksuite/affine-shared/services';
import { import {
type BlockStdScope, type BlockStdScope,
@@ -19,7 +23,6 @@ import { LitElement } from 'lit';
import { property, state } from 'lit/decorators.js'; import { property, state } from 'lit/decorators.js';
import { parseStringToRgba } from '../../edgeless/components/color-picker/utils.js'; import { parseStringToRgba } from '../../edgeless/components/color-picker/utils.js';
import { isTransparent } from '../../edgeless/components/panel/color-panel.js';
import type { EdgelessRootService } from '../../edgeless/index.js'; import type { EdgelessRootService } from '../../edgeless/index.js';
import { frameTitleStyle, frameTitleStyleVars } from './styles.js'; import { frameTitleStyle, frameTitleStyleVars } from './styles.js';
@@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */ /* oxlint-disable @typescript-eslint/no-non-null-assertion */
import type { SurfaceBlockModel } from '@blocksuite/affine-block-surface'; import type { SurfaceBlockModel } from '@blocksuite/affine-block-surface';
import { import {
CanvasRenderer, CanvasRenderer,
@@ -101,14 +101,14 @@ export class MindmapSurfaceBlock extends BlockComponent<SurfaceBlockModel> {
provider: { provider: {
selectedElements: () => [], selectedElements: () => [],
getColorScheme: () => themeService.edgelessTheme, getColorScheme: () => themeService.edgelessTheme,
getColorValue: (color: Color, fallback?: string, real?: boolean) => getColorValue: (color: Color, fallback?: Color, real?: boolean) =>
themeService.getColorValue( themeService.getColorValue(
color, color,
fallback, fallback,
real, real,
themeService.edgelessTheme themeService.edgelessTheme
), ),
generateColorProperty: (color: Color, fallback: string) => generateColorProperty: (color: Color, fallback?: Color) =>
themeService.generateColorProperty( themeService.generateColorProperty(
color, color,
fallback, fallback,
@@ -1,7 +1,7 @@
import type { CanvasRenderer } from '@blocksuite/affine-block-surface'; import type { CanvasRenderer } from '@blocksuite/affine-block-surface';
import type { NoteBlockModel } from '@blocksuite/affine-model'; import type { NoteBlockModel } from '@blocksuite/affine-model';
import { import {
DEFAULT_NOTE_BACKGROUND_COLOR, DefaultTheme,
NoteDisplayMode, NoteDisplayMode,
NoteShadow, NoteShadow,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
@@ -73,7 +73,7 @@ export class SurfaceRefNotePortal extends WithDisposable(ShadowlessElement) {
const backgroundColor = this.host.std const backgroundColor = this.host.std
.get(ThemeProvider) .get(ThemeProvider)
.generateColorProperty(model.background, DEFAULT_NOTE_BACKGROUND_COLOR); .generateColorProperty(model.background, DefaultTheme.noteBackgrounColor);
const [modelX, modelY, modelW, modelH] = deserializeXYWH(model.xywh); const [modelX, modelY, modelW, modelH] = deserializeXYWH(model.xywh);
const style = { const style = {
@@ -67,7 +67,6 @@ describe('theme service', () => {
expect(themeService.generateColorProperty({ normal: 'grey' })).toBe('grey'); expect(themeService.generateColorProperty({ normal: 'grey' })).toBe('grey');
expect(themeService.generateColorProperty('', 'blue')).toBe('blue'); expect(themeService.generateColorProperty('', 'blue')).toBe('blue');
expect(themeService.generateColorProperty({}, 'red')).toBe('red');
}); });
test('gets a color value', () => { test('gets a color value', () => {
@@ -2,26 +2,21 @@ import type { BlockStdScope } from '@blocksuite/block-std';
import { import {
type BrushElementModel, type BrushElementModel,
type ConnectorElementModel, type ConnectorElementModel,
DEFAULT_NOTE_BACKGROUND_COLOR,
DEFAULT_NOTE_SHADOW, DEFAULT_NOTE_SHADOW,
DEFAULT_TEXT_COLOR, DefaultTheme,
type EdgelessRootBlockComponent, type EdgelessRootBlockComponent,
type EdgelessTextBlockModel, type EdgelessTextBlockModel,
EditPropsStore, EditPropsStore,
FontFamily, FontFamily,
FrameBackgroundColor,
type FrameBlockModel, type FrameBlockModel,
getSurfaceBlock, getSurfaceBlock,
LayoutType, LayoutType,
type MindmapElementModel, type MindmapElementModel,
MindmapStyle, MindmapStyle,
NoteBackgroundColor,
type NoteBlockModel, type NoteBlockModel,
NoteShadow, NoteShadow,
type ShapeElementModel, type ShapeElementModel,
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';
@@ -51,14 +46,14 @@ describe('apply last props', () => {
}); });
assertExists(rectId); assertExists(rectId);
const rectShape = service.crud.getElementById(rectId) as ShapeElementModel; const rectShape = service.crud.getElementById(rectId) as ShapeElementModel;
expect(rectShape.fillColor).toBe(ShapeFillColor.Yellow); expect(rectShape.fillColor).toBe(DefaultTheme.shapeFillColor);
service.crud.updateElement(rectId, { service.crud.updateElement(rectId, {
fillColor: ShapeFillColor.Orange, fillColor: DefaultTheme.FillColorMap.Orange,
}); });
expect( expect(
std.get(EditPropsStore).lastProps$.value[`shape:${ShapeType.Rect}`] std.get(EditPropsStore).lastProps$.value[`shape:${ShapeType.Rect}`]
.fillColor .fillColor
).toBe(ShapeFillColor.Orange); ).toBe(DefaultTheme.FillColorMap.Orange);
// diamond shape // diamond shape
const diamondId = service.crud.addElement('shape', { const diamondId = service.crud.addElement('shape', {
@@ -68,14 +63,14 @@ describe('apply last props', () => {
const diamondShape = service.crud.getElementById( const diamondShape = service.crud.getElementById(
diamondId diamondId
) as ShapeElementModel; ) as ShapeElementModel;
expect(diamondShape.fillColor).toBe(ShapeFillColor.Yellow); expect(diamondShape.fillColor).toBe(DefaultTheme.FillColorMap.Yellow);
service.crud.updateElement(diamondId, { service.crud.updateElement(diamondId, {
fillColor: ShapeFillColor.Blue, fillColor: DefaultTheme.FillColorMap.Blue,
}); });
expect( expect(
std.get(EditPropsStore).lastProps$.value[`shape:${ShapeType.Diamond}`] std.get(EditPropsStore).lastProps$.value[`shape:${ShapeType.Diamond}`]
.fillColor .fillColor
).toBe(ShapeFillColor.Blue); ).toBe(DefaultTheme.FillColorMap.Blue);
// rounded rect shape // rounded rect shape
const roundedRectId = service.crud.addElement('shape', { const roundedRectId = service.crud.addElement('shape', {
@@ -86,13 +81,13 @@ describe('apply last props', () => {
const roundedRectShape = service.crud.getElementById( const roundedRectShape = service.crud.getElementById(
roundedRectId roundedRectId
) as ShapeElementModel; ) as ShapeElementModel;
expect(roundedRectShape.fillColor).toBe(ShapeFillColor.Yellow); expect(roundedRectShape.fillColor).toBe(DefaultTheme.FillColorMap.Yellow);
service.crud.updateElement(roundedRectId, { service.crud.updateElement(roundedRectId, {
fillColor: ShapeFillColor.Green, fillColor: DefaultTheme.FillColorMap.Green,
}); });
expect( expect(
std.get(EditPropsStore).lastProps$.value['shape:roundedRect'].fillColor std.get(EditPropsStore).lastProps$.value['shape:roundedRect'].fillColor
).toBe(ShapeFillColor.Green); ).toBe(DefaultTheme.FillColorMap.Green);
// apply last props // apply last props
const rectId2 = service.crud.addElement('shape', { const rectId2 = service.crud.addElement('shape', {
@@ -102,7 +97,7 @@ describe('apply last props', () => {
const rectShape2 = service.crud.getElementById( const rectShape2 = service.crud.getElementById(
rectId2 rectId2
) as ShapeElementModel; ) as ShapeElementModel;
expect(rectShape2.fillColor).toBe(ShapeFillColor.Orange); expect(rectShape2.fillColor).toBe(DefaultTheme.FillColorMap.Orange);
const diamondId2 = service.crud.addElement('shape', { const diamondId2 = service.crud.addElement('shape', {
shapeType: ShapeType.Diamond, shapeType: ShapeType.Diamond,
@@ -111,7 +106,7 @@ describe('apply last props', () => {
const diamondShape2 = service.crud.getElementById( const diamondShape2 = service.crud.getElementById(
diamondId2 diamondId2
) as ShapeElementModel; ) as ShapeElementModel;
expect(diamondShape2.fillColor).toBe(ShapeFillColor.Blue); expect(diamondShape2.fillColor).toBe(DefaultTheme.FillColorMap.Blue);
const roundedRectId2 = service.crud.addElement('shape', { const roundedRectId2 = service.crud.addElement('shape', {
shapeType: ShapeType.Rect, shapeType: ShapeType.Rect,
@@ -121,14 +116,14 @@ describe('apply last props', () => {
const roundedRectShape2 = service.crud.getElementById( const roundedRectShape2 = service.crud.getElementById(
roundedRectId2 roundedRectId2
) as ShapeElementModel; ) as ShapeElementModel;
expect(roundedRectShape2.fillColor).toBe(ShapeFillColor.Green); expect(roundedRectShape2.fillColor).toBe(DefaultTheme.FillColorMap.Green);
}); });
test('connector', () => { test('connector', () => {
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(StrokeColor.Grey); expect(connector.stroke).toBe(DefaultTheme.connectorColor);
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 +138,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: StrokeColor.Magenta, color: DefaultTheme.black,
fontFamily: FontFamily.Kalam, fontFamily: FontFamily.Kalam,
}, },
}); });
@@ -154,7 +149,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(StrokeColor.Magenta); expect(connector3.labelStyle.color).toEqual(DefaultTheme.black);
expect(connector3.labelStyle.fontFamily).toBe(FontFamily.Kalam); expect(connector3.labelStyle.fontFamily).toBe(FontFamily.Kalam);
}); });
@@ -162,10 +157,7 @@ describe('apply last props', () => {
const id = service.crud.addElement('brush', {}); const id = service.crud.addElement('brush', {});
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(DefaultTheme.black);
dark: StrokeColor.White,
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 });
const secondBrush = service.crud.getElementById( const secondBrush = service.crud.getElementById(
@@ -209,17 +201,17 @@ describe('apply last props', () => {
const id = service.crud.addBlock('affine:edgeless-text', {}, surface!.id); const id = service.crud.addBlock('affine:edgeless-text', {}, surface!.id);
assertExists(id); assertExists(id);
const text = service.crud.getElementById(id) as EdgelessTextBlockModel; const text = service.crud.getElementById(id) as EdgelessTextBlockModel;
expect(text.color).toBe(DEFAULT_TEXT_COLOR); expect(text.color).toBe(DefaultTheme.textColor);
expect(text.fontFamily).toBe(FontFamily.Inter); expect(text.fontFamily).toBe(FontFamily.Inter);
service.crud.updateElement(id, { service.crud.updateElement(id, {
color: StrokeColor.Green, color: DefaultTheme.StrokeColorMap.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(StrokeColor.Green); expect(text2.color).toBe(DefaultTheme.StrokeColorMap.Green);
expect(text2.fontFamily).toBe(FontFamily.OrelegaOne); expect(text2.fontFamily).toBe(FontFamily.OrelegaOne);
}); });
@@ -227,10 +219,10 @@ describe('apply last props', () => {
const id = service.crud.addBlock('affine:note', {}, doc.root!.id); const id = service.crud.addBlock('affine:note', {}, doc.root!.id);
assertExists(id); assertExists(id);
const note = service.crud.getElementById(id) as NoteBlockModel; const note = service.crud.getElementById(id) as NoteBlockModel;
expect(note.background).toBe(DEFAULT_NOTE_BACKGROUND_COLOR); expect(note.background).toEqual(DefaultTheme.noteBackgrounColor);
expect(note.edgeless.style.shadowType).toBe(DEFAULT_NOTE_SHADOW); expect(note.edgeless.style.shadowType).toBe(DEFAULT_NOTE_SHADOW);
service.crud.updateElement(id, { service.crud.updateElement(id, {
background: NoteBackgroundColor.Purple, background: DefaultTheme.NoteBackgroundColorMap.Purple,
edgeless: { edgeless: {
style: { style: {
shadowType: NoteShadow.Film, shadowType: NoteShadow.Film,
@@ -241,7 +233,9 @@ describe('apply last props', () => {
const id2 = service.crud.addBlock('affine:note', {}, doc.root!.id); const id2 = service.crud.addBlock('affine:note', {}, doc.root!.id);
assertExists(id2); assertExists(id2);
const note2 = service.crud.getElementById(id2) as NoteBlockModel; const note2 = service.crud.getElementById(id2) as NoteBlockModel;
expect(note2.background).toBe(NoteBackgroundColor.Purple); expect(note2.background).toEqual(
DefaultTheme.NoteBackgroundColorMap.Purple
);
expect(note2.edgeless.style.shadowType).toBe(NoteShadow.Film); expect(note2.edgeless.style.shadowType).toBe(NoteShadow.Film);
}); });
@@ -252,13 +246,13 @@ describe('apply last props', () => {
const note = service.crud.getElementById(id) as FrameBlockModel; const note = service.crud.getElementById(id) as FrameBlockModel;
expect(note.background).toBe('transparent'); expect(note.background).toBe('transparent');
service.crud.updateElement(id, { service.crud.updateElement(id, {
background: FrameBackgroundColor.Purple, background: DefaultTheme.StrokeColorMap.Purple,
}); });
const id2 = service.crud.addBlock('affine:frame', {}, surface!.id); const id2 = service.crud.addBlock('affine:frame', {}, surface!.id);
assertExists(id2); assertExists(id2);
const frame2 = service.crud.getElementById(id2) as FrameBlockModel; const frame2 = service.crud.getElementById(id2) as FrameBlockModel;
expect(frame2.background).toBe(FrameBackgroundColor.Purple); expect(frame2.background).toBe(DefaultTheme.StrokeColorMap.Purple);
service.crud.updateElement(id2, { service.crud.updateElement(id2, {
background: { normal: '#def4e740' }, background: { normal: '#def4e740' },
}); });
@@ -4,7 +4,7 @@ import type {
ShapeElementModel, ShapeElementModel,
SurfaceBlockModel, SurfaceBlockModel,
} from '@blocksuite/blocks'; } from '@blocksuite/blocks';
import { StrokeColor } from '@blocksuite/blocks'; import { DefaultTheme } 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';
@@ -72,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(StrokeColor.Yellow); expect(element.strokeColor).toBe(DefaultTheme.shapeStrokeColor);
expect(element.strokeWidth).toBe(4); expect(element.strokeWidth).toBe(4);
}); });
@@ -94,7 +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(StrokeColor.Yellow); expect(element.yMap.get('strokeColor')).toBe(DefaultTheme.shapeStrokeColor);
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');
+60 -10
View File
@@ -144,7 +144,12 @@ test('can insert attachment from slash menu', async ({ page }) => {
page, page,
` `
<affine:note <affine:note
prop:background="--affine-v2-edgeless-note-white" prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -191,7 +196,12 @@ test('should undo/redo works for attachment', async ({ page }) => {
await assertStoreMatchJSX( await assertStoreMatchJSX(
page, page,
` <affine:note ` <affine:note
prop:background="--affine-v2-edgeless-note-white" prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -229,7 +239,12 @@ test('should undo/redo works for attachment', async ({ page }) => {
page, page,
` `
<affine:note <affine:note
prop:background="--affine-v2-edgeless-note-white" prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -260,7 +275,12 @@ test('should undo/redo works for attachment', async ({ page }) => {
page, page,
` `
<affine:note <affine:note
prop:background="--affine-v2-edgeless-note-white" prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -348,7 +368,12 @@ test('should turn attachment to image works', async ({ page }) => {
page, page,
` `
<affine:note <affine:note
prop:background="--affine-v2-edgeless-note-white" prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -382,7 +407,12 @@ test('should turn attachment to image works', async ({ page }) => {
page, page,
` `
<affine:note <affine:note
prop:background="--affine-v2-edgeless-note-white" prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -431,7 +461,12 @@ test('should attachment can be deleted', async ({ page }) => {
page, page,
` `
<affine:note <affine:note
prop:background="--affine-v2-edgeless-note-white" prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -475,7 +510,12 @@ test.fixme(`support dragging attachment block directly`, async ({ page }) => {
await assertStoreMatchJSX( await assertStoreMatchJSX(
page, page,
` <affine:note ` <affine:note
prop:background="--affine-v2-edgeless-note-white" prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -531,7 +571,12 @@ test.fixme(`support dragging attachment block directly`, async ({ page }) => {
page, page,
/*xml*/ `<affine:page> /*xml*/ `<affine:page>
<affine:note <affine:note
prop:background="--affine-v2-edgeless-note-white" prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -589,7 +634,12 @@ test.fixme(`support dragging attachment block directly`, async ({ page }) => {
page, page,
/*xml*/ `<affine:page> /*xml*/ `<affine:page>
<affine:note <affine:note
prop:background="--affine-v2-edgeless-note-white" prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
+24 -6
View File
@@ -1,4 +1,5 @@
import { expect } from '@playwright/test'; import { expect } from '@playwright/test';
import { lightThemeV2 } from '@toeverything/theme/v2';
import { initDatabaseColumn } from '../database/actions.js'; import { initDatabaseColumn } from '../database/actions.js';
import { import {
@@ -441,7 +442,12 @@ test(scoped`should copy and paste of database work`, async ({ page }) => {
/*xml*/ ` /*xml*/ `
<affine:page> <affine:page>
<affine:note <affine:note
prop:background="--affine-v2-edgeless-note-white" prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -491,7 +497,12 @@ test(scoped`should copy and paste of database work`, async ({ page }) => {
/*xml*/ ` /*xml*/ `
<affine:page> <affine:page>
<affine:note <affine:note
prop:background="--affine-v2-edgeless-note-white" prop:background={
Object {
"dark": "#000000",
"light": "#ffffff",
}
}
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
@@ -574,9 +585,12 @@ 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-v2-edgeless-note-grey'; await changeEdgelessNoteBackground(page, 'White');
await changeEdgelessNoteBackground(page, color); await assertEdgelessNoteBackground(
await assertEdgelessNoteBackground(page, ids.noteId, color); page,
ids.noteId,
lightThemeV2['edgeless/note/white']
);
await copyByKeyboard(page); await copyByKeyboard(page);
@@ -584,7 +598,11 @@ test(scoped`paste note block with background`, async ({ page }) => {
await pasteByKeyboard(page, false); await pasteByKeyboard(page, false);
const noteIds = await getAllNoteIds(page); const noteIds = await getAllNoteIds(page);
for (const noteId of noteIds) { for (const noteId of noteIds) {
await assertEdgelessNoteBackground(page, noteId, color); await assertEdgelessNoteBackground(
page,
noteId,
lightThemeV2['edgeless/note/white']
);
} }
}); });
@@ -1,9 +1,5 @@
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 { lightThemeV2 } from '@toeverything/theme/v2';
import { clickView, moveView } from '../utils/actions/click.js'; import { clickView, moveView } from '../utils/actions/click.js';
import { dragBetweenCoords } from '../utils/actions/drag.js'; import { dragBetweenCoords } from '../utils/actions/drag.js';
@@ -139,11 +135,9 @@ 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 = StrokeColor.Red; await changeShapeStrokeColor(page, 'MediumRed');
await changeShapeStrokeColor(page, lineColor);
await triggerComponentToolbarAction(page, 'changeShapeFillColor'); await triggerComponentToolbarAction(page, 'changeShapeFillColor');
const color = ShapeFillColor.Green; await changeShapeFillColor(page, 'HeavyGreen');
await changeShapeFillColor(page, color);
await dragBetweenViewCoords(page, [120, 50], [200, 0]); await dragBetweenViewCoords(page, [120, 50], [200, 0]);
const noteButton = getAutoCompletePanelButton(page, 'note'); const noteButton = getAutoCompletePanelButton(page, 'note');
@@ -168,7 +162,7 @@ test.describe('auto-complete', () => {
await assertEdgelessNoteBackground( await assertEdgelessNoteBackground(
page, page,
noteId, noteId,
DEFAULT_NOTE_BACKGROUND_COLOR lightThemeV2['edgeless/note/white']
); );
const rect = await edgelessNote.boundingBox(); const rect = await edgelessNote.boundingBox();
@@ -181,15 +175,18 @@ test.describe('auto-complete', () => {
// select connector // select connector
await dragBetweenViewCoords(page, [140, 50], [160, 0]); await dragBetweenViewCoords(page, [140, 50], [160, 0]);
await waitNextFrame(page); await waitNextFrame(page);
await assertConnectorStrokeColor(page, lineColor); await assertConnectorStrokeColor(
page,
'MediumRed',
lightThemeV2['edgeless/palette/medium/redMedium']
);
// select note block // select note block
await page.mouse.click(rect.x + rect.width / 2, rect.y + rect.height / 2); await page.mouse.click(rect.x + rect.width / 2, rect.y + rect.height / 2);
await waitNextFrame(page); await waitNextFrame(page);
await triggerComponentToolbarAction(page, 'changeNoteColor'); await triggerComponentToolbarAction(page, 'changeNoteColor');
const noteColor = '--affine-v2-edgeless-note-red'; await changeEdgelessNoteBackground(page, 'Red');
await changeEdgelessNoteBackground(page, noteColor);
// move to arrow icon // move to arrow icon
await page.mouse.move( await page.mouse.move(
@@ -223,7 +220,11 @@ test.describe('auto-complete', () => {
return note?.getAttribute('data-block-id'); return note?.getAttribute('data-block-id');
}); });
assertExists(noteId2); assertExists(noteId2);
await assertEdgelessNoteBackground(page, noteId, noteColor); await assertEdgelessNoteBackground(
page,
noteId,
lightThemeV2['edgeless/note/red']
);
expect(await edgelessNote.count()).toBe(2); expect(await edgelessNote.count()).toBe(2);
}); });
@@ -1,5 +1,5 @@
import { StrokeColor } from '@blocksuite/affine-model';
import { expect } from '@playwright/test'; import { expect } from '@playwright/test';
import { lightThemeV2 } from '@toeverything/theme/v2';
import { import {
assertEdgelessTool, assertEdgelessTool,
@@ -80,15 +80,14 @@ test('add brush element with color', async ({ page }) => {
await switchEditorMode(page); await switchEditorMode(page);
await setEdgelessTool(page, 'brush'); await setEdgelessTool(page, 'brush');
const color = StrokeColor.Blue; await selectBrushColor(page, 'Blue');
await selectBrushColor(page, color);
const start = { x: 100, y: 100 }; const start = { x: 100, y: 100 };
const end = { x: 200, y: 200 }; const end = { x: 200, y: 200 };
await dragBetweenCoords(page, start, end, { steps: 100 }); await dragBetweenCoords(page, start, end, { steps: 100 });
const [pickedColor] = await pickColorAtPoints(page, [[110, 110]]); const [pickedColor] = await pickColorAtPoints(page, [[110, 110]]);
const color = lightThemeV2['edgeless/palette/medium/blueMedium'];
await assertEdgelessColorSameWithHexColor(page, color, pickedColor); await assertEdgelessColorSameWithHexColor(page, color, pickedColor);
}); });
@@ -101,8 +100,8 @@ 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 = StrokeColor.Blue; await selectBrushColor(page, 'Blue');
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 };
await dragBetweenCoords(page, start, end, { steps: 100 }); await dragBetweenCoords(page, start, end, { steps: 100 });
@@ -113,7 +112,9 @@ test('keep same color when mouse mode switched back to brush', async ({
await setEdgelessTool(page, 'brush'); await setEdgelessTool(page, 'brush');
const origin = { x: 100, y: 100 }; const origin = { x: 100, y: 100 };
await dragBetweenCoords(page, origin, start, { steps: 100 }); await dragBetweenCoords(page, origin, start, { steps: 100 });
const [pickedColor] = await pickColorAtPoints(page, [[110, 110]]); const [pickedColor] = await pickColorAtPoints(page, [[110, 110]]);
const color = lightThemeV2['edgeless/palette/medium/blueMedium'];
await assertEdgelessColorSameWithHexColor(page, color, pickedColor); await assertEdgelessColorSameWithHexColor(page, color, pickedColor);
}); });
@@ -124,8 +125,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 = StrokeColor.Blue; await selectBrushColor(page, 'Blue');
await selectBrushColor(page, color);
const start = { x: 100, y: 100 }; const start = { x: 100, y: 100 };
const end = { x: 200, y: 100 }; const end = { x: 200, y: 100 };
@@ -143,6 +143,7 @@ test('add brush element with different size', async ({ page }) => {
[110, 105], [110, 105],
]); ]);
const color = lightThemeV2['edgeless/palette/medium/blueMedium'];
await assertEdgelessColorSameWithHexColor(page, color, topEdge); await assertEdgelessColorSameWithHexColor(page, color, topEdge);
await assertEdgelessColorSameWithHexColor(page, color, bottomEdge); await assertEdgelessColorSameWithHexColor(page, color, bottomEdge);
assertSameColor(nearTopEdge, '#84cfff'); assertSameColor(nearTopEdge, '#84cfff');
@@ -1,4 +1,3 @@
import { StrokeColor } from '@blocksuite/affine-model';
import { expect } from '@playwright/test'; import { expect } from '@playwright/test';
import { import {
@@ -149,7 +148,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, StrokeColor.Grey); await changeConnectorStrokeColor(page, 'MediumGrey');
await triggerComponentToolbarAction(page, 'changeConnectorStrokeStyles'); await triggerComponentToolbarAction(page, 'changeConnectorStrokeStyles');
await changeConnectorStrokeWidth(page, 5); await changeConnectorStrokeWidth(page, 5);
@@ -174,7 +173,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, StrokeColor.Grey); await changeConnectorStrokeColor(page, 'MediumGrey');
await triggerComponentToolbarAction(page, 'changeConnectorStrokeStyles'); await triggerComponentToolbarAction(page, 'changeConnectorStrokeStyles');
await changeConnectorStrokeStyle(page, 'dash'); await changeConnectorStrokeStyle(page, 'dash');
@@ -59,7 +59,6 @@ test.describe('lock', () => {
test('edgeless element can be locked and unlocked', async ({ page }) => { test('edgeless element can be locked and unlocked', async ({ page }) => {
await edgelessCommonSetup(page); await edgelessCommonSetup(page);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const wrapTest = async <F extends (...args: any) => any>( const wrapTest = async <F extends (...args: any) => any>(
elementCreateFn: F, elementCreateFn: F,
...args: Parameters<F> ...args: Parameters<F>
@@ -4,6 +4,7 @@ import {
NoteDisplayMode, NoteDisplayMode,
} from '@blocksuite/affine-model'; } from '@blocksuite/affine-model';
import { expect } from '@playwright/test'; import { expect } from '@playwright/test';
import { lightThemeV2 } from '@toeverything/theme/v2';
import { import {
activeNoteInEdgeless, activeNoteInEdgeless,
@@ -304,14 +305,17 @@ test('change note color', async ({ page }) => {
await assertEdgelessNoteBackground( await assertEdgelessNoteBackground(
page, page,
noteId, noteId,
'--affine-v2-edgeless-note-white' lightThemeV2['edgeless/note/white']
); );
await selectNoteInEdgeless(page, noteId); await selectNoteInEdgeless(page, noteId);
await triggerComponentToolbarAction(page, 'changeNoteColor'); await triggerComponentToolbarAction(page, 'changeNoteColor');
const color = '--affine-v2-edgeless-note-green'; await changeEdgelessNoteBackground(page, 'Green');
await changeEdgelessNoteBackground(page, color); await assertEdgelessNoteBackground(
await assertEdgelessNoteBackground(page, noteId, color); page,
noteId,
lightThemeV2['edgeless/note/green']
);
}); });
test('cursor for active and inactive state', async ({ page }) => { test('cursor for active and inactive state', async ({ page }) => {
+21 -11
View File
@@ -1,5 +1,5 @@
import { ShapeFillColor, StrokeColor } from '@blocksuite/affine-model';
import { expect, type Page } from '@playwright/test'; import { expect, type Page } from '@playwright/test';
import { lightThemeV2 } from '@toeverything/theme/v2';
import { import {
assertEdgelessTool, assertEdgelessTool,
@@ -168,14 +168,17 @@ 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 = ShapeFillColor.Grey; await changeShapeFillColor(page, 'MediumGrey');
await changeShapeFillColor(page, color);
await page.waitForTimeout(50); await page.waitForTimeout(50);
const [picked] = await pickColorAtPoints(page, [ const [picked] = await pickColorAtPoints(page, [
[rect.start.x + 20, rect.start.y + 20], [rect.start.x + 20, rect.start.y + 20],
]); ]);
await assertEdgelessColorSameWithHexColor(page, color, picked); await assertEdgelessColorSameWithHexColor(
page,
lightThemeV2['edgeless/palette/medium/greyMedium'],
picked
);
}); });
test('change shape stroke color', async ({ page }) => { test('change shape stroke color', async ({ page }) => {
@@ -191,14 +194,17 @@ 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 = StrokeColor.Grey; await changeShapeStrokeColor(page, 'HeavyYellow');
await changeShapeStrokeColor(page, color);
await page.waitForTimeout(50); await page.waitForTimeout(50);
const [picked] = await pickColorAtPoints(page, [ const [picked] = await pickColorAtPoints(page, [
[rect.start.x + 1, rect.start.y + 1], [rect.start.x + 1, rect.start.y + 1],
]); ]);
await assertEdgelessColorSameWithHexColor(page, color, picked); await assertEdgelessColorSameWithHexColor(
page,
lightThemeV2['edgeless/palette/heavy/yellow'],
picked
);
}); });
test('the tooltip of shape tool button should be hidden when the shape menu is shown', async ({ test('the tooltip of shape tool button should be hidden when the shape menu is shown', async ({
@@ -339,7 +345,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, StrokeColor.Magenta); await changeShapeStrokeColor(page, 'MediumMagenta');
await triggerComponentToolbarAction(page, 'changeShapeStrokeStyles'); await triggerComponentToolbarAction(page, 'changeShapeStrokeStyles');
await changeShapeStrokeWidth(page); await changeShapeStrokeWidth(page);
@@ -362,7 +368,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, StrokeColor.Blue); await changeShapeStrokeColor(page, 'MediumBlue');
await triggerComponentToolbarAction(page, 'changeShapeStrokeStyles'); await triggerComponentToolbarAction(page, 'changeShapeStrokeStyles');
await changeShapeStrokeStyle(page, 'dash'); await changeShapeStrokeStyle(page, 'dash');
@@ -549,12 +555,16 @@ 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 = StrokeColor.Purple; const color = 'LightPurple';
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]]);
await assertEdgelessColorSameWithHexColor(page, color, picked); await assertEdgelessColorSameWithHexColor(
page,
lightThemeV2['edgeless/palette/light/purpleLight'],
picked
);
}); });
test('shape adds text by button', async ({ page }) => { test('shape adds text by button', async ({ page }) => {
@@ -251,7 +251,7 @@ test('readonly mode', async ({ page }) => {
throw new Error('Cannot find editor'); throw new Error('Cannot find editor');
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any // oxlint-disable-next-line @typescript-eslint/no-explicit-any
(richTextA as any).inlineEditor.setReadonly(true); (richTextA as any).inlineEditor.setReadonly(true);
}); });
@@ -834,13 +834,13 @@ test('yText should not contain \r', async ({ page }) => {
throw new Error('Cannot find test-rich-text'); throw new Error('Cannot find test-rich-text');
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any // oxlint-disable-next-line @typescript-eslint/no-explicit-any
const editor = (richText as any).inlineEditor as InlineEditor; const editor = (richText as any).inlineEditor as InlineEditor;
try { try {
editor.insertText({ index: 0, length: 0 }, 'abc\r'); editor.insertText({ index: 0, length: 0 }, 'abc\r');
} catch (e) { } catch (e) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // oxlint-disable-next-line @typescript-eslint/no-explicit-any
return (e as any).message; return (e as any).message;
} }
}); });
+1 -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-v2-edgeless-note-white" prop:background="--affine-note-background-blue"
prop:displayMode="both" prop:displayMode="both"
prop:edgeless={ prop:edgeless={
Object { Object {
+2 -1
View File
@@ -11,7 +11,8 @@
"@blocksuite/block-std": "workspace:*", "@blocksuite/block-std": "workspace:*",
"@blocksuite/global": "workspace:*", "@blocksuite/global": "workspace:*",
"@blocksuite/presets": "workspace:*", "@blocksuite/presets": "workspace:*",
"@playwright/test": "=1.49.1" "@playwright/test": "=1.49.1",
"@toeverything/theme": "^1.1.3"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
+2 -2
View File
@@ -885,7 +885,7 @@ test.describe('slash menu with customize menu', () => {
{ groupName: 'Custom Menu' }, { groupName: 'Custom Menu' },
{ {
name: 'Custom Menu Item', name: 'Custom Menu Item',
// eslint-disable-next-line @typescript-eslint/no-explicit-any // oxlint-disable-next-line @typescript-eslint/no-explicit-any
icon: '' as any, icon: '' as any,
action: () => { action: () => {
// do nothing // do nothing
@@ -893,7 +893,7 @@ test.describe('slash menu with customize menu', () => {
}, },
{ {
name: 'Custom Menu Item', name: 'Custom Menu Item',
// eslint-disable-next-line @typescript-eslint/no-explicit-any // oxlint-disable-next-line @typescript-eslint/no-explicit-any
icon: '' as any, icon: '' as any,
action: () => { action: () => {
// do nothing // do nothing
@@ -17,7 +17,10 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-v2-edgeless-note-white", "background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,
@@ -17,7 +17,10 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-v2-edgeless-note-white", "background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,
@@ -17,7 +17,10 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-v2-edgeless-note-white", "background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,
@@ -27,7 +27,10 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,234]", "xywh": "[0,0,498,234]",
"background": "--affine-v2-edgeless-note-white", "background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,
@@ -17,7 +17,10 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-v2-edgeless-note-white", "background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,
@@ -17,7 +17,10 @@
"version": 1, "version": 1,
"props": { "props": {
"xywh": "[0,0,498,92]", "xywh": "[0,0,498,92]",
"background": "--affine-v2-edgeless-note-white", "background": {
"dark": "#000000",
"light": "#ffffff"
},
"index": "a0", "index": "a0",
"lockedBySelf": false, "lockedBySelf": false,
"hidden": false, "hidden": false,
Loaded 100 of 287 files, more files were not shown because too many files have changed in this diff. Show more