mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-24 18:02:47 +08:00
fix(core): add shortcuts to open doc dropdown menu (#11358)
Closes: [BS-2992](https://linear.app/affine-design/issue/BS-2992/走查toolbar上的open-in-button) [Screen Recording 2025-04-01 at 16.37.57.mov <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/8ypiIKZXudF5a0tIgIzf/cf4b1baf-aa2c-4f37-9c62-f7202d0f7c42.mov" />](https://app.graphite.dev/media/video/8ypiIKZXudF5a0tIgIzf/cf4b1baf-aa2c-4f37-9c62-f7202d0f7c42.mov)
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
import {
|
||||
type OpenDocMode,
|
||||
type ToolbarAction,
|
||||
ToolbarContext,
|
||||
} from '@blocksuite/affine-shared/services';
|
||||
import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
|
||||
import { SignalWatcher, WithDisposable } from '@blocksuite/global/lit';
|
||||
import { PropTypes, requiredProperties } from '@blocksuite/std';
|
||||
import type { ReadonlySignal } from '@preact/signals-core';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
import { ifDefined } from 'lit-html/directives/if-defined.js';
|
||||
import { repeat } from 'lit-html/directives/repeat.js';
|
||||
|
||||
import { EditorChevronDown } from '../toolbar';
|
||||
|
||||
@requiredProperties({
|
||||
actions: PropTypes.array,
|
||||
context: PropTypes.instanceOf(ToolbarContext),
|
||||
openDocMode$: PropTypes.object,
|
||||
updateOpenDocMode: PropTypes.instanceOf(Function),
|
||||
})
|
||||
export class OpenDocDropdownMenu extends SignalWatcher(
|
||||
WithDisposable(LitElement)
|
||||
) {
|
||||
static override styles = css`
|
||||
div[data-orientation] {
|
||||
width: 264px;
|
||||
gap: 4px;
|
||||
min-width: unset;
|
||||
overflow: unset;
|
||||
}
|
||||
|
||||
editor-menu-action {
|
||||
.label {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.shortcut {
|
||||
color: ${unsafeCSSVarV2('text/secondary')};
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor actions!: (ToolbarAction & {
|
||||
mode: OpenDocMode;
|
||||
shortcut?: string;
|
||||
})[];
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor context!: ToolbarContext;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor openDocMode$!: ReadonlySignal<OpenDocMode>;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor updateOpenDocMode!: (mode: OpenDocMode) => void;
|
||||
|
||||
override render() {
|
||||
const {
|
||||
actions,
|
||||
context,
|
||||
openDocMode$: { value: openDocMode },
|
||||
updateOpenDocMode,
|
||||
} = this;
|
||||
const currentAction =
|
||||
actions.find(a => a.mode === openDocMode) ?? actions[0];
|
||||
|
||||
return html`
|
||||
<editor-menu-button
|
||||
aria-label="Open doc menu"
|
||||
.contentPadding="${'8px'}"
|
||||
.button=${html`
|
||||
<editor-icon-button
|
||||
data-open-doc-mode="${currentAction.label}"
|
||||
aria-label="Open doc"
|
||||
.tooltip="${'Open doc'}"
|
||||
.justify="${'space-between'}"
|
||||
.labelHeight="${'20px'}"
|
||||
.iconContainerWidth="${'84px'}"
|
||||
>
|
||||
${currentAction.icon}
|
||||
<span class="label">Open</span> ${EditorChevronDown}
|
||||
</editor-icon-button>
|
||||
`}
|
||||
>
|
||||
<div data-orientation="vertical">
|
||||
${repeat(
|
||||
actions,
|
||||
action => action.id,
|
||||
({ label, icon, run, disabled, mode, shortcut }) => html`
|
||||
<editor-menu-action
|
||||
aria-label=${ifDefined(label)}
|
||||
?disabled=${ifDefined(disabled)}
|
||||
@click=${() => {
|
||||
run?.(context);
|
||||
updateOpenDocMode(mode);
|
||||
}}
|
||||
>
|
||||
${icon}
|
||||
<div class="label">
|
||||
${label}
|
||||
<span class="shortcut">${shortcut}</span>
|
||||
</div>
|
||||
</editor-menu-action>
|
||||
`
|
||||
)}
|
||||
</div>
|
||||
</editor-menu-button>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'affine-open-doc-dropdown-menu': OpenDocDropdownMenu;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import { OpenDocDropdownMenu } from './dropdown-menu';
|
||||
|
||||
export * from './dropdown-menu';
|
||||
|
||||
export function effects() {
|
||||
customElements.define('affine-open-doc-dropdown-menu', OpenDocDropdownMenu);
|
||||
}
|
||||
Reference in New Issue
Block a user