UNPKG

@furystack/shades-common-components

Version:

Common UI components for FuryStack Shades

124 lines 6.24 kB
import { createComponent, maybeViewTransition, Shade } from '@furystack/shades'; import { cssVariableTheme } from '../../services/css-variable-theme.js'; import { Paper } from '../paper.js'; export const Wizard = Shade({ customElementName: 'shades-wizard', css: { fontFamily: cssVariableTheme.typography.fontFamily, '& .wizard-container': { display: 'flex', alignItems: 'center', justifyContent: 'center', width: '100%', height: '100%', }, '& .wizard-step-indicator': { display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '16px 24px 8px', gap: '0', }, '& .wizard-step-node': { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '4px', zIndex: '1', minWidth: '32px', }, '& .wizard-step-circle': { width: '28px', height: '28px', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: cssVariableTheme.typography.fontSize.xs, fontWeight: cssVariableTheme.typography.fontWeight.semibold, border: `2px solid ${cssVariableTheme.action.subtleBorder}`, background: cssVariableTheme.background.default, color: cssVariableTheme.text.secondary, transition: `all ${cssVariableTheme.transitions.duration.normal} ease`, }, '& .wizard-step-circle[data-active]': { borderColor: cssVariableTheme.palette.primary.main, background: cssVariableTheme.palette.primary.main, color: cssVariableTheme.palette.primary.mainContrast, }, '& .wizard-step-circle[data-completed]': { borderColor: cssVariableTheme.palette.primary.main, background: cssVariableTheme.palette.primary.main, color: cssVariableTheme.palette.primary.mainContrast, opacity: '0.7', }, '& .wizard-step-label': { fontSize: cssVariableTheme.typography.fontSize.xs, color: cssVariableTheme.text.secondary, textAlign: 'center', maxWidth: '80px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', }, '& .wizard-step-label[data-active]': { color: cssVariableTheme.palette.primary.main, fontWeight: cssVariableTheme.typography.fontWeight.semibold, }, '& .wizard-step-connector': { flex: '1', height: '2px', background: cssVariableTheme.action.subtleBorder, minWidth: '24px', alignSelf: 'flex-start', marginTop: '14px', transition: `background ${cssVariableTheme.transitions.duration.normal} ease`, }, '& .wizard-step-connector[data-completed]': { background: cssVariableTheme.palette.primary.main, }, '& .wizard-progress-bar': { height: '4px', background: cssVariableTheme.action.subtleBorder, margin: '12px 24px 4px', borderRadius: '2px', overflow: 'hidden', }, '& .wizard-progress-fill': { height: '100%', background: cssVariableTheme.palette.primary.main, borderRadius: '2px', transition: `width ${cssVariableTheme.transitions.duration.normal} ease`, }, }, render: ({ props, useState }) => { const [currentPage, setCurrentPage] = useState('currentPage', 0); if (props.stepLabels && props.stepLabels.length !== props.steps.length) { console.warn(`[Wizard] stepLabels length (${props.stepLabels.length}) does not match steps length (${props.steps.length}).`); } const CurrentPage = props.steps[currentPage]; const progressPercent = props.steps.length > 1 ? (currentPage / (props.steps.length - 1)) * 100 : 100; return (createComponent("div", { className: "wizard-container" }, createComponent(Paper, { style: { maxWidth: '100%', maxHeight: '100%' }, elevation: 3, onclick: (ev) => ev.stopPropagation() }, props.stepLabels && props.stepLabels.length > 0 && (createComponent("div", { className: "wizard-step-indicator", "data-testid": "wizard-step-indicator" }, props.steps.map((_, index) => (createComponent(createComponent, null, index > 0 && (createComponent("div", { className: "wizard-step-connector", ...(index <= currentPage ? { 'data-completed': '' } : {}) })), createComponent("div", { className: "wizard-step-node" }, createComponent("div", { className: "wizard-step-circle", ...(index === currentPage ? { 'data-active': '' } : {}), ...(index < currentPage ? { 'data-completed': '' } : {}) }, (index + 1).toString()), createComponent("span", { className: "wizard-step-label", ...(index === currentPage ? { 'data-active': '' } : {}) }, props.stepLabels?.[index] ?? ''))))))), props.showProgress && (createComponent("div", { className: "wizard-progress-bar", "data-testid": "wizard-progress-bar" }, createComponent("div", { className: "wizard-progress-fill", style: { width: `${progressPercent}%` } }))), createComponent(CurrentPage, { currentPage: currentPage, maxPages: props.steps.length, onNext: () => { if (currentPage < props.steps.length - 1) { void maybeViewTransition(props.viewTransition, () => setCurrentPage(currentPage + 1)); } else { props.onFinish?.(); } }, onPrev: () => { if (currentPage > 0) { void maybeViewTransition(props.viewTransition, () => setCurrentPage(currentPage - 1)); } } })))); }, }); //# sourceMappingURL=index.js.map