-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Implement base and mktg card components (#31)
* feat: Implement base card component for header and body content * feat: Implement vertical mktg card * feat: Implement horizontal card component * feat: Add parameter to left align price in vertical card * feat: Implement tests for vertical card * feat: Implement tests for horizontal card * refactor: Add button role to base card div * refactor: Conditionally render divider in horizontal card * refactor: Rebase and add link on index.hbs * refactor: Combine horizontal and vertical card and address requested changes * fix: Fix isClickable implementation * refactor: Update tests and clean test app * refactor: Clean up empty getters and conditionals * refactor: Fix formatting after rebase
- Loading branch information
1 parent
e9656c7
commit 044d433
Showing
11 changed files
with
483 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import Controller from '@ember/controller'; | ||
|
||
export default class CardsController extends Controller { | ||
clickHandler() { | ||
console.log('clickHandler called'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,158 @@ | ||
<div class="container"> | ||
<p class="py-3">Row on desktop, stacked on mobile</p> | ||
{{!-- template-lint-disable no-inline-styles --}} | ||
<Mktg::CardContainer class="bg-info rounded" style="--bs-gap: .5rem;" as |Container|> | ||
<Container.Card class="g-col-12 g-col-md-4" /> | ||
<Container.Card class="g-col-12 g-col-md-4" /> | ||
<Container.Card class="g-col-12 g-col-md-4" /> | ||
</Mktg::CardContainer> | ||
<p class="py-3">stacked on mobile and desktop</p> | ||
<Mktg::CardContainer class="bg-secondary" as |Container|> | ||
<Container.Card class="g-col-12" /> | ||
<Container.Card class="g-col-12" /> | ||
<Container.Card class="g-col-12" /> | ||
<div data-theme="marketing" class="container"> | ||
<p class="py-3 fw-bold">Row on desktop, stacked on mobile</p> | ||
{{! template-lint-disable no-inline-styles }} | ||
<Mktg::CardContainer style="--bs-gap: .5rem;" as |Container|> | ||
<Container.Card | ||
@isClickable={{true}} | ||
@onClick={{this.clickHandler}} | ||
class="g-col-12 g-col-md-4" | ||
> | ||
<:header> | ||
<p>Here is a title</p> | ||
</:header> | ||
<:body> | ||
<p>Here is some body content</p> | ||
</:body> | ||
</Container.Card> | ||
<Container.Card | ||
@isClickable={{true}} | ||
@onClick={{this.clickHandler}} | ||
class="g-col-12 g-col-md-4" | ||
> | ||
<:header> | ||
<p>Here is a title</p> | ||
</:header> | ||
<:body> | ||
<p>Here is some body content</p> | ||
</:body> | ||
</Container.Card> | ||
<Container.Card | ||
@isClickable={{true}} | ||
@onClick={{this.clickHandler}} | ||
class="g-col-12 g-col-md-4" | ||
> | ||
<:header> | ||
<p>Here is a title</p> | ||
</:header> | ||
<:body> | ||
<p>Here is some body content</p> | ||
</:body> | ||
</Container.Card> | ||
</Mktg::CardContainer> | ||
<div class="container"> | ||
<p class="pt-3 fw-bold">Vertical card with right aligned price</p> | ||
<Mktg::CardContainer class="justify-content-center" as |Container|> | ||
<Container.MktgCard | ||
class="g-col-12" | ||
@title="The Gig" | ||
@subtitle="Experience lightning-fast internet connectivity" | ||
> | ||
<:start> | ||
<div class="d-flex w-100 align-items-start"> | ||
<p>Start Section can go here if you'd like</p> | ||
</div> | ||
</:start> | ||
<:callout> | ||
<p | ||
class="d-flex align-self-start align-self-md-center fs-1 fw-bold m-0" | ||
>$315<span class="fs-5 align-self-end mb-2">/mo</span></p> | ||
</:callout> | ||
<:end> | ||
<p class="card-text mt-2">Includes:</p> | ||
<div class="container"> | ||
<div class="row row-cols-2"> | ||
<p class="col-12 col-md-6"><span | ||
class="me-2 fw-bold" | ||
>✓</span>Cool feature</p> | ||
<p class="col-12 col-md-6"><span | ||
class="me-2 fw-bold" | ||
>✓</span>Cool feature</p> | ||
<p class="col-12 col-md-6"><span | ||
class="me-2 fw-bold" | ||
>✓</span>Cool feature</p> | ||
<p class="col-12 col-md-6"><span | ||
class="me-2 fw-bold" | ||
>✓</span>Cool feature</p> | ||
</div> | ||
</div> | ||
<Button @text="Add to Bundle" class="btn-primary w-100 mt-2" /> | ||
</:end> | ||
</Container.MktgCard> | ||
</Mktg::CardContainer> | ||
<p class="pt-3 fw-bold">Vertical card with left aligned price</p> | ||
<Mktg::CardContainer class="justify-content-center" as |Container|> | ||
<Container.MktgCard | ||
class="g-col-12" | ||
@title="The Gig" | ||
@subtitle="Experience lightning-fast internet connectivity" | ||
@leftAlignCallout={{true}} | ||
> | ||
<:callout> | ||
<p class="d-flex fs-1 fw-bold m-0">$300/mo</p> | ||
</:callout> | ||
<:end> | ||
<p class="card-text mt-2">Includes:</p> | ||
<div class="container"> | ||
<div class="row row-cols-2"> | ||
<p class="col-12 col-md-6"><span | ||
class="me-2 fw-bold" | ||
>✓</span>Cool feature</p> | ||
<p class="col-12 col-md-6"><span | ||
class="me-2 fw-bold" | ||
>✓</span>Cool feature</p> | ||
<p class="col-12 col-md-6"><span | ||
class="me-2 fw-bold" | ||
>✓</span>Cool feature</p> | ||
<p class="col-12 col-md-6"><span | ||
class="me-2 fw-bold" | ||
>✓</span>Cool feature</p> | ||
</div> | ||
</div> | ||
<Button @text="Add to Bundle" class="btn-primary w-100 mt-2" /> | ||
</:end> | ||
</Container.MktgCard> | ||
</Mktg::CardContainer> | ||
</div> | ||
|
||
<div class="container"> | ||
<p class="pt-3 fw-bold">Horizontal card</p> | ||
<Mktg::CardContainer as |Container|> | ||
<Container.MktgCard | ||
@title="The Gig 10" | ||
@horizontal={{true}} | ||
class="g-col-12" | ||
> | ||
<:callout> | ||
<p | ||
class="card-title d-flex align-self-start fs-1 fw-bold m-0 pb-2" | ||
>$300/mo</p> | ||
</:callout> | ||
<:start> | ||
<p class="card-text text-body-secondary">Stream multiple 4k videos, | ||
download large files in seconds, and dominate online gaming like | ||
never before.</p> | ||
<Button | ||
@text="Get Started" | ||
class="bg-primary text-white w-100 mt-2" | ||
/> | ||
</:start> | ||
<:end> | ||
<p class="card-text mt-2">Includes:</p> | ||
<div class="container"> | ||
<div class="row"> | ||
<p class="col-12"><span class="me-2 fw-bold">✓</span>Cool | ||
feature</p> | ||
<p class="col-12"><span class="me-2 fw-bold">✓</span>Cool | ||
feature</p> | ||
<p class="col-12"><span class="me-2 fw-bold">✓</span>Cool | ||
feature</p> | ||
<p class="col-12"><span class="me-2 fw-bold">✓</span>Cool | ||
feature</p> | ||
</div> | ||
</div> | ||
</:end> | ||
</Container.MktgCard> | ||
</Mktg::CardContainer> | ||
</div> | ||
<div class="p-5"></div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
packages/ember-test-app/tests/integration/components/card-test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { assert, module, test } from 'qunit'; | ||
import { setupRenderingTest } from 'ember-qunit'; | ||
import { render } from '@ember/test-helpers'; | ||
import { hbs } from 'ember-cli-htmlbars'; | ||
|
||
module('Integration | components | card', function (hooks) { | ||
setupRenderingTest(hooks); | ||
|
||
test('it renders the card with the correct content', async function () { | ||
await render(hbs` | ||
<Card> | ||
<:header> | ||
<p>Header content</p> | ||
</:header> | ||
<:body> | ||
<p>Body content</p> | ||
</:body> | ||
</Card>`); | ||
|
||
assert.dom('.card').exists('Card is rendered'); | ||
assert | ||
.dom('.card .card-header p') | ||
.hasText('Header content', 'Correct content is rendered in card header'); | ||
assert | ||
.dom('.card .card-body p') | ||
.hasText('Body content', 'Correct content is rendered in card body'); | ||
}); | ||
}); |
159 changes: 159 additions & 0 deletions
159
packages/ember-test-app/tests/integration/components/mktg/card-test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
import { assert, module, test } from 'qunit'; | ||
import { setupRenderingTest } from 'ember-qunit'; | ||
import { render } from '@ember/test-helpers'; | ||
import { hbs } from 'ember-cli-htmlbars'; | ||
|
||
module('Integration | Component | mktg/card', function (hooks) { | ||
setupRenderingTest(hooks); | ||
|
||
test('card correctly renders vertical as default', async function () { | ||
await render(hbs` | ||
<Mktg::Card | ||
class="g-col-12" | ||
@title="Title" | ||
@subtitle="Subtitle" | ||
> | ||
<:callout> | ||
<p>Callout</p> | ||
</:callout> | ||
<:start> | ||
<div> | ||
<p>Start section content</p> | ||
</div> | ||
</:start> | ||
<:end> | ||
<p>End section content</p> | ||
</:end> | ||
</Mktg::Card>`); | ||
assert | ||
.dom('.card.g-col-12') | ||
.exists('Base card is rendered with passed attributes'); | ||
assert | ||
.dom( | ||
'.card .card-header .d-flex.flex-column.justify-content-start.align-items-center.bg-white.mb-2', | ||
) | ||
.exists('Card renders vertically if no @horizontal is passed'); | ||
assert | ||
.dom('.card .card-header div div p') | ||
.hasText( | ||
'Title', | ||
'Title content renders in correct order with correct text', | ||
); | ||
assert | ||
.dom('.card .card-header div p:nth-of-type(2)') | ||
.hasText( | ||
'Callout', | ||
'Callout renders in correct order with correct content when @leftAlignCallout is not passed', | ||
); | ||
assert | ||
.dom('.card .card-header div div:nth-of-type(2) p') | ||
.hasText( | ||
'Subtitle', | ||
'Subtitle content renders in correct order with correct text', | ||
); | ||
|
||
assert | ||
.dom('.card .card-header div div:nth-of-type(3) p') | ||
.hasText( | ||
'Start section content', | ||
'Start section renders when block is present', | ||
); | ||
assert.dom('.card .card-body').exists('Base card body renders'); | ||
assert | ||
.dom('.card .card-body p') | ||
.hasText( | ||
'End section content', | ||
'End section renders when block is present', | ||
); | ||
await render(hbs` | ||
<Mktg::Card | ||
class="g-col-12" | ||
@title="Title" | ||
@subtitle="Subtitle" | ||
@leftAlignCallout={{true}} | ||
> | ||
<:callout> | ||
<p>Callout</p> | ||
</:callout> | ||
<:start> | ||
<div> | ||
<p>Start section content</p> | ||
</div> | ||
</:start> | ||
<:end> | ||
<p>End section content</p> | ||
</:end> | ||
</Mktg::Card> | ||
`); | ||
assert | ||
.dom( | ||
'.card .card-header div .d-flex.flex-column.justify-content-start.w-100.m-0', | ||
) | ||
.exists( | ||
'Div containing left aligned callout renders when @leftAlignedCallout is true', | ||
); | ||
assert | ||
.dom('.card .card-header div div p') | ||
.hasText( | ||
'Callout', | ||
'Callout renders in correct order when @leftAlignCallout is true', | ||
); | ||
assert | ||
.dom('.card .card-header div div p:nth-of-type(2)') | ||
.hasText( | ||
'Title', | ||
'Title renders in correct order when @leftAlignCallout is true', | ||
); | ||
}); | ||
|
||
test('card correctly renders horizontal when @horizontal is true', async function () { | ||
await render(hbs` | ||
<Mktg::Card | ||
class="g-col-12" | ||
@title="Title" | ||
@subtitle="Subtitle" | ||
@horizontal={{true}} | ||
> | ||
<:callout> | ||
<p>Callout</p> | ||
</:callout> | ||
<:start> | ||
<div> | ||
<p>Start section content</p> | ||
</div> | ||
</:start> | ||
<:end> | ||
<p>End section content</p> | ||
</:end> | ||
</Mktg::Card>`); | ||
|
||
assert.notOk( | ||
document.querySelector('.card-header'), | ||
'Card header does not render when @horizontal is true', | ||
); | ||
assert.dom('.card .card-body').exists('Base card body renders'); | ||
assert | ||
.dom('.card .card-body div div div p') | ||
.hasText('Title', 'Title renders in correct order with correct text'); | ||
assert | ||
.dom('.card .card-body div div div p:nth-of-type(2)') | ||
.hasText( | ||
'Callout', | ||
'Callout renders in correct order with correct content', | ||
); | ||
assert | ||
.dom('.card .card-body div div div div p') | ||
.hasText( | ||
'Start section content', | ||
'Start section renders in correct order when present', | ||
); | ||
assert | ||
.dom( | ||
'.card .card-body div:nth-of-type(2) .vr.d-none.d-md-flex.text-body-secondary', | ||
) | ||
.exists('Divider renders if end block is present'); | ||
assert | ||
.dom('.card .card-body div:nth-of-type(3) p') | ||
.hasText('End section content', 'End section renders when present'); | ||
}); | ||
}); |
Oops, something went wrong.