refactor(editor): simplify color picker (#10776)

### What's Changed!

* Added `enableCustomColor` property into `EdgelessColorPickerButton` component
* Removed redundant code
This commit is contained in:
fundon
2025-03-12 05:17:04 +00:00
parent 4b5d1de206
commit d823792f85
8 changed files with 236 additions and 525 deletions

View File

@@ -3,10 +3,7 @@ import type {
EdgelessColorPickerButton,
PickColorEvent,
} from '@blocksuite/affine-components/color-picker';
import {
packColor,
packColorsWithColorScheme,
} from '@blocksuite/affine-components/color-picker';
import { packColor } from '@blocksuite/affine-components/color-picker';
import type {
BrushElementModel,
BrushProps,
@@ -18,11 +15,9 @@ import {
resolveColor,
} from '@blocksuite/affine-model';
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
import { WithDisposable } from '@blocksuite/global/lit';
import { html, LitElement, nothing } from 'lit';
import { property, query } from 'lit/decorators.js';
import { when } from 'lit/directives/when.js';
import countBy from 'lodash-es/countBy';
import maxBy from 'lodash-es/maxBy';
@@ -53,11 +48,6 @@ function notEqual<K extends keyof BrushProps>(key: K, value: BrushProps[K]) {
}
export class EdgelessChangeBrushButton extends WithDisposable(LitElement) {
private readonly _setBrushColor = ({ detail }: ColorEvent) => {
const color = detail.value;
this._setBrushProp('color', color);
};
private readonly _setLineWidth = ({ detail: lineWidth }: LineWidthEvent) => {
this._setBrushProp('lineWidth', lineWidth);
};
@@ -112,6 +102,9 @@ export class EdgelessChangeBrushButton extends WithDisposable(LitElement) {
const elements = this.elements;
const selectedColor = getMostCommonColor(elements, colorScheme);
const selectedSize = getMostCommonSize(elements);
const enableCustomColor = this.edgeless.doc
.get(FeatureFlagService)
.getFlag('enable_color_picker');
return html`
<edgeless-line-width-panel
@@ -122,50 +115,16 @@ export class EdgelessChangeBrushButton extends WithDisposable(LitElement) {
<editor-toolbar-separator></editor-toolbar-separator>
${when(
this.edgeless.doc
.get(FeatureFlagService)
.getFlag('enable_color_picker'),
() => {
const { type, colors } = packColorsWithColorScheme(
colorScheme,
selectedColor,
elements[0].color
);
return html`
<edgeless-color-picker-button
class="color"
.label="${'Color'}"
.pick=${this.pickColor}
.color=${selectedColor}
.colors=${colors}
.colorType=${type}
.theme=${colorScheme}
>
</edgeless-color-picker-button>
`;
},
() => html`
<editor-menu-button
.contentPadding=${'8px'}
.button=${html`
<editor-icon-button aria-label="Color" .tooltip=${'Color'}>
<edgeless-color-button
.color=${selectedColor}
></edgeless-color-button>
</editor-icon-button>
`}
>
<edgeless-color-panel
.value=${selectedColor}
.theme=${colorScheme}
@select=${this._setBrushColor}
>
</edgeless-color-panel>
</editor-menu-button>
`
)}
<edgeless-color-picker-button
class="color"
.label="${'Color'}"
.pick=${this.pickColor}
.color=${selectedColor}
.theme=${colorScheme}
.originalColor=${elements[0].color}
.enableCustomColor=${enableCustomColor}
>
</edgeless-color-picker-button>
`;
}

View File

@@ -3,10 +3,7 @@ import type {
EdgelessColorPickerButton,
PickColorEvent,
} from '@blocksuite/affine-components/color-picker';
import {
packColor,
packColorsWithColorScheme,
} from '@blocksuite/affine-components/color-picker';
import { packColor } from '@blocksuite/affine-components/color-picker';
import { renderToolbarSeparator } from '@blocksuite/affine-components/toolbar';
import {
type ColorScheme,
@@ -24,7 +21,6 @@ import {
StrokeStyle,
} from '@blocksuite/affine-model';
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
import { WithDisposable } from '@blocksuite/global/lit';
import {
AddTextIcon,
@@ -50,7 +46,6 @@ import { choose } from 'lit/directives/choose.js';
import { join } from 'lit/directives/join.js';
import { repeat } from 'lit/directives/repeat.js';
import { styleMap } from 'lit/directives/style-map.js';
import { when } from 'lit/directives/when.js';
import countBy from 'lodash-es/countBy';
import maxBy from 'lodash-es/maxBy';
@@ -232,11 +227,6 @@ export class EdgelessChangeConnectorButton extends WithDisposable(LitElement) {
return this.edgeless.std.get(EdgelessCRUDIdentifier);
}
private readonly _setConnectorColor = (e: ColorEvent) => {
const stroke = e.detail.value;
this._setConnectorProp('stroke', stroke);
};
private readonly _setConnectorStroke = ({ type, value }: LineStyleEvent) => {
if (type === 'size') {
this._setConnectorStrokeWidth(value);
@@ -358,81 +348,45 @@ export class EdgelessChangeConnectorButton extends WithDisposable(LitElement) {
ConnectorEndpoint.Rear,
DEFAULT_REAR_END_POINT_STYLE
);
const enableCustomColor = this.edgeless.doc
.get(FeatureFlagService)
.getFlag('enable_color_picker');
return join(
[
when(
this.edgeless.doc
.get(FeatureFlagService)
.getFlag('enable_color_picker'),
() => {
const { type, colors } = packColorsWithColorScheme(
colorScheme,
selectedColor,
elements[0].stroke
);
return html`
<edgeless-color-picker-button
class="stroke-color"
.label="${'Stroke style'}"
.pick=${this.pickColor}
.color=${selectedColor}
.colors=${colors}
.colorType=${type}
.theme=${colorScheme}
.hollowCircle=${true}
>
<div
slot="other"
class="line-styles"
style=${styleMap({
display: 'flex',
flexDirection: 'row',
gap: '8px',
alignItems: 'center',
})}
>
${LineStylesPanel({
selectedLineSize: selectedLineSize,
selectedLineStyle: selectedLineStyle,
onClick: this._setConnectorStroke,
})}
</div>
<editor-toolbar-separator
slot="separator"
data-orientation="horizontal"
></editor-toolbar-separator>
</edgeless-color-picker-button>
`;
},
() => html`
<editor-menu-button
.contentPadding=${'8px'}
.button=${html`
<editor-icon-button
aria-label="Stroke style"
.tooltip=${'Stroke style'}
.iconSize=${'20px'}
>
<edgeless-color-button
.color=${selectedColor}
></edgeless-color-button>
</editor-icon-button>
`}
html`
<edgeless-color-picker-button
class="stroke-color"
.label="${'Stroke style'}"
.pick=${this.pickColor}
.color=${selectedColor}
.theme=${colorScheme}
.hollowCircle=${true}
.originalColor=${elements[0].stroke}
.enableCustomColor=${enableCustomColor}
>
<div
slot="other"
class="line-styles"
style=${styleMap({
display: 'flex',
flexDirection: 'row',
gap: '8px',
alignItems: 'center',
})}
>
<stroke-style-panel
.theme=${colorScheme}
.strokeWidth=${selectedLineSize}
.strokeStyle=${selectedLineStyle}
.strokeColor=${selectedColor}
.setStrokeStyle=${this._setConnectorStroke}
.setStrokeColor=${this._setConnectorColor}
>
</stroke-style-panel>
</editor-menu-button>
`
),
${LineStylesPanel({
selectedLineSize: selectedLineSize,
selectedLineStyle: selectedLineStyle,
onClick: this._setConnectorStroke,
})}
</div>
<editor-toolbar-separator
slot="separator"
data-orientation="horizontal"
></editor-toolbar-separator>
</edgeless-color-picker-button>
`,
html`
<editor-menu-button

View File

@@ -4,10 +4,7 @@ import type {
EdgelessColorPickerButton,
PickColorEvent,
} from '@blocksuite/affine-components/color-picker';
import {
packColor,
packColorsWithColorScheme,
} from '@blocksuite/affine-components/color-picker';
import { packColor } from '@blocksuite/affine-components/color-picker';
import { toast } from '@blocksuite/affine-components/toast';
import { renderToolbarSeparator } from '@blocksuite/affine-components/toolbar';
import {
@@ -19,7 +16,6 @@ import {
resolveColor,
} from '@blocksuite/affine-model';
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
import { matchModels } from '@blocksuite/affine-shared/utils';
import { GfxExtensionIdentifier } from '@blocksuite/block-std/gfx';
import { deserializeXYWH, serializeXYWH } from '@blocksuite/global/gfx';
@@ -28,7 +24,6 @@ import { EditIcon, PageIcon, UngroupIcon } from '@blocksuite/icons/lit';
import { html, LitElement, nothing } from 'lit';
import { property, query } from 'lit/decorators.js';
import { join } from 'lit/directives/join.js';
import { when } from 'lit/directives/when.js';
import countBy from 'lodash-es/countBy';
import maxBy from 'lodash-es/maxBy';
@@ -51,13 +46,6 @@ export class EdgelessChangeFrameButton extends WithDisposable(LitElement) {
return this.edgeless.std.get(EdgelessCRUDIdentifier);
}
private readonly _setFrameBackground = (e: ColorEvent) => {
const background = e.detail.value;
this.frames.forEach(frame => {
this.crud.updateElement(frame.id, { background });
});
};
pickColor = (e: PickColorEvent) => {
const field = 'background';
@@ -128,6 +116,9 @@ export class EdgelessChangeFrameButton extends WithDisposable(LitElement) {
const onlyOne = len === 1;
const colorScheme = this.edgeless.surface.renderer.getColorScheme();
const background = getMostCommonColor(frames, colorScheme);
const enableCustomColor = this.edgeless.doc
.get(FeatureFlagService)
.getFlag('enable_color_picker');
return join(
[
@@ -183,53 +174,18 @@ export class EdgelessChangeFrameButton extends WithDisposable(LitElement) {
</editor-icon-button>
`,
when(
this.edgeless.doc
.get(FeatureFlagService)
.getFlag('enable_color_picker'),
() => {
const { type, colors } = packColorsWithColorScheme(
colorScheme,
background,
this.frames[0].background
);
return html`
<edgeless-color-picker-button
class="background"
.label="${'Background'}"
.pick=${this.pickColor}
.color=${background}
.colors=${colors}
.colorType=${type}
.theme=${colorScheme}
>
</edgeless-color-picker-button>
`;
},
() => html`
<editor-menu-button
.contentPadding=${'8px'}
.button=${html`
<editor-icon-button
aria-label="Background"
.tooltip=${'Background'}
>
<edgeless-color-button
.color=${background}
></edgeless-color-button>
</editor-icon-button>
`}
>
<edgeless-color-panel
.value=${background}
.theme=${colorScheme}
@select=${this._setFrameBackground}
>
</edgeless-color-panel>
</editor-menu-button>
`
),
html`
<edgeless-color-picker-button
class="background"
.label="${'Background'}"
.pick=${this.pickColor}
.color=${background}
.theme=${colorScheme}
.originalColor=${this.frames[0].background}
.enableCustomColor=${enableCustomColor}
>
</edgeless-color-picker-button>
`,
].filter(button => button !== nothing),
renderToolbarSeparator
);

View File

@@ -7,10 +7,7 @@ import type {
EdgelessColorPickerButton,
PickColorEvent,
} from '@blocksuite/affine-components/color-picker';
import {
packColor,
packColorsWithColorScheme,
} from '@blocksuite/affine-components/color-picker';
import { packColor } from '@blocksuite/affine-components/color-picker';
import {
type EditorMenuButton,
renderToolbarSeparator,
@@ -46,7 +43,6 @@ import { html, LitElement, nothing, type TemplateResult } from 'lit';
import { property, query } from 'lit/decorators.js';
import { join } from 'lit/directives/join.js';
import { createRef, type Ref, ref } from 'lit/directives/ref.js';
import { when } from 'lit/directives/when.js';
import countBy from 'lodash-es/countBy';
import maxBy from 'lodash-es/maxBy';
@@ -90,12 +86,6 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
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) => {
this.notes.forEach(note => {
const props = {
@@ -348,6 +338,10 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
NoteConfigExtension.identifier
)?.edgelessNoteHeader;
const enableCustomColor = this.edgeless.doc
.get(FeatureFlagService)
.getFlag('enable_color_picker');
const theme = this.edgeless.std.get(ThemeProvider).theme;
const buttonIconSize = { width: '20px', height: '20px' };
const buttons = [
@@ -403,57 +397,20 @@ export class EdgelessChangeNoteButton extends WithDisposable(LitElement) {
isDocOnly
? nothing
: when(
this.edgeless.doc
.get(FeatureFlagService)
.getFlag('enable_color_picker'),
() => {
const { type, colors } = packColorsWithColorScheme(
colorScheme,
background,
note.background
);
return html`
<edgeless-color-picker-button
class="background"
.label=${'Background'}
.pick=${this.pickColor}
.color=${background}
.colorPanelClass=${'small'}
.colorType=${type}
.colors=${colors}
.theme=${colorScheme}
.palettes=${DefaultTheme.NoteBackgroundColorPalettes}
>
</edgeless-color-picker-button>
`;
},
() => html`
<editor-menu-button
.contentPadding=${'8px'}
.button=${html`
<editor-icon-button
aria-label="Background"
.tooltip=${'Background'}
>
<edgeless-color-button
.color=${background}
></edgeless-color-button>
</editor-icon-button>
`}
>
<edgeless-color-panel
class="small"
.value=${background}
.theme=${colorScheme}
.palettes=${DefaultTheme.NoteBackgroundColorPalettes}
@select=${this._setBackground}
>
</edgeless-color-panel>
</editor-menu-button>
`
),
: html`
<edgeless-color-picker-button
class="background"
.label=${'Background'}
.pick=${this.pickColor}
.color=${background}
.colorPanelClass=${'small'}
.theme=${colorScheme}
.palettes=${DefaultTheme.NoteBackgroundColorPalettes}
.originalColor=${note.background}
.enableCustomColor=${enableCustomColor}
>
</edgeless-color-picker-button>
`,
isDocOnly
? nothing

View File

@@ -3,10 +3,7 @@ import type {
EdgelessColorPickerButton,
PickColorEvent,
} from '@blocksuite/affine-components/color-picker';
import {
packColor,
packColorsWithColorScheme,
} from '@blocksuite/affine-components/color-picker';
import { packColor } from '@blocksuite/affine-components/color-picker';
import { renderToolbarSeparator } from '@blocksuite/affine-components/toolbar';
import type {
Color,
@@ -28,7 +25,6 @@ import {
StrokeStyle,
} from '@blocksuite/affine-model';
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
import { WithDisposable } from '@blocksuite/global/lit';
import {
AddTextIcon,
@@ -42,7 +38,6 @@ import { cache } from 'lit/directives/cache.js';
import { choose } from 'lit/directives/choose.js';
import { join } from 'lit/directives/join.js';
import { styleMap } from 'lit/directives/style-map.js';
import { when } from 'lit/directives/when.js';
import countBy from 'lodash-es/countBy';
import isEqual from 'lodash-es/isEqual';
import maxBy from 'lodash-es/maxBy';
@@ -143,22 +138,6 @@ function getMostCommonShapeStyle(elements: ShapeElementModel[]): ShapeStyle {
export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
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);
@@ -191,10 +170,15 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
return DefaultTheme.white;
} else if (isEqual(fillColor, DefaultTheme.white)) {
return DefaultTheme.black;
} else if (isEqual(fillColor, DefaultTheme.pureBlack)) {
return DefaultTheme.pureWhite;
} else if (isEqual(fillColor, DefaultTheme.pureWhite)) {
return DefaultTheme.pureBlack;
}
}
return DefaultTheme.black;
// aka `DefaultTheme.pureBlack`
return DefaultTheme.shapeTextColor;
}
private _setShapeStrokeStyle(strokeStyle: StrokeStyle) {
@@ -249,12 +233,14 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
) {
return (e: PickColorEvent) => {
if (e.type === 'pick') {
const color = e.detail.value;
const value = e.detail.value;
const filled = field === 'fillColor' && !isTransparent(value);
this.elements.forEach(ele => {
const props = packColor(field, color);
const props = packColor(field, value);
// If `filled` can be set separately, this logic can be removed
if (field === 'fillColor' && !ele.filled) {
Object.assign(props, { filled: true });
if (field && !ele.filled) {
const color = this._getTextColor(value, filled);
Object.assign(props, { filled, color });
}
this.crud.updateElement(ele.id, props);
});
@@ -277,6 +263,9 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
const selectedLineStyle = getMostCommonLineStyle(elements);
const selectedShapeStyle = getMostCommonShapeStyle(elements);
const iconSize = { width: '20px', height: '20px' };
const enableCustomColor = this.edgeless.doc
.get(FeatureFlagService)
.getFlag('enable_color_picker');
return join(
[
@@ -320,129 +309,52 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
</editor-menu-button>
`,
when(
this.edgeless.doc
.get(FeatureFlagService)
.getFlag('enable_color_picker'),
() => {
const { type, colors } = packColorsWithColorScheme(
colorScheme,
selectedFillColor,
elements[0].fillColor
);
html`
<edgeless-color-picker-button
class="fill-color"
.label="${'Fill color'}"
.pick=${this.pickColor('fillColor')}
.color=${selectedFillColor}
.theme=${colorScheme}
.originalColor=${elements[0].fillColor}
.enableCustomColor=${enableCustomColor}
>
</edgeless-color-picker-button>
`,
return html`
<edgeless-color-picker-button
class="fill-color"
.label=${'Fill color'}
.pick=${this.pickColor('fillColor')}
.color=${selectedFillColor}
.colors=${colors}
.colorType=${type}
.theme=${colorScheme}
>
</edgeless-color-picker-button>
`;
},
() => html`
<editor-menu-button
.contentPadding=${'8px'}
.button=${html`
<editor-icon-button
aria-label="Fill color"
.tooltip=${'Fill color'}
>
<edgeless-color-button
.color=${selectedFillColor}
></edgeless-color-button>
</editor-icon-button>
`}
html`
<edgeless-color-picker-button
class="border-style"
.label="${'Border style'}"
.pick=${this.pickColor('strokeColor')}
.color=${selectedStrokeColor}
.theme=${colorScheme}
.hollowCircle=${true}
.originalColor=${elements[0].strokeColor}
.enableCustomColor=${enableCustomColor}
>
<div
slot="other"
class="line-styles"
style=${styleMap({
display: 'flex',
flexDirection: 'row',
gap: '8px',
alignItems: 'center',
})}
>
<edgeless-color-panel
role="listbox"
aria-label="Fill colors"
.value=${selectedFillColor}
.theme=${colorScheme}
@select=${this._setShapeFillColor}
>
</edgeless-color-panel>
</editor-menu-button>
`
),
when(
this.edgeless.doc
.get(FeatureFlagService)
.getFlag('enable_color_picker'),
() => {
const { type, colors } = packColorsWithColorScheme(
colorScheme,
selectedStrokeColor,
elements[0].strokeColor
);
return html`
<edgeless-color-picker-button
class="border-style"
.label=${'Border style'}
.pick=${this.pickColor('strokeColor')}
.color=${selectedStrokeColor}
.colors=${colors}
.colorType=${type}
.theme=${colorScheme}
.hollowCircle=${true}
>
<div
slot="other"
class="line-styles"
style=${styleMap({
display: 'flex',
flexDirection: 'row',
gap: '8px',
alignItems: 'center',
})}
>
${LineStylesPanel({
selectedLineSize: selectedLineSize,
selectedLineStyle: selectedLineStyle,
onClick: this._setShapeStyles,
})}
</div>
<editor-toolbar-separator
slot="separator"
data-orientation="horizontal"
></editor-toolbar-separator>
</edgeless-color-picker-button>
`;
},
() => html`
<editor-menu-button
.contentPadding=${'8px'}
.button=${html`
<editor-icon-button
aria-label="Border style"
.tooltip=${'Border style'}
>
<edgeless-color-button
.color=${selectedStrokeColor}
.hollowCircle=${true}
></edgeless-color-button>
</editor-icon-button>
`}
>
<stroke-style-panel
.theme=${colorScheme}
.hollowCircle=${true}
.strokeWidth=${selectedLineSize}
.strokeStyle=${selectedLineStyle}
.strokeColor=${selectedStrokeColor}
.setStrokeStyle=${this._setShapeStyles}
.setStrokeColor=${this._setShapeStrokeColor}
>
</stroke-style-panel>
</editor-menu-button>
`
),
${LineStylesPanel({
selectedLineSize: selectedLineSize,
selectedLineStyle: selectedLineStyle,
onClick: this._setShapeStyles,
})}
</div>
<editor-toolbar-separator
slot="separator"
data-orientation="horizontal"
></editor-toolbar-separator>
</edgeless-color-picker-button>
`,
choose<string, TemplateResult<1> | typeof nothing>(
this._showAddButtonOrTextMenu(),

View File

@@ -8,10 +8,7 @@ import type {
EdgelessColorPickerButton,
PickColorEvent,
} from '@blocksuite/affine-components/color-picker';
import {
packColor,
packColorsWithColorScheme,
} from '@blocksuite/affine-components/color-picker';
import { packColor } from '@blocksuite/affine-components/color-picker';
import { renderToolbarSeparator } from '@blocksuite/affine-components/toolbar';
import {
type ColorScheme,
@@ -30,7 +27,6 @@ import {
type TextStyleProps,
} from '@blocksuite/affine-model';
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
import { Bound } from '@blocksuite/global/gfx';
import { WithDisposable } from '@blocksuite/global/lit';
import {
@@ -42,7 +38,6 @@ import { css, html, LitElement, nothing, type TemplateResult } from 'lit';
import { property, query } from 'lit/decorators.js';
import { choose } from 'lit/directives/choose.js';
import { join } from 'lit/directives/join.js';
import { when } from 'lit/directives/when.js';
import countBy from 'lodash-es/countBy';
import maxBy from 'lodash-es/maxBy';
@@ -229,14 +224,6 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
});
};
private readonly _setTextColor = (e: ColorEvent) => {
const color = e.detail.value;
const props = { color };
this.elements.forEach(element => {
this.crud.updateElement(element.id, buildProps(element, props));
});
};
private readonly _updateElementBound = (element: SurfaceTextModel) => {
const elementType = this.elementType;
if (elementType === 'text' && element instanceof TextElementModel) {
@@ -346,6 +333,9 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
this.elementType === 'shape'
? DefaultTheme.ShapeTextColorPalettes
: DefaultTheme.Palettes;
const enableCustomColor = this.edgeless.doc
.get(FeatureFlagService)
.getFlag('enable_color_picker');
return join(
[
@@ -375,57 +365,22 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
</editor-menu-button>
`,
when(
this.edgeless.doc
.get(FeatureFlagService)
.getFlag('enable_color_picker'),
() => {
const { type, colors } = packColorsWithColorScheme(
colorScheme,
selectedColor,
elements[0] instanceof ConnectorElementModel
? elements[0].labelStyle.color
: elements[0].color
);
return html`
<edgeless-color-picker-button
class="text-color"
.label="${'Text color'}"
.pick=${this.pickColor}
.isText=${true}
.color=${selectedColor}
.colors=${colors}
.colorType=${type}
.theme=${colorScheme}
.palettes=${palettes}
>
</edgeless-color-picker-button>
`;
},
() => html`
<editor-menu-button
.contentPadding=${'8px'}
.button=${html`
<editor-icon-button
aria-label="Text color"
.tooltip=${'Text color'}
>
<edgeless-text-color-icon
.color=${selectedColor}
></edgeless-text-color-icon>
</editor-icon-button>
`}
>
<edgeless-color-panel
.value=${selectedColor}
.theme=${colorScheme}
.palettes=${palettes}
@select=${this._setTextColor}
></edgeless-color-panel>
</editor-menu-button>
`
),
html`
<edgeless-color-picker-button
class="text-color"
.label="${'Text color'}"
.pick=${this.pickColor}
.isText=${true}
.color=${selectedColor}
.originalColor=${elements[0] instanceof ConnectorElementModel
? elements[0].labelStyle.color
: elements[0].color}
.theme=${colorScheme}
.palettes=${palettes}
.enableCustomColor=${enableCustomColor}
>
</edgeless-color-picker-button>
`,
html`
<editor-menu-button

View File

@@ -1,4 +1,4 @@
import type { ColorScheme, Palette } from '@blocksuite/affine-model';
import type { Color, ColorScheme, Palette } from '@blocksuite/affine-model';
import { DefaultTheme, resolveColor } from '@blocksuite/affine-model';
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
import { WithDisposable } from '@blocksuite/global/lit';
@@ -7,23 +7,28 @@ import { property, query, state } from 'lit/decorators.js';
import { choose } from 'lit/directives/choose.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { styleMap } from 'lit/directives/style-map.js';
import { when } from 'lit-html/directives/when.js';
import type { EditorMenuButton } from '../toolbar/menu-button.js';
import type { ModeType, PickColorEvent, PickColorType } from './types.js';
import { keepColor, preprocessColor, rgbaToHex8 } from './utils.js';
import type { EditorMenuButton } from '../toolbar/menu-button';
import type { PickColorEvent } from './types';
import {
keepColor,
packColorsWithColorScheme,
preprocessColor,
rgbaToHex8,
} from './utils.js';
type Type = 'normal' | 'custom';
export class EdgelessColorPickerButton extends WithDisposable(LitElement) {
readonly #select = (e: ColorEvent) => {
e.stopPropagation();
this.#pick(e.detail);
};
switchToCustomTab = (e: MouseEvent) => {
e.stopPropagation();
if (this.colorType === 'palette') {
this.colorType = 'normal';
}
this.tabType = 'custom';
// refresh menu's position
this.menuButton.show(true);
@@ -82,12 +87,16 @@ export class EdgelessColorPickerButton extends WithDisposable(LitElement) {
}
override firstUpdated() {
this.disposables.addFromEvent(this.menuButton, 'toggle', (e: Event) => {
const opened = (e as CustomEvent<boolean>).detail;
if (!opened && this.tabType !== 'normal') {
this.tabType = 'normal';
this.disposables.addFromEvent(
this.menuButton,
'toggle',
(e: CustomEvent<boolean>) => {
const opened = e.detail;
if (!opened && this.tabType !== 'normal') {
this.tabType = 'normal';
}
}
});
);
}
override render() {
@@ -99,18 +108,20 @@ export class EdgelessColorPickerButton extends WithDisposable(LitElement) {
aria-label=${this.label}
.tooltip=${this.tooltip || this.label}
>
${this.isText
? html`
<edgeless-text-color-icon
.color=${this.colorWithoutAlpha}
></edgeless-text-color-icon>
`
: html`
<edgeless-color-button
.color=${this.colorWithoutAlpha}
.hollowCircle=${this.hollowCircle}
></edgeless-color-button>
`}
${when(
this.isText,
() => html`
<edgeless-text-color-icon
.color=${this.colorWithoutAlpha}
></edgeless-text-color-icon>
`,
() => html`
<edgeless-color-button
.color=${this.colorWithoutAlpha}
.hollowCircle=${this.hollowCircle}
></edgeless-color-button>
`
)}
</editor-icon-button>
`}
>
@@ -128,53 +139,60 @@ export class EdgelessColorPickerButton extends WithDisposable(LitElement) {
.theme=${this.theme}
.palettes=${this.palettes}
.hollowCircle=${this.hollowCircle}
.openColorPicker=${this.switchToCustomTab}
.hasTransparent=${false}
@select=${this.#select}
>
<edgeless-color-custom-button
slot="custom"
style=${styleMap(this.customButtonStyle)}
?active=${this.isCustomColor}
@click=${this.switchToCustomTab}
></edgeless-color-custom-button>
${when(
this.enableCustomColor,
() => html`
<edgeless-color-custom-button
slot="custom"
style=${styleMap(this.customButtonStyle)}
?active=${this.isCustomColor}
@click=${this.switchToCustomTab}
></edgeless-color-custom-button>
`
)}
</edgeless-color-panel>
</div>
`,
],
[
'custom',
() => html`
<edgeless-color-picker
class="custom"
.pick=${this.pick}
.colors=${{
type:
this.colorType === 'palette' ? 'normal' : this.colorType,
modes: this.colors.map(
preprocessColor(window.getComputedStyle(this))
),
}}
></edgeless-color-picker>
`,
() => {
const packed = packColorsWithColorScheme(
this.theme,
this.color,
this.originalColor
);
const type = packed.type === 'palette' ? 'normal' : packed.type;
const modes = packed.colors.map(
preprocessColor(window.getComputedStyle(this))
);
return html`
<edgeless-color-picker
class="custom"
.pick=${this.pick}
.colors=${{ type, modes }}
></edgeless-color-picker>
`;
},
],
])}
</editor-menu-button>
`;
}
@property()
accessor originalColor!: Color;
@property()
accessor color!: string;
@property()
accessor colorPanelClass: string | undefined = undefined;
@property({ attribute: false })
accessor colors: { type: ModeType; value: string }[] = [];
@property()
accessor colorType: PickColorType = 'palette';
@property({ attribute: false })
accessor hollowCircle: boolean = false;
@@ -201,4 +219,7 @@ export class EdgelessColorPickerButton extends WithDisposable(LitElement) {
@property()
accessor tooltip: string | undefined = undefined;
@property()
accessor enableCustomColor: boolean = true;
}

View File

@@ -253,9 +253,6 @@ export class EdgelessColorPanel extends LitElement {
@property({ attribute: false })
accessor hollowCircle = false;
@property()
accessor openColorPicker!: (e: MouseEvent) => void;
@property({ type: Array })
accessor palettes: readonly Palette[] = DefaultTheme.Palettes;