UNPKG

braid-design-system

Version:
171 lines (170 loc) 3.79 kB
import { jsx } from "react/jsx-runtime"; import { createContext, useReducer } from "react"; import { normalizeKey } from "../private/normalizeKey.mjs"; const StepContext = createContext({ stepNumber: 0, isLast: false }); const NAV_RIGHT = 0; const NAV_DOWN = 1; const NAV_LEFT = 2; const NAV_UP = 3; const NAV_HOME = 4; const NAV_END = 5; const NAV_TAB = 6; const NAV_CLICKED = 7; const NAV_FOCUSED = 8; const NAV_BLURRED = 9; const StepperContext = createContext(null); const getNextStep = (moveAmount, current, maxStep) => { if (current === null) { return moveAmount > 0 ? 1 : maxStep; } const nextStep = moveAmount + current; if (nextStep > maxStep) { return 1; } if (nextStep < 1) { return maxStep; } return nextStep; }; const StepperContextProvider = ({ children, activeStep, stepCount: stepCountProp, progress, isLinear, align, tone = "formAccent", onStepClick }) => { const stepCount = isLinear ? progress : stepCountProp; const [stepperState, dispatch] = useReducer( (state, action) => { switch (action.type) { case NAV_UP: case NAV_LEFT: { return { ...state, focusedStep: getNextStep(-1, state.focusedStep, stepCount) }; } case NAV_DOWN: case NAV_RIGHT: { return { ...state, focusedStep: getNextStep(1, state.focusedStep, stepCount) }; } case NAV_HOME: { return { ...state, focusedStep: 1 }; } case NAV_END: { return { ...state, focusedStep: stepCount }; } case NAV_BLURRED: case NAV_TAB: { return { ...state, focusedStep: null }; } case NAV_CLICKED: { return { ...state, focusedStep: action.value }; } case NAV_FOCUSED: { return { ...state, focusedStep: state.focusedStep === null ? activeStep : state.focusedStep }; } default: return state; } }, { focusedStep: null, activeStep, isLinear, tone, align, progress, onStepClick } ); const onKeyUp = (event) => { const targetKey = normalizeKey(event); if (targetKey === "Tab") { return; } const action = { ArrowRight: { type: NAV_RIGHT }, ArrowLeft: { type: NAV_LEFT }, ArrowUp: { type: NAV_UP }, ArrowDown: { type: NAV_DOWN }, Home: { type: NAV_HOME }, End: { type: NAV_END } }; if (action[targetKey]) { dispatch(action[targetKey]); } }; const onKeyDown = (event) => { const targetKey = normalizeKey(event); if (targetKey === "Tab") { dispatch({ type: NAV_TAB }); return; } const isNavigationKeyPress = targetKey.indexOf("Arrow") === 0 || ["Home", "End"].includes(targetKey); if (isNavigationKeyPress) { event.preventDefault(); } }; const onFocus = () => dispatch({ type: NAV_FOCUSED }); const onBlur = () => dispatch({ type: NAV_BLURRED }); const onClick = (index) => dispatch({ type: NAV_CLICKED, value: index }); return /* @__PURE__ */ jsx( StepperContext.Provider, { value: { ...stepperState, activeStep, isLinear, align, tone, progress, onStepClick, ...typeof onStepClick === "function" ? { onKeyUp, onKeyDown, onClick, onFocus, onBlur } : {} }, children } ); }; export { StepContext, StepperContext, StepperContextProvider };