refactor: 💡 simplify tabs

This commit is contained in:
Randall Morey committed 2020-06-04 15:33:24 -04:00
1 parent ffdeb8b1c3
commit b03b31ff1a
18 files changed
+111 -194

No files matched your search

@@ -3,7 +3,7 @@ import { hbs } from 'ember-cli-htmlbars';
import { action } from '@storybook/addon-actions';
import { text, boolean, select } from '@storybook/addon-knobs';
<Meta title="Rose|Nav/Sidebar" component="Nav/Sidebar" />
<Meta title="Rose|Nav|Sidebar" component="Nav/Sidebar" />
# Sidebar Navigation
@@ -1,43 +0,0 @@
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';
<Meta title="Rose|Nav|Tab" component="Tab" />
# Tab
A tab item component with ability to configure icon, title, and badge sections.
```html
<Rose::Nav::Tab @title="Tab item" @badge="3" @icon="info-circle-outline" @disabled={{false}} />
```
<Preview>
<Story name="Basic">{{
template: hbs`
<Rose::Nav::Tab
@title={{title}}
@badge={{badge}}
@icon={{icon}}
@disabled={{disabled}}
/>`,
context: {
title: text('title', 'Tab item'),
badge: text('badge', '3'),
icon: select(
'icon',
{
'info-circle-outline': 'info-circle-outline',
'user-square-fill': 'user-square-fill',
'check-circle-outline': 'check-circle-outline',
'copy-action': 'copy-action',
'unfold-more': 'unfold-more',
'unfold-less': 'unfold-less',
},
'info-circle-outline'
),
disabled: boolean('disabled', false)
},
}}</Story>
</Preview>
@@ -1,7 +1,6 @@
import Component from '@ember/component';
import layout from '../../../templates/components/rose/nav/tab';
import layout from '../../../templates/components/rose/nav/tabs';
export default Component.extend({
layout,
tagName: '',
});
@@ -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';
<Meta title="Rose|Nav|Tabs" component="Nav/Tabs" />
# Tabs Navigation
A simple tabbed navigation component.
```html
<Rose::Nav::Tabs as |nav|>
<nav.link @route='index' class="active">Text</nav.link>
<nav.link @route='index'>Text</nav.link>
<nav.link @route='index'>Text</nav.link>
</Rose::Nav::Tabs>
```
<Preview>
<Story name="Basic Tabs">{{
template: hbs`
<Rose::Nav::Tabs as |nav|>
<nav.link @route='index' class="active">Text</nav.link>
<nav.link @route='index'>Text</nav.link>
<nav.link @route='index'>Text</nav.link>
</Rose::Nav::Tabs>
`,
context: {},
}}</Story>
</Preview>
@@ -20,8 +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;
@@ -1,2 +1,2 @@
@import "sidebar";
@import 'tab';
@import 'sidebar';
@import 'tabs';
@@ -1,53 +0,0 @@
@use '../../variables/sizing';
@use '../../utilities/type';
.rose-nav-tab {
@include type.type(s);
display: inline-block;
background-color: var(--subtle);
.rose-nav-tab-link {
text-decoration: none;
color: var(--ui-gray);
display: inline-block;
padding: sizing.rems(s) sizing.rems(m);
border-bottom: sizing.rems(xxxs) solid var(--subtle);
&.rose-nav-tab-link-disabled {
cursor: not-allowed;
pointer-events: none;
color: var(--ui-gray-subtler-2);
}
&:active, &.active {
color: var(--action);
border-color: var(--action);
background-color: var(--subtle);
}
&:hover {
color: var(--ui-gray);
border-color: var(--ui-gray-subtler-2);
background-color: var(--ui-gray-subtler-4);
}
&:hover:active {
color: var(--action);
border-color: var(--action);
background-color: var(--ui-gray-subtler-4);
}
}
.rose-nav-tab-icon {
svg {
width: sizing.rems(m);
height: sizing.rems(m);
vertical-align: sub;
}
}
.rose-nav-tab-badge {
@include type.type(xs);
margin-left: sizing.rems(xxs);
}
}
@@ -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;
}
}
}
@@ -1,22 +0,0 @@
<div ...attributes class="rose-nav-tab">
<LinkTo
title={{@title}}
@route={{if @route @route "index"}}
@model={{@model}}
class={{concat "rose-nav-tab-link" (if @disabled " rose-nav-tab-link-disabled")}}
>
{{#if @icon}}
<span class="rose-nav-tab-icon">{{inline-svg @icon}}</span>
{{/if}}
{{#if @title}}
<span class="rose-nav-tab-title">{{@title}}</span>
{{/if}}
{{#if @badge}}
<span class="rose-nav-tab-badge">{{@badge}}</span>
{{/if}}
</LinkTo>
{{yield}}
</div>
@@ -0,0 +1,9 @@
<nav
...attributes
class="rose-nav-tabs">
{{yield (hash
link=(component "link-to" class="rose-nav-link")
)}}
</nav>
@@ -1 +0,0 @@
export { default } from 'rose/components/rose/nav/tab';
@@ -0,0 +1 @@
export { default } from 'rose/components/rose/nav/tabs';
@@ -198,7 +198,5 @@
<Rose::Card::Link @title="I'm a card" />
<Rose::Card::Link @title="I'm a card" @description="I'm a description" />
<Rose::Card::Link @title="I'm a card" @description="I'm a description" @subtitle="I'm a subtitle"/>
<Rose::Nav::Tab @title="Text" @badge="3" @icon="info-circle-outline" />
</page.main>
</Rose::Layout::Page>
@@ -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`
<Rose::Nav::Sidebar @title="Title" as |nav|>
<nav.link @route="index">Item Name</nav.link>
@@ -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`
<Rose::Nav::Sidebar @title="Title" as |nav|>
<nav.link @route="index">Item Name</nav.link>
@@ -1,50 +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/nav/tab', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
await render(hbs`<Rose::Nav::Tab />`);
assert.ok(find('a'));
assert.ok(find('.rose-nav-tab'));
assert.ok(find('.rose-nav-tab-link'));
assert.notOk(find('.rose-nav-tab-icon'));
assert.notOk(find('.rose-nav-tab-badge'));
assert.notOk(find('.rose-nav-tab-link-disabled'));
});
test('it renders with title', async function (assert) {
await render(hbs`<Rose::Nav::Tab @title="Tab title" />`);
assert.equal(find('a').title, 'Tab title');
assert.equal(find('.rose-nav-tab-link').textContent.trim(), 'Tab title');
});
test('it renders with icon', async function (assert) {
await render(hbs`<Rose::Nav::Tab @icon="info-circle-outline" />`);
assert.ok(find('svg'));
assert.ok(find('.rose-nav-tab-icon'));
});
test('it renders with badge', async function (assert) {
await render(hbs`<Rose::Nav::Tab @badge="3" />`);
assert.ok(find('.rose-nav-tab-badge'));
assert.equal(find('.rose-nav-tab-badge').textContent.trim(), '3');
});
test('it render with attributes', async function (assert) {
await render(hbs`<Rose::Nav::Tab id="tab" />`);
assert.ok(find('#tab'));
});
test('it renders disabled', async function (assert) {
this.set('disabled', true);
await render(hbs`<Rose::Nav::Tab @disabled={{this.disabled}} />`);
assert.ok(find('.rose-nav-tab-link-disabled'));
this.set('disabled', false);
assert.notOk(find('.rose-nav-tab-link-disabled'));
});
});
@@ -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`
<Rose::Nav::Tabs as |nav|>
<nav.link @route='index'>Item Name</nav.link>
</Rose::Nav::Tabs>
`);
assert.ok(find('.rose-nav-tabs'));
assert.equal(find('.rose-nav-link').textContent.trim(), 'Item Name');
});
});
+1 -9
View File
@@ -9,7 +9,7 @@
.rose-form {
width: 66%;
.rose-form-input {
width: 100%;
@@ -64,12 +64,4 @@
width: 100%;
}
}
.tabs {
border-bottom: 2px solid #bac1cc;
display: flex;
flex-wrap: wrap;
flex-direction: row;
margin-bottom: 10px;
}
}
@@ -9,9 +9,14 @@
<h2>{{t "resources.project.settings"}}</h2>
<div class="tabs">
<Rose::Nav::Tab @title={{t "nav.overview"}} @route='orgs.org.projects.project' @model={{@model}} />
</div>
<Rose::Nav::Tabs as |nav|>
<nav.link @route='orgs.org.projects.project'>
{{t 'dev.item-name'}}
</nav.link>
<nav.link @route='index'>
{{t 'dev.item-name'}}
</nav.link>
</Rose::Nav::Tabs>
<Form::Project
@model={{@model}}