diff --git a/addons/rose/addon/components/rose/nav/primary.js b/addons/rose/addon/components/rose/nav/primary.js new file mode 100644 index 000000000..47266ffef --- /dev/null +++ b/addons/rose/addon/components/rose/nav/primary.js @@ -0,0 +1,11 @@ +import Component from '@ember/component'; +import layout from '../../../templates/components/rose/nav/primary'; +import ComponentAutoId from '../../../mixins/component-auto-id'; + +/** + * A simple navigation component intended for the sidebar layout region. + */ +export default Component.extend(ComponentAutoId, { + layout, + tagName: '', +}); diff --git a/addons/rose/addon/components/rose/nav/primary.stories.mdx b/addons/rose/addon/components/rose/nav/primary.stories.mdx new file mode 100644 index 000000000..36e0e4d4c --- /dev/null +++ b/addons/rose/addon/components/rose/nav/primary.stories.mdx @@ -0,0 +1,34 @@ +import { Meta, Story, Preview } from '@storybook/addon-docs/blocks'; +import { hbs } from 'ember-cli-htmlbars'; +import { action } from '@storybook/addon-actions'; +import { text, boolean, select } from '@storybook/addon-knobs'; + + + +# Primary Navigation + +A simple navigation component intended for use in the sidebar layout region. + + + {{ + template: hbs` + + Item Name + Item Name + + `, + context: { + title: text('title', 'Title'), + }, + }} + + +_Note_: do not assign the `active` class directly. This is done by the link +component automatically. We use it in this story for illustrative purposes. + +```htmlbars + + Item Name + Item Name + +``` diff --git a/addons/rose/addon/styles/rose/components/_index.scss b/addons/rose/addon/styles/rose/components/_index.scss index bbd2ebcda..ec7bd22af 100644 --- a/addons/rose/addon/styles/rose/components/_index.scss +++ b/addons/rose/addon/styles/rose/components/_index.scss @@ -4,3 +4,4 @@ @import 'layout'; @import 'notification'; @import 'card'; +@import 'nav'; diff --git a/addons/rose/addon/styles/rose/components/nav/_index.scss b/addons/rose/addon/styles/rose/components/nav/_index.scss new file mode 100644 index 000000000..77d16beb5 --- /dev/null +++ b/addons/rose/addon/styles/rose/components/nav/_index.scss @@ -0,0 +1 @@ +@import "primary"; diff --git a/addons/rose/addon/styles/rose/components/nav/_primary.scss b/addons/rose/addon/styles/rose/components/nav/_primary.scss new file mode 100644 index 000000000..e91f6de8f --- /dev/null +++ b/addons/rose/addon/styles/rose/components/nav/_primary.scss @@ -0,0 +1,40 @@ +@use '../../variables/sizing'; +@use '../../utilities/type'; + +.rose-nav-primary { + $threePX: sizing.rems(xxxs) + sizing.rems(xxxxs); + + .rose-nav-title { + @include type.type(xs, semibold); + display: block; + color: var(--ui-gray); + text-transform: uppercase; + $lineHeight: 20 / 12; + line-height: $lineHeight; + padding: 0 sizing.rems(m); + margin-bottom: $threePX; + border-bottom: sizing.rems(xxxxs) solid var(--ui-gray-subtler-2); + } + + .rose-nav-link { + @include type.type(s); + display: block; + color: var(--stark); + $lineHeight: 36 / 14; + line-height: $lineHeight; + text-decoration: none; + padding: 0 sizing.rems(m); + border-right: $threePX solid transparent; + + &.active { + color: var(--action); + border-color: currentColor; + } + + &:hover { + text-decoration: underline; + color: var(--action); + background-color: var(--action-subtler-1h); + } + } +} diff --git a/addons/rose/addon/styles/rose/variables/color/_css.scss b/addons/rose/addon/styles/rose/variables/color/_css.scss index ca6df5c3d..a0644f2e4 100644 --- a/addons/rose/addon/styles/rose/variables/color/_css.scss +++ b/addons/rose/addon/styles/rose/variables/color/_css.scss @@ -56,6 +56,7 @@ --success-starker-1: #{color(green, 800)}; --action-subtler-2: #{color(blue, 010)}; + --action-subtler-1h: #{color(blue, 050)}; --action-subtler-1: #{color(blue, 100)}; --action: #{color(blue)}; --action-starker-1: #{color(blue, 700)}; @@ -115,6 +116,7 @@ --success-starker-1: #{color(green, 200)}; --action-subtler-2: #{color(blue, 900)}; + --action-subtler-1h: #{color(blue, 800)}; --action-subtler-1: #{color(blue, 800)}; --action: #{color(blue)}; --action-starker-1: #{color(blue, 300)}; diff --git a/addons/rose/addon/templates/components/rose/nav/primary.hbs b/addons/rose/addon/templates/components/rose/nav/primary.hbs new file mode 100644 index 000000000..dd0406587 --- /dev/null +++ b/addons/rose/addon/templates/components/rose/nav/primary.hbs @@ -0,0 +1,17 @@ + diff --git a/addons/rose/app/components/rose/nav/primary.js b/addons/rose/app/components/rose/nav/primary.js new file mode 100644 index 000000000..adaf57f51 --- /dev/null +++ b/addons/rose/app/components/rose/nav/primary.js @@ -0,0 +1 @@ +export { default } from 'rose/components/rose/nav/primary'; \ No newline at end of file diff --git a/addons/rose/tests/dummy/app/templates/index.hbs b/addons/rose/tests/dummy/app/templates/index.hbs index e47846e50..0eb142a9b 100644 --- a/addons/rose/tests/dummy/app/templates/index.hbs +++ b/addons/rose/tests/dummy/app/templates/index.hbs @@ -1,187 +1,202 @@ - + + + - + - - - Menu item - Menu item - Button menu item - - Section - Section - + + + Menu item + Menu item + Button menu item + + Section + Section + - - + + Menu item + Menu item + Button menu item + + + + + + + + + Item Name + Item Name + Item Name + Item Name + + + + + + Dummy app index template + + - Menu item - Menu item - Button menu item - - + An error occurred. + - +

