feat(editor): update footnote node style and config (#10392)
[BS-2581](https://linear.app/affine-design/issue/BS-2581/优化-footnote-node-正文样式)
This commit is contained in:
@@ -25,6 +25,7 @@ export interface FootNoteNodeConfig {
|
|||||||
customPopupRenderer?: FootNotePopupRenderer;
|
customPopupRenderer?: FootNotePopupRenderer;
|
||||||
interactive?: boolean;
|
interactive?: boolean;
|
||||||
hidePopup?: boolean;
|
hidePopup?: boolean;
|
||||||
|
disableHoverEffect?: boolean;
|
||||||
onPopupClick?: FootNotePopupClickHandler;
|
onPopupClick?: FootNotePopupClickHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +34,9 @@ export class FootNoteNodeConfigProvider {
|
|||||||
private _customPopupRenderer?: FootNotePopupRenderer;
|
private _customPopupRenderer?: FootNotePopupRenderer;
|
||||||
private _hidePopup: boolean;
|
private _hidePopup: boolean;
|
||||||
private _interactive: boolean;
|
private _interactive: boolean;
|
||||||
|
private _disableHoverEffect: boolean;
|
||||||
private _onPopupClick?: FootNotePopupClickHandler;
|
private _onPopupClick?: FootNotePopupClickHandler;
|
||||||
|
|
||||||
get customNodeRenderer() {
|
get customNodeRenderer() {
|
||||||
return this._customNodeRenderer;
|
return this._customNodeRenderer;
|
||||||
}
|
}
|
||||||
@@ -58,6 +61,10 @@ export class FootNoteNodeConfigProvider {
|
|||||||
return this._interactive;
|
return this._interactive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get disableHoverEffect() {
|
||||||
|
return this._disableHoverEffect;
|
||||||
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
config: FootNoteNodeConfig,
|
config: FootNoteNodeConfig,
|
||||||
readonly std: BlockStdScope
|
readonly std: BlockStdScope
|
||||||
@@ -66,6 +73,7 @@ export class FootNoteNodeConfigProvider {
|
|||||||
this._customPopupRenderer = config.customPopupRenderer;
|
this._customPopupRenderer = config.customPopupRenderer;
|
||||||
this._hidePopup = config.hidePopup ?? false;
|
this._hidePopup = config.hidePopup ?? false;
|
||||||
this._interactive = config.interactive ?? true;
|
this._interactive = config.interactive ?? true;
|
||||||
|
this._disableHoverEffect = config.disableHoverEffect ?? false;
|
||||||
this._onPopupClick = config.onPopupClick;
|
this._onPopupClick = config.onPopupClick;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,6 +93,10 @@ export class FootNoteNodeConfigProvider {
|
|||||||
this._interactive = interactive;
|
this._interactive = interactive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setDisableHoverEffect(disableHoverEffect: boolean) {
|
||||||
|
this._disableHoverEffect = disableHoverEffect;
|
||||||
|
}
|
||||||
|
|
||||||
setPopupClick(onPopupClick: FootNotePopupClickHandler) {
|
setPopupClick(onPopupClick: FootNotePopupClickHandler) {
|
||||||
this._onPopupClick = onPopupClick;
|
this._onPopupClick = onPopupClick;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import { shift } from '@floating-ui/dom';
|
|||||||
import { baseTheme } from '@toeverything/theme';
|
import { baseTheme } from '@toeverything/theme';
|
||||||
import { css, html, nothing, unsafeCSS } from 'lit';
|
import { css, html, nothing, unsafeCSS } from 'lit';
|
||||||
import { property } from 'lit/decorators.js';
|
import { property } from 'lit/decorators.js';
|
||||||
|
import { classMap } from 'lit-html/directives/class-map.js';
|
||||||
import { ref } from 'lit-html/directives/ref.js';
|
import { ref } from 'lit-html/directives/ref.js';
|
||||||
|
|
||||||
import { HoverController } from '../../../../../hover/controller';
|
import { HoverController } from '../../../../../hover/controller';
|
||||||
@@ -37,7 +38,7 @@ export class AffineFootnoteNode extends WithDisposable(ShadowlessElement) {
|
|||||||
|
|
||||||
.footnote-content-default {
|
.footnote-content-default {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background: ${unsafeCSSVarV2('button/primary')};
|
background: ${unsafeCSSVarV2('block/footnote/numberBgHover')};
|
||||||
color: ${unsafeCSSVarV2('button/pureWhiteText')};
|
color: ${unsafeCSSVarV2('button/pureWhiteText')};
|
||||||
width: 14px;
|
width: 14px;
|
||||||
height: 14px;
|
height: 14px;
|
||||||
@@ -48,6 +49,21 @@ export class AffineFootnoteNode extends WithDisposable(ShadowlessElement) {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
font-family: ${unsafeCSS(baseTheme.fontSansFamily)};
|
font-family: ${unsafeCSS(baseTheme.fontSansFamily)};
|
||||||
|
transition: background 0.3s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footnote-node.hover-effect {
|
||||||
|
.footnote-content-default {
|
||||||
|
color: var(--affine-text-primary-color);
|
||||||
|
background: ${unsafeCSSVarV2('block/footnote/numberBg')};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footnote-node.hover-effect:hover {
|
||||||
|
.footnote-content-default {
|
||||||
|
color: ${unsafeCSSVarV2('button/pureWhiteText')};
|
||||||
|
background: ${unsafeCSSVarV2('block/footnote/numberBgHover')};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -67,6 +83,10 @@ export class AffineFootnoteNode extends WithDisposable(ShadowlessElement) {
|
|||||||
return this.config?.hidePopup;
|
return this.config?.hidePopup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get disableHoverEffect() {
|
||||||
|
return this.config?.disableHoverEffect;
|
||||||
|
}
|
||||||
|
|
||||||
get onPopupClick() {
|
get onPopupClick() {
|
||||||
return this.config?.onPopupClick;
|
return this.config?.onPopupClick;
|
||||||
}
|
}
|
||||||
@@ -142,7 +162,7 @@ export class AffineFootnoteNode extends WithDisposable(ShadowlessElement) {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
{ enterDelay: 500 }
|
{ enterDelay: 300 }
|
||||||
);
|
);
|
||||||
|
|
||||||
override render() {
|
override render() {
|
||||||
@@ -156,9 +176,14 @@ export class AffineFootnoteNode extends WithDisposable(ShadowlessElement) {
|
|||||||
? this.customNodeRenderer(footnote, this.std)
|
? this.customNodeRenderer(footnote, this.std)
|
||||||
: this._FootNoteDefaultContent(footnote);
|
: this._FootNoteDefaultContent(footnote);
|
||||||
|
|
||||||
|
const nodeClasses = classMap({
|
||||||
|
'footnote-node': true,
|
||||||
|
'hover-effect': !this.disableHoverEffect,
|
||||||
|
});
|
||||||
|
|
||||||
return html`<span
|
return html`<span
|
||||||
${this.hidePopup ? '' : ref(this._whenHover.setReference)}
|
${this.hidePopup ? '' : ref(this._whenHover.setReference)}
|
||||||
class="footnote-node"
|
class=${nodeClasses}
|
||||||
>${node}<v-text .str=${ZERO_WIDTH_NON_JOINER}></v-text
|
>${node}<v-text .str=${ZERO_WIDTH_NON_JOINER}></v-text
|
||||||
></span>`;
|
></span>`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export class FootNotePopupChip extends LitElement {
|
|||||||
gap: 4px;
|
gap: 4px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
|
transition: width 0.3s ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.prefix-icon,
|
.prefix-icon,
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ export class FootNotePopup extends SignalWatcher(WithDisposable(LitElement)) {
|
|||||||
.footnote-popup-container {
|
.footnote-popup-container {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-shadow: ${unsafeCSSVar('overlayPanelShadow')};
|
box-shadow: ${unsafeCSSVar('overlayPanelShadow')};
|
||||||
border-radius: 4px;
|
|
||||||
background-color: ${unsafeCSSVarV2('layer/background/primary')};
|
background-color: ${unsafeCSSVarV2('layer/background/primary')};
|
||||||
border: 0.5px solid ${unsafeCSSVarV2('layer/insideBorder/border')};
|
border: 0.5px solid ${unsafeCSSVarV2('layer/insideBorder/border')};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { WorkspaceService } from '@affine/core/modules/workspace';
|
|||||||
import {
|
import {
|
||||||
createSignalFromObservable,
|
createSignalFromObservable,
|
||||||
DocModeProvider,
|
DocModeProvider,
|
||||||
|
FootNoteNodeConfigExtension,
|
||||||
RefNodeSlotsProvider,
|
RefNodeSlotsProvider,
|
||||||
} from '@blocksuite/affine/blocks';
|
} from '@blocksuite/affine/blocks';
|
||||||
import { useFramework } from '@toeverything/infra';
|
import { useFramework } from '@toeverything/infra';
|
||||||
@@ -20,6 +21,11 @@ export interface SidebarTabProps {
|
|||||||
onLoad?: ((component: HTMLElement) => void) | null;
|
onLoad?: ((component: HTMLElement) => void) | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Disable hover effect for footnote node in chat panel
|
||||||
|
const FOOTNOTE_CONFIG = FootNoteNodeConfigExtension({
|
||||||
|
disableHoverEffect: true,
|
||||||
|
});
|
||||||
|
|
||||||
// A wrapper for CopilotPanel
|
// A wrapper for CopilotPanel
|
||||||
export const EditorChatPanel = forwardRef(function EditorChatPanel(
|
export const EditorChatPanel = forwardRef(function EditorChatPanel(
|
||||||
{ editor, onLoad }: SidebarTabProps,
|
{ editor, onLoad }: SidebarTabProps,
|
||||||
@@ -84,8 +90,9 @@ export const EditorChatPanel = forwardRef(function EditorChatPanel(
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
chatPanelRef.current.previewSpecBuilder =
|
const previewSpecBuilder = createPageModePreviewSpecs(framework);
|
||||||
createPageModePreviewSpecs(framework);
|
previewSpecBuilder.extend([FOOTNOTE_CONFIG]);
|
||||||
|
chatPanelRef.current.previewSpecBuilder = previewSpecBuilder;
|
||||||
} else {
|
} else {
|
||||||
chatPanelRef.current.host = editor.host;
|
chatPanelRef.current.host = editor.host;
|
||||||
chatPanelRef.current.doc = editor.doc;
|
chatPanelRef.current.doc = editor.doc;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import type { AIChatBlockModel } from '@affine/core/blocksuite/ai/blocks/ai-chat
|
|||||||
import { createPageModePreviewSpecs } from '@affine/core/blocksuite/block-suite-editor/specs/preview';
|
import { createPageModePreviewSpecs } from '@affine/core/blocksuite/block-suite-editor/specs/preview';
|
||||||
import { AINetworkSearchService } from '@affine/core/modules/ai-button/services/network-search';
|
import { AINetworkSearchService } from '@affine/core/modules/ai-button/services/network-search';
|
||||||
import type { EditorHost } from '@blocksuite/affine/block-std';
|
import type { EditorHost } from '@blocksuite/affine/block-std';
|
||||||
|
import { FootNoteNodeConfigExtension } from '@blocksuite/affine/blocks';
|
||||||
import { useFramework } from '@toeverything/infra';
|
import { useFramework } from '@toeverything/infra';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
@@ -12,6 +13,11 @@ export type AIChatBlockPeekViewProps = {
|
|||||||
host: EditorHost;
|
host: EditorHost;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Disable hover effect for footnote node in center peek preview mode
|
||||||
|
const FOOTNOTE_CONFIG = FootNoteNodeConfigExtension({
|
||||||
|
disableHoverEffect: true,
|
||||||
|
});
|
||||||
|
|
||||||
export const AIChatBlockPeekView = ({
|
export const AIChatBlockPeekView = ({
|
||||||
model,
|
model,
|
||||||
host,
|
host,
|
||||||
@@ -20,6 +26,7 @@ export const AIChatBlockPeekView = ({
|
|||||||
const searchService = framework.get(AINetworkSearchService);
|
const searchService = framework.get(AINetworkSearchService);
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
const previewSpecBuilder = createPageModePreviewSpecs(framework);
|
const previewSpecBuilder = createPageModePreviewSpecs(framework);
|
||||||
|
previewSpecBuilder.extend([FOOTNOTE_CONFIG]);
|
||||||
const networkSearchConfig = {
|
const networkSearchConfig = {
|
||||||
visible: searchService.visible,
|
visible: searchService.visible,
|
||||||
enabled: searchService.enabled,
|
enabled: searchService.enabled,
|
||||||
|
|||||||
Reference in New Issue
Block a user