UNPKG

@awsui/components-react

Version:

AWS UI is a collection of [React](https://reactjs.org/) components that help create intuitive, responsive, and accessible user experiences for web applications. It is developed by Amazon Web Services (AWS). This work is available under the terms of the [A

174 lines (173 loc) • 8.83 kB
import { __assign, __rest } from "tslib"; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { OpenAnnotation } from './annotation/open-annotation'; import { ClosedAnnotation } from './annotation/closed-annotation'; import { hotspotContext } from './context'; import { fireNonCancelableEvent } from '../internal/events'; import { useTelemetry } from '../internal/hooks/use-telemetry'; export function getStepInfo(annotations, index) { if (index >= 0) { var taskIndex = 0; for (var _i = 0, annotations_1 = annotations; _i < annotations_1.length; _i++) { var task = annotations_1[_i]; if (task.steps.length <= index) { index -= task.steps.length; taskIndex++; continue; } return { task: task, step: task.steps[index], localIndex: index, taskIndex: taskIndex }; } } return { task: undefined, step: undefined, localIndex: 0, taskIndex: 0 }; } export default function AnnotationContext(_a) { var _b, _c, _d, _e; var currentTutorial = _a.currentTutorial, children = _a.children, onStepChange = _a.onStepChange, onFinishHandler = _a.onFinish, onStartTutorial = _a.onStartTutorial, onExitTutorial = _a.onExitTutorial, announcementPopoverHeader = _a.announcementPopoverHeader, announcementPopoverBody = _a.announcementPopoverBody, onDismissAnnouncementPopover = _a.onDismissAnnouncementPopover, i18nStrings = _a.i18nStrings; useTelemetry('AnnotationContext'); var _f = useState(true), open = _f[0], setOpen = _f[1]; var _g = useState(0), currentStepIndex = _g[0], setCurrentStepIndex = _g[1]; useEffect(function () { setCurrentStepIndex(0); setOpen(true); }, [currentTutorial, setOpen]); var _h = useState({}), availableHotspots = _h[0], setAvailableHotspots = _h[1]; var annotations = currentTutorial ? currentTutorial.tasks : []; var _j = getStepInfo(annotations, currentStepIndex), task = _j.task, step = _j.step, localIndex = _j.localIndex, taskIndex = _j.taskIndex; var currentId = step === null || step === void 0 ? void 0 : step.hotspotId; var totalStepCount = annotations.map(function (a) { return a.steps.length; }).reduce(function (a, b) { return a + b; }, 0); var id2index = useMemo(function () { var mapping = {}; var counter = 0; for (var _i = 0, annotations_2 = annotations; _i < annotations_2.length; _i++) { var annotation = annotations_2[_i]; for (var _a = 0, _b = annotation.steps; _a < _b.length; _a++) { var step_1 = _b[_a]; mapping[step_1.hotspotId] = counter; counter++; } } return mapping; }, [annotations]); var openNextStep = useCallback(function () { var newStepIndex = Math.min(currentStepIndex + 1, totalStepCount); setCurrentStepIndex(newStepIndex); fireNonCancelableEvent(onStepChange, { step: newStepIndex, reason: 'next' }); }, [currentStepIndex, onStepChange, totalStepCount]); var openPreviousStep = useCallback(function () { var newStepIndex = Math.max(currentStepIndex - 1, 0); setCurrentStepIndex(newStepIndex); fireNonCancelableEvent(onStepChange, { step: newStepIndex, reason: 'previous' }); }, [onStepChange, currentStepIndex]); var onFinish = useCallback(function () { return fireNonCancelableEvent(onFinishHandler); }, [onFinishHandler]); useEffect(function () { if (!currentId || availableHotspots[currentId]) { return; } var findNearestHotspot = function () { var nearestHotspot = undefined; var nearestDistance = Infinity; for (var _i = 0, _a = Object.keys(availableHotspots); _i < _a.length; _i++) { var hotspotId = _a[_i]; var distanceFromCurrentHotspot = Math.abs(id2index[hotspotId] - currentStepIndex); if (distanceFromCurrentHotspot < nearestDistance) { nearestDistance = distanceFromCurrentHotspot; nearestHotspot = hotspotId; } } return nearestHotspot; }; var nearestHotspot = findNearestHotspot(); if (nearestHotspot) { var newStepIndex = id2index[nearestHotspot]; setCurrentStepIndex(newStepIndex); fireNonCancelableEvent(onStepChange, { step: newStepIndex, reason: 'auto-fallback' }); } }, [annotations, availableHotspots, currentId, currentStepIndex, id2index, onStepChange]); var onDismiss = useCallback(function () { setOpen(false); }, [setOpen]); var onOpen = useCallback(function (stepIndex) { setCurrentStepIndex(stepIndex); fireNonCancelableEvent(onStepChange, { step: stepIndex, reason: 'open' }); setOpen(true); }, [onStepChange, setOpen]); var idOfPreviousHotspot = (_b = getStepInfo(annotations, currentStepIndex - 1).step) === null || _b === void 0 ? void 0 : _b.hotspotId; var idOfNextHotspot = (_c = getStepInfo(annotations, currentStepIndex + 1).step) === null || _c === void 0 ? void 0 : _c.hotspotId; var previousHotspotIsAvailable = (_d = (idOfPreviousHotspot !== undefined && availableHotspots[idOfPreviousHotspot])) !== null && _d !== void 0 ? _d : false; var nextHotspotIsAvailable = (_e = (idOfNextHotspot !== undefined && availableHotspots[idOfNextHotspot])) !== null && _e !== void 0 ? _e : false; var getContentForId = useCallback(function (id, direction) { if (currentTutorial === null || currentTutorial === void 0 ? void 0 : currentTutorial.completed) { return null; } var globalStepIndex = id2index[id]; if (globalStepIndex === undefined) { return null; } if (!task || !step || !open || id !== currentId) { return (React.createElement(ClosedAnnotation, { globalStepIndex: globalStepIndex, i18nStrings: i18nStrings, onOpen: onOpen, focusOnRender: id === currentId })); } return (React.createElement(OpenAnnotation, { i18nStrings: i18nStrings, direction: direction, title: i18nStrings.taskTitle(taskIndex, task.title), content: step.content, alert: step.warningAlert, showFinishButton: globalStepIndex + 1 === totalStepCount, taskLocalStepIndex: localIndex, totalLocalSteps: task.steps.length, nextButtonEnabled: nextHotspotIsAvailable, onNextButtonClick: openNextStep, onFinish: onFinish, previousButtonEnabled: previousHotspotIsAvailable, onPreviousButtonClick: openPreviousStep, onDismiss: onDismiss })); }, [ id2index, currentTutorial, task, step, open, currentId, i18nStrings, taskIndex, localIndex, totalStepCount, nextHotspotIsAvailable, openNextStep, onFinish, previousHotspotIsAvailable, openPreviousStep, onDismiss, onOpen ]); var registerHotspot = useCallback(function (id) { if (!id2index || id2index[id] === undefined) { return; } if (availableHotspots[id]) { return; } setAvailableHotspots(function (availableHotspots) { var _a; if (availableHotspots[id]) { return availableHotspots; } return __assign(__assign({}, availableHotspots), (_a = {}, _a[id] = true, _a)); }); }, [id2index, availableHotspots]); var unregisterHotspot = useCallback(function (id) { if (!availableHotspots[id]) { return; } setAvailableHotspots(function (availableHotspots) { if (!availableHotspots[id]) { return availableHotspots; } var removeKey = function (key, _a) { var _b = key, _ = _a[_b], remainingObject = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]); return remainingObject; }; return removeKey(id, availableHotspots); }); }, [availableHotspots]); var context = { getContentForId: getContentForId, registerHotspot: registerHotspot, unregisterHotspot: unregisterHotspot, onStartTutorial: onStartTutorial, onExitTutorial: onExitTutorial, currentStepIndex: currentStepIndex, currentTutorial: currentTutorial, announcementPopoverHeader: announcementPopoverHeader, announcementPopoverBody: announcementPopoverBody, onDismissAnnouncementPopover: onDismissAnnouncementPopover, labelDismissAnnouncementPopover: i18nStrings.labelDismissAnnouncementPopover }; return React.createElement(hotspotContext.Provider, { value: context }, children); }