Skip to content

Commit

Permalink
Merge branch 'master' into fix-carousel-docs
Browse files Browse the repository at this point in the history
  • Loading branch information
st3fun1 authored Aug 29, 2024
2 parents 64acc27 + b2015f8 commit 76a0b1c
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 52 deletions.
10 changes: 9 additions & 1 deletion projects/canopy-test-app/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,14 @@
Test primary dark button
</button>
</lg-accordion-item>
<lg-accordion-item>
<lg-accordion-panel-heading><lg-icon name="notes"></lg-icon>Accordion item with icon</lg-accordion-panel-heading>
<p>
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur.
</p>
</lg-accordion-item>
</lg-accordion>

<lg-separator></lg-separator>
Expand Down Expand Up @@ -660,7 +668,7 @@ <h3>Carousel item 3</h3>
<lg-progress-header>
Thinking long term
</lg-progress-header>
</lg-progress-indicator>
</lg-progress-indicator>
</div>
<lg-separator></lg-separator>

Expand Down
2 changes: 2 additions & 0 deletions projects/canopy-test-app/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import {
LgIconComponent,
lgIconFilter,
lgIconLinkExternal,
lgIconNotes,
LgIconRegistry,
lgIconRepeat,
lgIconSearch,
Expand Down Expand Up @@ -369,6 +370,7 @@ export class AppComponent {
lgIconArrowRight,
lgIconLinkExternal,
lgIconCheckboxMark,
lgIconNotes,
]);

this.brandIconRegistry.registerBrandIcon([ lgBrandIconCalendar ]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
[class.lg-accordion__heading-toggle--active]="_isActive"
[attr.aria-expanded]="_isActive"
[attr.aria-controls]="_panelId"
(click)="toggle()"
>
(click)="toggle()">
<ng-content></ng-content>
<lg-icon class="lg-accordion__heading-icon" name="chevron-down"></lg-icon>
<lg-icon class="lg-accordion__heading-icon lg-accordion__heading-icon--animated" name="chevron-down">
</lg-icon>
</button>
</lg-heading>
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,33 @@
}

.lg-accordion__heading-icon {
transition: transform var(--animation-duration) var(--animation-fn);
position: absolute;
left: 0;
top: calc(50% - var(--icon-width) / 2);
margin-left: var(--space-sm);
margin-right: var(--space-sm);
width: var(--space-md);
height: var(--space-md);
pointer-events: none;

&--animated {
transition: transform var(--animation-duration) var(--animation-fn);
}
}

