UNPKG

@furystack/shades-common-components

Version:

Common UI components for FuryStack Shades

146 lines 6.76 kB
import { Shade, createComponent } from '@furystack/shades'; import { buildTransition, cssVariableTheme } from '../services/css-variable-theme.js'; import { paletteFullColors } from '../services/palette-css-vars.js'; import { Icon } from './icons/icon.js'; import { close } from './icons/icon-definitions.js'; const defaultColors = { main: cssVariableTheme.text.secondary, mainContrast: cssVariableTheme.background.default, light: cssVariableTheme.text.primary, lightContrast: cssVariableTheme.background.default, dark: cssVariableTheme.text.disabled, darkContrast: cssVariableTheme.background.default, }; export const Chip = Shade({ customElementName: 'shade-chip', css: { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: cssVariableTheme.spacing.xs, maxWidth: '100%', fontFamily: cssVariableTheme.typography.fontFamily, fontSize: cssVariableTheme.typography.fontSize.sm, fontWeight: cssVariableTheme.typography.fontWeight.medium, lineHeight: '1', borderRadius: cssVariableTheme.shape.borderRadius.lg, whiteSpace: 'nowrap', verticalAlign: 'middle', boxSizing: 'border-box', userSelect: 'none', transition: buildTransition(['background', cssVariableTheme.transitions.duration.fast, cssVariableTheme.transitions.easing.default], ['box-shadow', cssVariableTheme.transitions.duration.fast, cssVariableTheme.transitions.easing.default], ['color', cssVariableTheme.transitions.duration.fast, cssVariableTheme.transitions.easing.default], ['opacity', cssVariableTheme.transitions.duration.fast, cssVariableTheme.transitions.easing.default]), // Size: medium (default) height: '32px', padding: `0 ${cssVariableTheme.spacing.md}`, '&[data-size="small"]': { height: '24px', padding: `0 ${cssVariableTheme.spacing.sm}`, fontSize: cssVariableTheme.typography.fontSize.xs, }, '&[data-size="large"]': { height: '40px', padding: `0 ${cssVariableTheme.spacing.lg}`, fontSize: cssVariableTheme.typography.fontSize.md, }, // Disabled state '&[data-disabled]': { opacity: cssVariableTheme.action.disabledOpacity, pointerEvents: 'none', }, // Clickable state '&[data-clickable]': { cursor: 'pointer', }, '&[data-clickable]:active:not([data-disabled])': { transform: 'scale(0.96)', }, // ========================================== // FILLED VARIANT (default) // ========================================== '&:not([data-variant])': { background: 'color-mix(in srgb, var(--chip-color-main) 15%, transparent)', color: 'var(--chip-color-main)', }, '&:not([data-variant])[data-clickable]:hover:not([data-disabled])': { background: 'color-mix(in srgb, var(--chip-color-main) 25%, transparent)', }, '&[data-variant="filled"]': { background: 'color-mix(in srgb, var(--chip-color-main) 15%, transparent)', color: 'var(--chip-color-main)', }, '&[data-variant="filled"][data-clickable]:hover:not([data-disabled])': { background: 'color-mix(in srgb, var(--chip-color-main) 25%, transparent)', }, // ========================================== // OUTLINED VARIANT // ========================================== '&[data-variant="outlined"]': { background: 'transparent', color: 'var(--chip-color-main)', boxShadow: '0px 0px 0px 1px var(--chip-color-main)', }, '&[data-variant="outlined"][data-clickable]:hover:not([data-disabled])': { background: 'color-mix(in srgb, var(--chip-color-main) 10%, transparent)', }, // ========================================== // DELETE BUTTON // ========================================== '& .chip-delete': { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', borderRadius: cssVariableTheme.shape.borderRadius.full, border: 'none', background: 'transparent', color: 'inherit', padding: '0', marginLeft: cssVariableTheme.spacing.xs, marginRight: `calc(-1 * ${cssVariableTheme.spacing.xs})`, width: '18px', height: '18px', fontSize: cssVariableTheme.typography.fontSize.md, lineHeight: '1', opacity: '0.7', transition: buildTransition(['opacity', cssVariableTheme.transitions.duration.fast, cssVariableTheme.transitions.easing.default], ['background', cssVariableTheme.transitions.duration.fast, cssVariableTheme.transitions.easing.default]), }, '& .chip-delete:hover': { opacity: '1', background: 'color-mix(in srgb, currentColor 15%, transparent)', }, // Label truncation '& .chip-label': { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', }, }, render: ({ props, children, useHostProps }) => { const { variant, color, size, disabled, clickable, onDelete, style, ...rest } = props; const colors = color ? paletteFullColors[color] : defaultColors; const isClickable = clickable || rest.onclick; useHostProps({ 'data-variant': variant || undefined, 'data-size': size && size !== 'medium' ? size : undefined, 'data-disabled': disabled ? '' : undefined, 'data-clickable': isClickable ? '' : undefined, tabIndex: isClickable && !disabled ? 0 : undefined, style: { '--chip-color-main': colors.main, '--chip-color-main-contrast': colors.mainContrast, '--chip-color-light': colors.light, '--chip-color-dark': colors.dark, '--chip-color-dark-contrast': colors.darkContrast, ...style, }, }); return (createComponent(createComponent, null, createComponent("span", { className: "chip-label" }, children), onDelete ? (createComponent("span", { className: "chip-delete", role: "button", tabIndex: 0, onclick: (ev) => { ev.stopPropagation(); onDelete(ev); } }, createComponent(Icon, { icon: close, size: 14 }))) : null)); }, }); //# sourceMappingURL=chip.js.map