Skip to content

Commit

Permalink
feat(empty-state): adding connotation and design variation (VIV-1378) (
Browse files Browse the repository at this point in the history
  • Loading branch information
rachelbt authored Jul 31, 2024
1 parent 2341122 commit 953db49
Show file tree
Hide file tree
Showing 12 changed files with 230 additions and 8 deletions.
114 changes: 114 additions & 0 deletions libs/components/src/lib/empty-state/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,120 @@ Use the `icon` attribute to set the icon of the empty state.
<vwc-empty-state icon="search-line"></vwc-empty-state>
```

### Connotation

Set the `connotation` attribute to change the empty-state's connotation.
It accepts a subset of predefined values.

- Type: `'accent'` | `'success'` | `'alert'` | `'cta'` | `'information'` | `'warning'`
- Default: `'accent'`

```html preview 300px
<div
style="display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; align-items: flex-start"
>
<vwc-empty-state icon="search-line" headline="Accent connotation">
No results
</vwc-empty-state>
<vwc-empty-state
icon="check-solid"
headline="Success connotation"
connotation="success"
>
No results
</vwc-empty-state>
<vwc-empty-state
icon="error-solid"
headline="Alert connotation"
connotation="alert"
>
No results
</vwc-empty-state>
<vwc-empty-state
icon="sparkles-solid"
headline="Cta connotation"
connotation="cta"
>
No results
</vwc-empty-state>
<vwc-empty-state
icon="envelope-solid"
headline="Information connotation"
connotation="information"
>
No results
</vwc-empty-state>
<vwc-empty-state
icon="warning-solid"
headline="Warning connotation"
connotation="warning"
>
No results
</vwc-empty-state>
</div>
```

### Icon-decoration

Use icon-decoration to change the design of the icon circle.

- Type: `filled` | `outlined`
- Default: `filled`

```html preview 300px
<div
style="display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; align-items: flex-start"
>
<vwc-empty-state
icon-decoration="outlined"
icon="search-line"
headline="Accent connotation"
>
No results
</vwc-empty-state>
<vwc-empty-state
icon-decoration="outlined"
icon="check-solid"
headline="Success connotation"
connotation="success"
>
No results
</vwc-empty-state>
<vwc-empty-state
icon-decoration="outlined"
icon="error-solid"
headline="Alert connotation"
connotation="alert"
>
No results
</vwc-empty-state>
<vwc-empty-state
icon-decoration="outlined"
icon="sparkles-solid"
headline="Cta connotation"
connotation="cta"
>
No results
</vwc-empty-state>
<vwc-empty-state
icon-decoration="outlined"
icon="envelope-solid"
headline="Information connotation"
connotation="information"
>
No results
</vwc-empty-state>
<vwc-empty-state
icon-decoration="outlined"
icon="warning-solid"
headline="Warning connotation"
connotation="warning"
>
No results
</vwc-empty-state>
</div>
```

## Slots

### Default
Expand Down
5 changes: 5 additions & 0 deletions libs/components/src/lib/empty-state/definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import styles from './empty-state.scss?inline';
import { EmptyState } from './empty-state';
import { EmptyStateTemplate as template } from './empty-state.template';

export type {
EmptyStateConnotation,
EmptyStateIconDecoration,
} from './empty-state';

export const emptyStateDefinition =
EmptyState.compose<FoundationElementDefinition>({
baseName: 'empty-state',
Expand Down
44 changes: 40 additions & 4 deletions libs/components/src/lib/empty-state/empty-state.scss
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
@use 'partials/variables' as variables;
@use '../../../../../dist/libs/tokens/scss/tokens.constants' as constants;
@use '../../../../shared/src/lib/sass/mixins/border-radius' as
border-radius-variables;
@use '../../../../shared/src/lib/sass/mixins/connotation/config' with (
$connotations: accent cta success alert warning information announcement,
$shades: firm-all dim faint,
$default: accent
);
@use '../../../../shared/src/lib/sass/mixins/connotation' as connotation;

:host {
display: block;
}

.base {
@include connotation.connotation(empty-state);

#{variables.$empty-state-icon-container}: 120px;
#{variables.$empty-state-icon-background}: var(
#{connotation.get-connotation-token(faint)}
);
#{variables.$empty-state-icon-font-size}: 52px;

display: flex;
box-sizing: border-box;
flex-direction: column;
Expand All @@ -21,21 +36,42 @@
align-items: center;
justify-content: center;
border-radius: #{border-radius-variables.$border-radius-full};
background-color: var(#{constants.$vvd-color-neutral-100});
block-size: 120px;
inline-size: 120px;
background-color: var(#{variables.$empty-state-icon-background});
block-size: var(#{variables.$empty-state-icon-container});
font-size: var(#{variables.$empty-state-icon-font-size});
inline-size: var(#{variables.$empty-state-icon-container});

.icon-decoration-outlined & {
#{variables.$empty-state-icon-background}: transparent;
#{variables.$empty-state-icon-font-size}: 40px;

box-shadow: inset 0 0 0 21px
var(#{connotation.get-connotation-token(faint)});
}

.icon {
color: var(#{connotation.get-connotation-token(firm-all)});

.icon-decoration-outlined & {
padding: 19px;
border: 1px solid var(#{connotation.get-connotation-token(dim)});
border-radius: inherit;
}
}
}

.content {
display: flex;
flex-direction: column;
color: var(#{constants.$vvd-color-canvas-text});
font: var(#{constants.$vvd-typography-base});
gap: 8px;
text-align: center;
}

header {
font: var(#{constants.$vvd-typography-base-bold});
color: var(#{connotation.get-connotation-token(firm-all)});
font: var(#{constants.$vvd-typography-base-extended-bold});
}

.actions {
Expand Down
15 changes: 12 additions & 3 deletions libs/components/src/lib/empty-state/empty-state.template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,17 @@ import { classNames } from '@microsoft/fast-web-utilities';
import { Icon } from '../icon/icon';
import type { EmptyState } from './empty-state';

const getClasses = (x: EmptyState) =>
classNames('base', ['no-actions', x.slottedActionItems?.length === 0]);
const getClasses = ({
connotation,
iconDecoration,
slottedActionItems,
}: EmptyState) =>
classNames(
'base',
[`connotation-${connotation}`, Boolean(connotation)],
[`icon-decoration-${iconDecoration}`, Boolean(iconDecoration)],
['no-actions', slottedActionItems?.length === 0]
);

/**
* The template for the EmptyState component.
Expand All @@ -28,7 +37,7 @@ export const EmptyStateTemplate: (
${when(
(x) => x.icon,
html<EmptyState>`<div class="icon-container">
<${iconTag} class="icon" name="${(x) => x.icon}" size="5"></${iconTag}>
<${iconTag} class="icon" name="${(x) => x.icon}"></${iconTag}>
</div>`
)}
</slot>
Expand Down
43 changes: 43 additions & 0 deletions libs/components/src/lib/empty-state/empty-state.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
import { FoundationElement } from '@microsoft/fast-foundation';
import { attr, observable } from '@microsoft/fast-element';
import type { Connotation, IconDecoration } from '../enums.js';

/**
* Types of empty-state connotation.
*
* @public
*/
export type EmptyStateConnotation = Extract<
Connotation,
| Connotation.Accent
| Connotation.CTA
| Connotation.Success
| Connotation.Alert
| Connotation.Warning
| Connotation.Information
>;

/**
* Types of empty-state IconDecoration
*
* @public
*/
export type EmptyStateIconDecoration = Extract<
IconDecoration,
IconDecoration.Filled | IconDecoration.Outlined
>;

/**
* An empty state element. Used when there is no data to display to the user.
Expand All @@ -11,6 +37,14 @@ import { attr, observable } from '@microsoft/fast-element';
* @slot action-items - Slot to add action items to the empty state
*/
export class EmptyState extends FoundationElement {
/**
* The connotation the empty state should have.
*
* @public
* @remarks
* HTML Attribute: connotation
*/
@attr connotation?: EmptyStateConnotation;
/**
* An optional headline for the empty state.
* @public
Expand All @@ -23,6 +57,15 @@ export class EmptyState extends FoundationElement {
*/
@attr icon?: string;

/**
* option to a new design for the icon circle
*
* @public
* HTML Attribute: icon-decoration
*/
@attr({ attribute: 'icon-decoration' })
iconDecoration?: EmptyStateIconDecoration;

/**
* The action items to display in the empty state.
* @internal
Expand Down
3 changes: 3 additions & 0 deletions libs/components/src/lib/empty-state/partials/variables.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
$empty-state-icon-container: --_empty-state-icon-container;
$empty-state-icon-background: --_empty-state-icon-background;
$empty-state-icon-font-size: --_empty-state-icon-font-size;
2 changes: 1 addition & 1 deletion libs/components/src/lib/empty-state/ui.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ test('should show the component', async ({ page }: { page: Page }) => {
const template =
`<style>
#wrapper {
width: 500px;
width: 800px;
display: grid;
grid-auto-rows: 380px;
grid-template-columns: 1fr;
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions libs/components/src/lib/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ export enum Appearance {
Elevated = 'elevated',
}

/* eslint-disable no-shadow */
export enum IconDecoration {
Filled = 'filled',
Outlined = 'outlined',
}

export enum Size {
UltraCondensed = 'ultra-condensed',
SuperCondensed = 'super-condensed',
Expand Down
6 changes: 6 additions & 0 deletions libs/wrapper-gen/src/generator/globalTypeDefs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,10 @@ export const globalTypeDefs: Record<string, TypeUnion> = {
{ text: "'checkbox'", vuePropType: 'String' },
{ text: "'radio'", vuePropType: 'String' },
],

// Empty-state:
EmptyStateIconDecoration: [
{ text: "'outlined'", vuePropType: 'String' },
{ text: "'filled'", vuePropType: 'String' },
],
};

0 comments on commit 953db49

Please sign in to comment.