Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an isOpenInitially argument to the AuAccordion component #469

Merged
merged 3 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,22 +1,43 @@
import {
AuButton,
AuContent,
AuIcon,
AuLoader,
AuToolbar,
} from '@appuniversum/ember-appuniversum';
import { on } from '@ember/modifier';
import { action } from '@ember/object';
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { modifier } from 'ember-modifier';
import AuButton from './au-button';
import AuContent from './au-content';
import AuIcon from './au-icon';
import AuLoader from './au-loader';
import AuToolbar from './au-toolbar';

const autofocus = modifier(function autofocus(element) {
const autofocus = modifier(function autofocus(element: HTMLElement) {
element.focus();
});

export default class AuAccordion extends Component {
@tracked isOpen = false;
export interface AuAccordionSignature {
Args: {
buttonLabel?: string;
iconClosed?: string;
iconOpen?: string;
isOpenInitially?: boolean;
loading?: boolean;
reverse?: boolean;
skin?: 'border';
subtitle?: string;
};
Blocks: {
default: [];
};
Element: HTMLDivElement;
}

export default class AuAccordion extends Component<AuAccordionSignature> {
@tracked isOpen;

constructor(owner: unknown, args: AuAccordionSignature['Args']) {
super(owner, args);

this.isOpen = Boolean(this.args.isOpenInitially);
}

get loading() {
if (this.args.loading) return 'is-loading';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
import type { TOC } from '@ember/component/template-only';
import Component from '@glimmer/component';

export default class AuToolbar extends Component {
export interface AuToolbarSignature {
Args: {
reverse?: boolean;
border?: 'top' | 'bottom';
skin?: 'tint';
size?: 'small' | 'medium' | 'large';
nowrap?: boolean;
};
Blocks: {
default: [typeof Group];
};
Element: HTMLDivElement;
}

export default class AuToolbar extends Component<AuToolbarSignature> {
get reverse() {
if (this.args.reverse) return 'au-c-toolbar--reverse';
else return '';
Expand Down Expand Up @@ -44,7 +59,14 @@ export default class AuToolbar extends Component {
</template>
}

const Group = <template>
interface GroupSignature {
Blocks: {
default: [];
};
Element: HTMLDivElement;
}

const Group: TOC<GroupSignature> = <template>
<div class="au-c-toolbar__group" ...attributes>
{{yield}}
</div>
Expand Down
4 changes: 4 additions & 0 deletions addon/template-registry.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Components
import type AuAccordion from '@appuniversum/ember-appuniversum/components/au-accordion';
import type AuAlert from '@appuniversum/ember-appuniversum/components/au-alert';
import type AuApp from '@appuniversum/ember-appuniversum/components/au-app';
import type AuBadge from '@appuniversum/ember-appuniversum/components/au-badge';
Expand All @@ -18,12 +19,14 @@ import type AuLinkExternal from '@appuniversum/ember-appuniversum/components/au-
import type AuLink from '@appuniversum/ember-appuniversum/components/au-link';
import type AuList from '@appuniversum/ember-appuniversum/components/au-list';
import type AuLoader from '@appuniversum/ember-appuniversum/components/au-loader';
import type AuToolbar from '@appuniversum/ember-appuniversum/components/au-toolbar';

// Modifiers
import type AuDateInputModifier from '@appuniversum/ember-appuniversum/modifiers/au-date-input';

export default interface AppuniversumRegistry {
// Components
AuAccordion: typeof AuAccordion;
AuAlert: typeof AuAlert;
AuApp: typeof AuApp;
AuBadge: typeof AuBadge;
Expand All @@ -43,6 +46,7 @@ export default interface AppuniversumRegistry {
AuLink: typeof AuLink;
AuList: typeof AuList;
AuLoader: typeof AuLoader;
AuToolbar: typeof AuToolbar;

// Modifiers
'au-date-input': typeof AuDateInputModifier;
Expand Down
7 changes: 7 additions & 0 deletions stories/5-components/Content/AuAccordion.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ export default {
control: 'boolean',
description: 'Adds a loading state to the button',
},
isOpenInitially: {
control: 'boolean',
description:
'When set to `true`, this will render the accordion in the "open" state from the start.',
},
},
parameters: {
layout: 'padded',
Expand All @@ -50,6 +55,7 @@ const Template = (args) => ({
@iconClosed={{this.iconClosed}}
@buttonLabel={{this.buttonLabel}}
@loading={{this.loading}}
@isOpenInitially={{this.isOpenInitially}}
>
<p>I am information. I can even contain a <AuLink>A Link</AuLink>!</p>
</AuAccordion>`,
Expand All @@ -65,4 +71,5 @@ Component.args = {
iconClosed: 'nav-right',
buttonLabel: 'Accordion with arrows',
loading: false,
isOpenInitially: false,
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { module, test } from 'qunit';
import AuAccordion from '@appuniversum/ember-appuniversum/components/au-accordion';
import { click, settled, render } from '@ember/test-helpers';
import { tracked } from '@glimmer/tracking';
import { setupRenderingTest } from 'ember-qunit';
import { click, render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
import { module, test } from 'qunit';

const ACCORDION = {
TOGGLE: '[data-test-accordion-toggle]',
Expand All @@ -13,25 +14,47 @@ const ACCORDION = {
LOADER: '[data-test-accordion-loader]',
};

class TestState {
@tracked iconClosed?: string;
@tracked iconOpen?: string;
@tracked isLoading?: boolean;
}

module('Integration | Component | au-accordion', function (hooks) {
setupRenderingTest(hooks);

test("it doesn't render any content when initially rendered", async function (assert) {
await render(hbs`
<AuAccordion>
Content
</AuAccordion>
`);
await render(
<template>
<AuAccordion>
Content
</AuAccordion>
</template>,
);

assert.dom(ACCORDION.CONTENT).doesNotExist();
});

test('it renders the content by default if `isOpenInitially` is set to `true`', async function (assert) {
await render(
<template>
<AuAccordion @isOpenInitially={{true}}>
Content
</AuAccordion>
</template>,
);

assert.dom(ACCORDION.CONTENT).exists().hasText('Content');
});

test('it toggles its content rendering when clicking it', async function (assert) {
await render(hbs`
<AuAccordion>
Some content
</AuAccordion>
`);
await render(
<template>
<AuAccordion>
Some content
</AuAccordion>
</template>,
);

await toggleAccordion();
assert.dom(ACCORDION.CONTENT).exists().hasText('Some content');
Expand All @@ -41,31 +64,37 @@ module('Integration | Component | au-accordion', function (hooks) {
});

test('it can display a subtitle', async function (assert) {
await render(hbs`
<AuAccordion @subtitle="Foo">
Some content
</AuAccordion>
`);
await render(
<template>
<AuAccordion @subtitle="Foo">
Some content
</AuAccordion>
</template>,
);

assert.dom(ACCORDION.SUBTITLE).exists().hasText('Foo');
});

test('it supports changing the label of the toggle button', async function (assert) {
await render(hbs`
<AuAccordion @buttonLabel="Foo button">
Some content
</AuAccordion>
`);
await render(
<template>
<AuAccordion @buttonLabel="Foo button">
Some content
</AuAccordion>
</template>,
);

assert.dom(ACCORDION.BUTTON).exists().hasText('Foo button');
});

test('it shows a different icon depending on the open state', async function (assert) {
await render(hbs`
<AuAccordion>
Some content
</AuAccordion>
`);
await render(
<template>
<AuAccordion>
Some content
</AuAccordion>
</template>,
);

assert.dom(ACCORDION.ICON_OPEN).doesNotExist();
assert.dom(ACCORDION.ICON_CLOSED).exists();
Expand All @@ -76,17 +105,24 @@ module('Integration | Component | au-accordion', function (hooks) {
});

test('it supports choosing different icons', async function (assert) {
await render(hbs`
<AuAccordion @iconOpen={{this.iconOpen}} @iconClosed={{this.iconClosed}}>
Some content
</AuAccordion>
`);
const state = new TestState();
await render(
<template>
<AuAccordion
@iconOpen={{state.iconOpen}}
@iconClosed={{state.iconClosed}}
>
Some content
</AuAccordion>
</template>,
);

assert
.dom(ACCORDION.ICON_CLOSED)
.hasAttribute('data-test-accordion-icon-closed', 'nav-right');

this.set('iconClosed', 'other-closed-icon');
state.iconClosed = 'other-closed-icon';
await settled();

assert
.dom(ACCORDION.ICON_CLOSED)
Expand All @@ -97,35 +133,42 @@ module('Integration | Component | au-accordion', function (hooks) {
.dom(ACCORDION.ICON_OPEN)
.hasAttribute('data-test-accordion-icon-open', 'nav-down');

this.set('iconOpen', 'other-open-icon');
state.iconOpen = 'other-open-icon';
await settled();

assert
.dom(ACCORDION.ICON_OPEN)
.hasAttribute('data-test-accordion-icon-open', 'other-open-icon');
});

test('it can show a loading indicator instead of content', async function (assert) {
this.isLoading = true;
const state = new TestState();
state.isLoading = true;

await render(hbs`
<AuAccordion @loading={{this.isLoading}}>Some content</AuAccordion>
`);
await render(
<template>
<AuAccordion @loading={{state.isLoading}}>Some content</AuAccordion>
</template>,
);

assert.dom(ACCORDION.LOADER).doesNotExist();

await toggleAccordion();
assert.dom(ACCORDION.LOADER).exists();
assert.dom(ACCORDION.CONTENT).doesNotContainText('Some content');

this.set('isLoading', false);
state.isLoading = false;
await settled();
assert.dom(ACCORDION.LOADER).doesNotExist();
assert.dom(ACCORDION.CONTENT).containsText('Some content');
});

test("it's possible to add extra html attributes", async function (assert) {
await render(hbs`
<AuAccordion class="test" data-test-accordion-external></AuAccordion>
`);
await render(
<template>
<AuAccordion class="test" data-test-accordion-external />
</template>,
);

assert.dom('[data-test-accordion-external]').exists().hasClass('test');
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
import AuToolbar from '@appuniversum/ember-appuniversum/components/au-toolbar';

module('Integration | Component | au-toolbar', function (hooks) {
setupRenderingTest(hooks);

test('it yields a group component', async function (assert) {
await render(hbs`
<AuToolbar as |Group|>
<Group data-test-foo>Foo</Group>
<Group data-test-bar>Bar</Group>
</AuToolbar>
`);
await render(
<template>
<AuToolbar as |Group|>
<Group data-test-foo>Foo</Group>
<Group data-test-bar>Bar</Group>
</AuToolbar>
</template>,
);

assert.dom('[data-test-foo]').hasText('Foo');
assert.dom('[data-test-bar]').hasText('Bar');
});

test('it passes through extra html attributes', async function (assert) {
await render(hbs`
<AuToolbar data-test-foo="bar"></AuToolbar>
`);
await render(<template><AuToolbar data-test-foo="bar" /></template>);

assert.dom('[data-test-foo]').exists();
});
Expand Down
Loading
Loading