UNPKG

@quick-game/cli

Version:

Command line interface for rapid qg development

175 lines (159 loc) 5.43 kB
// Copyright 2023 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import * as ComponentHelpers from '../../../ui/components/helpers/helpers.js'; import * as LitHtml from '../../../ui/lit-html/lit-html.js'; // clean-css does not compile this file correctly. So as a workaround adding styles inline. const styles = ` :host { --current-main-area-size: 50%; --resizer-size: 3px; --min-main-area-size: 200px; --min-sidebar-size: 150px; --main-area-size: calc(max(var(--current-main-area-size), var(--min-main-area-size))); height: 100%; width: 100%; display: block; overflow: auto; } .wrapper { display: flex; flex-direction: row; height: 100%; width: 100%; container: sidebar / size; /* stylelint-disable-line property-no-unknown */ } .container { --resizer-position: calc(min(var(--main-area-size), calc(100% - var(--min-sidebar-size)))); --min-container-size: calc(var(--min-sidebar-size) + var(--min-main-area-size) + var(--resizer-size)); display: flex; flex-direction: row; height: 100%; width: 100%; position: relative; gap: var(--resizer-size); min-width: var(--min-container-size); } #resizer { background-color: var(--color-background-elevation-1); position: absolute; user-select: none; /* horizontal */ width: var(--resizer-size); cursor: col-resize; left: var(--resizer-position); bottom: 0; top: 0; } slot { overflow: auto; display: block; } slot[name="main"] { /* horizontal */ width: var(--resizer-position); min-width: var(--min-main-area-size); } slot[name="sidebar"] { flex: 1 0 0; min-width: var(--min-sidebar-size); } .horizontal .container { flex-direction: column; min-height: var(--min-container-size); min-width: auto; } .horizontal #resizer { width: auto; height: var(--resizer-size); cursor: row-resize; top: var(--resizer-position); left: 0; right: 0; } .horizontal slot[name="main"] { width: auto; min-width: auto; height: var(--resizer-position); min-height: var(--min-main-area-size); } .horizontal slot[name="sidebar"] { min-width: auto; min-height: var(--min-sidebar-size); } `; const splitViewStyles = new CSSStyleSheet(); splitViewStyles.replaceSync(styles); export class SplitView extends HTMLElement { static litTagName = LitHtml.literal `devtools-split-view`; #shadow = this.attachShadow({ mode: 'open' }); #mousePos = [0, 0]; #mainAxisIdx = 0; #mainDimensions = [0, 0]; #observer; #horizontal = false; connectedCallback() { this.style.setProperty('--current-main-area-size', '60%'); this.#shadow.adoptedStyleSheets = [splitViewStyles]; this.#observer = new ResizeObserver(entries => this.#onResize(entries[0].contentRect)); this.#observer.observe(this); this.#render(); } get horizontal() { return this.#horizontal; } set horizontal(horizontal) { this.#horizontal = horizontal; void ComponentHelpers.ScheduledRender.scheduleRender(this, this.#render); } #onResize = (rect) => { const prevMainAxisIdx = this.#mainAxisIdx; if (rect.width <= 600 && rect.height >= 600 || this.#horizontal) { this.#mainAxisIdx = 1; } else { this.#mainAxisIdx = 0; } if (this.#mainAxisIdx !== prevMainAxisIdx) { void ComponentHelpers.ScheduledRender.scheduleRender(this, this.#render); } }; #onMouseDown = (event) => { const main = this.#shadow.querySelector('slot[name=main]'); if (!main) { throw new Error('Main slot not found'); } const rect = main.getBoundingClientRect(); this.#mainDimensions = [rect.width, rect.height]; this.#mousePos = [event.clientX, event.clientY]; window.addEventListener('mousemove', this.#onMouseMove, true); window.addEventListener('mouseup', this.#onMouseUp, true); }; #onMouseUp = () => { window.removeEventListener('mousemove', this.#onMouseMove, true); window.removeEventListener('mouseup', this.#onMouseUp, true); }; #onMouseMove = (event) => { const mousePos = [event.clientX, event.clientY]; const delta = mousePos[this.#mainAxisIdx] - this.#mousePos[this.#mainAxisIdx]; const rect = this.getBoundingClientRect(); const containerDimensions = [rect.width, rect.height]; const length = ((this.#mainDimensions[this.#mainAxisIdx] + delta) * 100) / containerDimensions[this.#mainAxisIdx]; this.style.setProperty('--current-main-area-size', length + '%'); }; #render = () => { // clang-format off LitHtml.render(LitHtml.html ` <div class="wrapper ${this.#mainAxisIdx === 1 ? 'horizontal' : ''}"> <div class="container"> <slot name="main"></slot> <div id="resizer" @mousedown=${this.#onMouseDown}></div> <slot name="sidebar"></slot> </div> </div> `, this.#shadow, { host: this }); // clang-format on }; } ComponentHelpers.CustomElements.defineComponent('devtools-split-view', SplitView); //# sourceMappingURL=SplitView.js.map