Skip to content

Commit

Permalink
feat(segmented-button): add new beta components (#1495)
Browse files Browse the repository at this point in the history
* feat(chip): init component

* refactor: cleaning up component

* feat: init new chip concept

* feat: adding dismissible and selected functionality's

* feat: adding possibility for icons

* feat: adding unit test and storybook init

* feat: adding accessibility, disabled and removing magic numbers

* refactor: solving linting errors

* fix: naming

* fix: reference error

* fix: reference error

* fix: reference error

* refactor: changing story naming

* feat: init visual tests

* refactor: deleting href test case

* refactor: changing close trigger

* refactor: changing focus outline style

* refactor: updating visual snapshots

* refactor: deleting unneeded props

* feat: adding focus and active state

* feat: adding storybook stories

* fix: not loading project

* feat: adding focus state

* feat: implement new design

* refactor: storybook stories

* feat: add segmented-button

* refactor: changing stories chip label and deleting icon size property

* refactor: changing stories label

* fix: removing unneeded icon size property

* refactor: updating visual snapshots

* test(visual): update snapshots (#1434)

Co-authored-by: marvinLaubenstein <[email protected]>

* fix: solving color problem and transition bug

* refactor: changing label prop to slot

* test(visual): update snapshots (#1436)

Co-authored-by: marvinLaubenstein <[email protected]>

* refactor: changing icon to selected

* fix: add refactoring from separate branch

* test(visual): update snapshots (#1456)

Co-authored-by: felix-ico <[email protected]>

* refactor: renaming segmented-button to segment and segmented-button-g… (#1458)

* refactor: renaming segmented-button to segment and segmented-button-group to segmented-button

* refactor: updating visual snapshots

* refactor: deleting snapshots for better merging

* test(visual): update snapshots (#1457)

Co-authored-by: felix-ico <[email protected]>

* test(visual): update snapshots (#1459)

Co-authored-by: felix-ico <[email protected]>

* test(visual): update snapshots (#1461)

Co-authored-by: felix-ico <[email protected]>

* test(visual): update snapshots (#1462)

Co-authored-by: felix-ico <[email protected]>

* feat: disable deselecting on single-select

* fix: lint

* fix: format

* fix: improve naming

* test: update snapshot

* refactor: introducing new dynamic and persistent structure

* refactor: changing disabled functionality

* refactor: updating storybook stories

* fix: solving loading issues

* refactor: updating visual snapshots

* feat: adding example story for dynamic

* refactor: changing selected icon state setting

* refactor: improving storybook page

* refactor: updating visual snapshots

* fix: merging problem

* fix: solving storybook preview problem

* fix: quickfix

* refactor: removing example story

* refactor: changing minor styling in storybook

* feat: add fullwidth prop

* fix: remove ts-ignore

* feat: add fullwidth prop to story

* fix: format

* fix: missing closing bracket

* fix: style

* fix: format

* test(visual): update snapshots (#1496)

Co-authored-by: felix-ico <[email protected]>

* Feat/chip and segmented button usage text (#1501)

* feat: adding usage text for chip

* feat: adding usage text for segmented button

* feat: adding history text

* refactor: updating segmented button snapshots

* refactor: changing design matters

* fix: solving design notes

* refactor: deleting slitted view / mobile view issues

* refactor: including design feedback

* Refactor/chips segmentedbutton (#1512)

* refactor: changing unselected horizontal padding

* refactor: updating visual snapshots

* feat: add segmented-button (#1429)

* fix: ts, a11y, story

* test(visual): update snapshots (#1497)

Co-authored-by: felix-ico <[email protected]>

* test(visual): update snapshots (#1513)

Co-authored-by: marvinLaubenstein <[email protected]>

* test(visual): update snapshots (#1514)

Co-authored-by: felix-ico <[email protected]>

* fix: solving visual testing fails

* fix: remove unneeded dep, remove unneeded file

* fix: remove wrong deprecation warning

* test: disable segmented button vis test

* test(segmented-button): disable

* test(visual): update snapshots (#1516)

Co-authored-by: nowseemee <[email protected]>

Co-authored-by: Marvin_Laubenstein <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: marvinLaubenstein <[email protected]>
Co-authored-by: felix-ico <[email protected]>
Co-authored-by: Daniel Beck <[email protected]>
Co-authored-by: nowseemee <[email protected]>
  • Loading branch information
7 people authored Jan 25, 2023
1 parent 555d2b5 commit d0e38ab
Show file tree
Hide file tree
Showing 132 changed files with 2,928 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Chip should match snapshot 1`] = `
<scale-chip>
<mock:shadow-root>
<span class="chip chip--type-persistent chip--variant-standard" part="base type-persistent variant-standard" role="switch" tabindex="-1">
<slot name="chip-icon"></slot>
<span class="chip-label">
<slot></slot>
</span>
</span>
</mock:shadow-root>
Label
</scale-chip>
`;
169 changes: 169 additions & 0 deletions packages/components/src/components/chip/chip.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/**
* @license
* Scale https://github.com/telekom/scale
*
* Copyright (c) 2021 Egor Kirpichev and contributors, Deutsche Telekom AG
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

:host {
--font-size: var(--telekom-typography-font-size-body);
--line-height: var(--telekom-typography-line-spacing-standard);
--font-weight: var(--telekom-typography-font-weight-bold);
--color-focus: var(--telekom-color-functional-focus);
--focus-outline: var(--telekom-line-weight-highlight) solid
var(--telekom-color-functional-focus);
--box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.1), 0px 2px 8px rgba(0, 0, 0, 0.1);

/*standard selected*/
--background-standard-selected: var(--telekom-color-ui-extra-strong);
--color-standard-selected: var(
--telekom-color-text-and-icon-inverted-standard
);
}
/**TODO: colors unexplained in figma **/
.chip {
border: var(--telekom-spacing-unit-x025) solid transparent;
display: inline-flex;
outline: none;
padding: 0 var(--telekom-spacing-unit-x3);
text-align: center;
align-items: center;
white-space: nowrap;
border-radius: 1rem;
border-color: rgba(255, 255, 255, 0.14);
height: 32px;
vertical-align: baseline;
justify-content: center;
cursor: default;
color: var(--telekom-color-text-and-icon-standard);
background: var(--telekom-color-text-and-icon-inverted-standard);
border: 1px solid var(--telekom-color-ui-border-standard);
}

.chip:not(.chip--disabled):focus,
.chip.chip--type-dynamic:not(.chip--selected):focus {
outline: var(--telekom-spacing-unit-x05) solid var(--color-focus);
outline-offset: var(--telekom-spacing-unit-x025);
}

.chip:not(.chip--disabled):hover,
.chip.chip--type-dynamic:not(.chip--selected):hover {
background: linear-gradient(
var(--telekom-color-ui-state-fill-hovered),
var(--telekom-color-ui-state-fill-hovered)
),
var(--telekom-color-text-and-icon-inverted-standard);
}

.chip:not(.chip--disabled):active,
.chip.chip--type-dynamic:not(.chip--selected):active {
background: linear-gradient(
var(--telekom-color-ui-state-fill-pressed),
var(--telekom-color-ui-state-fill-pressed)
),
var(--telekom-color-text-and-icon-inverted-standard);
}

.chip--selected {
background: var(--background-standard-selected);
color: var(--color-standard-selected);
}

.chip--selected:not(.chip--disabled):hover {
background: linear-gradient(
var(--telekom-color-ui-state-fill-hovered-inverted),
var(--telekom-color-ui-state-fill-hovered-inverted)
),
var(--background-standard-selected);
}

.chip--selected:not(.chip--disabled):active {
background: linear-gradient(
var(--telekom-color-ui-state-fill-pressed-inverted),
var(--telekom-color-ui-state-fill-pressed-inverted)
),
var(--background-standard-selected);
}

/**
label
**/

.chip-label {
padding: 0 var(--telekom-spacing-unit-x1) 0 var(--telekom-spacing-unit-x1);
font-weight: var(--telekom-typography-font-weight-bold);
font-size: 1rem;
line-height: 100%;
}

.chip--type-dynamic.chip--selected .chip-label,
.chip--selected .chip-label {
padding-right: var(--telekom-spacing-unit-x2);
}

/**
icon front (slot)
**/

.chip slot[name='chip-icon']::slotted(*) {
padding-right: var(--telekom-spacing-unit-x1);
padding-top: var(--telekom-spacing-unit-x1);
}

/**
icon end
*/

/**
disabled
**/
.chip.chip--disabled:not(.chip--type-dynamic) {
color: var(--telekom-color-text-and-icon-disabled);
border: 1px solid var(--telekom-color-ui-border-disabled);
}

.chip--selected:not(.chip--variant-outlined):not(.chip--type-dynamic).chip--disabled {
background: var(--telekom-color-ui-disabled);
color: var(--telekom-color-text-and-icon-disabled);
border: none;
}

.chip--variant-outlined.chip--selected.chip--disabled:not(.chip--type-dynamic) {
background-color: var(--telekom-color-text-and-icon-inverted-standard);
color: var(--telekom-color-text-and-icon-disabled);
border: 1px solid var(--telekom-color-ui-border-disabled);
}

/**
variant outline
**/

.chip.chip--variant-outline.chip--selected {
color: var(--telekom-color-text-and-icon-primary-standard);
background: var(--telekom-color-text-and-icon-inverted-standard);
border: 1px solid var(--telekom-color-text-and-icon-primary-standard);
}

.chip.chip--variant-outline.chip--selected:not(.chip.chip--disabled):hover {
background: linear-gradient(
var(--telekom-color-ui-state-fill-hovered),
var(--telekom-color-ui-state-fill-hovered)
),
var(--telekom-color-text-and-icon-inverted-standard);
color: var(--telekom-color-text-and-icon-primary-hovered);
border: 1px solid var(--telekom-color-text-and-icon-primary-hovered);
}

.chip.chip--variant-outline.chip--selected:not(.chip.chip--disabled):active {
background: linear-gradient(
var(--telekom-color-ui-state-fill-pressed),
var(--telekom-color-ui-state-fill-pressed)
),
var(--telekom-color-text-and-icon-inverted-standard);
color: var(--telekom-color-text-and-icon-primary-pressed);
border: 1px solid var(--telekom-color-text-and-icon-primary-pressed);
}
25 changes: 25 additions & 0 deletions packages/components/src/components/chip/chip.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { newSpecPage } from '@stencil/core/testing';
import { Chip } from './chip';

describe('Chip', () => {
let element;

beforeEach(async () => {
element = new Chip();
});

it('should match snapshot', async () => {
const page = await newSpecPage({
components: [Chip],
html: `<scale-chip>Label</scale-chip>`,
});
expect(page.root).toMatchSnapshot();
});
it('should handle css classes', () => {
element.selected = true;
expect(element.getCssClassMap()).toContain('chip--selected');

element.disabled = true;
expect(element.getCssClassMap()).toContain('chip--disabled');
});
});
171 changes: 171 additions & 0 deletions packages/components/src/components/chip/chip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/**
* @license
* Scale https://github.com/telekom/scale
*
* Copyright (c) 2021 Egor Kirpichev and contributors, Deutsche Telekom AG
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

import {
Component,
Prop,
h,
Host,
Event,
EventEmitter,
Element,
} from '@stencil/core';
import classNames from 'classnames';
import { emitEvent } from '../../utils/utils';
@Component({
tag: 'scale-chip',
styleUrl: './chip.css',
shadow: true,
})
export class Chip {
@Element() hostElement: HTMLElement;
/** (optional) */
@Prop() variant?: 'standard' | 'outline' = 'standard';
/** (optional) */
@Prop() type?: 'dynamic' | 'persistent' = 'persistent';
/** (optional) */
@Prop() selected?: boolean = false;
/** (optional) chip aria-role */
@Prop() ariaRoleTitle?: string = 'switch';
/** (optional) chip aria-checked */
@Prop() ariaCheckedState?: boolean;
/** (optional) chip label */
@Prop() label?: string;
/** (optional) chip disabled */
@Prop() disabled?: boolean = false;
/** (optional) Injected CSS styles */
@Prop() styles?: string;

/** (optional) Change icon click event */
@Event({ eventName: 'scale-change' }) scaleChange: EventEmitter<MouseEvent>;
/** @deprecated in v3 in favor of kebab-case event names */
@Event({ eventName: 'scaleChange' })
scaleChangeLegacy: EventEmitter<MouseEvent>;
/** (optional) Close icon click event */
@Event({ eventName: 'scale-close' }) scaleClose: EventEmitter<MouseEvent>;
/** @deprecated in v3 in favor of kebab-case event names */
@Event({ eventName: 'scaleClose' })
scaleCloseLegacy: EventEmitter<MouseEvent>;

componentDidRender() {
// handle no setted icon size attribute
const defaultIconSize = 24;
const iconSlot = this.hostElement.querySelector(
'[slot="chip-icon"]'
) as HTMLElement;
if (iconSlot !== null) {
if (
iconSlot.children[0].getAttribute('size') === String(defaultIconSize)
) {
iconSlot.children[0].setAttribute('size', String(16));
}
if (this.selected) {
iconSlot.children[0].setAttribute('selected', String(true));
} else {
iconSlot.children[0].setAttribute('selected', String(false));
}
}
}
disconnectedCallback() {}

handleClose = (event: MouseEvent) => {
event.preventDefault();
event.stopPropagation();
if (this.disabled && this.type !== 'dynamic') {
return;
}
emitEvent(this, 'scaleClose', event);
};

handleClick = (event: MouseEvent) => {
if (this.type !== 'dynamic') {
this.selected = !this.selected;
}
event.preventDefault();
event.stopPropagation();
if (this.disabled && this.type !== 'dynamic') {
return;
}
emitEvent(this, 'scaleChange', event);
};

getIcon() {
if (this.type === 'dynamic' && this.selected) {
return (
<scale-icon-action-close
accessibility-title="close"
size={16}
onClick={!this.disabled ? this.handleClose : null}
selected
/>
);
} else if (this.type === 'persistent' && this.selected) {
return (
<scale-icon-action-success
accessibility-title="success"
size={16}
selected
/>
);
} else if (this.type === 'persistent') {
return (
<scale-icon-action-success accessibility-title="success" size={16} />
);
}
}

render() {
return (
<Host>
{this.styles && <style>{this.styles}</style>}
<span
role={this.ariaRoleTitle}
aria-checked={
this.ariaCheckedState ? this.ariaCheckedState : this.selected
}
tabindex={this.selected ? '0' : '-1'}
part={this.getBasePartMap()}
class={this.getCssClassMap()}
onClick={
!this.disabled || this.type === 'dynamic' ? this.handleClick : null
}
>
<slot name="chip-icon"></slot>
<span class="chip-label">
<slot />
</span>
{this.selected ? this.getIcon() : null}
</span>
</Host>
);
}

getBasePartMap() {
return this.getCssOrBasePartMap('basePart');
}

getCssClassMap() {
return this.getCssOrBasePartMap('css');
}

getCssOrBasePartMap(mode: 'basePart' | 'css') {
const component = 'chip';
const prefix = mode === 'basePart' ? '' : `${component}--`;

return classNames(
mode === 'basePart' ? 'base' : component,
!!this.selected && `${prefix}selected`,
!!this.disabled && `${prefix}disabled`,
this.type && `${prefix}type-${this.type}`,
this.variant && `${prefix}variant-${this.variant}`
);
}
}
Loading

0 comments on commit d0e38ab

Please sign in to comment.