diff --git a/addons/rose/addon/components/rose/card/link.js b/addons/rose/addon/components/rose/card/link.js new file mode 100644 index 000000000..162a08a0e --- /dev/null +++ b/addons/rose/addon/components/rose/card/link.js @@ -0,0 +1,7 @@ +import Component from '@ember/component'; +import layout from '../../../templates/components/rose/card/link'; + +export default Component.extend({ + layout, + tagName: '', +}); diff --git a/addons/rose/addon/components/rose/card/link.stories.mdx b/addons/rose/addon/components/rose/card/link.stories.mdx new file mode 100644 index 000000000..571bfb28a --- /dev/null +++ b/addons/rose/addon/components/rose/card/link.stories.mdx @@ -0,0 +1,60 @@ +import { Meta, Story, Preview } from '@storybook/addon-docs/blocks'; +import { hbs } from 'ember-cli-htmlbars'; +import { text } from '@storybook/addon-knobs'; + + + +# Card Link + +Card link component wraps content with `LinkTo` component. Supports title and description. + +```html + +``` + + + {{ + template: hbs` + + `, + context: { + title: text('title', 'Card title'), + description: text('description', 'Card description'), + }, + }} + + +`@route` defaults to 'index' when not supplied. + +`@title` and `@description` are optional. Card expands to fit content. + +```html + +``` + + {{ + template: hbs` + + `, + context: { + title: text('title', 'Card title'), + }, + }} + + +```html + +``` + + {{ + template: hbs` + + `, + context: { + description: text('description', 'Card description'), + }, + }} + diff --git a/addons/rose/addon/styles/rose/components/_index.scss b/addons/rose/addon/styles/rose/components/_index.scss index e6d3eefd1..bbd2ebcda 100644 --- a/addons/rose/addon/styles/rose/components/_index.scss +++ b/addons/rose/addon/styles/rose/components/_index.scss @@ -3,3 +3,4 @@ @import 'header'; @import 'layout'; @import 'notification'; +@import 'card'; diff --git a/addons/rose/addon/styles/rose/components/card/_index.scss b/addons/rose/addon/styles/rose/components/card/_index.scss new file mode 100644 index 000000000..f641f2e2d --- /dev/null +++ b/addons/rose/addon/styles/rose/components/card/_index.scss @@ -0,0 +1 @@ +@import 'link'; diff --git a/addons/rose/addon/styles/rose/components/card/_link.scss b/addons/rose/addon/styles/rose/components/card/_link.scss new file mode 100644 index 000000000..949734531 --- /dev/null +++ b/addons/rose/addon/styles/rose/components/card/_link.scss @@ -0,0 +1,62 @@ +@use '../../variables/sizing'; +@use '../../utilities/type'; + +.rose-card-link { + @include type.type(s); + border: 1px solid var(--ui-gray-subtler-2); + border-radius: sizing.rems(xxxs); + color: var(--ui-gray); + display: inline-flex; + flex-direction: column; + + a { + text-decoration: none; + margin: 0; + padding: 0; + display: flex; + justify-content: space-between; + flex-direction: column; + height: 100%; + padding: sizing.rems(s); + // TODO: Figure out better method of defining card dimensions + min-height: sizing.rems(m) * 6; //6 rems + width: sizing.rems(m) * 12; //12 rems + } + + &:hover { + border-color: var(--ui-gray); + background-color: var(--ui-gray-subtler-5); + } + + &:active { + background-color: var(--ui-gray-subtler-4); + } + + &:focus-within { + border-color: var(--info); + } + + .rose-card-link-title { + $truncate-line-count: 3; + @include type.type(m, semibold); + color: var(--stark); + margin: 0; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: $truncate-line-count; + overflow: hidden; + } + + .rose-card-link-subtitle { + color: var(--ui-gray); + margin: 0; + } + + .rose-card-link-description { + margin: auto 0 0; + color: var(--ui-gray); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} diff --git a/addons/rose/addon/templates/components/rose/card/link.hbs b/addons/rose/addon/templates/components/rose/card/link.hbs new file mode 100644 index 000000000..7f003a4a6 --- /dev/null +++ b/addons/rose/addon/templates/components/rose/card/link.hbs @@ -0,0 +1,21 @@ + diff --git a/addons/rose/app/components/rose/card/link.js b/addons/rose/app/components/rose/card/link.js new file mode 100644 index 000000000..350404c2b --- /dev/null +++ b/addons/rose/app/components/rose/card/link.js @@ -0,0 +1 @@ +export { default } from 'rose/components/rose/card/link'; diff --git a/addons/rose/tests/dummy/app/templates/index.hbs b/addons/rose/tests/dummy/app/templates/index.hbs index 12fac556c..3b791ba07 100644 --- a/addons/rose/tests/dummy/app/templates/index.hbs +++ b/addons/rose/tests/dummy/app/templates/index.hbs @@ -181,3 +181,7 @@ Dummy app index template @submitText="Save" @cancelText="Cancel" /> + + + + diff --git a/addons/rose/tests/integration/components/rose/card/link-test.js b/addons/rose/tests/integration/components/rose/card/link-test.js new file mode 100644 index 000000000..78a02af4b --- /dev/null +++ b/addons/rose/tests/integration/components/rose/card/link-test.js @@ -0,0 +1,54 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, find } from '@ember/test-helpers'; +import hbs from 'htmlbars-inline-precompile'; + +module('Integration | Component | rose/card/link', function (hooks) { + setupRenderingTest(hooks); + + test('it renders', async function (assert) { + await render(hbs``); + assert.ok(find('article')); + assert.ok(find('.rose-card-link')); + assert.notOk(find('.rose-card-link-title')); + assert.notOk(find('.rose-card-link-subtitle')); + assert.notOk(find('.rose-card-link-description')); + }); + + test('it renders with @title', async function (assert) { + await render(hbs``); + assert.equal(find('a').title, 'card title'); + assert.equal( + find('.rose-card-link-title').textContent.trim(), + 'card title' + ); + }); + + test('it renders with @subtitle', async function (assert) { + await render(hbs``); + assert.equal( + find('.rose-card-link-subtitle').textContent.trim(), + 'card subtitle' + ); + }); + + test('it renders with @description', async function (assert) { + await render(hbs``); + assert.equal( + find('.rose-card-link-description').textContent.trim(), + 'card description' + ); + }); + + test('it renders with attributes', async function (assert) { + await render(hbs``); + assert.ok(find('#card')); + }); + + test('it renders with content', async function (assert) { + await render(hbs` +