diff --git a/docs/assets/images/components/flip-card.gif b/docs/assets/images/components/flip-card.gif
new file mode 100644
index 0000000000..6645f3865a
Binary files /dev/null and b/docs/assets/images/components/flip-card.gif differ
diff --git a/docs/assets/images/components/reveal-card.gif b/docs/assets/images/components/reveal-card.gif
new file mode 100644
index 0000000000..ed680630cb
Binary files /dev/null and b/docs/assets/images/components/reveal-card.gif differ
diff --git a/docs/structure.ts b/docs/structure.ts
index 8887aa8d6e..fee54ddad3 100644
--- a/docs/structure.ts
+++ b/docs/structure.ts
@@ -266,6 +266,48 @@ export const STRUCTURE = [
},
],
},
+ {
+ type: 'page',
+ name: 'Flip Card',
+ children: [
+ {
+ type: 'block',
+ block: 'component',
+ blockData: 'NbFlipCardComponent',
+ },
+ {
+ type: 'block',
+ block: 'component',
+ blockData: 'NbCardFrontComponent',
+ },
+ {
+ type: 'block',
+ block: 'component',
+ blockData: 'NbCardBackComponent',
+ },
+ ],
+ },
+ {
+ type: 'page',
+ name: 'Reveal Card',
+ children: [
+ {
+ type: 'block',
+ block: 'component',
+ blockData: 'NbRevealCardComponent',
+ },
+ {
+ type: 'block',
+ block: 'component',
+ blockData: 'NbCardFrontComponent',
+ },
+ {
+ type: 'block',
+ block: 'component',
+ blockData: 'NbCardBackComponent',
+ },
+ ],
+ },
{
type: 'page',
name: 'Search',
diff --git a/e2e/card.e2e-spec.ts b/e2e/card.e2e-spec.ts
index cf7a6f38f9..6cbb04eb3e 100644
--- a/e2e/card.e2e-spec.ts
+++ b/e2e/card.e2e-spec.ts
@@ -5,28 +5,7 @@
*/
import { browser, element, by } from 'protractor';
-import { hexToRgbA } from './e2e-helper';
-
-const heights = {
- xxsmall: '96px',
- xsmall: '216px',
- small: '336px',
- medium: '456px',
- large: '576px',
- xlarge: '696px',
- xxlarge: '816px',
-};
-
-const colors = {
- // Make sure that you convert hex to rgba before validation
- primary: '#8a7fff',
- success: '#40dc7e',
- info: '#4ca6ff',
- warning: '#ffa100',
- danger: '#ff4c6a',
- default: '#a4abb3',
- disabled: 'rgba(255, 255, 255, 0.4)',
-};
+import { colors, sizes } from './cards-shared';
let cards: any[] = [];
@@ -34,25 +13,39 @@ function prepareCards() {
const result: any[] = [];
let elementNumber: number = 1;
- for (const colorKey in colors) {
- if (colors.hasOwnProperty(colorKey)) {
- for (const heightKey in heights) {
- if (heights.hasOwnProperty(heightKey)) {
- result.push({
- name: heightKey,
- height: heights[heightKey],
- colorKey,
- color: colorKey === 'disabled' ? colors[colorKey] : hexToRgbA(colors[colorKey]),
- elementNumber,
- });
- elementNumber++;
- }
- }
+ for (const { colorKey, color } of colors) {
+ for (const { sizeKey, height } of sizes) {
+ result.push({
+ size: sizeKey,
+ height: height,
+ colorKey,
+ color,
+ elementNumber,
+ });
+ elementNumber++;
}
}
+
return result;
}
+function prepareAccentCards(regularCardsOffset) {
+ function generateAccentCards(accentCardsOffset, colorKey, color) {
+ return colors.map((c, i) => ({
+ name: colorKey,
+ colorKey,
+ color,
+ accentColor: c.color,
+ accentKey: c.colorKey,
+ elementNumber: regularCardsOffset + accentCardsOffset + i,
+ }));
+ }
+
+ return colors.reduce((accentCards, { colorKey, color }) => {
+ return accentCards.concat(generateAccentCards(accentCards.length, colorKey, color));
+ }, []);
+}
+
describe('nb-card', () => {
cards = prepareCards();
@@ -63,11 +56,11 @@ describe('nb-card', () => {
cards.forEach(c => {
- it(`should display ${c.colorKey} card with ${c.name} size`, () => {
+ it(`should display ${c.colorKey} card with ${c.size} size`, () => {
expect(element(by.css(`nb-card:nth-child(${c.elementNumber}) > nb-card-header`))
.getText()).toEqual('Header');
- if (c.name !== 'xxsmall') {
+ if (c.size !== 'xxsmall') {
expect(element(by.css(`nb-card:nth-child(${c.elementNumber}) > nb-card-body`))
.getText()).toEqual('Body');
@@ -90,4 +83,15 @@ describe('nb-card', () => {
});
});
});
+
+ const accentCards = prepareAccentCards(cards.length);
+ accentCards.forEach(c => {
+ it(`should display ${c.colorKey} card with ${c.accentKey} accent`, () => {
+ element.all(by.css(`nb-card`))
+ .get(c.elementNumber)
+ .getCssValue('border-top-color').then(borderColor => {
+ expect(borderColor).toEqual(c.accentColor, 'Accent is not correct');
+ });
+ });
+ });
});
diff --git a/e2e/cards-shared.ts b/e2e/cards-shared.ts
new file mode 100644
index 0000000000..fa1e929283
--- /dev/null
+++ b/e2e/cards-shared.ts
@@ -0,0 +1,21 @@
+import { hexToRgbA } from './e2e-helper';
+
+export const sizes = [
+ { sizeKey: 'xxsmall', height: '96px' },
+ { sizeKey: 'xsmall', height: '216px' },
+ { sizeKey: 'small', height: '336px' },
+ { sizeKey: 'medium', height: '456px' },
+ { sizeKey: 'large', height: '576px' },
+ { sizeKey: 'xlarge', height: '696px' },
+ { sizeKey: 'xxlarge', height: '816px' },
+];
+
+export const colors = [
+ { colorKey: 'primary', color: hexToRgbA('#8a7fff') },
+ { colorKey: 'success', color: hexToRgbA('#40dc7e') },
+ { colorKey: 'info', color: hexToRgbA('#4ca6ff') },
+ { colorKey: 'warning', color: hexToRgbA('#ffa100') },
+ { colorKey: 'danger', color: hexToRgbA('#ff4c6a') },
+ { colorKey: 'default', color: hexToRgbA('#a4abb3') },
+ { colorKey: 'disabled', color: 'rgba(255, 255, 255, 0.4)' },
+];
diff --git a/e2e/flip-card.e2e-spec.ts b/e2e/flip-card.e2e-spec.ts
new file mode 100644
index 0000000000..bc4ba1a3ac
--- /dev/null
+++ b/e2e/flip-card.e2e-spec.ts
@@ -0,0 +1,59 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ */
+
+import { browser, element, by, ExpectedConditions as ec } from 'protractor';
+import { hexToRgbA } from './e2e-helper';
+import { sizes } from './cards-shared';
+
+const waitTime = 500;
+
+const cards = sizes.map((size, i) => ({ size, i }));
+
+describe('nb-flip-card', () => {
+ beforeEach((done) => {
+ browser.get('#/card-status').then(() => done());
+ });
+
+ cards.forEach(c => {
+ describe(`${c.size.sizeKey} flip card`, () => {
+ function shouldShowFrontCard () {
+ const flipCard = element.all(by.tagName('nb-flip-card')).get(c.i);
+ const frontCard = flipCard.all(by.tagName('.front-container')).first();
+ const backCard = flipCard.all(by.tagName('.back-container')).first();
+
+ expect(flipCard.getAttribute('class')).not.toContain('flipped', `flip card shouldn't be flipped`)
+ expect(frontCard.isDisplayed()).toBe(true, 'front card should be visible');
+ }
+
+ it(`should show front card`, shouldShowFrontCard);
+
+ it(`should flip`, () => {
+ const flipCard = element.all(by.tagName('nb-flip-card')).get(c.i);
+ const frontCardFlipButton = flipCard.all(by.css('.flip-button')).first();
+
+ frontCardFlipButton.click().then(() => {
+ expect(flipCard.getAttribute('class')).toContain('flipped', 'flip card should be flipped');
+ });
+ });
+
+ it(`should flip again`, () => {
+ const flipCard = element.all(by.tagName('nb-flip-card')).get(c.i);
+ const frontCardFlipButton = flipCard.all(by.css('.front-container .flip-button')).first();
+ const backCardFlipButton = flipCard.all(by.css('.back-container .flip-button')).first();
+
+ frontCardFlipButton.click()
+ .then(() => {
+ browser.sleep(waitTime);
+ return backCardFlipButton.click()
+ })
+ .then(() => {
+ browser.sleep(waitTime);
+ shouldShowFrontCard();
+ });
+ });
+ });
+ });
+});
diff --git a/e2e/reveal-card.e2e-spec.ts b/e2e/reveal-card.e2e-spec.ts
new file mode 100644
index 0000000000..0e49dd7538
--- /dev/null
+++ b/e2e/reveal-card.e2e-spec.ts
@@ -0,0 +1,75 @@
+/**
+ * @license
+ * Copyright Akveo. All Rights Reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ */
+
+import { browser, element, by, ExpectedConditions as ec } from 'protractor';
+import { hexToRgbA } from './e2e-helper';
+import { sizes } from './cards-shared';
+import { protractor } from 'protractor/built/ptor';
+
+function toInt(cssValue) {
+ return parseInt(cssValue, 10);
+}
+
+const waitTime = 1000;
+
+const cards = sizes.map((size, i) => ({
+ size,
+ i,
+}));
+
+describe('nb-reveal-card', () => {
+ beforeEach((done) => {
+ browser.get('#/card-status').then(() => done());
+ });
+
+ cards.forEach(c => {
+ describe(`${c.size.sizeKey} reveal card`, () => {
+ function showOnlyFrontCard () {
+ const revealCard = element.all(by.tagName('nb-reveal-card')).get(c.i);
+ const frontCard = revealCard.all(by.tagName('nb-card-front')).first();
+ const backCardContainer = revealCard.all(by.css('.second-card-container')).first();
+
+ protractor.promise.all([
+ backCardContainer.getCssValue('top'),
+ revealCard.getCssValue('height'),
+ revealCard.getCssValue('margin-bottom'),
+ ]).then(([ backCardTop, cardHeight, cardMargin ]) => {
+ expect(revealCard.getAttribute('class')).not.toContain('revealed', `card shouldn't has 'revealed' class`);
+ expect(frontCard.isDisplayed()).toBe(true, 'front card should be visible');
+ expect(toInt(backCardTop)).toEqual(toInt(cardHeight) - toInt(cardMargin), 'back card should be hidden');
+ });
+ }
+
+ it(`should show only front card`, showOnlyFrontCard);
+
+ it(`should reveal back card`, () => {
+ const revealCard = element.all(by.tagName('nb-reveal-card')).get(c.i);
+ const backCardContainer = revealCard.all(by.css('.second-card-container')).first();
+ const revealButton = revealCard.all(by.css('.reveal-button')).first();
+
+ revealButton.click().then(() => {
+ expect(revealCard.getAttribute('class')).toContain('revealed', `card should has 'revealed' class`);
+ backCardContainer
+ .getCssValue('top')
+ .then(top => expect(toInt(top)).toEqual(0, 'revealed card should be visible'));
+ });
+ });
+
+ it(`should hide back card`, () => {
+ const revealCard = element.all(by.tagName('nb-reveal-card')).get(c.i);
+ const backCardContainer = revealCard.all(by.css('.second-card-container')).first();
+ const revealButton = revealCard.all(by.css('.reveal-button')).first();
+
+ revealButton.click()
+ .then(() => revealButton.click())
+ .then(() => {
+ browser.sleep(waitTime);
+ showOnlyFrontCard();
+ });
+ });
+ });
+ });
+});
diff --git a/src/app/card-test/card-test.component.ts b/src/app/card-test/card-test.component.ts
index 9f04c9c886..d878c67ead 100644
--- a/src/app/card-test/card-test.component.ts
+++ b/src/app/card-test/card-test.component.ts
@@ -11,6 +11,7 @@ import { Component } from '@angular/core';
template: `
Accent Cards
+
+ Reveal Cards
+
+ Flip Cards
+
+