import { ShadowlessElement, WithDisposable } from '@blockeditor/lit'; import type { ReferenceElement } from '@floating-ui/dom'; import { css, html } from 'lit'; import { customElement, property, query } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { repeat } from 'lit/directives/repeat.js'; import Sortable from 'sortablejs'; import { createPopup } from '../../_common/components/menu/index.js'; import { ArrowLeftBigIcon } from '../../_common/icons/index.js'; import type { DataViewColumnManager, DataViewManager, } from './data-view-manager.js'; const show = html` `; const hidden = html` `; @customElement('data-view-properties-setting') export class DataViewPropertiesSettingView extends WithDisposable( ShadowlessElement ) { static override styles = css` data-view-properties-setting { position: absolute; background-color: var(--affine-background-overlay-panel-color); border-radius: 8px; box-shadow: var(--affine-shadow-2); padding: 8px; min-width: 300px; } .properties-group-header { user-select: none; padding: 4px 12px 12px 12px; margin-bottom: 12px; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid var(--affine-divider-color); } .properties-group-title { font-size: 12px; line-height: 20px; color: var(--affine-text-secondary-color); display: flex; align-items: center; gap: 8px; } .properties-group-op { padding: 4px 8px; font-size: 12px; line-height: 20px; font-weight: 500; border-radius: 4px; cursor: pointer; } .properties-group-op:hover { background-color: var(--affine-hover-color); } .properties-group { min-height: 40px; } .property-item { padding: 4px; display: flex; align-items: center; gap: 8px; user-select: none; cursor: pointer; border-radius: 4px; } .property-item:hover { background-color: var(--affine-hover-color); } .property-item-drag-bar { width: 4px; height: 12px; border-radius: 1px; background-color: #efeff0; } .property-item:hover .property-item-drag-bar { background-color: #c0bfc1; } .property-item-icon { display: flex; align-items: center; } .property-item-icon svg { color: var(--affine-icon-color); fill: var(--affine-icon-color); width: 20px; height: 20px; } .property-item-op-icon { display: flex; align-items: center; border-radius: 4px; } .property-item-op-icon:hover { background-color: var(--affine-hover-color); } .property-item-op-icon.disabled:hover { background-color: transparent; } .property-item-op-icon svg { fill: var(--affine-icon-color); color: var(--affine-icon-color); width: 20px; height: 20px; } .property-item-op-icon.disabled svg { fill: var(--affine-text-disable-color); color: var(--affine-text-disable-color); } .property-item-name { font-size: 14px; line-height: 22px; flex: 1; } `; @property({ attribute: false }) view!: DataViewManager; @property({ attribute: false }) onBack?: () => void; override connectedCallback() { super.connectedCallback(); this._disposables.add( this.view.slots.update.on(() => { this.requestUpdate(); }) ); this._disposables.addFromEvent(this, 'pointerdown', e => { e.stopPropagation(); }); } @query('.properties-group') groupContainer!: HTMLElement; override firstUpdated() { const sortable = new Sortable(this.groupContainer, { animation: 150, group: `properties-sort-${this.view.id}`, onEnd: evt => { const properties = [...this.view.columnsWithoutFilter]; const index = evt.oldIndex ?? -1; const from = properties[index]; properties.splice(index, 1); const to = properties[evt.newIndex ?? -1]; this.view.columnMove( from, to ? { before: true, id: to, } : 'end' ); }, }); this._disposables.add({ dispose: () => sortable.destroy(), }); } private itemsGroup() { return this.view.columnsWithoutFilter.map(id => this.view.columnGet(id)); } renderColumn = (column: DataViewColumnManager) => { const isTitle = column.type === 'title'; const icon = column.hide ? hidden : show; const changeVisible = () => { if (column.type !== 'title') { column.updateHide(!column.hide); } }; const classList = classMap({ 'property-item-op-icon': true, disabled: isTitle, }); return html`