1import { DiffuseElement } from "@common/element.js";
2
3/**
4 * @import {RenderArg} from "@common/element.d.ts"
5 */
6
7////////////////////////////////////////////
8// ELEMENT
9////////////////////////////////////////////
10
11class WindowElement extends DiffuseElement {
12 static observedAttributes = ["open"];
13
14 constructor() {
15 super();
16
17 this.id = this.id?.length ? this.id : crypto.randomUUID();
18 this.attachShadow({ mode: "open" });
19 }
20
21 // ACTIONS
22
23 activate() {
24 this.shadowRoot?.querySelector(".title-bar")?.classList.remove("inactive");
25 }
26
27 deactivate() {
28 this.shadowRoot?.querySelector(".title-bar")?.classList.add("inactive");
29 }
30
31 // RENDER
32
33 /**
34 * @param {RenderArg} _
35 */
36 render({ html }) {
37 return html`
38 <link rel="stylesheet" href="styles/vendor/98.css" />
39
40 <style>
41 dialog {
42 background: transparent;
43 border: 0;
44 padding: 0;
45 }
46
47 .window-body {
48 min-width: 350px;
49 overflow: hidden;
50 resize: both;
51 }
52
53 .title-bar {
54 justify-content: unset;
55 user-select: none;
56 }
57
58 .title-bar-icon {
59 margin-right: 4px;
60 }
61
62 .title-bar-text {
63 flex: 1;
64 }
65 </style>
66
67 <dialog ?open="${this.hasAttribute("open")}">
68 <div class="window">
69 <div
70 class="title-bar"
71 @mousedown="${this.titleBarMouseDown.bind(this)}"
72 >
73 <div class="title-bar-icon">
74 <slot name="title-icon"></slot>
75 </div>
76 <div class="title-bar-text" draggable="false">
77 <slot name="title"></slot>
78 </div>
79 <div class="title-bar-controls">
80 <!--<button aria-label="Minimize"></button>-->
81 <!--<button aria-label="Maximize"></button>-->
82 <button aria-label="Close" @click="${() =>
83 this.removeAttribute("open")}"></button>
84 </div>
85 </div>
86 <div class="window-body" style="${this.getAttribute(`window-style`) ??
87 ``}">
88 <slot></slot>
89 </div>
90 </div>
91 </dialog>
92 `;
93 }
94
95 // EVENTS
96
97 /**
98 * @param {MouseEvent} mouse
99 */
100 titleBarMouseDown(mouse) {
101 const event = new CustomEvent("dtw-window-start-move", {
102 bubbles: true,
103 composed: true,
104 detail: {
105 element: this,
106 x: mouse.x,
107 xElement: mouse.layerX,
108 y: mouse.y,
109 yElement: mouse.layerY,
110 },
111 });
112
113 this.dispatchEvent(event);
114 }
115}
116
117export default WindowElement;
118
119////////////////////////////////////////////
120// REGISTER
121////////////////////////////////////////////
122
123export const CLASS = WindowElement;
124export const NAME = "dtw-window";
125
126customElements.define(NAME, WindowElement);