&--active .lg-accordion__heading-icon {
&--active .lg-accordion__heading-icon--animated {
transform: rotateX(180deg);
}

lg-icon {
position: absolute;
left: 0;
top: calc(50% - var(--space-md) / 2);

&:first-child {
@extend .lg-accordion__heading-icon;
}

& ~ lg-icon {
right: 0;
left: unset;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,26 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { MockComponents } from 'ng-mocks';
import { spy, verify } from '@typestrong/ts-mockito';
import { Component } from '@angular/core';

import { LgHeadingComponent } from '../../heading';
import { LgIconComponent } from '../../icon';
import { LgIconComponent, lgIconIdea, LgIconRegistry } from '../../icon';

import { LgAccordionPanelHeadingComponent } from './accordion-panel-heading.component';

@Component({
template: `
<lg-accordion-panel-heading>
<lg-icon name="idea"></lg-icon>Panel heading
</lg-accordion-panel-heading>
`,
})
class LgAccordionPanelHeadingWithDecorativeIconComponent {
constructor(private iconRegistry: LgIconRegistry) {
this.iconRegistry.registerIcons([ lgIconIdea ]);
}
}

describe('LgAccordionPanelHeadingComponent', () => {
let component: LgAccordionPanelHeadingComponent;
let fixture: ComponentFixture<LgAccordionPanelHeadingComponent>;
Expand All @@ -17,6 +31,7 @@ describe('LgAccordionPanelHeadingComponent', () => {
TestBed.configureTestingModule({
imports: [
LgAccordionPanelHeadingComponent,
LgAccordionPanelHeadingWithDecorativeIconComponent,
MockComponents(LgHeadingComponent, LgIconComponent),
],
}).compileComponents();
Expand Down Expand Up @@ -126,4 +141,33 @@ describe('LgAccordionPanelHeadingComponent', () => {
expect().nothing();

Check warning on line 141 in projects/canopy/src/lib/accordion/accordion-panel-heading/accordion-panel-heading.component.spec.ts

View workflow job for this annotation

GitHub Actions / verify

Expect must have a single argument. No arguments were provided
});
});

describe('accordion panel heading with decorative icon', () => {
let fixtureAccordionPanelHeadingWithIcon: ComponentFixture<LgAccordionPanelHeadingWithDecorativeIconComponent>;

beforeEach(() => {
fixtureAccordionPanelHeadingWithIcon = TestBed.createComponent(
LgAccordionPanelHeadingWithDecorativeIconComponent,
);

fixtureAccordionPanelHeadingWithIcon.detectChanges();
});

it('should render an icon when an lg-icon is passed via content projection', () => {
const icons = fixtureAccordionPanelHeadingWithIcon.debugElement.queryAll(
By.css('lg-icon'),
);

expect(icons[0].attributes.name).toBe('idea');
});

it('should still render the chevron icon', () => {
const icons = fixtureAccordionPanelHeadingWithIcon.debugElement.queryAll(
By.css('lg-icon'),
);

expect(icons.length).toBe(2);
expect(icons[1].attributes.name).toBe('chevron-down');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export class LgAccordionPanelHeadingComponent implements AfterViewChecked {
_toggleId = `lg-accordion-panel-heading-${this._id}`;
_panelId = `lg-accordion-panel-${this._id}`;
_isActive = false;
_hasDecorativeIcon = false;

constructor(
private cdr: ChangeDetectorRef,
Expand Down
177 changes: 136 additions & 41 deletions projects/canopy/src/lib/accordion/docs/accordion.stories.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,83 @@
import { CommonModule } from '@angular/common';
import { Meta, moduleMetadata, StoryFn } from '@storybook/angular';
import { Component, Input } from '@angular/core';

import { LgAccordionComponent } from '../accordion.component';
import { LgAccordionItemComponent } from '../accordion-item/accordion-item.component';
import { LgAccordionItemContentDirective } from '../accordion-item/accordion-item-content.directive';
import { LgAccordionPanelHeadingComponent } from '../accordion-panel-heading/accordion-panel-heading.component';
import { LgButtonComponent } from '../../button';
import { LgMarginDirective } from '../../spacing';
import {
lgIconNews,
lgIconNotes,
lgIconIdea,
LgIconRegistry,
LgIconComponent,
} from '../../icon';

const accordionItems = `
<lg-accordion-item [isActive]="itemOneActive"
(opened)="toggle('Item 1 opened')"
(closed)="toggle('Item 1 closed')">
<lg-accordion-panel-heading><lg-icon *ngIf="iconForFirstAccordionItem" [name]="iconForFirstAccordionItem"></lg-icon>Item 1</lg-accordion-panel-heading>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua.</p>
</lg-accordion-item>
<lg-accordion-item [isActive]="itemTwoActive"
(opened)="toggle('Item 3 opened')"
(closed)="toggle('Item 2 closed')">
<lg-accordion-panel-heading><lg-icon *ngIf="iconForSecondAccordionItem" [name]="iconForSecondAccordionItem"></lg-icon>Item 2</lg-accordion-panel-heading>
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
ut aliquip ex ea commodo consequat. Duis aute irure dolor in
<a href="#">reprehenderit</a> in voluptate velit esse cillum dolore eu fugiat nulla
pariatur.</p>
<button lg-button lgMarginTop="sm" variant="primary-dark">
Test primary button
</button>
</lg-accordion-item>
<lg-accordion-item [isActive]="itemThreeActive">
<lg-accordion-panel-heading><lg-icon *ngIf="iconForThirdAccordionItem" [name]="iconForThirdAccordionItem"></lg-icon>Item 3 is Lazy</lg-accordion-panel-heading>
<ng-template lgAccordionItemContent>
<p>This panel content is only initialised when opened</p>
</ng-template>
</lg-accordion-item>
`;

const standardTemplate = `<lg-accordion [headingLevel]="headingLevel" [multi]=multi>${accordionItems}</lg-accordion>`;

@Component({
selector: 'lg-accordion-with-icons-wrapper',
template: standardTemplate,
styles: [
`
:host {
display: block;
padding: var(--space-sm);
}
`,
],
})
class AccordionWrapperComponent {
@Input() iconForFirstAccordionItem = '';
@Input() iconForSecondAccordionItem = '';
@Input() iconForThirdAccordionItem = '';
@Input() headingLevel = 2;
@Input() itemOneActive = false;
@Input() itemTwoActive = true;
@Input() itemThreeActive = false;
@Input() multi = false;
constructor(private registry: LgIconRegistry) {
this.registry.registerIcons([ lgIconNotes, lgIconNews, lgIconIdea ]);
}
}

// This default export determines where your story goes in the story list
export default {
title: 'Components/Accordion/Examples',
component: LgAccordionComponent,
decorators: [
moduleMetadata({
imports: [
Expand All @@ -22,7 +88,9 @@ export default {
LgAccordionPanelHeadingComponent,
LgButtonComponent,
LgMarginDirective,
LgIconComponent,
],
declarations: [ AccordionWrapperComponent ],
}),
],
argTypes: {
Expand Down Expand Up @@ -71,61 +139,88 @@ export default {
},
} as Meta;

const accordionItems = `
<lg-accordion-item [isActive]="itemOneActive"
(opened)="toggle('Item 1 opened')"
(closed)="toggle('Item 1 closed')">
<lg-accordion-panel-heading>Item 1</lg-accordion-panel-heading>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua.</p>
</lg-accordion-item>
<lg-accordion-item [isActive]="itemTwoActive"
(opened)="toggle('Item 3 opened')"
(closed)="toggle('Item 2 closed')">
<lg-accordion-panel-heading>Item 2</lg-accordion-panel-heading>
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
ut aliquip ex ea commodo consequat. Duis aute irure dolor in
<a href="#">reprehenderit</a> in voluptate velit esse cillum dolore eu fugiat nulla
pariatur.</p>
<button lg-button lgMarginTop="sm" variant="primary-dark">
Test primary button
</button>
</lg-accordion-item>
<lg-accordion-item [isActive]="itemThreeActive">
<lg-accordion-panel-heading>Item 3 is Lazy</lg-accordion-panel-heading>
const standardAccordionTemplate: StoryFn<AccordionWrapperComponent> = (
args: AccordionWrapperComponent,
) => ({
props: args,
template: `
<lg-accordion-with-icons-wrapper
[headingLevel]="headingLevel"
[itemOneActive]="itemOneActive"
[itemTwoActive]="itemTwoActive"
[itemThreeActive]="itemThreeActive"
[multi]="multi"
>
</lg-accordion-with-icons-wrapper>
`,
});

<ng-template lgAccordionItemContent>
<p>This panel content is only initialised when opened</p>
</ng-template>
</lg-accordion-item>
`;
export const standardAccordion = standardAccordionTemplate.bind({});

Check warning on line 158 in projects/canopy/src/lib/accordion/docs/accordion.stories.ts

View workflow job for this annotation

GitHub Actions / verify

Unsafe assignment of an `any` value
standardAccordion.storyName = 'Accordion';

Check warning on line 159 in projects/canopy/src/lib/accordion/docs/accordion.stories.ts

View workflow job for this annotation

GitHub Actions / verify

Unsafe member access .storyName on an `any` value

const standardTemplate = `<lg-accordion [headingLevel]="headingLevel" [multi]=multi>${accordionItems}</lg-accordion>`;
standardAccordion.args = {

Check warning on line 161 in projects/canopy/src/lib/accordion/docs/accordion.stories.ts

View workflow job for this annotation

GitHub Actions / verify

Unsafe member access .args on an `any` value
headingLevel: 2,
itemOneActive: false,
itemTwoActive: true,
itemThreeActive: false,
multi: false,
};

const accordionTemplate: StoryFn<LgAccordionComponent> = (
args: LgAccordionComponent,
const accordionWithIconsTemplate: StoryFn<AccordionWrapperComponent> = (
args: AccordionWrapperComponent,
) => ({
props: args,
template: standardTemplate,
template: `<lg-accordion-with-icons-wrapper
[headingLevel]="headingLevel"
[itemOneActive]="itemOneActive"
[itemTwoActive]="itemTwoActive"
[itemThreeActive]="itemThreeActive"
[iconForFirstAccordionItem]="iconForFirstAccordionItem"
[iconForSecondAccordionItem]="iconForSecondAccordionItem"
[iconForThirdAccordionItem]="iconForThirdAccordionItem"
[multi]="multi"
>
</lg-accordion-with-icons-wrapper>`,
});

export const standardAccordion = accordionTemplate.bind({});
standardAccordion.storyName = 'Accordion';
export const accordionWithIcons = accordionWithIconsTemplate.bind({});

standardAccordion.args = {
accordionWithIcons.storyName = 'Accordion with Icons';

accordionWithIcons.args = {
iconForFirstAccordionItem: 'notes',
iconForSecondAccordionItem: 'news',
iconForThirdAccordionItem: 'idea',
headingLevel: 2,
itemOneActive: false,
itemTwoActive: true,
itemThreeActive: false,
multi: false,
};

standardAccordion.parameters = {
docs: {
source: {
code: standardTemplate,
accordionWithIcons.argTypes = {
iconForFirstAccordionItem: {
options: [ 'news', 'notes', 'idea' ],
description:
'The icon to display in the left side of the heading of the first accordion item.',
control: {
type: 'select',
},
},
iconForSecondAccordionItem: {
options: [ 'news', 'notes', 'idea' ],
description:
'The icon to display in the left side of the heading of the second accordion item.',
control: {
type: 'select',
},
},
iconForThirdAccordionItem: {
options: [ 'news', 'notes', 'idea' ],
description:
'The icon to display in the left side of the heading of the third accordion item.',
control: {
type: 'select',
},
},
};
Loading

0 comments on commit 76a0b1c

Please sign in to comment.