From 1d76728e9d967c730611e4c7f04b7bc2084b4eeb Mon Sep 17 00:00:00 2001
From: rhenck <richard.henck@iqb.hu-berlin.de>
Date: Thu, 20 Jan 2022 13:23:29 +0100
Subject: [PATCH] [editor] Make menus not close when clicking on them

Also focus the height input field upon opening the menu.
For the layout menu this does not work as checkboxes don't play nicely
with menus.

In fact having anything but button in the menu is against the Material
spec. But i still think this is the best way to achieve the usability we
want.
---
 .../canvas/section-menu.component.ts          | 148 +++++++++---------
 .../unit-view/unit-view.component.html        | 134 ++++++++--------
 2 files changed, 144 insertions(+), 138 deletions(-)

diff --git a/projects/editor/src/app/components/unit-view/page-view/canvas/section-menu.component.ts b/projects/editor/src/app/components/unit-view/page-view/canvas/section-menu.component.ts
index 23e31341c..4dee89ed9 100644
--- a/projects/editor/src/app/components/unit-view/page-view/canvas/section-menu.component.ts
+++ b/projects/editor/src/app/components/unit-view/page-view/canvas/section-menu.component.ts
@@ -28,13 +28,15 @@ import { UIElement } from '../../../../../../../common/models/uI-element';
       <mat-icon>height</mat-icon>
     </button>
     <mat-menu #heightMenu="matMenu" class="layoutMenu" xPosition="before">
-      <mat-form-field appearance="fill">
-        <mat-label>Höhe</mat-label>
-        <input matInput type="number"
-               [value]="$any(section.height)"
-               (click)="$any($event).stopPropagation()"
-               (change)="updateModel('height', $any($event.target).value)">
-      </mat-form-field>
+      <div (click)="$event.stopPropagation()">
+        <mat-form-field appearance="fill">
+          <mat-label>Höhe</mat-label>
+          <input matInput mat-menu-item type="number"
+                 [value]="$any(section.height)"
+                 (click)="$any($event).stopPropagation()"
+                 (change)="updateModel('height', $any($event.target).value)">
+        </mat-form-field>
+      </div>
     </mat-menu>
     <button mat-mini-fab
             (click)="openColorPicker()">
@@ -48,75 +50,77 @@ import { UIElement } from '../../../../../../../common/models/uI-element';
       <mat-icon>space_dashboard</mat-icon>
     </button>
     <mat-menu #layoutMenu="matMenu" class="layoutMenu" xPosition="before">
-      <mat-checkbox class="menuItem" [checked]="section.dynamicPositioning"
-                    (click)="$any($event).stopPropagation()"
-                    (change)="updateModel('dynamicPositioning', $event.checked)">
-        dynamisches Layout
-      </mat-checkbox>
-      <div *ngIf="section.dynamicPositioning">
-        Spalten
-        <div class="size-group">
-          <mat-form-field>
-            <mat-label>Anzahl</mat-label>
-            <input matInput type="number"
-                   [value]="$any(section.gridColumnSizes.split(' ').length)"
-                   (click)="$any($event).stopPropagation()"
-                   (change)="modifySizeArray('gridColumnSizes', $any($event).target.value)">
-          </mat-form-field>
-          <mat-checkbox class="menuItem" [checked]="section.autoColumnSize"
+      <div (click)="$event.stopPropagation()">
+          <mat-checkbox class="menuItem" [checked]="section.dynamicPositioning"
                         (click)="$any($event).stopPropagation()"
-                        (change)="updateModel('autoColumnSize', $event.checked)">
-            dynamische Breite
+                        (change)="updateModel('dynamicPositioning', $event.checked)">
+            dynamisches Layout
           </mat-checkbox>
-          <ng-container *ngIf="!section.autoColumnSize">
-            <div *ngFor="let size of columnSizes ; let i = index" class="size-inputs" fxLayout="row">
-              <mat-form-field>
-                <mat-label>Breite {{i + 1}}</mat-label>
-                <input matInput type="number"
-                       [value]="size.value"
-                       (click)="$any($event).stopPropagation()"
-                       (change)="changeGridSize('gridColumnSizes', i, false, $any($event).target.value)">
-              </mat-form-field>
-              <mat-select [value]="size.unit"
+        <div *ngIf="section.dynamicPositioning">
+          Spalten
+          <div class="size-group">
+            <mat-form-field>
+              <mat-label>Anzahl</mat-label>
+              <input matInput type="number"
+                     [value]="$any(section.gridColumnSizes.split(' ').length)"
+                     (click)="$any($event).stopPropagation()"
+                     (change)="modifySizeArray('gridColumnSizes', $any($event).target.value)">
+            </mat-form-field>
+            <mat-checkbox class="menuItem" [checked]="section.autoColumnSize"
                           (click)="$any($event).stopPropagation()"
