feat(core): ai panel adaptation for edgeless theme (#11509)
### TL;DR AI panel adaptation for Edgeless theme > CLOSE BS-3017 
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import { createLitPortal } from '@blocksuite/affine/components/portal';
|
import { createLitPortal } from '@blocksuite/affine/components/portal';
|
||||||
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
||||||
|
import { ColorScheme } from '@blocksuite/affine/model';
|
||||||
import {
|
import {
|
||||||
EditorHost,
|
EditorHost,
|
||||||
PropTypes,
|
PropTypes,
|
||||||
@@ -123,6 +124,7 @@ export class AIItemList extends WithDisposable(LitElement) {
|
|||||||
item => item.name,
|
item => item.name,
|
||||||
item =>
|
item =>
|
||||||
html`<ai-item
|
html`<ai-item
|
||||||
|
.theme=${this.theme}
|
||||||
.onClick=${this.onClick}
|
.onClick=${this.onClick}
|
||||||
.item=${item}
|
.item=${item}
|
||||||
.host=${this.host}
|
.host=${this.host}
|
||||||
@@ -145,6 +147,9 @@ export class AIItemList extends WithDisposable(LitElement) {
|
|||||||
|
|
||||||
@property({ attribute: 'data-testid', reflect: true })
|
@property({ attribute: 'data-testid', reflect: true })
|
||||||
accessor testId = 'ai-item-list';
|
accessor testId = 'ai-item-list';
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
accessor theme: ColorScheme = ColorScheme.Light;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { ArrowRightIcon, EnterIcon } from '@blocksuite/affine/components/icons';
|
import { ArrowRightIcon, EnterIcon } from '@blocksuite/affine/components/icons';
|
||||||
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
||||||
|
import { ColorScheme } from '@blocksuite/affine/model';
|
||||||
import {
|
import {
|
||||||
EditorHost,
|
EditorHost,
|
||||||
PropTypes,
|
PropTypes,
|
||||||
@@ -27,6 +28,7 @@ export class AIItem extends WithDisposable(LitElement) {
|
|||||||
|
|
||||||
return html`<div
|
return html`<div
|
||||||
data-testid=${testId}
|
data-testid=${testId}
|
||||||
|
data-app-theme=${this.theme}
|
||||||
class="menu-item ${className}"
|
class="menu-item ${className}"
|
||||||
@pointerdown=${(e: MouseEvent) => e.stopPropagation()}
|
@pointerdown=${(e: MouseEvent) => e.stopPropagation()}
|
||||||
@click=${() => {
|
@click=${() => {
|
||||||
@@ -59,6 +61,9 @@ export class AIItem extends WithDisposable(LitElement) {
|
|||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor onClick: (() => void) | undefined;
|
accessor onClick: (() => void) | undefined;
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
accessor theme: ColorScheme = ColorScheme.Light;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
import { css } from 'lit';
|
import { unsafeCSSVar, unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
|
||||||
|
import { darkCssVariables, lightCssVariables } from '@toeverything/theme';
|
||||||
|
import {
|
||||||
|
darkCssVariablesV2,
|
||||||
|
lightCssVariablesV2,
|
||||||
|
} from '@toeverything/theme/v2';
|
||||||
|
import { css, unsafeCSS } from 'lit';
|
||||||
|
|
||||||
export const menuItemStyles = css`
|
export const menuItemStyles = css`
|
||||||
.menu-item {
|
.menu-item {
|
||||||
@@ -13,36 +19,41 @@ export const menuItemStyles = css`
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-item:hover {
|
.menu-item:hover {
|
||||||
background: var(--affine-hover-color);
|
background: ${unsafeCSSVar('--affine-hover-color')};
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-icon {
|
.item-icon {
|
||||||
display: flex;
|
display: flex;
|
||||||
color: var(--item-icon-color, var(--affine-brand-color));
|
color: ${unsafeCSSVar('--affine-brand-color')};
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-item:hover .item-icon {
|
.menu-item:hover .item-icon {
|
||||||
color: var(--item-icon-hover-color, var(--affine-brand-color));
|
color: ${unsafeCSSVar('--affine-brand-color')};
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-item.discard:hover {
|
.menu-item.discard:hover {
|
||||||
background: var(--affine-background-error-color);
|
background: ${unsafeCSSVar('--affine-background-error-color')};
|
||||||
.item-name,
|
.item-name,
|
||||||
.item-icon,
|
.item-icon,
|
||||||
.enter-icon {
|
.enter-icon {
|
||||||
color: var(--affine-error-color);
|
color: ${unsafeCSSVar('--affine-error-color')};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.item-name {
|
.item-name {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 0px 4px;
|
padding: 0px 4px;
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
flex: 1 0 0;
|
flex: 1 0 0;
|
||||||
color: var(--affine-text-primary-color);
|
color: ${unsafeCSSVarV2('text/primary')};
|
||||||
text-align: start;
|
text-align: start;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
font-feature-settings:
|
font-feature-settings:
|
||||||
@@ -55,7 +66,7 @@ export const menuItemStyles = css`
|
|||||||
}
|
}
|
||||||
|
|
||||||
.item-beta {
|
.item-beta {
|
||||||
color: var(--affine-text-secondary-color);
|
color: ${unsafeCSSVarV2('text/secondary')};
|
||||||
font-size: var(--affine-font-xs);
|
font-size: var(--affine-font-xs);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
margin-left: 0.5em;
|
margin-left: 0.5em;
|
||||||
@@ -63,14 +74,66 @@ export const menuItemStyles = css`
|
|||||||
|
|
||||||
.enter-icon,
|
.enter-icon,
|
||||||
.arrow-right-icon {
|
.arrow-right-icon {
|
||||||
color: var(--affine-icon-color);
|
color: ${unsafeCSSVarV2('icon/primary')};
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.enter-icon {
|
.enter-icon {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.arrow-right-icon,
|
.arrow-right-icon,
|
||||||
.menu-item:hover .enter-icon {
|
.menu-item:hover .enter-icon {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.menu-item[data-app-theme='light'] {
|
||||||
|
.item-name {
|
||||||
|
color: ${unsafeCSS(lightCssVariablesV2['--affine-v2-text-primary'])};
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-beta {
|
||||||
|
color: ${unsafeCSS(lightCssVariablesV2['--affine-v2-text-secondary'])};
|
||||||
|
}
|
||||||
|
|
||||||
|
.enter-icon,
|
||||||
|
.arrow-right-icon {
|
||||||
|
color: ${unsafeCSS(lightCssVariablesV2['--affine-v2-icon-primary'])};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item[data-app-theme='light']:hover {
|
||||||
|
background: ${unsafeCSS(lightCssVariables['--affine-hover-color'])};
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item.discard[data-app-theme='light']:hover {
|
||||||
|
background: ${unsafeCSS(
|
||||||
|
lightCssVariables['--affine-background-error-color']
|
||||||
|
)};
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item[data-app-theme='dark'] {
|
||||||
|
.item-name {
|
||||||
|
color: ${unsafeCSS(darkCssVariablesV2['--affine-v2-text-primary'])};
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-beta {
|
||||||
|
color: ${unsafeCSS(darkCssVariablesV2['--affine-v2-text-secondary'])};
|
||||||
|
}
|
||||||
|
|
||||||
|
.enter-icon,
|
||||||
|
.arrow-right-icon {
|
||||||
|
color: ${unsafeCSS(darkCssVariablesV2['--affine-v2-icon-primary'])};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item[data-app-theme='dark']:hover {
|
||||||
|
background: ${unsafeCSS(darkCssVariables['--affine-hover-color'])};
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item.discard[data-app-theme='dark']:hover {
|
||||||
|
background: ${unsafeCSS(
|
||||||
|
darkCssVariables['--affine-background-error-color']
|
||||||
|
)};
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
||||||
import { DocModeProvider } from '@blocksuite/affine/shared/services';
|
import {
|
||||||
|
DocModeProvider,
|
||||||
|
ThemeProvider,
|
||||||
|
} from '@blocksuite/affine/shared/services';
|
||||||
import { scrollbarStyle } from '@blocksuite/affine/shared/styles';
|
import { scrollbarStyle } from '@blocksuite/affine/shared/styles';
|
||||||
import { type EditorHost } from '@blocksuite/affine/std';
|
import { type EditorHost } from '@blocksuite/affine/std';
|
||||||
import { cssVar } from '@toeverything/theme';
|
import { cssVar } from '@toeverything/theme';
|
||||||
@@ -70,12 +73,23 @@ export class AskAIPanel extends WithDisposable(LitElement) {
|
|||||||
return filteredConfig;
|
return filteredConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
this.disposables.add(
|
||||||
|
this.host.std.get(ThemeProvider).app$.subscribe(() => {
|
||||||
|
this.requestUpdate();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
override render() {
|
override render() {
|
||||||
const style = styleMap({
|
const style = styleMap({
|
||||||
minWidth: `${this.minWidth}px`,
|
minWidth: `${this.minWidth}px`,
|
||||||
});
|
});
|
||||||
|
const appTheme = this.host.std.get(ThemeProvider).app$.value;
|
||||||
return html`<div class="ask-ai-panel" style=${style}>
|
return html`<div class="ask-ai-panel" style=${style}>
|
||||||
<ai-item-list
|
<ai-item-list
|
||||||
|
.theme=${appTheme}
|
||||||
.host=${this.host}
|
.host=${this.host}
|
||||||
.groups=${this._actionGroups}
|
.groups=${this._actionGroups}
|
||||||
.onClick=${this.onItemClick}
|
.onClick=${this.onItemClick}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {
|
|||||||
AFFINE_VIEWPORT_OVERLAY_WIDGET,
|
AFFINE_VIEWPORT_OVERLAY_WIDGET,
|
||||||
type AffineViewportOverlayWidget,
|
type AffineViewportOverlayWidget,
|
||||||
} from '@blocksuite/affine/blocks/root';
|
} from '@blocksuite/affine/blocks/root';
|
||||||
|
import { ColorScheme } from '@blocksuite/affine/model';
|
||||||
import {
|
import {
|
||||||
DocModeProvider,
|
DocModeProvider,
|
||||||
NotificationProvider,
|
NotificationProvider,
|
||||||
@@ -9,6 +10,7 @@ import {
|
|||||||
ToolbarFlag,
|
ToolbarFlag,
|
||||||
ToolbarRegistryIdentifier,
|
ToolbarRegistryIdentifier,
|
||||||
} from '@blocksuite/affine/shared/services';
|
} from '@blocksuite/affine/shared/services';
|
||||||
|
import { unsafeCSSVar } from '@blocksuite/affine/shared/theme';
|
||||||
import {
|
import {
|
||||||
getPageRootByElement,
|
getPageRootByElement,
|
||||||
stopPropagation,
|
stopPropagation,
|
||||||
@@ -27,7 +29,8 @@ import {
|
|||||||
type Rect,
|
type Rect,
|
||||||
shift,
|
shift,
|
||||||
} from '@floating-ui/dom';
|
} from '@floating-ui/dom';
|
||||||
import { css, html, nothing, type PropertyValues } from 'lit';
|
import { darkCssVariables, lightCssVariables } from '@toeverything/theme';
|
||||||
|
import { css, html, nothing, type PropertyValues, unsafeCSS } from 'lit';
|
||||||
import { property, query } from 'lit/decorators.js';
|
import { property, query } from 'lit/decorators.js';
|
||||||
import { choose } from 'lit/directives/choose.js';
|
import { choose } from 'lit/directives/choose.js';
|
||||||
import { literal, unsafeStatic } from 'lit/static-html.js';
|
import { literal, unsafeStatic } from 'lit/static-html.js';
|
||||||
@@ -43,9 +46,10 @@ export class AffineAIPanelWidget extends WidgetComponent {
|
|||||||
display: flex;
|
display: flex;
|
||||||
outline: none;
|
outline: none;
|
||||||
border-radius: var(--8, 8px);
|
border-radius: var(--8, 8px);
|
||||||
border: 1px solid var(--affine-border-color);
|
border: 1px solid;
|
||||||
background: var(--affine-background-overlay-panel-color);
|
border-color: ${unsafeCSSVar('--affine-border-color')};
|
||||||
box-shadow: var(--affine-overlay-shadow);
|
background: ${unsafeCSSVar('backgroundOverlayPanelColor')};
|
||||||
|
box-shadow: ${unsafeCSSVar('overlayShadow')};
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: max-content;
|
width: max-content;
|
||||||
@@ -58,6 +62,21 @@ export class AffineAIPanelWidget extends WidgetComponent {
|
|||||||
--affine-font-family: var(--affine-font-sans-family);
|
--affine-font-family: var(--affine-font-sans-family);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:host([data-app-theme='light']) {
|
||||||
|
background: ${unsafeCSS(
|
||||||
|
lightCssVariables['--affine-background-overlay-panel-color']
|
||||||
|
)};
|
||||||
|
border-color: ${unsafeCSS(lightCssVariables['--affine-border-color'])};
|
||||||
|
box-shadow: ${unsafeCSS(lightCssVariables['--affine-overlay-shadow'])};
|
||||||
|
}
|
||||||
|
:host([data-app-theme='dark']) {
|
||||||
|
background: ${unsafeCSS(
|
||||||
|
darkCssVariables['--affine-background-overlay-panel-color']
|
||||||
|
)};
|
||||||
|
border-color: ${unsafeCSS(darkCssVariables['--affine-border-color'])};
|
||||||
|
box-shadow: ${unsafeCSS(darkCssVariables['--affine-overlay-shadow'])};
|
||||||
|
}
|
||||||
|
|
||||||
.ai-panel-container {
|
.ai-panel-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -414,6 +433,13 @@ export class AffineAIPanelWidget extends WidgetComponent {
|
|||||||
|
|
||||||
override connectedCallback() {
|
override connectedCallback() {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
|
this.appTheme = this.std.get(ThemeProvider).app$.value;
|
||||||
|
this.disposables.add(
|
||||||
|
this.std.get(ThemeProvider).app$.subscribe(theme => {
|
||||||
|
this.appTheme = theme;
|
||||||
|
this.requestUpdate();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
this.tabIndex = -1;
|
this.tabIndex = -1;
|
||||||
// No need to synchronize the contents of the input into the editor.
|
// No need to synchronize the contents of the input into the editor.
|
||||||
@@ -460,7 +486,7 @@ export class AffineAIPanelWidget extends WidgetComponent {
|
|||||||
if (!this.config) return nothing;
|
if (!this.config) return nothing;
|
||||||
const config = this.config;
|
const config = this.config;
|
||||||
|
|
||||||
const theme = this.std.get(ThemeProvider).theme;
|
const theme = this.std.get(ThemeProvider).app$.value;
|
||||||
const mainTemplate = choose(this.state, [
|
const mainTemplate = choose(this.state, [
|
||||||
[
|
[
|
||||||
'input',
|
'input',
|
||||||
@@ -470,6 +496,7 @@ export class AffineAIPanelWidget extends WidgetComponent {
|
|||||||
.onFinish=${this._inputFinish}
|
.onFinish=${this._inputFinish}
|
||||||
.onInput=${this.onInput}
|
.onInput=${this.onInput}
|
||||||
.networkSearchConfig=${config.networkSearchConfig}
|
.networkSearchConfig=${config.networkSearchConfig}
|
||||||
|
.theme=${theme}
|
||||||
></ai-panel-input>`,
|
></ai-panel-input>`,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -564,6 +591,9 @@ export class AffineAIPanelWidget extends WidgetComponent {
|
|||||||
|
|
||||||
@property()
|
@property()
|
||||||
accessor state: AffineAIPanelState = 'hidden';
|
accessor state: AffineAIPanelState = 'hidden';
|
||||||
|
|
||||||
|
@property({ attribute: 'data-app-theme', reflect: true })
|
||||||
|
accessor appTheme: ColorScheme = ColorScheme.Light;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const aiPanelWidget = WidgetViewExtension(
|
export const aiPanelWidget = WidgetViewExtension(
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
import { AIStarIcon } from '@blocksuite/affine/components/icons';
|
import { AIStarIcon } from '@blocksuite/affine/components/icons';
|
||||||
import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
|
import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
|
||||||
|
import { ColorScheme } from '@blocksuite/affine/model';
|
||||||
import { unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
|
import { unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
|
||||||
import { stopPropagation } from '@blocksuite/affine/shared/utils';
|
import { stopPropagation } from '@blocksuite/affine/shared/utils';
|
||||||
import { PublishIcon, SendIcon } from '@blocksuite/icons/lit';
|
import { PublishIcon, SendIcon } from '@blocksuite/icons/lit';
|
||||||
import { css, html, LitElement, nothing } from 'lit';
|
import {
|
||||||
|
darkCssVariablesV2,
|
||||||
|
lightCssVariablesV2,
|
||||||
|
} from '@toeverything/theme/v2';
|
||||||
|
import { css, html, LitElement, nothing, unsafeCSS } from 'lit';
|
||||||
import { property, query, state } from 'lit/decorators.js';
|
import { property, query, state } from 'lit/decorators.js';
|
||||||
|
|
||||||
import type { AINetworkSearchConfig } from '../../type';
|
import type { AINetworkSearchConfig } from '../../type';
|
||||||
@@ -20,7 +25,6 @@ export class AIPanelInput extends SignalWatcher(WithDisposable(LitElement)) {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
background: var(--affine-background-overlay-panel-color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.star {
|
.star {
|
||||||
@@ -47,7 +51,7 @@ export class AIPanelInput extends SignalWatcher(WithDisposable(LitElement)) {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
|
|
||||||
color: var(--affine-text-primary-color);
|
color: ${unsafeCSSVarV2('text/primary')};
|
||||||
|
|
||||||
/* light/sm */
|
/* light/sm */
|
||||||
font-family: var(--affine-font-family);
|
font-family: var(--affine-font-family);
|
||||||
@@ -58,11 +62,11 @@ export class AIPanelInput extends SignalWatcher(WithDisposable(LitElement)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
textarea::placeholder {
|
textarea::placeholder {
|
||||||
color: var(--affine-placeholder-color);
|
color: ${unsafeCSSVarV2('text/placeholder')};
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea::-moz-placeholder {
|
textarea::-moz-placeholder {
|
||||||
color: var(--affine-placeholder-color);
|
color: ${unsafeCSSVarV2('text/placeholder')};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,12 +83,15 @@ export class AIPanelInput extends SignalWatcher(WithDisposable(LitElement)) {
|
|||||||
color: ${unsafeCSSVarV2('button/pureWhiteText')};
|
color: ${unsafeCSSVarV2('button/pureWhiteText')};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.arrow[data-active] {
|
.arrow[data-active] {
|
||||||
background: ${unsafeCSSVarV2('icon/activated')};
|
background: ${unsafeCSSVarV2('icon/activated')};
|
||||||
}
|
}
|
||||||
|
|
||||||
.arrow[data-active]:hover {
|
.arrow[data-active]:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.network {
|
.network {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -97,9 +104,90 @@ export class AIPanelInput extends SignalWatcher(WithDisposable(LitElement)) {
|
|||||||
color: ${unsafeCSSVarV2('icon/primary')};
|
color: ${unsafeCSSVarV2('icon/primary')};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.network[data-active='true'] svg {
|
.network[data-active='true'] svg {
|
||||||
color: ${unsafeCSSVarV2('icon/activated')};
|
color: ${unsafeCSSVarV2('icon/activated')};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:host([data-app-theme='light']) {
|
||||||
|
.network svg {
|
||||||
|
color: ${unsafeCSS(lightCssVariablesV2['--affine-v2-icon-primary'])};
|
||||||
|
}
|
||||||
|
|
||||||
|
.network[data-active='true'] svg {
|
||||||
|
color: ${unsafeCSS(lightCssVariablesV2['--affine-v2-icon-activated'])};
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
color: ${unsafeCSS(lightCssVariablesV2['--affine-v2-text-primary'])};
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea::placeholder {
|
||||||
|
color: ${unsafeCSS(
|
||||||
|
lightCssVariablesV2['--affine-v2-text-placeholder']
|
||||||
|
)};
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea::-moz-placeholder {
|
||||||
|
color: ${unsafeCSS(
|
||||||
|
lightCssVariablesV2['--affine-v2-text-placeholder']
|
||||||
|
)};
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow {
|
||||||
|
background: ${unsafeCSS(
|
||||||
|
lightCssVariablesV2['--affine-v2-icon-disable']
|
||||||
|
)};
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow[data-active] {
|
||||||
|
background: ${unsafeCSS(
|
||||||
|
lightCssVariablesV2['--affine-v2-icon-activated']
|
||||||
|
)};
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow svg {
|
||||||
|
color: ${unsafeCSS(lightCssVariablesV2['--affine-v2-pure-white-text'])};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:host([data-app-theme='dark']) {
|
||||||
|
.network svg {
|
||||||
|
color: ${unsafeCSS(darkCssVariablesV2['--affine-v2-icon-primary'])};
|
||||||
|
}
|
||||||
|
|
||||||
|
.network[data-active='true'] svg {
|
||||||
|
color: ${unsafeCSS(darkCssVariablesV2['--affine-v2-icon-activated'])};
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
color: ${unsafeCSS(darkCssVariablesV2['--affine-v2-text-primary'])};
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea::placeholder {
|
||||||
|
color: ${unsafeCSS(darkCssVariablesV2['--affine-v2-text-placeholder'])};
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea::-moz-placeholder {
|
||||||
|
color: ${unsafeCSS(darkCssVariablesV2['--affine-v2-text-placeholder'])};
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow {
|
||||||
|
background: ${unsafeCSS(
|
||||||
|
darkCssVariablesV2['--affine-v2-icon-disable']
|
||||||
|
)};
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow[data-active] {
|
||||||
|
background: ${unsafeCSS(
|
||||||
|
darkCssVariablesV2['--affine-v2-icon-activated']
|
||||||
|
)};
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow svg {
|
||||||
|
color: ${unsafeCSS(darkCssVariablesV2['--affine-v2-pure-white-text'])};
|
||||||
|
}
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
private readonly _onInput = () => {
|
private readonly _onInput = () => {
|
||||||
@@ -209,6 +297,9 @@ export class AIPanelInput extends SignalWatcher(WithDisposable(LitElement)) {
|
|||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor onInput: ((input: string) => void) | undefined = undefined;
|
accessor onInput: ((input: string) => void) | undefined = undefined;
|
||||||
|
|
||||||
|
@property({ attribute: 'data-app-theme', reflect: true })
|
||||||
|
accessor theme: ColorScheme = ColorScheme.Light;
|
||||||
|
|
||||||
@query('textarea')
|
@query('textarea')
|
||||||
accessor textarea!: HTMLTextAreaElement;
|
accessor textarea!: HTMLTextAreaElement;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
||||||
|
import { ThemeProvider } from '@blocksuite/affine/shared/services';
|
||||||
import { scrollbarStyle } from '@blocksuite/affine/shared/styles';
|
import { scrollbarStyle } from '@blocksuite/affine/shared/styles';
|
||||||
|
import { unsafeCSSVar } from '@blocksuite/affine/shared/theme';
|
||||||
import { on, stopPropagation } from '@blocksuite/affine/shared/utils';
|
import { on, stopPropagation } from '@blocksuite/affine/shared/utils';
|
||||||
import type { EditorHost } from '@blocksuite/affine/std';
|
import type { EditorHost } from '@blocksuite/affine/std';
|
||||||
import { css, html, LitElement, nothing } from 'lit';
|
import { darkCssVariables, lightCssVariables } from '@toeverything/theme';
|
||||||
|
import { css, html, LitElement, nothing, unsafeCSS } from 'lit';
|
||||||
import { property } from 'lit/decorators.js';
|
import { property } from 'lit/decorators.js';
|
||||||
|
|
||||||
import type { AIItemGroupConfig } from '../../components/ai-item/types';
|
import type { AIItemGroupConfig } from '../../components/ai-item/types';
|
||||||
@@ -20,16 +23,44 @@ export class EdgelessCopilotPanel extends WithDisposable(LitElement) {
|
|||||||
min-width: 330px;
|
min-width: 330px;
|
||||||
max-height: 374px;
|
max-height: 374px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
background: var(--affine-background-overlay-panel-color);
|
background: ${unsafeCSSVar('--affine-background-overlay-panel-color')};
|
||||||
box-shadow: var(--affine-shadow-2);
|
box-shadow: ${unsafeCSSVar('--affine-overlay-shadow')};
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
z-index: var(--affine-z-index-popover);
|
z-index: var(--affine-z-index-popover);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.edgeless-copilot-panel[data-app-theme='light'] {
|
||||||
|
background: ${unsafeCSS(
|
||||||
|
lightCssVariables['--affine-background-overlay-panel-color']
|
||||||
|
)};
|
||||||
|
|
||||||
|
box-shadow: ${unsafeCSS(lightCssVariables['--affine-overlay-shadow'])};
|
||||||
|
}
|
||||||
|
|
||||||
|
.edgeless-copilot-panel[data-app-theme='dark'] {
|
||||||
|
background: ${unsafeCSS(
|
||||||
|
darkCssVariables['--affine-background-overlay-panel-color']
|
||||||
|
)};
|
||||||
|
|
||||||
|
box-shadow: ${unsafeCSS(darkCssVariables['--affine-overlay-shadow'])};
|
||||||
|
}
|
||||||
|
|
||||||
|
.edgeless-copilot-panel[data-app-theme='dark'] ai-item {
|
||||||
|
background: blue;
|
||||||
|
}
|
||||||
|
|
||||||
${scrollbarStyle('.edgeless-copilot-panel')}
|
${scrollbarStyle('.edgeless-copilot-panel')}
|
||||||
.edgeless-copilot-panel:hover::-webkit-scrollbar-thumb {
|
.edgeless-copilot-panel:hover::-webkit-scrollbar-thumb {
|
||||||
background-color: var(--affine-black-30);
|
background-color: var(--affine-black-30);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.edgeless-copilot-panel[data-app-theme='light']:hover::-webkit-scrollbar-thumb {
|
||||||
|
background-color: ${unsafeCSS(lightCssVariables['--affine-black30'])};
|
||||||
|
}
|
||||||
|
|
||||||
|
.edgeless-copilot-panel[data-app-theme='dark']:hover::-webkit-scrollbar-thumb {
|
||||||
|
background-color: ${unsafeCSS(darkCssVariables['--affine-black30'])};
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
private _getChain() {
|
private _getChain() {
|
||||||
@@ -40,6 +71,11 @@ export class EdgelessCopilotPanel extends WithDisposable(LitElement) {
|
|||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
this._disposables.add(on(this, 'wheel', stopPropagation));
|
this._disposables.add(on(this, 'wheel', stopPropagation));
|
||||||
this._disposables.add(on(this, 'pointerdown', stopPropagation));
|
this._disposables.add(on(this, 'pointerdown', stopPropagation));
|
||||||
|
this.disposables.add(
|
||||||
|
this.host.std.get(ThemeProvider).app$.subscribe(() => {
|
||||||
|
this.requestUpdate();
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
hide() {
|
hide() {
|
||||||
@@ -47,6 +83,7 @@ export class EdgelessCopilotPanel extends WithDisposable(LitElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override render() {
|
override render() {
|
||||||
|
const appTheme = this.host.std.get(ThemeProvider).app$.value;
|
||||||
const chain = this._getChain();
|
const chain = this._getChain();
|
||||||
const groups = this.groups.reduce((pre, group) => {
|
const groups = this.groups.reduce((pre, group) => {
|
||||||
const filtered = group.items.filter(item =>
|
const filtered = group.items.filter(item =>
|
||||||
@@ -61,8 +98,9 @@ export class EdgelessCopilotPanel extends WithDisposable(LitElement) {
|
|||||||
if (groups.every(group => group.items.length === 0)) return nothing;
|
if (groups.every(group => group.items.length === 0)) return nothing;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="edgeless-copilot-panel">
|
<div class="edgeless-copilot-panel" data-app-theme=${appTheme}>
|
||||||
<ai-item-list
|
<ai-item-list
|
||||||
|
.theme=${appTheme}
|
||||||
.onClick=${() => {
|
.onClick=${() => {
|
||||||
this.onClick?.();
|
this.onClick?.();
|
||||||
}}
|
}}
|
||||||
|
|||||||
Reference in New Issue
Block a user