feat(editor): add footnote node click handler (#11699)
Close [BS-3114](https://linear.app/affine-design/issue/BS-3114/点击-footnote-node-行为更新)
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import { HoverController } from '@blocksuite/affine-components/hover';
|
import { HoverController } from '@blocksuite/affine-components/hover';
|
||||||
|
import { PeekViewProvider } from '@blocksuite/affine-components/peek';
|
||||||
import type { FootNote } from '@blocksuite/affine-model';
|
import type { FootNote } from '@blocksuite/affine-model';
|
||||||
import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
|
import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
|
||||||
import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
|
import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
|
||||||
@@ -105,8 +106,47 @@ export class AffineFootnoteNode extends WithDisposable(ShadowlessElement) {
|
|||||||
return selfInlineRange;
|
return selfInlineRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get footnote() {
|
||||||
|
return this.delta.attributes?.footnote;
|
||||||
|
}
|
||||||
|
|
||||||
|
onFootnoteClick = () => {
|
||||||
|
if (!this.footnote) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { type, docId, url } = this.footnote.reference;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'doc':
|
||||||
|
if (docId) {
|
||||||
|
this._handleDocReference(docId);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'url':
|
||||||
|
if (url) {
|
||||||
|
this._handleUrlReference(url);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly _handleDocReference = (docId: string) => {
|
||||||
|
this.std
|
||||||
|
.getOptional(PeekViewProvider)
|
||||||
|
?.peek({
|
||||||
|
docId,
|
||||||
|
})
|
||||||
|
.catch(console.error);
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly _handleUrlReference = (url: string) => {
|
||||||
|
window.open(url, '_blank');
|
||||||
|
};
|
||||||
|
|
||||||
private readonly _FootNoteDefaultContent = (footnote: FootNote) => {
|
private readonly _FootNoteDefaultContent = (footnote: FootNote) => {
|
||||||
return html`<span class="footnote-content-default"
|
return html`<span
|
||||||
|
class="footnote-content-default"
|
||||||
|
@click=${this.onFootnoteClick}
|
||||||
>${footnote.label}</span
|
>${footnote.label}</span
|
||||||
>`;
|
>`;
|
||||||
};
|
};
|
||||||
@@ -121,14 +161,14 @@ export class AffineFootnoteNode extends WithDisposable(ShadowlessElement) {
|
|||||||
.footnote=${footnote}
|
.footnote=${footnote}
|
||||||
.std=${this.std}
|
.std=${this.std}
|
||||||
.abortController=${abortController}
|
.abortController=${abortController}
|
||||||
.onPopupClick=${this.onPopupClick}
|
.onPopupClick=${this.onPopupClick ?? this.onFootnoteClick}
|
||||||
></footnote-popup>`;
|
></footnote-popup>`;
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly _whenHover: HoverController = new HoverController(
|
private readonly _whenHover: HoverController = new HoverController(
|
||||||
this,
|
this,
|
||||||
({ abortController }) => {
|
({ abortController }) => {
|
||||||
const footnote = this.delta.attributes?.footnote;
|
const { footnote } = this;
|
||||||
if (!footnote) return null;
|
if (!footnote) return null;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import {
|
|||||||
LightLoadingIcon,
|
LightLoadingIcon,
|
||||||
WebIcon16,
|
WebIcon16,
|
||||||
} from '@blocksuite/affine-components/icons';
|
} from '@blocksuite/affine-components/icons';
|
||||||
import { PeekViewProvider } from '@blocksuite/affine-components/peek';
|
|
||||||
import { ColorScheme, type FootNote } from '@blocksuite/affine-model';
|
import { ColorScheme, type FootNote } from '@blocksuite/affine-model';
|
||||||
import {
|
import {
|
||||||
DocDisplayMetaProvider,
|
DocDisplayMetaProvider,
|
||||||
@@ -127,50 +126,9 @@ export class FootNotePopup extends SignalWatcher(WithDisposable(LitElement)) {
|
|||||||
return theme === ColorScheme.Light ? LightLoadingIcon : DarkLoadingIcon;
|
return theme === ColorScheme.Light ? LightLoadingIcon : DarkLoadingIcon;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* When clicking the chip, we will navigate to the reference doc or open the url
|
|
||||||
*/
|
|
||||||
private readonly _handleDocReference = (docId: string) => {
|
|
||||||
this.std
|
|
||||||
.getOptional(PeekViewProvider)
|
|
||||||
?.peek({
|
|
||||||
docId,
|
|
||||||
})
|
|
||||||
.catch(console.error);
|
|
||||||
};
|
|
||||||
|
|
||||||
private readonly _handleUrlReference = (url: string) => {
|
|
||||||
window.open(url, '_blank');
|
|
||||||
};
|
|
||||||
|
|
||||||
private readonly _handleReference = () => {
|
|
||||||
const { type, docId, url } = this.footnote.reference;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case 'doc':
|
|
||||||
if (docId) {
|
|
||||||
this._handleDocReference(docId);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'url':
|
|
||||||
if (url) {
|
|
||||||
this._handleUrlReference(url);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.abortController.abort();
|
|
||||||
};
|
|
||||||
|
|
||||||
private readonly _onChipClick = () => {
|
private readonly _onChipClick = () => {
|
||||||
// If the onPopupClick is defined, use it
|
this.onPopupClick(this.footnote, this.abortController);
|
||||||
if (this.onPopupClick) {
|
this.abortController.abort();
|
||||||
this.onPopupClick(this.footnote, this.abortController);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, handle the reference by default
|
|
||||||
this._handleReference();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
override connectedCallback() {
|
override connectedCallback() {
|
||||||
@@ -217,5 +175,5 @@ export class FootNotePopup extends SignalWatcher(WithDisposable(LitElement)) {
|
|||||||
accessor abortController!: AbortController;
|
accessor abortController!: AbortController;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor onPopupClick: FootNotePopupClickHandler | undefined = undefined;
|
accessor onPopupClick: FootNotePopupClickHandler | (() => void) = () => {};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user