import { html, css, TemplateResult, CSSResultArray } from 'lit'; import { customElement, property } from 'lit/decorators.js'; import NileElement from '../../internal/nile-element'; import { renderGlyph } from '../../internal/glyph'; import type { ToolbarState } from '../engine/selection-state'; interface ImageOp { label: string; /** Design-system icon name; `text` is the fallback when no glyph fits. */ icon?: string; text?: string; command: string; attrs?: Record; active?: (s: ToolbarState) => boolean; } const OPS: ImageOp[] = [ { label: 'Align left', icon: 'format_align_left', command: 'setImageAlign', attrs: { align: 'left' }, active: s => s.imageAlign === 'left', }, { label: 'Align center', icon: 'format_align_middle', command: 'setImageAlign', attrs: { align: 'center' }, active: s => s.imageAlign === 'center', }, { label: 'Align right', icon: 'format_align_right', command: 'setImageAlign', attrs: { align: 'right' }, active: s => s.imageAlign === 'right', }, { label: 'Toggle caption', icon: 'ng-captions', command: 'toggleImageCaption', active: s => s.imageIsFigure, }, { label: 'Original size', text: '1:1', command: 'setImageWidth', attrs: { width: null } }, { label: 'Delete image', icon: 'ng-trash-01', command: 'deleteImage' }, ]; /** * Compact floating bar shown while an image or figure is selected. The host * positions it; operations bubble up as `wysiwyg-command` events. */ @customElement('nile-wysiwyg-image-menu') export class NileWysiwygImageMenu extends NileElement { @property({ type: Boolean, reflect: true }) open = false; @property({ attribute: false }) toolbarState?: ToolbarState; public static get styles(): CSSResultArray { return [ css` :host { font-family: var( --nile-font-family-sans-serif, var(--ng-font-family-body, system-ui, -apple-system, sans-serif) ); position: absolute; z-index: 15; display: none; } :host([open]) { display: block; } .menu { display: flex; gap: 2px; padding: 4px; background: var(--nile-wysiwyg-popover-bg, #ffffff); border: 1px solid var(--nile-colors-neutral-400, #d0d5dd); border-radius: 8px; box-shadow: var(--nile-wysiwyg-popover-shadow, 0 4px 12px rgba(16, 24, 40, 0.12)); } button { display: inline-flex; align-items: center; justify-content: center; min-width: 26px; height: 26px; padding: 0 4px; border: none; border-radius: 5px; background: transparent; cursor: pointer; font-size: 12px; font-weight: 600; color: var(--nile-colors-neutral-700, #344054); } button:hover { background: var(--nile-colors-neutral-100, #f2f4f7); } button[data-active] { background: var(--nile-colors-primary-50, var(--ng-componentcolors-utility-blue-50, #eff4ff)); color: var(--nile-colors-primary-700, var(--ng-componentcolors-utility-blue-700, #1d4ed8)); } `, ]; } public render(): TemplateResult { const state = this.toolbarState; return html` `; } } declare global { interface HTMLElementTagNameMap { 'nile-wysiwyg-image-menu': NileWysiwygImageMenu; } }