matcha-components 20.198.0 → 20.199.0
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.
|
@@ -331,7 +331,7 @@ class MatchaPanelComponent {
|
|
|
331
331
|
const viewportWidth = window.innerWidth;
|
|
332
332
|
const margin = 10;
|
|
333
333
|
// Posicionamento lateral (para submenus)
|
|
334
|
-
if (this.placement === '
|
|
334
|
+
if (this.placement === 'side') {
|
|
335
335
|
return this.calculateSidePosition(rect, viewportWidth, viewportHeight, margin);
|
|
336
336
|
}
|
|
337
337
|
let top;
|
|
@@ -341,6 +341,13 @@ class MatchaPanelComponent {
|
|
|
341
341
|
let maxHeight = this.maxHeight;
|
|
342
342
|
let placement = 'bottom';
|
|
343
343
|
let actualHeight = 0;
|
|
344
|
+
// Para max-content, medir a largura real renderizada do painel
|
|
345
|
+
if (this.widthMode === 'max-content' && this.paneRef) {
|
|
346
|
+
const panelWidth = this.paneRef.nativeElement.scrollWidth;
|
|
347
|
+
if (panelWidth > width) {
|
|
348
|
+
width = panelWidth;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
344
351
|
// Determinar se deve abrir para cima ou para baixo
|
|
345
352
|
const spaceBelow = viewportHeight - rect.bottom - margin;
|
|
346
353
|
const spaceAbove = rect.top - margin;
|
|
@@ -366,10 +373,11 @@ class MatchaPanelComponent {
|
|
|
366
373
|
}
|
|
367
374
|
// Posicionamento horizontal: alinhar à esquerda do trigger
|
|
368
375
|
left = rect.left;
|
|
369
|
-
//
|
|
376
|
+
// Se o painel ultrapassa a tela pela direita, alinhar pela direita do trigger
|
|
370
377
|
if (left + width > viewportWidth - margin) {
|
|
371
|
-
left =
|
|
378
|
+
left = rect.right - width;
|
|
372
379
|
}
|
|
380
|
+
// Se ainda ultrapassa pela esquerda, empurrar para a margem
|
|
373
381
|
if (left < margin) {
|
|
374
382
|
left = margin;
|
|
375
383
|
width = Math.min(width, viewportWidth - 2 * margin);
|
|
@@ -383,21 +391,33 @@ class MatchaPanelComponent {
|
|
|
383
391
|
}
|
|
384
392
|
/**
|
|
385
393
|
* Calcula posição lateral (para submenus multinível)
|
|
394
|
+
* Detecta automaticamente se deve abrir à direita ou à esquerda
|
|
386
395
|
*/
|
|
387
396
|
calculateSidePosition(rect, viewportWidth, viewportHeight, margin) {
|
|
388
|
-
|
|
397
|
+
let width = this.minWidth;
|
|
389
398
|
const maxHeight = this.maxHeight;
|
|
390
|
-
//
|
|
399
|
+
// Para max-content, medir a largura real renderizada
|
|
400
|
+
if (this.widthMode === 'max-content' && this.paneRef) {
|
|
401
|
+
const panelWidth = this.paneRef.nativeElement.scrollWidth;
|
|
402
|
+
if (panelWidth > width) {
|
|
403
|
+
width = panelWidth;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
// Auto-detectar: preferir direita, usar esquerda se não houver espaço
|
|
391
407
|
const spaceRight = viewportWidth - rect.right - margin;
|
|
392
408
|
const spaceLeft = rect.left - margin;
|
|
393
409
|
let left;
|
|
394
|
-
if (
|
|
395
|
-
|
|
410
|
+
if (spaceRight >= width) {
|
|
411
|
+
left = rect.right + 2;
|
|
412
|
+
}
|
|
413
|
+
else if (spaceLeft >= width) {
|
|
396
414
|
left = rect.left - width - 2;
|
|
397
415
|
}
|
|
398
416
|
else {
|
|
399
|
-
//
|
|
400
|
-
left =
|
|
417
|
+
// Nenhum lado cabe: abrir no lado com mais espaço
|
|
418
|
+
left = spaceRight >= spaceLeft
|
|
419
|
+
? rect.right + 2
|
|
420
|
+
: rect.left - width - 2;
|
|
401
421
|
}
|
|
402
422
|
// Posição vertical: alinhar o topo do submenu com o topo do item trigger
|
|
403
423
|
let top = rect.top;
|
|
@@ -411,7 +431,7 @@ class MatchaPanelComponent {
|
|
|
411
431
|
}
|
|
412
432
|
// Garantir que não saia da tela horizontalmente
|
|
413
433
|
if (left + width > viewportWidth - margin) {
|
|
414
|
-
left =
|
|
434
|
+
left = viewportWidth - width - margin;
|
|
415
435
|
}
|
|
416
436
|
if (left < margin) {
|
|
417
437
|
left = margin;
|
|
@@ -7457,7 +7477,7 @@ class MatchaMenuComponent {
|
|
|
7457
7477
|
constructor(cdr) {
|
|
7458
7478
|
this.cdr = cdr;
|
|
7459
7479
|
this.placement = 'auto';
|
|
7460
|
-
this._maxHeight =
|
|
7480
|
+
this._maxHeight = 300;
|
|
7461
7481
|
this._minWidth = 160;
|
|
7462
7482
|
this.opened = new EventEmitter();
|
|
7463
7483
|
this.closed = new EventEmitter();
|
|
@@ -7714,6 +7734,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImpor
|
|
|
7714
7734
|
}] } });
|
|
7715
7735
|
|
|
7716
7736
|
class MatchaSubmenuTriggerDirective {
|
|
7737
|
+
/** Detecta dispositivos sem hover (touch-primary) */
|
|
7738
|
+
get isTouch() {
|
|
7739
|
+
return window.matchMedia('(hover: none)').matches;
|
|
7740
|
+
}
|
|
7717
7741
|
constructor(el) {
|
|
7718
7742
|
this.el = el;
|
|
7719
7743
|
this.hasSubmenuClass = true;
|
|
@@ -7727,14 +7751,38 @@ class MatchaSubmenuTriggerDirective {
|
|
|
7727
7751
|
// Quando o mouse entra no painel do submenu, cancela TODA a cadeia de fechamento
|
|
7728
7752
|
this.submenu.onPanelMouseEnter = () => this.cancelClose();
|
|
7729
7753
|
// Quando o mouse sai do painel do submenu, agenda fechamento
|
|
7730
|
-
// apenas se não houver submenus filhos abertos
|
|
7754
|
+
// apenas se não houver submenus filhos abertos (ignora em touch)
|
|
7731
7755
|
this.submenu.onPanelMouseLeave = () => {
|
|
7732
|
-
if (!this.submenu.hasOpenSubMenus()) {
|
|
7756
|
+
if (!this.isTouch && !this.submenu.hasOpenSubMenus()) {
|
|
7733
7757
|
this.scheduleClose();
|
|
7734
7758
|
}
|
|
7735
7759
|
};
|
|
7736
7760
|
}
|
|
7761
|
+
onClick(event) {
|
|
7762
|
+
if (!this.isTouch)
|
|
7763
|
+
return;
|
|
7764
|
+
// Impedir que o clique propague para o onContentClick do menu pai
|
|
7765
|
+
event.stopPropagation();
|
|
7766
|
+
if (!this.submenu || !this.parentMenu)
|
|
7767
|
+
return;
|
|
7768
|
+
// Toggle: se já está aberto, fecha; senão, abre
|
|
7769
|
+
if (this.submenu.open) {
|
|
7770
|
+
this.submenu.closePanel();
|
|
7771
|
+
this.parentMenu.unregisterSubMenu(this.submenu);
|
|
7772
|
+
return;
|
|
7773
|
+
}
|
|
7774
|
+
// Fechar outros submenus do mesmo nível
|
|
7775
|
+
this.parentMenu.closeOtherSubMenus(this.submenu);
|
|
7776
|
+
// Configurar relação pai/filho e abrir
|
|
7777
|
+
this.submenu.parentMenu = this.parentMenu;
|
|
7778
|
+
this.submenu.placement = 'side';
|
|
7779
|
+
this.submenu.openPanel(this.el.nativeElement);
|
|
7780
|
+
this.parentMenu.registerSubMenu(this.submenu);
|
|
7781
|
+
}
|
|
7737
7782
|
onMouseEnter() {
|
|
7783
|
+
// Em touch, o submenu é controlado por click
|
|
7784
|
+
if (this.isTouch)
|
|
7785
|
+
return;
|
|
7738
7786
|
// Cancelar qualquer fechamento pendente neste nível e nos pais
|
|
7739
7787
|
this.cancelClose();
|
|
7740
7788
|
if (this.parentMenu) {
|
|
@@ -7746,7 +7794,7 @@ class MatchaSubmenuTriggerDirective {
|
|
|
7746
7794
|
this.parentMenu.closeOtherSubMenus(this.submenu);
|
|
7747
7795
|
// Configurar relação pai/filho
|
|
7748
7796
|
this.submenu.parentMenu = this.parentMenu;
|
|
7749
|
-
this.submenu.placement = '
|
|
7797
|
+
this.submenu.placement = 'side';
|
|
7750
7798
|
// Abrir o submenu posicionado ao lado deste item
|
|
7751
7799
|
if (!this.submenu.open) {
|
|
7752
7800
|
this.submenu.openPanel(this.el.nativeElement);
|
|
@@ -7754,6 +7802,9 @@ class MatchaSubmenuTriggerDirective {
|
|
|
7754
7802
|
}
|
|
7755
7803
|
}
|
|
7756
7804
|
onMouseLeave() {
|
|
7805
|
+
// Em touch, o submenu é controlado por click
|
|
7806
|
+
if (this.isTouch)
|
|
7807
|
+
return;
|
|
7757
7808
|
// Agendar fechamento mas o cancelClose será chamado
|
|
7758
7809
|
// se o mouse entrar no painel do submenu ou no item novamente
|
|
7759
7810
|
this.scheduleClose();
|
|
@@ -7789,7 +7840,7 @@ class MatchaSubmenuTriggerDirective {
|
|
|
7789
7840
|
}
|
|
7790
7841
|
}
|
|
7791
7842
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: MatchaSubmenuTriggerDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
7792
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.2", type: MatchaSubmenuTriggerDirective, isStandalone: false, selector: "[matchaSubmenuTriggerFor]", inputs: { submenu: ["matchaSubmenuTriggerFor", "submenu"], parentMenu: "parentMenu" }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()" }, properties: { "class.matcha-menu-item-has-submenu": "this.hasSubmenuClass" } }, ngImport: i0 }); }
|
|
7843
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.2", type: MatchaSubmenuTriggerDirective, isStandalone: false, selector: "[matchaSubmenuTriggerFor]", inputs: { submenu: ["matchaSubmenuTriggerFor", "submenu"], parentMenu: "parentMenu" }, host: { listeners: { "click": "onClick($event)", "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()" }, properties: { "class.matcha-menu-item-has-submenu": "this.hasSubmenuClass" } }, ngImport: i0 }); }
|
|
7793
7844
|
}
|
|
7794
7845
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImport: i0, type: MatchaSubmenuTriggerDirective, decorators: [{
|
|
7795
7846
|
type: Directive,
|
|
@@ -7805,6 +7856,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.2", ngImpor
|
|
|
7805
7856
|
}], hasSubmenuClass: [{
|
|
7806
7857
|
type: HostBinding,
|
|
7807
7858
|
args: ['class.matcha-menu-item-has-submenu']
|
|
7859
|
+
}], onClick: [{
|
|
7860
|
+
type: HostListener,
|
|
7861
|
+
args: ['click', ['$event']]
|
|
7808
7862
|
}], onMouseEnter: [{
|
|
7809
7863
|
type: HostListener,
|
|
7810
7864
|
args: ['mouseenter']
|