chore: Update rose/dropdown link and button components

Instead of wrapping dropdown button component in rose/button, create a
new simplified button.
This commit is contained in:
Susmitha Girumala committed 2020-08-17 13:15:58 -04:00
1 parent 5c1bb1052a
commit 7df2295058
26 files changed
+257 -92

No files matched your search

@@ -13,6 +13,7 @@ A simple dropdown component with support for links and buttons.
<Rose::Dropdown @text="Choose One&hellip;" @icon="user-organization" as |dropdown|>
<dropdown.link @route="index">Menu item</dropdown.link>
<dropdown.link @route="about">Menu item</dropdown.link>
<dropdown.separator />
<dropdown.button>Button menu item</dropdown.button>
</Rose::Dropdown>
`,
@@ -25,6 +26,7 @@ A simple dropdown component with support for links and buttons.
<Rose::Dropdown @text="Choose One&hellip;" @icon="user-organization" @iconOnly={{true}} as |dropdown|>
<dropdown.link @route="index">Menu item</dropdown.link>
<dropdown.link @route="about">Menu item</dropdown.link>
<dropdown.separator />
<dropdown.button>Button menu item</dropdown.button>
</Rose::Dropdown>
`,
@@ -46,18 +48,16 @@ Dropdown content can be aligned to right edge of the component instead of the de
<Rose::Dropdown @text="Choose One&hellip;" style="float: right" @dropdownRight={{true}} as |dropdown|>
<dropdown.link @route="index">Menu item</dropdown.link>
<dropdown.link @route="about">Menu item</dropdown.link>
<dropdown.separator />
<dropdown.button>Button menu item</dropdown.button>
</Rose::Dropdown>
```
Dropdown button styles support all `Rose::Button` styles through a `style` attribute.
Dropdown supports `danger` styling through `style` attribute.
```htmlbars
<Rose::Dropdown @text="Dropdown" as |dropdown|>
<dropdown.button>Button menu item</dropdown.button>
<dropdown.button @style="warning">Button - warning</dropdown.button>
<dropdown.button @style="primary">Button - primary</dropdown.button>
<dropdown.button @style="secondary">Button - secondary</dropdown.button>
<dropdown.button @style="ghost">Button - ghost</dropdown.button>
<dropdown.link @style="danger">Link - danger</dropdown.link>
<dropdown.button @style="danger">Button - danger</dropdown.button>
</Rose::Dropdown>
```
@@ -0,0 +1,10 @@
import Component from '@ember/component';
import layout from '../../../templates/components/rose/dropdown/button';
/**
* A dropdown button component based on simplified rose/button
*/
export default Component.extend({
layout,
tagName: '',
});
@@ -0,0 +1,10 @@
import Component from '@ember/component';
import layout from '../../../templates/components/rose/dropdown/link';
/**
* A dropdown link wrapper for LinkTo component.
*/
export default Component.extend({
layout,
tagName: '',
});
@@ -0,0 +1,34 @@
@use '../../variables/sizing';
@use '../../utilities/type';
.rose-dropdown-button {
@include type.type(s, normal);
display: block;
// Targeting min-width of 200
min-width: (sizing.rems(m) + sizing.rems(xxs)) * 10;
border: 0;
margin: 0;
padding: 0 sizing.rems(s);
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;
cursor: pointer;
&.rose-dropdown-button-danger {
--background: var(--white);
--color: var(--failure);
color: var(--color);
background-color: var(--background-color);
&:hover {
--color: var(--white);
--background-color: var(--failure);
}
}
}
@@ -1,5 +1,5 @@
@use '../variables/sizing';
@use '../utilities/type';
@use '../../variables/sizing';
@use '../../utilities/type';
$chevron: "data:image/svg+xml;utf-8,<svg viewBox='0 0 24 24' fill='%231b1f26' xmlns='http://www.w3.org/2000/svg'><path fill-rule='evenodd' clip-rule='evenodd' d='M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6-1.41-1.41z'></path></svg>";
@@ -92,42 +92,9 @@ $chevron: "data:image/svg+xml;utf-8,<svg viewBox='0 0 24 24' fill='%231b1f26' xm
}
}
.rose-dropdown-link,
.rose-dropdown-button {
@include type.type(s, 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;
box-shadow: none;
text-shadow: none;
cursor: pointer;
&:hover {
box-shadow: none;
text-shadow: none;
}
}
.rose-dropdown-button {
width: 100%;
&.rose-button-warning {
color: var(--failure);
&:hover {
color: var(--white);
}
}
.rose-dropdown-separator {
background-color: var(--ui-gray-subtler-3);
height: sizing.rems(xxxxs);
border: none;
}
}
@@ -0,0 +1,3 @@
@import 'dropdown';
@import 'button';
@import 'link';
@@ -0,0 +1,33 @@
@use '../../variables/sizing';
@use '../../utilities/type';
.rose-dropdown-link {
@include type.type(s, normal);
display: block;
// Targeting min-width of 200
min-width: (sizing.rems(s) + sizing.rems(xxs)) * 10;
border: 0;
padding: 0 sizing.rems(s);
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;
cursor: pointer;
&.rose-dropdown-link-danger {
--background: var(--white);
--color: var(--failure);
color: var(--color);
background-color: var(--background-color);
&:hover {
--color: var(--white);
--background-color: var(--failure);
}
}
}
@@ -1,11 +1,11 @@
<details
...attributes
class="rose-dropdown {{if @dropdownRight " rose-dropdown-right"}}"
class="rose-dropdown {{if @dropdownRight "rose-dropdown-right"}}"
{{on-click-outside this.close}}
>
<summary
class="rose-dropdown-trigger{{if @iconOnly " has-icon-only"}}"
class="rose-dropdown-trigger {{if @iconOnly "has-icon-only"}}"
title={{@text}}
>
@@ -24,8 +24,9 @@
<div class="rose-dropdown-content" {{on-click-inside this.close}}>
{{yield (hash
link=(component "link-to" class="rose-dropdown-link")
button=(component "rose/button" classNames="rose-dropdown-button" style=this.style)
link=(component "rose/dropdown/link" style=this.style)
button=(component "rose/dropdown/button" style=this.style)
separator=(component "rose/anonymous" tagName="hr" class="rose-dropdown-separator")
)}}
</div>
@@ -0,0 +1,19 @@
<button
...attributes
type={{if @submit "submit" "button"}}
disabled={{if @disabled "disabled"}}
class="rose-dropdown-button {{if @style (concat "rose-dropdown-button-" @style)}} {{if @iconOnly "has-icon-only"}}"
>
<span class="rose-dropdown-button-wrapper">
<span class="rose-dropdown-button-body">
{{yield}}
</span>
{{#if @iconOnly}}
<Rose::Icon
@name={{@iconOnly}}
@size="medium"
/>
{{/if}}
</span>
</button>
@@ -0,0 +1,8 @@
<LinkTo
...attributes
@route={{if @route @route "index"}}
@model={{@model}}
class="rose-dropdown-link {{if @style (concat "rose-dropdown-link-" @style)}}"
>
{{yield}}
</LinkTo>
@@ -0,0 +1 @@
export { default } from 'rose/components/rose/dropdown/button';
@@ -0,0 +1 @@
export { default } from 'rose/components/rose/dropdown/link';
+10 -11
View File
@@ -4,9 +4,11 @@
<header.nav as |nav|>
<nav.dropdown @text="org-name" as |dropdown|>
<dropdown.link @route="index">Menu item</dropdown.link>
<dropdown.link @route="about">Menu item</dropdown.link>
<dropdown.link @route="about" @style="danger">Menu item - danger</dropdown.link>
<dropdown.separator />
<dropdown.button>Button menu item</dropdown.button>
</nav.dropdown>
<nav.link @route="index">Section</nav.link>
<nav.link @route="about">Section</nav.link>
</header.nav>
@@ -18,22 +20,19 @@
@icon="user-square-fill" as |dropdown|
>
<dropdown.link @route="index">Menu item</dropdown.link>
<dropdown.link @route="about">Menu item</dropdown.link>
<dropdown.link @route="about" @style="danger">Menu item - danger</dropdown.link>
<dropdown.button>Button - default</dropdown.button>
<dropdown.button @style="warning">Button - warning</dropdown.button>
<dropdown.button @style="primary">Button - primary</dropdown.button>
<dropdown.button @style="secondary">Button - secondary</dropdown.button>
<dropdown.button @style="ghost">Button - ghost</dropdown.button>
<dropdown.separator />
<dropdown.button @style="danger">Button - danger</dropdown.button>
</utilities.dropdown>
</header.utilities>
</Rose::Header>
<Rose::Dropdown @text="Dropdown" as |dropdown|>
<dropdown.link @route="index">Menu item</dropdown.link>
<dropdown.link @route="about">Menu item</dropdown.link>
<dropdown.link @route="about" @style="danger">Menu item - danger</dropdown.link>
<dropdown.separator></dropdown.separator>
<dropdown.button>Button menu item</dropdown.button>
<dropdown.button @style="warning">Button - warning</dropdown.button>
<dropdown.button @style="primary">Button - primary</dropdown.button>
<dropdown.button @style="secondary">Button - secondary</dropdown.button>
<dropdown.button @style="ghost">Button - ghost</dropdown.button>
<dropdown.button @style="danger">Button - danger</dropdown.button>
</Rose::Dropdown>
@@ -0,0 +1,38 @@
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/dropdown/button', function(hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
await render(hbs`<Rose::Dropdown::Button />`);
assert.ok(find('.rose-dropdown-button'));
});
test('it is type="button" by default', async function (assert) {
await render(hbs`<Rose::Dropdown::Button />`);
assert.equal(find('button').type, 'button');
});
test('it is type="submit" when @submit={{true}}', async function (assert) {
await render(hbs`<Rose::Dropdown::Button @submit={{true}} />`);
assert.equal(find('button').type, 'submit');
});
test('it is disabled when @disabled={{true}}', async function (assert) {
await render(hbs`<Rose::Dropdown::Button @disabled={{true}} />`);
assert.equal(find('button').disabled, true);
});
test('it adds a style class', async function (assert) {
await render(hbs`<Rose::Dropdown::Button @style="warning" />`);
assert.ok(find('.rose-dropdown-button-warning'));
});
test('it supports an icon-only type', async function (assert) {
await render(hbs`<Rose::Dropdown::Button @iconOnly="chevron-left" />`);
assert.ok(find('.has-icon-only .rose-icon'));
});
});
@@ -0,0 +1,31 @@
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/dropdown/link', function(hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
await render(hbs`<Rose::Dropdown::Link />`);
assert.ok(find('a'));
assert.ok(find('.rose-dropdown-link'));
});
test('it renders with attributes', async function (assert) {
await render(hbs`<Rose::Dropdown::Link id="dropdown" />`);
assert.ok(find('#dropdown'));
});
test('it renders with content', async function (assert) {
await render(hbs`<Rose::Dropdown::Link>
content
</Rose::Dropdown::Link>`);
assert.equal(find('.rose-dropdown-link').textContent.trim(), 'content');
});
test('it supports style', async function (assert) {
await render(hbs`<Rose::Dropdown::Link @style='warning' />`);
assert.ok('.rose-dropdown-link-warning');
});
});
@@ -17,9 +17,9 @@
</page.navigation>
<page.actions>
<Rose::Dropdown @text="{{t 'form.label.manage'}}" @alignRight={{true}} as |dropdown|>
<Rose::Dropdown @text="{{t 'form.label.manage'}}" @dropdownRight={{true}} as |dropdown|>
<dropdown.button
@style="warning"
@style="danger"
@disabled={{@model.canSave}}
{{on "click" (route-action "delete" @model)}}
>
@@ -16,20 +16,24 @@
</Rose::Nav::Tabs>
</page.navigation>
<page.actions>
<Rose::Dropdown @text="{{t 'form.label.manage'}}" @dropdownRight={{true}} as |dropdown|>
<dropdown.button
@style="danger"
@disabled={{@model.canSave}}
{{on "click" (route-action "delete" @model)}}
>
{{t 'actions.delete-host-catalog'}}
</dropdown.button>
</Rose::Dropdown>
</page.actions>
<page.body>
<Form::HostCatalog
@model={{@model}}
@submit={{route-action "save" @model}}
@cancel={{route-action "cancel" @model}}
/>
<Rose::Separator />
<Rose::Button
@style="warning"
@disabled={{@model.canSave}}
{{on "click" (route-action "delete" @model)}}
>
{{t 'actions.delete'}}
</Rose::Button>
</page.body>
</Rose::Layout::Page>
@@ -16,20 +16,24 @@
</Rose::Nav::Tabs>
</page.navigation>
<page.actions>
<Rose::Dropdown @text="{{t 'form.label.manage'}}" @dropdownRight={{true}} as |dropdown|>
<dropdown.button
@style="danger"
@disabled={{@model.canSave}}
{{on "click" (route-action "delete" @model)}}
>
{{t 'actions.delete-project'}}
</dropdown.button>
</Rose::Dropdown>
</page.actions>
<page.body>
<Form::Project
@model={{@model}}
@submit={{route-action "save" @model}}
@cancel={{route-action "cancel" @model}}
/>
<Rose::Separator />
<Rose::Button
@style="warning"
@disabled={{@model.canSave}}
{{on "click" (route-action "delete" @model)}}
>
{{t 'actions.delete'}}
</Rose::Button>
</page.body>
</Rose::Layout::Page>
@@ -11,9 +11,9 @@
</page.header>
<page.actions>
<Rose::Dropdown @text="{{t 'form.label.manage'}}" @alignRight={{true}} as |dropdown|>
<Rose::Dropdown @text="{{t 'form.label.manage'}}" @dropdownRight={{true}} as |dropdown|>
<dropdown.button
@style="warning"
@style="danger"
@disabled={{@model.canSave}}
{{on "click" (route-action "delete" @model)}}
>
@@ -9,9 +9,9 @@
</page.header>
<page.actions>
<Rose::Dropdown @text="{{t 'form.label.manage'}}" @alignRight={{true}} as |dropdown|>
<Rose::Dropdown @text="{{t 'form.label.manage'}}" @dropdownRight={{true}} as |dropdown|>
<dropdown.button
@style="warning"
@style="danger"
@disabled={{@model.canSave}}
{{on "click" (route-action "delete" @model)}}
>
+2 -2
View File
@@ -133,7 +133,7 @@ module('Acceptance | groups', function (hooks) {
assert.expect(1);
const groupsCount = this.server.db.groups.length;
await visit(groupURL);
await click('.rose-button-warning');
await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.equal(this.server.db.groups.length, groupsCount - 1);
});
@@ -210,7 +210,7 @@ module('Acceptance | groups', function (hooks) {
);
});
await visit(groupURL);
await click('.rose-button-warning');
await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.ok(
find('[role="alert"]').textContent.trim(),
'Oops.',
@@ -80,7 +80,7 @@ module('Acceptance | host catalogs', function (hooks) {
authenticateSession({});
await visit(urls.hostCatalog);
assert.equal(currentURL(), urls.hostCatalog);
await click('.rose-button-warning');
await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.equal(this.server.db.hostCatalogs.length, hostCatalogsCount - 1);
});
@@ -162,7 +162,7 @@ module('Acceptance | host catalogs', function (hooks) {
});
authenticateSession({});
await visit(urls.hostCatalog);
await click('.rose-button-warning');
await click('.rose-layout-page-actions .rose-dropdown-button-danger');
await a11yAudit();
assert.ok(
find('[role="alert"]').textContent.trim(),
+2 -2
View File
@@ -135,7 +135,7 @@ module('Acceptance | projects', function (hooks) {
test('can delete project', async function (assert) {
assert.expect(1);
await visit(existingProjectURL);
await click('.rose-button-warning');
await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.equal(getProjectScopesCount(), initialProjectScopesCount - 1);
});
@@ -212,7 +212,7 @@ module('Acceptance | projects', function (hooks) {
);
});
await visit(existingProjectURL);
await click('.rose-button-warning');
await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.ok(
find('[role="alert"]').textContent.trim(),
'Oops.',
+2 -2
View File
@@ -133,7 +133,7 @@ module('Acceptance | roles', function (hooks) {
assert.expect(1);
const rolesCount = this.server.db.roles.length;
await visit(roleURL);
await click('.rose-button-warning');
await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.equal(this.server.db.roles.length, rolesCount - 1);
});
@@ -210,7 +210,7 @@ module('Acceptance | roles', function (hooks) {
);
});
await visit(roleURL);
await click('.rose-button-warning');
await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.ok(
find('[role="alert"]').textContent.trim(),
'Oops.',
+2 -2
View File
@@ -133,7 +133,7 @@ module('Acceptance | users', function (hooks) {
assert.expect(1);
const usersCount = this.server.db.users.length;
await visit(userURL);
await click('.rose-button-warning');
await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.equal(this.server.db.users.length, usersCount - 1);
});
@@ -210,7 +210,7 @@ module('Acceptance | users', function (hooks) {
);
});
await visit(userURL);
await click('.rose-button-warning');
await click('.rose-layout-page-actions .rose-dropdown-button-danger');
assert.ok(
find('[role="alert"]').textContent.trim(),
'Oops.',
+2
View File
@@ -12,6 +12,8 @@ actions:
delete-user: Delete user
delete-group: Delete group
delete-role: Delete role
delete-project: Delete project
delete-host-catalog: Delete host catalog
auth:
titles:
no-scopes: No Scopes Available