UNPKG

@hitachivantara/uikit-react-lab

Version:

Contributed React components to UI Kit by the community.

140 lines (139 loc) 5.56 kB
import { HvDefaultNavigation } from "./DefaultNavigation/DefaultNavigation.js"; import { HvSimpleNavigation } from "./SimpleNavigation/SimpleNavigation.js"; import { useClasses } from "./StepNavigation.styles.js"; import { HvTooltip, HvTypography, useTheme, useWidth } from "@hitachivantara/uikit-react-core"; import { theme as theme$1 } from "@hitachivantara/uikit-styles"; import { jsx } from "react/jsx-runtime"; import styled from "@emotion/styled"; //#region src/StepNavigation/StepNavigation.tsx /** * Navigation page with steps. * * You need to define the `steps` displayed on the component so that itself can be drawn on the UI. * On each step, you need to define a `state` - 'Pending', 'Failed', 'Completed', 'Current', 'Disabled' - * and a `title` to be shown as a tooltip or a text above of the step. You can also defined `className`, `separatorClassName`, and `titleClassName` to override the default styles. * * If the step component has titles, each one will have 215px of width by default. */ var 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) => { return /* @__PURE__ */ jsx("li", { "aria-hidden": true, className: cx(css({ height: separatorHeight, width: separatorWidth - 8, backgroundColor, margin: `0 4px` }), 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$1)); 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) * 235 * steps.length - 20, 100 * (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); return { width: navWidth, titleWidth: Number(hasTitles) * Math.ceil((navWidth + 20) / steps.length), separatorWidth: Number(!hasTitles) * Math.ceil((navWidth - stepsWidth) / (steps.length - 1)) }; }; 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 - 20, marginRight: 20 }), 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) }) }); }; //#endregion export { HvStepNavigation };