@furystack/shades-common-components
Version:
112 lines • 4.77 kB
JavaScript
import { createComponent, Shade } from '@furystack/shades';
import { NotyService } from '../services/noty-service.js';
import { ThemeProviderService } from '../services/theme-provider-service.js';
import { promisifyAnimation } from '../utils/promisify-animation.js';
import { Button } from './button.js';
export const getDefaultNotyTimeouts = (type) => {
switch (type) {
case 'error':
return 0;
case 'warning':
return 0;
case 'success':
return 5000;
case 'info':
return 20000;
default:
return 0;
}
};
export const NotyComponent = Shade({
shadowDomName: 'shade-noty',
constructed: ({ element }) => {
setTimeout(() => {
const height = element.scrollHeight || 80;
void promisifyAnimation(element, [
{ opacity: '0', height: '0px' },
{ opacity: '1', height: `${height}px` },
], {
fill: 'forwards',
duration: 700,
easing: 'cubic-bezier(0.190, 1.000, 0.220, 1.000)',
});
});
},
style: {
margin: '8px',
overflow: 'hidden',
borderRadius: '6px',
boxShadow: '1px 3px 6px rgba(0,0,0,0.3)',
width: '300px',
display: 'flex',
flexDirection: 'column',
height: '0px',
},
render: ({ props, injector, element }) => {
const themeProvider = injector.getInstance(ThemeProviderService);
const colors = themeProvider.theme.palette[props.model.type];
const headerTextColor = themeProvider.getTextColor(colors.dark);
const textColor = themeProvider.getTextColor(colors.main);
const removeSelf = async () => {
await promisifyAnimation(element, [
{ opacity: '1', height: `${element?.scrollHeight || 0}px`, margin: '8px 8px' },
{ opacity: '0', height: '0px', margin: '0px 8px' },
], {
fill: 'forwards',
duration: 700,
easing: 'cubic-bezier(0.190, 1.000, 0.220, 1.000)',
});
props.onDismiss();
};
const timeout = props.model.timeout || getDefaultNotyTimeouts(props.model.type);
if (timeout) {
setTimeout(() => void removeSelf(), timeout);
}
element.className = `noty ${props.model.type}`;
element.style.backgroundColor = colors.main;
element.style.color = textColor;
return (createComponent(createComponent, null,
createComponent("div", { style: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
padding: '0px 6px 0px 16px',
backgroundColor: colors.dark,
color: headerTextColor,
fontSize: '1.3em',
} },
createComponent("h5", { style: {
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
margin: '0',
fontSize: '.7em',
}, title: props.model.title }, props.model.title),
createComponent(Button, { style: { margin: '4px 0', padding: '0 4px', fontSize: '12px' }, className: "dismissNoty", onclick: removeSelf, title: "Close Notification", variant: "contained", color: props.model.type }, "\u2716")),
createComponent("div", { style: { padding: '16px 16px' } }, props.model.body)));
},
});
export const NotyList = Shade({
shadowDomName: 'shade-noty-list',
style: {
position: 'fixed',
bottom: '1em',
right: '1em',
display: 'flex',
flexDirection: 'column',
},
render: ({ useDisposable, injector, element }) => {
const notyService = injector.getInstance(NotyService);
const currentNotys = notyService.getNotyList();
useDisposable('addNoty', () => notyService.subscribe('onNotyAdded', (n) => element.append(createComponent(NotyComponent, { model: n, onDismiss: () => notyService.emit('onNotyRemoved', n) }))));
useDisposable('removeNoty', () => notyService.subscribe('onNotyRemoved', (n) => {
element.querySelectorAll('shade-noty').forEach((e) => {
if (e.props.model === n) {
e.remove();
}
});
}));
return (createComponent(createComponent, null, currentNotys.map((n) => (createComponent(NotyComponent, { model: n, onDismiss: () => injector.getInstance(NotyService).emit('onNotyRemoved', n) })))));
},
});
//# sourceMappingURL=noty-list.js.map