diff --git a/addons/rose/addon/components/rose/form/input.js b/addons/rose/addon/components/rose/form/input.js index 0b7915a17..005ed82e2 100644 --- a/addons/rose/addon/components/rose/form/input.js +++ b/addons/rose/addon/components/rose/form/input.js @@ -18,5 +18,5 @@ import layout from '../../../templates/components/rose/form/input'; */ export default Component.extend({ layout, - tagName: '' + tagName: '', }); diff --git a/addons/rose/addon/components/rose/form/textarea.js b/addons/rose/addon/components/rose/form/textarea.js index f8f4a6a71..fd74470f7 100644 --- a/addons/rose/addon/components/rose/form/textarea.js +++ b/addons/rose/addon/components/rose/form/textarea.js @@ -18,5 +18,5 @@ import layout from '../../../templates/components/rose/form/textarea'; */ export default Component.extend({ layout, - tagName: '' + tagName: '', }); diff --git a/addons/rose/addon/components/rose/header.stories.mdx b/addons/rose/addon/components/rose/header.stories.mdx index 05d376e64..bffd410b7 100644 --- a/addons/rose/addon/components/rose/header.stories.mdx +++ b/addons/rose/addon/components/rose/header.stories.mdx @@ -1,36 +1,37 @@ 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'; +import { text, boolean, select } from '@storybook/addon-knobs'; # Header -A header component that allows three distinct sections to be configured: brand, navigation, and utilities. +A header component that allows three distinct sections to be configured: brand, nav, and utilities. ```htmlbars - - + + - - - Org name - - link - button - + + + Menu item + Menu item + Button menu item + Section Section - + - - Click me - - link - button - + + Menu item + Menu item + Button menu item @@ -39,34 +40,43 @@ A header component that allows three distinct sections to be configured: brand, {{ template: hbs` - - - - - {{navigation-dropdown-label}} - - {{navigation-dropdown-link-label}} - {{navigation-dropdown-button-label}} - + + + + + Menu item + Menu item + Button menu item - {{navigation-link-label}} - + Section + Section + - - - - link - button - + + Menu item + Menu item + Button menu item `, 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'), + brandName: text('brandName', 'Brand Name'), + dropdownIcon: select( + 'dropdownIcon', + { + 'user-square-fill': 'user-square-fill', + 'check-circle-outline': 'check-circle-outline', + 'copy-action': 'copy-action', + 'unfold-more': 'unfold-more', + 'unfold-less': 'unfold-less', + }, + 'user-square-fill' + ), }, }} diff --git a/addons/rose/addon/components/rose/header/dropdown/content.js b/addons/rose/addon/components/rose/header/dropdown/content.js deleted file mode 100644 index 4f2bf32a0..000000000 --- a/addons/rose/addon/components/rose/header/dropdown/content.js +++ /dev/null @@ -1,7 +0,0 @@ -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 deleted file mode 100644 index fa19bd4b9..000000000 --- a/addons/rose/addon/components/rose/header/dropdown/content/button.js +++ /dev/null @@ -1,7 +0,0 @@ -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 deleted file mode 100644 index 72ffb581c..000000000 --- a/addons/rose/addon/components/rose/header/dropdown/trigger.js +++ /dev/null @@ -1,7 +0,0 @@ -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/nav.js similarity index 93% rename from addons/rose/addon/components/rose/header/navigation.js rename to addons/rose/addon/components/rose/header/nav.js index 4ef10f9e3..387bd6be8 100644 --- a/addons/rose/addon/components/rose/header/navigation.js +++ b/addons/rose/addon/components/rose/header/nav.js @@ -1,5 +1,5 @@ import Component from '@ember/component'; -import layout from '../../../templates/components/rose/header/navigation'; +import layout from '../../../templates/components/rose/header/nav'; export default Component.extend({ layout, diff --git a/addons/rose/addon/modifiers/on-click-outside.js b/addons/rose/addon/modifiers/on-click-outside.js index 8feb0335e..be434a234 100644 --- a/addons/rose/addon/modifiers/on-click-outside.js +++ b/addons/rose/addon/modifiers/on-click-outside.js @@ -1,5 +1,10 @@ import { modifier } from 'ember-modifier'; +/** + * Used to detect clicks occuring _outside_ of the modified element. + * This is useful especially for dropdowns to toggle content visibility + * when the user clicks away. + */ export default modifier((element, [callback]) => { function handleClick(event) { if (!element.contains(event.target)) { diff --git a/addons/rose/addon/styles/rose/components/_header.scss b/addons/rose/addon/styles/rose/components/_header.scss deleted file mode 100644 index fb9787b99..000000000 --- a/addons/rose/addon/styles/rose/components/_header.scss +++ /dev/null @@ -1,168 +0,0 @@ -@use '../variables/sizing'; -@use '../variables/media'; -@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(--black); - color: var(--white); - - .rose-header-brand { - grid-area: brand; - 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; - - .rose-header-navigation-flex { - display: flex; - flex-wrap: wrap; - } - - .rose-header-navigation-link { - text-decoration: none; - display: block; - color: var(--white); - border: 1px solid var(--stark); - border-radius: sizing.rems(xxs); - text-align: center; - 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); - } - - &:active { - background: var(--ui-gray-starker-2); - } - } - } - - .rose-header-utilities { - grid-area: utilities; - - .rose-header-utilities-flex { - margin-right: sizing.rems(s); - display: flex; - flex-wrap: wrap; - flex-direction: row-reverse; - } - } - - .rose-header-navigation, - .rose-header-utilities { - .rose-header-dropdown { - &[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; - } - - .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-header-dropdown-content { - position: absolute; - 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(s); - } - - .rose-header-dropdown-content-link { - 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(xs) sizing.rems(s); - color: var(--ui-gray-starker-4); - display: inline-block; - border: none; - text-decoration: none; - font-size: inherit; - font-weight: inherit; - -webkit-appearance: none; - } - } - } - } - } -} - -@media (max-width: media.width(small)) { - .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/header/_brand.scss b/addons/rose/addon/styles/rose/components/header/_brand.scss new file mode 100644 index 000000000..671e38ffc --- /dev/null +++ b/addons/rose/addon/styles/rose/components/header/_brand.scss @@ -0,0 +1,31 @@ +@use '../../variables/sizing'; +@use '../../utilities/type'; + +.rose-header-brand { + grid-area: brand; + display: flex; + align-items: center; + color: var(--white); + text-decoration: none; + padding: 0 10px; + margin: 10px; + + svg { + // 28px... header sizes do not follow the sizing system + $logoSize: sizing.rems(l) + sizing.rems(xxs); + display: block; + width: $logoSize; + } + + .rose-header-brand-text { + @include type.type(m, normal); + margin: 0; + white-space: nowrap; + position: absolute; + top: -1000px; + left: -1000px; + opacity: 0; + width: 1px; + height: 1px; + } +} diff --git a/addons/rose/addon/styles/rose/components/header/_dropdown.scss b/addons/rose/addon/styles/rose/components/header/_dropdown.scss new file mode 100644 index 000000000..bf6ab366d --- /dev/null +++ b/addons/rose/addon/styles/rose/components/header/_dropdown.scss @@ -0,0 +1,105 @@ +@use 'sass:map'; +@use '../../variables/sizing'; +@use '../../utilities/type'; + +$dropdown-chevron: ( + 'default': + "data:image/svg+xml;utf-8,", +); + +.rose-header-dropdown { + position: relative; + + .rose-header-dropdown-trigger { + cursor: default; + overflow: hidden; + display: flex; + align-items: center; + color: var(--white); + background: url(map.get($dropdown-chevron, default)) no-repeat right center; + background-size: sizing.rems(m); + margin-right: sizing.rems(s); + padding-right: sizing.rems(l) - sizing.rems(xxs); + $lineHeight: 48 / 16; + line-height: $lineHeight; + + &.icon-only { + padding-right: sizing.rems(m); + + .rose-header-dropdown-trigger-text { + // TODO: factor out into visually-hidden mixin utility + position: absolute; + left: -1000px; + top: -1000px; + width: 1px; + height: 1px; + opacity: 0; + } + } + + // Hide default twistie triangle + // Webkit / Chromium + &::-webkit-details-marker { + display: none; + } + // Firefox + list-style-type: none; + &::marker { + display: none; + } + + .rose-icon { + display: inline-block; + height: var(--size); + + > svg { + vertical-align: top; + } + } + } + + .rose-header-dropdown-content { + $xs: sizing.rems(xs); // 8 + $xxs: sizing.rems(xxs); // 4 + position: absolute; + padding: $xxs 0; + border: 1px solid var(--ui-gray-subtler-2); + border-radius: sizing.rems(xxxs); + background: var(--subtle); + box-shadow: 0 $xxs $xxs rgba(var(--stark-components), var(--opacity-3)), + 0 $xxs $xs rgba(var(--stark-components), var(--opacity-4)); + } + + &.dropdown-right { + .rose-header-dropdown-content { + right: 0; + } + } + + .rose-header-dropdown-link, + .rose-button-header-dropdown { + @include type.type(m, normal); + display: block; + // Targeting min-width of 200 + min-width: (sizing.rems(m) + sizing.rems(xxs)) * 10; + padding: 0 sizing.rems(s); + margin: 0; + border: 0; + color: var(--stark); + background-color: transparent; + // target line height is 36, which is not a standard line height for this + // font size + $lineHeight: 36 / 16; + line-height: $lineHeight; + text-align: left; + text-decoration: none; + + &:hover { + background-color: var(--ui-gray-subtler-4); + } + } + + .rose-button-header-dropdown { + width: 100%; + } +} diff --git a/addons/rose/addon/styles/rose/components/header/_index.scss b/addons/rose/addon/styles/rose/components/header/_index.scss new file mode 100644 index 000000000..6ba8aba30 --- /dev/null +++ b/addons/rose/addon/styles/rose/components/header/_index.scss @@ -0,0 +1,26 @@ +@use '../../variables/sizing'; +@use '../../variables/media'; +@use '../../utilities/type'; + +@import 'brand'; +@import 'nav'; +@import 'utilities'; +@import 'link'; +@import 'dropdown'; + +.rose-header { + display: grid; + grid-template-areas: 'brand nav utilities'; + grid-template-columns: 0.01fr auto 1fr; + background: var(--black) linear-gradient(90deg, #191a1c 0%, #1b212d 100%); +} + +@media (max-width: media.width(small)) { + .rose-header { + grid-template-columns: 1fr 3fr; + grid-template-areas: + 'brand utilities' + 'nav nav'; + padding-bottom: 0; + } +} diff --git a/addons/rose/addon/styles/rose/components/header/_link.scss b/addons/rose/addon/styles/rose/components/header/_link.scss new file mode 100644 index 000000000..e1620d910 --- /dev/null +++ b/addons/rose/addon/styles/rose/components/header/_link.scss @@ -0,0 +1,29 @@ +@use '../../variables/sizing'; +@use '../../utilities/type'; + +.rose-header-nav-link { + @include type.type(s, semibold); + + // target line height is 16, which is not a standard line height + $lineHeight: 16 / 14; + line-height: $lineHeight; + text-decoration: none; + + color: var(--white); + opacity: 0.75; + + // again, nonstandard sizing for header stuff + margin: 10px 0; + padding: 6px 12px; + border-radius: sizing.rems(xxs); + + &.active { + opacity: 1; + background: #{color(ui-gray, 800)}; + } + + &:hover { + opacity: 1; + text-decoration: underline; + } +} diff --git a/addons/rose/addon/styles/rose/components/header/_nav.scss b/addons/rose/addon/styles/rose/components/header/_nav.scss new file mode 100644 index 000000000..6e50ec714 --- /dev/null +++ b/addons/rose/addon/styles/rose/components/header/_nav.scss @@ -0,0 +1,14 @@ +@use '../../variables/sizing'; +@use '../../variables/media'; + +.rose-header-nav { + grid-area: nav; + display: flex; + flex-wrap: wrap; + align-items: center; + + @media (max-width: media.width(small)) { + padding: 0 20px; + background: var(--ui-header-subtler); + } +} diff --git a/addons/rose/addon/styles/rose/components/header/_utilities.scss b/addons/rose/addon/styles/rose/components/header/_utilities.scss new file mode 100644 index 000000000..ad28137ff --- /dev/null +++ b/addons/rose/addon/styles/rose/components/header/_utilities.scss @@ -0,0 +1,9 @@ +@use '../../variables/sizing'; + +.rose-header-utilities { + grid-area: utilities; + display: flex; + flex-wrap: wrap; + flex-direction: row-reverse; + align-items: center; +} diff --git a/addons/rose/addon/templates/components/rose/header.hbs b/addons/rose/addon/templates/components/rose/header.hbs index 343b45d93..2d355f398 100644 --- a/addons/rose/addon/templates/components/rose/header.hbs +++ b/addons/rose/addon/templates/components/rose/header.hbs @@ -1,8 +1,10 @@ -
+
{{yield (hash brand=(component 'rose/header/brand') utilities=(component 'rose/header/utilities') - navigation=(component 'rose/header/navigation') + nav=(component 'rose/header/nav') )}} -
+ diff --git a/addons/rose/addon/templates/components/rose/header/brand.hbs b/addons/rose/addon/templates/components/rose/header/brand.hbs index 836e22b70..cff66cc3b 100644 --- a/addons/rose/addon/templates/components/rose/header/brand.hbs +++ b/addons/rose/addon/templates/components/rose/header/brand.hbs @@ -1 +1,16 @@ - + + + {{#if @logo}} + {{inline-svg @logo}} + {{/if}} + + {{#if @text}} +

{{@text}}

+ {{/if}} + +
diff --git a/addons/rose/addon/templates/components/rose/header/dropdown.hbs b/addons/rose/addon/templates/components/rose/header/dropdown.hbs index 3f4810eea..86406b2d9 100644 --- a/addons/rose/addon/templates/components/rose/header/dropdown.hbs +++ b/addons/rose/addon/templates/components/rose/header/dropdown.hbs @@ -1,8 +1,32 @@ -
+
+ + + + {{#if @icon}} + + {{/if}} + + + {{@text}} + + + + +
+ {{yield (hash + link=(component "link-to" class="rose-header-dropdown-link") + button=(component "rose/button" style="header-dropdown") + )}} +
- {{yield (hash - 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 deleted file mode 100644 index 68af8036a..000000000 --- a/addons/rose/addon/templates/components/rose/header/dropdown/content.hbs +++ /dev/null @@ -1,6 +0,0 @@ - - {{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 deleted file mode 100644 index e437e4689..000000000 --- a/addons/rose/addon/templates/components/rose/header/dropdown/content/button.hbs +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/addons/rose/addon/templates/components/rose/header/dropdown/trigger.hbs b/addons/rose/addon/templates/components/rose/header/dropdown/trigger.hbs deleted file mode 100644 index f513aa8bd..000000000 --- a/addons/rose/addon/templates/components/rose/header/dropdown/trigger.hbs +++ /dev/null @@ -1,4 +0,0 @@ - - {{yield}} - - diff --git a/addons/rose/addon/templates/components/rose/header/nav.hbs b/addons/rose/addon/templates/components/rose/header/nav.hbs new file mode 100644 index 000000000..2b2978e00 --- /dev/null +++ b/addons/rose/addon/templates/components/rose/header/nav.hbs @@ -0,0 +1,6 @@ + diff --git a/addons/rose/addon/templates/components/rose/header/navigation.hbs b/addons/rose/addon/templates/components/rose/header/navigation.hbs deleted file mode 100644 index 9e2b4308b..000000000 --- a/addons/rose/addon/templates/components/rose/header/navigation.hbs +++ /dev/null @@ -1,8 +0,0 @@ - - - {{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 eefb15e8d..6ee49e33f 100644 --- a/addons/rose/addon/templates/components/rose/header/utilities.hbs +++ b/addons/rose/addon/templates/components/rose/header/utilities.hbs @@ -1,7 +1,5 @@ - - - {{yield (hash - dropdown=(component 'rose/header/dropdown' position="true") - )}} - - +
+ {{yield (hash + dropdown=(component 'rose/header/dropdown' alignRight=true) + )}} +
diff --git a/addons/rose/app/components/rose/header/dropdown/content.js b/addons/rose/app/components/rose/header/dropdown/content.js deleted file mode 100644 index 51792f92e..000000000 --- a/addons/rose/app/components/rose/header/dropdown/content.js +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index cc70f39b5..000000000 --- a/addons/rose/app/components/rose/header/dropdown/content/button.js +++ /dev/null @@ -1 +0,0 @@ -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 deleted file mode 100644 index 0bb1491ed..000000000 --- a/addons/rose/app/components/rose/header/dropdown/trigger.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from 'rose/components/rose/header/dropdown/trigger'; diff --git a/addons/rose/app/components/rose/header/nav.js b/addons/rose/app/components/rose/header/nav.js new file mode 100644 index 000000000..896417ffd --- /dev/null +++ b/addons/rose/app/components/rose/header/nav.js @@ -0,0 +1 @@ +export { default } from 'rose/components/rose/header/nav'; diff --git a/addons/rose/app/components/rose/header/navigation.js b/addons/rose/app/components/rose/header/navigation.js deleted file mode 100644 index ff5cfc74a..000000000 --- a/addons/rose/app/components/rose/header/navigation.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from 'rose/components/rose/header/navigation'; diff --git a/addons/rose/index.js b/addons/rose/index.js index 8b3c004d5..73cccf517 100644 --- a/addons/rose/index.js +++ b/addons/rose/index.js @@ -11,6 +11,8 @@ module.exports = { this.includeStyles(app); this.includeIcons(app); + this.includePublic(app); + this.setupSVGO(app); }, /** @@ -56,4 +58,32 @@ module.exports = { if (addon.name === 'ember-inline-svg') addon.included(app); }); }, + + /** + * Finds the public folder and includes it into the ember-inline-svg addon. + */ + includePublic(app) { + const publicPath = path.resolve('public'); + const dummyPublicPath = path.resolve('tests/dummy/public'); + + app.options.svg = app.options.svg || {}; + app.options.svg.paths = app.options.svg.paths || []; + + app.options.svg.paths.push(publicPath); + if (this.isDevelopingAddon()) app.options.svg.paths.push(dummyPublicPath); + + this.addons.forEach((addon) => { + if (addon.name === 'ember-inline-svg') addon.included(app); + }); + }, + + /** + * Adjust SVG optimizer defaults (used by ember-inline-svg). + */ + setupSVGO(app) { + app.options.svg = app.options.svg || {}; + app.options.svg.optimize = app.options.svg.optimize || {}; + app.options.svg.optimize.plugins = app.options.svg.optimize.plugins || []; + app.options.svg.optimize.plugins.push({ removeViewBox: false }); + }, }; diff --git a/addons/rose/package.json b/addons/rose/package.json index bcc19b49f..4ec6dadf1 100644 --- a/addons/rose/package.json +++ b/addons/rose/package.json @@ -16,7 +16,7 @@ "lint:sass": "sass-lint -v -q", "format": "npm run format:js && npm run format:sass", "format:js": "prettier --write '{addon,app,config,stories,tests}/**/*.js' *.js", - "format:sass": "prettier --write {addon,app}/**/*.scss", + "format:sass": "prettier --write addon/**/*.scss", "start": "ember serve", "test": "ember test", "test:all": "ember try:each", diff --git a/addons/rose/tests/dummy/app/templates/index.hbs b/addons/rose/tests/dummy/app/templates/index.hbs index 6e3605e07..400f1d6f1 100644 --- a/addons/rose/tests/dummy/app/templates/index.hbs +++ b/addons/rose/tests/dummy/app/templates/index.hbs @@ -1,26 +1,30 @@ - - + - - - Org name - - link - button - + + + + + Menu item + Menu item + Button menu item + Section Section - + + - - - - link - button - + + Menu item + Menu item + Button menu item + diff --git a/addons/rose/tests/dummy/public/logo.svg b/addons/rose/tests/dummy/public/logo.svg new file mode 100644 index 000000000..2a28cc024 --- /dev/null +++ b/addons/rose/tests/dummy/public/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/rose/tests/integration/components/rose/header-test.js b/addons/rose/tests/integration/components/rose/header-test.js index 72b6ef3fb..7e0f57da7 100644 --- a/addons/rose/tests/integration/components/rose/header-test.js +++ b/addons/rose/tests/integration/components/rose/header-test.js @@ -16,26 +16,26 @@ module('Integration | Component | rose/header', function (hooks) { `); assert.ok(find('.rose-header-brand')); - assert.notOk(find('.rose-header-navigation')); + assert.notOk(find('.rose-header-nav')); assert.notOk(find('.rose-header-utilities')); }); - test('it renders with navigation', async function (assert) { + test('it renders with nav', async function (assert) { await render(hbs` - + `); - assert.ok(find('.rose-header-navigation')); + assert.ok(find('.rose-header-nav')); assert.notOk(find('.rose-header-brand')); assert.notOk(find('.rose-header-utilities')); }); - test('it renders with navigation elements', async function (assert) { + test('it renders with nav elements', async function (assert) { await render(hbs` - + - + `); - assert.ok(find('.rose-header-navigation-link')); + assert.ok(find('.rose-header-nav-link')); }); test('it renders with utilities', async function (assert) { @@ -43,7 +43,7 @@ module('Integration | Component | rose/header', function (hooks) { `); assert.notOk(find('.rose-header-brand')); - assert.notOk(find('.rose-header-navigation')); + assert.notOk(find('.rose-header-nav')); assert.ok(find('.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 e3df6dc9e..e89327632 100644 --- a/addons/rose/tests/integration/components/rose/header/brand-test.js +++ b/addons/rose/tests/integration/components/rose/header/brand-test.js @@ -7,7 +7,15 @@ module('Integration | Component | rose/header/brand', function (hooks) { setupRenderingTest(hooks); test('it renders', async function (assert) { - await render(hbs``); + assert.expect(3); + await render(hbs` + + `); assert.ok(find('.rose-header-brand')); + assert.ok(find('.rose-header-brand svg')); + assert.equal( + find('.rose-header-brand-text').textContent.trim(), + 'Product Name' + ); }); }); 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 439c29800..96806b98b 100644 --- a/addons/rose/tests/integration/components/rose/header/dropdown-test.js +++ b/addons/rose/tests/integration/components/rose/header/dropdown-test.js @@ -20,25 +20,35 @@ module('Integration | Component | rose/header/dropdown', function (hooks) { }); test('it renders with trigger', async function (assert) { - await render(hbs` - Click me - `); - assert.ok(find('.rose-header-dropdown-trigger')); + await render(hbs``); assert.equal( find('.rose-header-dropdown-trigger').textContent.trim(), 'Click me' ); }); + test('it supports an icon', async function (assert) { + await render(hbs``); + assert.ok(find('svg')); + }); + + test('it supports icon-only display', async function (assert) { + await render(hbs``); + assert.ok(find('.icon-only')); + }); + + test('it supports right-aligned content', async function (assert) { + await render(hbs``); + assert.ok(find('.dropdown-right')); + }); + test('it renders with content', async function (assert) { - await render(hbs` - - - - - - - + await render(hbs` + + + + + `); assert.ok(find('.rose-header-dropdown-content')); assert.equal(findAll('a').length, 2); @@ -46,32 +56,24 @@ module('Integration | Component | rose/header/dropdown', function (hooks) { }); test('it is toggled on click on trigger content', async function (assert) { - await render(hbs` - Click me - - - - `); + await render(hbs``); + assert.notOk(find('#dropdown').open); - - await click('#trigger'); + await click('summary'); assert.ok(find('#dropdown').open); - - await click('#trigger'); + await click('summary'); assert.notOk(find('#dropdown').open); }); test('it is closed with outside click is triggered', async function (assert) { - await render(hbs`
- Click me - - - -
`); + await render(hbs` +
+ +
+ `); - await click('#trigger'); + await click('summary'); 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 deleted file mode 100644 index b0bb4a371..000000000 --- a/addons/rose/tests/integration/components/rose/header/dropdown/content-test.js +++ /dev/null @@ -1,75 +0,0 @@ -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 positioned right when @alignRight={{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 deleted file mode 100644 index a73dc28df..000000000 --- a/addons/rose/tests/integration/components/rose/header/dropdown/content/button-test.js +++ /dev/null @@ -1,32 +0,0 @@ -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 deleted file mode 100644 index 83309f23e..000000000 --- a/addons/rose/tests/integration/components/rose/header/dropdown/trigger-test.js +++ /dev/null @@ -1,41 +0,0 @@ -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 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/nav-test.js b/addons/rose/tests/integration/components/rose/header/nav-test.js new file mode 100644 index 000000000..d1c5a688d --- /dev/null +++ b/addons/rose/tests/integration/components/rose/header/nav-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/nav', function (hooks) { + setupRenderingTest(hooks); + + test('it renders', async function (assert) { + await render(hbs``); + assert.ok(find('.rose-header-nav')); + }); + + test('it renders nav link elements', async function (assert) { + await render(hbs` + + + `); + assert.equal(findAll('a').length, 2); + }); + + test('it renders nav 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/navigation-test.js b/addons/rose/tests/integration/components/rose/header/navigation-test.js deleted file mode 100644 index 11ac6cda5..000000000 --- a/addons/rose/tests/integration/components/rose/header/navigation-test.js +++ /dev/null @@ -1,29 +0,0 @@ -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 index b0dca161d..884266d8f 100644 --- a/addons/rose/tests/integration/components/rose/header/utilities-test.js +++ b/addons/rose/tests/integration/components/rose/header/utilities-test.js @@ -11,10 +11,10 @@ module('Integration | Component | rose/header/utilities', function (hooks) { assert.ok(find('.rose-header-utilities')); }); - test('it renders navigation dropdown elements', async function (assert) { - await render(hbs` - - + test('it renders nav dropdown elements', async function (assert) { + await render(hbs` + + `); assert.equal(findAll('.rose-header-dropdown').length, 2); }); diff --git a/ui/core/app/templates/application.hbs b/ui/core/app/templates/application.hbs index 221940351..1ac60bbce 100644 --- a/ui/core/app/templates/application.hbs +++ b/ui/core/app/templates/application.hbs @@ -1,9 +1,8 @@ - - - - - {{title (app-name)}} + + + + {{outlet}} diff --git a/ui/core/public/logo.svg b/ui/core/public/logo.svg new file mode 100644 index 000000000..2a28cc024 --- /dev/null +++ b/ui/core/public/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file