From 0538d5fbcf21e4e468ba739cd546a8cfb8303c64 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Tue, 19 May 2020 15:05:42 -0400 Subject: [PATCH 1/5] =?UTF-8?q?chore:=20=F0=9F=A4=96=20New=20header=20comp?= =?UTF-8?q?onent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/rose/addon/components/rose/header.js | 7 + .../addon/components/rose/header.stories.mdx | 73 ++++++++ .../addon/components/rose/header/brand.js | 7 + .../addon/components/rose/header/dropdown.js | 34 ++++ .../rose/header/dropdown/content.js | 7 + .../rose/header/dropdown/content/button.js | 7 + .../rose/header/dropdown/trigger.js | 7 + .../components/rose/header/navigation.js | 7 + .../addon/components/rose/header/utilities.js | 7 + .../addon/styles/rose/components/_header.scss | 171 ++++++++++++++++++ .../addon/styles/rose/components/_index.scss | 1 + .../styles/rose/variables/color/_css.scss | 4 + .../templates/components/rose/header.hbs | 8 + .../components/rose/header/brand.hbs | 1 + .../components/rose/header/dropdown.hbs | 14 ++ .../rose/header/dropdown/content.hbs | 6 + .../rose/header/dropdown/content/button.hbs | 3 + .../rose/header/dropdown/trigger.hbs | 4 + .../components/rose/header/navigation.hbs | 8 + .../components/rose/header/utilities.hbs | 7 + addons/rose/app/components/rose/header.js | 1 + .../rose/app/components/rose/header/brand.js | 1 + .../app/components/rose/header/dropdown.js | 1 + .../rose/header/dropdown/content.js | 1 + .../rose/header/dropdown/content/button.js | 1 + .../rose/header/dropdown/trigger.js | 1 + .../app/components/rose/header/navigation.js | 1 + .../app/components/rose/header/utilities.js | 1 + .../unit/.gitkeep => app/templates/about.hbs} | 0 addons/rose/package.json | 1 + addons/rose/tests/dummy/app/router.js | 4 +- .../rose/tests/dummy/app/templates/index.hbs | 26 +++ .../components/rose/header-test.js | 58 ++++++ .../components/rose/header/brand-test.js | 13 ++ .../components/rose/header/dropdown-test.js | 96 ++++++++++ .../rose/header/dropdown/content-test.js | 73 ++++++++ .../header/dropdown/content/button-test.js | 24 +++ .../rose/header/dropdown/trigger-test.js | 37 ++++ .../components/rose/header/navigation-test.js | 29 +++ .../components/rose/header/utilities-test.js | 21 +++ yarn.lock | 111 +++++++++--- 41 files changed, 857 insertions(+), 27 deletions(-) create mode 100644 addons/rose/addon/components/rose/header.js create mode 100644 addons/rose/addon/components/rose/header.stories.mdx create mode 100644 addons/rose/addon/components/rose/header/brand.js create mode 100644 addons/rose/addon/components/rose/header/dropdown.js create mode 100644 addons/rose/addon/components/rose/header/dropdown/content.js create mode 100644 addons/rose/addon/components/rose/header/dropdown/content/button.js create mode 100644 addons/rose/addon/components/rose/header/dropdown/trigger.js create mode 100644 addons/rose/addon/components/rose/header/navigation.js create mode 100644 addons/rose/addon/components/rose/header/utilities.js create mode 100644 addons/rose/addon/styles/rose/components/_header.scss create mode 100644 addons/rose/addon/templates/components/rose/header.hbs create mode 100644 addons/rose/addon/templates/components/rose/header/brand.hbs create mode 100644 addons/rose/addon/templates/components/rose/header/dropdown.hbs create mode 100644 addons/rose/addon/templates/components/rose/header/dropdown/content.hbs create mode 100644 addons/rose/addon/templates/components/rose/header/dropdown/content/button.hbs create mode 100644 addons/rose/addon/templates/components/rose/header/dropdown/trigger.hbs create mode 100644 addons/rose/addon/templates/components/rose/header/navigation.hbs create mode 100644 addons/rose/addon/templates/components/rose/header/utilities.hbs create mode 100644 addons/rose/app/components/rose/header.js create mode 100644 addons/rose/app/components/rose/header/brand.js create mode 100644 addons/rose/app/components/rose/header/dropdown.js create mode 100644 addons/rose/app/components/rose/header/dropdown/content.js create mode 100644 addons/rose/app/components/rose/header/dropdown/content/button.js create mode 100644 addons/rose/app/components/rose/header/dropdown/trigger.js create mode 100644 addons/rose/app/components/rose/header/navigation.js create mode 100644 addons/rose/app/components/rose/header/utilities.js rename addons/rose/{tests/unit/.gitkeep => app/templates/about.hbs} (100%) create mode 100644 addons/rose/tests/integration/components/rose/header-test.js create mode 100644 addons/rose/tests/integration/components/rose/header/brand-test.js create mode 100644 addons/rose/tests/integration/components/rose/header/dropdown-test.js create mode 100644 addons/rose/tests/integration/components/rose/header/dropdown/content-test.js create mode 100644 addons/rose/tests/integration/components/rose/header/dropdown/content/button-test.js create mode 100644 addons/rose/tests/integration/components/rose/header/dropdown/trigger-test.js create mode 100644 addons/rose/tests/integration/components/rose/header/navigation-test.js create mode 100644 addons/rose/tests/integration/components/rose/header/utilities-test.js diff --git a/addons/rose/addon/components/rose/header.js b/addons/rose/addon/components/rose/header.js new file mode 100644 index 000000000..0eb922549 --- /dev/null +++ b/addons/rose/addon/components/rose/header.js @@ -0,0 +1,7 @@ +import Component from '@ember/component'; +import layout from '../../templates/components/rose/header'; + +export default Component.extend({ + layout, + tagName: '', +}); diff --git a/addons/rose/addon/components/rose/header.stories.mdx b/addons/rose/addon/components/rose/header.stories.mdx new file mode 100644 index 000000000..aa5126a23 --- /dev/null +++ b/addons/rose/addon/components/rose/header.stories.mdx @@ -0,0 +1,73 @@ +import { Meta, Story, Preview } from '@storybook/addon-docs/blocks'; +import { hbs } from 'ember-cli-htmlbars'; +import { action } from '@storybook/addon-actions'; +import { text, boolean } from '@storybook/addon-knobs'; + + + +# Header + +A header component that allows three distinct sections to be configured: brand, navigation, and utilities. + +```htmlbars + + + + + + Org name + + link + button + + + Section + + + + + Click me + + link + button + + + + +``` + + + {{ + template: hbs` + + + + + {{navigation-dropdown-label}} + + {{navigation-dropdown-link-label}} + {{navigation-dropdown-button-label}} + + + {{navigation-link-label}} + + + + + + link + button + + + + + `, + context: { + 'navigation-dropdown-label': text('navigation-dropdown-label', 'Org Name'), + 'navigation-dropdown-link-label': text('navigation-dropdown-link-label', 'Menu Item'), + 'navigation-dropdown-button-label': text('navigation-dropdown-button-label', 'Menu Item'), + 'navigation-link-label': text('navigation-link-label', 'Section'), + 'open-dropdown': boolean('open-dropdown', false), + }, + }} + diff --git a/addons/rose/addon/components/rose/header/brand.js b/addons/rose/addon/components/rose/header/brand.js new file mode 100644 index 000000000..c1e63e6ab --- /dev/null +++ b/addons/rose/addon/components/rose/header/brand.js @@ -0,0 +1,7 @@ +import Component from '@ember/component'; +import layout from '../../../templates/components/rose/header/brand'; + +export default Component.extend({ + layout, + tagName: '', +}); diff --git a/addons/rose/addon/components/rose/header/dropdown.js b/addons/rose/addon/components/rose/header/dropdown.js new file mode 100644 index 000000000..2808ab8a7 --- /dev/null +++ b/addons/rose/addon/components/rose/header/dropdown.js @@ -0,0 +1,34 @@ +import Component from '@ember/component'; +import layout from '../../../templates/components/rose/header/dropdown'; +import { tracked } from '@glimmer/tracking'; +import { action } from '@ember/object'; + +export default Component.extend({ + layout, + tagName: '', + + @tracked isOpen: false, + + @action + toggle(event) { + this.isOpen = event.target.open; + }, + + @action + addClickOutside(element) { + document.addEventListener('click', event => this.clickOutside(event, element), true); + }, + + @action + removeClickOutside(element) { + document.removeEventListener('click', event => this.clickOutside(event, element), true); + }, + + @action + clickOutside(event, element) { + // Only close dropdown when non-nested elements are clicked + if(element.contains(event.target)) { return; } + this.removeClickOutside(element); + this.isOpen = false; + } +}); diff --git a/addons/rose/addon/components/rose/header/dropdown/content.js b/addons/rose/addon/components/rose/header/dropdown/content.js new file mode 100644 index 000000000..4f2bf32a0 --- /dev/null +++ b/addons/rose/addon/components/rose/header/dropdown/content.js @@ -0,0 +1,7 @@ +import Component from '@ember/component'; +import layout from '../../../../templates/components/rose/header/dropdown/content'; + +export default Component.extend({ + layout, + tagName: '', +}); diff --git a/addons/rose/addon/components/rose/header/dropdown/content/button.js b/addons/rose/addon/components/rose/header/dropdown/content/button.js new file mode 100644 index 000000000..fa19bd4b9 --- /dev/null +++ b/addons/rose/addon/components/rose/header/dropdown/content/button.js @@ -0,0 +1,7 @@ +import Component from '@ember/component'; +import layout from '../../../../../templates/components/rose/header/dropdown/content/button'; + +export default Component.extend({ + layout, + tagName: '', +}); diff --git a/addons/rose/addon/components/rose/header/dropdown/trigger.js b/addons/rose/addon/components/rose/header/dropdown/trigger.js new file mode 100644 index 000000000..72ffb581c --- /dev/null +++ b/addons/rose/addon/components/rose/header/dropdown/trigger.js @@ -0,0 +1,7 @@ +import Component from '@ember/component'; +import layout from '../../../../templates/components/rose/header/dropdown/trigger'; + +export default Component.extend({ + layout, + tagName: '', +}); diff --git a/addons/rose/addon/components/rose/header/navigation.js b/addons/rose/addon/components/rose/header/navigation.js new file mode 100644 index 000000000..4ef10f9e3 --- /dev/null +++ b/addons/rose/addon/components/rose/header/navigation.js @@ -0,0 +1,7 @@ +import Component from '@ember/component'; +import layout from '../../../templates/components/rose/header/navigation'; + +export default Component.extend({ + layout, + tagName: '', +}); diff --git a/addons/rose/addon/components/rose/header/utilities.js b/addons/rose/addon/components/rose/header/utilities.js new file mode 100644 index 000000000..ff615c434 --- /dev/null +++ b/addons/rose/addon/components/rose/header/utilities.js @@ -0,0 +1,7 @@ +import Component from '@ember/component'; +import layout from '../../../templates/components/rose/header/utilities'; + +export default Component.extend({ + layout, + tagName: '', +}); diff --git a/addons/rose/addon/styles/rose/components/_header.scss b/addons/rose/addon/styles/rose/components/_header.scss new file mode 100644 index 000000000..dbd1740e3 --- /dev/null +++ b/addons/rose/addon/styles/rose/components/_header.scss @@ -0,0 +1,171 @@ +@use '../variables/sizing'; +@use '../utilities/type'; + +$brand-hashicorp: "data:image/svg+xml;utf-8,"; + +$dropdown-chevron: ( + 'default': "data:image/svg+xml;utf-8,", + 'open': "data:image/svg+xml;utf-8,", +); + +.rose-header { + @include type.type(s, semibold); + display: grid; + grid-template-areas: 'brand navigation utilities'; + grid-template-columns: 0.01fr auto 1fr; + grid-gap: sizing.rems(xxxs); + background: var(--stark); + color: var(--subtle); + padding: sizing.rems(xxs) 0; + + .rose-header-brand { + grid-area: brand; + margin: sizing.rems(xs) 0 sizing.rems(xs) sizing.rems(m); + padding: 0 sizing.rems(m); + height: sizing.rems(l) + sizing.rems(xxs); + background-image: url($brand-hashicorp); + background-repeat: no-repeat; + } + + .rose-header-navigation { + grid-area: navigation; + + .wrapper { + display: flex; + flex-wrap: wrap; + } + + .rose-header-navigation-link { + padding: sizing.rems(xs) sizing.rems(s) sizing.rems(xxxs) sizing.rems(s); + text-decoration: none; + display: block; + color: var(--subtle); + height: sizing.rems(l); + border: 1px solid var(--stark); + border-radius: sizing.rems(xxs); + text-align: center; + margin-top: sizing.rems(xxs); + cursor: pointer; + + &:hover { + background: var(--ui-gray-starker-3); + } + + &:active { + background: var(--ui-gray-starker-2); + } + } + } + + .rose-header-utilities { + grid-area: utilities; + + .wrapper { + margin-right: sizing.rems(s); + display: flex; + flex-wrap: wrap; + flex-direction: row-reverse; + } + } + + .rose-header-navigation, .rose-header-utilities { + .rose-header-dropdown { + height: sizing.rems(m) + sizing.rems(xxxs); + + .rose-header-dropdown-trigger { + height: sizing.rems(m) + sizing.rems(xxxs); + padding: sizing.rems(xs) sizing.rems(xxs); + border-radius: sizing.rems(xxxs); + color: var(--subtle); + margin: sizing.rems(xxs) sizing.rems(xxs) 0 0; + cursor: pointer; + + &.rose-header-dropdown-open { + background: var(--subtle); + color: var(--ui-gray-starker-4); + + .rose-header-dropdown-chevron { + background-image: url(map-get($dropdown-chevron, 'open')); + } + } + + &::-webkit-details-marker { + display: none; + } + + .rose-header-dropdown-chevron { + background-image: url(map-get($dropdown-chevron, 'default')); + width: sizing.rems(m); + height: sizing.rems(m); + background-repeat: no-repeat; + display: inline-block; + vertical-align: middle; + } + + .rose-icon { + position: relative; + top: - sizing.rems(xxs); + } + } + + .rose-header-dropdown-content { + position: absolute; + background-color: var(--subtle); + border-radius: sizing.rems(xxxs); + border: 1px solid var(--ui-gray-subtler-2); + + &.rose-header-dropdown-content-right { + right: sizing.rems(m); + } + + .rose-header-dropdown-content-link{ + padding: sizing.rems(s) (sizing.rems(xl) * 3) sizing.rems(xxs) sizing.rems(s); + text-decoration: none; + display: block; + color: var(--ui-gray-starker-4); + height: sizing.rems(l); + } + + + .rose-header-dropdown-content-button { + button { + cursor: pointer; + padding: sizing.rems(s) (sizing.rems(xl) * 3) sizing.rems(xs) sizing.rems(s); + color: var(--ui-gray-starker-4); + box-shadow: none; + display: inline-block; + border: none; + text-decoration: none; + font-size: inherit; + font-weight: inherit; + -webkit-appearance: none; + } + } + } + } + } +} + +//TODO: Where do media query sizes live? +@media (max-width: 768px) { + .rose-header { + grid-template-columns: 1fr 3fr; + grid-template-areas: + 'brand utilities' + 'navigation navigation'; + padding-bottom: 0; + + .rose-header-navigation { + background: var(--ui-header-subtler); + padding: sizing.rems(xs) sizing.rems(s); + + .rose-header-navigation-link { + border: 1px solid var(--ui-gray-subtler); + + &:hover { + background: var(--ui-gray-starker-3); + } + } + } + } +} diff --git a/addons/rose/addon/styles/rose/components/_index.scss b/addons/rose/addon/styles/rose/components/_index.scss index dd972080b..475417601 100644 --- a/addons/rose/addon/styles/rose/components/_index.scss +++ b/addons/rose/addon/styles/rose/components/_index.scss @@ -1,2 +1,3 @@ @import 'button'; @import 'form'; +@import 'header'; diff --git a/addons/rose/addon/styles/rose/variables/color/_css.scss b/addons/rose/addon/styles/rose/variables/color/_css.scss index 765b71ac7..ca6df5c3d 100644 --- a/addons/rose/addon/styles/rose/variables/color/_css.scss +++ b/addons/rose/addon/styles/rose/variables/color/_css.scss @@ -74,6 +74,8 @@ --ui-gray-starker-2: #{color(ui-gray, 700)}; --ui-gray-starker-3: #{color(ui-gray, 800)}; --ui-gray-starker-4: #{color(ui-gray, 900)}; + + --ui-header-subtler: #{color(ui-cool-gray, 700)}; } // Dark Mode @@ -131,5 +133,7 @@ --ui-gray-starker-2: #{color(ui-gray, 100)}; --ui-gray-starker-3: #{color(ui-gray, 050)}; --ui-gray-starker-4: #{color(ui-gray, 010)}; + + --ui-header-subtler: #{color(ui-cool-gray, 100)}; } } diff --git a/addons/rose/addon/templates/components/rose/header.hbs b/addons/rose/addon/templates/components/rose/header.hbs new file mode 100644 index 000000000..343b45d93 --- /dev/null +++ b/addons/rose/addon/templates/components/rose/header.hbs @@ -0,0 +1,8 @@ +
+ {{yield (hash + brand=(component 'rose/header/brand') + utilities=(component 'rose/header/utilities') + navigation=(component 'rose/header/navigation') + )}} +
diff --git a/addons/rose/addon/templates/components/rose/header/brand.hbs b/addons/rose/addon/templates/components/rose/header/brand.hbs new file mode 100644 index 000000000..836e22b70 --- /dev/null +++ b/addons/rose/addon/templates/components/rose/header/brand.hbs @@ -0,0 +1 @@ + diff --git a/addons/rose/addon/templates/components/rose/header/dropdown.hbs b/addons/rose/addon/templates/components/rose/header/dropdown.hbs new file mode 100644 index 000000000..d8b289a44 --- /dev/null +++ b/addons/rose/addon/templates/components/rose/header/dropdown.hbs @@ -0,0 +1,14 @@ +
+ {{yield (hash + isOpen=this.isOpen + trigger=(component 'rose/header/dropdown/trigger' + isOpen=this.isOpen) + content=(component 'rose/header/dropdown/content' isOpen=this.isOpen + position=@position) + )}} +
diff --git a/addons/rose/addon/templates/components/rose/header/dropdown/content.hbs b/addons/rose/addon/templates/components/rose/header/dropdown/content.hbs new file mode 100644 index 000000000..48c30b03c --- /dev/null +++ b/addons/rose/addon/templates/components/rose/header/dropdown/content.hbs @@ -0,0 +1,6 @@ + + {{yield (hash + link=(component 'link-to' class="rose-header-dropdown-content-link") + button=(component 'rose/header/dropdown/content/button') + )}} + diff --git a/addons/rose/addon/templates/components/rose/header/dropdown/content/button.hbs b/addons/rose/addon/templates/components/rose/header/dropdown/content/button.hbs new file mode 100644 index 000000000..e437e4689 --- /dev/null +++ b/addons/rose/addon/templates/components/rose/header/dropdown/content/button.hbs @@ -0,0 +1,3 @@ + + + diff --git a/addons/rose/addon/templates/components/rose/header/dropdown/trigger.hbs b/addons/rose/addon/templates/components/rose/header/dropdown/trigger.hbs new file mode 100644 index 000000000..960ad35f5 --- /dev/null +++ b/addons/rose/addon/templates/components/rose/header/dropdown/trigger.hbs @@ -0,0 +1,4 @@ + + {{yield}} + + diff --git a/addons/rose/addon/templates/components/rose/header/navigation.hbs b/addons/rose/addon/templates/components/rose/header/navigation.hbs new file mode 100644 index 000000000..8ce8c7a72 --- /dev/null +++ b/addons/rose/addon/templates/components/rose/header/navigation.hbs @@ -0,0 +1,8 @@ + + + {{yield (hash + link=(component 'link-to' class="rose-header-navigation-link") + dropdown=(component 'rose/header/dropdown') + )}} + + diff --git a/addons/rose/addon/templates/components/rose/header/utilities.hbs b/addons/rose/addon/templates/components/rose/header/utilities.hbs new file mode 100644 index 000000000..c5b060286 --- /dev/null +++ b/addons/rose/addon/templates/components/rose/header/utilities.hbs @@ -0,0 +1,7 @@ + + + {{yield (hash + dropdown=(component 'rose/header/dropdown' position="true") + )}} + + diff --git a/addons/rose/app/components/rose/header.js b/addons/rose/app/components/rose/header.js new file mode 100644 index 000000000..7c011982b --- /dev/null +++ b/addons/rose/app/components/rose/header.js @@ -0,0 +1 @@ +export { default } from 'rose/components/rose/header'; diff --git a/addons/rose/app/components/rose/header/brand.js b/addons/rose/app/components/rose/header/brand.js new file mode 100644 index 000000000..b21f5e748 --- /dev/null +++ b/addons/rose/app/components/rose/header/brand.js @@ -0,0 +1 @@ +export { default } from 'rose/components/rose/header/brand'; \ No newline at end of file diff --git a/addons/rose/app/components/rose/header/dropdown.js b/addons/rose/app/components/rose/header/dropdown.js new file mode 100644 index 000000000..689d4487e --- /dev/null +++ b/addons/rose/app/components/rose/header/dropdown.js @@ -0,0 +1 @@ +export { default } from 'rose/components/rose/header/dropdown'; \ No newline at end of file diff --git a/addons/rose/app/components/rose/header/dropdown/content.js b/addons/rose/app/components/rose/header/dropdown/content.js new file mode 100644 index 000000000..0ef8131da --- /dev/null +++ b/addons/rose/app/components/rose/header/dropdown/content.js @@ -0,0 +1 @@ +export { default } from 'rose/components/rose/header/dropdown/content'; \ No newline at end of file diff --git a/addons/rose/app/components/rose/header/dropdown/content/button.js b/addons/rose/app/components/rose/header/dropdown/content/button.js new file mode 100644 index 000000000..7576f9dae --- /dev/null +++ b/addons/rose/app/components/rose/header/dropdown/content/button.js @@ -0,0 +1 @@ +export { default } from 'rose/components/rose/header/dropdown/content/button'; \ No newline at end of file diff --git a/addons/rose/app/components/rose/header/dropdown/trigger.js b/addons/rose/app/components/rose/header/dropdown/trigger.js new file mode 100644 index 000000000..ea84a3b44 --- /dev/null +++ b/addons/rose/app/components/rose/header/dropdown/trigger.js @@ -0,0 +1 @@ +export { default } from 'rose/components/rose/header/dropdown/trigger'; \ No newline at end of file diff --git a/addons/rose/app/components/rose/header/navigation.js b/addons/rose/app/components/rose/header/navigation.js new file mode 100644 index 000000000..ff5cfc74a --- /dev/null +++ b/addons/rose/app/components/rose/header/navigation.js @@ -0,0 +1 @@ +export { default } from 'rose/components/rose/header/navigation'; diff --git a/addons/rose/app/components/rose/header/utilities.js b/addons/rose/app/components/rose/header/utilities.js new file mode 100644 index 000000000..bb5f37bc3 --- /dev/null +++ b/addons/rose/app/components/rose/header/utilities.js @@ -0,0 +1 @@ +export { default } from 'rose/components/rose/header/utilities'; \ No newline at end of file diff --git a/addons/rose/tests/unit/.gitkeep b/addons/rose/app/templates/about.hbs similarity index 100% rename from addons/rose/tests/unit/.gitkeep rename to addons/rose/app/templates/about.hbs diff --git a/addons/rose/package.json b/addons/rose/package.json index 755adec7e..e61a1d234 100644 --- a/addons/rose/package.json +++ b/addons/rose/package.json @@ -32,6 +32,7 @@ }, "devDependencies": { "@ember/optional-features": "^1.3.0", + "@ember/render-modifiers": "^1.0.2", "@glimmer/component": "^1.0.0", "@glimmer/tracking": "^1.0.0", "@hashicorp/structure-icons": "^1.8.1", diff --git a/addons/rose/tests/dummy/app/router.js b/addons/rose/tests/dummy/app/router.js index 818c8d496..c5464a74c 100644 --- a/addons/rose/tests/dummy/app/router.js +++ b/addons/rose/tests/dummy/app/router.js @@ -6,4 +6,6 @@ export default class Router extends EmberRouter { rootURL = config.rootURL; } -Router.map(function () {}); +Router.map(function () { + this.route('about'); +}); diff --git a/addons/rose/tests/dummy/app/templates/index.hbs b/addons/rose/tests/dummy/app/templates/index.hbs index 0a96fc98a..236fd0598 100644 --- a/addons/rose/tests/dummy/app/templates/index.hbs +++ b/addons/rose/tests/dummy/app/templates/index.hbs @@ -1,3 +1,29 @@ + + + + + + Org name + + link + button + + + Section + + + + + Click me + + link + button + + + + + + Dummy app index template

Icon

diff --git a/addons/rose/tests/integration/components/rose/header-test.js b/addons/rose/tests/integration/components/rose/header-test.js new file mode 100644 index 000000000..72b6ef3fb --- /dev/null +++ b/addons/rose/tests/integration/components/rose/header-test.js @@ -0,0 +1,58 @@ +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/header', function (hooks) { + setupRenderingTest(hooks); + + test('it renders', async function (assert) { + await render(hbs``); + assert.ok(find('.rose-header')); + }); + + test('it renders with brand', async function (assert) { + await render(hbs` + + `); + assert.ok(find('.rose-header-brand')); + assert.notOk(find('.rose-header-navigation')); + assert.notOk(find('.rose-header-utilities')); + }); + + test('it renders with navigation', async function (assert) { + await render(hbs` + + `); + assert.ok(find('.rose-header-navigation')); + assert.notOk(find('.rose-header-brand')); + assert.notOk(find('.rose-header-utilities')); + }); + + test('it renders with navigation elements', async function (assert) { + await render(hbs` + + + + `); + assert.ok(find('.rose-header-navigation-link')); + }); + + test('it renders with utilities', async function (assert) { + await render(hbs` + + `); + assert.notOk(find('.rose-header-brand')); + assert.notOk(find('.rose-header-navigation')); + assert.ok(find('.rose-header-utilities')); + }); + + test('it renders with utility elements', async function (assert) { + await render(hbs` + + + + `); + assert.ok(find('.rose-header-dropdown')); + }); +}); diff --git a/addons/rose/tests/integration/components/rose/header/brand-test.js b/addons/rose/tests/integration/components/rose/header/brand-test.js new file mode 100644 index 000000000..5529aa5a3 --- /dev/null +++ b/addons/rose/tests/integration/components/rose/header/brand-test.js @@ -0,0 +1,13 @@ +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/header/brand', function(hooks) { + setupRenderingTest(hooks); + + test('it renders', async function (assert) { + await render(hbs``); + assert.ok(find('.rose-header-brand')); + }); +}); diff --git a/addons/rose/tests/integration/components/rose/header/dropdown-test.js b/addons/rose/tests/integration/components/rose/header/dropdown-test.js new file mode 100644 index 000000000..ea6f0cb29 --- /dev/null +++ b/addons/rose/tests/integration/components/rose/header/dropdown-test.js @@ -0,0 +1,96 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, click, find, findAll } from '@ember/test-helpers'; +import hbs from 'htmlbars-inline-precompile'; + +module('Integration | Component | rose/header/dropdown', function(hooks) { + setupRenderingTest(hooks); + + test('it renders', async function(assert) { + await render(hbs``); + assert.ok(find('.rose-header-dropdown')); + }); + + test('it renders with html attributes', async function(assert) { + await render(hbs``); + assert.ok(find('#custom-id')); + assert.ok(find('.custom-class')); + }); + + test('it renders with trigger', async function(assert) { + await render(hbs` + Click me + `); + assert.ok(find('.rose-header-dropdown-trigger')); + assert.equal(find('.rose-header-dropdown-trigger').textContent.trim(), 'Click me'); + }); + + test('it renders with content', async function(assert) { + await render(hbs` + + + + + + + + `); + assert.ok(find('.rose-header-dropdown-content')); + assert.equal(findAll('a').length, 2); + assert.equal(findAll('button').length, 3); + }); + + test('it is opened when @isOpen={{true}}', async function(assert) { + this.set('isOpen', false); + await render(hbs` + Click me + + + + `); + assert.notOk(find('.rose-header-dropdown-trigger.rose-header-dropdown-open')); + assert.notOk(find('.rose-header-dropdown-content.rose-header-dropdown-open')); + + this.set('isOpen', true); + assert.ok(find('.rose-header-dropdown-trigger.rose-header-dropdown-open')); + assert.ok(find('.rose-header-dropdown-content.rose-header-dropdown-open')); + }); + + test('it is toggled on click on trigger content', async function(assert) { + await render(hbs` + Click me + + + + `); + assert.notOk(find('#dropdown').open); + assert.notOk(find('.rose-header-dropdown-trigger.rose-header-dropdown-open')); + assert.notOk(find('.rose-header-dropdown-content.rose-header-dropdown-open')); + + await click('#trigger'); + + assert.ok(find('#dropdown').open); + assert.ok(find('.rose-header-dropdown-trigger.rose-header-dropdown-open')); + assert.ok(find('.rose-header-dropdown-content.rose-header-dropdown-open')); + + await click('#trigger'); + assert.notOk(find('#dropdown').open); + assert.notOk(find('.rose-header-dropdown-trigger.rose-header-dropdown-open')); + assert.notOk(find('.rose-header-dropdown-content.rose-header-dropdown-open')); + }); + + test('it is closed with outside click is triggered', async function(assert) { + await render(hbs`
+ Click me + + + +
`); + + await click('#trigger'); + assert.ok(find('#dropdown').open); + + await click('#wrapper'); + assert.notOk(find('#dropdown').open); + }); +}); diff --git a/addons/rose/tests/integration/components/rose/header/dropdown/content-test.js b/addons/rose/tests/integration/components/rose/header/dropdown/content-test.js new file mode 100644 index 000000000..7ea669671 --- /dev/null +++ b/addons/rose/tests/integration/components/rose/header/dropdown/content-test.js @@ -0,0 +1,73 @@ +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/header/dropdown/content', function(hooks) { + setupRenderingTest(hooks); + + test('it renders', async function(assert) { + await render(hbs``); + assert.ok(find('.rose-header-dropdown-content')); + }); + + test('it renders with content', async function(assert) { + await render(hbs` + content + `); + assert.equal(find('.rose-header-dropdown-content').textContent.trim(), 'content'); + }); + + test('it renders with html attributes', async function(assert) { + await render(hbs``); + assert.equal(find('.rose-header-dropdown-content').id, 'dropdown-content'); + assert.ok(find('.rose-header-dropdown-content').className.match('universe')); + }); + + test('it is open when @isOpen={{true}}', async function(assert) { + this.set('isOpen', false); + await render(hbs``); + assert.notOk(find('.rose-header-dropdown-open')); + + this.set('isOpen', true); + assert.ok(find('.rose-header-dropdown-open')); + }); + + test('it is positioned right when @position={{true}}', async function(assert) { + await render(hbs``); + assert.notOk(find('.rose-header-dropdown-content-right')); + + await render(hbs``); + assert.ok(find('.rose-header-dropdown-content-right')); + }); + + test('it render link element', async function(assert) { + await render(hbs` + + `); + assert.ok(find('a')); + assert.ok(find('.rose-header-dropdown-content-link')); + }); + + test('it render link element with content', async function(assert) { + await render(hbs` + linkify + `); + assert.equal(find('a').textContent.trim(), 'linkify'); + }); + + test('it render button element', async function(assert) { + await render(hbs` + + `); + assert.ok(find('button')); + assert.ok(find('.rose-header-dropdown-content-button')); + }); + + test('it render button element with content', async function(assert) { + await render(hbs` + dropdown button + `); + assert.equal(find('button').textContent.trim(), 'dropdown button'); + }); +}); diff --git a/addons/rose/tests/integration/components/rose/header/dropdown/content/button-test.js b/addons/rose/tests/integration/components/rose/header/dropdown/content/button-test.js new file mode 100644 index 000000000..8ea5783c8 --- /dev/null +++ b/addons/rose/tests/integration/components/rose/header/dropdown/content/button-test.js @@ -0,0 +1,24 @@ +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/header/dropdown/content/button', function(hooks) { + setupRenderingTest(hooks); + + test('it renders', async function(assert) { + await render(hbs``); + assert.ok(find('.rose-header-dropdown-content-button')); + }); + + test('it renders with content', async function(assert) { + await render(hbs`Button content`); + assert.equal(find('.rose-header-dropdown-content-button').textContent.trim(), 'Button content'); + }); + + test('it render button element', async function(assert) { + await render(hbs``); + assert.ok(find('button')); + assert.equal(find('button').type, 'button'); + }); +}); diff --git a/addons/rose/tests/integration/components/rose/header/dropdown/trigger-test.js b/addons/rose/tests/integration/components/rose/header/dropdown/trigger-test.js new file mode 100644 index 000000000..e2180c867 --- /dev/null +++ b/addons/rose/tests/integration/components/rose/header/dropdown/trigger-test.js @@ -0,0 +1,37 @@ +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/header/dropdown/trigger', function(hooks) { + setupRenderingTest(hooks); + + test('it renders', async function(assert) { + await render(hbs``); + assert.ok(find('.rose-header-dropdown-trigger')); + assert.notOk(find('.rose-header-dropdown-open')); + }); + + test('it renders with content', async function(assert) { + await render(hbs` + trigger content + `); + assert.equal(find('.rose-header-dropdown-trigger').textContent.trim(), 'trigger content'); + }); + + test('it renders with html attributes', async function(assert) { + await render(hbs``); + assert.equal(find('.rose-header-dropdown-trigger').id, 'trigger'); + assert.ok(find('.rose-header-dropdown-trigger').className.match('dropdown-trigger')); + }); + + test('it is open when @isOpen={{true}}', async function(assert) { + await render(hbs``); + assert.ok(find('.rose-header-dropdown-open')); + }); + + test('it renders chevron', async function(assert) { + await render(hbs``); + assert.ok(find('.rose-header-dropdown-chevron')); + }); +}); diff --git a/addons/rose/tests/integration/components/rose/header/navigation-test.js b/addons/rose/tests/integration/components/rose/header/navigation-test.js new file mode 100644 index 000000000..11ac6cda5 --- /dev/null +++ b/addons/rose/tests/integration/components/rose/header/navigation-test.js @@ -0,0 +1,29 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, find, findAll } from '@ember/test-helpers'; +import hbs from 'htmlbars-inline-precompile'; + +module('Integration | Component | rose/header/navigation', function (hooks) { + setupRenderingTest(hooks); + + test('it renders', async function (assert) { + await render(hbs``); + assert.ok(find('.rose-header-navigation')); + }); + + test('it renders navigation link elements', async function (assert) { + await render(hbs` + + + `); + assert.equal(findAll('a').length, 2); + }); + + test('it renders navigation dropdown elements', async function (assert) { + await render(hbs` + + + `); + assert.equal(findAll('.rose-header-dropdown').length, 2); + }); +}); diff --git a/addons/rose/tests/integration/components/rose/header/utilities-test.js b/addons/rose/tests/integration/components/rose/header/utilities-test.js new file mode 100644 index 000000000..56f263714 --- /dev/null +++ b/addons/rose/tests/integration/components/rose/header/utilities-test.js @@ -0,0 +1,21 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, find, findAll } from '@ember/test-helpers'; +import hbs from 'htmlbars-inline-precompile'; + +module('Integration | Component | rose/header/utilities', function(hooks) { + setupRenderingTest(hooks); + + test('it renders', async function (assert) { + await render(hbs``); + assert.ok(find('.rose-header-utilities')); + }); + + test('it renders navigation dropdown elements', async function (assert) { + await render(hbs` + + + `); + assert.equal(findAll('.rose-header-dropdown').length, 2); + }); +}); diff --git a/yarn.lock b/yarn.lock index e888e5e7a..7747f7348 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1451,6 +1451,14 @@ ember-cli-babel "^6.16.0" ember-compatibility-helpers "^1.1.1" +"@ember/render-modifiers@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@ember/render-modifiers/-/render-modifiers-1.0.2.tgz#2e87c48db49d922ce4850d707215caaac60d8444" + integrity sha512-6tEnHl5+62NTSAG2mwhGMFPhUrJQjoVqV+slsn+rlTknm2Zik+iwxBQEbwaiQOU1FUYxkS8RWcieovRNMR8inQ== + dependencies: + ember-cli-babel "^7.10.0" + ember-modifier-manager-polyfill "^1.1.0" + "@ember/test-helpers@^1.7.0", "@ember/test-helpers@^1.7.1": version "1.7.1" resolved "https://registry.yarnpkg.com/@ember/test-helpers/-/test-helpers-1.7.1.tgz#cc22a954b3b46856518f034bd492a74e0482389f" @@ -2470,9 +2478,9 @@ integrity sha512-LB2R1Oyhpg8gu4SON/mfforE525+Hi/M1ineICEDftqNVTyFg1aRIeGuTvXAoWHc4nbrFncWtJgMmoyRvuGh7A== "@types/node@^9.6.0": - version "9.6.55" - resolved "https://registry.yarnpkg.com/@types/node/-/node-9.6.55.tgz#7cc1358c9c18e71f6c020e410962971863232cf5" - integrity sha512-e/5tg8Ok0gSrN6pvHphnwTK0/CD9VPZrtZqpvvpEFAtfs+ZntusgGaWkf2lSEq1OFe2EDPeUMiMVpy4nZpJ4AQ== + version "9.6.56" + resolved "https://registry.yarnpkg.com/@types/node/-/node-9.6.56.tgz#036f665320d2f04bd62c0cd83222254a6a3b4437" + integrity sha512-Cq4pUCsBL6H7X0HFAOap75lmQqcnSmUDSP0R03lz9UsxRvBu5QsnKLLgIoitlFBX+j6LmciWYQAbOSmGMi7vwA== "@types/npmlog@^4.1.2": version "4.1.2" @@ -3844,6 +3852,13 @@ babel-plugin-ember-modules-api-polyfill@^2.12.0, babel-plugin-ember-modules-api- dependencies: ember-rfc176-data "^0.3.12" +babel-plugin-ember-modules-api-polyfill@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-ember-modules-api-polyfill/-/babel-plugin-ember-modules-api-polyfill-2.13.0.tgz#f9d3928d4c40192a44a5b52b67bbdedc4a748ea2" + integrity sha512-Q2i7uZMNSuJFYUV8stEsLQIRfMhQJew62sOnR+ESNjb4vlI7Rj1JlSgymTGwmCTVh+poTBpMidiWCoITDtbiIA== + dependencies: + ember-rfc176-data "^0.3.13" + babel-plugin-emotion@^10.0.20, babel-plugin-emotion@^10.0.27: version "10.0.33" resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-10.0.33.tgz#ce1155dcd1783bbb9286051efee53f4e2be63e03" @@ -4896,23 +4911,21 @@ broccoli-funnel-reducer@^1.0.0: resolved "https://registry.yarnpkg.com/broccoli-funnel-reducer/-/broccoli-funnel-reducer-1.0.0.tgz#11365b2a785aec9b17972a36df87eef24c5cc0ea" integrity sha1-ETZbKnha7JsXlyo234fu8kxcwOo= -broccoli-funnel@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/broccoli-funnel/-/broccoli-funnel-3.0.0.tgz#46fa8b570eccdfa9f66c71e85ce4a5dc68ec2ad6" - integrity sha512-BzqVvCXQt/d0Lk9fmT8Z/34rt2BB1OjQe1+e5w29ZXkg7pBlvRIYiPq3M+1Hy0E6jJ/ASB6m/d7TBl7cTHjEFQ== +broccoli-funnel@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/broccoli-funnel/-/broccoli-funnel-3.0.3.tgz#26fd42632471f67a91f4770d1987118087219937" + integrity sha512-LPzZ91BwStoHZXdXHQAJeYORl189OrRKM5NdIi86SDU9wZ4s/3lV1PRFOiobDT/jKM10voM7CDzfvicHbCYxAQ== dependencies: array-equal "^1.0.0" blank-object "^1.0.1" - broccoli-plugin "^3.0.0" + broccoli-plugin "^4.0.1" debug "^4.1.1" fast-ordered-set "^1.0.0" fs-tree-diff "^2.0.1" heimdalljs "^0.2.0" minimatch "^3.0.0" path-posix "^1.0.0" - rimraf "^3.0.0" - symlink-or-copy "^1.0.0" - walk-sync "^0.3.1" + walk-sync "^2.0.2" broccoli-funnel@^1.0.1: version "1.2.0" @@ -5175,7 +5188,7 @@ broccoli-plugin@^2.0.0, broccoli-plugin@^2.1.0: rimraf "^2.3.4" symlink-or-copy "^1.1.8" -broccoli-plugin@^3.0.0, broccoli-plugin@^3.1.0: +broccoli-plugin@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/broccoli-plugin/-/broccoli-plugin-3.1.0.tgz#54ba6dd90a42ec3db5624063292610e326b1e542" integrity sha512-7w7FP8WJYjLvb0eaw27LO678TGGaom++49O1VYIuzjhXjK5kn2+AMlDm7CaUFw4F7CLGoVQeZ84d8gICMJa4lA== @@ -5694,9 +5707,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0: - version "1.0.30001061" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001061.tgz#80ca87ef14eb543a7458e7fd2b5e2face3458c9f" - integrity sha512-SMICCeiNvMZnyXpuoO+ot7FHpMVPlrsR+HmfByj6nY4xYDHXLqMTbgH7ecEkDNXWkH1vaip+ZS0D7VTXwM1KYQ== + version "1.0.30001062" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001062.tgz#d814b648338504b315222ace6f1a533d9a55e390" + integrity sha512-ei9ZqeOnN7edDrb24QfJ0OZicpEbsWxv7WusOiQGz/f2SfvBgHHbOEwBJ8HKGVSyx8Z6ndPjxzR6m0NQq+0bfw== caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001043: version "1.0.30001046" @@ -7233,14 +7246,14 @@ elliptic@^6.0.0: minimalistic-crypto-utils "^1.0.0" ember-a11y-testing@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ember-a11y-testing/-/ember-a11y-testing-3.0.0.tgz#b2680aa115ba9eeed1d02dae8052df4053ef1435" - integrity sha512-ovkdLWINtt3sdbVgQfZ/ZiYNWB4tLaOENS6zp241gBXvo7AJqj3t9RrH1ljWAs9G8k9Cx6Z4F+dJrMJ6v/z6Hg== + version "3.0.1" + resolved "https://registry.yarnpkg.com/ember-a11y-testing/-/ember-a11y-testing-3.0.1.tgz#011643aec55f6fbf4fa0beeca883f3e911eb0512" + integrity sha512-T+s4qsMQRftxI9wLaQhP19mqCMEa8zHMGbtZh8F0lJOkfwFcETKMXXEyrEPo/PCEiemNG00BuwOJ75teyu+fyA== dependencies: axe-core "3.5.3" - broccoli-funnel "3.0.0" + broccoli-funnel "3.0.3" ember-cli-babel "7.19.0" - ember-cli-version-checker "5.0.2" + ember-cli-version-checker "5.1.1" ember-get-config "0.2.4" ember-assign-polyfill@^2.6.0: @@ -7310,7 +7323,7 @@ ember-cli-babel-plugin-helpers@^1.0.0, ember-cli-babel-plugin-helpers@^1.1.0: resolved "https://registry.yarnpkg.com/ember-cli-babel-plugin-helpers/-/ember-cli-babel-plugin-helpers-1.1.0.tgz#de3baedd093163b6c2461f95964888c1676325ac" integrity sha512-Zr4my8Xn+CzO0gIuFNXji0eTRml5AxZUTDQz/wsNJ5AJAtyFWCY4QtKdoELNNbiCVGt1lq5yLiwTm4scGKu6xA== -ember-cli-babel@7.19.0, ember-cli-babel@^7.1.2, ember-cli-babel@^7.11.0, ember-cli-babel@^7.11.1, ember-cli-babel@^7.12.0, ember-cli-babel@^7.13.2, ember-cli-babel@^7.17.2, ember-cli-babel@^7.18.0, ember-cli-babel@^7.19.0, ember-cli-babel@^7.4.1, ember-cli-babel@^7.7.0, ember-cli-babel@^7.7.3: +ember-cli-babel@7.19.0, ember-cli-babel@^7.1.2, ember-cli-babel@^7.11.0, ember-cli-babel@^7.11.1, ember-cli-babel@^7.12.0, ember-cli-babel@^7.13.2, ember-cli-babel@^7.17.2, ember-cli-babel@^7.18.0, ember-cli-babel@^7.7.0, ember-cli-babel@^7.7.3: version "7.19.0" resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-7.19.0.tgz#e6eddea18a867231fcf90a80689e92b98be9a63b" integrity sha512-HiWKuoyy35vGEr+iCw6gUnQ3pS5qslyTlKEDW8cVoMbvZNGYBgRxHed5nklVUh+BS74AwR9lsp25BTAagYAP9Q== @@ -7361,6 +7374,38 @@ ember-cli-babel@^6.0.0-beta.4, ember-cli-babel@^6.11.0, ember-cli-babel@^6.12.0, ember-cli-version-checker "^2.1.2" semver "^5.5.0" +ember-cli-babel@^7.10.0, ember-cli-babel@^7.19.0, ember-cli-babel@^7.4.1: + version "7.20.0" + resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-7.20.0.tgz#aa77eadd15036a053534fc68f7933bb97c5a1e25" + integrity sha512-DwV5Cbn8wlRFpG8zQXxYPRb0NRnnaj/2qVDODeUEjM/doDhoDDbTSSaEI5Pf0kIlkVIimyGB8qpGv1fkgj2IfQ== + dependencies: + "@babel/core" "^7.9.0" + "@babel/helper-compilation-targets" "^7.8.7" + "@babel/plugin-proposal-class-properties" "^7.8.3" + "@babel/plugin-proposal-decorators" "^7.8.3" + "@babel/plugin-transform-modules-amd" "^7.9.0" + "@babel/plugin-transform-runtime" "^7.9.0" + "@babel/plugin-transform-typescript" "^7.9.0" + "@babel/polyfill" "^7.8.7" + "@babel/preset-env" "^7.9.0" + "@babel/runtime" "^7.9.0" + amd-name-resolver "^1.2.1" + babel-plugin-debug-macros "^0.3.0" + babel-plugin-ember-data-packages-polyfill "^0.1.2" + babel-plugin-ember-modules-api-polyfill "^2.13.0" + babel-plugin-module-resolver "^3.1.1" + broccoli-babel-transpiler "^7.4.0" + broccoli-debug "^0.6.4" + broccoli-funnel "^2.0.1" + broccoli-source "^1.1.0" + clone "^2.1.2" + ember-cli-babel-plugin-helpers "^1.1.0" + ember-cli-version-checker "^4.1.0" + ensure-posix-path "^1.0.2" + fixturify-project "^1.10.0" + rimraf "^3.0.1" + semver "^5.5.0" + ember-cli-code-coverage@^1.0.0-beta.9: version "1.0.0-beta.9" resolved "https://registry.yarnpkg.com/ember-cli-code-coverage/-/ember-cli-code-coverage-1.0.0-beta.9.tgz#4a4ca60e88fbf1895de99e3b439f46c129417ab7" @@ -7641,13 +7686,13 @@ ember-cli-uglify@^3.0.0: broccoli-uglify-sourcemap "^3.1.0" lodash.defaultsdeep "^4.6.0" -ember-cli-version-checker@5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/ember-cli-version-checker/-/ember-cli-version-checker-5.0.2.tgz#7e96157be4b13b083a68078b188820193275d8c4" - integrity sha512-cqFrIg9++GKdpMv2DP8pryAhTcmCYUL2hzHatLwkcJe23s+ioZ0JQWte0avxZ5lJnwn5e3kzUKkLkDfHDFBMUw== +ember-cli-version-checker@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/ember-cli-version-checker/-/ember-cli-version-checker-5.1.1.tgz#3185c526c14671609cbd22ab0d0925787fc84f3d" + integrity sha512-YziSW1MgOuVdJSyUY2CKSC4vXrGQIHF6FgygHkJOxYGjZNQYwf5MK0sbliKatvJf7kzDSnXs+r8JLrD74W/A8A== dependencies: resolve-package-path "^2.0.0" - semver "^7.1.3" + semver "^7.3.2" silent-error "^1.1.1" ember-cli-version-checker@^1.0.2: @@ -7960,6 +8005,15 @@ ember-maybe-import-regenerator@^0.1.6: ember-cli-babel "^6.0.0-beta.4" regenerator-runtime "^0.9.5" +ember-modifier-manager-polyfill@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ember-modifier-manager-polyfill/-/ember-modifier-manager-polyfill-1.2.0.tgz#cf4444e11a42ac84f5c8badd85e635df57565dda" + integrity sha512-bnaKF1LLKMkBNeDoetvIJ4vhwRPKIIumWr6dbVuW6W6p4QV8ZiO+GdF8J7mxDNlog9CeL9Z/7wam4YS86G8BYA== + dependencies: + ember-cli-babel "^7.10.0" + ember-cli-version-checker "^2.1.2" + ember-compatibility-helpers "^1.2.0" + ember-page-title@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/ember-page-title/-/ember-page-title-5.2.1.tgz#12261e010bec96af6200cd132fe4068e717ccbec" @@ -8008,6 +8062,11 @@ ember-rfc176-data@^0.3.12: resolved "https://registry.yarnpkg.com/ember-rfc176-data/-/ember-rfc176-data-0.3.12.tgz#90d82878e69e2ac9a5438e8ce14d12c6031c5bd2" integrity sha512-g9HeZj/gU5bfIIrGXkP7MhS2b3Vu5DfNUrYr14hy99TgIvtZETO+96QF4WOEUXGjIJdfTRjerVnQlqngPQSv1g== +ember-rfc176-data@^0.3.13: + version "0.3.13" + resolved "https://registry.yarnpkg.com/ember-rfc176-data/-/ember-rfc176-data-0.3.13.tgz#ed1712a26e65fec703655f35410414aa1982cf3b" + integrity sha512-m9JbwQlT6PjY7x/T8HslnXP7Sz9bx/pz3FrNfNi2NesJnbNISly0Lix6NV1fhfo46572cpq4jrM+/6yYlMefTQ== + ember-router-generator@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/ember-router-generator/-/ember-router-generator-1.2.3.tgz#8ed2ca86ff323363120fc14278191e9e8f1315ee" From 5bc7e54b3ebda503178355c739fc273aea1f5d2a Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Tue, 19 May 2020 16:45:14 -0400 Subject: [PATCH 2/5] Add ember-modifiers addon to replace render-modifiers addon --- addons/rose/package.json | 2 +- yarn.lock | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/addons/rose/package.json b/addons/rose/package.json index e61a1d234..bcc19b49f 100644 --- a/addons/rose/package.json +++ b/addons/rose/package.json @@ -32,7 +32,6 @@ }, "devDependencies": { "@ember/optional-features": "^1.3.0", - "@ember/render-modifiers": "^1.0.2", "@glimmer/component": "^1.0.0", "@glimmer/tracking": "^1.0.0", "@hashicorp/structure-icons": "^1.8.1", @@ -58,6 +57,7 @@ "ember-inline-svg": "^1.0.0", "ember-load-initializers": "^2.1.1", "ember-maybe-import-regenerator": "^0.1.6", + "ember-modifier": "^1.0.3", "ember-qunit": "^4.6.0", "ember-radio-button": "^2.0.1", "ember-resolver": "^7.0.0", diff --git a/yarn.lock b/yarn.lock index 7747f7348..99c5c4865 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1451,14 +1451,6 @@ ember-cli-babel "^6.16.0" ember-compatibility-helpers "^1.1.1" -"@ember/render-modifiers@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@ember/render-modifiers/-/render-modifiers-1.0.2.tgz#2e87c48db49d922ce4850d707215caaac60d8444" - integrity sha512-6tEnHl5+62NTSAG2mwhGMFPhUrJQjoVqV+slsn+rlTknm2Zik+iwxBQEbwaiQOU1FUYxkS8RWcieovRNMR8inQ== - dependencies: - ember-cli-babel "^7.10.0" - ember-modifier-manager-polyfill "^1.1.0" - "@ember/test-helpers@^1.7.0", "@ember/test-helpers@^1.7.1": version "1.7.1" resolved "https://registry.yarnpkg.com/@ember/test-helpers/-/test-helpers-1.7.1.tgz#cc22a954b3b46856518f034bd492a74e0482389f" @@ -8005,7 +7997,7 @@ ember-maybe-import-regenerator@^0.1.6: ember-cli-babel "^6.0.0-beta.4" regenerator-runtime "^0.9.5" -ember-modifier-manager-polyfill@^1.1.0: +ember-modifier-manager-polyfill@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/ember-modifier-manager-polyfill/-/ember-modifier-manager-polyfill-1.2.0.tgz#cf4444e11a42ac84f5c8badd85e635df57565dda" integrity sha512-bnaKF1LLKMkBNeDoetvIJ4vhwRPKIIumWr6dbVuW6W6p4QV8ZiO+GdF8J7mxDNlog9CeL9Z/7wam4YS86G8BYA== @@ -8014,6 +8006,17 @@ ember-modifier-manager-polyfill@^1.1.0: ember-cli-version-checker "^2.1.2" ember-compatibility-helpers "^1.2.0" +ember-modifier@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/ember-modifier/-/ember-modifier-1.0.3.tgz#ab18250666aad17c0d9170feb178e954148eb4ed" + integrity sha512-vWuFyvdkULUyasvEXxe5lcfuPZV/Uqe+b0IQ1yU+TY1RSJnFdVUu/CVHT8Bu4HUJInqzAihwPMTwty7fypzi5Q== + dependencies: + ember-cli-babel "^7.11.1" + ember-cli-is-package-missing "^1.0.0" + ember-cli-normalize-entity-name "^1.0.0" + ember-cli-string-utils "^1.1.0" + ember-modifier-manager-polyfill "^1.2.0" + ember-page-title@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/ember-page-title/-/ember-page-title-5.2.1.tgz#12261e010bec96af6200cd132fe4068e717ccbec" From cfceb3e580104a86157d74d9f48295dd37d2b7c3 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Wed, 20 May 2020 17:47:27 -0400 Subject: [PATCH 3/5] -Update dropdown to use modifiers -Cleanup colors, padding, and margin for header styles -Introduce media query width variables --- .../addon/components/rose/header.stories.mdx | 5 +- .../addon/components/rose/header/dropdown.js | 28 ++------- .../rose/addon/modifiers/on-click-outside.js | 15 +++++ .../addon/styles/rose/components/_header.scss | 63 +++++++++---------- .../addon/styles/rose/variables/_index.scss | 1 + .../addon/styles/rose/variables/_media.scss | 21 +++++++ .../components/rose/header/dropdown.hbs | 16 ++--- .../rose/header/dropdown/content.hbs | 2 +- .../rose/header/dropdown/trigger.hbs | 2 +- .../components/rose/header/navigation.hbs | 2 +- .../components/rose/header/utilities.hbs | 2 +- addons/rose/app/modifiers/on-click-outside.js | 1 + .../rose/tests/dummy/app/templates/index.hbs | 2 +- .../components/rose/header/dropdown-test.js | 23 ------- .../rose/header/dropdown/content-test.js | 13 +--- .../rose/header/dropdown/trigger-test.js | 5 -- .../modifiers/on-click-outside-test.js | 34 ++++++++++ 17 files changed, 122 insertions(+), 113 deletions(-) create mode 100644 addons/rose/addon/modifiers/on-click-outside.js create mode 100644 addons/rose/addon/styles/rose/variables/_media.scss create mode 100644 addons/rose/app/modifiers/on-click-outside.js create mode 100644 addons/rose/tests/integration/modifiers/on-click-outside-test.js diff --git a/addons/rose/addon/components/rose/header.stories.mdx b/addons/rose/addon/components/rose/header.stories.mdx index aa5126a23..05d376e64 100644 --- a/addons/rose/addon/components/rose/header.stories.mdx +++ b/addons/rose/addon/components/rose/header.stories.mdx @@ -42,7 +42,7 @@ A header component that allows three distinct sections to be configured: brand, - + {{navigation-dropdown-label}} {{navigation-dropdown-link-label}} @@ -52,7 +52,7 @@ A header component that allows three distinct sections to be configured: brand, {{navigation-link-label}} - + link @@ -67,7 +67,6 @@ A header component that allows three distinct sections to be configured: brand, 'navigation-dropdown-link-label': text('navigation-dropdown-link-label', 'Menu Item'), 'navigation-dropdown-button-label': text('navigation-dropdown-button-label', 'Menu Item'), 'navigation-link-label': text('navigation-link-label', 'Section'), - 'open-dropdown': boolean('open-dropdown', false), }, }} diff --git a/addons/rose/addon/components/rose/header/dropdown.js b/addons/rose/addon/components/rose/header/dropdown.js index 2808ab8a7..bfc8ec9e1 100644 --- a/addons/rose/addon/components/rose/header/dropdown.js +++ b/addons/rose/addon/components/rose/header/dropdown.js @@ -1,34 +1,16 @@ import Component from '@ember/component'; import layout from '../../../templates/components/rose/header/dropdown'; -import { tracked } from '@glimmer/tracking'; import { action } from '@ember/object'; export default Component.extend({ layout, tagName: '', - @tracked isOpen: false, - + // Uses details widget state to close dropdown @action - toggle(event) { - this.isOpen = event.target.open; + close(element) { + if(element.open) { + element.open = false; + } }, - - @action - addClickOutside(element) { - document.addEventListener('click', event => this.clickOutside(event, element), true); - }, - - @action - removeClickOutside(element) { - document.removeEventListener('click', event => this.clickOutside(event, element), true); - }, - - @action - clickOutside(event, element) { - // Only close dropdown when non-nested elements are clicked - if(element.contains(event.target)) { return; } - this.removeClickOutside(element); - this.isOpen = false; - } }); diff --git a/addons/rose/addon/modifiers/on-click-outside.js b/addons/rose/addon/modifiers/on-click-outside.js new file mode 100644 index 000000000..8feb0335e --- /dev/null +++ b/addons/rose/addon/modifiers/on-click-outside.js @@ -0,0 +1,15 @@ +import { modifier } from 'ember-modifier'; + +export default modifier((element, [callback]) => { + function handleClick(event) { + if (!element.contains(event.target)) { + callback(element, event); + } + } + + document.addEventListener('click', handleClick, false); + + return () => { + document.removeEventListener('click', handleClick, false); + }; +}); diff --git a/addons/rose/addon/styles/rose/components/_header.scss b/addons/rose/addon/styles/rose/components/_header.scss index dbd1740e3..a6970359f 100644 --- a/addons/rose/addon/styles/rose/components/_header.scss +++ b/addons/rose/addon/styles/rose/components/_header.scss @@ -1,4 +1,5 @@ @use '../variables/sizing'; +@use '../variables/media'; @use '../utilities/type'; $brand-hashicorp: "data:image/svg+xml;utf-8,"; @@ -14,38 +15,38 @@ $dropdown-chevron: ( grid-template-areas: 'brand navigation utilities'; grid-template-columns: 0.01fr auto 1fr; grid-gap: sizing.rems(xxxs); - background: var(--stark); - color: var(--subtle); - padding: sizing.rems(xxs) 0; + background: var(--black); + color: var(--white); .rose-header-brand { grid-area: brand; - margin: sizing.rems(xs) 0 sizing.rems(xs) sizing.rems(m); - padding: 0 sizing.rems(m); - height: sizing.rems(l) + sizing.rems(xxs); + width: sizing.rems(l); + height: sizing.rems(l); background-image: url($brand-hashicorp); background-repeat: no-repeat; + margin: sizing.rems(xxs); } .rose-header-navigation { grid-area: navigation; - .wrapper { + .rose-header-navigation-flex { display: flex; flex-wrap: wrap; } .rose-header-navigation-link { - padding: sizing.rems(xs) sizing.rems(s) sizing.rems(xxxs) sizing.rems(s); text-decoration: none; display: block; - color: var(--subtle); - height: sizing.rems(l); + color: var(--white); border: 1px solid var(--stark); border-radius: sizing.rems(xxs); text-align: center; - margin-top: sizing.rems(xxs); + padding: sizing.rems(xxs) sizing.rems(s); + position: relative; + top: sizing.rems(xxxs); cursor: pointer; + margin: 0 sizing.rems(xs); &:hover { background: var(--ui-gray-starker-3); @@ -60,7 +61,7 @@ $dropdown-chevron: ( .rose-header-utilities { grid-area: utilities; - .wrapper { + .rose-header-utilities-flex { margin-right: sizing.rems(s); display: flex; flex-wrap: wrap; @@ -70,25 +71,24 @@ $dropdown-chevron: ( .rose-header-navigation, .rose-header-utilities { .rose-header-dropdown { - height: sizing.rems(m) + sizing.rems(xxxs); - - .rose-header-dropdown-trigger { - height: sizing.rems(m) + sizing.rems(xxxs); - padding: sizing.rems(xs) sizing.rems(xxs); - border-radius: sizing.rems(xxxs); - color: var(--subtle); - margin: sizing.rems(xxs) sizing.rems(xxs) 0 0; - cursor: pointer; - - &.rose-header-dropdown-open { - background: var(--subtle); + &[open] { + .rose-header-dropdown-trigger { + background: var(--white); color: var(--ui-gray-starker-4); .rose-header-dropdown-chevron { background-image: url(map-get($dropdown-chevron, 'open')); } } + } + .rose-header-dropdown-trigger { + padding: sizing.rems(xxs) sizing.rems(s); + border-radius: sizing.rems(xxxs); + color: var(--white); + position: relative; + top: sizing.rems(xxxs); + cursor: pointer; &::-webkit-details-marker { display: none; } @@ -110,29 +110,29 @@ $dropdown-chevron: ( .rose-header-dropdown-content { position: absolute; - background-color: var(--subtle); + background-color: var(--white); border-radius: sizing.rems(xxxs); border: 1px solid var(--ui-gray-subtler-2); + padding-right: sizing.rems(xl); + margin-top: sizing.rems(xxxs); &.rose-header-dropdown-content-right { - right: sizing.rems(m); + right: sizing.rems(s); } .rose-header-dropdown-content-link{ - padding: sizing.rems(s) (sizing.rems(xl) * 3) sizing.rems(xxs) sizing.rems(s); + padding: sizing.rems(xs) sizing.rems(s); text-decoration: none; display: block; color: var(--ui-gray-starker-4); height: sizing.rems(l); } - .rose-header-dropdown-content-button { button { cursor: pointer; - padding: sizing.rems(s) (sizing.rems(xl) * 3) sizing.rems(xs) sizing.rems(s); + padding: sizing.rems(xs) sizing.rems(s); color: var(--ui-gray-starker-4); - box-shadow: none; display: inline-block; border: none; text-decoration: none; @@ -146,8 +146,7 @@ $dropdown-chevron: ( } } -//TODO: Where do media query sizes live? -@media (max-width: 768px) { +@media (max-width: media.width(small)) { .rose-header { grid-template-columns: 1fr 3fr; grid-template-areas: diff --git a/addons/rose/addon/styles/rose/variables/_index.scss b/addons/rose/addon/styles/rose/variables/_index.scss index 0f1c38707..c789019f7 100644 --- a/addons/rose/addon/styles/rose/variables/_index.scss +++ b/addons/rose/addon/styles/rose/variables/_index.scss @@ -2,3 +2,4 @@ @import 'typography'; @import 'color'; @import 'opacity'; +@import 'media'; diff --git a/addons/rose/addon/styles/rose/variables/_media.scss b/addons/rose/addon/styles/rose/variables/_media.scss new file mode 100644 index 000000000..d0f695bbf --- /dev/null +++ b/addons/rose/addon/styles/rose/variables/_media.scss @@ -0,0 +1,21 @@ +@use 'sass:map'; + +/** + * SASS variables various media query sizes + */ + +$width-breakpoints: ( + xxlarge: 1440px, + xlarge: 1200px, + large: 1024px, + medium: 768px, + small: 480px, + xsmall: 320px +); + +/** + * Returns a media width variable. + */ +@function width($name) { + @return map.get($width-breakpoints, $name); +} diff --git a/addons/rose/addon/templates/components/rose/header/dropdown.hbs b/addons/rose/addon/templates/components/rose/header/dropdown.hbs index d8b289a44..3f4810eea 100644 --- a/addons/rose/addon/templates/components/rose/header/dropdown.hbs +++ b/addons/rose/addon/templates/components/rose/header/dropdown.hbs @@ -1,14 +1,8 @@ -
+
+ {{yield (hash - isOpen=this.isOpen - trigger=(component 'rose/header/dropdown/trigger' - isOpen=this.isOpen) - content=(component 'rose/header/dropdown/content' isOpen=this.isOpen - position=@position) + trigger=(component 'rose/header/dropdown/trigger') + content=(component 'rose/header/dropdown/content' alignRight=@alignRight) )}}
diff --git a/addons/rose/addon/templates/components/rose/header/dropdown/content.hbs b/addons/rose/addon/templates/components/rose/header/dropdown/content.hbs index 48c30b03c..68af8036a 100644 --- a/addons/rose/addon/templates/components/rose/header/dropdown/content.hbs +++ b/addons/rose/addon/templates/components/rose/header/dropdown/content.hbs @@ -1,4 +1,4 @@ - + {{yield (hash link=(component 'link-to' class="rose-header-dropdown-content-link") button=(component 'rose/header/dropdown/content/button') diff --git a/addons/rose/addon/templates/components/rose/header/dropdown/trigger.hbs b/addons/rose/addon/templates/components/rose/header/dropdown/trigger.hbs index 960ad35f5..f513aa8bd 100644 --- a/addons/rose/addon/templates/components/rose/header/dropdown/trigger.hbs +++ b/addons/rose/addon/templates/components/rose/header/dropdown/trigger.hbs @@ -1,4 +1,4 @@ - + {{yield}} diff --git a/addons/rose/addon/templates/components/rose/header/navigation.hbs b/addons/rose/addon/templates/components/rose/header/navigation.hbs index 8ce8c7a72..9e2b4308b 100644 --- a/addons/rose/addon/templates/components/rose/header/navigation.hbs +++ b/addons/rose/addon/templates/components/rose/header/navigation.hbs @@ -1,5 +1,5 @@ - + {{yield (hash link=(component 'link-to' class="rose-header-navigation-link") dropdown=(component 'rose/header/dropdown') diff --git a/addons/rose/addon/templates/components/rose/header/utilities.hbs b/addons/rose/addon/templates/components/rose/header/utilities.hbs index c5b060286..eefb15e8d 100644 --- a/addons/rose/addon/templates/components/rose/header/utilities.hbs +++ b/addons/rose/addon/templates/components/rose/header/utilities.hbs @@ -1,5 +1,5 @@ - + {{yield (hash dropdown=(component 'rose/header/dropdown' position="true") )}} diff --git a/addons/rose/app/modifiers/on-click-outside.js b/addons/rose/app/modifiers/on-click-outside.js new file mode 100644 index 000000000..845e122c1 --- /dev/null +++ b/addons/rose/app/modifiers/on-click-outside.js @@ -0,0 +1 @@ +export { default } from 'rose/modifiers/on-click-outside'; diff --git a/addons/rose/tests/dummy/app/templates/index.hbs b/addons/rose/tests/dummy/app/templates/index.hbs index 236fd0598..d7aa67b35 100644 --- a/addons/rose/tests/dummy/app/templates/index.hbs +++ b/addons/rose/tests/dummy/app/templates/index.hbs @@ -13,7 +13,7 @@ - + Click me link diff --git a/addons/rose/tests/integration/components/rose/header/dropdown-test.js b/addons/rose/tests/integration/components/rose/header/dropdown-test.js index ea6f0cb29..690e5103d 100644 --- a/addons/rose/tests/integration/components/rose/header/dropdown-test.js +++ b/addons/rose/tests/integration/components/rose/header/dropdown-test.js @@ -40,22 +40,6 @@ module('Integration | Component | rose/header/dropdown', function(hooks) { assert.equal(findAll('button').length, 3); }); - test('it is opened when @isOpen={{true}}', async function(assert) { - this.set('isOpen', false); - await render(hbs` - Click me - - - - `); - assert.notOk(find('.rose-header-dropdown-trigger.rose-header-dropdown-open')); - assert.notOk(find('.rose-header-dropdown-content.rose-header-dropdown-open')); - - this.set('isOpen', true); - assert.ok(find('.rose-header-dropdown-trigger.rose-header-dropdown-open')); - assert.ok(find('.rose-header-dropdown-content.rose-header-dropdown-open')); - }); - test('it is toggled on click on trigger content', async function(assert) { await render(hbs` Click me @@ -64,19 +48,12 @@ module('Integration | Component | rose/header/dropdown', function(hooks) { `); assert.notOk(find('#dropdown').open); - assert.notOk(find('.rose-header-dropdown-trigger.rose-header-dropdown-open')); - assert.notOk(find('.rose-header-dropdown-content.rose-header-dropdown-open')); await click('#trigger'); - assert.ok(find('#dropdown').open); - assert.ok(find('.rose-header-dropdown-trigger.rose-header-dropdown-open')); - assert.ok(find('.rose-header-dropdown-content.rose-header-dropdown-open')); await click('#trigger'); assert.notOk(find('#dropdown').open); - assert.notOk(find('.rose-header-dropdown-trigger.rose-header-dropdown-open')); - assert.notOk(find('.rose-header-dropdown-content.rose-header-dropdown-open')); }); test('it is closed with outside click is triggered', async function(assert) { diff --git a/addons/rose/tests/integration/components/rose/header/dropdown/content-test.js b/addons/rose/tests/integration/components/rose/header/dropdown/content-test.js index 7ea669671..26fd3c413 100644 --- a/addons/rose/tests/integration/components/rose/header/dropdown/content-test.js +++ b/addons/rose/tests/integration/components/rose/header/dropdown/content-test.js @@ -24,20 +24,11 @@ module('Integration | Component | rose/header/dropdown/content', function(hooks) assert.ok(find('.rose-header-dropdown-content').className.match('universe')); }); - test('it is open when @isOpen={{true}}', async function(assert) { - this.set('isOpen', false); - await render(hbs``); - assert.notOk(find('.rose-header-dropdown-open')); - - this.set('isOpen', true); - assert.ok(find('.rose-header-dropdown-open')); - }); - - test('it is positioned right when @position={{true}}', async function(assert) { + test('it is positioned right when @alignRight={{true}}', async function(assert) { await render(hbs``); assert.notOk(find('.rose-header-dropdown-content-right')); - await render(hbs``); + await render(hbs``); assert.ok(find('.rose-header-dropdown-content-right')); }); diff --git a/addons/rose/tests/integration/components/rose/header/dropdown/trigger-test.js b/addons/rose/tests/integration/components/rose/header/dropdown/trigger-test.js index e2180c867..aca4e98b3 100644 --- a/addons/rose/tests/integration/components/rose/header/dropdown/trigger-test.js +++ b/addons/rose/tests/integration/components/rose/header/dropdown/trigger-test.js @@ -25,11 +25,6 @@ module('Integration | Component | rose/header/dropdown/trigger', function(hooks) assert.ok(find('.rose-header-dropdown-trigger').className.match('dropdown-trigger')); }); - test('it is open when @isOpen={{true}}', async function(assert) { - await render(hbs``); - assert.ok(find('.rose-header-dropdown-open')); - }); - test('it renders chevron', async function(assert) { await render(hbs``); assert.ok(find('.rose-header-dropdown-chevron')); diff --git a/addons/rose/tests/integration/modifiers/on-click-outside-test.js b/addons/rose/tests/integration/modifiers/on-click-outside-test.js new file mode 100644 index 000000000..859de9902 --- /dev/null +++ b/addons/rose/tests/integration/modifiers/on-click-outside-test.js @@ -0,0 +1,34 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, click } from '@ember/test-helpers'; +import hbs from 'htmlbars-inline-precompile'; + +module('Integration | Modifier | on-click-outside', function(hooks) { + setupRenderingTest(hooks); + + test('it fires event when an outside element is clicked', async function(assert) { + this.set('clickedOutside', (element, event) => { + assert.ok(element); + assert.equal(event.target.id, 'outside'); + }); + + await render(hbs`
+
`); + + await click('#outside'); + }); + + test('it does not fire event when element is clicked', async function(assert) { + assert.expect(1); + this.set('clickedOutside', () => { assert.ok(true)}); + + await render(hbs`
+
+
+
`); + + await click('#inside'); + await click('#item'); + await click('#outside'); + }); +}); From 045416954bbe4027246aa42930e6e0333713fb89 Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Wed, 20 May 2020 18:06:56 -0400 Subject: [PATCH 4/5] Format JS and scss files --- .../addon/components/rose/header/dropdown.js | 2 +- .../addon/styles/rose/components/_header.scss | 13 +++--- .../addon/styles/rose/variables/_media.scss | 2 +- .../rose/app/components/rose/header/brand.js | 2 +- .../app/components/rose/header/dropdown.js | 2 +- .../rose/header/dropdown/content.js | 2 +- .../rose/header/dropdown/content/button.js | 2 +- .../rose/header/dropdown/trigger.js | 2 +- .../app/components/rose/header/utilities.js | 2 +- .../components/rose/header/brand-test.js | 2 +- .../components/rose/header/dropdown-test.js | 23 ++++++----- .../rose/header/dropdown/content-test.js | 37 +++++++++++------ .../header/dropdown/content/button-test.js | 40 +++++++++++-------- .../rose/header/dropdown/trigger-test.js | 25 ++++++++---- .../components/rose/header/utilities-test.js | 2 +- .../modifiers/on-click-outside-test.js | 10 +++-- 16 files changed, 103 insertions(+), 65 deletions(-) diff --git a/addons/rose/addon/components/rose/header/dropdown.js b/addons/rose/addon/components/rose/header/dropdown.js index bfc8ec9e1..4a5897084 100644 --- a/addons/rose/addon/components/rose/header/dropdown.js +++ b/addons/rose/addon/components/rose/header/dropdown.js @@ -9,7 +9,7 @@ export default Component.extend({ // Uses details widget state to close dropdown @action close(element) { - if(element.open) { + if (element.open) { element.open = false; } }, diff --git a/addons/rose/addon/styles/rose/components/_header.scss b/addons/rose/addon/styles/rose/components/_header.scss index a6970359f..184cd52f2 100644 --- a/addons/rose/addon/styles/rose/components/_header.scss +++ b/addons/rose/addon/styles/rose/components/_header.scss @@ -5,8 +5,10 @@ $brand-hashicorp: "data:image/svg+xml;utf-8,"; $dropdown-chevron: ( - 'default': "data:image/svg+xml;utf-8,", - 'open': "data:image/svg+xml;utf-8,", + 'default': + "data:image/svg+xml;utf-8,", + 'open': + "data:image/svg+xml;utf-8,", ); .rose-header { @@ -69,7 +71,8 @@ $dropdown-chevron: ( } } - .rose-header-navigation, .rose-header-utilities { + .rose-header-navigation, + .rose-header-utilities { .rose-header-dropdown { &[open] { .rose-header-dropdown-trigger { @@ -104,7 +107,7 @@ $dropdown-chevron: ( .rose-icon { position: relative; - top: - sizing.rems(xxs); + top: -sizing.rems(xxs); } } @@ -120,7 +123,7 @@ $dropdown-chevron: ( right: sizing.rems(s); } - .rose-header-dropdown-content-link{ + .rose-header-dropdown-content-link { padding: sizing.rems(xs) sizing.rems(s); text-decoration: none; display: block; diff --git a/addons/rose/addon/styles/rose/variables/_media.scss b/addons/rose/addon/styles/rose/variables/_media.scss index d0f695bbf..289c96ad9 100644 --- a/addons/rose/addon/styles/rose/variables/_media.scss +++ b/addons/rose/addon/styles/rose/variables/_media.scss @@ -10,7 +10,7 @@ $width-breakpoints: ( large: 1024px, medium: 768px, small: 480px, - xsmall: 320px + xsmall: 320px, ); /** diff --git a/addons/rose/app/components/rose/header/brand.js b/addons/rose/app/components/rose/header/brand.js index b21f5e748..edd708f53 100644 --- a/addons/rose/app/components/rose/header/brand.js +++ b/addons/rose/app/components/rose/header/brand.js @@ -1 +1 @@ -export { default } from 'rose/components/rose/header/brand'; \ No newline at end of file +export { default } from 'rose/components/rose/header/brand'; diff --git a/addons/rose/app/components/rose/header/dropdown.js b/addons/rose/app/components/rose/header/dropdown.js index 689d4487e..16d89ac10 100644 --- a/addons/rose/app/components/rose/header/dropdown.js +++ b/addons/rose/app/components/rose/header/dropdown.js @@ -1 +1 @@ -export { default } from 'rose/components/rose/header/dropdown'; \ No newline at end of file +export { default } from 'rose/components/rose/header/dropdown'; diff --git a/addons/rose/app/components/rose/header/dropdown/content.js b/addons/rose/app/components/rose/header/dropdown/content.js index 0ef8131da..51792f92e 100644 --- a/addons/rose/app/components/rose/header/dropdown/content.js +++ b/addons/rose/app/components/rose/header/dropdown/content.js @@ -1 +1 @@ -export { default } from 'rose/components/rose/header/dropdown/content'; \ No newline at end of file +export { default } from 'rose/components/rose/header/dropdown/content'; diff --git a/addons/rose/app/components/rose/header/dropdown/content/button.js b/addons/rose/app/components/rose/header/dropdown/content/button.js index 7576f9dae..cc70f39b5 100644 --- a/addons/rose/app/components/rose/header/dropdown/content/button.js +++ b/addons/rose/app/components/rose/header/dropdown/content/button.js @@ -1 +1 @@ -export { default } from 'rose/components/rose/header/dropdown/content/button'; \ No newline at end of file +export { default } from 'rose/components/rose/header/dropdown/content/button'; diff --git a/addons/rose/app/components/rose/header/dropdown/trigger.js b/addons/rose/app/components/rose/header/dropdown/trigger.js index ea84a3b44..0bb1491ed 100644 --- a/addons/rose/app/components/rose/header/dropdown/trigger.js +++ b/addons/rose/app/components/rose/header/dropdown/trigger.js @@ -1 +1 @@ -export { default } from 'rose/components/rose/header/dropdown/trigger'; \ No newline at end of file +export { default } from 'rose/components/rose/header/dropdown/trigger'; diff --git a/addons/rose/app/components/rose/header/utilities.js b/addons/rose/app/components/rose/header/utilities.js index bb5f37bc3..6c4acf7b5 100644 --- a/addons/rose/app/components/rose/header/utilities.js +++ b/addons/rose/app/components/rose/header/utilities.js @@ -1 +1 @@ -export { default } from 'rose/components/rose/header/utilities'; \ No newline at end of file +export { default } from 'rose/components/rose/header/utilities'; diff --git a/addons/rose/tests/integration/components/rose/header/brand-test.js b/addons/rose/tests/integration/components/rose/header/brand-test.js index 5529aa5a3..e3df6dc9e 100644 --- a/addons/rose/tests/integration/components/rose/header/brand-test.js +++ b/addons/rose/tests/integration/components/rose/header/brand-test.js @@ -3,7 +3,7 @@ import { setupRenderingTest } from 'ember-qunit'; import { render, find } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -module('Integration | Component | rose/header/brand', function(hooks) { +module('Integration | Component | rose/header/brand', function (hooks) { setupRenderingTest(hooks); test('it renders', async function (assert) { diff --git a/addons/rose/tests/integration/components/rose/header/dropdown-test.js b/addons/rose/tests/integration/components/rose/header/dropdown-test.js index 690e5103d..439c29800 100644 --- a/addons/rose/tests/integration/components/rose/header/dropdown-test.js +++ b/addons/rose/tests/integration/components/rose/header/dropdown-test.js @@ -3,29 +3,34 @@ import { setupRenderingTest } from 'ember-qunit'; import { render, click, find, findAll } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -module('Integration | Component | rose/header/dropdown', function(hooks) { +module('Integration | Component | rose/header/dropdown', function (hooks) { setupRenderingTest(hooks); - test('it renders', async function(assert) { + test('it renders', async function (assert) { await render(hbs``); assert.ok(find('.rose-header-dropdown')); }); - test('it renders with html attributes', async function(assert) { - await render(hbs``); + test('it renders with html attributes', async function (assert) { + await render( + hbs`` + ); assert.ok(find('#custom-id')); assert.ok(find('.custom-class')); }); - test('it renders with trigger', async function(assert) { + test('it renders with trigger', async function (assert) { await render(hbs` Click me `); assert.ok(find('.rose-header-dropdown-trigger')); - assert.equal(find('.rose-header-dropdown-trigger').textContent.trim(), 'Click me'); + assert.equal( + find('.rose-header-dropdown-trigger').textContent.trim(), + 'Click me' + ); }); - test('it renders with content', async function(assert) { + test('it renders with content', async function (assert) { await render(hbs` @@ -40,7 +45,7 @@ module('Integration | Component | rose/header/dropdown', function(hooks) { assert.equal(findAll('button').length, 3); }); - test('it is toggled on click on trigger content', async function(assert) { + test('it is toggled on click on trigger content', async function (assert) { await render(hbs` Click me @@ -56,7 +61,7 @@ module('Integration | Component | rose/header/dropdown', function(hooks) { assert.notOk(find('#dropdown').open); }); - test('it is closed with outside click is triggered', async function(assert) { + test('it is closed with outside click is triggered', async function (assert) { await render(hbs`
Click me diff --git a/addons/rose/tests/integration/components/rose/header/dropdown/content-test.js b/addons/rose/tests/integration/components/rose/header/dropdown/content-test.js index 26fd3c413..b0bb4a371 100644 --- a/addons/rose/tests/integration/components/rose/header/dropdown/content-test.js +++ b/addons/rose/tests/integration/components/rose/header/dropdown/content-test.js @@ -3,36 +3,47 @@ import { setupRenderingTest } from 'ember-qunit'; import { render, find } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -module('Integration | Component | rose/header/dropdown/content', function(hooks) { +module('Integration | Component | rose/header/dropdown/content', function ( + hooks +) { setupRenderingTest(hooks); - test('it renders', async function(assert) { + test('it renders', async function (assert) { await render(hbs``); assert.ok(find('.rose-header-dropdown-content')); }); - test('it renders with content', async function(assert) { + test('it renders with content', async function (assert) { await render(hbs` content `); - assert.equal(find('.rose-header-dropdown-content').textContent.trim(), 'content'); + assert.equal( + find('.rose-header-dropdown-content').textContent.trim(), + 'content' + ); }); - test('it renders with html attributes', async function(assert) { - await render(hbs``); + test('it renders with html attributes', async function (assert) { + await render( + hbs`` + ); assert.equal(find('.rose-header-dropdown-content').id, 'dropdown-content'); - assert.ok(find('.rose-header-dropdown-content').className.match('universe')); + assert.ok( + find('.rose-header-dropdown-content').className.match('universe') + ); }); - test('it is positioned right when @alignRight={{true}}', async function(assert) { + test('it is positioned right when @alignRight={{true}}', async function (assert) { await render(hbs``); assert.notOk(find('.rose-header-dropdown-content-right')); - await render(hbs``); + await render( + hbs`` + ); assert.ok(find('.rose-header-dropdown-content-right')); }); - test('it render link element', async function(assert) { + test('it render link element', async function (assert) { await render(hbs` `); @@ -40,14 +51,14 @@ module('Integration | Component | rose/header/dropdown/content', function(hooks) assert.ok(find('.rose-header-dropdown-content-link')); }); - test('it render link element with content', async function(assert) { + test('it render link element with content', async function (assert) { await render(hbs` linkify `); assert.equal(find('a').textContent.trim(), 'linkify'); }); - test('it render button element', async function(assert) { + test('it render button element', async function (assert) { await render(hbs` `); @@ -55,7 +66,7 @@ module('Integration | Component | rose/header/dropdown/content', function(hooks) assert.ok(find('.rose-header-dropdown-content-button')); }); - test('it render button element with content', async function(assert) { + test('it render button element with content', async function (assert) { await render(hbs` dropdown button `); diff --git a/addons/rose/tests/integration/components/rose/header/dropdown/content/button-test.js b/addons/rose/tests/integration/components/rose/header/dropdown/content/button-test.js index 8ea5783c8..a73dc28df 100644 --- a/addons/rose/tests/integration/components/rose/header/dropdown/content/button-test.js +++ b/addons/rose/tests/integration/components/rose/header/dropdown/content/button-test.js @@ -3,22 +3,30 @@ import { setupRenderingTest } from 'ember-qunit'; import { render, find } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -module('Integration | Component | rose/header/dropdown/content/button', function(hooks) { - setupRenderingTest(hooks); +module( + 'Integration | Component | rose/header/dropdown/content/button', + function (hooks) { + setupRenderingTest(hooks); - test('it renders', async function(assert) { - await render(hbs``); - assert.ok(find('.rose-header-dropdown-content-button')); - }); + test('it renders', async function (assert) { + await render(hbs``); + assert.ok(find('.rose-header-dropdown-content-button')); + }); - test('it renders with content', async function(assert) { - await render(hbs`Button content`); - assert.equal(find('.rose-header-dropdown-content-button').textContent.trim(), 'Button content'); - }); + test('it renders with content', async function (assert) { + await render( + hbs`Button content` + ); + assert.equal( + find('.rose-header-dropdown-content-button').textContent.trim(), + 'Button content' + ); + }); - test('it render button element', async function(assert) { - await render(hbs``); - assert.ok(find('button')); - assert.equal(find('button').type, 'button'); - }); -}); + test('it render button element', async function (assert) { + await render(hbs``); + assert.ok(find('button')); + assert.equal(find('button').type, 'button'); + }); + } +); diff --git a/addons/rose/tests/integration/components/rose/header/dropdown/trigger-test.js b/addons/rose/tests/integration/components/rose/header/dropdown/trigger-test.js index aca4e98b3..83309f23e 100644 --- a/addons/rose/tests/integration/components/rose/header/dropdown/trigger-test.js +++ b/addons/rose/tests/integration/components/rose/header/dropdown/trigger-test.js @@ -3,29 +3,38 @@ import { setupRenderingTest } from 'ember-qunit'; import { render, find } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -module('Integration | Component | rose/header/dropdown/trigger', function(hooks) { +module('Integration | Component | rose/header/dropdown/trigger', function ( + hooks +) { setupRenderingTest(hooks); - test('it renders', async function(assert) { + test('it renders', async function (assert) { await render(hbs``); assert.ok(find('.rose-header-dropdown-trigger')); assert.notOk(find('.rose-header-dropdown-open')); }); - test('it renders with content', async function(assert) { + test('it renders with content', async function (assert) { await render(hbs` trigger content `); - assert.equal(find('.rose-header-dropdown-trigger').textContent.trim(), 'trigger content'); + assert.equal( + find('.rose-header-dropdown-trigger').textContent.trim(), + 'trigger content' + ); }); - test('it renders with html attributes', async function(assert) { - await render(hbs``); + test('it renders with html attributes', async function (assert) { + await render( + hbs`` + ); assert.equal(find('.rose-header-dropdown-trigger').id, 'trigger'); - assert.ok(find('.rose-header-dropdown-trigger').className.match('dropdown-trigger')); + assert.ok( + find('.rose-header-dropdown-trigger').className.match('dropdown-trigger') + ); }); - test('it renders chevron', async function(assert) { + test('it renders chevron', async function (assert) { await render(hbs``); assert.ok(find('.rose-header-dropdown-chevron')); }); diff --git a/addons/rose/tests/integration/components/rose/header/utilities-test.js b/addons/rose/tests/integration/components/rose/header/utilities-test.js index 56f263714..b0dca161d 100644 --- a/addons/rose/tests/integration/components/rose/header/utilities-test.js +++ b/addons/rose/tests/integration/components/rose/header/utilities-test.js @@ -3,7 +3,7 @@ import { setupRenderingTest } from 'ember-qunit'; import { render, find, findAll } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -module('Integration | Component | rose/header/utilities', function(hooks) { +module('Integration | Component | rose/header/utilities', function (hooks) { setupRenderingTest(hooks); test('it renders', async function (assert) { diff --git a/addons/rose/tests/integration/modifiers/on-click-outside-test.js b/addons/rose/tests/integration/modifiers/on-click-outside-test.js index 859de9902..7318ef423 100644 --- a/addons/rose/tests/integration/modifiers/on-click-outside-test.js +++ b/addons/rose/tests/integration/modifiers/on-click-outside-test.js @@ -3,10 +3,10 @@ import { setupRenderingTest } from 'ember-qunit'; import { render, click } from '@ember/test-helpers'; import hbs from 'htmlbars-inline-precompile'; -module('Integration | Modifier | on-click-outside', function(hooks) { +module('Integration | Modifier | on-click-outside', function (hooks) { setupRenderingTest(hooks); - test('it fires event when an outside element is clicked', async function(assert) { + test('it fires event when an outside element is clicked', async function (assert) { this.set('clickedOutside', (element, event) => { assert.ok(element); assert.equal(event.target.id, 'outside'); @@ -18,9 +18,11 @@ module('Integration | Modifier | on-click-outside', function(hooks) { await click('#outside'); }); - test('it does not fire event when element is clicked', async function(assert) { + test('it does not fire event when element is clicked', async function (assert) { assert.expect(1); - this.set('clickedOutside', () => { assert.ok(true)}); + this.set('clickedOutside', () => { + assert.ok(true); + }); await render(hbs`
From a5d8032b02197ada1038a284e493d3d402293b7c Mon Sep 17 00:00:00 2001 From: Susmitha Girumala Date: Wed, 20 May 2020 18:21:42 -0400 Subject: [PATCH 5/5] =?UTF-8?q?chore:=20=F0=9F=A4=96=20Remove=20negative?= =?UTF-8?q?=20positioning=20for=20icons=20within=20header?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I might need to use straight svg instead of reusing rose-icon coz header needs control over icon and it's chevron positioning. --- addons/rose/addon/styles/rose/components/_header.scss | 5 ----- addons/rose/tests/dummy/app/templates/index.hbs | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/addons/rose/addon/styles/rose/components/_header.scss b/addons/rose/addon/styles/rose/components/_header.scss index 184cd52f2..fb9787b99 100644 --- a/addons/rose/addon/styles/rose/components/_header.scss +++ b/addons/rose/addon/styles/rose/components/_header.scss @@ -104,11 +104,6 @@ $dropdown-chevron: ( display: inline-block; vertical-align: middle; } - - .rose-icon { - position: relative; - top: -sizing.rems(xxs); - } } .rose-header-dropdown-content { diff --git a/addons/rose/tests/dummy/app/templates/index.hbs b/addons/rose/tests/dummy/app/templates/index.hbs index d7aa67b35..6e3605e07 100644 --- a/addons/rose/tests/dummy/app/templates/index.hbs +++ b/addons/rose/tests/dummy/app/templates/index.hbs @@ -14,7 +14,7 @@ - Click me + link button