Angular ignores the animation duration - css

I have a sidebar component which take the sidebarExpanded state from Input(). Whenever the input changes, the animation is triggered correctly but the width change appears instantly. The same animation code is working in another component, so is not a common import problem. The problem persists in different browsers. What am I missing here?
Thank you.
sidebar.component.ts
import {
animate,
state,
style,
transition,
trigger,
} from '#angular/animations';
import { Component, Input, OnInit } from '#angular/core';
#Component({
selector: 'app-sidebar',
templateUrl: './sidebar.component.html',
styleUrls: ['./sidebar.component.scss'],
animations: [
trigger('collapse', [
state('false', style({ width: '0' })),
state('true', style({ width: '25rem' })),
transition('false <=> true', animate(1000)),
]),
],
})
export class SidebarComponent implements OnInit {
constructor() {}
#Input() sidebarExpanded = true;
ngOnInit(): void {}
}
sidebar.component.html
<div class="sidebar" [#collapse]="sidebarExpanded"></div>
sidebar.component.scss
.sidebar {
display: flex;
flex-direction: column;
position: fixed;
top: 8rem;
bottom: 0;
background-color: var(--color-grey-dark-4);
box-shadow: var(--shadow-dark);
}

I figured out i had placed the animation both on the div containing the sidebar and on the sidebar itself. Removing the animation from the parent div solved my problem.

Related

Make bottom sheet(popover) sticky to button (Angular material)

I have project in angular, i add bottom sheet from angular material and it work.
i try to make the opened popup be sticky to botton and responsive to him But its not work.
my main components:
import { Component, OnInit } from '#angular/core';
import { MatBottomSheet } from '#angular/material/bottom-sheet';
import { PopupsDialogComponent } from '../../../modules/home/components/popups-dialog/popups-dialog.component';
#Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.sass']
})
export class HeaderComponent implements OnInit {
constructor(private _bottomSheet: MatBottomSheet) { }
ngOnInit() {
}
openBottomSheet(): void {
this._bottomSheet.open(PopupsDialogComponent, {
panelClass: 'custom-popup'
});
}
}
main components html:
This the button that i want the dialog be stiky to him
<header>
<div class="container">
<button mat-fab class="mat-success" (click)=openBottomSheet()>+</button>
</div>
</header>
PopupsDialogComponents:
import { Component } from '#angular/core';
import {MatBottomSheetRef} from '#angular/material/bottom-sheet';
#Component({
selector: 'app-popups-dialog',
templateUrl: './popups-dialog.component.html',
styleUrls: ['./popups-dialog.component.sass']
})
export class PopupsDialogComponent {
constructor(private _bottomSheetRef: MatBottomSheetRef<PopupsDialogComponent>) {}
openLink(event: MouseEvent): void {
this._bottomSheetRef.dismiss();
event.preventDefault();
}
}
style.css:
.custom-popup
position: absolute
top: 95px
right: 26%
min-width: 0% !important
thanks a lot
Some of built-in angular components are rendered lately,
I think you can handle that in CSS like:
:host ::ng-deep .custom-popup {
position: absolute
top: 95px
right: 26%
min-width: 0% !important
}

set the scroll to top using CSS in Angular4 app

In my Angular4 app, when I'm scrolling down some list and click a list item to see details which is on another route, needs to scroll up to go to top of the page.
I have found some answers to set the scroll to top using JQuery. But is it possible to set the scroll to top using CSS(SASS may be) only?
try this, without any css. In your app component(bootstrap) subscribe the router and check event is a instance of NavigationEnd and then scoll window to top
import {Component, ElementRef, Inject} from '#angular/core';
import {NavigationEnd, Router} from '#angular/router';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
elementRef: ElementRef;
constructor(#Inject(ElementRef) elementRef: ElementRef,
private router: Router) {
this.elementRef = elementRef;
router.events.subscribe((myEvent) => {
if (myEvent instanceof NavigationEnd) {
window.scrollTo(0, 0);
}
});
}
}
Here is working plunker : https://plnkr.co/edit/IyO1Cp?p=preview
Here is quick example using css based smooth scrolling only. And here is another SO thread with more answers.
Hope this helps.
html {
scroll-behavior: smooth
}
a {
display: block;
background: #fff;
padding: 4px;
}
div {
height: 1000px;
width: 200px;
padding: 4px;
}
#red {
background: red;
}
#blue {
background: blue;
}
#green {
background: green;
}
#yellow {
background: yellow;
}
<a name="top"></a>
Red
Blue
Green
Yellow
<div id="red">Top</div>
<div id="blue">Top</div>
<div id="green">Top</div>
<div id="yellow">Top</div>

How to css style angular2's Ng2-completer plugin input box and dropdown color?

