diff --git a/src/lib/help-mode/help-button/help-button.component.html b/src/lib/help-mode/help-button/help-button.component.html index 1e611bb..68369e2 100644 --- a/src/lib/help-mode/help-button/help-button.component.html +++ b/src/lib/help-mode/help-button/help-button.component.html @@ -2,12 +2,14 @@ [id]="buttonId" class="help-mode-slide-toggle" [class.dialog-toggle]="dialogButton" - [class.active]="helpModeService.isHelpModeActive" + [class.active]="helpModeService.isHelpModeActive()" [matTooltip]="buttonTooltip" + #helpModeButton > - -
-
- + +
+
+ +
diff --git a/src/lib/help-mode/help-button/help-button.component.scss b/src/lib/help-mode/help-button/help-button.component.scss index 1d5c87c..2392292 100644 --- a/src/lib/help-mode/help-button/help-button.component.scss +++ b/src/lib/help-mode/help-button/help-button.component.scss @@ -22,27 +22,24 @@ } .toggle-track { - position: absolute; - top: 50%; - left: 0; + position: relative; + display: flex; + align-items: center; + justify-content: start; width: 100%; height: 25px; background-color: var(--iqser-grey-4); border-radius: 20px; - transform: translateY(-50%); } .toggle-thumb { - position: absolute; - top: 50%; - left: 4px; + margin-left: 6%; width: 20px; height: 20px; background-color: #fff; border-radius: 50%; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); - transform: translateY(-50%); - transition: left 0.3s ease; + transition: margin-left 0.3s ease; display: flex; align-items: center; justify-content: center; @@ -60,7 +57,9 @@ background: var(--iqser-helpmode-primary); } - .toggle-input:checked + .toggle-track + .toggle-thumb { - left: calc(100% - 22px); + .toggle-input:checked + .toggle-track { + .toggle-thumb { + margin-left: 43.5%; + } } } diff --git a/src/lib/help-mode/help-button/help-button.component.ts b/src/lib/help-mode/help-button/help-button.component.ts index 437669b..9db9a60 100644 --- a/src/lib/help-mode/help-button/help-button.component.ts +++ b/src/lib/help-mode/help-button/help-button.component.ts @@ -1,5 +1,5 @@ /* eslint-disable @angular-eslint/prefer-on-push-component-change-detection */ -import { AfterViewInit, Component, ElementRef, HostListener, Input, OnDestroy, OnInit } from '@angular/core'; +import { Component, effect, ElementRef, Input, OnDestroy, OnInit, viewChild } from '@angular/core'; import { MatIcon } from '@angular/material/icon'; import { HelpModeService } from '../help-mode.service'; import { MatTooltip } from '@angular/material/tooltip'; @@ -13,15 +13,30 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; standalone: true, imports: [MatIcon, MatTooltip], }) -export class HelpButtonComponent implements OnInit, AfterViewInit, OnDestroy { +export class HelpButtonComponent implements OnInit, OnDestroy { + #helpModeHasBeenActivated = false; + readonly helpModeButton = viewChild.required('helpModeButton'); @Input() dialogButton = true; - helpModeButton: HTMLElement; constructor( private readonly _elementRef: ElementRef, private readonly _translateService: TranslateService, readonly helpModeService: HelpModeService, - ) {} + ) { + effect(() => { + if (this.helpModeService.isHelpModeActive()) { + this.#helpModeHasBeenActivated = true; + this.#applyActiveButtonStyles(); + } else if (this.#helpModeHasBeenActivated) { + this.#applyInactiveButtonStyles(); + } + }); + } + + get buttonTooltip() { + const translation = this.helpModeService.isHelpModeActive() ? _('help-button.disable') : _('help-button.enable'); + return this._translateService.instant(translation); + } get buttonId() { return `help-mode-button${this.dialogButton ? '-dialog' : ''}`; @@ -34,47 +49,42 @@ export class HelpButtonComponent implements OnInit, AfterViewInit, OnDestroy { } } - ngAfterViewInit() { - const currentComponent = this._elementRef.nativeElement; - this.helpModeButton = currentComponent.querySelector('.help-mode-slide-toggle'); - - if (this.helpModeButton) { - setTimeout(() => { - const currentComponentRect = currentComponent.getBoundingClientRect(); - this.helpModeButton.style.setProperty('position', 'absolute'); - this.helpModeButton.style.setProperty('top', `${currentComponentRect.top}px`); - this.helpModeButton.style.setProperty('left', `${currentComponentRect.left}px`); - document.body.appendChild(this.helpModeButton); - }, 500); - } - } - ngOnDestroy() { - document.body.removeChild(this.helpModeButton); if (this.dialogButton) { const defaultButton = document.getElementById('help-mode-button') as HTMLElement; defaultButton.style.removeProperty('z-index'); + if (!this.helpModeService.isHelpModeActive()) { + document.querySelectorAll('iqser-help-button')[this.dialogButton ? 1 : 0]?.removeChild(this.helpModeButton().nativeElement); + } } } toggleHelpMode(): void { - if (this.helpModeService.isHelpModeActive) { + if (this.helpModeService.isHelpModeActive()) { this.helpModeService.deactivateHelpMode(); return; } this.helpModeService.activateHelpMode(this.dialogButton); } - @HostListener('window:resize', ['$event']) - onResize() { + #applyActiveButtonStyles() { const currentComponent = this._elementRef.nativeElement; const currentComponentRect = currentComponent.getBoundingClientRect(); - this.helpModeButton?.style.setProperty('top', `${currentComponentRect.top}px`); - this.helpModeButton?.style.setProperty('left', `${currentComponentRect.left}px`); + setTimeout(() => { + this.helpModeButton().nativeElement.style.setProperty('position', 'absolute'); + this.helpModeButton().nativeElement.style.setProperty('top', `${currentComponentRect.top}px`); + this.helpModeButton().nativeElement.style.setProperty('left', `${currentComponentRect.left}px`); + document.body.appendChild(this.helpModeButton().nativeElement); + }, 500); } - get buttonTooltip() { - const translation = this.helpModeService.isHelpModeActive ? _('help-button.disable') : _('help-button.enable'); - return this._translateService.instant(translation); + #applyInactiveButtonStyles() { + setTimeout(() => { + this.helpModeButton().nativeElement.style.setProperty('position', 'relative'); + this.helpModeButton().nativeElement.style.setProperty('top', 'unset'); + this.helpModeButton().nativeElement.style.setProperty('left', 'unset'); + document.body.removeChild(this.helpModeButton().nativeElement); + document.querySelectorAll('iqser-help-button')[this.dialogButton ? 1 : 0]?.appendChild(this.helpModeButton().nativeElement); + }, 500); } } diff --git a/src/lib/help-mode/help-mode.service.ts b/src/lib/help-mode/help-mode.service.ts index 3be3294..6345b7c 100644 --- a/src/lib/help-mode/help-mode.service.ts +++ b/src/lib/help-mode/help-mode.service.ts @@ -2,8 +2,8 @@ import { Inject, Injectable, Renderer2, RendererFactory2 } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { TranslateService } from '@ngx-translate/core'; import { BehaviorSubject, firstValueFrom } from 'rxjs'; -import { getConfig } from '../services/iqser-config.service'; -import { IqserUserPreferenceService } from '../services/iqser-user-preference.service'; +import { getConfig } from '../services'; +import { IqserUserPreferenceService } from '../services'; import { HelpModeDialogComponent } from './help-mode-dialog/help-mode-dialog.component'; import { HELP_MODE_KEYS, MANUAL_BASE_URL } from './tokens'; import { HelpModeKey } from './types'; @@ -20,6 +20,7 @@ import { ScrollableParentViews, WEB_VIEWER_ELEMENTS, } from './utils/constants'; +import { toSignal } from '@angular/core/rxjs-interop'; export interface Helper { readonly element: HTMLElement; @@ -39,6 +40,7 @@ export class HelpModeService { #helpers: Record = {}; #dialogMode = false; readonly isHelpModeActive$ = this.#isHelpModeActive$.asObservable(); + readonly isHelpModeActive = toSignal(this.isHelpModeActive$, { initialValue: false }); readonly helpModeDialogIsOpened$ = this.#helpModeDialogIsOpened$.asObservable(); constructor( @@ -52,10 +54,6 @@ export class HelpModeService { this.#renderer = this._rendererFactory.createRenderer(null, null); } - get isHelpModeActive(): boolean { - return this.#isHelpModeActive$.getValue(); - } - get helpModeDialogIsOpened(): boolean { return this.#helpModeDialogIsOpened$.getValue(); } @@ -78,7 +76,7 @@ export class HelpModeService { } activateHelpMode(dialogMode: boolean = false): void { - if (!this.isHelpModeActive) { + if (!this.isHelpModeActive()) { document.body.style.setProperty('overflow', 'unset'); this.#isHelpModeActive$.next(true); this.openHelpModeDialog(); @@ -92,7 +90,7 @@ export class HelpModeService { } deactivateHelpMode(): void { - if (this.isHelpModeActive) { + if (this.isHelpModeActive()) { document.body.style.removeProperty('overflow'); this.#isHelpModeActive$.next(false); this.#disableHelperElements(); diff --git a/src/lib/help-mode/help-mode/help-mode.component.ts b/src/lib/help-mode/help-mode/help-mode.component.ts index 337a924..5f640c4 100644 --- a/src/lib/help-mode/help-mode/help-mode.component.ts +++ b/src/lib/help-mode/help-mode/help-mode.component.ts @@ -24,7 +24,7 @@ export class HelpModeComponent { @HostListener('document:keydown.escape', ['$event']) onEscKeydownHandler(event: KeyboardEvent): void { - if (!this.helpModeService.helpModeDialogIsOpened && this.helpModeService.isHelpModeActive) { + if (!this.helpModeService.helpModeDialogIsOpened && this.helpModeService.isHelpModeActive()) { event?.stopPropagation(); this.helpModeService.deactivateHelpMode(); } @@ -33,7 +33,7 @@ export class HelpModeComponent { @HostListener('document:keydown.h', ['$event']) onHKeydownHandler(event: KeyboardEvent): void { const node = (event.target as IqserEventTarget).localName; - if (!this.helpModeService.isHelpModeActive && node !== 'input' && node !== 'textarea') { + if (!this.helpModeService.isHelpModeActive() && node !== 'input' && node !== 'textarea') { const dialogMode = !!this._dialog.openDialogs.length; this.helpModeService.activateHelpMode(dialogMode); } @@ -41,14 +41,14 @@ export class HelpModeComponent { @HostListener('click') onClick(): void { - if (this.helpModeService.isHelpModeActive) { + if (this.helpModeService.isHelpModeActive()) { this.helpModeService.highlightHelperElements(); } } @HostListener('window:resize') onResize() { - if (this.helpModeService.isHelpModeActive) { + if (this.helpModeService.isHelpModeActive()) { this.helpModeService.updateHelperElements(); } }