Merge remote-tracking branch 'origin/develop' into remove-build-references-to-connect-client
This commit is contained in:
18 files changed
+345
-28
No files matched your search
@@ -0,0 +1,7 @@
|
||||
import Component from '@ember/component';
|
||||
import layout from '../../templates/components/rose/badge';
|
||||
|
||||
export default Component.extend({
|
||||
layout,
|
||||
tagName: '',
|
||||
});
|
||||
@@ -0,0 +1,75 @@
|
||||
import { Meta, Story, Preview } from '@storybook/addon-docs/blocks';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { text, select } from '@storybook/addon-knobs';
|
||||
|
||||
<Meta title="Rose|Badge" component="Badge" />
|
||||
|
||||
# Badge
|
||||
|
||||
A badge component that supports icons and predefined styles.
|
||||
When style definition isn't supplied, a default style will be supplied.
|
||||
|
||||
Styles: outline, dark, informational, informational-outline, success, success-outline, error, error-outline, warning, warning-outline, alert, alert-outline
|
||||
|
||||
```html
|
||||
<Rose::Badge @style="outline" @icon="user-organization">Badge</Rose::Badge>
|
||||
```
|
||||
|
||||
<Preview>
|
||||
<Story name="Basic">{{
|
||||
template: hbs`<Rose::Badge
|
||||
@style={{style}}
|
||||
@icon={{icon}}>
|
||||
{{text}}
|
||||
</Rose::Badge>`,
|
||||
context: {
|
||||
text: text('text', 'Badge'),
|
||||
style: select('style', {
|
||||
'none': 'none',
|
||||
'outline': 'outline',
|
||||
'dark': 'dark',
|
||||
'informational': 'informational',
|
||||
'informational-outline': 'informational-outline',
|
||||
'success': 'success',
|
||||
'success-outline': 'success-outline',
|
||||
'alert': 'alert',
|
||||
'alert-outline': 'alert-outline',
|
||||
'error': 'error',
|
||||
'error-outline': 'error-outline',
|
||||
'warning': 'warning',
|
||||
'warning-outline': 'warning-outline',
|
||||
},
|
||||
'none'
|
||||
),
|
||||
icon: select('icon', {
|
||||
'user-organization': 'user-organization',
|
||||
'partner': 'partner',
|
||||
'gift-fill': 'gift-fill',
|
||||
},
|
||||
'user-organization'
|
||||
),
|
||||
}
|
||||
}}</Story>
|
||||
</Preview>
|
||||
|
||||
<Preview>
|
||||
<Story name="Style legend">{{
|
||||
template: hbs`
|
||||
<Rose::Badge>default style</Rose::Badge>
|
||||
<Rose::Badge @style="outline">outline</Rose::Badge>
|
||||
<Rose::Badge @icon="user-organization">default style with icon</Rose::Badge>
|
||||
<Rose::Badge @style="dark">dark</Rose::Badge>
|
||||
<Rose::Badge @style="informational">informational</Rose::Badge>
|
||||
<Rose::Badge @style="informational-outline">informational-outline</Rose::Badge>
|
||||
<Rose::Badge @style="alert">alert</Rose::Badge>
|
||||
<Rose::Badge @style="alert-outline">alert-outline</Rose::Badge>
|
||||
<Rose::Badge @style="error">error</Rose::Badge>
|
||||
<Rose::Badge @style="error-outline">error-outline</Rose::Badge>
|
||||
<Rose::Badge @style="success">success</Rose::Badge>
|
||||
<Rose::Badge @style="success-outline">success-outline</Rose::Badge>
|
||||
<Rose::Badge @style="warning">warning</Rose::Badge>
|
||||
<Rose::Badge @style="warning-outline">warning-outline</Rose::Badge>
|
||||
`,
|
||||
}}</Story>
|
||||
</Preview>
|
||||
@@ -3,7 +3,6 @@ import layout from '../../templates/components/rose/dropdown';
|
||||
import { action } from '@ember/object';
|
||||
|
||||
export default Component.extend({
|
||||
|
||||
// =attributes
|
||||
|
||||
layout,
|
||||
@@ -13,14 +12,15 @@ export default Component.extend({
|
||||
|
||||
/**
|
||||
* Closes the details element by setting its `open` attribute to `false`.
|
||||
* While the details element handles open/close functionality without
|
||||
* JavaScript, we include this helper action to ensure that when the user
|
||||
* clicks _outside_ of the element, it still closes.
|
||||
* While the details element handles open/close functionality when clicking
|
||||
* directly on the summar elemenet without JavaScript, we include this helper
|
||||
* action to ensure that when the user clicks _outside_ of the element,
|
||||
* or _inside_ the content, it still closes.
|
||||
* @param {HTMLElement} element
|
||||
*/
|
||||
@action
|
||||
close(element) {
|
||||
if (element.open) element.open = false;
|
||||
if (element.parentElement.open) element.parentElement.open = false;
|
||||
},
|
||||
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
import { modifier } from 'ember-modifier';
|
||||
|
||||
/**
|
||||
* Used to detect clicks occuring _inside_ the modified element.
|
||||
* This is useful especially for dropdowns to toggle content visibility
|
||||
* when the user clicks an item.
|
||||
*/
|
||||
export default modifier((element, [callback]) => {
|
||||
function handleClick(event) {
|
||||
if (element.contains(event.target)) {
|
||||
callback(element, event);
|
||||
}
|
||||
}
|
||||
|
||||
element.addEventListener('click', handleClick, false);
|
||||
|
||||
return () => {
|
||||
element.removeEventListener('click', handleClick, false);
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,84 @@
|
||||
@use '../utilities/type';
|
||||
@use '../variables/sizing';
|
||||
|
||||
.rose-badge {
|
||||
@include type.type(s, semibold);
|
||||
padding: sizing.rems(xxxs) sizing.rems(xxs);
|
||||
border-radius: sizing.rems(xxxs);
|
||||
border-width: sizing.rems(xxxxs);
|
||||
border-style: solid;
|
||||
display: inline-block;
|
||||
|
||||
--color: var(--ui-gray-starker-1);
|
||||
--border-color: var(--ui-gray-subtler-5);
|
||||
--background-color: none;
|
||||
|
||||
color: var(--color);
|
||||
border-color: var(--border-color);
|
||||
background-color: var(--background-color);
|
||||
|
||||
&.rose-badge-outline {
|
||||
--border-color: var(--ui-gray-starker-1);
|
||||
}
|
||||
|
||||
&.rose-badge-dark {
|
||||
--color: var(--ui-gray-subtler-6);
|
||||
--border-color: var(--ui-gray-starker-1);
|
||||
--background-color: var(--ui-gray-starker-1);
|
||||
}
|
||||
|
||||
&.rose-badge-active {
|
||||
--color: var(--info);
|
||||
}
|
||||
|
||||
&.rose-badge-informational {
|
||||
--color: var(--info-starker-1);
|
||||
--border-color: var(--info-subtler-2);
|
||||
--background-color: var(--info-subtler-2);
|
||||
}
|
||||
|
||||
&.rose-badge-informational-outline {
|
||||
--color: var(--info-starker-1);
|
||||
--border-color: var(--info-starker-1);
|
||||
}
|
||||
|
||||
&.rose-badge-alert {
|
||||
--color: var(--alert-starker-1);
|
||||
--background-color: var(--alert-subtler-1);
|
||||
}
|
||||
|
||||
&.rose-badge-alert-outline {
|
||||
--color: var(--alert-starker-1);
|
||||
--border-color: var(--alert-starker-1);
|
||||
}
|
||||
|
||||
&.rose-badge-error {
|
||||
--color: var(--failure-starker-1);
|
||||
--background-color: var(--failure-subtler-1);
|
||||
}
|
||||
|
||||
&.rose-badge-error-outline {
|
||||
--color: var(--failure-starker-1);
|
||||
--border-color: var(--failure-starker-1);
|
||||
}
|
||||
|
||||
&.rose-badge-success {
|
||||
--color: var(--success-starker-1);
|
||||
--background-color: var(--success-subtler-1);
|
||||
}
|
||||
|
||||
&.rose-badge-success-outline {
|
||||
--color: var(--success-starker-1);
|
||||
--border-color: var(--success-starker-1);
|
||||
}
|
||||
|
||||
&.rose-badge-warning {
|
||||
--color: var(--warning-starker-1);
|
||||
--background-color: var(--warning-subtler-1);
|
||||
}
|
||||
|
||||
&.rose-badge-warning-outline {
|
||||
--color: var(--warning-starker-1);
|
||||
--border-color: var(--warning-starker-1);
|
||||
}
|
||||
}
|
||||
@@ -13,3 +13,4 @@
|
||||
@import 'table';
|
||||
@import 'message';
|
||||
@import 'link-button';
|
||||
@import 'badge';
|
||||
@@ -0,0 +1,14 @@
|
||||
<span ...attributes
|
||||
class="rose-badge {{if @style (concat "rose-badge-" @style)}}"
|
||||
>
|
||||
{{#if @icon}}
|
||||
<Rose::Icon
|
||||
@name={{@icon}}
|
||||
@size="medium"
|
||||
/>
|
||||
{{/if}}
|
||||
|
||||
<span class="rose-badge-body">
|
||||
{{yield}}
|
||||
</span>
|
||||
</span>
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
</summary>
|
||||
|
||||
<div class="rose-dropdown-content">
|
||||
<div class="rose-dropdown-content" {{on-click-inside this.close}}>
|
||||
{{yield (hash
|
||||
link=(component "link-to" class="rose-dropdown-link")
|
||||
button=(component "rose/button" style="dropdown")
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'rose/components/rose/badge';
|
||||
@@ -1 +1 @@
|
||||
export { default } from 'rose/components/rose/dropdown';
|
||||
export { default } from 'rose/components/rose/dropdown';
|
||||
@@ -1 +1 @@
|
||||
export { default } from 'rose/components/rose/layout/sidebar';
|
||||
export { default } from 'rose/components/rose/layout/sidebar';
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from 'rose/modifiers/on-click-inside';
|
||||
@@ -1,9 +1,21 @@
|
||||
<Rose::LinkButton @route="index" @style="primary">Primary</Rose::LinkButton>
|
||||
<Rose::LinkButton @route="index" @style="secondary">Secondary</Rose::LinkButton>
|
||||
<Rose::LinkButton @route="index" @style="warning">Warning</Rose::LinkButton>
|
||||
<Rose::LinkButton @route="index" @style="ghost">Ghost</Rose::LinkButton>
|
||||
<br />
|
||||
<Rose::Badge>Default</Rose::Badge>
|
||||
<Rose::Badge @style="outline">Default Outline</Rose::Badge>
|
||||
<Rose::Badge @icon="user-organization">Default with Icon</Rose::Badge>
|
||||
|
||||
<Rose::LinkButton @route="index" @style="primary" @iconLeft="help-circle-outline">Left Icon</Rose::LinkButton>
|
||||
<Rose::LinkButton @route="index" @style="primary" @iconRight="help-circle-outline">Right Icon</Rose::LinkButton>
|
||||
<Rose::LinkButton @route="index" @style="primary" @iconOnly="help-circle-outline" />
|
||||
<Rose::Badge @style="light">Light</Rose::Badge>
|
||||
<Rose::Badge @style="dark">Dark</Rose::Badge>
|
||||
|
||||
<Rose::Badge @style="informational">Informational</Rose::Badge>
|
||||
<Rose::Badge @style="informational-outline">Informational Outline</Rose::Badge>
|
||||
|
||||
<Rose::Badge @style="alert">Alert</Rose::Badge>
|
||||
<Rose::Badge @style="alert-outline">Alert Outline</Rose::Badge>
|
||||
|
||||
<Rose::Badge @style="error">Error</Rose::Badge>
|
||||
<Rose::Badge @style="error-outline">Error Outline</Rose::Badge>
|
||||
|
||||
<Rose::Badge @style="success">Success</Rose::Badge>
|
||||
<Rose::Badge @style="success-outline">Success Outline</Rose::Badge>
|
||||
|
||||
<Rose::Badge @style="warning">Warning</Rose::Badge>
|
||||
<Rose::Badge @style="warning-outline">Warning Outline</Rose::Badge>
|
||||
@@ -0,0 +1,49 @@
|
||||
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/badge', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders', async function (assert) {
|
||||
await render(hbs`<Rose::Badge />`);
|
||||
assert.ok(find('.rose-badge'));
|
||||
});
|
||||
|
||||
test('it renders with content', async function (assert) {
|
||||
await render(hbs`<Rose::Badge>host-catalog-1</Rose::Badge>`);
|
||||
assert.equal(find('.rose-badge').textContent.trim(), 'host-catalog-1');
|
||||
});
|
||||
|
||||
test('it renders an icon using @icon', async function (assert) {
|
||||
await render(hbs`<Rose::Badge @icon="chevron-right" />`);
|
||||
assert.ok(find('.rose-icon'));
|
||||
});
|
||||
|
||||
test('it styles content using @style', async function (assert) {
|
||||
let styles = [
|
||||
'outline',
|
||||
'dark',
|
||||
'informational',
|
||||
'informational-outline',
|
||||
'alert',
|
||||
'alert-outline',
|
||||
'warning',
|
||||
'warning-outline',
|
||||
'error',
|
||||
'error-outline',
|
||||
'success',
|
||||
'success-outline',
|
||||
'warning',
|
||||
'warning-outline',
|
||||
];
|
||||
|
||||
await render(hbs`<Rose::Badge @style={{this.style}} />`);
|
||||
|
||||
styles.forEach((style) => {
|
||||
this.set('style', style);
|
||||
assert.ok(find(`.rose-badge-${style}`), `defines style: ${style}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -12,19 +12,14 @@ module('Integration | Component | rose/dropdown', function (hooks) {
|
||||
});
|
||||
|
||||
test('it renders with html attributes', async function (assert) {
|
||||
await render(
|
||||
hbs`<Rose::Dropdown id="custom-id" class="custom-class"/>`
|
||||
);
|
||||
await render(hbs`<Rose::Dropdown id="custom-id" class="custom-class"/>`);
|
||||
assert.ok(find('#custom-id'));
|
||||
assert.ok(find('.custom-class'));
|
||||
});
|
||||
|
||||
test('it renders with trigger', async function (assert) {
|
||||
await render(hbs`<Rose::Dropdown @text="Click me" />`);
|
||||
assert.equal(
|
||||
find('.rose-dropdown-trigger').textContent.trim(),
|
||||
'Click me'
|
||||
);
|
||||
assert.equal(find('.rose-dropdown-trigger').textContent.trim(), 'Click me');
|
||||
});
|
||||
|
||||
test('it supports an icon', async function (assert) {
|
||||
@@ -72,4 +67,17 @@ module('Integration | Component | rose/dropdown', function (hooks) {
|
||||
await click('#wrapper');
|
||||
assert.notOk(find('#dropdown').open);
|
||||
});
|
||||
|
||||
test('it is closed when inside content is clicked', async function (assert) {
|
||||
await render(hbs`
|
||||
<Rose::Dropdown as |dropdown|>
|
||||
<dropdown.button>Button</dropdown.button>
|
||||
</Rose::Dropdown>
|
||||
`);
|
||||
|
||||
await click('summary');
|
||||
assert.ok(find('.rose-dropdown').open);
|
||||
await click('button');
|
||||
assert.notOk(find('.rose-dropdown').open);
|
||||
});
|
||||
});
|
||||
@@ -3,7 +3,7 @@ import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, find } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
module('Integration | Component | rose/layout/sidebar', function(hooks) {
|
||||
module('Integration | Component | rose/layout/sidebar', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it renders', async function (assert) {
|
||||
|
||||
@@ -19,7 +19,9 @@ module('Integration | Component | rose/link-button', function (hooks) {
|
||||
});
|
||||
|
||||
test('it renders with content', async function (assert) {
|
||||
await render(hbs`<Rose::LinkButton @route="index">Link button content</Rose::LinkButton>`);
|
||||
await render(
|
||||
hbs`<Rose::LinkButton @route="index">Link button content</Rose::LinkButton>`
|
||||
);
|
||||
assert.ok(
|
||||
find('.rose-link-button').textContent.trim(),
|
||||
'Link button content'
|
||||
@@ -32,19 +34,25 @@ module('Integration | Component | rose/link-button', function (hooks) {
|
||||
});
|
||||
|
||||
test('it supports left icon with @iconLeft', async function (assert) {
|
||||
await render(hbs`<Rose::LinkButton @route="index" @iconLeft="chevron-left" />`);
|
||||
await render(
|
||||
hbs`<Rose::LinkButton @route="index" @iconLeft="chevron-left" />`
|
||||
);
|
||||
assert.ok(find('.rose-icon'));
|
||||
assert.ok(find('.has-icon-left'));
|
||||
});
|
||||
|
||||
test('it supports left icon with @iconRight', async function (assert) {
|
||||
await render(hbs`<Rose::LinkButton @route="index" @iconRight="chevron-right" />`);
|
||||
await render(
|
||||
hbs`<Rose::LinkButton @route="index" @iconRight="chevron-right" />`
|
||||
);
|
||||
assert.ok(find('.rose-icon'));
|
||||
assert.ok(find('.has-icon-right'));
|
||||
});
|
||||
|
||||
test('it supports only icon with @iconOnly', async function (assert) {
|
||||
await render(hbs`<Rose::LinkButton @route="index" @iconOnly="help-circle-outline" />`);
|
||||
await render(
|
||||
hbs`<Rose::LinkButton @route="index" @iconOnly="help-circle-outline" />`
|
||||
);
|
||||
assert.ok(find('.rose-icon'));
|
||||
assert.ok(find('.has-icon-only'));
|
||||
});
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import { render, click } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
|
||||
module('Integration | Modifier | on-click-inside', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('it fires event when inside is clicked', async function (assert) {
|
||||
assert.expect(2);
|
||||
this.set('clickedInside', (element) => {
|
||||
assert.ok(element);
|
||||
assert.equal(element.id, 'inside');
|
||||
});
|
||||
await render(hbs`
|
||||
<div id="outside"></div>
|
||||
<div id="inside" {{on-click-inside this.clickedInside}}>
|
||||
<div id="item" />
|
||||
</div>
|
||||
`);
|
||||
await click('#item');
|
||||
});
|
||||
|
||||
test('it does not fire event when outside is clicked', async function (assert) {
|
||||
assert.expect(0);
|
||||
this.set('clickedInside', () => {
|
||||
assert.ok(true);
|
||||
});
|
||||
await render(hbs`
|
||||
<div id="outside"></div>
|
||||
<div id="inside" {{on-click-inside this.clickedInside}}>
|
||||
<div id="item" />
|
||||
</div>
|
||||
`);
|
||||
await click('#outside');
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user