mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-17 22:37:04 +08:00
feat(editor): gfx connector package (#11091)
This commit is contained in:
65
blocksuite/affine/gfx/shape/src/components/shape-panel.ts
Normal file
65
blocksuite/affine/gfx/shape/src/components/shape-panel.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { ShapeStyle } from '@blocksuite/affine-model';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
import { repeat } from 'lit/directives/repeat.js';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
import type { ShapeTool } from '../shape-tool';
|
||||
import { ShapeComponentConfig } from '../toolbar/shape-menu-config';
|
||||
|
||||
export class EdgelessShapePanel extends LitElement {
|
||||
static override styles = css`
|
||||
:host {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
}
|
||||
`;
|
||||
|
||||
slots = {
|
||||
select: new Subject<ShapeTool['activatedOption']['shapeName']>(),
|
||||
};
|
||||
|
||||
private _onSelect(value: ShapeTool['activatedOption']['shapeName']) {
|
||||
this.selectedShape = value;
|
||||
this.slots.select.next(value);
|
||||
}
|
||||
|
||||
override disconnectedCallback(): void {
|
||||
this.slots.select.complete();
|
||||
super.disconnectedCallback();
|
||||
}
|
||||
|
||||
override render() {
|
||||
return repeat(
|
||||
ShapeComponentConfig,
|
||||
item => item.name,
|
||||
({ name, generalIcon, scribbledIcon, tooltip, disabled }) =>
|
||||
html`<edgeless-tool-icon-button
|
||||
.disabled=${disabled}
|
||||
.tooltip=${tooltip}
|
||||
.active=${this.selectedShape === name}
|
||||
.activeMode=${'background'}
|
||||
.iconSize=${'20px'}
|
||||
@click=${() => {
|
||||
if (disabled) return;
|
||||
this._onSelect(name);
|
||||
}}
|
||||
>
|
||||
${this.shapeStyle === ShapeStyle.General
|
||||
? generalIcon
|
||||
: scribbledIcon}
|
||||
</edgeless-tool-icon-button>`
|
||||
);
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor selectedShape:
|
||||
| ShapeTool['activatedOption']['shapeName']
|
||||
| null
|
||||
| undefined = undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor shapeStyle: ShapeStyle = ShapeStyle.Scribbled;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import { ShapeStyle } from '@blocksuite/affine-model';
|
||||
import { StyleGeneralIcon, StyleScribbleIcon } from '@blocksuite/icons/lit';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
import { repeat } from 'lit/directives/repeat.js';
|
||||
|
||||
const SHAPE_STYLE_LIST = [
|
||||
{
|
||||
value: ShapeStyle.General,
|
||||
icon: StyleGeneralIcon(),
|
||||
},
|
||||
{
|
||||
value: ShapeStyle.Scribbled,
|
||||
icon: StyleScribbleIcon(),
|
||||
},
|
||||
];
|
||||
|
||||
export class EdgelessShapeStylePanel extends LitElement {
|
||||
static override styles = css`
|
||||
:host {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
}
|
||||
`;
|
||||
|
||||
private _onSelect(value: ShapeStyle) {
|
||||
this.value = value;
|
||||
if (this.onSelect) {
|
||||
this.onSelect(value);
|
||||
}
|
||||
}
|
||||
|
||||
override render() {
|
||||
return repeat(
|
||||
SHAPE_STYLE_LIST,
|
||||
item => item.value,
|
||||
({ value, icon }) =>
|
||||
html`<edgeless-tool-icon-button
|
||||
.tipPosition=${'top'}
|
||||
.activeMode=${'background'}
|
||||
aria-label=${value}
|
||||
.tooltip=${value}
|
||||
.active=${this.value === value}
|
||||
.iconSize=${'20px'}
|
||||
@click=${() => this._onSelect(value)}
|
||||
>
|
||||
${icon}
|
||||
</edgeless-tool-icon-button>`
|
||||
);
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor onSelect: undefined | ((value: ShapeStyle) => void) = undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor value!: ShapeStyle;
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import { EdgelessShapePanel } from './components/shape-panel';
|
||||
import { EdgelessShapeStylePanel } from './components/shape-style-panel';
|
||||
import {
|
||||
EdgelessShapeMenu,
|
||||
EdgelessShapeToolButton,
|
||||
@@ -18,6 +20,8 @@ export function effects() {
|
||||
'edgeless-toolbar-shape-draggable',
|
||||
EdgelessToolbarShapeDraggable
|
||||
);
|
||||
customElements.define('edgeless-shape-panel', EdgelessShapePanel);
|
||||
customElements.define('edgeless-shape-style-panel', EdgelessShapeStylePanel);
|
||||
}
|
||||
|
||||
declare global {
|
||||
@@ -27,5 +31,7 @@ declare global {
|
||||
'edgeless-shape-tool-element': EdgelessShapeToolElement;
|
||||
'edgeless-toolbar-shape-draggable': EdgelessToolbarShapeDraggable;
|
||||
'edgeless-shape-tool-button': EdgelessShapeToolButton;
|
||||
'edgeless-shape-panel': EdgelessShapePanel;
|
||||
'edgeless-shape-style-panel': EdgelessShapeStylePanel;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user