From e0454958a1fa3bc63a4f3f4a413bc7cd1c73a4d7 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 2 Nov 2022 10:26:51 -0400 Subject: [PATCH] feat(components): adding @divrags status header component --- libs/components/src/icon/icon.stories.js | 2 +- libs/components/src/index.ts | 2 + .../src/snackbar/_snackbar.theme.scss | 3 +- .../status-header/_status-header.theme.scss | 75 ++++++++++++ .../src/status-header/status-header-base.ts | 42 +++++++ .../src/status-header/status-header-item.scss | 14 +++ .../src/status-header/status-header-item.ts | 26 ++++ .../src/status-header/status-header.scss | 57 +++++++++ .../status-header/status-header.stories.js | 111 ++++++++++++++++++ .../src/status-header/status-header.ts | 19 +++ libs/components/src/tab/tab.stories.js | 9 +- libs/components/webpack.config.js | 3 + 12 files changed, 355 insertions(+), 8 deletions(-) create mode 100644 libs/components/src/status-header/_status-header.theme.scss create mode 100644 libs/components/src/status-header/status-header-base.ts create mode 100644 libs/components/src/status-header/status-header-item.scss create mode 100644 libs/components/src/status-header/status-header-item.ts create mode 100644 libs/components/src/status-header/status-header.scss create mode 100644 libs/components/src/status-header/status-header.stories.js create mode 100644 libs/components/src/status-header/status-header.ts diff --git a/libs/components/src/icon/icon.stories.js b/libs/components/src/icon/icon.stories.js index 417989043..122239c9a 100644 --- a/libs/components/src/icon/icon.stories.js +++ b/libs/components/src/icon/icon.stories.js @@ -127,7 +127,7 @@ export default { size: { options: ['64px', '48px', '24px', '16px'], control: { type: 'select' }, - defaultValue: 'houseboat', + defaultValue: '48px', }, onClick: { action: 'onClick' }, diff --git a/libs/components/src/index.ts b/libs/components/src/index.ts index f3f1ce710..302beefb4 100644 --- a/libs/components/src/index.ts +++ b/libs/components/src/index.ts @@ -24,6 +24,8 @@ export * from './select/select'; export * from './slider/slider'; export * from './slider/slider-range'; export * from './snackbar/snackbar'; +export * from './status-header/status-header'; +export * from './status-header/status-header-item'; export * from './switch/switch'; export * from './tab/tab'; export * from './tab/tab-bar'; diff --git a/libs/components/src/snackbar/_snackbar.theme.scss b/libs/components/src/snackbar/_snackbar.theme.scss index 27541ca6e..f597cb22a 100644 --- a/libs/components/src/snackbar/_snackbar.theme.scss +++ b/libs/components/src/snackbar/_snackbar.theme.scss @@ -3,8 +3,9 @@ @mixin snack-bar-theme($theme) { $accent: map-get($theme, primary); $icon-on-dark: map-get($theme, text-icon-on-dark); + $text-on-dark: map-get($theme, text-primary-on-dark); - --mdc-snackbar-action-color: #{$accent}; + --mdc-snackbar-action-color: #{$text-on-dark}; td-snackbar { td-icon-button { diff --git a/libs/components/src/status-header/_status-header.theme.scss b/libs/components/src/status-header/_status-header.theme.scss new file mode 100644 index 000000000..b24dcf320 --- /dev/null +++ b/libs/components/src/status-header/_status-header.theme.scss @@ -0,0 +1,75 @@ +@mixin theme { + .status-header { + --td-status-header-background: transparent; + --td-status-header-icon-background: var( + --mdc-theme-surface-neutral-highlight-hover + ); + --td-status-header-icon-color: var(--mdc-theme-text-icon-on-background); + --td-status-header-status-color: var(--mdc-theme-on-surface); + + background-color: var(--td-status-header-background); + + .status-header-content { + max-width: inherit; + flex-direction: column; + } + + .status-header-icon { + background-color: var(--td-status-header-icon-background); + color: var(--td-status-header-icon-color); + } + + .status-header-text { + --mdc-theme-primary: var(--mdc-theme-surface-neutral-highlight-hover); + --mdc-theme-on-surface: var(--mdc-theme-text-icon-on-background); + + color: var(--td-status-header-status-color); + } + + .status-header-title-text { + color: var(--mdc-theme-on-surface); + } + + &.active { + --td-status-header-background: var( + --mdc-theme-surface-secondary-highlight + ); + --td-status-header-icon-background: var( + --mdc-theme-surface-secondary-highlight-hover + ); + --td-status-header-icon-color: var(--mdc-theme-secondary); + --td-status-header-status-color: var(--mdc-theme-secondary); + } + + &.caution { + --td-status-header-background: var(--mdc-theme-surface-caution-highlight); + --td-status-header-icon-background: var( + --mdc-theme-surface-caution-highlight-hover + ); + --td-status-header-icon-color: var(--mdc-theme-caution); + --td-status-header-status-color: var(--mdc-theme-caution); + } + + &.error { + --td-status-header-background: var( + --mdc-theme-surface-negative-highlight + ); + --td-status-header-icon-background: var( + --mdc-theme-surface-negative-highlight-hover + ); + --td-status-header-icon-color: var(--mdc-theme-negative); + --td-status-header-status-color: var(--mdc-theme-negative); + } + + &.positive { + --td-status-header-background: var( + --mdc-theme-surface-positive-highlight + ); + --td-status-header-icon-background: var( + --mdc-theme-surface-positive-highlight-hover + ); + --td-status-header-icon-color: var(--mdc-theme-positive); + --td-status-header-status-color: var(--mdc-theme-positive); + } + } +} diff --git a/libs/components/src/status-header/status-header-base.ts b/libs/components/src/status-header/status-header-base.ts new file mode 100644 index 000000000..a98be19f2 --- /dev/null +++ b/libs/components/src/status-header/status-header-base.ts @@ -0,0 +1,42 @@ +import { html, LitElement } from 'lit'; +import { classMap } from 'lit/directives/class-map.js'; +import { property } from 'lit/decorators.js'; + +export class StatusHeaderBase extends LitElement { + @property() state: 'active' | 'positive' | 'caution' | 'error' | 'neutral' = + 'neutral'; + @property({ type: String }) statusText = ''; + @property({ type: String }) statusHelper = ''; + @property({ type: String }) titleText = ''; + + protected override render() { + const classes = { + active: this.state === 'active', + caution: this.state === 'caution', + error: this.state === 'error', + positive: this.state === 'positive', + }; + + return html` +
+
+
${this.titleText}
+ +
+
+
+ +
+
+
${this.statusText}
+
${this.statusHelper}
+
+
+ +
+
+ +
+ `; + } +} diff --git a/libs/components/src/status-header/status-header-item.scss b/libs/components/src/status-header/status-header-item.scss new file mode 100644 index 000000000..9675c535a --- /dev/null +++ b/libs/components/src/status-header/status-header-item.scss @@ -0,0 +1,14 @@ +:host { + --td-status-header-item-width: 178px; + + display: block; + font-family: var(--mdc-typography-body2-font-family); + font-size: var(--mdc-typography-body2-font-size); + font-weight: var(--mdc-typography-body2-font-weight); + line-height: var(--mdc-typography-body2-line-height); +} + +span { + display: inline-block; + width: var(--td-status-header-item-width); +} diff --git a/libs/components/src/status-header/status-header-item.ts b/libs/components/src/status-header/status-header-item.ts new file mode 100644 index 000000000..723dce8a4 --- /dev/null +++ b/libs/components/src/status-header/status-header-item.ts @@ -0,0 +1,26 @@ +import { html, LitElement } from 'lit'; +import { customElement, property } from 'lit/decorators.js'; +import styles from './status-header-item.scss'; + +declare global { + interface HTMLElementTagNameMap { + 'td-status-header-item': CovalentStatusHeaderItem; + } +} + +/** + * Status header item + * + * @slot - This element has a slot + */ +@customElement('td-status-header-item') +export class CovalentStatusHeaderItem extends LitElement { + static override styles = [styles]; + + @property() + label!: string; + + render() { + return html`${this.label} `; + } +} diff --git a/libs/components/src/status-header/status-header.scss b/libs/components/src/status-header/status-header.scss new file mode 100644 index 000000000..0e0cbeada --- /dev/null +++ b/libs/components/src/status-header/status-header.scss @@ -0,0 +1,57 @@ +@use './status-header.theme'; +@include status-header.theme(); + +.status-header-title { + padding: 0 0 16px 16px; + height: fit-content; + display: flex; + justify-content: space-between; + align-items: center; +} + +.status-header-title-text { + font-family: var(--mdc-typography-headline6-font-family); + font-size: var(--mdc-typography-headline6-font-size); + font-weight: var(--mdc-typography-headline6-font-weight); + line-height: var(--mdc-typography-headline6-line-height); +} + +.status-header-text { + font-family: var(--mdc-typography-body2-font-family); + font-size: var(--mdc-typography-body2-font-size); + font-weight: var(--mdc-typography-body2-font-weight); + line-height: var(--mdc-typography-body2-line-height); +} + +.status-header-icon { + --mdc-icon-size: 36px; + + border-radius: 50%; + min-width: 72px; + height: 72px; + display: flex; + justify-content: center; + align-items: center; +} + +.status-header-status { + padding-left: 32px; + padding-bottom: 16px; + display: flex; + flex-direction: row; + align-items: center; +} + +.status-header-text-block { + display: flex; + flex-direction: column; + margin-left: 12px; + margin-right: 56px; + + .status-header-helper { + font-family: var(--mdc-typography-caption-font-family); + font-size: var(--mdc-typography-caption-font-size); + font-weight: var(--mdc-typography-caption-font-weight); + line-height: var(--mdc-typography-caption-line-height); + } +} diff --git a/libs/components/src/status-header/status-header.stories.js b/libs/components/src/status-header/status-header.stories.js new file mode 100644 index 000000000..f0e259996 --- /dev/null +++ b/libs/components/src/status-header/status-header.stories.js @@ -0,0 +1,111 @@ +export default { + title: 'Components/Status Header', + parameters: { + layout: 'fullscreen', + }, + argTypes: { + title: { + control: 'text', + defaultValue: 'Item details', + }, + state: { + options: ['active', 'caution', 'error', 'positive', 'neutral'], + control: { type: 'select' }, + defaultValue: 'neutral', + }, + status: { + control: 'text', + defaultValue: 'Status', + }, + icon: { + control: 'text', + defaultValue: 'Status', + }, + }, +}; + +const renderIcon = (state, icon) => { + if (state === 'active') { + return ``; + } else if (state === 'pending') { + return `loader_dots`; + } else { + return `${icon}`; + } +}; + +const HeaderWithTabs = ({ state = 'neutral', status, title, icon }) => { + return ` + + ${renderIcon(state, icon)} + + + + + 09/30/21 4:38:50 PM + + + 09/30/21 4:38:51 PM + + + linux-x64 + + + 02.18.00.01-1 + + + Yes + + + cs3094-04.labs.teradata.com + + + + + + + + + + `; +}; + +export const Active = HeaderWithTabs.bind({}); +Active.args = { + state: 'active', + status: 'Running', + title: 'Active item details', +}; +export const Caution = HeaderWithTabs.bind({}); +Caution.args = { + state: 'caution', + icon: 'warning', + status: 'Caution', + title: 'Caution item details', +}; +export const Error = HeaderWithTabs.bind({}); +Error.args = { + state: 'error', + icon: 'error', + status: 'Error', + title: 'Error item details', +}; +export const Positive = HeaderWithTabs.bind({}); +Positive.args = { + state: 'positive', + icon: 'done', + status: 'Positive', + title: 'Positive item details', +}; +export const Paused = HeaderWithTabs.bind({}); +Paused.args = { + icon: 'pause', + status: 'Paused', + title: 'Paused item details', +}; +export const Pending = HeaderWithTabs.bind({}); +Pending.args = { + state: 'pending', + status: 'Pending', + title: 'Pending item details', +}; diff --git a/libs/components/src/status-header/status-header.ts b/libs/components/src/status-header/status-header.ts new file mode 100644 index 000000000..b3e8af204 --- /dev/null +++ b/libs/components/src/status-header/status-header.ts @@ -0,0 +1,19 @@ +import { customElement } from 'lit/decorators.js'; +import { StatusHeaderBase } from './status-header-base'; +import styles from './status-header.scss'; + +/** + * Status header + * + * @slot - This element has a slot + */ +@customElement('td-status-header') +export class CovalentStatusHeader extends StatusHeaderBase { + static override styles = [styles]; +} + +declare global { + interface HTMLElementTagNameMap { + 'td-status-header': CovalentStatusHeader; + } +} diff --git a/libs/components/src/tab/tab.stories.js b/libs/components/src/tab/tab.stories.js index e24ef29b7..e474deafa 100644 --- a/libs/components/src/tab/tab.stories.js +++ b/libs/components/src/tab/tab.stories.js @@ -11,14 +11,11 @@ export default { const Template = ({ icon, activeIndex = 0 }) => { return ` - + - + - + `; }; diff --git a/libs/components/webpack.config.js b/libs/components/webpack.config.js index ff33fa5cc..0d4113fa2 100644 --- a/libs/components/webpack.config.js +++ b/libs/components/webpack.config.js @@ -34,6 +34,9 @@ module.exports = { slider: './libs/components/src/slider/slider.ts', sliderRange: './libs/components/src/slider/slider-range.ts', snackBar: './libs/components/src/snackbar/snackbar.ts', + statusHeader: './libs/components/src/status-header/status-header.ts', + statusHeaderItem: + './libs/components/src/status-header/status-header-item.ts', switch: './libs/components/src/switch/switch.ts', tab: './libs/components/src/tab/tab.ts', tabBar: './libs/components/src/tab/tab-bar.ts',