-                          (selectionChange)="changeGridSize('gridColumnSizes', i, true, $event.value)">
-                <mat-option value="fr">Anteile</mat-option>
-                <mat-option value="px">Bildpunkte</mat-option>
-              </mat-select>
-            </div>
-          </ng-container>
-        </div>
-        Zeilen
-        <div class="size-group">
-          <mat-form-field>
-            <mat-label>Anzahl</mat-label>
-            <input matInput type="number"
-                   [value]="$any(section.gridRowSizes.split(' ').length)"
-                   (click)="$any($event).stopPropagation()"
-                   (change)="modifySizeArray('gridRowSizes', $any($event).target.value)">
-          </mat-form-field>
-          <mat-checkbox class="menuItem" [checked]="section.autoRowSize"
-                        (click)="$any($event).stopPropagation()"
-                        (change)="updateModel('autoRowSize', $event.checked)">
-            dynamische Höhe
-          </mat-checkbox>
-          <ng-container *ngIf="!section.autoRowSize">
-            <div *ngFor="let size of rowSizes ; let i = index" class="size-inputs" fxLayout="row">
-              <mat-form-field>
-                <mat-label>Höhe {{i + 1}}</mat-label>
-                <input matInput type="number"
-                       [value]="size.value"
-                       (click)="$any($event).stopPropagation()"
-                       (change)="changeGridSize('gridRowSizes', i, false, $any($event).target.value)">
-              </mat-form-field>
-              <mat-select [value]="size.unit"
+                          (change)="updateModel('autoColumnSize', $event.checked)">
+              dynamische Breite
+            </mat-checkbox>
+            <ng-container *ngIf="!section.autoColumnSize">
+              <div *ngFor="let size of columnSizes ; let i = index" class="size-inputs" fxLayout="row">
+                <mat-form-field>
+                  <mat-label>Breite {{i + 1}}</mat-label>
+                  <input matInput type="number"
+                         [value]="size.value"
+                         (click)="$any($event).stopPropagation()"
+                         (change)="changeGridSize('gridColumnSizes', i, false, $any($event).target.value)">
+                </mat-form-field>
+                <mat-select [value]="size.unit"
+                            (click)="$any($event).stopPropagation()"
+                            (selectionChange)="changeGridSize('gridColumnSizes', i, true, $event.value)">
+                  <mat-option value="fr">Anteile</mat-option>
+                  <mat-option value="px">Bildpunkte</mat-option>
+                </mat-select>
+              </div>
+            </ng-container>
+          </div>
+          Zeilen
+          <div class="size-group">
+            <mat-form-field>
+              <mat-label>Anzahl</mat-label>
+              <input matInput type="number"
+                     [value]="$any(section.gridRowSizes.split(' ').length)"
+                     (click)="$any($event).stopPropagation()"
+                     (change)="modifySizeArray('gridRowSizes', $any($event).target.value)">
+            </mat-form-field>
+            <mat-checkbox class="menuItem" [checked]="section.autoRowSize"
                           (click)="$any($event).stopPropagation()"
-                          (selectionChange)="changeGridSize('gridRowSizes', i, true, $event.value)">
-                <mat-option value="fr">Anteile</mat-option>
-                <mat-option value="px">Bildpunkte</mat-option>
-              </mat-select>
-            </div>
-          </ng-container>
+                          (change)="updateModel('autoRowSize', $event.checked)">
+              dynamische Höhe
+            </mat-checkbox>
+            <ng-container *ngIf="!section.autoRowSize">
+              <div *ngFor="let size of rowSizes ; let i = index" class="size-inputs" fxLayout="row">
+                <mat-form-field>
+                  <mat-label>Höhe {{i + 1}}</mat-label>
+                  <input matInput type="number"
+                         [value]="size.value"
+                         (click)="$any($event).stopPropagation()"
+                         (change)="changeGridSize('gridRowSizes', i, false, $any($event).target.value)">
+                </mat-form-field>
+                <mat-select [value]="size.unit"
+                            (click)="$any($event).stopPropagation()"
+                            (selectionChange)="changeGridSize('gridRowSizes', i, true, $event.value)">
+                  <mat-option value="fr">Anteile</mat-option>
+                  <mat-option value="px">Bildpunkte</mat-option>
+                </mat-select>
+              </div>
+            </ng-container>
+          </div>
         </div>
       </div>
     </mat-menu>
