diff --git a/CHANGELOG.md b/CHANGELOG.md index 361ead01..9ca2835e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +## 6.1.0 (27.05.2024) + +### Fixes and improvements: + +- [Multi range](https://mdbootstrap.com/docs/angular/forms/multi-range-slider/) + - Fixed problem with thumb limiting logic when using custom step + - Fixed problem with updating thumb positions via form controls +- [Popconfirm](https://mdbootstrap.com/docs/angular/components/popconfirm/) - added focus trap +- [Autocomplete](https://mdbootstrap.com/docs/angular/forms/autocomplete/) - restored native `shift + home` and `shift + end` keys behavior (open/close dropdown) +- [Select](https://mdbootstrap.com/docs/angular/forms/select/) - added support for opening and closing dropdown with `alt + arrow-up` and `alt + arrow-down` keys + +### New: + +- [Table pagination](https://mdbootstrap.com/docs/angular/data/datatables/) - added new `page` input that allows to set page number +- [Multi range](https://mdbootstrap.com/docs/angular/forms/multi-range-slider/) - added new `highlightRange` input that allows to highlight range +- [Parallax](https://mdbootstrap.com/docs/angular/plugins/parallax/) - added new `container` input that allows to set wrapper element for parallax effect + +--- + ## 6.0.0 (15.01.2024) This version requires Angular v17. Follow the [Angular Update Guide](https://update.angular.io/?l=3&v=16.0-17.0) to migrate your project to Angular 17. diff --git a/README.txt b/README.txt index d98138ef..34520791 100644 --- a/README.txt +++ b/README.txt @@ -1,6 +1,6 @@ MDB 5 Angular -Version: FREE 6.0.0 +Version: FREE 6.1.0 Documentation: https://mdbootstrap.com/docs/angular/ diff --git a/package-lock.json b/package-lock.json index 17f3c35e..27e16d29 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "mdb-angular-ui-kit-free", - "version": "6.0.0", + "version": "6.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "mdb-angular-ui-kit-free", - "version": "6.0.0", + "version": "6.1.0", "dependencies": { "@angular/animations": "^17.0.7", "@angular/cdk": "^17.0.4", diff --git a/package.json b/package.json index 1adab0fb..79bc60e3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mdb-angular-ui-kit-free", - "version": "6.0.0", + "version": "6.1.0", "scripts": { "ng": "ng", "start": "ng serve", diff --git a/projects/mdb-angular-ui-kit/CHANGELOG.md b/projects/mdb-angular-ui-kit/CHANGELOG.md index 361ead01..9ca2835e 100644 --- a/projects/mdb-angular-ui-kit/CHANGELOG.md +++ b/projects/mdb-angular-ui-kit/CHANGELOG.md @@ -1,3 +1,22 @@ +## 6.1.0 (27.05.2024) + +### Fixes and improvements: + +- [Multi range](https://mdbootstrap.com/docs/angular/forms/multi-range-slider/) + - Fixed problem with thumb limiting logic when using custom step + - Fixed problem with updating thumb positions via form controls +- [Popconfirm](https://mdbootstrap.com/docs/angular/components/popconfirm/) - added focus trap +- [Autocomplete](https://mdbootstrap.com/docs/angular/forms/autocomplete/) - restored native `shift + home` and `shift + end` keys behavior (open/close dropdown) +- [Select](https://mdbootstrap.com/docs/angular/forms/select/) - added support for opening and closing dropdown with `alt + arrow-up` and `alt + arrow-down` keys + +### New: + +- [Table pagination](https://mdbootstrap.com/docs/angular/data/datatables/) - added new `page` input that allows to set page number +- [Multi range](https://mdbootstrap.com/docs/angular/forms/multi-range-slider/) - added new `highlightRange` input that allows to highlight range +- [Parallax](https://mdbootstrap.com/docs/angular/plugins/parallax/) - added new `container` input that allows to set wrapper element for parallax effect + +--- + ## 6.0.0 (15.01.2024) This version requires Angular v17. Follow the [Angular Update Guide](https://update.angular.io/?l=3&v=16.0-17.0) to migrate your project to Angular 17. diff --git a/projects/mdb-angular-ui-kit/assets/scss/free/_buttons.scss b/projects/mdb-angular-ui-kit/assets/scss/free/_buttons.scss index 93692619..95a9c233 100644 --- a/projects/mdb-angular-ui-kit/assets/scss/free/_buttons.scss +++ b/projects/mdb-angular-ui-kit/assets/scss/free/_buttons.scss @@ -165,6 +165,7 @@ box-shadow: none; } } + // scss-docs-end btn-secondary // scss-docs-start btn-variant-loop @@ -219,10 +220,11 @@ &:disabled, &.disabled, fieldset:disabled & { - box-shadow: $btn-contextual-box-shadow map-get($value, shadow-color); + box-shadow: var(--#{$prefix}btn-box-shadow); } } } + // scss-docs-end btn-variant-loop // scss-docs-start btn-outline-variant-loop @@ -279,6 +281,7 @@ } } } + // scss-docs-end btn-outline-variant-loop // diff --git a/projects/mdb-angular-ui-kit/assets/scss/free/_carousel.scss b/projects/mdb-angular-ui-kit/assets/scss/free/_carousel.scss index cb788579..cd601f05 100644 --- a/projects/mdb-angular-ui-kit/assets/scss/free/_carousel.scss +++ b/projects/mdb-angular-ui-kit/assets/scss/free/_carousel.scss @@ -30,6 +30,7 @@ } } +// Additional MDB Angular styles .carousel-indicators { button { box-sizing: content-box; @@ -56,3 +57,4 @@ background-color: $carousel-dark-indicator-active-bg; } } +// Additional MDB Angular styles diff --git a/projects/mdb-angular-ui-kit/assets/scss/free/_progress.scss b/projects/mdb-angular-ui-kit/assets/scss/free/_progress.scss index c13114e7..9712a7f1 100644 --- a/projects/mdb-angular-ui-kit/assets/scss/free/_progress.scss +++ b/projects/mdb-angular-ui-kit/assets/scss/free/_progress.scss @@ -2,4 +2,5 @@ .progress { border-radius: 0; + // box-shadow: none; This should be added in next major release 7.0.0 } diff --git a/projects/mdb-angular-ui-kit/assets/scss/free/_toasts.scss b/projects/mdb-angular-ui-kit/assets/scss/free/_toasts.scss index 78e0ee1f..8c1ae520 100644 --- a/projects/mdb-angular-ui-kit/assets/scss/free/_toasts.scss +++ b/projects/mdb-angular-ui-kit/assets/scss/free/_toasts.scss @@ -1,4 +1,6 @@ -// Toasts +// +// Toast styles +// .toast { // scss-docs-start toast-css-vars diff --git a/projects/mdb-angular-ui-kit/assets/scss/free/forms/_form-check.scss b/projects/mdb-angular-ui-kit/assets/scss/free/forms/_form-check.scss index 09dce406..4466abca 100644 --- a/projects/mdb-angular-ui-kit/assets/scss/free/forms/_form-check.scss +++ b/projects/mdb-angular-ui-kit/assets/scss/free/forms/_form-check.scss @@ -3,7 +3,9 @@ // .form-check { + // Additional MDB Angular styles position: relative; + // Additional MDB Angular styles min-height: 1.5rem; } @@ -83,7 +85,7 @@ &[type='checkbox'] { border-radius: $form-check-input-checkbox-border-radius; margin-top: 0.19em; - margin-right: 4px; + margin-right: 4px; // This should be changed to 6px in next major release 7.0.0 &:focus { &:after { @@ -123,28 +125,7 @@ } &:indeterminate { - background-image: none; - background-color: transparent; - border-color: $form-check-input-indeterminate-border-color; - - &:after { - display: block; - transform: $form-check-input-indeterminate-checked-after-transform #{'/*!rtl:ignore*/'}; - border-width: $form-check-input-indeterminate-checked-after-border-width; - border-color: $form-check-input-indeterminate-checked-after-border-color; - width: $form-check-input-indeterminate-checked-after-width; - height: $form-check-input-indeterminate-checked-after-height; - border-style: solid; - border-top: 0; - border-left: 0 #{'/*!rtl:ignore*/'}; - margin-left: $form-check-input-indeterminate-checked-after-margin-left; - margin-top: 0; - } - - &:focus { - background-color: $form-check-input-indeterminate-focus-background-color; - border-color: $form-check-input-indeterminate-focus-border-color; - } + border-color: $form-check-input-indeterminate-focus-border-color; } } @@ -196,7 +177,7 @@ } .form-check-label { - // padding-left: 0.15rem; + // padding-left: 0.15rem; This should be added in next major release 7.0.0 &:hover { cursor: pointer; } @@ -215,7 +196,7 @@ height: $form-switch-form-check-input-height; background-color: $form-switch-form-check-input-background-color; margin-top: 0.3em; - margin-right: 4px; + margin-right: 4px; // This should be changed to 8px in next major release 7.0.0 &:after { content: ''; diff --git a/projects/mdb-angular-ui-kit/assets/scss/free/forms/_form-control.scss b/projects/mdb-angular-ui-kit/assets/scss/free/forms/_form-control.scss index 0d0d5e10..3bc53fd3 100644 --- a/projects/mdb-angular-ui-kit/assets/scss/free/forms/_form-control.scss +++ b/projects/mdb-angular-ui-kit/assets/scss/free/forms/_form-control.scss @@ -25,6 +25,7 @@ } } +// Additional MDB Angular styles .select { ~ .form-label { position: absolute; @@ -161,9 +162,13 @@ } } } +// Additional MDB Angular styles .form-outline { position: relative; + // width: 100%; // This change introduces big layout differences + // and should be treated as a breaking change. + // It should be revised and checked. .form-helper { width: 100%; @@ -337,6 +342,7 @@ } } + // Additional MDB Angular styles .select-lg ~ .form-label { padding-top: $form-label-padding-top-lg; } @@ -345,6 +351,7 @@ padding-top: $form-label-padding-top-sm; font-size: $form-label-font-size-sm; } + // Additional MDB Angular styles &.form-white { .form-control { diff --git a/projects/mdb-angular-ui-kit/assets/scss/free/forms/_form-range.scss b/projects/mdb-angular-ui-kit/assets/scss/free/forms/_form-range.scss index e1952dba..1d7ee415 100644 --- a/projects/mdb-angular-ui-kit/assets/scss/free/forms/_form-range.scss +++ b/projects/mdb-angular-ui-kit/assets/scss/free/forms/_form-range.scss @@ -34,10 +34,15 @@ &::-webkit-slider-runnable-track { height: $form-range-webkit-slider-runnable-track-height; border-radius: 0; + // box-shadow: none; This should be added in next major release 7.0.0 } &::-moz-range-thumb { box-shadow: none; appearance: none; } + + &::-moz-range-track { + // box-shadow: none; This should be added in next major release 7.0.0 + } } diff --git a/projects/mdb-angular-ui-kit/assets/scss/free/forms/_input-group.scss b/projects/mdb-angular-ui-kit/assets/scss/free/forms/_input-group.scss index 4c190516..287efe24 100644 --- a/projects/mdb-angular-ui-kit/assets/scss/free/forms/_input-group.scss +++ b/projects/mdb-angular-ui-kit/assets/scss/free/forms/_input-group.scss @@ -3,6 +3,8 @@ // .input-group { + // flex-wrap: nowrap; This should be added in next major release 7.0.0 + > .form-control { min-height: $input-group-min-height; height: $input-group-height; diff --git a/projects/mdb-angular-ui-kit/assets/scss/mdb.free.scss b/projects/mdb-angular-ui-kit/assets/scss/mdb.free.scss index 523455ce..c5a92d1b 100644 --- a/projects/mdb-angular-ui-kit/assets/scss/mdb.free.scss +++ b/projects/mdb-angular-ui-kit/assets/scss/mdb.free.scss @@ -54,6 +54,7 @@ // MDB CORE @import './free/mixins'; +@import './free/utilities'; // MDB CORE COMPONENTS @import './free/root'; diff --git a/projects/mdb-angular-ui-kit/dropdown/dropdown.directive.spec.ts b/projects/mdb-angular-ui-kit/dropdown/dropdown.directive.spec.ts index de5f362b..47539eb9 100644 --- a/projects/mdb-angular-ui-kit/dropdown/dropdown.directive.spec.ts +++ b/projects/mdb-angular-ui-kit/dropdown/dropdown.directive.spec.ts @@ -1,15 +1,15 @@ -import { ComponentFixture, fakeAsync, flush, inject, TestBed } from '@angular/core/testing'; -import { Component, DebugElement } from '@angular/core'; -import { MdbDropdownModule } from './index'; +import { ComponentFixture, fakeAsync, flush, inject, TestBed, tick } from '@angular/core/testing'; +import { Component } from '@angular/core'; +import { MdbDropdownMenuDirective, MdbDropdownModule } from './index'; import { MdbDropdownDirective } from './index'; import { By } from '@angular/platform-browser'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { OverlayContainer } from '@angular/cdk/overlay'; +import { first } from 'rxjs'; describe('MDB Dropdown', () => { let fixture: ComponentFixture; - let element: any; - let component: TestDropdownComponent; + let testComponent: TestDropdownComponent; let directive: MdbDropdownDirective; let overlayContainer: OverlayContainer; let overlayContainerElement: HTMLElement; @@ -27,12 +27,10 @@ describe('MDB Dropdown', () => { })(); fixture = TestBed.createComponent(TestDropdownComponent); - component = fixture.componentInstance; - element = fixture.nativeElement; + testComponent = fixture.componentInstance; directive = fixture.debugElement .query(By.directive(MdbDropdownDirective)) .injector.get(MdbDropdownDirective); - fixture.detectChanges(); }); @@ -46,7 +44,7 @@ describe('MDB Dropdown', () => { jest.spyOn(directive, 'show'); jest.spyOn(directive, 'hide'); - const buttonEl: HTMLButtonElement = element.querySelector('.dropdown-toggle'); + const buttonEl: HTMLButtonElement = fixture.nativeElement.querySelector('.dropdown-toggle'); buttonEl.click(); fixture.detectChanges(); @@ -77,20 +75,6 @@ describe('MDB Dropdown', () => { expect(overlayContainerElement.textContent).toEqual(''); })); - it('should not close dropdown on outside click if closeOnOutsideClick is set to false', fakeAsync(() => { - component.closeOnOutsideClick = false; - directive.show(); - fixture.detectChanges(); - - document.body.click(); - fixture.detectChanges(); - - flush(); - fixture.detectChanges(); - - expect(overlayContainerElement.textContent).toContain('Action'); - })); - it('should close dropdown on dropdown item click', fakeAsync(() => { directive.show(); fixture.detectChanges(); @@ -105,22 +89,6 @@ describe('MDB Dropdown', () => { expect(overlayContainerElement.textContent).toEqual(''); })); - - it('should not close dropdown on dropdown item click if closeOnItemClick is set to false', fakeAsync(() => { - component.closeOnItemClick = false; - directive.show(); - fixture.detectChanges(); - - const item: HTMLElement = document.querySelector('.dropdown-item'); - - item.click(); - fixture.detectChanges(); - - flush(); - fixture.detectChanges(); - - expect(overlayContainerElement.textContent).toContain('Action'); - })); }); describe('Keyboard navigation', () => { @@ -172,12 +140,16 @@ describe('MDB Dropdown', () => { expect(overlayContainerElement.textContent).toEqual(''); })); + }); - it('should not close dropdown on ESC keyup if closeOnEsc is set to false', fakeAsync(() => { - component.closeOnEsc = false; + describe('Inputs', () => { + it('should not close dropdown on ESC keyup if closeOnEsc input is set to false', fakeAsync(() => { + testComponent.closeOnEsc = false; directive.show(); fixture.detectChanges(); + expect(overlayContainerElement.textContent).toContain('Action'); + document.dispatchEvent(new KeyboardEvent('keyup', { key: 'Escape' })); fixture.detectChanges(); @@ -186,6 +158,166 @@ describe('MDB Dropdown', () => { expect(overlayContainerElement.textContent).toContain('Action'); })); + + it('should not close dropdown on dropdown item click if closeOnItemClick input is set to false', fakeAsync(() => { + testComponent.closeOnItemClick = false; + directive.show(); + fixture.detectChanges(); + + expect(overlayContainerElement.textContent).toContain('Action'); + + const item: HTMLElement = document.querySelector('.dropdown-item'); + + item.click(); + fixture.detectChanges(); + + flush(); + fixture.detectChanges(); + + expect(overlayContainerElement.textContent).toContain('Action'); + })); + + it('should not close dropdown on outside click if closeOnOutsideClick input is set to false', fakeAsync(() => { + testComponent.closeOnOutsideClick = false; + directive.show(); + fixture.detectChanges(); + + expect(overlayContainerElement.textContent).toContain('Action'); + + document.body.click(); + fixture.detectChanges(); + + flush(); + fixture.detectChanges(); + + expect(overlayContainerElement.textContent).toContain('Action'); + })); + + it('should apply appropriate transform style when offset input is set', () => { + testComponent.offset = 43; + fixture.detectChanges(); + + directive.show(); + fixture.detectChanges(); + + let overlayPane: HTMLDivElement = overlayContainerElement.querySelector('.cdk-overlay-pane'); + expect(overlayPane.style.transform).toBe('translateY(43px)'); + }); + + it('should apply appropriate class when positionClass input is set', () => { + expect(directive.host.classList).toContain('dropdown'); + expect(directive.host.classList).not.toContain('dropup'); + + directive.positionClass = 'dropup'; + + expect(directive.host.classList).not.toContain('dropdown'); + expect(directive.host.classList).toContain('dropup'); + }); + + it('should apply appropriate class when menuPositionClass input is set', () => { + const dropdownMenuDirective: MdbDropdownMenuDirective = directive._dropdownMenu; + expect(dropdownMenuDirective.elementRef.nativeElement.classList).toContain( + 'dropdown-menu-start' + ); + expect(dropdownMenuDirective.elementRef.nativeElement.classList).not.toContain( + 'dropdown-menu-end' + ); + + dropdownMenuDirective.menuPositionClass = 'dropdown-menu-end'; + + expect(dropdownMenuDirective.elementRef.nativeElement.classList).not.toContain( + 'dropdown-menu-start' + ); + expect(dropdownMenuDirective.elementRef.nativeElement.classList).toContain( + 'dropdown-menu-end' + ); + }); + }); + + describe('Outputs', () => { + it('should emit events on show and hide', fakeAsync(() => { + let showDropdown: MdbDropdownDirective | undefined; + let shownDropdown: MdbDropdownDirective | undefined; + let hideDropdown: MdbDropdownDirective | undefined; + let hiddenDropdown: MdbDropdownDirective | undefined; + + const showSpy = jest.spyOn(directive.dropdownShow, 'emit'); + const shownSpy = jest.spyOn(directive.dropdownShown, 'emit'); + const hideSpy = jest.spyOn(directive.dropdownHide, 'emit'); + const hiddenSpy = jest.spyOn(directive.dropdownHidden, 'emit'); + + directive.dropdownShow.pipe(first()).subscribe((event) => (showDropdown = event)); + directive.dropdownShown.pipe(first()).subscribe((event) => (shownDropdown = event)); + directive.dropdownHide.pipe(first()).subscribe((event) => (hideDropdown = event)); + directive.dropdownHidden.pipe(first()).subscribe((event) => (hiddenDropdown = event)); + + directive.show(); + fixture.detectChanges(); + + expect(showSpy).toHaveBeenCalledTimes(1); + expect(showDropdown).toEqual(directive); + + tick(); + + expect(shownSpy).toHaveBeenCalledTimes(1); + expect(shownDropdown).toEqual(directive); + + directive.hide(); + fixture.detectChanges(); + + expect(hideSpy).toHaveBeenCalledTimes(1); + expect(hideDropdown).toEqual(directive); + + tick(); + + expect(hiddenSpy).toHaveBeenCalledTimes(1); + expect(hiddenDropdown).toEqual(directive); + })); + }); + + describe('Public methods', () => { + it('should show dropdown when show method is called', fakeAsync(() => { + expect(overlayContainerElement.textContent).not.toContain('Action'); + + directive.show(); + fixture.detectChanges(); + flush(); + + expect(overlayContainerElement.textContent).toContain('Action'); + })); + + it('should hide dropdown when hide method is called', fakeAsync(() => { + expect(overlayContainerElement.textContent).not.toContain('Action'); + + directive.show(); + fixture.detectChanges(); + flush(); + + expect(overlayContainerElement.textContent).toContain('Action'); + + directive.hide(); + fixture.detectChanges(); + flush(); + fixture.detectChanges(); + + expect(overlayContainerElement.textContent).toEqual(''); + })); + + it('should toggle dropdown when toggle method is called', fakeAsync(() => { + expect(overlayContainerElement.textContent).not.toContain('Action'); + + directive.toggle(); + fixture.detectChanges(); + + expect(overlayContainerElement.textContent).toContain('Action'); + + directive.toggle(); + fixture.detectChanges(); + flush(); + fixture.detectChanges(); + + expect(overlayContainerElement.textContent).toEqual(''); + })); }); }); @@ -198,9 +330,14 @@ describe('MDB Dropdown', () => { [closeOnOutsideClick]="closeOnOutsideClick" [closeOnItemClick]="closeOnItemClick" [closeOnEsc]="closeOnEsc" + [offset]="offset" > -