import { css, html, LitElement } from "lit"; import { classMap } from "lit/directives/class-map.js"; import { createRef, ref } from "lit/directives/ref.js"; import { customElement, property, state } from "lit/decorators.js"; import { type Selection } from "./selections.ts"; export { SelectionFilters } from "./selection-filters.ts"; @customElement("lens-controls") export class LensControls extends LitElement { @property({ attribute: true, type: Array }) selections: Selection[] = []; @state() private _isOpen = false; private _controlPanelDialog = createRef(); static override styles = css` :host { --shadow: 0 0.5rem 0.5rem #3333; --background: #fff; --border-color: #ccc; --border-radius: 0.5rem; } #container-positioner { position: fixed; bottom: 2rem; display: flex; justify-content: center; align-items: flex-end; overflow: visible; width: 100%; height: 0; } #container { display: grid; grid-template-columns: max-content max-content; filter: drop-shadow(var(--shadow)); } #tab-box { height: 2rem; display: flex; align-items: center; list-style-type: none; padding: 0.5rem; margin: 0; border: solid 1px var(--border-color); border-right: none; border-top-left-radius: var(--border-radius); border-bottom-left-radius: var(--border-radius); background: var(--background); grid-row: 2; & button { appearance: none; background: none; border: none; font-size: inherit; padding: 0.25rem 0.5rem; border-radius: 0.25rem; font-family: inherit; } & button.active { background: #39f3; } } #control-bar { height: 3rem; flex-shrink: 0; border: solid 1px var(--border-color); border-top-right-radius: var(--border-radius); border-bottom-right-radius: var(--border-radius); display: flex; justify-content: stretch; align-items: stretch; overflow: hidden; width: 40rem; grid-row: 2; & input { appearance: none; width: 100%; border: none; outline: none; font-size: inherit; font-family: "Funnel Sans"; padding: 0.5rem; } &.open { border-top-right-radius: 0; } } #control-panel-positioner { grid-template-columns: subgrid; grid-column: 2; grid-row: 1; position: relative; overflow: visible; /* Flexbox positioning is required for Safari */ display: flex; align-items: flex-end; anchor-name: --control-bar; } #control-panel-container:popover-open { inset: unset; border: solid 1px var(--border-color); border-bottom: none; border-top-left-radius: var(--border-radius); border-top-right-radius: var(--border-radius); margin: 0; position: fixed; display: block; width: 40rem; /* Anchor positioning is required for Chromium */ position-anchor: --control-bar; position-area: top; padding: 0; background: var(--background); box-shadow: var(--shadow); /* Clip drop shadow */ clip-path: polygon( -100% -100%, 200% -100%, 200% 200%, 100% 200%, 100% 100%, -100% 100% ); } #control-panel { padding: 1rem; overflow: auto; max-height: 8rem; } .selections { display: grid; grid-template-columns: max-content 1fr 1fr; } .selection { display: grid; grid-template-columns: subgrid; justify-content: start; align-items: center; grid-gap: 1rem; padding: 0.25rem 0; & .visibility { grid-column: 1; } & .selection-filters { grid-column: 2; } & .conversions { grid-column: 3; } } `; open(): void { this._controlPanelDialog.value?.showPopover(); } private _handleVisibilityInput(ev: InputEvent, selectionId: string): void { this.selections = this.selections.map(( selection, ) => (selection.id === selectionId ? { ...selection, visible: (ev.target as HTMLInputElement).checked, } : selection) ); } private _handleSelectionFiltersChange(ev: Event, selectionId: string): void { // TODO } protected override render() { return html` Filters Columns { this._isOpen = ev.newState === "open"; }}" > ${this.selections.map((selection) => html` this._handleVisibilityInput(ev, selection.id)}" > this._handleSelectionFiltersChange(ev, selection.id)}" > ` )} `; } }