Files
AFFiNE-Mirror/blocksuite/affine/components/src/highlight-dropdown-menu/dropdown-menu.ts
T
2025-03-28 07:20:34 +00:00

121 lines
3.8 KiB
TypeScript

import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
import { PropTypes, requiredProperties } from '@blocksuite/std';
import { LitElement } from 'lit';
import { property } from 'lit/decorators.js';
import { styleMap } from 'lit/directives/style-map.js';
import { html } from 'lit-html';
import { repeat } from 'lit-html/directives/repeat.js';
import { EditorChevronDown } from '../toolbar';
const colors = [
'default',
'red',
'orange',
'yellow',
'green',
'teal',
'blue',
'purple',
'grey',
] as const;
type HighlightType = 'color' | 'background';
// TODO(@fundon): these recent settings should be added to the dropdown menu
// tests/blocksutie/e2e/format-bar.spec.ts#253
//
// let latestHighlightColor: string | null = null;
// let latestHighlightType: HighlightType = 'background';
@requiredProperties({
updateHighlight: PropTypes.instanceOf(Function),
})
export class HighlightDropdownMenu extends LitElement {
@property({ attribute: false })
accessor updateHighlight!: (styles: AffineTextAttributes) => void;
private readonly _update = (value: string | null, type: HighlightType) => {
// latestHighlightColor = value;
// latestHighlightType = type;
this.updateHighlight({ [`${type}`]: value });
};
override render() {
const prefix = '--affine-text-highlight';
return html`
<editor-menu-button
.contentPadding="${'8px'}"
.button=${html`
<editor-icon-button aria-label="highlight" .tooltip="${'Highlight'}">
<affine-highlight-duotone-icon
style=${styleMap({
'--color':
// latestHighlightColor ?? 'var(--affine-text-primary-color)',
'var(--affine-text-primary-color)',
})}
></affine-highlight-duotone-icon>
${EditorChevronDown}
</editor-icon-button>
`}
>
<div data-size="large" data-orientation="vertical">
<div class="highlight-heading">Color</div>
${repeat(colors, color => {
const isDefault = color === 'default';
const value = isDefault
? null
: `var(${prefix}-foreground-${color})`;
return html`
<editor-menu-action
data-testid="foreground-${color}"
@click=${() => this._update(value, 'color')}
>
<affine-text-duotone-icon
style=${styleMap({
'--color': value ?? 'var(--affine-text-primary-color)',
})}
></affine-text-duotone-icon>
<span class="label capitalize"
>${isDefault ? `${color} color` : color}</span
>
</editor-menu-action>
`;
})}
<div class="highlight-heading">Background</div>
${repeat(colors, color => {
const isDefault = color === 'default';
const value = isDefault ? null : `var(${prefix}-${color})`;
return html`
<editor-menu-action
data-testid="background-${color}"
@click=${() => this._update(value, 'background')}
>
<affine-text-duotone-icon
style=${styleMap({
'--color': 'var(--affine-text-primary-color)',
'--background': value ?? 'transparent',
})}
></affine-text-duotone-icon>
<span class="label capitalize"
>${isDefault ? `${color} background` : color}</span
>
</editor-menu-action>
`;
})}
</div>
</editor-menu-button>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
'affine-highlight-dropdown-menu': HighlightDropdownMenu;
}
}