@quandis/qbo4.ui 4.0.1-CI-20241028-221206 → 4.0.1-CI-20241029-174756

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,169 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { LitElement, html, css } from 'lit';
11
+ import { customElement, property } from 'lit/decorators.js';
12
+ import { qboui } from './styles.js';
13
+ let QboMenu = class QboMenu extends LitElement {
14
+ constructor() {
15
+ super(...arguments);
16
+ this.type = 'side';
17
+ this.expanded = false;
18
+ /* Css Selector for the HTMLElement that the context menu applies to. */
19
+ this.target = '';
20
+ this.showContextMenu = (event) => {
21
+ event.preventDefault();
22
+ if (!this.expanded) {
23
+ this.expanded = true;
24
+ this.positionContextMenu(event);
25
+ }
26
+ };
27
+ this.hideContextMenu = (event) => {
28
+ if (this.expanded && !this.shadowRoot?.contains(event.target) && !this.contains(event.target)) {
29
+ this.expanded = false;
30
+ }
31
+ };
32
+ }
33
+ static { this.styles = [qboui, css `
34
+ :host {
35
+ display: block;
36
+ }
37
+
38
+ .toggle-btn {
39
+ width: 100%;
40
+ background: none;
41
+ border: none;
42
+ font-size: 1.5rem;
43
+ cursor: pointer;
44
+ text-align: left;
45
+ }
46
+ `]; }
47
+ toggleSidebar() {
48
+ this.expanded = !this.expanded;
49
+ }
50
+ connectedCallback() {
51
+ super.connectedCallback();
52
+ switch (this.type) {
53
+ case 'context':
54
+ document.addEventListener('click', this.hideContextMenu);
55
+ this.contextParent?.addEventListener('contextmenu', this.showContextMenu);
56
+ break;
57
+ }
58
+ }
59
+ disconnectedCallback() {
60
+ super.disconnectedCallback();
61
+ switch (this.type) {
62
+ case 'context':
63
+ this.contextParent?.removeEventListener('contextmenu', this.showContextMenu);
64
+ document.removeEventListener('click', this.hideContextMenu);
65
+ break;
66
+ }
67
+ }
68
+ async positionContextMenu(event) {
69
+ event.preventDefault();
70
+ this.expanded = true;
71
+ await this.updateComplete;
72
+ const viewportWidth = window.innerWidth;
73
+ const viewportHeight = window.innerHeight;
74
+ const menuWidth = this.offsetWidth || 0;
75
+ const menuHeight = this.offsetHeight || 0;
76
+ // Calculate adjusted x and y positions
77
+ let x = event.clientX;
78
+ let y = event.clientY;
79
+ if (x + menuWidth > viewportWidth) {
80
+ x = viewportWidth - menuWidth;
81
+ }
82
+ if (y + menuHeight > viewportHeight) {
83
+ y = viewportHeight - menuHeight;
84
+ }
85
+ console.log(`mouse event: ${event.clientX} x ${event.clientY} ; ${x} x ${y}`);
86
+ this.style.left = x + 'px';
87
+ this.style.top = y + 'px';
88
+ }
89
+ get contextParent() {
90
+ if (this.target) {
91
+ return (this.closest(this.target) ||
92
+ (() => {
93
+ const rootNode = this.getRootNode();
94
+ if (rootNode instanceof ShadowRoot || rootNode instanceof Document) {
95
+ return rootNode.querySelector(this.target);
96
+ }
97
+ return null;
98
+ })() ||
99
+ document.querySelector(this.target) ||
100
+ document);
101
+ }
102
+ else {
103
+ return this.parentElement;
104
+ }
105
+ }
106
+ context() {
107
+ return html `${this.expanded ? html `<slot></slot>` : ''}`;
108
+ }
109
+ side() {
110
+ return html `<nav class="qbo-menu side ${this.expanded ? 'expanded' : ''}">
111
+ <slot name="toggle" @click=${this.toggleSidebar}><button class="toggle-btn" >☰</button></slot>
112
+ <slot></slot>
113
+ </nav>`;
114
+ }
115
+ render() {
116
+ switch (this.type) {
117
+ case 'side': return this.side();
118
+ case 'context': return this.context();
119
+ }
120
+ }
121
+ xrender() {
122
+ // Only render sidebar layout if type is "side"
123
+ return html `
124
+ ${this.type === 'side'
125
+ ? html `
126
+ <nav class="sidebar ${this.expanded ? 'expanded' : ''}">
127
+ <button class="toggle-btn" @click=${this.toggleSidebar}>☰</button>
128
+ <ul class="nav flex-column mt-3">
129
+ <li class="nav-item">
130
+ <a href="#" class="nav-link">
131
+ <i class="bi bi-house-door"></i>
132
+ <span class="sidebar-label">Home</span>
133
+ </a>
134
+ </li>
135
+ <li class="nav-item">
136
+ <a href="#" class="nav-link">
137
+ <i class="bi bi-gear"></i>
138
+ <span class="sidebar-label">Settings</span>
139
+ </a>
140
+ </li>
141
+ <li class="nav-item">
142
+ <a href="#" class="nav-link">
143
+ <i class="bi bi-person"></i>
144
+ <span class="sidebar-label">Profile</span>
145
+ </a>
146
+ </li>
147
+ </ul>
148
+ </nav>
149
+ `
150
+ : null}
151
+ `;
152
+ }
153
+ };
154
+ __decorate([
155
+ property({ type: String }),
156
+ __metadata("design:type", String)
157
+ ], QboMenu.prototype, "type", void 0);
158
+ __decorate([
159
+ property({ type: Boolean }),
160
+ __metadata("design:type", Boolean)
161
+ ], QboMenu.prototype, "expanded", void 0);
162
+ __decorate([
163
+ property({ type: String }),
164
+ __metadata("design:type", Object)
165
+ ], QboMenu.prototype, "target", void 0);
166
+ QboMenu = __decorate([
167
+ customElement('qbo-menu')
168
+ ], QboMenu);
169
+ export { QboMenu };
@@ -0,0 +1,168 @@
1
+ import { LitElement, html, css } from 'lit';
2
+ import { customElement, property } from 'lit/decorators.js';
3
+ import { qboui } from './styles.js';
4
+
5
+ @customElement('qbo-menu')
6
+ export class QboMenu extends LitElement {
7
+
8
+ @property({ type: String })
9
+ type: string = 'side';
10
+
11
+ @property({ type: Boolean })
12
+ expanded: boolean = false;
13
+
14
+ static styles = [qboui, css`
15
+ :host {
16
+ display: block;
17
+ }
18
+
19
+ .toggle-btn {
20
+ width: 100%;
21
+ background: none;
22
+ border: none;
23
+ font-size: 1.5rem;
24
+ cursor: pointer;
25
+ text-align: left;
26
+ }
27
+ `];
28
+
29
+ private toggleSidebar() {
30
+ this.expanded = !this.expanded;
31
+ }
32
+
33
+ connectedCallback() {
34
+ super.connectedCallback();
35
+ switch (this.type) {
36
+ case 'context':
37
+ document.addEventListener('click', this.hideContextMenu);
38
+ this.contextParent?.addEventListener('contextmenu', this.showContextMenu);
39
+ break;
40
+ }
41
+ }
42
+
43
+ disconnectedCallback() {
44
+ super.disconnectedCallback();
45
+ switch (this.type) {
46
+ case 'context':
47
+ this.contextParent?.removeEventListener('contextmenu', this.showContextMenu);
48
+ document.removeEventListener('click', this.hideContextMenu);
49
+ break;
50
+ }
51
+ }
52
+
53
+ /* Css Selector for the HTMLElement that the context menu applies to. */
54
+ @property({ type: String })
55
+ target = '';
56
+
57
+ private showContextMenu = (event: Event) => {
58
+ event.preventDefault();
59
+ if (!this.expanded) {
60
+ this.expanded = true;
61
+ this.positionContextMenu(event as MouseEvent);
62
+ }
63
+ }
64
+
65
+ private hideContextMenu = (event: Event) => {
66
+ if (this.expanded && !this.shadowRoot?.contains(event.target as Node) && !this.contains(event.target as Node)) {
67
+ this.expanded = false;
68
+ }
69
+ }
70
+
71
+ private async positionContextMenu(event: MouseEvent) {
72
+ event.preventDefault();
73
+ this.expanded = true;
74
+ await this.updateComplete;
75
+
76
+ const viewportWidth = window.innerWidth;
77
+ const viewportHeight = window.innerHeight;
78
+
79
+ const menuWidth = this.offsetWidth || 0;
80
+ const menuHeight = this.offsetHeight || 0;
81
+
82
+ // Calculate adjusted x and y positions
83
+ let x = event.clientX;
84
+ let y = event.clientY;
85
+
86
+ if (x + menuWidth > viewportWidth) {
87
+ x = viewportWidth - menuWidth;
88
+ }
89
+
90
+ if (y + menuHeight > viewportHeight) {
91
+ y = viewportHeight - menuHeight;
92
+ }
93
+ console.log(`mouse event: ${event.clientX} x ${event.clientY} ; ${x} x ${y}`)
94
+
95
+ this.style.left = x + 'px';
96
+ this.style.top = y + 'px';
97
+ }
98
+
99
+ get contextParent(): HTMLElement | Document | null {
100
+ if (this.target) {
101
+ return (
102
+ this.closest(this.target) as HTMLElement ||
103
+ (() => {
104
+ const rootNode = this.getRootNode();
105
+ if (rootNode instanceof ShadowRoot || rootNode instanceof Document) {
106
+ return rootNode.querySelector(this.target);
107
+ }
108
+ return null;
109
+ })() ||
110
+ document.querySelector(this.target) ||
111
+ document
112
+ );
113
+ } else {
114
+ return this.parentElement;
115
+ }
116
+ }
117
+
118
+ context() {
119
+ return html`${this.expanded ? html`<slot></slot>` : ''}`;
120
+ }
121
+
122
+ side() {
123
+ return html`<nav class="qbo-menu side ${this.expanded ? 'expanded' : ''}">
124
+ <slot name="toggle" @click=${this.toggleSidebar}><button class="toggle-btn" >☰</button></slot>
125
+ <slot></slot>
126
+ </nav>`
127
+ }
128
+
129
+ render() {
130
+ switch (this.type) {
131
+ case 'side': return this.side();
132
+ case 'context': return this.context();
133
+ }
134
+ }
135
+
136
+ xrender() {
137
+ // Only render sidebar layout if type is "side"
138
+ return html`
139
+ ${this.type === 'side'
140
+ ? html`
141
+ <nav class="sidebar ${this.expanded ? 'expanded' : ''}">
142
+ <button class="toggle-btn" @click=${this.toggleSidebar}>☰</button>
143
+ <ul class="nav flex-column mt-3">
144
+ <li class="nav-item">
145
+ <a href="#" class="nav-link">
146
+ <i class="bi bi-house-door"></i>
147
+ <span class="sidebar-label">Home</span>
148
+ </a>
149
+ </li>
150
+ <li class="nav-item">
151
+ <a href="#" class="nav-link">
152
+ <i class="bi bi-gear"></i>
153
+ <span class="sidebar-label">Settings</span>
154
+ </a>
155
+ </li>
156
+ <li class="nav-item">
157
+ <a href="#" class="nav-link">
158
+ <i class="bi bi-person"></i>
159
+ <span class="sidebar-label">Profile</span>
160
+ </a>
161
+ </li>
162
+ </ul>
163
+ </nav>
164
+ `
165
+ : null}
166
+ `;
167
+ }
168
+ }