From b606d45ea271e6e6acdd9cb38edf77640942d5ec Mon Sep 17 00:00:00 2001 From: Umanskiy Aleksey Date: Mon, 4 Nov 2024 15:18:17 +0200 Subject: [PATCH 1/2] refactor(accordion): introducing signals signals --- .../src/lib/demos/animated/animated.ts | 6 ++- .../accordion/src/lib/demos/basic/basic.html | 2 +- .../lib/demos/custom-html/custom-html.html | 2 +- .../src/lib/demos/disabled/disabled.html | 2 +- .../src/lib/demos/dymanic/dynamic.html | 2 +- .../lib/demos/dynamic-body/dynamic-body.html | 2 +- .../demos/manual-toggle/manual-toggle.html | 2 +- .../src/lib/demos/open-event/open-event.html | 2 +- .../src/lib/demos/opened/opened.html | 2 +- .../src/lib/demos/styling/styling.html | 2 +- src/accordion/accordion-group.component.html | 12 +++--- src/accordion/accordion-group.component.ts | 42 ++++++++----------- src/accordion/accordion.component.ts | 30 +++++++++---- 13 files changed, 59 insertions(+), 49 deletions(-) diff --git a/libs/doc-pages/accordion/src/lib/demos/animated/animated.ts b/libs/doc-pages/accordion/src/lib/demos/animated/animated.ts index 6af8cdcb03..0096afaca1 100644 --- a/libs/doc-pages/accordion/src/lib/demos/animated/animated.ts +++ b/libs/doc-pages/accordion/src/lib/demos/animated/animated.ts @@ -1,8 +1,10 @@ -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; @Component({ // eslint-disable-next-line @angular-eslint/component-selector selector: 'demo-accordion-animation', - templateUrl: './animated.html' + templateUrl: './animated.html', + changeDetection: ChangeDetectionStrategy.OnPush }) export class DemoAccordionAnimatedComponent {} + diff --git a/libs/doc-pages/accordion/src/lib/demos/basic/basic.html b/libs/doc-pages/accordion/src/lib/demos/basic/basic.html index 21a2759b8b..02ff0a98da 100644 --- a/libs/doc-pages/accordion/src/lib/demos/basic/basic.html +++ b/libs/doc-pages/accordion/src/lib/demos/basic/basic.html @@ -1,4 +1,4 @@ - + This content is straight in the template. diff --git a/libs/doc-pages/accordion/src/lib/demos/custom-html/custom-html.html b/libs/doc-pages/accordion/src/lib/demos/custom-html/custom-html.html index 281f0598c7..905de847e5 100644 --- a/libs/doc-pages/accordion/src/lib/demos/custom-html/custom-html.html +++ b/libs/doc-pages/accordion/src/lib/demos/custom-html/custom-html.html @@ -1,4 +1,4 @@ - +

- + {{ group?.content }} diff --git a/libs/doc-pages/accordion/src/lib/demos/dynamic-body/dynamic-body.html b/libs/doc-pages/accordion/src/lib/demos/dynamic-body/dynamic-body.html index e122e3ba74..30510a373d 100644 --- a/libs/doc-pages/accordion/src/lib/demos/dynamic-body/dynamic-body.html +++ b/libs/doc-pages/accordion/src/lib/demos/dynamic-body/dynamic-body.html @@ -1,4 +1,4 @@ - +

The body of the accordion group grows to fit the contents

- +

accordion 1

diff --git a/libs/doc-pages/accordion/src/lib/demos/open-event/open-event.html b/libs/doc-pages/accordion/src/lib/demos/open-event/open-event.html index 03e913c4b7..8d7a3eeb58 100644 --- a/libs/doc-pages/accordion/src/lib/demos/open-event/open-event.html +++ b/libs/doc-pages/accordion/src/lib/demos/open-event/open-event.html @@ -1,4 +1,4 @@ - +

Some content

diff --git a/libs/doc-pages/accordion/src/lib/demos/opened/opened.html b/libs/doc-pages/accordion/src/lib/demos/opened/opened.html index 64561b29a2..05503cb57a 100644 --- a/libs/doc-pages/accordion/src/lib/demos/opened/opened.html +++ b/libs/doc-pages/accordion/src/lib/demos/opened/opened.html @@ -1,4 +1,4 @@ - +

accordion 1

diff --git a/libs/doc-pages/accordion/src/lib/demos/styling/styling.html b/libs/doc-pages/accordion/src/lib/demos/styling/styling.html index 1a78a356e3..7332ee96cb 100644 --- a/libs/doc-pages/accordion/src/lib/demos/styling/styling.html +++ b/libs/doc-pages/accordion/src/lib/demos/styling/styling.html @@ -1,4 +1,4 @@ - + diff --git a/src/accordion/accordion-group.component.html b/src/accordion/accordion-group.component.html index 84b2c126de..a03d8e743d 100644 --- a/src/accordion/accordion-group.component.html +++ b/src/accordion/accordion-group.component.html @@ -1,20 +1,20 @@ -
+
-
+
diff --git a/src/accordion/accordion-group.component.ts b/src/accordion/accordion-group.component.ts index 20e01f29a4..e1959b5e12 100644 --- a/src/accordion/accordion-group.component.ts +++ b/src/accordion/accordion-group.component.ts @@ -1,5 +1,5 @@ import { - Component, HostBinding, Inject, Input, OnDestroy, OnInit, Output, EventEmitter + Component, HostBinding, Inject, OnDestroy, OnInit, input, output, model } from '@angular/core'; import { AccordionComponent } from './accordion.component'; import { CollapseModule } from 'ngx-bootstrap/collapse'; @@ -27,44 +27,38 @@ export class AccordionPanelComponent implements OnInit, OnDestroy { /** turn on/off animation */ isAnimated = false; /** Clickable text in accordion's group header, check `accordion heading` below for using html in header */ - @Input() heading!: string; + public heading = input(); /** Provides an ability to use Bootstrap's contextual panel classes * (`panel-primary`, `panel-success`, `panel-info`, etc...). * List of all available classes [available here] * (https://getbootstrap.com/docs/3.3/components/#panels-alternatives) */ - @Input() panelClass = 'panel-default'; + public panelClass = input('panel-default'); /** if true — disables accordion group */ - @Input() isDisabled = false; + public isDisabled = input(false); /** Emits when the opened state changes */ - @Output() isOpenChange: EventEmitter = new EventEmitter(); + public isOpenChange = output(); // Questionable, maybe .panel-open should be on child div.panel element? /** Is accordion group open or closed. This property supports two-way binding */ @HostBinding('class.panel-open') - @Input() - get isOpen(): boolean { - return this._isOpen; - } - - set isOpen(value: boolean) { - if (value !== this.isOpen) { - if (value) { - this.accordion.closeOtherPanels(this); - } - this._isOpen = value; - Promise.resolve(null) - .then(() => { - this.isOpenChange.emit(value); - }); - } - } + public isOpen = model(false); protected _isOpen = false; protected accordion: AccordionComponent; constructor(@Inject(AccordionComponent) accordion: AccordionComponent) { this.accordion = accordion; + + this.isOpen.subscribe((value) => { + if (value !== this._isOpen) { + if (value) { + this.accordion.closeOtherPanels(this); + } + this._isOpen = value; + this.isOpenChange.emit(value); + } + }); } ngOnInit(): void { @@ -76,8 +70,8 @@ export class AccordionPanelComponent implements OnInit, OnDestroy { } toggleOpen(): void { - if (!this.isDisabled) { - this.isOpen = !this.isOpen; + if (!this.isDisabled()) { + this.isOpen.set(!this.isOpen()); } } } diff --git a/src/accordion/accordion.component.ts b/src/accordion/accordion.component.ts index c6782fa87a..a4ef7493ef 100644 --- a/src/accordion/accordion.component.ts +++ b/src/accordion/accordion.component.ts @@ -1,4 +1,4 @@ -import { Component, Input } from '@angular/core'; +import { Component, input, OnChanges, SimpleChanges } from '@angular/core'; import { AccordionPanelComponent } from './accordion-group.component'; import { AccordionConfig } from './accordion.config'; @@ -8,18 +8,21 @@ import { AccordionConfig } from './accordion.config'; template: ``, // eslint-disable-next-line @angular-eslint/no-host-metadata-property host: { - '[attr.aria-multiselectable]': 'closeOthers', + '[attr.aria-multiselectable]': '_closeOthers', role: 'tablist', class: 'panel-group', style: 'display: block' }, standalone: true }) -export class AccordionComponent { +export class AccordionComponent implements OnChanges { /** turn on/off animation */ - @Input() isAnimated = false; + isAnimated = input(false); + _isAnimated = this.isAnimated(); + /** if `true` expanding one item will close all others */ - @Input() closeOthers = false; + closeOthers = input(false); + _closeOthers = this.closeOthers(); protected groups: AccordionPanelComponent[] = []; @@ -27,20 +30,31 @@ export class AccordionComponent { Object.assign(this, config); } + ngOnChanges(changes: SimpleChanges) { + if (changes['isAnimated'] && !changes['isAnimated'].firstChange) { + // Only update if foo has changed and isn't the initial setup + this._isAnimated = this.isAnimated(); + } + if (changes['closeOthers'] && !changes['closeOthers'].firstChange) { + // Only update if foo has changed and isn't the initial setup + this._closeOthers = this.closeOthers(); + } + } + closeOtherPanels(openGroup: AccordionPanelComponent): void { - if (!this.closeOthers) { + if (!this._closeOthers) { return; } this.groups.forEach((group: AccordionPanelComponent) => { if (group !== openGroup) { - group.isOpen = false; + group.isOpen.set(false); } }); } addGroup(group: AccordionPanelComponent): void { - group.isAnimated = this.isAnimated; + group.isAnimated = this._isAnimated; this.groups.push(group); } From a8c6fd411cb2eb70b2b5a85468cacc2b5fccb04f Mon Sep 17 00:00:00 2001 From: Umanskiy Aleksey Date: Mon, 4 Nov 2024 15:41:57 +0200 Subject: [PATCH 2/2] refactor(accordion): introducing signals signals --- src/accordion/accordion.component.ts | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/accordion/accordion.component.ts b/src/accordion/accordion.component.ts index a4ef7493ef..d62233c0f2 100644 --- a/src/accordion/accordion.component.ts +++ b/src/accordion/accordion.component.ts @@ -1,4 +1,4 @@ -import { Component, input, OnChanges, SimpleChanges } from '@angular/core'; +import { Component, effect, input } from '@angular/core'; import { AccordionPanelComponent } from './accordion-group.component'; import { AccordionConfig } from './accordion.config'; @@ -15,7 +15,7 @@ import { AccordionConfig } from './accordion.config'; }, standalone: true }) -export class AccordionComponent implements OnChanges { +export class AccordionComponent { /** turn on/off animation */ isAnimated = input(false); _isAnimated = this.isAnimated(); @@ -28,17 +28,11 @@ export class AccordionComponent implements OnChanges { constructor(config: AccordionConfig) { Object.assign(this, config); - } - - ngOnChanges(changes: SimpleChanges) { - if (changes['isAnimated'] && !changes['isAnimated'].firstChange) { - // Only update if foo has changed and isn't the initial setup + effect(() => { this._isAnimated = this.isAnimated(); - } - if (changes['closeOthers'] && !changes['closeOthers'].firstChange) { - // Only update if foo has changed and isn't the initial setup this._closeOthers = this.closeOthers(); - } + + }); } closeOtherPanels(openGroup: AccordionPanelComponent): void {