Skip to content

Commit

Permalink
Merge pull request #485 from Vonage/viv-200-badge-parity
Browse files Browse the repository at this point in the history
feat(vwc-badge): viv-200 badge volta parity
  • Loading branch information
yinonov authored Dec 13, 2020
2 parents 708d7b9 + adc1c2b commit d313dfa
Show file tree
Hide file tree
Showing 12 changed files with 285 additions and 40 deletions.
3 changes: 3 additions & 0 deletions common/foundation/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,8 @@
},
"dependencies": {
"tslib": "^2.0.3"
},
"devDependencies": {
"@vonage/vvd-design-tokens": "^0.17.0"
}
}
41 changes: 41 additions & 0 deletions common/foundation/scss/mixins/_layout-mixins.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
@use '@vonage/vvd-design-tokens/build/scss/semantic-variables/scheme-variables';
@use '../variable-names/color-semantic-variable-names' as color-semantic;
@use '../functions';

// override to apply relevance
$layouts: filled outlined soft text !default;
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
$allLayouts: (
filled: 'filled',
outlined: 'outlined',
soft: 'soft',
text: 'text',
);

$bg: var(#{color-semantic.$vvd-color-connotation});

%filled {
--background-color: #{$bg};
--color: var(#{color-semantic.$vvd-color-on-connotation});
}

%outlined {
--background-color: transparent;
--border: 1px solid #{$bg};
--color: #{$bg};
}

%soft {
--background-color: #{$bg};
--color: var(#{scheme-variables.$vvd-color-on-base});
--opaque: 20;
}

@mixin layout() {
@each $layout in functions.pick($layouts, $allLayouts) {
#{':host([layout="#{$layout}"])'} {
@extend %#{$layout};
}
}
}
8 changes: 8 additions & 0 deletions common/foundation/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,11 @@ export enum Shape {
Rounded = 'rounded',
Pill = 'pill',
}

/* eslint-disable no-shadow */
export enum Layout {
Text = 'text',
Filled = 'filled',
Outlined = 'outlined',
Soft = 'soft',
}
19 changes: 19 additions & 0 deletions common/foundation/src/general-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,22 @@ export function handleAutofocus(targetElement: HTMLElement): void {
targetElement.focus();
}
}

export function handleMultipleDenseProps(
// eslint-disable-next-line
targetElement: any,
changes: Map<string, boolean>
): void {
if (changes.has('dense')) {
if (targetElement.dense && targetElement.enlarged) {
targetElement.enlarged = false;
}
}

if (changes.has('enlarged')) {
if (targetElement.enlarged && targetElement.dense) {
targetElement.removeAttribute('dense');
targetElement.dense = false;
}
}
}
36 changes: 31 additions & 5 deletions components/badge/src/vwc-badge-base.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,42 @@
import { html, LitElement, property, TemplateResult } from 'lit-element';
import { Connotation, Shape } from '@vonage/vvd-foundation/constants';
import { Connotation, Shape, Layout } from '@vonage/vvd-foundation/constants';
import { handleMultipleDenseProps } from '@vonage/vvd-foundation/general-utils';

export class BadgeBase extends LitElement {
@property({ type: Boolean, reflect: true })
translucent = false;
type BadgeConnotation = Extract<
Connotation,
| Connotation.Primary
| Connotation.CTA
| Connotation.Success
| Connotation.Alert
| Connotation.Warning
| Connotation.Info
>;

type BadgeLayout = Extract<
Layout,
Layout.Filled | Layout.Outlined | Layout.Soft
>;

export class BadgeBase extends LitElement {
@property({ type: String, reflect: true })
connotation: Connotation = Connotation.Primary;
connotation: BadgeConnotation = Connotation.Primary;

@property({ type: String, reflect: true })
shape?: Shape;

@property({ type: String, reflect: true })
layout: BadgeLayout = Layout.Filled;

@property({ type: Boolean, reflect: true })
dense = false;

@property({ type: Boolean, reflect: true })
enlarged = false;

protected updated(changes: Map<string, boolean>): void {
handleMultipleDenseProps(this, changes);
}

protected render(): TemplateResult {
return html`<slot></slot>`;
}
Expand Down
46 changes: 36 additions & 10 deletions components/badge/src/vwc-badge.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,66 @@
@use '@vonage/vvd-foundation/scss/mixins/color-connotation-mixins';
@use '@vonage/vvd-foundation/scss/mixins/shape-mixins';
@use '@vonage/vvd-typography/scss/typography';
@use '@vonage/vvd-foundation/scss/mixins/layout-mixins' with (
$layouts: filled outlined soft
);

@include color-connotation-mixins.connotations-context(
':host(#{color-connotation-mixins.$connotation-placeholder})'
);

$vvd-badge-block-size: --vvd-badge-block-size;

:host {
display: inline;
padding: 4px 8px;
display: inline-flex;
align-items: center;
#{$vvd-badge-block-size}: 24px;
height: var(#{$vvd-badge-block-size});
block-size: var(#{$vvd-badge-block-size});
padding: 0 10px;
position: relative;
color: var(#{color-semantic.$vvd-color-on-connotation});
color: var(--color);
@include typography.typography-cat-shorthand('caption-bold');

&::before {
content: '';
z-index: -1;
border-radius: var(--border-radius);
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: var(#{color-semantic.$vvd-color-connotation});
background-color: var(--background-color);
border-radius: var(--border-radius);
border: var(--border);
opacity: calc(var(--opaque) * 0.01);
}
}

:host([translucent]) {
--opaque: 20;
color: var(#{scheme-variables.$vvd-color-on-base});
:host([disabled]) {
color: var(#{scheme-variables.$vvd-color-contrast-dim});

&::before {
--opaque: 100;
background-color: var(#{scheme-variables.$vvd-color-contrast-soft});
}
}

:host([dense]) {
#{$vvd-badge-block-size}: 20px;
padding: 0 8px;
}

:host([enlarged]) {
#{$vvd-badge-block-size}: 28px;
padding: 0 12px;
}

@include shape-mixins.shape(
$shapes: (
rounded: 6px,
pill: 12px,
rounded: 4px,
pill: 14px,
)
);

@include layout-mixins.layout();
27 changes: 22 additions & 5 deletions components/badge/stories/arg-types.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,40 @@
import { Connotation, Shape } from '@vonage/vvd-foundation/constants';
import { Connotation, Shape, Layout } from '@vonage/vvd-foundation/constants';


export const argTypes = {
connotation: {
control: {
type: 'select',
options: Object.values(Connotation),
options: Object.values(Connotation).filter(c => [
Connotation.Primary, Connotation.CTA, Connotation.Success, Connotation.Alert, Connotation.Info, Connotation.Warning
].includes(c)),
}
},
shape: {
control: {
type: 'select',
options: Object.values(Shape),
options: Object.values(Shape)
}
},
translucent: {
layout: {
control: {
type: 'select',
options: Object.values(Layout).filter(l => [
Layout.Filled, Layout.Outlined, Layout.Soft
].includes(l)),
}
},
dense: {
control: {
type: 'inline-radio',
options: { 'true': '', 'false': undefined }
}
},
enlarged: {
control: {
type: 'inline-radio',
options: { 'true': '', 'false': undefined }
}
}
},
styles: { table: { disable: true } },
}
15 changes: 0 additions & 15 deletions components/badge/stories/badge-basic.stories.js

This file was deleted.

30 changes: 30 additions & 0 deletions components/badge/stories/badge.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import '@vonage/vwc-badge/vwc-badge.js';
import { html } from 'lit-element';
import { spread } from '@open-wc/lit-helpers';
import { argTypes } from './arg-types.js';

export default {
title: 'Atoms/Badge',
component: 'vwc-badge',
argTypes
}

const Template = args => html`<vwc-badge ...=${spread(args)}>I'm a badge</vwc-badge>`;

export const Basic = Template.bind({});
Basic.args = { connotation: 'cta', layout: 'filled' };

export const Soft = Template.bind({});
Soft.args = { connotation: 'cta', layout: 'soft' };

export const Outlined = Template.bind({});
Outlined.args = { layout: 'outlined' };

export const PillShape = Template.bind({});
PillShape.args = { layout: 'filled', shape: 'pill' };

export const Dense = Template.bind({});
Dense.args = { layout: 'filled', dense: '' };

export const Enlarged = Template.bind({});
Enlarged.args = { layout: 'filled', enlarged: '' };
67 changes: 67 additions & 0 deletions components/badge/test/badge.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
isolatedElementsCreation,
getTypographyStyle,
} from '../../../test/test-helpers.js';
import { shapeStyles } from '../../../test/style-utils.js';
import { chaiDomDiff } from '@open-wc/semantic-dom-diff';

chai.use(chaiDomDiff);
Expand Down Expand Up @@ -39,4 +40,70 @@ describe('badge', () => {
assertComputedStyle(badge, await getTypographyStyle('caption-bold'));
});
});

describe('sizing', () => {
it('should have normal size by default', async () => {
const addedElements = addElement(
textToDomToParent(`<${VWC_BADGE}>I'm a badge</${VWC_BADGE}>`)
);
const actualElement = addedElements[0];
await waitNextTask();
assertComputedStyle(actualElement, { height: '24px' });
});

it('should have dense size when dense', async () => {
const addedElements = addElement(
textToDomToParent(`<${VWC_BADGE} dense>I'm a badge</${VWC_BADGE}>`)
);
const actualElement = addedElements[0];
await waitNextTask();
assertComputedStyle(actualElement, { height: '20px' });
});

it('should have enlarged size when enlarged', async () => {
const addedElements = addElement(
textToDomToParent(`<${VWC_BADGE} enlarged>I'm a badge</${VWC_BADGE}>`)
);
const actualElement = addedElements[0];
await waitNextTask();
assertComputedStyle(actualElement, { height: '28px' });
});
});

describe('shape', () => {
let actualElement;
beforeEach(async () => {
const addedElements = addElement(
textToDomToParent(
`<${VWC_BADGE} layout="filled">I'm a badge</${VWC_BADGE}>`
)
);
await waitNextTask();
actualElement = addedElements[0];
});

it('should have rounded shape by default', async () => {
assertComputedStyle(
actualElement,
shapeStyles('rounded', 'badge'),
'::before'
);
});

it('should have rounded shape when shape set to rounded', async () => {
actualElement.shape = 'rounded';
await waitNextTask();
assertComputedStyle(
actualElement,
shapeStyles('rounded', 'badge'),
'::before'
);
});

it('should have pill shape when shape set to pill', async () => {
actualElement.shape = 'pill';
await waitNextTask();
assertComputedStyle(actualElement, shapeStyles('pill', 'badge'), '::before');
});
});
});
6 changes: 3 additions & 3 deletions test/style-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ function borderRadiusStyles(expectedRadius) {
};
}

export function shapeStyles(shape) {
export function shapeStyles(shape, element) {
const shapeRadius = {
rounded: 6,
pill: 24,
rounded: element === 'badge' ? 4 : 6,
pill: element === 'badge' ? 14 : 24,
}

return borderRadiusStyles(shapeRadius[shape]);
Expand Down
Loading

0 comments on commit d313dfa

Please sign in to comment.