Skip to content

Commit

Permalink
feat(action-group): new component (#1308)
Browse files Browse the repository at this point in the history
* feat(action-group): new component

* update file

* story & ui tests

* ui tests snapshot

* unitest

* Unit tests for action group

* update unitest

Co-authored-by: yonatankra <yonatan.kra@vonage.com>
  • Loading branch information
rachelbt and YonatanKra committed Jun 8, 2022
1 parent e6d8829 commit 27cada0
Show file tree
Hide file tree
Showing 11 changed files with 393 additions and 0 deletions.
12 changes: 12 additions & 0 deletions __snapshots__/Action-Group.md
@@ -0,0 +1,12 @@
# `Action-Group`

#### `should internal contents`

```html
<div class="vwc-action-group">
<slot>
</slot>
</div>

```

42 changes: 42 additions & 0 deletions components/action-group/package.json
@@ -0,0 +1,42 @@
{
"name": "@vonage/vwc-action-group",
"version": "2.30.3",
"description": "action-group component",
"homepage": "https://github.com/Vonage/vivid/tree/master/components/action-group#readme",
"license": "ISC",
"main": "vwc-action-group.js",
"module": "vwc-action-group.js",
"files": [
"src",
"*.js",
"*.ts",
"*.map"
],
"repository": {
"type": "git",
"url": "https://github.com/vonage/vivid.git",
"directory": "components/action-group"
},
"scripts": {
"test": "echo \"Error: run tests from root\" && exit 1",
"build:typescript": "tsc -b",
"build:styles": "umbrella-style-modules",
"build": "yarn run build:styles && yarn run build:typescript"
},
"bugs": {
"url": "https://github.com/Vonage/vivid/issues"
},
"dependencies": {
"@vonage/vvd-core": "2.31.0",
"@vonage/vvd-foundation": "2.31.0",
"lit-element": "^2.4.0",
"tslib": "^2.3.0"
},
"devDependencies": {
"@vonage/vvd-design-tokens": "2.31.0",
"@vonage/vvd-typography": "2.31.0",
"@vonage/vvd-umbrella": "2.31.0",
"lit-html": "^1.3.0",
"typescript": "^4.3.2"
}
}
44 changes: 44 additions & 0 deletions components/action-group/src/vwc-action-group-base.ts
@@ -0,0 +1,44 @@
import {
html, LitElement, property, TemplateResult
} from 'lit-element';
import { classMap } from 'lit-html/directives/class-map.js';
import type { ClassInfo } from 'lit-html/directives/class-map.js';
import type { Shape, Layout } from '@vonage/vvd-foundation/constants.js';

type ActionGroupLayout = Extract<
Layout,
Layout.Outlined | Layout.Ghost
>;

type ActionGroupShape = Extract<Shape, Shape.Rounded | Shape.Pill>;


/**
* @slot - This is a default/unnamed slot to assign text content. *deprecated* please use _text_ property instead
*/
export class VWCActionGroupBase extends LitElement {
@property({ type: String, reflect: true })
shape?: ActionGroupShape;

@property({ type: String, reflect: true })
layout?: ActionGroupLayout;

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

protected getRenderClasses(): ClassInfo {
return {
[`shape-${this.shape}`]: !!this.shape,
[`layout-${this.layout}`]: !!this.layout,
['tight']: !!this.tight,
};
}

protected override render(): TemplateResult {
return html`
<div class="vwc-action-group ${classMap(this.getRenderClasses())}">
<slot>
</slot>
</div>`;
}
}
54 changes: 54 additions & 0 deletions components/action-group/src/vwc-action-group.scss
@@ -0,0 +1,54 @@
@use '@vonage/vvd-design-tokens/build/scss/semantic-variables/scheme-variables' as scheme-variables;

@use '@vonage/vvd-foundation/scss/mixins/layout/config' as layout-config with (
$layout-set: outlined ghost,
$default: ghost,
);
@use '@vonage/vvd-foundation/scss/mixins/layout' as layout;


.vwc-action-group {
@include layout.layout;

display: inline-flex;
box-sizing: border-box;
align-items: center;
color: var(#{scheme-variables.$vvd-color-on-canvas});
vertical-align: middle;

/* Shape */
&:not(.shape-pill) {
border-radius: 6px;
}

&.shape-pill {
border-radius: 24px;
}
/* Appearance */
&.layout-outlined {
position: relative;
background-color: var(#{scheme-variables.$vvd-color-canvas});
&::before {
position: absolute;
z-index: 1;
border-radius: inherit;
box-shadow: inset 0 0 0 1px var(#{scheme-variables.$vvd-color-neutral-50});
content: '';
inset: 0;
pointer-events: none;
}
}

/* Tight */
&:not(.tight) {
padding: 4px;
column-gap: 4px;
}
}

::slotted([role='separator']) {
width: 1px;
align-self: stretch;
background-color: var(#{scheme-variables.$vvd-color-neutral-30});
margin-block: 4px;
}
20 changes: 20 additions & 0 deletions components/action-group/src/vwc-action-group.ts
@@ -0,0 +1,20 @@
import '@vonage/vvd-core';
import { customElement } from 'lit-element';

import { VWCActionGroupBase } from './vwc-action-group-base.js';
import { style } from './vwc-action-group.css.js';

/**
* Represents an action-group custom element.
*/

@customElement('vwc-action-group')
export class VWCActionGroup extends VWCActionGroupBase {
static override styles = style;
}

declare global {
interface HTMLElementTagNameMap {
'vwc-action-group': VWCActionGroup;
}
}
77 changes: 77 additions & 0 deletions components/action-group/stories/action-group.stories.js
@@ -0,0 +1,77 @@
import '@vonage/vwc-action-group/vwc-action-group.js';
import { html } from 'lit-element';
import { spread } from '@open-wc/lit-helpers';
import { argTypes } from './arg-types.js';

export default {
title: 'Alpha/Components/ActionGroup',
component: 'vwc-action-group',
argTypes
};

const ActionGroupOutlinedTemplate = args => html`
<vwc-action-group ...=${spread(args)}>
<vwc-button label="copy"></vwc-button>
<vwc-button label="paste"></vwc-button>
<vwc-button label="submit"></vwc-button>
</vwc-action-group>`;

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

const ActionGroupGhostTemplate = args => html`
<vwc-action-group ...=${spread(args)}>
<vwc-button label="copy" layout="filled"></vwc-button>
<vwc-button label="paste" layout="filled"></vwc-button>
<vwc-button label="submit" layout="filled"></vwc-button>
</vwc-action-group>`;

export const Ghost = ActionGroupGhostTemplate.bind({});
Ghost.args = { };

const ActionGroupPillTemplate = args => html`
<vwc-action-group ...=${spread(args)}>
<vwc-button label="copy" shape="pill"></vwc-button>
<vwc-button label="paste" shape="pill"></vwc-button>
<vwc-button label="submit" shape="pill"></vwc-button>
</vwc-action-group>`;

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

const ActionGroupSeparatorTemplate = args => html`
<vwc-text></vwc-text>
<p>Use a <code>&lt;span&gt;</code> tag with <code>role="separator"</code> for adding separator between the action elements</p>
<vwc-action-group ...=${spread(args)}>
<vwc-icon-button icon="reply-line"></vwc-icon-button>
<vwc-icon-button icon="transfer-line"></vwc-icon-button>
<span role="separator"></span>
<vwc-icon-button icon="compose-line"></vwc-icon-button>
<vwc-icon-button icon="crop-line"></vwc-icon-button>
<span role="separator"></span>
<vwc-icon-button icon="copy-2-line"></vwc-icon-button>
<vwc-icon-button icon="save-line"></vwc-icon-button>
</vwc-action-group>`;

export const Separator = ActionGroupSeparatorTemplate.bind({});
Separator.args = { layout: 'outlined' };

const ActionGroupTightTemplate = args => html`
<div style="display: flex; column-gap: 2px">
<vwc-action-group ...=${spread(args)}>
<vwc-button icon="flag-uruguay">
<span>+1</span>
<span style="font-size: 14px; margin-left: 8px"><vwc-icon type="chevron-down-solid" inline></vwc-icon></span>
</vwc-button>
<span role="separator"></span>
<vwc-textfield icon="search" dense placeholder="Search" appearance="ghost">
</vwc-textfield>
</vwc-action-group>
<vwc-button label="submit" layout="filled"></vwc-button>
</div>`;

export const tight = ActionGroupTightTemplate.bind({});
tight.args = { layout: 'outlined', tight };



4 changes: 4 additions & 0 deletions components/action-group/stories/arg-types.js
@@ -0,0 +1,4 @@
export const argTypes = {

};

63 changes: 63 additions & 0 deletions components/action-group/test/action-group.test.js
@@ -0,0 +1,63 @@
import '../vwc-action-group.js';
import {
isolatedElementsCreation, textToDomToParent
} from '../../../test/test-helpers.js';
import { chaiDomDiff } from '@open-wc/semantic-dom-diff';
import {VWCActionGroup} from '../vwc-action-group.js';

chai.use(chaiDomDiff);

const COMPONENT_NAME = 'vwc-action-group';

describe ('Action-Group', () => {
let addElement = isolatedElementsCreation();
let element;

beforeEach(async function () {
[element] = (
textToDomToParent(`<${COMPONENT_NAME}>Content</${COMPONENT_NAME}>`)
);
await element.updateComplete;
});

it(`${COMPONENT_NAME} is defined as a custom element`, async () => {
assert.exists(
customElements.get(COMPONENT_NAME)
);
});

it('should internal contents', async () => {
await element.updateComplete;
expect(element.shadowRoot.innerHTML).to.equalSnapshot();
});

describe('basic', () => {
it('should be initialized as a vwc-action-group', async () => {
expect(element instanceof VWCActionGroup).to.equal(true);
});
});

describe('layout', function () {
it('should set the outline class on the base', async function () {
const control = element.shadowRoot?.querySelector('.vwc-action-group');
const layout = 'outlined';
element.layout = layout;
await element.updateComplete;

expect(control?.classList.contains(`layout-${layout}`))
.to.equal(true);
});
});

describe('shape', function () {
it('should set the shape class on the base', async function () {
const control = element.shadowRoot?.querySelector('.vwc-action-group');
const shape = 'pill';
element.shape = shape;
await element.updateComplete;

expect(control?.classList.contains(`shape-${shape}`))
.to.equal(true);
});
});
});
15 changes: 15 additions & 0 deletions components/action-group/tsconfig.json
@@ -0,0 +1,15 @@
{
"extends": "@vonage/vvd-umbrella/configs/tsconfig.json",
"compilerOptions": {
"composite": true,
"rootDir": "src",
"outDir": ".",
"tsBuildInfoFile": ".tsbuildinfo"
},
"include": [
"src/*.ts"
],
"exclude": [
"src/test/*.ts"
]
}
Binary file added ui-tests/snapshots/vwc-action-group.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 27cada0

Please sign in to comment.