mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-10-30 18:17:55 +00:00
UI/StatText Component (#12295)
* creates stattext component * creates .scss file * creates storybook * fixes typo * fixes readme * adds changelog * finishes tests
This commit is contained in:
3
changelog/12295.txt
Normal file
3
changelog/12295.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
```release-note:feature
|
||||||
|
ui: Creates new StatText component
|
||||||
|
```
|
||||||
27
ui/README.md
27
ui/README.md
@@ -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]`
|
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).
|
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.
|
See the [Storybook Docs](https://storybook.js.org/docs/basics/introduction/) for more information on writing stories.
|
||||||
|
|
||||||
|
|||||||
101
ui/app/styles/components/stat-text.scss
Normal file
101
ui/app/styles/components/stat-text.scss
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
.stat-text-container {
|
||||||
|
line-height: normal;
|
||||||
|
|
||||||
|
&.l,
|
||||||
|
&.m {
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -101,6 +101,7 @@
|
|||||||
@import './components/shamir-progress';
|
@import './components/shamir-progress';
|
||||||
@import './components/sidebar';
|
@import './components/sidebar';
|
||||||
@import './components/splash-page';
|
@import './components/splash-page';
|
||||||
|
@import './components/stat-text';
|
||||||
@import './components/status-menu';
|
@import './components/status-menu';
|
||||||
@import './components/tabs';
|
@import './components/tabs';
|
||||||
@import './components/text-file';
|
@import './components/text-file';
|
||||||
|
|||||||
@@ -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-monospace: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
|
||||||
$family-primary: $family-sans;
|
$family-primary: $family-sans;
|
||||||
$body-size: 14px;
|
$body-size: 14px;
|
||||||
$size-3: (24/14) + 0rem;
|
$size-3: (24/14) + 0rem; // ~1.714rem
|
||||||
$size-7: (13/14) + 0rem;
|
$size-5: 1.25rem;
|
||||||
$size-8: (12/14) + 0rem;
|
$size-7: (13/14) + 0rem; // ~.929rem
|
||||||
|
$size-8: (12/14) + 0rem; // ~.857rem
|
||||||
$size-9: 0.75rem;
|
$size-9: 0.75rem;
|
||||||
$size-10: 0.5rem;
|
$size-10: 0.5rem;
|
||||||
$size-11: 0.25rem;
|
$size-11: 0.25rem;
|
||||||
|
|||||||
21
ui/lib/core/addon/components/stat-text.js
Normal file
21
ui/lib/core/addon/components/stat-text.js
Normal file
@@ -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
ui/lib/core/addon/templates/components/stat-text.hbs
Normal file
7
ui/lib/core/addon/templates/components/stat-text.hbs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<div class={{concat "stat-text-container " @size (unless @subText "-no-subText")}} data-test-stat-text-container>
|
||||||
|
<div class="stat-label">{{@label}}</div>
|
||||||
|
{{#if @subText}}
|
||||||
|
<div class="stat-text">{{@subText}}</div>
|
||||||
|
{{/if}}
|
||||||
|
<div class="stat-value">{{@value}}</div>
|
||||||
|
</div>
|
||||||
1
ui/lib/core/app/components/stat-text.js
Normal file
1
ui/lib/core/app/components/stat-text.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export { default } from 'core/components/stat-text';
|
||||||
26
ui/lib/core/stories/stat-text.md
Normal file
26
ui/lib/core/stories/stat-text.md
Normal file
@@ -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
ui/lib/core/stories/stat-text.stories.js
Normal file
28
ui/lib/core/stories/stat-text.stories.js
Normal file
@@ -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 }
|
||||||
|
);
|
||||||
29
ui/tests/integration/components/stat-text-test.js
Normal file
29
ui/tests/integration/components/stat-text-test.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
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) {
|
||||||
|
await render(hbs`<StatText />`);
|
||||||
|
|
||||||
|
assert.dom('[data-test-stat-text-container]').exists('renders element');
|
||||||
|
});
|
||||||
|
|
||||||
|
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');
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user