Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI/StatText Component #12295

Merged
merged 17 commits into from
Aug 16, 2021
Merged
3 changes: 3 additions & 0 deletions changelog/12295.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:feature
ui: Creates new StatText component
```
27 changes: 26 additions & 1 deletion ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,32 @@ Note that placing a param inside brackets (e.g. `[closedLabel=More options]` ind

2. Generate a new story with `ember generate story [name-of-component]`
3. Inside the newly generated `stories` file, add at least one example of the component. If the component should be interactive, enable the [Storybook Knobs addon](https://github.com/storybooks/storybook/tree/master/addons/knobs).
4. Generate the `notes` file for the component with `yarn gen-story-md [name-of-component] [name-of-engine-or-addon]` (e.g. `yarn gen-md alert-banner core`). This will generate markdown documentation of the component and place it at `vault/ui/stories/[name-of-component].md`. If your component is a template-only component, you will need to manually create the markdown file.
4. Generate the `notes` file for the component with `yarn gen-story-md [name-of-component] [name-of-engine-or-addon]` (e.g. `yarn gen-md alert-banner core`). This will generate markdown documentation of the component and place it at `vault/ui/stories/[name-of-component].md`. If your component is a template-only component, you will need to manually create the markdown file. The markdown file will need to be imported in your `[component-name].stories.js` file (e.g. `import notes from './[name-of-component].md'`).
5. The completed `[component-name].stories.js` file should look something like this (with knobs):
````js
import hbs from 'htmlbars-inline-precompile';
import { storiesOf } from '@storybook/ember';
import { text, withKnobs } from '@storybook/addon-knobs';
import notes from './stat-text.md';

storiesOf('MyComponent', module)
.addParameters({ options: { showPanel: true } })
.addDecorator(withKnobs())
.add(
`MyComponent`,
() => ({
template: hbs`
<h5 class="title is-5">My Component</h5>
<MyComponent @param={{param}} @anotherParam={{anotherParam}} />
`,
context: {
param: text('param', 'My parameter'),
anotherParam: boolean('anotherParam', true)
},
}),
{ notes }
);
````

See the [Storybook Docs](https://storybook.js.org/docs/basics/introduction/) for more information on writing stories.

Expand Down
100 changes: 100 additions & 0 deletions ui/app/styles/components/stat-text.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
.stat-text-container {
line-height: normal;

&.l {
> .stat-label {
font-size: $size-5;
font-weight: $font-weight-semibold;
line-height: inherit;
}
.stat-text {
font-size: $size-8;
font-weight: $font-weight-normal;
color: $ui-gray-700;
line-height: inherit;
}
.stat-value {
font-size: $size-3;
font-weight: $font-weight-normal;
margin-top: $spacing-s;
}
}

&.s {
> .stat-label {
font-size: $size-5;
font-weight: $font-weight-semibold;
line-height: inherit;
}
> .stat-text {
font-size: $size-8;
font-weight: $font-weight-normal;
color: $ui-gray-700;
line-height: inherit;
}
> .stat-value {
font-size: $size-5;
font-weight: $font-weight-normal;
margin-top: $spacing-s;
}
}

&.l-no-subText {
> .stat-label {
font-size: $size-5;
font-weight: $font-weight-semibold;
line-height: inherit;
}
.stat-text {
font-size: $size-8;
font-weight: $font-weight-normal;
color: $ui-gray-700;
line-height: inherit;
}
.stat-value {
font-size: $size-3;
font-weight: $font-weight-normal;
margin-top: $spacing-xxs;
}
}

&.m-no-subText {
> .stat-label {
font-size: $size-8;
font-weight: $font-weight-bold;
line-height: inherit;
}
> .stat-text {
font-size: $size-8;
font-weight: $font-weight-normal;
color: $ui-gray-700;
line-height: inherit;
}
> .stat-value {
font-size: $size-5;
font-weight: $font-weight-normal;
margin-top: $spacing-xxs;
}
}

&.s-no-subText {
> .stat-label {
font-size: $size-8;
font-weight: $font-weight-normal;
color: $ui-gray-500;
line-height: inherit;
}
> .stat-text {
font-size: $size-8;
font-weight: $font-weight-normal;
color: $ui-gray-700;
line-height: inherit;
}
> .stat-value {
font-size: $size-8;
font-weight: $font-weight-normal;
color: $ui-gray-800;
line-height: inherit;
}
}
}
1 change: 1 addition & 0 deletions ui/app/styles/core.scss
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
@import './components/shamir-progress';
@import './components/sidebar';
@import './components/splash-page';
@import './components/stat-text';
@import './components/status-menu';
@import './components/tabs';
@import './components/text-file';
Expand Down
7 changes: 4 additions & 3 deletions ui/app/styles/utils/_bulma_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ $family-sans: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto'
$family-monospace: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
$family-primary: $family-sans;
$body-size: 14px;
$size-3: (24/14) + 0rem;
$size-7: (13/14) + 0rem;
$size-8: (12/14) + 0rem;
$size-3: (24/14) + 0rem; // ~1.714rem
$size-5: 1.25rem;
$size-7: (13/14) + 0rem; // ~.929rem
$size-8: (12/14) + 0rem; // ~.857rem
$size-9: 0.75rem;
$size-10: 0.5rem;
$size-11: 0.25rem;
Expand Down
21 changes: 21 additions & 0 deletions ui/lib/core/addon/components/stat-text.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* @module StatText
* StatText components are used to display a label and associated value beneath, with the option to include a description.
*
* @example
* ```js
* <StatText @label="Active Clients" @stat="4,198" @size="l" @subText="These are the active client counts"/>
* ```
* @param {string} label=null - The label for the statistic
* @param {string} value=null - Value passed in, usually a number or statistic
* @param {string} size=null - Sizing changes whether or not there is subtext. If there is subtext 's' and 'l' are valid sizes. If no subtext, then 'm' is also acceptable.
* @param {string} [subText] - SubText is optional and will display below the label
*/

import Component from '@glimmer/component';
import layout from '../templates/components/stat-text';
import { setComponentTemplate } from '@ember/component';

class StatTextComponent extends Component {}

export default setComponentTemplate(layout, StatTextComponent);
7 changes: 7 additions & 0 deletions ui/lib/core/addon/templates/components/stat-text.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<div class={{concat "stat-text-container " @size (unless @subText "-no-subText")}}>
<div class="stat-label">{{@label}}</div>
{{#if @subText}}
<div class="stat-text">{{@subText}}</div>
{{/if}}
<div class="stat-value">{{@value}}</div>
</div>
1 change: 1 addition & 0 deletions ui/lib/core/app/components/stat-text.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from 'core/components/stat-text';
26 changes: 26 additions & 0 deletions ui/lib/core/stories/stat-text.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!--THIS FILE IS AUTO GENERATED. This file is generated from JSDoc comments in lib/core/addon/components/stat-text.js. To make changes, first edit that file and run "yarn gen-story-md stat-text" to re-generate the content.-->

## StatText
StatText components are used to display a label and associated value beneath, with the option to include a description.

**Params**

| Param | Type | Default | Description |
| --- | --- | --- | --- |
| label | <code>string</code> | <code>null</code> | The label for the statistic |
| value | <code>string</code> | <code>null</code> | Value passed in, usually a number or statistic |
| size | <code>string</code> | <code>null</code> | Sizing changes whether or not there is subtext. If there is subtext 's' and 'l' are valid sizes. If no subtext, then 'm' is also acceptable. |
| [subText] | <code>string</code> | | SubText is optional and will display below the label |

**Example**

```js
<StatText @label="Active Clients" @stat="4,198" @size="l" @subText="These are the active client counts"/>
```

**See**

- [Uses of StatText](https://github.com/hashicorp/vault/search?l=Handlebars&q=StatText+OR+stat-text)
- [StatText Source Code](https://github.com/hashicorp/vault/blob/master/ui/lib/core/addon/components/stat-text.js)

---
28 changes: 28 additions & 0 deletions ui/lib/core/stories/stat-text.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import hbs from 'htmlbars-inline-precompile';
import { storiesOf } from '@storybook/ember';
import { text, withKnobs } from '@storybook/addon-knobs';
import notes from './stat-text.md';

storiesOf('StatText', module)
.addParameters({ options: { showPanel: true } })
.addDecorator(withKnobs())
.add(
`StatText`,
() => ({
template: hbs`
<h5 class="title is-5">StatText Component</h5>
<StatText
@label={{label}}
@value={{value}}
@size={{size}}
@subText={{subText}} />
`,
context: {
label: text('label', 'Active Clients'),
value: text('value', '4,198'),
size: text('size', 'l'),
subText: text('subText', 'These are your active clients'),
},
}),
{ notes }
);
32 changes: 32 additions & 0 deletions ui/tests/integration/components/stat-text-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';

module('Integration | Component | StatText', function(hooks) {
setupRenderingTest(hooks);

test('it renders', async function(assert) {
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.set('myAction', function(val) { ... });

await render(hbs`<StatText />`);

assert.equal(this.element.textContent.trim(), '');
});

test('it renders passed in attributes', async function(assert) {
this.set('label', 'A Label');
this.set('value', '9,999');
this.set('size', 'l');
this.set('subText', 'This is my description');

await render(
hbs`<StatText @label={{this.label}} @size={{this.size}} @value={{this.value}} @subText={{this.subText}}/>`
);

assert.dom('.stat-label').hasText(this.label, 'renders label');
assert.dom('.stat-text').hasText(this.subText, 'renders subtext');
assert.dom('.stat-value').hasText(this.value, 'renders value');
});
});