@furystack/shades-common-components
Version:
Common UI components for FuryStack Shades
77 lines • 3.2 kB
JavaScript
import { Shade, createComponent } from '@furystack/shades';
import { buildTransition, cssVariableTheme } from '../services/css-variable-theme.js';
import { ThemeProviderService } from '../services/theme-provider-service.js';
import { promisifyAnimation } from '../utils/promisify-animation.js';
const clampValue = (v) => Math.max(0, Math.min(100, v));
export const LinearProgress = Shade({
customElementName: 'shade-linear-progress',
css: {
display: 'block',
fontFamily: cssVariableTheme.typography.fontFamily,
width: '100%',
overflow: 'hidden',
position: 'relative',
borderRadius: cssVariableTheme.shape.borderRadius.xs,
backgroundColor: 'color-mix(in srgb, var(--progress-color) 20%, transparent)',
// Medium size (default)
height: '6px',
'&[data-size="small"]': {
height: '4px',
},
'& .progress-bar': {
position: 'absolute',
top: '0',
left: '0',
height: '100%',
borderRadius: 'inherit',
backgroundColor: 'var(--progress-color)',
transition: buildTransition([
'width',
cssVariableTheme.transitions.duration.normal,
cssVariableTheme.transitions.easing.easeInOut,
]),
},
'& .progress-bar[data-indeterminate]': {
transition: 'none',
},
},
render: ({ props, injector, useHostProps, useRef }) => {
const themeProvider = injector.get(ThemeProviderService);
const barRef = useRef('progressBar');
const variant = props.variant || 'indeterminate';
const value = clampValue(props.value ?? 0);
const color = themeProvider.theme.palette[props.color || 'primary'].main;
useHostProps({
'data-size': props.size === 'small' ? 'small' : undefined,
role: 'progressbar',
...(variant === 'determinate'
? {
'aria-valuenow': String(value),
'aria-valuemin': '0',
'aria-valuemax': '100',
}
: {
'aria-valuenow': undefined,
}),
style: { '--progress-color': color },
});
const barWidth = variant === 'determinate' ? `${value}%` : '40%';
if (variant === 'indeterminate') {
setTimeout(() => {
if (barRef.current) {
void promisifyAnimation(barRef.current, [
{ left: '-40%', width: '40%' },
{ left: '60%', width: '40%' },
{ left: '100%', width: '10%' },
], {
duration: 1800,
easing: 'cubic-bezier(0.65, 0, 0.35, 1)',
iterations: Infinity,
});
}
}, 1);
}
return (createComponent("div", { ref: barRef, className: "progress-bar", style: { width: barWidth }, ...(variant === 'indeterminate' ? { 'data-indeterminate': '' } : {}) }));
},
});
//# sourceMappingURL=linear-progress.js.map