UNPKG

@furystack/shades-common-components

Version:

Common UI components for FuryStack Shades

132 lines 6.11 kB
import { Shade, createComponent } from '@furystack/shades'; import { buildTransition, cssVariableTheme } from '../services/css-variable-theme.js'; import { paletteMainColors } from '../services/palette-css-vars.js'; import { Icon } from './icons/icon.js'; import { checkCircle, close as closeIcon, errorCircle, info as infoIcon, warning as warningIcon, } from './icons/icon-definitions.js'; const severityColorMap = { error: { ...paletteMainColors.error, light: cssVariableTheme.palette.error.light }, warning: { ...paletteMainColors.warning, light: cssVariableTheme.palette.warning.light }, info: { ...paletteMainColors.info, light: cssVariableTheme.palette.info.light }, success: { ...paletteMainColors.success, light: cssVariableTheme.palette.success.light }, }; const defaultIconDefs = { error: errorCircle, warning: warningIcon, info: infoIcon, success: checkCircle, }; const getDefaultIcon = (severity) => createComponent(Icon, { icon: defaultIconDefs[severity], size: "small" }); export const Alert = Shade({ customElementName: 'shade-alert', css: { display: 'flex', alignItems: 'flex-start', gap: cssVariableTheme.spacing.md, padding: `${cssVariableTheme.spacing.md} ${cssVariableTheme.spacing.lg}`, fontFamily: cssVariableTheme.typography.fontFamily, fontSize: cssVariableTheme.typography.fontSize.sm, lineHeight: '1.5', borderRadius: cssVariableTheme.shape.borderRadius.md, boxSizing: 'border-box', transition: buildTransition(['background', cssVariableTheme.transitions.duration.fast, cssVariableTheme.transitions.easing.default], ['color', cssVariableTheme.transitions.duration.fast, cssVariableTheme.transitions.easing.default], ['box-shadow', cssVariableTheme.transitions.duration.fast, cssVariableTheme.transitions.easing.default]), // ========================================== // STANDARD VARIANT (default) // ========================================== '&:not([data-variant]), &[data-variant="standard"]': { background: 'color-mix(in srgb, var(--alert-color-main) 12%, transparent)', color: 'var(--alert-color-main)', }, // ========================================== // FILLED VARIANT // ========================================== '&[data-variant="filled"]': { background: 'var(--alert-color-main)', color: 'var(--alert-color-main-contrast)', }, // ========================================== // OUTLINED VARIANT // ========================================== '&[data-variant="outlined"]': { background: 'transparent', color: 'var(--alert-color-main)', boxShadow: '0px 0px 0px 1px var(--alert-color-main)', }, // ========================================== // ICON // ========================================== '& .alert-icon': { display: 'flex', alignItems: 'center', fontSize: '20px', lineHeight: '1', flexShrink: '0', paddingTop: '1px', }, // ========================================== // CONTENT // ========================================== '& .alert-content': { flex: '1', minWidth: '0', }, '& .alert-title': { fontWeight: cssVariableTheme.typography.fontWeight.semibold, marginBottom: cssVariableTheme.spacing.xs, }, '& .alert-message': { opacity: '0.9', }, // ========================================== // CLOSE BUTTON // ========================================== '& .alert-close': { display: 'inline-flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', borderRadius: cssVariableTheme.shape.borderRadius.full, border: 'none', background: 'transparent', color: 'inherit', padding: '4px', marginTop: '-2px', marginRight: `-${cssVariableTheme.spacing.sm}`, fontSize: '14px', lineHeight: '1', opacity: '0.7', flexShrink: '0', transition: buildTransition(['opacity', cssVariableTheme.transitions.duration.fast, cssVariableTheme.transitions.easing.default], ['background', cssVariableTheme.transitions.duration.fast, cssVariableTheme.transitions.easing.default]), }, '& .alert-close:hover': { opacity: '1', background: 'color-mix(in srgb, currentColor 15%, transparent)', }, }, render: ({ props, children, useHostProps }) => { const { severity = 'info', variant, title, onClose, icon, style } = props; const colors = severityColorMap[severity]; useHostProps({ 'data-variant': variant || undefined, 'data-severity': severity, role: 'alert', style: { '--alert-color-main': colors.main, '--alert-color-main-contrast': colors.mainContrast, '--alert-color-light': colors.light, ...style, }, }); const displayIcon = icon ?? getDefaultIcon(severity); return (createComponent(createComponent, null, createComponent("span", { className: "alert-icon" }, displayIcon), createComponent("div", { className: "alert-content" }, title ? createComponent("div", { className: "alert-title" }, title) : null, createComponent("div", { className: "alert-message" }, children)), onClose ? (createComponent("span", { className: "alert-close", role: "button", onclick: (ev) => { ev.stopPropagation(); onClose(ev); } }, createComponent(Icon, { icon: closeIcon, size: "small" }))) : null)); }, }); //# sourceMappingURL=alert.js.map