mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-22 20:46:38 +08:00
1f45cc5dec
**Directory Structure Changes** - Renamed multiple block-related directories by removing the "block-" prefix: - `block-attachment` → `attachment` - `block-bookmark` → `bookmark` - `block-callout` → `callout` - `block-code` → `code` - `block-data-view` → `data-view` - `block-database` → `database` - `block-divider` → `divider` - `block-edgeless-text` → `edgeless-text` - `block-embed` → `embed`
101 lines
2.8 KiB
TypeScript
101 lines
2.8 KiB
TypeScript
import { SignalWatcher, WithDisposable } from '@blocksuite/global/lit';
|
|
import {
|
|
PropTypes,
|
|
requiredProperties,
|
|
ShadowlessElement,
|
|
} from '@blocksuite/std';
|
|
import { html, nothing, type PropertyValues } from 'lit';
|
|
import { property } from 'lit/decorators.js';
|
|
import { repeat } from 'lit/directives/repeat.js';
|
|
|
|
import type {
|
|
KeyboardIconType,
|
|
KeyboardToolbarActionItem,
|
|
KeyboardToolbarContext,
|
|
KeyboardToolPanelConfig,
|
|
KeyboardToolPanelGroup,
|
|
} from './config.js';
|
|
import { keyboardToolPanelStyles } from './styles.js';
|
|
|
|
export const AFFINE_KEYBOARD_TOOL_PANEL = 'affine-keyboard-tool-panel';
|
|
|
|
@requiredProperties({
|
|
context: PropTypes.object,
|
|
})
|
|
export class AffineKeyboardToolPanel extends SignalWatcher(
|
|
WithDisposable(ShadowlessElement)
|
|
) {
|
|
static override styles = keyboardToolPanelStyles;
|
|
|
|
private readonly _handleItemClick = (item: KeyboardToolbarActionItem) => {
|
|
if (item.disableWhen && item.disableWhen(this.context)) return;
|
|
if (item.action) {
|
|
Promise.resolve(item.action(this.context)).catch(console.error);
|
|
}
|
|
};
|
|
|
|
private _renderGroup(group: KeyboardToolPanelGroup) {
|
|
const items = group.items.filter(
|
|
item => item.showWhen?.(this.context) ?? true
|
|
);
|
|
|
|
return html`<div class="keyboard-tool-panel-group">
|
|
<div class="keyboard-tool-panel-group-header">${group.name}</div>
|
|
<div class="keyboard-tool-panel-group-item-container">
|
|
${repeat(
|
|
items,
|
|
item => item.name,
|
|
item => this._renderItem(item)
|
|
)}
|
|
</div>
|
|
</div>`;
|
|
}
|
|
|
|
private _renderIcon(icon: KeyboardIconType) {
|
|
return typeof icon === 'function' ? icon(this.context) : icon;
|
|
}
|
|
|
|
private _renderItem(item: KeyboardToolbarActionItem) {
|
|
return html`<div class="keyboard-tool-panel-item">
|
|
<button @click=${() => this._handleItemClick(item)}>
|
|
${this._renderIcon(item.icon)}
|
|
</button>
|
|
<span>${item.name}</span>
|
|
</div>`;
|
|
}
|
|
|
|
override render() {
|
|
if (!this.config) return nothing;
|
|
|
|
const groups = this.config.groups
|
|
.map(group => (typeof group === 'function' ? group(this.context) : group))
|
|
.filter((group): group is KeyboardToolPanelGroup => group !== null);
|
|
|
|
return repeat(
|
|
groups,
|
|
group => group.name,
|
|
group => this._renderGroup(group)
|
|
);
|
|
}
|
|
|
|
protected override willUpdate(changedProperties: PropertyValues<this>) {
|
|
if (changedProperties.has('height')) {
|
|
this.style.height = `${this.height}px`;
|
|
if (this.height === 0) {
|
|
this.style.padding = '0';
|
|
} else {
|
|
this.style.padding = '';
|
|
}
|
|
}
|
|
}
|
|
|
|
@property({ attribute: false })
|
|
accessor config: KeyboardToolPanelConfig | null = null;
|
|
|
|
@property({ attribute: false })
|
|
accessor context!: KeyboardToolbarContext;
|
|
|
|
@property({ attribute: false })
|
|
accessor height = 0;
|
|
}
|