Skip to content

Commit

Permalink
feat(chip): add odsChipRemoval event
Browse files Browse the repository at this point in the history
  • Loading branch information
Leotheluck authored and dpellier committed Dec 8, 2023
1 parent 3816ddc commit 5c82f10
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { EventEmitter } from '@stencil/core';

interface OdsChipEvent {
odsChipRemoval: EventEmitter<void>;
}

export type {
OdsChipEvent,
};
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,55 @@ describe('spec:osds-chip', () => {
});
});

describe('events', () => {
it('should have an odsChipRemoval event', async() => {
await setup();
expect(instance.odsChipRemoval).toBeTruthy();
});

it('should call onRemoval on Enter or Space key press', async () => {
await setup();
const mockEventEnter = new KeyboardEvent('keydown', { key: 'Enter' });
const mockEventSpace = new KeyboardEvent('keydown', { key: ' ' });

jest.spyOn(instance, 'onRemoval');

root?.dispatchEvent(mockEventEnter);
expect(instance.onRemoval).toHaveBeenCalledTimes(1);

root?.dispatchEvent(mockEventSpace);
expect(instance.onRemoval).toHaveBeenCalledTimes(2);
});


it('should not emit odsChipRemoval event when not removable', async () => {
await setup({ attributes: { removable: false } });

jest.spyOn(instance.odsChipRemoval, 'emit');

instance.emitRemoval();
expect(instance.odsChipRemoval.emit).not.toHaveBeenCalled();
});

it('should emit odsChipRemoval event when removable', async () => {
await setup({ attributes: { removable: true } });

jest.spyOn(instance.odsChipRemoval, 'emit');

instance.emitRemoval();
expect(instance.odsChipRemoval.emit).toHaveBeenCalled();
});

it('should render correctly based on removable and selectable props', async () => {
await setup({ attributes: { removable: true, selectable: false } });
expect(root).toMatchSnapshot();

await setup({ attributes: { removable: false, selectable: true } });
expect(root).toMatchSnapshot();
});

});

describe('controller', () => {
it('should call controller.validateAttributes', async() => {
await setup();
Expand Down
40 changes: 29 additions & 11 deletions packages/components/chip/src/components/osds-chip/osds-chip.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
import type { ODS_CHIP_SIZE } from './constants/chip-size';
import type { ODS_CHIP_VARIANT } from './constants/chip-variant';
import type { OdsChipAttribute } from './interfaces/attributes';

import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming';
import type { OdsChipEvent } from './interfaces/events';
import type { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming';
import type { EventEmitter } from '@stencil/core';
import { ODS_ICON_NAME, ODS_ICON_SIZE } from '@ovhcloud/ods-component-icon';
import { Component, Element, Host, Prop, h } from '@stencil/core';


import { Component, Element, Event, Host, Listen, Prop, h } from '@stencil/core';
import { DEFAULT_ATTRIBUTE } from './constants/default-attributes';
import { OdsChipController } from './core/controller';


/**
* @slot (unnamed) - Chip content
*/
@Component({
tag: 'osds-chip',
styleUrl: 'osds-chip.scss',
shadow: true,
styleUrl: 'osds-chip.scss',
tag: 'osds-chip',
})
export class OsdsChip implements OdsChipAttribute {
export class OsdsChip implements OdsChipAttribute, OdsChipEvent {
controller: OdsChipController = new OdsChipController(this);
@Element() el!: HTMLElement;

Expand Down Expand Up @@ -47,6 +45,17 @@ export class OsdsChip implements OdsChipAttribute {
/** @see OdsChipAttributes.variant */
@Prop({ reflect: true }) public variant?: ODS_CHIP_VARIANT = DEFAULT_ATTRIBUTE.variant;

/** @see OdsChipEvents.odsChipRemoval */
@Event() odsChipRemoval!: EventEmitter<void>;

@Listen('keydown', { capture: true })
handleKeyDown(event: KeyboardEvent): void {
const { key } = event;
if (key === 'Enter' || key === ' ') {
this.onRemoval();
}
}

/**
* @see OdsChipBehavior.beforeRender
*/
Expand All @@ -58,7 +67,15 @@ export class OsdsChip implements OdsChipAttribute {
this.beforeRender();
}

render() {
emitRemoval(): void {
this.removable && this.odsChipRemoval.emit();
}

onRemoval(): void {
this.emitRemoval();
}

render(): JSX.Element {
const { color, contrasted, removable, selectable } = this;
const isSelectable = selectable || removable;

Expand All @@ -71,7 +88,8 @@ export class OsdsChip implements OdsChipAttribute {
? <osds-icon color={color}
contrasted={contrasted}
name={ODS_ICON_NAME.CLOSE}
size={ODS_ICON_SIZE.xxs}>
size={ODS_ICON_SIZE.xxs}
onClick={(): void => this.onRemoval()}>
</osds-icon> : ''
}
</span>
Expand Down

0 comments on commit 5c82f10

Please sign in to comment.