diff --git a/addons/rose/addon/components/rose/nav/sidebar.stories.mdx b/addons/rose/addon/components/rose/nav/sidebar.stories.mdx
index 353cf0e86..6fb344b7f 100644
--- a/addons/rose/addon/components/rose/nav/sidebar.stories.mdx
+++ b/addons/rose/addon/components/rose/nav/sidebar.stories.mdx
@@ -3,7 +3,7 @@ import { hbs } from 'ember-cli-htmlbars';
import { action } from '@storybook/addon-actions';
import { text, boolean, select } from '@storybook/addon-knobs';
-
+
# Sidebar Navigation
diff --git a/addons/rose/addon/components/rose/nav/tabs.js b/addons/rose/addon/components/rose/nav/tabs.js
new file mode 100644
index 000000000..5ee542903
--- /dev/null
+++ b/addons/rose/addon/components/rose/nav/tabs.js
@@ -0,0 +1,6 @@
+import Component from '@ember/component';
+import layout from '../../../templates/components/rose/nav/tabs';
+
+export default Component.extend({
+ layout,
+});
diff --git a/addons/rose/addon/components/rose/nav/tabs.stories.mdx b/addons/rose/addon/components/rose/nav/tabs.stories.mdx
new file mode 100644
index 000000000..fd429ce62
--- /dev/null
+++ b/addons/rose/addon/components/rose/nav/tabs.stories.mdx
@@ -0,0 +1,31 @@
+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';
+
+
+
+# Tabs Navigation
+
+A simple tabbed navigation component.
+
+```html
+
+ Text
+ Text
+ Text
+
+```
+
+
+ {{
+ template: hbs`
+
+ Text
+ Text
+ Text
+
+ `,
+ context: {},
+ }}
+
diff --git a/addons/rose/addon/components/rose/notification.js b/addons/rose/addon/components/rose/notification.js
index 856dbc863..1b1677a67 100644
--- a/addons/rose/addon/components/rose/notification.js
+++ b/addons/rose/addon/components/rose/notification.js
@@ -20,7 +20,7 @@ export default Component.extend({
get icon() {
let icon = 'info-circle-fill';
- switch(this.style) {
+ switch (this.style) {
case 'error':
icon = 'cancel-square-fill';
break;
@@ -33,6 +33,5 @@ export default Component.extend({
}
return icon;
- }
-
+ },
});
diff --git a/addons/rose/addon/styles/rose/components/_notification.scss b/addons/rose/addon/styles/rose/components/_notification.scss
index ac88ea4f4..c69dde3f1 100644
--- a/addons/rose/addon/styles/rose/components/_notification.scss
+++ b/addons/rose/addon/styles/rose/components/_notification.scss
@@ -58,11 +58,11 @@
}
&:hover {
- background-color: rgba(var(--stark-components), var(--opacity-3))
+ background-color: rgba(var(--stark-components), var(--opacity-3));
}
&:active {
- background-color: rgba(var(--stark-components), var(--opacity-2))
+ background-color: rgba(var(--stark-components), var(--opacity-2));
}
}
diff --git a/addons/rose/addon/styles/rose/components/card/_link.scss b/addons/rose/addon/styles/rose/components/card/_link.scss
index ba0e367e8..26b3e3f8c 100644
--- a/addons/rose/addon/styles/rose/components/card/_link.scss
+++ b/addons/rose/addon/styles/rose/components/card/_link.scss
@@ -3,7 +3,7 @@
.rose-card-link {
@include type.type(s);
- border: 1px solid var(--ui-gray-subtler-2);
+ border: sizing.rems(xxxxs) solid var(--ui-gray-subtler-2);
border-radius: sizing.rems(xxxs);
color: var(--ui-gray);
display: inline-flex;
diff --git a/addons/rose/addon/styles/rose/components/nav/_index.scss b/addons/rose/addon/styles/rose/components/nav/_index.scss
index 0abffa8bd..4a208cbee 100644
--- a/addons/rose/addon/styles/rose/components/nav/_index.scss
+++ b/addons/rose/addon/styles/rose/components/nav/_index.scss
@@ -1 +1,2 @@
-@import "sidebar";
+@import 'sidebar';
+@import 'tabs';
diff --git a/addons/rose/addon/styles/rose/components/nav/_tabs.scss b/addons/rose/addon/styles/rose/components/nav/_tabs.scss
new file mode 100644
index 000000000..73c2f78b2
--- /dev/null
+++ b/addons/rose/addon/styles/rose/components/nav/_tabs.scss
@@ -0,0 +1,33 @@
+@use '../../variables/sizing';
+@use '../../utilities/type';
+
+.rose-nav-tabs {
+ display: flex;
+ margin-bottom: sizing.rems(m);
+ box-shadow: inset 0 -#{sizing.rems(xxxxs)} 0 var(--ui-gray-subtler-2);
+
+ .rose-nav-link {
+ --color: var(--ui-gray);
+ --background: transparent;
+ --box-shadow-color: transparent;
+
+ @include type.type(s, semibold);
+ display: inline-block;
+ color: var(--color);
+ background-color: var(--background);
+ box-shadow: inset 0 -#{sizing.rems(xxxxs) * 3} 0 var(--box-shadow-color);
+ text-decoration: none;
+ padding: sizing.rems(m);
+
+ &:hover {
+ --box-shadow-color: var(--ui-gray-subtler-2);
+ --background: var(--ui-gray-subtler-4);
+ }
+
+ &:active,
+ &.active {
+ --color: var(--action);
+ --box-shadow-color: currentColor;
+ }
+ }
+}
diff --git a/addons/rose/addon/templates/components/rose/nav/tabs.hbs b/addons/rose/addon/templates/components/rose/nav/tabs.hbs
new file mode 100644
index 000000000..18470f7d5
--- /dev/null
+++ b/addons/rose/addon/templates/components/rose/nav/tabs.hbs
@@ -0,0 +1,9 @@
+
diff --git a/addons/rose/app/components/rose/layout/tabs.js b/addons/rose/app/components/rose/layout/tabs.js
new file mode 100644
index 000000000..9de968192
--- /dev/null
+++ b/addons/rose/app/components/rose/layout/tabs.js
@@ -0,0 +1 @@
+export { default } from 'rose/components/rose/layout/tabs';
diff --git a/addons/rose/app/components/rose/nav/tabs.js b/addons/rose/app/components/rose/nav/tabs.js
new file mode 100644
index 000000000..91a0d8fe8
--- /dev/null
+++ b/addons/rose/app/components/rose/nav/tabs.js
@@ -0,0 +1 @@
+export { default } from 'rose/components/rose/nav/tabs';
diff --git a/addons/rose/app/components/rose/notification.js b/addons/rose/app/components/rose/notification.js
index 228bd468c..bf9252122 100644
--- a/addons/rose/app/components/rose/notification.js
+++ b/addons/rose/app/components/rose/notification.js
@@ -1 +1 @@
-export { default } from 'rose/components/rose/notification';
\ No newline at end of file
+export { default } from 'rose/components/rose/notification';
diff --git a/addons/rose/app/components/rose/tab.js b/addons/rose/app/components/rose/tab.js
new file mode 100644
index 000000000..37b6e680c
--- /dev/null
+++ b/addons/rose/app/components/rose/tab.js
@@ -0,0 +1 @@
+export { default } from 'rose/components/rose/tab';
diff --git a/addons/rose/tests/dummy/app/templates/index.hbs b/addons/rose/tests/dummy/app/templates/index.hbs
index a58b48caf..ec3965039 100644
--- a/addons/rose/tests/dummy/app/templates/index.hbs
+++ b/addons/rose/tests/dummy/app/templates/index.hbs
@@ -49,7 +49,7 @@
@dismiss={{this.actionHandler}}
@dismissText="Dismiss"
>
- An error occurred.
+ An error occurred.
Icon
diff --git a/addons/rose/tests/integration/components/rose/nav/sidebar-test.js b/addons/rose/tests/integration/components/rose/nav/sidebar-test.js
index dfda90191..293079caa 100644
--- a/addons/rose/tests/integration/components/rose/nav/sidebar-test.js
+++ b/addons/rose/tests/integration/components/rose/nav/sidebar-test.js
@@ -3,11 +3,11 @@ import { setupRenderingTest } from 'ember-qunit';
import { render, find } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
-module('Integration | Component | rose/nav/sidebar', function(hooks) {
+module('Integration | Component | rose/nav/sidebar', function (hooks) {
setupRenderingTest(hooks);
- test('it renders', async function(assert) {
- assert.expect(2)
+ test('it renders', async function (assert) {
+ assert.expect(2);
await render(hbs`
Item Name
@@ -18,7 +18,7 @@ module('Integration | Component | rose/nav/sidebar', function(hooks) {
});
test('it associates title with nav via aria-labelledby', async function (assert) {
- assert.expect(2)
+ assert.expect(2);
await render(hbs`
Item Name
diff --git a/addons/rose/tests/integration/components/rose/nav/tabs-test.js b/addons/rose/tests/integration/components/rose/nav/tabs-test.js
new file mode 100644
index 000000000..733f9e997
--- /dev/null
+++ b/addons/rose/tests/integration/components/rose/nav/tabs-test.js
@@ -0,0 +1,19 @@
+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/tabs', function (hooks) {
+ setupRenderingTest(hooks);
+
+ test('it renders', async function (assert) {
+ assert.expect(2);
+ await render(hbs`
+
+ Item Name
+
+ `);
+ assert.ok(find('.rose-nav-tabs'));
+ assert.equal(find('.rose-nav-link').textContent.trim(), 'Item Name');
+ });
+});
diff --git a/addons/rose/tests/integration/components/rose/notification-test.js b/addons/rose/tests/integration/components/rose/notification-test.js
index 6027644d0..f8c1573b5 100644
--- a/addons/rose/tests/integration/components/rose/notification-test.js
+++ b/addons/rose/tests/integration/components/rose/notification-test.js
@@ -3,10 +3,10 @@ import { setupRenderingTest } from 'ember-qunit';
import { render, find, click } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
-module('Integration | Component | rose/notification', function(hooks) {
+module('Integration | Component | rose/notification', function (hooks) {
setupRenderingTest(hooks);
- test('it renders', async function(assert) {
+ test('it renders', async function (assert) {
await render(hbs`
`);
assert.ok(find('.rose-notification'));
- assert.equal(find('.rose-notification-body').textContent.trim(), 'An error occurred.');
+ assert.equal(
+ find('.rose-notification-body').textContent.trim(),
+ 'An error occurred.'
+ );
});
- test('it has optional dismiss button which triggers a function', async function(assert) {
+ test('it has optional dismiss button which triggers a function', async function (assert) {
assert.expect(1);
this.dismiss = () => assert.ok(true, 'dismiss clicked');
await render(hbs`
diff --git a/ui/core/app/templates/orgs/org/projects/project.hbs b/ui/core/app/templates/orgs/org/projects/project.hbs
index 4c360b74c..26770d11b 100644
--- a/ui/core/app/templates/orgs/org/projects/project.hbs
+++ b/ui/core/app/templates/orgs/org/projects/project.hbs
@@ -7,7 +7,16 @@
{{@model.name}}
- {{@model.name}}
+ {{t "resources.project.settings"}}
+
+
+
+ {{t 'dev.item-name'}}
+
+
+ {{t 'dev.item-name'}}
+
+