Skip to content

Commit

Permalink
feat(description): allow only item to be expanded (#33)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidlj95 authored Sep 28, 2023
1 parent f0a6a78 commit 7e1d8ad
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/app/about/description/description.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</ng-template>
<ul *ngIf="line.children.length" [attr.id]="sluggedId" [@expanded]="isCollapsible ? isExpanded : true">
<li *ngFor="let line of line.children">
<app-description [line]="line" [depth]="depth+1">
<app-description [line]="line" [depth]="depth+1" [parent]="this">
</app-description>
</li>
</ul>
63 changes: 60 additions & 3 deletions src/app/about/description/description.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { getComponentSelector } from '../../../test/helpers/component-testers';
import { MATERIAL_SYMBOLS_SELECTOR } from '../../../test/helpers/material-symbols';
import { PLATFORM_BROWSER_ID, PLATFORM_SERVER_ID } from '../../../test/helpers/platform-ids';
import { expectIsHidden, expectIsVisible } from '../../../test/helpers/visibility';
import { DescriptionLine } from '../../metadata';
import { DescriptionLine, DescriptionLineData } from '../../metadata';

import { COLLAPSIBLE_CONFIG, CollapsibleConfiguration, DescriptionComponent } from './description.component';

Expand Down Expand Up @@ -167,9 +167,9 @@ describe('DescriptionComponent', () => {
})
describe('when depth is set to configured depth to start a collapsible', () => {

function configureToBeCollapsible(component: DescriptionComponent) {
function configureToBeCollapsible(component: DescriptionComponent, line?: DescriptionLine) {
component.depth = fakeConfig.collapsibleStartAtDepth
component.line = fakeLine
component.line = line ?? fakeLine
}

describe('data', () => {
Expand Down Expand Up @@ -292,6 +292,63 @@ describe('DescriptionComponent', () => {
testShouldBeCollapsed()
})
})

describe('when expanding a child item', () => {
const fakeLineWithManyChildren = new DescriptionLine(
new DescriptionLineData({symbol: '', html: 'Root'}), [
new DescriptionLine(new DescriptionLineData({symbol: '', html: 'Child 1'}), [
new DescriptionLine(),
]),
new DescriptionLine(new DescriptionLineData({symbol: '', html: 'Child 2'}), [
new DescriptionLine(),
]),
new DescriptionLine(new DescriptionLineData({symbol: '', html: 'Child 3'}), [
new DescriptionLine(),
]),
])
beforeEach(() => {
[fixture, component] = makeSut()
configureToBeCollapsible(component, fakeLineWithManyChildren)

fixture.detectChanges()

listElement = fixture.debugElement.query(LIST_SELECTOR)
})
it('should collapse sibling items', () => {
const listItemElements = listElement.children
expect(listItemElements.length).toBe(fakeLineWithManyChildren.children.length)

// Everything is collapsed
listItemElements.forEach((listItemElement, index) => {
const child = fakeLineWithManyChildren.children[index]
const childDataElement = listItemElement.query(DATA_CLASS_SELECTOR)
expect(childDataElement.attributes['aria-expanded'])
.withContext(`item ${child.data?.text} is collapsed`)
.toBe(false.toString())
})

// Expand first item and ensure is expanded
const firstListItemDataElement = listItemElements[0].query(DATA_CLASS_SELECTOR)
firstListItemDataElement.triggerEventHandler('click')
fixture.detectChanges()
expect(firstListItemDataElement.attributes['aria-expanded'])
.withContext('first item should now be expanded')
.toBe(true.toString())

// Expand second item
const secondListItemDataElement = listItemElements[1].query(DATA_CLASS_SELECTOR)
secondListItemDataElement.triggerEventHandler('click')
fixture.detectChanges()
expect(secondListItemDataElement.attributes['aria-expanded'])
.withContext('second item should now be expanded')
.toBe(true.toString())

// Now first item should be collapsed
expect(firstListItemDataElement.attributes['aria-expanded'])
.withContext('first item should finally be magically collapsed')
.toBe(false.toString())
})
})
})
})
})
Expand Down
25 changes: 24 additions & 1 deletion src/app/about/description/description.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import { animate, AUTO_STYLE, state, style, transition, trigger } from '@angular/animations';
import { isPlatformBrowser } from '@angular/common';
import { Component, HostBinding, Inject, InjectionToken, Input, PLATFORM_ID } from '@angular/core';
import {
Component,
HostBinding,
Inject,
InjectionToken,
Input,
PLATFORM_ID,
QueryList,
ViewChildren,
} from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { EMPHASIZED_DURATION_MS, TIMING_FUNCTION } from '../../common/animations';
import { DescriptionLine } from '../../metadata';
Expand All @@ -26,6 +35,8 @@ import { DescriptionLine } from '../../metadata';
export class DescriptionComponent {
@Input({required: true}) public line!: DescriptionLine
@Input() public depth: number = 0
@Input() protected parent?: DescriptionComponent

// 👇 Using `protected` to avoid being marked as unused
@HostBinding('class.visibleIfNoScript') protected visibleIfNoScript = true
@HostBinding('class.hidden') protected hidden = true
Expand All @@ -34,6 +45,9 @@ export class DescriptionComponent {
private EXPANDED_DEFAULT_JS_ENABLED = false
public isExpanded = this.EXPANDED_DEFAULT_NO_JS

@ViewChildren(DescriptionComponent)
private children!: QueryList<DescriptionComponent>

constructor(
protected sanitizer: DomSanitizer,
@Inject(COLLAPSIBLE_CONFIG) protected config: CollapsibleConfiguration,
Expand Down Expand Up @@ -68,6 +82,15 @@ export class DescriptionComponent {

expand() {
this.isExpanded = true
this.parent?.collapseAllChildren({except: this})
}

collapseAllChildren({except}: {except?: DescriptionComponent} = {}) {
const childrenToCollapse = this.children
.filter((child) => child !== except)
for(const child of childrenToCollapse) {
child.collapse()
}
}
}

Expand Down

0 comments on commit 7e1d8ad

Please sign in to comment.