@quandis/qbo4.ui 4.0.1-CI-20241113-192850 → 4.0.1-CI-20241113-211132

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.
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "author": "Quandis, Inc.",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
- "version": "4.0.1-CI-20241113-192850",
6
+ "version": "4.0.1-CI-20241113-211132",
7
7
  "workspaces": [
8
8
  "code"
9
9
  ],
package/scss/qbo.scss CHANGED
@@ -4,14 +4,15 @@
4
4
  --qbo-border-color: #999;
5
5
  --qbo-border-radius: 4px;
6
6
  --qbo-background-color: #ffffff;
7
- --qbo-padding-horizontal: 0rem;
8
- --qbo-padding-vertical: 0rem;
7
+ --qbo-padding-horizontal: 0.75rem;
8
+ --qbo-padding-vertical: 0.375rem;
9
9
  --qbo-padding: var(--qbo-padding-vertical) var(--qbo-padding-horizontal);
10
10
  --qbo-margin: 0.5rem;
11
11
  --qbo-margin-horizontal: 0.5rem;
12
12
  --qbo-margin-vertical: 0.5rem;
13
13
  --qbo-focus-border-color: #80bdff;
14
14
  --qbo-focus-box-shadow: rgba(0, 123, 255, 0.25);
15
+ --qbo-line-height: var(--qbo-line-height);
15
16
 
16
17
  --qbo-button-bg: #007bff;
17
18
  --qbo-button-border: #007bff;
@@ -92,43 +93,6 @@
92
93
  gap: var(--qbo-margin);
93
94
  }
94
95
 
95
- /* Default column styling */
96
- .qbo-card {
97
- @extend .qbo-col;
98
- border: 1px solid var(--qbo-border-color);
99
- border-radius: var(--qbo-border-radius);
100
- box-shadow: 2px 2px 3px var(--qbo-border-color);
101
- padding: .5em;
102
- overflow: auto;
103
- }
104
-
105
- .qbo-card-bottom {
106
- margin-bottom: .5em;
107
- }
108
-
109
- .qbo-card-left {
110
- margin-left: .5em;
111
- }
112
-
113
- .qbo-card-right {
114
- margin-right: .5em;
115
- }
116
-
117
- .qbo-card-top {
118
- margin-top: .5em;
119
- }
120
-
121
- svg {
122
- height: 1rem;
123
- width: 1rem;
124
- }
125
-
126
- .qbo-row {
127
- display: flex;
128
- flex-wrap: wrap;
129
- gap: var(--qbo-margin);
130
- }
131
-
132
96
  /* Default column styling */