Icon

+ + + + +

Button

+ Primary +
+ Primary +
+ + Secondary +
+ Secondary +
+ +

Form

+ + +

Inputs

+ + + + + +

Textareas

+ + + + + +

Selects

+ + + Choose an option + Value 1 + Value 2 + Value 3 + + + + + Choose an option + + -Dummy app index template +

Radio Group

+ + + + + - - An error occurred. - +

Checkboxes

+ + + + + -

Icon

- - - + +
-

Button

-Primary -
-Primary -
- -Secondary -
-Secondary -
- -

Form

- - -

Inputs

- - - - - -

Textareas

- - - - - -

Selects

- - - Choose an option - Value 1 - Value 2 - Value 3 - - - - - Choose an option - - - - -

Radio Group

- - - - - - -

Checkboxes

- - - - - - - -
- - - - + + + + + diff --git a/addons/rose/tests/integration/components/rose/nav/primary-test.js b/addons/rose/tests/integration/components/rose/nav/primary-test.js new file mode 100644 index 000000000..20229e9e3 --- /dev/null +++ b/addons/rose/tests/integration/components/rose/nav/primary-test.js @@ -0,0 +1,34 @@ +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/nav/primary', function(hooks) { + setupRenderingTest(hooks); + + test('it renders', async function(assert) { + assert.expect(2) + await render(hbs` + + Item Name + + `); + assert.equal(find('.rose-nav-title').textContent.trim(), 'Title'); + assert.equal(find('.rose-nav-link').textContent.trim(), 'Item Name'); + }); + + test('it associates title with nav via aria-labelledby', async function (assert) { + assert.expect(2) + await render(hbs` + + Item Name + + `); + const el = find('.rose-nav-primary'); + const id = el.id; + const titleId = `title-${id}`; + const titleEl = find('.rose-nav-title'); + assert.equal(titleEl.id, titleId); + assert.equal(el.getAttribute('aria-labelledby').trim(), titleId); + }); +}); diff --git a/ui/core/app/styles/app.scss b/ui/core/app/styles/app.scss index ae92ab2d8..d04a9ed2b 100644 --- a/ui/core/app/styles/app.scss +++ b/ui/core/app/styles/app.scss @@ -3,6 +3,10 @@ @import 'rose'; @import 'notify'; +.rose-nav-primary { + margin-top: sizing.rems(xxl); +} + .projects-overview { margin: sizing.rems(l); diff --git a/ui/core/app/templates/application.hbs b/ui/core/app/templates/application.hbs index 4a6e12e89..a3f55929f 100644 --- a/ui/core/app/templates/application.hbs +++ b/ui/core/app/templates/application.hbs @@ -29,7 +29,15 @@ {{outlet}} - + + + {{t 'dev.item-name'}} + {{t 'dev.item-name'}} + {{t 'dev.item-name'}} + {{t 'dev.item-name'}} + + + diff --git a/ui/core/translations/en-us.yaml b/ui/core/translations/en-us.yaml index 3abe145c0..ca4bc7961 100644 --- a/ui/core/translations/en-us.yaml +++ b/ui/core/translations/en-us.yaml @@ -21,3 +21,5 @@ dev: menu-item: Menu item button-menu-item: Button menu item section: Section + title: Title + item-name: Item Name