UNPKG

@hitachivantara/uikit-react-lab

Version:

Contributed React components for the NEXT UI Kit.

188 lines (187 loc) 6.24 kB
import { jsx } from "react/jsx-runtime"; import styled from "@emotion/styled"; import { useTheme, useWidth, HvTypography, HvTooltip } from "@hitachivantara/uikit-react-core"; import { theme } from "@hitachivantara/uikit-styles"; import { useClasses } from "./StepNavigation.styles.js"; import { staticClasses } from "./StepNavigation.styles.js"; import { TITLE_WIDTH, TITLE_MARGIN, SEPARATOR_WIDTH } from "./utils.js"; import { HvSimpleNavigation } from "./SimpleNavigation/SimpleNavigation.js"; import { HvDefaultNavigation } from "./DefaultNavigation/DefaultNavigation.js"; const HvStepNavigation = ({ className, classes: classesProp, width, steps, stepSize, showTitles, type = "Default", "aria-label": ariaLabel, ...others }) => { const { classes, css, cx } = useClasses(classesProp); const { activeTheme } = useTheme(); const breakpoint = useWidth(); const stepSizeKey = stepSize ?? (["xs", "sm"].includes(breakpoint) ? "sm" : "md"); const hasTitles = showTitles ?? !["xs", "sm"].includes(breakpoint); const styledLi = (containerSize) => styled("li")({ width: containerSize, height: containerSize }); const styledDiv = (containerSize) => styled("div")({ width: containerSize, height: containerSize }); const styledSeparatorElement = (title, separatorClassName, separatorHeight, separatorWidth, backgroundColor) => { const widthValue = separatorWidth - 2 * Number( (activeTheme?.stepNavigation.separatorMargin || "0px").replace( "px", "" ) ); return /* @__PURE__ */ jsx( "li", { "aria-hidden": true, className: cx( css({ height: separatorHeight, width: widthValue, backgroundColor, margin: `0 ${theme.stepNavigation.separatorMargin}` }), classes.separator ), children: /* @__PURE__ */ jsx("div", { className: separatorClassName }) }, `separator-${title}` ); }; const drawItems = ({ separatorValues: { minWidth, maxWidth, getColor, height }, stepValues: { minSize, maxSize, StepComponent } }) => { const items = steps.reduce( (acc, { state, title, separatorClassName, ...props }, index) => { const containerSize = state === "Current" ? maxSize : minSize; const StepContainer = styledLi(containerSize); const Step = styledDiv(Math.max(containerSize, 30)); const stepProps = { size: stepSizeKey, state, title, number: index + 1, ...props }; const stepElement = /* @__PURE__ */ jsx(StepContainer, { className: classes.li, children: hasTitles ? /* @__PURE__ */ jsx( StepComponent, { "aria-label": `${title}`, ...stepProps }, `step-${title}` ) : /* @__PURE__ */ jsx( HvTooltip, { placement: "bottom", title: /* @__PURE__ */ jsx(HvTypography, { children: `${index + 1}. ${title}` }), children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Step, { className: classes.li, children: /* @__PURE__ */ jsx(StepComponent, { "aria-label": `${title}`, ...stepProps }) }) }) } ) }, `step-${title}`); if (index < steps.length - 1) { const separatorElement = styledSeparatorElement( title, separatorClassName, height, [steps[index + 1].state, state].includes("Current") ? minWidth : maxWidth, getColor( steps[index + 1].state === "Disabled" ? "Disabled" : state, theme ) ); acc.push(stepElement, separatorElement); return acc; } acc.push(stepElement); return acc; }, [] ); return /* @__PURE__ */ jsx("ol", { className: classes.ol, children: items }); }; const getDynamicValues = (stepsWidth) => { const themeBreakpoints = activeTheme?.breakpoints.values || {}; const maxWidth = width?.[breakpoint] ?? Math.max( Number(hasTitles) * (TITLE_WIDTH + TITLE_MARGIN) * steps.length - TITLE_MARGIN, SEPARATOR_WIDTH * (steps.length - 1) + stepsWidth ); const next = Object.keys(themeBreakpoints).find( (_, index, self) => index - 1 >= 0 ? self[index - 1] === breakpoint : false ); const navWidth = Math.min( maxWidth, next ? themeBreakpoints[next] : maxWidth ); const titleWidth = Number(hasTitles) * Math.ceil((navWidth + TITLE_MARGIN) / steps.length); const separatorWidth = Number(!hasTitles) * Math.ceil((navWidth - stepsWidth) / (steps.length - 1)); return { width: navWidth, titleWidth, separatorWidth }; }; const getTitles = (getTitleProps) => hasTitles ? /* @__PURE__ */ jsx("div", { className: classes.titles, children: steps.map(({ title: rawTitle, state, titleClassName }, index) => { const { variant = "label", title = rawTitle, titleWidth = 0, titleDisabled = false } = getTitleProps?.({ state, rawTitle, number: index + 1 }) ?? {}; return /* @__PURE__ */ jsx( HvTypography, { variant, className: cx( css({ textAlign: "center", width: titleWidth - TITLE_MARGIN, marginRight: TITLE_MARGIN }), titleClassName ), disabled: titleDisabled, children: title }, title ); }) }) : null; const StepNavigation = { Default: HvDefaultNavigation, Simple: HvSimpleNavigation }[type]; return /* @__PURE__ */ jsx( StepNavigation, { numSteps: steps.length, stepSize: stepSizeKey, getTitles, getDynamicValues, className: cx(classes.root, className), ...others, children: ({ stepsWidth, navWidth, ...itemsProps }) => /* @__PURE__ */ jsx( "nav", { style: { width: `${navWidth}px`, margin: 0 }, "aria-label": ariaLabel, children: drawItems(itemsProps) } ) } ); }; export { HvStepNavigation, staticClasses as stepNavigationClasses };