Skip to content

Instantly share code, notes, and snippets.

@guiseek
Last active September 9, 2022 14:16
Show Gist options
  • Save guiseek/94a9b07e2f779f2f8727e6e21064d54c to your computer and use it in GitHub Desktop.
Save guiseek/94a9b07e2f779f2f8727e6e21064d54c to your computer and use it in GitHub Desktop.
Accordion Details Component
[eghp-accordion-item-heading] {
align-items: center;
display: inline-flex;
cursor: pointer;
padding: 16px;
> * {
flex: 1;
}
}
import {
Component,
ViewEncapsulation,
ChangeDetectionStrategy,
} from '@angular/core';
@Component({
selector: '[eghp-accordion-item-heading]',
template: `<ng-content></ng-content>`,
styleUrls: ['./accordion-item-heading.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
})
export class AccordionItemHeadingComponent {}
details[eghp-accordion-item] {
border-bottom: 1px solid rgba(0, 0, 0, 0.3);
> summary::marker {
content: var(--accordion-marker-icon-closed, '👉');
}
&[open] > summary::marker {
content: var(--accordion-marker-icon-opened, '👇');
}
summary {
margin-left: 16px;
&:hover {
cursor: pointer;
}
> h1,
> h2,
> h3,
> h4,
> h5,
> h6 {
font-size: 100%;
font-weight: 500;
padding: 8px 8px 0 8px;
}
}
> section {
border-top: 1px solid rgba(0, 0, 0, 0.2);
padding: 16px;
margin: 0;
> p:first-child {
margin-top: 0;
}
> p:last-child {
margin-bottom: 0;
}
}
}
import {
Input,
Output,
Component,
HostBinding,
EventEmitter,
HostListener,
ViewEncapsulation,
ChangeDetectionStrategy,
} from '@angular/core';
@Component({
exportAs: 'accordionItem',
selector: 'details[eghp-accordion-item]',
template: `
<summary>
<ng-content select="[eghp-accordion-item-heading]"></ng-content>
</summary>
<ng-content select="section"></ng-content>
`,
styleUrls: ['./accordion-item.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
})
export class AccordionItemComponent<Ref = unknown> {
@Output()
private opened = new EventEmitter<Ref>();
@Output()
private closed = new EventEmitter<Ref>();
private _expanded?: boolean | null = null;
public get expanded() {
return this._expanded;
}
@Input()
@HostBinding('open')
set expanded(value) {
this._expanded = value;
}
@Input()
ref?: Ref;
@HostListener('click', ['$event.currentTarget'])
private onClick(target: HTMLDetailsElement) {
if (target.open) {
this.closed.emit(this.ref);
} else {
this.opened.emit(this.ref);
}
}
}
:host {
display: flex;
flex-direction: column;
border: 1px solid rgba(0, 0, 0, 0.3);
border-bottom-color: transparent;
border-radius: 4px;
}
import {
Input,
QueryList,
Component,
ContentChildren,
AfterContentInit,
ChangeDetectionStrategy,
} from '@angular/core';
import { AccordionItemComponent } from './accordion-item.component';
@Component({
selector: 'eghp-accordion',
template: `<ng-content select="[eghp-accordion-item]"></ng-content>`,
changeDetection: ChangeDetectionStrategy.OnPush,
styleUrls: ['./accordion.component.scss'],
})
export class AccordionComponent implements AfterContentInit {
@ContentChildren(AccordionItemComponent)
children!: QueryList<AccordionItemComponent>;
@Input()
allExpanded = false;
ngAfterContentInit() {
this.children.forEach((item) => {
if (item.expanded === null) {
item.expanded = this.allExpanded;
}
});
}
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AccordionComponent } from './accordion.component';
import { AccordionItemComponent } from './accordion-item.component';
import { AccordionItemHeadingComponent } from './accordion-item-heading.component';
@NgModule({
imports: [CommonModule],
declarations: [
AccordionComponent,
AccordionItemComponent,
AccordionItemHeadingComponent,
],
exports: [
AccordionComponent,
AccordionItemComponent,
AccordionItemHeadingComponent,
],
})
export class AccordionModule {}
<h2>Accordion</h2>
<div eghp-accordion>
<details eghp-accordion-item [expanded]="true">
<h3 eghp-accordion-item-heading>Item 1</h3>
<section>
<p>
Mussum Ipsum, cacilds vidis litro abertis. Posuere libero varius. Nullam
a nisl ut ante blandit hendrerit. Aenean sit amet nisi.Suco de cevadiss,
é um leite divinis, qui tem lupuliz, matis, aguis e fermentis.Em pé sem
cair, deitado sem dormir, sentado sem cochilar e fazendo pose.Nullam
volutpat risus nec leo commodo, ut interdum diam laoreet. Sed non
consequat odio.
</p>
</section>
</details>
<details eghp-accordion-item>
<h3 eghp-accordion-item-heading>Item 2</h3>
<section>
<p>
Mussum Ipsum, cacilds vidis litro abertis. Copo furadis é disculpa de
bebadis, arcu quam euismod magna.Sapien in monti palavris qui num
significa nadis i pareci latim.Leite de capivaris, leite de mula manquis
sem cabeça.Cevadis im ampola pa arma uma pindureta.
</p>
<p>
Leite de capivaris, leite de mula manquis sem cabeça.Pra lá , depois
divoltis porris, paradis.In elementis mé pra quem é amistosis quis
leo.Manduma pindureta quium dia nois paga.
</p>
</section>
</details>
</div>
<hr />
<h3>Accordion with <code>[allExpanded]</code></h3>
<div eghp-accordion [allExpanded]="true">
<details eghp-accordion-item>
<h3 eghp-accordion-item-heading>Item 1</h3>
<section>
<p>
Mussum Ipsum, cacilds vidis litro abertis. Posuere libero varius. Nullam
a nisl ut ante blandit hendrerit. Aenean sit amet nisi.Suco de cevadiss,
é um leite divinis, qui tem lupuliz, matis, aguis e fermentis.Em pé sem
cair, deitado sem dormir, sentado sem cochilar e fazendo pose.Nullam
volutpat risus nec leo commodo, ut interdum diam laoreet. Sed non
consequat odio.
</p>
</section>
</details>
<details eghp-accordion-item>
<h3 eghp-accordion-item-heading>Item 2</h3>
<section>
<p>
Mussum Ipsum, cacilds vidis litro abertis. Copo furadis é disculpa de
bebadis, arcu quam euismod magna.Sapien in monti palavris qui num
significa nadis i pareci latim.Leite de capivaris, leite de mula manquis
sem cabeça.Cevadis im ampola pa arma uma pindureta.
</p>
<p>
Leite de capivaris, leite de mula manquis sem cabeça.Pra lá , depois
divoltis porris, paradis.In elementis mé pra quem é amistosis quis
leo.Manduma pindureta quium dia nois paga.
</p>
</section>
</details>
</div>
<hr />
<h3>Accordion Item</h3>
<details eghp-accordion-item>
<h3 eghp-accordion-item-heading>Item 1</h3>
<section>
<p>
Mussum Ipsum, cacilds vidis litro abertis. Posuere libero varius. Nullam a
nisl ut ante blandit hendrerit. Aenean sit amet nisi.Suco de cevadiss, é
um leite divinis, qui tem lupuliz, matis, aguis e fermentis.Em pé sem
cair, deitado sem dormir, sentado sem cochilar e fazendo pose.Nullam
volutpat risus nec leo commodo, ut interdum diam laoreet. Sed non
consequat odio.
</p>
</section>
</details>
<hr />
<h3>Accordion Item events</h3>
<details
eghp-accordion-item
ref="accordion-item-1"
(opened)="log('opened: ' + $event)"
(closed)="log('closed: ' + $event)"
>
<h3 eghp-accordion-item-heading>Item 1</h3>
<section>
<p>
Mussum Ipsum, cacilds vidis litro abertis. Posuere libero varius. Nullam a
nisl ut ante blandit hendrerit. Aenean sit amet nisi.Suco de cevadiss, é
um leite divinis, qui tem lupuliz, matis, aguis e fermentis.Em pé sem
cair, deitado sem dormir, sentado sem cochilar e fazendo pose.Nullam
volutpat risus nec leo commodo, ut interdum diam laoreet. Sed non
consequat odio.
</p>
</section>
</details>
<ol>
<li *ngFor="let log of eventLogs">
{{ log }}
</li>
</ol>
<hr />
<h3>Accordion Item with <code>[expanded]</code></h3>
<details eghp-accordion-item [expanded]="true">
<h3 eghp-accordion-item-heading>Item 1</h3>
<section>
<p>
Mussum Ipsum, cacilds vidis litro abertis. Posuere libero varius. Nullam a
nisl ut ante blandit hendrerit. Aenean sit amet nisi.Suco de cevadiss, é
um leite divinis, qui tem lupuliz, matis, aguis e fermentis.Em pé sem
cair, deitado sem dormir, sentado sem cochilar e fazendo pose.Nullam
volutpat risus nec leo commodo, ut interdum diam laoreet. Sed non
consequat odio.
</p>
</section>
</details>
import { Component } from '@angular/core';
@Component({
selector: 'demo-accordion',
templateUrl: './accordion.component.html',
})
export class AccordionComponent {
eventLogs: string[] = [];
log(value: unknown) {
this.eventLogs.push(`${value} - ${new Date().toLocaleString()}`);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment