Skip to content

Commit

Permalink
feat: create object card and collection card component (#154)
Browse files Browse the repository at this point in the history
  • Loading branch information
BelgianNoise authored May 9, 2021
1 parent e55a805 commit f74650a
Show file tree
Hide file tree
Showing 32 changed files with 966 additions and 27 deletions.
90 changes: 90 additions & 0 deletions packages/nde-erfgoed-components/lib/collections/card.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { css, html, LitElement, unsafeCSS } from 'lit-element';
import { Theme } from '@digita-ai/nde-erfgoed-theme';

/**
* A card component
*/
export class CardComponent extends LitElement {

/**
* The styles associated with the component.
*/
static get styles() {

return [
unsafeCSS(Theme),
css`
.card:hover {
cursor: pointer;
transform: scale(1.01);
}
.card {
display: flex;
flex-direction: column;
transition: all .1s ease-in-out;
line-height: var(--line-height-large);
}
.card .content {
display: flex;
flex-direction: column;
background-color: var(--colors-foreground-inverse);
padding: var(--gap-normal);
flex: 0 0 53px;
}
.card .content .title, .card .content .subtitle {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.card .content .subtitle {
font-size: var(--font-size-small);
color: var(--colors-accent-primary);
margin-bottom: var(--gap-tiny);
}
.card .image {
flex: 0 0 135px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: var(--colors-foreground-inverse);
}
.card .image slot[name="image"]::slotted(*) {
height: 135px;
width: 100%;
object-fit: cover;
}
.card .image slot[name="image"]::slotted(*) {
fill: var(--colors-foreground-light);
}
`,
];

}

render() {

return html`
<div class='card'>
<div class="image">
<slot name='image'></slot>
</div>
<div class='content'>
<div class='subtitle'>
<slot name='subtitle'></slot>
</div>
<div class='title'>
<slot name='title'></slot>
</div>
</div>
</div>
`;

}

}

export default CardComponent;
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { ArgumentError, Collection, MemoryTranslator } from '@digita-ai/nde-erfgoed-core';
import { CollectionCardComponent } from './collection-card.component';

describe('AlertComponent', () => {

let component: CollectionCardComponent;
const tag = 'nde-collection-card';

const testCollection = {
uri: 'Test Uri Collection',
name: 'Test Collection',
description: 'Collection Test Description',
} as Collection;

beforeEach(() => {

component = window.document.createElement('nde-collection-card') as CollectionCardComponent;

component.translator = new MemoryTranslator([
{
key: 'nde.collections.card.name-unavailable',
value:'Name unavailable',
locale:'en-GB',
},
], 'en-GB');

});

afterEach(() => {

document.getElementsByTagName('html')[0].innerHTML = '';

});

it('should be correctly instantiated', () => {

expect(component).toBeTruthy();

});

it('should display name and description of the collection', async () => {

component.collection = testCollection;
window.document.body.appendChild(component);
await component.updateComplete;

const html = window.document.body.getElementsByTagName(tag)[0].shadowRoot.innerHTML;

expect(html).toContain(testCollection.name);
expect(html).toContain(testCollection.description);

});

it('should display no description when the collection does not have a description', async () => {

component.collection = { ...testCollection, description: undefined };
window.document.body.appendChild(component);
await component.updateComplete;

const html = window.document.body.getElementsByTagName(tag)[0].shadowRoot.innerHTML;

expect(html).toContain(testCollection.name);
expect(html).not.toContain(testCollection.description);

});

it('should display a message when the collection does not have a name', async () => {

component.collection = { ...testCollection, name: undefined };
window.document.body.appendChild(component);
await component.updateComplete;

const html = window.document.body.getElementsByTagName(tag)[0].shadowRoot.innerHTML;

expect(html).not.toContain(testCollection.name);
expect(html).toContain('Name unavailable');
expect(html).toContain(testCollection.description);

});

it('should display no description and a message when the collection is null', async () => {

window.document.body.appendChild(component);
await component.updateComplete;

const html = window.document.body.getElementsByTagName(tag)[0].shadowRoot.innerHTML;

expect(html).not.toContain(testCollection.name);
expect(html).not.toContain(testCollection.description);
expect(html).toContain('Name unavailable');

});

});
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { css, html, property, LitElement, unsafeCSS } from 'lit-element';
import { Collection, Translator } from '@digita-ai/nde-erfgoed-core';
import { Theme } from '@digita-ai/nde-erfgoed-theme';

/**
* A component which shows the details of a single collection.
*/
export class CollectionCardComponent extends LitElement {

/** The collection which will be rendered by the component */
@property({ type: Object })
public collection: Collection = null;

/** Translator used to display last updated time */
@property({ type: Object })
public translator: Translator;

/** The styles associated with the component */
static get styles() {

return [
unsafeCSS(Theme),
css``,
];

}

render() {

return html`
<nde-card>
<span slot='title'>
${this.collection?.name ?? this.translator.translate('nde.collections.card.name-unavailable')}
</span>
<span slot='subtitle'>
<span>
${this.collection?.description ?? ''}
</span>
</span>
</nde-card>
`;

}

}

export default CollectionCardComponent;
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export class CollectionComponent extends LitElement implements Component {
.then((response) => response.text())
.then(() => {

this.collection = { uri:'test', name: 'Test' };
this.collection = { uri:'test', name: 'Test', description: 'Test desc' };

});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import { CollectionObject, MemoryTranslator } from '@digita-ai/nde-erfgoed-core';
import { ObjectCardComponent } from './object-card.component';

describe('ObjectCardComponent', () => {

let component: ObjectCardComponent;
const tag = 'nde-object-card';

const testObject = {
uri: 'test uri',
name: 'test name',
description: 'test description',
subject: 'test subject',
image: 'https://images.unsplash.com/photo-1615390164801-cf2e70f32b53?ixid=MnwxMjA3fDB8MHxwcm9maWxlLXBhZ2V8M3x8fGVufDB8fHx8&ixlib=rb-1.2.1&w=1000&q=80',
updated: +new Date(),
} as CollectionObject;

beforeEach(() => {

component = window.document.createElement('nde-object-card') as ObjectCardComponent;

component.translator = new MemoryTranslator([
{
key: 'nde.collections.card.name-unavailable',
value:'Name unavailable',
locale:'en-GB',
},
{
key: 'nde.collections.card.subject-unavailable',
value:'Subject unavailable',
locale:'en-GB',
},
{
key: 'nde.common.date.just-now',
value:'Just Now',
locale:'en-GB',
},
], 'en-GB');

});

afterEach(() => {

document.getElementsByTagName('html')[0].innerHTML = '';

});

it('should be correctly instantiated', () => {

expect(component).toBeTruthy();

});

it('should display name, subject and time ago of the object', async () => {

component.object = testObject;
window.document.body.appendChild(component);
await component.updateComplete;

const html = window.document.body.getElementsByTagName(tag)[0].shadowRoot.innerHTML;

expect(html).toContain(testObject.name);
expect(html).toContain(testObject.subject);
expect(html).not.toContain('Name unavailable');
expect(html).not.toContain('Subject unavailable');
expect(html).toContain('- Just Now');

});

it('should display message when name of the object is undefined', async () => {

component.object = { ...testObject, name: undefined };
window.document.body.appendChild(component);
await component.updateComplete;

const html = window.document.body.getElementsByTagName(tag)[0].shadowRoot.innerHTML;

expect(html).not.toContain(testObject.name);
expect(html).toContain('Name unavailable');
expect(html).toContain(testObject.subject);
expect(html).not.toContain('Subject unavailable');
expect(html).toContain('- Just Now');

});

it('should display message when subject of the object is undefined', async () => {

component.object = { ...testObject, subject: undefined };
window.document.body.appendChild(component);
await component.updateComplete;

const html = window.document.body.getElementsByTagName(tag)[0].shadowRoot.innerHTML;

expect(html).toContain(testObject.name);
expect(html).not.toContain('Name unavailable');
expect(html).not.toContain(testObject.subject);
expect(html).toContain('Subject unavailable');
expect(html).toContain('- Just Now');

});

it('should not display time ago when updated of the object is undefined', async () => {

component.object = { ...testObject, updated: undefined };
window.document.body.appendChild(component);
await component.updateComplete;

const html = window.document.body.getElementsByTagName(tag)[0].shadowRoot.innerHTML;

expect(html).toContain(testObject.name);
expect(html).not.toContain('Name unavailable');
expect(html).toContain(testObject.subject);
expect(html).not.toContain('Subject unavailable');
expect(html).not.toContain('- Just Now');

});

it('should display the image of the object', async () => {

component.object = testObject;
window.document.body.appendChild(component);
await component.updateComplete;

const html = window.document.body.getElementsByTagName(tag)[0].shadowRoot.innerHTML;

expect(html.split('amp;').join('')).toContain(testObject.image);

});

it('should not display the image of the object', async () => {

component.object = { ...testObject, image: undefined };
window.document.body.appendChild(component);
await component.updateComplete;

const html = window.document.body.getElementsByTagName(tag)[0].shadowRoot.innerHTML;

expect(html.split('amp;').join('')).not.toContain(testObject.image);

});

});
Loading

0 comments on commit f74650a

Please sign in to comment.