@equinor/eds-core-react
Version:
The React implementation of the Equinor Design System
120 lines (116 loc) • 4.22 kB
JavaScript
import { forwardRef, Children, cloneElement } from 'react';
import styled, { css } from 'styled-components';
import { Icon } from './Icon.js';
import * as Chip_tokens from './Chip.tokens.js';
import { outlineTemplate, bordersTemplate, spacingsTemplate, typographyTemplate } from '@equinor/eds-utils';
import { jsxs, jsx } from 'react/jsx-runtime';
const {
enabled,
error
} = Chip_tokens;
const {
background,
height,
typography,
spacings,
border,
states
} = enabled;
const StyledChips = styled.div.attrs(({
$clickable,
$deletable
}) => ({
tabIndex: $clickable || $deletable ? 0 : null,
role: $clickable ? 'button' : null
})).withConfig({
displayName: "Chip__StyledChips",
componentId: "sc-wzsllq-0"
})(["background:", ";height:", ";width:fit-content;display:grid;grid-gap:8px;grid-auto-flow:column;grid-auto-columns:max-content;align-items:center;svg{fill:", ";}&:focus{outline:none;}&[data-focus-visible-added]:focus{", "}&:focus-visible{", "}", " ", " ", " ", " ", " ", " ", " ", ""], background, height, typography.color, outlineTemplate(states.focus.outline), outlineTemplate(states.focus.outline), bordersTemplate(border), spacingsTemplate(spacings), typographyTemplate(typography), ({
$clickable
}) => $clickable && css(["@media (hover:hover) and (pointer:fine){&:hover{cursor:pointer;color:", ";svg{fill:", ";}}}"], states.hover.typography.color, states.hover.typography.color), ({
$variant,
$clickable
}) => {
switch ($variant) {
case 'active':
return css(["background:", ";"], states.active.background);
case 'error':
return css(["background:", ";color:", ";svg{fill:", ";}", ";@media (hover:hover) and (pointer:fine){&:hover{border-color:", ";color:", ";svg{fill:", ";}}}"], error.background, error.typography.color, error.entities.icon.typography.color, bordersTemplate(error.border), $clickable && error.states.hover.typography.color, $clickable && error.states.hover.typography.color, $clickable && error.states.hover.typography.color);
default:
return '';
}
}, ({
$disabled
}) => $disabled && css(["cursor:not-allowed;background:", ";color:", ";svg{fill:", ";}@media (hover:hover) and (pointer:fine){&:hover{color:", ";cursor:not-allowed;svg{fill:", ";}}}"], background, states.disabled.typography.color, states.disabled.typography.color, states.disabled.typography.color, states.disabled.typography.color), ({
$deletable
}) => $deletable && css(["padding-right:4px;"]), ({
$onlyChild
}) => $onlyChild ? css(["padding-left:8px;"]) : '');
const Chip = /*#__PURE__*/forwardRef(function Chip({
children,
onDelete,
disabled = false,
onClick,
variant = 'default',
...other
}, ref) {
const handleDelete = disabled ? undefined : onDelete;
const handleClick = disabled ? undefined : onClick;
const deletable = handleDelete !== undefined;
const clickable = handleClick !== undefined;
const onlyChild = typeof children === 'string';
const chipProps = {
...other,
ref,
$disabled: disabled,
$deletable: deletable,
$clickable: clickable,
$onlyChild: onlyChild,
$variant: variant
};
const handleKeyPress = event => {
const {
key
} = event;
if (key === 'Enter') {
if (deletable) {
handleDelete(event);
}
// Delete takes precedence, else click action is activated
if (clickable && !deletable) {
handleClick(event);
}
}
};
const resizedChildren = Children.map(children, child => {
// We force size on Icon & Avatar component
if (child.props) {
return /*#__PURE__*/cloneElement(child, {
size: 16,
disabled
});
}
return child;
});
const onDeleteClick = event => {
event.stopPropagation();
if (deletable) {
handleDelete(event);
}
};
return /*#__PURE__*/jsxs(StyledChips, {
...chipProps,
onClick: event => clickable && handleClick(event),
onKeyDown: handleKeyPress,
children: [resizedChildren, onDelete && /*#__PURE__*/jsx(Icon, {
name: "close",
title: "close",
$disabled: disabled,
$variant: variant,
onClick: onDeleteClick,
size: 16
})]
});
});
// Chip.displayName = 'eds-chip'
export { Chip };