133
97
  .qbo-col {
134
98
  flex: 1 0 0;
@@ -136,12 +100,6 @@ svg {
136
100
  box-sizing: border-box;
137
101
  }
138
102
 
139
- .qbo-row {
140
- display: flex;
141
- flex-wrap: wrap;
142
- gap: var(--qbo-margin); /* Use --qbo-margin as the gap */
143
- }
144
-
145
103
  .qbo-col-1 {
146
104
  flex: 0 0 calc(8.33% - (var(--qbo-margin) / 2));
147
105
  max-width: calc(8.33% - (var(--qbo-margin) / 2));
@@ -202,10 +160,33 @@ svg {
202
160
  max-width: calc(100% - (var(--qbo-margin) / 2));
203
161
  }
204
162
 
163
+ /* Default column styling */
164
+ .qbo-card {
165
+ @extend .qbo-col;
166
+ border: 1px solid var(--qbo-border-color);
167
+ border-radius: var(--qbo-border-radius);
168
+ box-shadow: 2px 2px 3px var(--qbo-border-color);
169
+ padding: .5em;
170
+ overflow: auto;
171
+ }
172
+
173
+ .qbo-card-left {
174
+ margin-left: .5em;
175
+ }
176
+
177
+ .qbo-card-right {
178
+ margin-right: .5em;
179
+ }
180
+
181
+ svg {
182
+ height: 1rem;
183
+ width: 1rem;
184
+ }
185
+
205
186
  /* Form */
206
187
  .qbo-form {
207
188
  margin: 0 auto;
208
- padding: var(--qbo-padding);
189
+ padding: var(--qbo-padding-vertical) var(--qbo-padding-horizontal);
209
190
  }
210
191
 
211
192
  .qbo-form label {
@@ -230,7 +211,7 @@ svg {
230
211
  .qbo-form textarea {
231
212
  width: 100%;
232
213
  box-sizing: border-box;
233
- padding: var(--qbo-padding);
214
+ padding: var(--qbo-padding-vertical) var(--qbo-padding-horizontal);
234
215
  font-size: 1rem;
235
216
  line-height: 1;
236
217
  color: var(--qbo-color);
@@ -330,9 +311,9 @@ button,
330
311
  background-color: var(--qbo-background-color);
331
312
  border: 1px solid var(--qbo-border-color);
332
313
  border-radius: var(--qbo-border-radius);
333
- padding: var(--qbo-padding);
314
+ padding: var(--qbo-padding-vertical) var(--qbo-padding-horizontal);
334
315
  font-size: 1rem;
335
- line-height: 1.5;
316
+ line-height: var(--qbo-line-height);
336
317
  text-align: center;
337
318
  vertical-align: middle;
338
319
  cursor: pointer;
@@ -348,7 +329,7 @@ button:focus,
348
329
  .qbo-button:focus {
349
330
  background-color: var(--qbo-border-color);
350
331
  text-decoration: none;
351
- line-height: 1.5;
332
+ line-height: var(--qbo-line-height);
352
333
  border-radius: var(--qbo-border-radius);
353
334
  transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;
354
335
  }
@@ -406,87 +387,6 @@ button:disabled,
406
387
  background-position: left center;
407
388
  }
408
389
 
409
- /* Grid */
410
- .qbo-row {
411
- display: flex;
412
- flex-wrap: wrap;
413
- gap: var(--qbo-margin);
414
- }
415
-
416
- /* Default column styling */
417
- .qbo-col {
418
- flex: 1 0 0;
419
- min-width: calc(8.33% - (var(--qbo-margin) / 2));
420
- max-width: 100%;
421
- box-sizing: border-box;
422
- }
423
-
424
- .qbo-row {
425
- display: flex;
426
- flex-wrap: wrap;
427
- gap: var(--qbo-margin); /* Use --qbo-margin as the gap */
428
- }
429
-
430
- .qbo-col-1 {
431
- flex: 0 0 calc(8.33% - (var(--qbo-margin) / 2));
432
- max-width: calc(8.33% - (var(--qbo-margin) / 2));
433
- }
434
-
435
- .qbo-col-2 {
436
- flex: 0 0 calc(16.66% - (var(--qbo-margin) / 2));
437
- max-width: calc(16.66% - (var(--qbo-margin) / 2));
438
- }
439
-
440
- .qbo-col-3 {
441
- flex: 0 0 calc(25% - (var(--qbo-margin) / 2));
442
- max-width: calc(25% - (var(--qbo-margin) / 2));
443
- }
444
-
445
- .qbo-col-4 {
446
- flex: 0 0 calc(33.33% - (var(--qbo-margin) / 2));
447
- max-width: calc(33.33% - (var(--qbo-margin) / 2));
448
- }
449
-
450
- .qbo-col-5 {
451
- flex: 0 0 calc(41.66% - (var(--qbo-margin) / 2));
452
- max-width: calc(41.66% - (var(--qbo-margin) / 2));
453
- }
454
-
455
- .qbo-col-6 {
456
- flex: 0 0 calc(50% - (var(--qbo-margin) / 2));
457
- max-width: calc(50% - (var(--qbo-margin) / 2));
458
- }
459
-
460
- .qbo-col-7 {
461
- flex: 0 0 calc(58.33% - (var(--qbo-margin) / 2));
462
- max-width: calc(58.33% - (var(--qbo-margin) / 2));
463
- }
464
-
465
- .qbo-col-8 {
466
- flex: 0 0 calc(66.66% - (var(--qbo-margin) / 2));
467
- max-width: calc(66.66% - (var(--qbo-margin) / 2));
468
- }
469
-
470
- .qbo-col-9 {
471
- flex: 0 0 calc(75% - (var(--qbo-margin) / 2));
472
- max-width: calc(75% - (var(--qbo-margin) / 2));
473
- }
474
-
475
- .qbo-col-10 {
476
- flex: 0 0 calc(83.33% - (var(--qbo-margin) / 2));
477
- max-width: calc(83.33% - (var(--qbo-margin) / 2));
478
- }
479
-
480
- .qbo-col-11 {
481
- flex: 0 0 calc(91.66% - (var(--qbo-margin) / 2));
482
- max-width: calc(91.66% - (var(--qbo-margin) / 2));
483
- }
484
-
485
- .qbo-col-12 {
486
- flex: 0 0 calc(100% - (var(--qbo-margin) / 2));
487
- max-width: calc(100% - (var(--qbo-margin) / 2));
488
- }
489
-
490
390
  /* Menu */
491
391
  nav {
492
392
  --qbo-background-color: var(--qbo-nav-background-color, black);
@@ -507,7 +407,7 @@ nav {
507
407
  border: 1px solid var(--qbo-nav-background-color, black);
508
408
  cursor: pointer;
509
409
  display: inline-block;
510
- line-height: 1.5;
410
+ line-height: var(--qbo-line-height);
511
411
  padding: 5px;
512
412
 
513
413
  & svg {
@@ -560,35 +460,35 @@ menu.qbo-toolbar {
560
460
  flex-direction: row;
561
461
  margin-right: var(--qbo-margin);
562
462
 
563
- li {
463
+ > li {
564
464
  display: inline-block;
565
465
  margin-right: 0;
566
466
  color: var(--qbo-color);
567
467
  background-color: var(--qbo-background-color);
568
468
  border: 1px solid var(--qbo-border-color);
569
- padding: var(--qbo-padding);
570
- line-height: 1.5;
469
+ padding: var(--qbo-padding-vertical) var(--qbo-padding-horizontal);
470
+ line-height: var(--qbo-line-height);
571
471
  cursor: pointer;
572
472
  border-radius: 0;
573
473
  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
574
474
  text-decoration: none;
575
475
  }
576
476
 
577
- li:first-child {
477
+ > li:first-child {
578
478
  border-top-left-radius: var(--qbo-border-radius);
579
479
  border-bottom-left-radius: var(--qbo-border-radius);
580
480
  }
581
481
 
582
- li:last-child {
482
+ > li:last-child {
583
483
  border-top-right-radius: var(--qbo-border-radius);
584
484
  border-bottom-right-radius: var(--qbo-border-radius);
585
485
  }
586
486
 
587
- li:hover,
588
- li:focus {
487
+ > li:hover,
488
+ > li:focus {
589
489
  background-color: var(--qbo-border-color);
590
490
  text-decoration: none;
591
- line-height: 1.5;
491
+ line-height: var(--qbo-line-height);
592
492
  transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;
593
493
  }
594
494
  }
@@ -618,7 +518,7 @@ qbo-menu {
618
518
  border: 1px solid var(--qbo-border-color);
619
519
  border-radius: var(--qbo-border-radius);
620
520
  box-sizing: border-box;
621
- height: 0;
521
+ height: auto;
622
522
  list-style-type: none;
623
523
  margin: 0;
624
524
  padding-left: 0;
@@ -629,6 +529,18 @@ qbo-menu {
629
529
  *[data-mega].open,
630
530
  aside.open,
631
531
  menu.open {
532
+ visibility: visible;
533
+ }
534
+
535
+ *[data-mega],
536
+ aside {
537
+ width: 0;
538
+ margin: var(--qbo-margin);
539
+ padding: var(--qbo-padding-vertical) var(--qbo-padding-horizontal);
540
+ padding-bottom: .6em;
541
+ overflow-y: scroll;
542
+ top: 53px !important;
543
+ width: 100%;
632
544
  background-color: #f0f0f0;
633
545
  border: 0;
634
546
  border-radius: 0;
@@ -639,9 +551,6 @@ qbo-menu {
639
551
  left: 0px;
640
552
  margin: 0;
641
553
  overflow-y: auto;
642
- top: 53px !important;
643
- visibility: visible;
644
- width: 100%;
645
554
 
646
555
  > h1 {
647
556
  color: var(--qbo-color);
@@ -656,19 +565,11 @@ qbo-menu {
656
565
  }
657
566
  }
658
567
 
659
- *[data-mega],
660
- aside {
661
- width: 0;
662
- margin: var(--qbo-margin);
663
- padding: var(--qbo-padding-vertical) var(--qbo-padding-horizontal);
664
- padding-bottom: .6em;
665
- overflow-y: scroll;
666
- }
667
568
  /* Dropdown item styling for each li element */
668
569
  li {
669
570
  display: list-item !important;
670
- padding: var(--qbo-padding, 0.5rem 1rem);
671
- line-height: 1.5;
571
+ padding: var(--qbo-padding-vertical) var(--qbo-padding-horizontal);
572
+ line-height: var(--qbo-line-height);
672
573
  text-align: left;
673
574
  white-space: nowrap;
674
575
  cursor: pointer;
@@ -2,9 +2,9 @@ import { LitElement, PropertyValues } from "lit";
2
2
  import { Placement } from "@floating-ui/dom";
3
3
  export declare class QboMenu extends LitElement {
4
4
  placement: Placement;
5
+ type: string;
6
+ target: string | null;
5
7
  private isOpen;
6
- private slotElement;
7
- private menuSlotElement;
8
8
  private triggerButton;
9
9
  private menuContainer;
10
10
  private middleware;
@@ -14,6 +14,7 @@ export declare class QboMenu extends LitElement {
14
14
  handleMenuOpen: (event: Event) => void;
15
15
  handleOutsideClick: (event: Event) => void;
16
16
  firstUpdated(changes: PropertyValues): void;
17
+ showContextMenu: (event: Event) => void;
17
18
  toggleMenu: (event: Event) => void;
18
19
  closeMenu(): void;
19
20
  private updateMenuPosition;
@@ -8,13 +8,15 @@ var __metadata = (this && this.__metadata) || function (k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
10
  import { LitElement, html, css } from "lit";
11
- import { property, query, state } from "lit/decorators.js";
11
+ import { property, state } from "lit/decorators.js";
12
12
  import { computePosition, shift, flip } from "@floating-ui/dom";
13
13
  export class QboMenu extends LitElement {
14
14
  constructor() {
15
15
  super(...arguments);
16
16
  // Define the placement property with type `string`
17
17
  this.placement = "bottom-start";
18
+ this.type = "dropdown";
19
+ this.target = null;
18
20
  // Internal state to control menu visibility
19
21
  this.isOpen = false;
20
22
  this.middleware = [flip(), shift()];
@@ -27,50 +29,65 @@ export class QboMenu extends LitElement {
27
29
  }
28
30
  };
29
31
  this.handleOutsideClick = (event) => {
30
- const customEvent = event;
31
- const target = customEvent.target;
32
- if (target !== this && !this.contains(target)) {
32
+ const target = event.target;
33
+ const path = event.composedPath();
34
+ if (!path.includes(this)) {
33
35
  this.closeMenu();
34
36
  }
35
37
  };
38
+ this.showContextMenu = (event) => {
39
+ const clickEvent = event;
40
+ event.preventDefault();
41
+ event.stopPropagation();
42
+ this.isOpen = true;
43
+ this.menuContainer.classList.toggle("open", this.isOpen);
44
+ const source = {
45
+ getBoundingClientRect: () => ({
46
+ x: clickEvent.clientX,
47
+ y: clickEvent.clientY,
48
+ width: 0,
49
+ height: 0,
50
+ top: clickEvent.clientY,
51
+ left: clickEvent.clientX,
52
+ right: clickEvent.clientX,
53
+ bottom: clickEvent.clientY,
54
+ }),
55
+ };
56
+ this.updateMenuPosition(source);
57
+ };
36
58
  this.toggleMenu = (event) => {
37
- if (event.target instanceof HTMLElement
38
- || event.target instanceof SVGElement
39
- || event.target instanceof SVGUseElement) {
40
- let toggleMenu = true;
41
- let parent = event.target.parentElement;
42
- while (toggleMenu && parent) {
43
- if (parent instanceof HTMLElement && parent.tagName.toLowerCase() == 'aside')
44
- toggleMenu = false;
45
- else
46
- parent = parent.parentElement;
47
- }
48
- if (toggleMenu) {
49
- this.isOpen = !this.isOpen;
50
- this.menuContainer.classList.toggle("open", this.isOpen);
51
- if (this.isOpen) {
52
- this.updateMenuPosition();
53
- document.dispatchEvent(new CustomEvent("qbo-menu-open", {
54
- bubbles: true,
55
- composed: true,
56
- detail: { menu: this },
57
- }));
58
- }
59
- }
59
+ //event.preventDefault();
60
+ //event.stopPropagation();
61
+ const target = event.target;
62
+ const path = event.composedPath();
63
+ if (!path.includes(this.triggerButton) || path.includes(this.menuContainer))
64
+ return;
65
+ this.isOpen = !this.isOpen;
66
+ this.menuContainer.classList.toggle("open", this.isOpen);
67
+ if (this.isOpen) {
68
+ this.updateMenuPosition(this.triggerButton);
69
+ document.dispatchEvent(new CustomEvent("qbo-menu-open", {
70
+ bubbles: true,
71
+ composed: true,
72
+ detail: { menu: this },
73
+ }));
60
74
  }
61
75
  };
62
76
  }
63
77
  static { this.styles = css ``; }
64
78
  connectedCallback() {
65
79
  super.connectedCallback();
66
- // document.addEventListener("click", this.handleOutsideClick.bind);
67
- document.addEventListener("qbo-menu-open", this.handleMenuOpen.bind(this));
80
+ document.addEventListener("click", this.handleOutsideClick);
81
+ // document.addEventListener("qbo-menu-open", this.handleMenuOpen);
68
82
  }
69
83
  disconnectedCallback() {
70
84
  super.disconnectedCallback();
71
- // document.removeEventListener("click", this.handleOutsideClick);
72
- document.removeEventListener("qbo-menu-open", this.handleMenuOpen);
73
- this.triggerButton.removeEventListener("click", this.toggleMenu);
85
+ document.removeEventListener("click", this.handleOutsideClick);
86
+ // document.removeEventListener("qbo-menu-open", this.handleMenuOpen);
87
+ if (this.type === "context")
88
+ this.triggerButton.removeEventListener("contextmenu", this.showContextMenu);
89
+ else
90
+ this.triggerButton.removeEventListener("click", this.toggleMenu);
74
91
  }
75
92
  firstUpdated(changes) {
76
93
  super.firstUpdated(changes);
@@ -82,17 +99,38 @@ export class QboMenu extends LitElement {
82
99
  this.querySelector("*[data-content]") ||
83
100
  this.querySelector("aside") ||
84
101
  this.querySelector("menu");
85
- if (this.triggerButton != null)
86
- this.triggerButton.addEventListener("click", this.toggleMenu);
102
+ if (this.type === "context") {
103
+ if (this.target) {
104
+ this.triggerButton =
105
+ this.closest(this.target) ||
106
+ (() => {
107
+ const rootNode = this.getRootNode();
108
+ if (rootNode instanceof ShadowRoot ||
109
+ rootNode instanceof Document) {
110
+ return rootNode.querySelector(this.target);
111
+ }
112
+ return null;
113
+ })() ||
114
+ document.querySelector(this.target) ||
115
+ document;
116
+ }
117
+ this.triggerButton.addEventListener("contextmenu", this.showContextMenu);
118
+ }
119
+ else {
120
+ if (this.triggerButton != null)
121
+ this.triggerButton.addEventListener("click", this.toggleMenu);
122
+ }
87
123
  }
88
124
  closeMenu() {
89
125
  this.isOpen = false;
90
126
  this.menuContainer.classList.remove("open");
91
127
  }
92
- async updateMenuPosition() {
93
- const { x, y } = await computePosition(this.triggerButton, this.menuContainer, {
128
+ async updateMenuPosition(source) {
129
+ console.log(source, typeof source);
130
+ const { x, y } = await computePosition(source, this.menuContainer, {
94
131
  placement: this.placement,
95
132
  middleware: this.middleware,
133
+ strategy: 'fixed'
96
134
  });
97
135
  Object.assign(this.menuContainer.style, {
98
136
  left: `${x}px`,
@@ -107,17 +145,17 @@ __decorate([
107
145
  property({ type: String }),
108
146
  __metadata("design:type", String)
109
147
  ], QboMenu.prototype, "placement", void 0);
148
+ __decorate([
149
+ property(),
150
+ __metadata("design:type", String)
151
+ ], QboMenu.prototype, "type", void 0);
152
+ __decorate([
153
+ property(),
154
+ __metadata("design:type", Object)
155
+ ], QboMenu.prototype, "target", void 0);
110
156
  __decorate([
111
157
  state(),
112
158
  __metadata("design:type", Object)
113
159
  ], QboMenu.prototype, "isOpen", void 0);
114
- __decorate([
115
- query("slot"),
116
- __metadata("design:type", HTMLSlotElement)
117
- ], QboMenu.prototype, "slotElement", void 0);
118
- __decorate([
119
- query('slot[name="menu"]'),
120
- __metadata("design:type", HTMLSlotElement)
121
- ], QboMenu.prototype, "menuSlotElement", void 0);
122
160
  if (!customElements.get("qbo-menu"))
123
161
  customElements.define("qbo-menu", QboMenu);