Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature(components): add chip component #11

Open
wants to merge 2 commits into
base: redesign
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/images/components/chip/icon-chip-active.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions app/images/components/chip/icon-chip-delete.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions app/images/components/chip/icon-chip-ellipsis-vertical.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/scripts/components/common/_variables.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
$images-path: "../images/components";
110 changes: 110 additions & 0 deletions app/scripts/components/common/chip/chip.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
.chip {
display: inline-block;
padding: 4px 8px;
border: 1px solid #E5E5E5;
border-radius: 16px;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's use rem instead. Also, it will be nice to store these values as a common variables. (for future possible design changes)


font-family: "Roboto-Regular";
font-size: 14px;
line-height: 16px;
color: #8B8B8F;

cursor: pointer;

&:hover {
box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.25);
color: #010101;
}
}

.chip__content {
display: flex;
align-items: center;
}

.chip__buttons {
display: flex;
align-items: center;
}

.chip__icon {
display: flex;
align-items: center;
justify-content: center;
width: 16px;
height: 16px;

&:before {
display: block;
content: '';
width: 8px;
height: 8px;
background-position: center;
background-repeat: no-repeat;
background-size: contain;
}

&.chip__icon_name_drag {
width: 2px;
margin-right: 4px;

&:before {
width: 2px;
background-image: url('#{$images-path}/chip/icon-chip-ellipsis-vertical.svg');
}
}

&.chip__icon_name_active:before {
width: 12px;
background-image: url('#{$images-path}/chip/icon-chip-active.svg');
}
}

.chip__button {
display: flex;
align-items: center;
justify-content: center;
width: 16px;
height: 16px;

&:before {
display: block;
content: '';
width: 12px;
height: 12px;
background-position: center;
background-repeat: no-repeat;
background-size: contain;
}

&.chip__button_action_delete:before {
width: 8px;
height: 8px;
background-image: url('#{$images-path}/chip/icon-chip-delete.svg');
}
}

.chip {
&:not(.chip_state_active) {
.chip__icon_name_active {
display: none;
}
}

&.chip_state_active {
.chip__button_action_delete {
display: none;
}
}

&:not(:hover) {
.chip__icon_name_drag {
visibility: hidden;
}
}
}

.chip__text {
margin-right: 6px;
user-select: none;
}
86 changes: 86 additions & 0 deletions app/scripts/components/common/chip/chip.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import * as React from 'react';

interface IChip {
value: any;
text: string;
active?: boolean;
maxLength?: number;
onChange?: ( state: IChipState ) => any;
onDelete?: ( state: IChipState ) => any;
}

interface IChipState {
text: string;
value: any;
active: boolean;
}

/**
* Chip component
* @param props { IChip } - component properties
* @returns
*/
export function Chip (props: IChip) {
const {
value = null,
text = '',
maxLength = 15,
active = false,
onChange = null,
onDelete = null
} = props;

const chipClassList = ['chip'];

// add a class for applying CSS styles when the chip is active
if (active) {
chipClassList.push('chip_state_active');
}

// trim the "text" if its length is greater than "maxLength"
const chipText = text.length > maxLength ? text.slice(0, maxLength) + '..' : text;

// call the "onChange" function when the chip is clicked
// skip clicks on chip buttons
const handleChange = (event: React.MouseEvent<HTMLElement>) => {
if ( !isButtonElement(event.target as HTMLElement) ) {
onChange && onChange({ text, value, active });
}
};

// call the "onDelete" function when the "delete" button is clicked
const handleDelete = () => {
onDelete && onDelete({ text, value, active });
};

return (
<div
className={ chipClassList.join(' ') }
title={ text }
onClick={ (event) => {
handleChange(event);
} }
>
<div className="chip__content">
<span className="chip__icon chip__icon_name_drag"></span>
<div className="chip__text">{ chipText }</div>
<span className="chip__icon chip__icon_name_active"></span>
<span
className="chip__button chip__button_action_delete"
onClick={ (event) => {
handleDelete();
} }
></span>
</div>
</div>
);
};

/**
* Returns true, if the element is [inside] the chip button element
* @param element { HTMLElement } - an
* @returns boolean;
*/
function isButtonElement (element: HTMLElement): boolean {
return element && !!element.closest('.chip__button');
}
2 changes: 2 additions & 0 deletions app/scripts/components/common/common.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@import "./variables";
@import "./chip/chip.component";