I am using angular2/4's Ng2-Completer plugin and am having trouble with styling of the component. I want to change the background dropdown to "red" and the input box to be blue.
The following is my plunkr:
https://plnkr.co/edit/sVnfpBiEb5jBdtul4ls9?p=preview
I tried to include the following CSS, but it does not appear to impact anything:
.completer-row {
display: inherit;
background:blue;
}
.completer-selected-row {
background-color: lightblue;
color: yellow;
}
.completer-row p {
position: relative;
top: 50%;
transform: translateY(50%);
}
.completer-dropdown-holder {
position: absolute;
background: red;
}
.customid {
background:blue;
}
My component:
import { Component } from '#angular/core';
import { CompleterService, CompleterData } from 'ng2-completer';
import {Observable} from 'rxjs/Observable';
import 'rxjs/Rx';
#Component({
selector: 'my-app',
styleUrls: [
'./app.component.css'
],
template: `<h1>Search color</h1>
<ng2-completer id="customid" [(ngModel)]="searchStr" [datasource]="searchData" [minSearchLength]="0" [clearSelected]="true" (selected)="onSelected($event)"></ng2-completer>
<p>Selected: {{selectedColor}}</p>
`
})
export class AppComponent {
protected searchStr: string;
protected dataService: CompleterData;
protected selectedColor: string;
protected searchData = ['red', 'green', 'blue', 'cyan', 'magenta', 'yellow', 'black'];
protected onSelected(item: CompleterItem) {
this.selectedColor = item? item.title: "";
}
}
You can use inputClass propery of ng2-completer.
For example with bootstrap:
<ng2-completer [inputClass]="'form-control form-control-inline'" ...></ng2-completer>
You can style the angular ng2 completer like this:
::ng-deep .completer-row{
}
Angular 2 have a safety feature where CSS only work on HTML files of their respected component. Or css have to go in the global styles.css file for global use. However you can force CSS to apply by adding hots: >>> .class-name this method will force the css to apply to a child component.
More info on this thread Angular 2: How to style host element of the component?
https://alligator.io/angular/styles-between-components-angular/

How to dynamically change CSS in :host in angular 2?

How do I dynamically change CSS properties of a component host?
I have a component and in it's CSS I have given it a stlye:
:host {
overflow-x: hidden
}
On a button click from child component, I need to add overflow-y: hidden to the host component.
How do I achieve this behavior?
Here is a working example.
Use the following HostBinding:
#HostBinding('style.overflow-y') overflowY = 'scroll';
This would give the following component:
#Component({
selector: 'my-app',
template: `
<div>
<button (click)="addStyle()">Add Style</button>
<h2>Hello</h2>
</div>`, styles: [
`
:host {
overflow-x: hidden;
height: 50px;
width: 200px;
display: block;
}
`,
],
})
export class App {
name: string;
#HostBinding('style.overflow-y')
overflowY = 'scroll';
constructor() {
}
addStyle() {
this.overflowY = 'hidden';
}
}

Ionic 2 how to make ion-list grow from bottom upwards?

Here is the gist of my code:
<ion-content>
<ion-list>
<ion-item *ngFor="let item of array">{{item.name}}</ion-item>
</ion-list>
</ion-content>
<ion-footer>
<ion-searchbar (ionInput)="search()"></ion-searchbar>
</ion-footer>
The idea is to have a searchbar at the bottom of the screen, with a list above it that changes depending on the searchbar input. However, this code will make the list populate top-down with a lot of empty space between it and the searchbar if there are few items. I'd like the list to hug the searchbar (basically aligned to ion-content's bottom), while still remaining scrollable inside ion-content. What are some ways to do this?
Working Plunker
To push the ion-list element to the bottom you need to:
Set view encapsulation to none
Style the ion-list's container to display: flex and flex-direction: column
Style the ion-list element using margin-top: auto
No change to your html template should be necessary, and here is a good answer explaining how to push content to the bottom of a container.
Component Decorator
#Component({
selector: 'page-home',
templateUrl: 'pages/home/home.html',
styles: [`
.scroll-content {
display: flex;
flex-direction: column;
}
.scroll-content ion-list {
margin-top: auto;
margin-bottom: 0;
}
`],
encapsulation: ViewEncapsulation.None
})
#adriancarriger's answer is great, but a small improvement can be made. Since you're pushing the new elements to the bottom of the list, I guess that it would be nice to always scroll the content to the bottom, to make the new items always visible. That could be easily achieved by adding just a few lines of code:
// First add ViewChild and Content imports
import { ViewChild, Component, ViewEncapsulation } from '#angular/core';
import { NavController, Content } from 'ionic-angular';
#Component({
selector: 'page-home',
templateUrl: 'pages/home/home.html',
styles: [`
.scroll-content {
display: flex;
flex-direction: column;
}
.scroll-content ion-list {
margin-top: auto;
margin-bottom: 0;
}
`],
encapsulation: ViewEncapsulation.None
})
export class HomePage {
#ViewChild(Content) content: Content; // <-- get a reference of the content
count = 4; // for demo
appName = 'Ionic App';
array = [
{ name: 'item-1' },
{ name: 'item-2' },
{ name: 'item-3' }
];
constructor(private navController: NavController) {
}
search() {
console.log('searching...');
}
add(number) {
let itemNumber = this.count;
this.array.push({ name: 'item-' + itemNumber });
this.scrollToBottom(); // <- when the new item is pushed, scroll to the bottom to show it
this.count += number;
}
scrollToBottom(){
// use the content's dimension to obtain the current height of the scroll
let dimension = this.content.getContentDimensions();
// scroll to it (you can also set the duration in ms by passing a third parameter to the scrollTo(x,y,duration) method.
this.content.scrollTo(0, dimension.scrollHeight);
}
}

Resources