diff --git a/projects/editor/src/app/components/unit-view/unit-view.component.html b/projects/editor/src/app/components/unit-view/unit-view.component.html
index a7e6c798b..b0da05308 100644
--- a/projects/editor/src/app/components/unit-view/unit-view.component.html
+++ b/projects/editor/src/app/components/unit-view/unit-view.component.html
@@ -31,72 +31,74 @@
               <mat-icon>more_vert</mat-icon>
             </button>
             <mat-menu #pageMenu="matMenu">
-              <button *ngIf="!page.alwaysVisible"
-                      mat-menu-item (click)="movePage(page,'up')">
-                <mat-icon>west</mat-icon>
-                <span>{{'forward' | translate }}</span>
-              </button>
-              <button *ngIf="!page.alwaysVisible"
-                      mat-menu-item (click)="movePage(page, 'down')">
-                <mat-icon>east</mat-icon>
-                <span>{{'backward' | translate }}</span>
-              </button>
-              <button mat-menu-item (click)="deletePage(page)">
-                <mat-icon>delete</mat-icon>
-                <span>{{'delete' | translate }}</span>
-              </button>
-              <mat-divider></mat-divider>
-              <mat-checkbox class="menuItem" [checked]="page.hasMaxWidth"
-                            (click)="$any($event).stopPropagation()"
-                            (change)="updateModel(page, 'hasMaxWidth', $any($event.source).checked)">
-                {{'pageProperties.maxWidth' | translate }}
-              </mat-checkbox>
-              <mat-form-field *ngIf="page.hasMaxWidth" class="menuItem" appearance="fill">
-                <mat-label>{{'maxWidth' | translate }}</mat-label>
-                <input matInput type="number" min="0" #maxWidth="ngModel"
-                       [ngModel]="page.maxWidth"
-                       (click)="$any($event).stopPropagation()"
-                       (ngModelChange)="updateModel(page,'maxWidth', $event, maxWidth.valid)">
-              </mat-form-field>
-              <mat-form-field class="menuItem" appearance="fill">
-                <mat-label>{{'pageProperties.marginWidth' | translate }}</mat-label>
-                <input matInput type="number" min="0" #margin="ngModel"
-                       [ngModel]="page.margin"
-                       (click)="$any($event).stopPropagation()"
-                       (ngModelChange)="updateModel(page,'margin', $event, margin.valid)">
-              </mat-form-field>
-              <mat-form-field class="menuItem" appearance="fill">
-                <mat-label>{{'pageProperties.backgroundColor' | translate }}</mat-label>
-                <input matInput type="color"
-                       [value]="page.backgroundColor"
-                       (change)="updateModel(page,'backgroundColor', $any($event.target).value)">
-              </mat-form-field>
-              <mat-checkbox class="menuItem"
-                            [disabled]="unitService.unit.pages.length < 2 || unitService.unit.pages[0].alwaysVisible && i != 0"
-                            [ngModel]="page.alwaysVisible"
-                            (click)="$any($event).stopPropagation()"
-                            (change)="updateModel(page, 'alwaysVisible', $any($event.source).checked)">
-                {{'pageProperties.alwaysVisible' | translate }}
-              </mat-checkbox>
-              <mat-form-field *ngIf="page.alwaysVisible" class="menuItem" appearance="fill">
-                <mat-label>{{'pageProperties.position' | translate }}</mat-label>
-                <mat-select [value]="page.alwaysVisiblePagePosition"
-                            (click)="$any($event).stopPropagation()"
-                            (selectionChange)="updateModel(page, 'alwaysVisiblePagePosition', $event.value)">
-                  <mat-option *ngFor="let option of ['left', 'right', 'top', 'bottom']"
-                              [value]="option">
-                    {{option | translate}}
-                  </mat-option>
-                </mat-select>
-              </mat-form-field>
-              <mat-form-field class="menuItem" appearance="fill"
-                              *ngIf="page.alwaysVisible">
-                <mat-label>{{'pageProperties.alwaysVisibleAspectRatio' | translate }}</mat-label>
-                <input matInput type="number" min="0" max="100"
-                       [ngModel]="page.alwaysVisibleAspectRatio"
-                       (click)="$any($event).stopPropagation()"
-                       (ngModelChange)="updateModel(page, 'alwaysVisibleAspectRatio', $event)">
-              </mat-form-field>
+              <div (click)="$event.stopPropagation()">
+                <button *ngIf="!page.alwaysVisible"
+                        mat-menu-item (click)="movePage(page,'up')">
+                  <mat-icon>west</mat-icon>
+                  <span>{{'forward' | translate }}</span>
+                </button>
+                <button *ngIf="!page.alwaysVisible"
+                        mat-menu-item (click)="movePage(page, 'down')">
+                  <mat-icon>east</mat-icon>
+                  <span>{{'backward' | translate }}</span>
+                </button>
+                <button mat-menu-item (click)="deletePage(page)">
+                  <mat-icon>delete</mat-icon>
+                  <span>{{'delete' | translate }}</span>
+                </button>
+                <mat-divider></mat-divider>
+                <mat-checkbox class="menuItem" [checked]="page.hasMaxWidth"
+                              (click)="$any($event).stopPropagation()"
+                              (change)="updateModel(page, 'hasMaxWidth', $any($event.source).checked)">
+                  {{'pageProperties.maxWidth' | translate }}
+                </mat-checkbox>
+                <mat-form-field *ngIf="page.hasMaxWidth" class="menuItem" appearance="fill">
+                  <mat-label>{{'maxWidth' | translate }}</mat-label>
+                  <input matInput type="number" min="0" #maxWidth="ngModel"
+                         [ngModel]="page.maxWidth"
+                         (click)="$any($event).stopPropagation()"
+                         (ngModelChange)="updateModel(page,'maxWidth', $event, maxWidth.valid)">
+                </mat-form-field>
+                <mat-form-field class="menuItem" appearance="fill">
+                  <mat-label>{{'pageProperties.marginWidth' | translate }}</mat-label>
+                  <input matInput type="number" min="0" #margin="ngModel"
+                         [ngModel]="page.margin"
+                         (click)="$any($event).stopPropagation()"
+                         (ngModelChange)="updateModel(page,'margin', $event, margin.valid)">
+                </mat-form-field>
+                <mat-form-field class="menuItem" appearance="fill">
+                  <mat-label>{{'pageProperties.backgroundColor' | translate }}</mat-label>
+                  <input matInput type="color"
+                         [value]="page.backgroundColor"
+                         (change)="updateModel(page,'backgroundColor', $any($event.target).value)">
+                </mat-form-field>
+                <mat-checkbox class="menuItem"
+                              [disabled]="unitService.unit.pages.length < 2 || unitService.unit.pages[0].alwaysVisible && i != 0"
+                              [ngModel]="page.alwaysVisible"
+                              (click)="$any($event).stopPropagation()"
+                              (change)="updateModel(page, 'alwaysVisible', $any($event.source).checked)">
+                  {{'pageProperties.alwaysVisible' | translate }}
+                </mat-checkbox>
+                <mat-form-field *ngIf="page.alwaysVisible" class="menuItem" appearance="fill">
+                  <mat-label>{{'pageProperties.position' | translate }}</mat-label>
+                  <mat-select [value]="page.alwaysVisiblePagePosition"
+                              (click)="$any($event).stopPropagation()"
+                              (selectionChange)="updateModel(page, 'alwaysVisiblePagePosition', $event.value)">
+                    <mat-option *ngFor="let option of ['left', 'right', 'top', 'bottom']"
+                                [value]="option">
+                      {{option | translate}}
+                    </mat-option>
+                  </mat-select>
+                </mat-form-field>
+                <mat-form-field class="menuItem" appearance="fill"
+                                *ngIf="page.alwaysVisible">
+                  <mat-label>{{'pageProperties.alwaysVisibleAspectRatio' | translate }}</mat-label>
+                  <input matInput type="number" min="0" max="100"
+                         [ngModel]="page.alwaysVisibleAspectRatio"
+                         (click)="$any($event).stopPropagation()"
+                         (ngModelChange)="updateModel(page, 'alwaysVisibleAspectRatio', $event)">
+                </mat-form-field>
+              </div>
             </mat-menu>
 
           </ng-template>
-- 
GitLab