@vectara/vectara-ui 20.1.0 → 20.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/app/appLayout.scss +0 -1
- package/lib/components/index.d.ts +4 -3
- package/lib/components/index.js +2 -1
- package/lib/components/popover/Popover.d.ts +1 -1
- package/lib/components/popover/Popover.js +6 -0
- package/lib/components/popover/_index.scss +10 -0
- package/lib/components/stepNavigator/StepNavigator.d.ts +16 -0
- package/lib/components/stepNavigator/StepNavigator.js +47 -0
- package/lib/components/stepNavigator/_index.scss +105 -0
- package/lib/components/stepsVertical/StepsVertical.d.ts +4 -2
- package/lib/components/stepsVertical/StepsVertical.js +3 -3
- package/lib/styles/index.css +100 -1
- package/package.json +1 -1
- package/src/docs/pages/stepNavigator/BasicStepNavigator.tsx +18 -0
- package/src/docs/pages/stepNavigator/index.tsx +12 -0
- package/src/docs/pages.tsx +2 -1
|
@@ -93,8 +93,9 @@ import { SPINNER_COLOR, SPINNER_SIZE } from "./spinner/types";
|
|
|
93
93
|
import { Stat, VuiStatList } from "./statList/StatList";
|
|
94
94
|
import { VuiStat } from "./stat/Stat";
|
|
95
95
|
import { VuiStatus } from "./status/Status";
|
|
96
|
+
import { VuiStepNavigator, StepNavigatorStep, StepNavigatorSteps } from "./stepNavigator/StepNavigator";
|
|
96
97
|
import { VuiSteps, StepStatus, StepSize, Steps } from "./steps/Steps";
|
|
97
|
-
import { VuiStepsVertical, StepsVertical, StepVerticalStatus } from "./stepsVertical/StepsVertical";
|
|
98
|
+
import { VuiStepsVertical, StepVertical, StepsVertical, StepVerticalStatus } from "./stepsVertical/StepsVertical";
|
|
98
99
|
import { SKELETON_COLOR, VuiSkeleton } from "./skeleton/Skeleton";
|
|
99
100
|
import { VuiSummary, VuiSummaryCitation } from "./summary";
|
|
100
101
|
import { VuiTable } from "./table/Table";
|
|
@@ -116,5 +117,5 @@ import { VuiInfoTooltip } from "./tooltip/InfoTooltip";
|
|
|
116
117
|
import { VuiTopicButton } from "./topicButton/TopicButton";
|
|
117
118
|
import { copyToClipboard } from "../utils/copyToClipboard";
|
|
118
119
|
import { toRgb, toRgba } from "./context/Theme";
|
|
119
|
-
export type { AnchorSide, AppContentPadding, BarChartSeries, ComposedSeries, LineChartSeries, LineChartVariant, ScatterSeries, ButtonColor, CalloutColor, ChatLanguage, ChatStyle, ChatTurn, CheckboxConfig, CodeEditorColorConfig, CodeEditorError, CodeLanguage, ComposerFileError, ComposerShortcutApi, ComposerShortcutHandler, ComposerSubmission, InfoListItemType, InfoListType, InfoTableColumnAlign, InfoTableRow, InfoTableRowType, KvTableAlign, KvTableItem, KvTableItems, KvTablePadding, LinkProps, MenuItem, OptionListItem, Pagination, PatchColor, RadioButtonConfig, SearchResult, SearchSuggestion, Sections, SectionItem, SpansRow, Stat, StepStatus, StepSize, Steps, StepsVertical, StepVerticalStatus, TabNavigatorRoute, TabSize, Tree, TreeItem, AccountButtonHandle };
|
|
120
|
-
export { BADGE_COLOR, BUTTON_COLOR, BUTTON_SIZE, CHART_PALETTE, CALLOUT_COLOR, CALLOUT_SIZE, DURATION_BAR_COLOR, ICON_COLOR, ICON_SIZE, ICON_TYPE, PATCH_COLOR, PROGRESS_BAR_COLOR, SPACER_SIZE, SPINNER_COLOR, SKELETON_COLOR, SPINNER_SIZE, TAB_SIZE, TEXT_COLOR, TEXT_SIZE, TITLE_SIZE, addNotification, copyToClipboard, generateTokensProvider, toRgb, toRgba, VuiAccordion, VuiAccountButton, VuiAppContent, VuiAppHeader, VuiAppLayout, VuiAppSideNav, VuiAppSideNavLink, VuiAppSideNavGroup, VuiBadge, VuiBarChart, VuiComposedChart, VuiLineChart, VuiPieChart, VuiScatterChart, VuiSparkline, VuiTreeMap, VuiButtonPrimary, VuiButtonSecondary, VuiButtonTertiary, VuiIconButton, VuiCallout, VuiCard, VuiChat, VuiCheckbox, VuiChip, VuiCode, VuiCodeEditor, VuiComposer, VuiComplexConfigurationButton, VuiContextProvider, VuiCopyButton, VuiDatePicker, VuiDateRangePicker, VuiDrawer, VuiDurationBar, VuiErrorBoundary, VuiFileDropTarget, VuiFlexContainer, VuiFlexItem, VuiFormGroup, VuiGrid, VuiGridItem, VuiHorizontalRule, VuiIcon, VuiImage, VuiImagePreview, VuiInfoList, VuiInfoListItem, VuiInfoMenu, VuiInfoTable, VuiInfoTooltip, VuiKvTable, VuiInProgress, VuiItemsInput, VuiLabel, VuiLink, VuiLinkInternal, VuiList, VuiMenu, VuiMenuItem, VuiMenuList, VuiMenuListButton, VuiModal, VuiNotifications, VuiNumberInput, VuiOptionsButton, VuiOptionsList, VuiOptionsListItem, VuiPagination, VuiPanel, VuiPasswordInput, VuiPatch, VuiPopover, VuiPortal, VuiProgressBar, VuiPrompt, VuiRadioButton, VuiScreenBlock, VuiSearchInput, VuiSearchResult, VuiSearchSelect, VuiSelect, VuiSetting, VuiSideList, VuiSideListButton, VuiSimpleCard, VuiSimpleGrid, VuiSpacer, VuiSpans, VuiSpinner, VuiStat, VuiStatList, VuiStatus, VuiSteps, VuiStepsVertical, VuiSummary, VuiSkeleton, VuiSummaryCitation, VuiSuperCheckboxGroup, VuiSuperRadioGroup, VuiTable, VuiTab, VuiTabbedRoutes, VuiTabs, VuiTabsNavigator, VuiText, VuiTextArea, VuiTextColor, VuiTextInput, VuiTimeline, VuiTimelineItem, VuiTitle, VuiToggle, VuiTooltip, VuiTopicButton };
|
|
120
|
+
export type { AnchorSide, AppContentPadding, BarChartSeries, ComposedSeries, LineChartSeries, LineChartVariant, ScatterSeries, ButtonColor, CalloutColor, ChatLanguage, ChatStyle, ChatTurn, CheckboxConfig, CodeEditorColorConfig, CodeEditorError, CodeLanguage, ComposerFileError, ComposerShortcutApi, ComposerShortcutHandler, ComposerSubmission, InfoListItemType, InfoListType, InfoTableColumnAlign, InfoTableRow, InfoTableRowType, KvTableAlign, KvTableItem, KvTableItems, KvTablePadding, LinkProps, MenuItem, OptionListItem, Pagination, PatchColor, RadioButtonConfig, SearchResult, SearchSuggestion, Sections, SectionItem, SpansRow, Stat, StepNavigatorStep, StepNavigatorSteps, StepStatus, StepSize, Steps, StepVertical, StepsVertical, StepVerticalStatus, TabNavigatorRoute, TabSize, Tree, TreeItem, AccountButtonHandle };
|
|
121
|
+
export { BADGE_COLOR, BUTTON_COLOR, BUTTON_SIZE, CHART_PALETTE, CALLOUT_COLOR, CALLOUT_SIZE, DURATION_BAR_COLOR, ICON_COLOR, ICON_SIZE, ICON_TYPE, PATCH_COLOR, PROGRESS_BAR_COLOR, SPACER_SIZE, SPINNER_COLOR, SKELETON_COLOR, SPINNER_SIZE, TAB_SIZE, TEXT_COLOR, TEXT_SIZE, TITLE_SIZE, addNotification, copyToClipboard, generateTokensProvider, toRgb, toRgba, VuiAccordion, VuiAccountButton, VuiAppContent, VuiAppHeader, VuiAppLayout, VuiAppSideNav, VuiAppSideNavLink, VuiAppSideNavGroup, VuiBadge, VuiBarChart, VuiComposedChart, VuiLineChart, VuiPieChart, VuiScatterChart, VuiSparkline, VuiTreeMap, VuiButtonPrimary, VuiButtonSecondary, VuiButtonTertiary, VuiIconButton, VuiCallout, VuiCard, VuiChat, VuiCheckbox, VuiChip, VuiCode, VuiCodeEditor, VuiComposer, VuiComplexConfigurationButton, VuiContextProvider, VuiCopyButton, VuiDatePicker, VuiDateRangePicker, VuiDrawer, VuiDurationBar, VuiErrorBoundary, VuiFileDropTarget, VuiFlexContainer, VuiFlexItem, VuiFormGroup, VuiGrid, VuiGridItem, VuiHorizontalRule, VuiIcon, VuiImage, VuiImagePreview, VuiInfoList, VuiInfoListItem, VuiInfoMenu, VuiInfoTable, VuiInfoTooltip, VuiKvTable, VuiInProgress, VuiItemsInput, VuiLabel, VuiLink, VuiLinkInternal, VuiList, VuiMenu, VuiMenuItem, VuiMenuList, VuiMenuListButton, VuiModal, VuiNotifications, VuiNumberInput, VuiOptionsButton, VuiOptionsList, VuiOptionsListItem, VuiPagination, VuiPanel, VuiPasswordInput, VuiPatch, VuiPopover, VuiPortal, VuiProgressBar, VuiPrompt, VuiRadioButton, VuiScreenBlock, VuiSearchInput, VuiSearchResult, VuiSearchSelect, VuiSelect, VuiSetting, VuiSideList, VuiSideListButton, VuiSimpleCard, VuiSimpleGrid, VuiSpacer, VuiSpans, VuiSpinner, VuiStat, VuiStatList, VuiStatus, VuiStepNavigator, VuiSteps, VuiStepsVertical, VuiSummary, VuiSkeleton, VuiSummaryCitation, VuiSuperCheckboxGroup, VuiSuperRadioGroup, VuiTable, VuiTab, VuiTabbedRoutes, VuiTabs, VuiTabsNavigator, VuiText, VuiTextArea, VuiTextColor, VuiTextInput, VuiTimeline, VuiTimelineItem, VuiTitle, VuiToggle, VuiTooltip, VuiTopicButton };
|
package/lib/components/index.js
CHANGED
|
@@ -85,6 +85,7 @@ import { SPINNER_COLOR, SPINNER_SIZE } from "./spinner/types";
|
|
|
85
85
|
import { VuiStatList } from "./statList/StatList";
|
|
86
86
|
import { VuiStat } from "./stat/Stat";
|
|
87
87
|
import { VuiStatus } from "./status/Status";
|
|
88
|
+
import { VuiStepNavigator } from "./stepNavigator/StepNavigator";
|
|
88
89
|
import { VuiSteps } from "./steps/Steps";
|
|
89
90
|
import { VuiStepsVertical } from "./stepsVertical/StepsVertical";
|
|
90
91
|
import { SKELETON_COLOR, VuiSkeleton } from "./skeleton/Skeleton";
|
|
@@ -107,4 +108,4 @@ import { VuiInfoTooltip } from "./tooltip/InfoTooltip";
|
|
|
107
108
|
import { VuiTopicButton } from "./topicButton/TopicButton";
|
|
108
109
|
import { copyToClipboard } from "../utils/copyToClipboard";
|
|
109
110
|
import { toRgb, toRgba } from "./context/Theme";
|
|
110
|
-
export { BADGE_COLOR, BUTTON_COLOR, BUTTON_SIZE, CHART_PALETTE, CALLOUT_COLOR, CALLOUT_SIZE, DURATION_BAR_COLOR, ICON_COLOR, ICON_SIZE, ICON_TYPE, PATCH_COLOR, PROGRESS_BAR_COLOR, SPACER_SIZE, SPINNER_COLOR, SKELETON_COLOR, SPINNER_SIZE, TAB_SIZE, TEXT_COLOR, TEXT_SIZE, TITLE_SIZE, addNotification, copyToClipboard, generateTokensProvider, toRgb, toRgba, VuiAccordion, VuiAccountButton, VuiAppContent, VuiAppHeader, VuiAppLayout, VuiAppSideNav, VuiAppSideNavLink, VuiAppSideNavGroup, VuiBadge, VuiBarChart, VuiComposedChart, VuiLineChart, VuiPieChart, VuiScatterChart, VuiSparkline, VuiTreeMap, VuiButtonPrimary, VuiButtonSecondary, VuiButtonTertiary, VuiIconButton, VuiCallout, VuiCard, VuiChat, VuiCheckbox, VuiChip, VuiCode, VuiCodeEditor, VuiComposer, VuiComplexConfigurationButton, VuiContextProvider, VuiCopyButton, VuiDatePicker, VuiDateRangePicker, VuiDrawer, VuiDurationBar, VuiErrorBoundary, VuiFileDropTarget, VuiFlexContainer, VuiFlexItem, VuiFormGroup, VuiGrid, VuiGridItem, VuiHorizontalRule, VuiIcon, VuiImage, VuiImagePreview, VuiInfoList, VuiInfoListItem, VuiInfoMenu, VuiInfoTable, VuiInfoTooltip, VuiKvTable, VuiInProgress, VuiItemsInput, VuiLabel, VuiLink, VuiLinkInternal, VuiList, VuiMenu, VuiMenuItem, VuiMenuList, VuiMenuListButton, VuiModal, VuiNotifications, VuiNumberInput, VuiOptionsButton, VuiOptionsList, VuiOptionsListItem, VuiPagination, VuiPanel, VuiPasswordInput, VuiPatch, VuiPopover, VuiPortal, VuiProgressBar, VuiPrompt, VuiRadioButton, VuiScreenBlock, VuiSearchInput, VuiSearchResult, VuiSearchSelect, VuiSelect, VuiSetting, VuiSideList, VuiSideListButton, VuiSimpleCard, VuiSimpleGrid, VuiSpacer, VuiSpans, VuiSpinner, VuiStat, VuiStatList, VuiStatus, VuiSteps, VuiStepsVertical, VuiSummary, VuiSkeleton, VuiSummaryCitation, VuiSuperCheckboxGroup, VuiSuperRadioGroup, VuiTable, VuiTab, VuiTabbedRoutes, VuiTabs, VuiTabsNavigator, VuiText, VuiTextArea, VuiTextColor, VuiTextInput, VuiTimeline, VuiTimelineItem, VuiTitle, VuiToggle, VuiTooltip, VuiTopicButton };
|
|
111
|
+
export { BADGE_COLOR, BUTTON_COLOR, BUTTON_SIZE, CHART_PALETTE, CALLOUT_COLOR, CALLOUT_SIZE, DURATION_BAR_COLOR, ICON_COLOR, ICON_SIZE, ICON_TYPE, PATCH_COLOR, PROGRESS_BAR_COLOR, SPACER_SIZE, SPINNER_COLOR, SKELETON_COLOR, SPINNER_SIZE, TAB_SIZE, TEXT_COLOR, TEXT_SIZE, TITLE_SIZE, addNotification, copyToClipboard, generateTokensProvider, toRgb, toRgba, VuiAccordion, VuiAccountButton, VuiAppContent, VuiAppHeader, VuiAppLayout, VuiAppSideNav, VuiAppSideNavLink, VuiAppSideNavGroup, VuiBadge, VuiBarChart, VuiComposedChart, VuiLineChart, VuiPieChart, VuiScatterChart, VuiSparkline, VuiTreeMap, VuiButtonPrimary, VuiButtonSecondary, VuiButtonTertiary, VuiIconButton, VuiCallout, VuiCard, VuiChat, VuiCheckbox, VuiChip, VuiCode, VuiCodeEditor, VuiComposer, VuiComplexConfigurationButton, VuiContextProvider, VuiCopyButton, VuiDatePicker, VuiDateRangePicker, VuiDrawer, VuiDurationBar, VuiErrorBoundary, VuiFileDropTarget, VuiFlexContainer, VuiFlexItem, VuiFormGroup, VuiGrid, VuiGridItem, VuiHorizontalRule, VuiIcon, VuiImage, VuiImagePreview, VuiInfoList, VuiInfoListItem, VuiInfoMenu, VuiInfoTable, VuiInfoTooltip, VuiKvTable, VuiInProgress, VuiItemsInput, VuiLabel, VuiLink, VuiLinkInternal, VuiList, VuiMenu, VuiMenuItem, VuiMenuList, VuiMenuListButton, VuiModal, VuiNotifications, VuiNumberInput, VuiOptionsButton, VuiOptionsList, VuiOptionsListItem, VuiPagination, VuiPanel, VuiPasswordInput, VuiPatch, VuiPopover, VuiPortal, VuiProgressBar, VuiPrompt, VuiRadioButton, VuiScreenBlock, VuiSearchInput, VuiSearchResult, VuiSearchSelect, VuiSelect, VuiSetting, VuiSideList, VuiSideListButton, VuiSimpleCard, VuiSimpleGrid, VuiSpacer, VuiSpans, VuiSpinner, VuiStat, VuiStatList, VuiStatus, VuiStepNavigator, VuiSteps, VuiStepsVertical, VuiSummary, VuiSkeleton, VuiSummaryCitation, VuiSuperCheckboxGroup, VuiSuperRadioGroup, VuiTable, VuiTab, VuiTabbedRoutes, VuiTabs, VuiTabsNavigator, VuiText, VuiTextArea, VuiTextColor, VuiTextInput, VuiTimeline, VuiTimelineItem, VuiTitle, VuiToggle, VuiTooltip, VuiTopicButton };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Props as VuiTooltipProps } from "../tooltip/Tooltip";
|
|
3
|
-
export type AnchorSide = "left" | "right" | "rightUp" | "rightDown" | "leftUp" | "leftDown" | "upLeft" | "upRight";
|
|
3
|
+
export type AnchorSide = "left" | "right" | "center" | "rightUp" | "rightDown" | "leftUp" | "leftDown" | "upLeft" | "upRight";
|
|
4
4
|
export type Props = {
|
|
5
5
|
button: React.ReactElement;
|
|
6
6
|
children?: React.ReactNode;
|
|
@@ -57,6 +57,11 @@ const calculatePopoverPosition = (button, anchorOptions) => {
|
|
|
57
57
|
return { bottom: `${adjustedBottom}px`, right: `${adjustedRight}px` };
|
|
58
58
|
}
|
|
59
59
|
const adjustedTop = bottom + offsetY + document.documentElement.scrollTop;
|
|
60
|
+
if (anchorSide === "center") {
|
|
61
|
+
// Anchor below the button, horizontally centered on it. Pairs with a
|
|
62
|
+
// translateX(-50%) in CSS to offset by half the popover's own width.
|
|
63
|
+
return { top: `${adjustedTop}px`, left: `${left + width / 2}px` };
|
|
64
|
+
}
|
|
60
65
|
if (anchorSide === "left") {
|
|
61
66
|
return { top: `${adjustedTop}px`, left: `${left}px` };
|
|
62
67
|
}
|
|
@@ -160,6 +165,7 @@ export const VuiPopover = (_a) => {
|
|
|
160
165
|
});
|
|
161
166
|
const classes = classNames("vuiPopover", className, {
|
|
162
167
|
"vuiPopover-isLoaded": showTransition,
|
|
168
|
+
"vuiPopover--center": anchorSide === "center",
|
|
163
169
|
"vuiPopover--rightUp": anchorSide === "rightUp",
|
|
164
170
|
"vuiPopover--leftUp": anchorSide === "leftUp",
|
|
165
171
|
"vuiPopover--upLeft": anchorSide === "upLeft",
|
|
@@ -27,6 +27,16 @@
|
|
|
27
27
|
transform: translateY(-100%) !important;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
// Centered below the button: shift left by half the popover's width while
|
|
31
|
+
// preserving the vertical enter transition.
|
|
32
|
+
.vuiPopover--center {
|
|
33
|
+
transform: translate(-50%, -$sizeXs);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.vuiPopover--center.vuiPopover-isLoaded {
|
|
37
|
+
transform: translate(-50%, 0);
|
|
38
|
+
}
|
|
39
|
+
|
|
30
40
|
.vuiPopover--upLeft,
|
|
31
41
|
.vuiPopover--upRight {
|
|
32
42
|
transform: translateY(0);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { StepVertical } from "../stepsVertical/StepsVertical";
|
|
2
|
+
export type StepNavigatorStep = Omit<StepVertical, "isActive" | "onSelect">;
|
|
3
|
+
export type StepNavigatorSteps = StepNavigatorStep[];
|
|
4
|
+
type Props = {
|
|
5
|
+
steps: StepNavigatorSteps;
|
|
6
|
+
activeStep: number;
|
|
7
|
+
showStepCount?: boolean;
|
|
8
|
+
onStepChange?: (index: number, step: StepNavigatorStep) => void;
|
|
9
|
+
onNext?: (index: number, step: StepNavigatorStep) => void;
|
|
10
|
+
onPrevious?: (index: number, step: StepNavigatorStep) => void;
|
|
11
|
+
onSelect?: (index: number, step: StepNavigatorStep) => void;
|
|
12
|
+
className?: string;
|
|
13
|
+
"data-testid"?: string;
|
|
14
|
+
};
|
|
15
|
+
export declare const VuiStepNavigator: ({ steps, activeStep, showStepCount, onStepChange, onNext, onPrevious, onSelect, className, "data-testid": dataTestId }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef, useState } from "react";
|
|
3
|
+
import classNames from "classnames";
|
|
4
|
+
import { BiChevronDown, BiChevronLeft, BiChevronRight } from "react-icons/bi";
|
|
5
|
+
import { VuiIcon } from "../icon/Icon";
|
|
6
|
+
import { VuiPopover } from "../popover/Popover";
|
|
7
|
+
import { VuiStepsVertical } from "../stepsVertical/StepsVertical";
|
|
8
|
+
// Center pill that displays the current step and toggles the dropdown. Receives
|
|
9
|
+
// `isSelected` and `onClick` from VuiPopover, which clones it as its trigger.
|
|
10
|
+
const StepNavigatorTrigger = forwardRef(({ icon, title, stepLabel, showStepCount, isSelected, onClick, "data-testid": dataTestId }, ref) => (_jsxs("button", Object.assign({ type: "button", ref: ref, onClick: onClick, "aria-haspopup": "listbox", "aria-expanded": Boolean(isSelected), "data-testid": dataTestId, className: classNames("vuiStepNavigator__trigger", {
|
|
11
|
+
"vuiStepNavigator__trigger--open": isSelected
|
|
12
|
+
}) }, { children: [_jsx(VuiIcon, Object.assign({ size: "s", color: "primary" }, { children: icon })), _jsx("span", Object.assign({ className: "vuiStepNavigator__triggerTitle" }, { children: title })), showStepCount && _jsxs("span", Object.assign({ className: "vuiStepNavigator__triggerCount" }, { children: [" \u00B7 ", stepLabel] })), _jsx("span", Object.assign({ className: classNames("vuiStepNavigator__caret", {
|
|
13
|
+
"vuiStepNavigator__caret--open": isSelected
|
|
14
|
+
}) }, { children: _jsx(VuiIcon, Object.assign({ size: "s", color: "subdued" }, { children: _jsx(BiChevronDown, {}) })) }))] }))));
|
|
15
|
+
export const VuiStepNavigator = ({ steps, activeStep, showStepCount = true, onStepChange, onNext, onPrevious, onSelect, className, "data-testid": dataTestId }) => {
|
|
16
|
+
const clamp = (index) => Math.max(0, Math.min(steps.length - 1, index));
|
|
17
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
18
|
+
const active = clamp(activeStep);
|
|
19
|
+
const current = steps[active];
|
|
20
|
+
const commit = (index) => {
|
|
21
|
+
const nextIndex = clamp(index);
|
|
22
|
+
setIsOpen(false);
|
|
23
|
+
onStepChange === null || onStepChange === void 0 ? void 0 : onStepChange(nextIndex, steps[nextIndex]);
|
|
24
|
+
};
|
|
25
|
+
const goPrevious = () => {
|
|
26
|
+
if (active <= 0)
|
|
27
|
+
return;
|
|
28
|
+
onPrevious === null || onPrevious === void 0 ? void 0 : onPrevious(active - 1, steps[active - 1]);
|
|
29
|
+
commit(active - 1);
|
|
30
|
+
};
|
|
31
|
+
const goNext = () => {
|
|
32
|
+
if (active >= steps.length - 1)
|
|
33
|
+
return;
|
|
34
|
+
onNext === null || onNext === void 0 ? void 0 : onNext(active + 1, steps[active + 1]);
|
|
35
|
+
commit(active + 1);
|
|
36
|
+
};
|
|
37
|
+
const select = (index) => {
|
|
38
|
+
onSelect === null || onSelect === void 0 ? void 0 : onSelect(index, steps[index]);
|
|
39
|
+
commit(index);
|
|
40
|
+
};
|
|
41
|
+
const prevDisabled = active <= 0;
|
|
42
|
+
const nextDisabled = active >= steps.length - 1;
|
|
43
|
+
const stepLabel = `Step ${active + 1} of ${steps.length}`;
|
|
44
|
+
const verticalSteps = steps.map((step, index) => (Object.assign(Object.assign({}, step), { isActive: index === active, onSelect: () => select(index) })));
|
|
45
|
+
const menu = (_jsx(VuiStepsVertical, { className: "vuiStepNavigator__menu", steps: verticalSteps, "data-testid": dataTestId ? `${dataTestId}-menu` : undefined }));
|
|
46
|
+
return (_jsxs("div", Object.assign({ className: classNames("vuiStepNavigator", className), "data-testid": dataTestId }, { children: [_jsx("button", Object.assign({ type: "button", className: "vuiStepNavigator__sideButton", onClick: goPrevious, disabled: prevDisabled, "aria-label": "Previous step", "data-testid": dataTestId ? `${dataTestId}-previous` : undefined }, { children: _jsx(VuiIcon, Object.assign({ size: "m" }, { children: _jsx(BiChevronLeft, {}) })) })), _jsx("div", Object.assign({ className: "vuiStepNavigator__center" }, { children: _jsx(VuiPopover, Object.assign({ className: "vuiStepNavigator__popover", anchorSide: "center", anchorOffsetY: 8, padding: "none", isOpen: isOpen, setIsOpen: setIsOpen, button: _jsx(StepNavigatorTrigger, { icon: current.icon, title: current.title, stepLabel: stepLabel, showStepCount: showStepCount, "data-testid": dataTestId ? `${dataTestId}-trigger` : undefined }) }, { children: menu })) })), _jsx("button", Object.assign({ type: "button", className: "vuiStepNavigator__sideButton", onClick: goNext, disabled: nextDisabled, "aria-label": "Next step", "data-testid": dataTestId ? `${dataTestId}-next` : undefined }, { children: _jsx(VuiIcon, Object.assign({ size: "m" }, { children: _jsx(BiChevronRight, {}) })) }))] })));
|
|
47
|
+
};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
@import "../../sassUtils/index";
|
|
2
|
+
|
|
3
|
+
$stepNavigatorBarHeight: 44px;
|
|
4
|
+
$stepNavigatorRadius: $sizeXs; // 8px buttons & pill & rows.
|
|
5
|
+
|
|
6
|
+
.vuiStepNavigator {
|
|
7
|
+
display: flex;
|
|
8
|
+
align-items: stretch;
|
|
9
|
+
gap: $sizeXs;
|
|
10
|
+
width: 100%;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Square previous / next chevron buttons.
|
|
14
|
+
.vuiStepNavigator__sideButton {
|
|
15
|
+
flex: 0 0 auto;
|
|
16
|
+
display: flex;
|
|
17
|
+
align-items: center;
|
|
18
|
+
justify-content: center;
|
|
19
|
+
width: $stepNavigatorBarHeight;
|
|
20
|
+
padding: 0;
|
|
21
|
+
background-color: var(--vui-color-empty-shade);
|
|
22
|
+
border: 1px solid var(--vui-color-border-medium);
|
|
23
|
+
border-radius: $stepNavigatorRadius;
|
|
24
|
+
color: var(--vui-color-darker-shade);
|
|
25
|
+
cursor: pointer;
|
|
26
|
+
transition: box-shadow $transitionSpeed;
|
|
27
|
+
|
|
28
|
+
&:not(:disabled):hover {
|
|
29
|
+
box-shadow: $shadowSmallEnd;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&:disabled {
|
|
33
|
+
color: var(--vui-color-subdued-shade);
|
|
34
|
+
opacity: 0.45;
|
|
35
|
+
cursor: not-allowed;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.vuiStepNavigator__center {
|
|
40
|
+
flex: 1 1 auto;
|
|
41
|
+
min-width: 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Center pill: current-step display and dropdown trigger.
|
|
45
|
+
.vuiStepNavigator__trigger {
|
|
46
|
+
display: flex;
|
|
47
|
+
align-items: center;
|
|
48
|
+
justify-content: center;
|
|
49
|
+
flex-wrap: wrap;
|
|
50
|
+
gap: $sizeXs;
|
|
51
|
+
width: 100%;
|
|
52
|
+
min-height: $stepNavigatorBarHeight;
|
|
53
|
+
padding: $sizeS $sizeM;
|
|
54
|
+
background-color: var(--vui-color-empty-shade);
|
|
55
|
+
border: 1px solid var(--vui-color-medium-shade);
|
|
56
|
+
border-radius: $stepNavigatorRadius;
|
|
57
|
+
cursor: pointer;
|
|
58
|
+
transition: border-color $transitionSpeed, box-shadow $transitionSpeed, background-color $transitionSpeed;
|
|
59
|
+
|
|
60
|
+
&:hover {
|
|
61
|
+
box-shadow: $shadowSmallEnd;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
&--open {
|
|
65
|
+
background-color: var(--vui-color-primary-lighter-shade);
|
|
66
|
+
border-color: var(--vui-color-primary-shade);
|
|
67
|
+
box-shadow: 0 0 0 3px rgba(var(--vui-color-primary-shade-rgb), 0.14);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.vuiStepNavigator__triggerTitle {
|
|
72
|
+
font-size: $fontSizeLarge - 3px; // 15px
|
|
73
|
+
font-weight: $fontWeightBold;
|
|
74
|
+
color: var(--vui-color-darker-shade);
|
|
75
|
+
white-space: nowrap;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.vuiStepNavigator__triggerCount {
|
|
79
|
+
font-size: $fontSizeStandard;
|
|
80
|
+
font-weight: $fontWeightNormal;
|
|
81
|
+
color: var(--vui-color-subdued-shade);
|
|
82
|
+
white-space: nowrap;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.vuiStepNavigator__caret {
|
|
86
|
+
display: flex;
|
|
87
|
+
transition: transform $transitionSpeed;
|
|
88
|
+
|
|
89
|
+
&--open {
|
|
90
|
+
transform: rotate(180deg);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Dropdown panel: applied to the VuiPopover surface to round and lighten it.
|
|
95
|
+
.vuiStepNavigator__popover {
|
|
96
|
+
border-radius: $sizeS;
|
|
97
|
+
border-color: var(--vui-color-border-light);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Dropdown body: VuiStepsVertical, constrained to the trigger's footprint.
|
|
101
|
+
.vuiStepNavigator__menu {
|
|
102
|
+
width: 340px;
|
|
103
|
+
max-width: 94vw;
|
|
104
|
+
padding: $sizeXs;
|
|
105
|
+
}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
export type { StepVerticalStatus } from "./types";
|
|
2
|
-
export type
|
|
2
|
+
export type StepVertical = {
|
|
3
3
|
id: string;
|
|
4
4
|
title: string;
|
|
5
5
|
isActive?: boolean;
|
|
6
6
|
hasErrors?: boolean;
|
|
7
|
+
isComplete?: boolean;
|
|
7
8
|
icon: React.ReactNode;
|
|
8
9
|
onSelect: () => void;
|
|
9
10
|
"data-testid"?: string;
|
|
10
|
-
}
|
|
11
|
+
};
|
|
12
|
+
export type StepsVertical = StepVertical[];
|
|
11
13
|
type Props = {
|
|
12
14
|
steps: StepsVertical;
|
|
13
15
|
className?: string;
|
|
@@ -10,7 +10,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
12
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
-
import { BiError } from "react-icons/bi";
|
|
13
|
+
import { BiCheckCircle, BiError } from "react-icons/bi";
|
|
14
14
|
import { VuiIcon } from "../icon/Icon";
|
|
15
15
|
import { VuiMenuList } from "../menuList/VuiMenuList";
|
|
16
16
|
import { VuiMenuListButton } from "../menuList/VuiMenuListButton";
|
|
@@ -18,8 +18,8 @@ export const VuiStepsVertical = (_a) => {
|
|
|
18
18
|
var { steps, className, "data-testid": dataTestId } = _a, rest = __rest(_a, ["steps", "className", "data-testid"]);
|
|
19
19
|
return (_jsx(VuiMenuList, Object.assign({ className: className, "data-testid": dataTestId }, rest, { children: steps.map((step) => {
|
|
20
20
|
var _a;
|
|
21
|
-
const { id, title, isActive, hasErrors, icon, onSelect } = step;
|
|
21
|
+
const { id, title, isActive, hasErrors, isComplete, icon, onSelect } = step;
|
|
22
22
|
const stepTestId = (_a = step["data-testid"]) !== null && _a !== void 0 ? _a : `${dataTestId}-step-${id}`;
|
|
23
|
-
return (_jsx(VuiMenuListButton, Object.assign({ isActive: isActive, onClick: () => onSelect(), "data-testid": stepTestId, icon: icon, append: hasErrors
|
|
23
|
+
return (_jsx(VuiMenuListButton, Object.assign({ isActive: isActive, onClick: () => onSelect(), "data-testid": stepTestId, icon: icon, append: hasErrors ? (_jsx(VuiIcon, Object.assign({ size: "s", color: "danger", "data-testid": `${stepTestId}-error` }, { children: _jsx(BiError, {}) }))) : (isComplete && (_jsx(VuiIcon, Object.assign({ size: "s", color: "success", "data-testid": `${stepTestId}-complete` }, { children: _jsx(BiCheckCircle, {}) })))) }, { children: title }), id));
|
|
24
24
|
}) })));
|
|
25
25
|
};
|
package/lib/styles/index.css
CHANGED
|
@@ -403,7 +403,6 @@ fieldset {
|
|
|
403
403
|
flex-direction: column;
|
|
404
404
|
align-items: center;
|
|
405
405
|
overflow-y: auto;
|
|
406
|
-
scrollbar-gutter: stable;
|
|
407
406
|
}
|
|
408
407
|
|
|
409
408
|
.vuiAppSideNav {
|
|
@@ -4787,6 +4786,14 @@ h2.react-datepicker__current-month {
|
|
|
4787
4786
|
transform: translateY(-100%) !important;
|
|
4788
4787
|
}
|
|
4789
4788
|
|
|
4789
|
+
.vuiPopover--center {
|
|
4790
|
+
transform: translate(-50%, -8px);
|
|
4791
|
+
}
|
|
4792
|
+
|
|
4793
|
+
.vuiPopover--center.vuiPopover-isLoaded {
|
|
4794
|
+
transform: translate(-50%, 0);
|
|
4795
|
+
}
|
|
4796
|
+
|
|
4790
4797
|
.vuiPopover--upLeft,
|
|
4791
4798
|
.vuiPopover--upRight {
|
|
4792
4799
|
transform: translateY(0);
|
|
@@ -5525,6 +5532,98 @@ h2.react-datepicker__current-month {
|
|
|
5525
5532
|
font-size: 12px !important;
|
|
5526
5533
|
}
|
|
5527
5534
|
|
|
5535
|
+
.vuiStepNavigator {
|
|
5536
|
+
display: flex;
|
|
5537
|
+
align-items: stretch;
|
|
5538
|
+
gap: 8px;
|
|
5539
|
+
width: 100%;
|
|
5540
|
+
}
|
|
5541
|
+
|
|
5542
|
+
.vuiStepNavigator__sideButton {
|
|
5543
|
+
flex: 0 0 auto;
|
|
5544
|
+
display: flex;
|
|
5545
|
+
align-items: center;
|
|
5546
|
+
justify-content: center;
|
|
5547
|
+
width: 44px;
|
|
5548
|
+
padding: 0;
|
|
5549
|
+
background-color: var(--vui-color-empty-shade);
|
|
5550
|
+
border: 1px solid var(--vui-color-border-medium);
|
|
5551
|
+
border-radius: 8px;
|
|
5552
|
+
color: var(--vui-color-darker-shade);
|
|
5553
|
+
cursor: pointer;
|
|
5554
|
+
transition: box-shadow 0.2s;
|
|
5555
|
+
}
|
|
5556
|
+
.vuiStepNavigator__sideButton:not(:disabled):hover {
|
|
5557
|
+
box-shadow: rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 2px 6px 2px;
|
|
5558
|
+
}
|
|
5559
|
+
.vuiStepNavigator__sideButton:disabled {
|
|
5560
|
+
color: var(--vui-color-subdued-shade);
|
|
5561
|
+
opacity: 0.45;
|
|
5562
|
+
cursor: not-allowed;
|
|
5563
|
+
}
|
|
5564
|
+
|
|
5565
|
+
.vuiStepNavigator__center {
|
|
5566
|
+
flex: 1 1 auto;
|
|
5567
|
+
min-width: 0;
|
|
5568
|
+
}
|
|
5569
|
+
|
|
5570
|
+
.vuiStepNavigator__trigger {
|
|
5571
|
+
display: flex;
|
|
5572
|
+
align-items: center;
|
|
5573
|
+
justify-content: center;
|
|
5574
|
+
flex-wrap: wrap;
|
|
5575
|
+
gap: 8px;
|
|
5576
|
+
width: 100%;
|
|
5577
|
+
min-height: 44px;
|
|
5578
|
+
padding: 12px 16px;
|
|
5579
|
+
background-color: var(--vui-color-empty-shade);
|
|
5580
|
+
border: 1px solid var(--vui-color-medium-shade);
|
|
5581
|
+
border-radius: 8px;
|
|
5582
|
+
cursor: pointer;
|
|
5583
|
+
transition: border-color 0.2s, box-shadow 0.2s, background-color 0.2s;
|
|
5584
|
+
}
|
|
5585
|
+
.vuiStepNavigator__trigger:hover {
|
|
5586
|
+
box-shadow: rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 2px 6px 2px;
|
|
5587
|
+
}
|
|
5588
|
+
.vuiStepNavigator__trigger--open {
|
|
5589
|
+
background-color: var(--vui-color-primary-lighter-shade);
|
|
5590
|
+
border-color: var(--vui-color-primary-shade);
|
|
5591
|
+
box-shadow: 0 0 0 3px rgba(var(--vui-color-primary-shade-rgb), 0.14);
|
|
5592
|
+
}
|
|
5593
|
+
|
|
5594
|
+
.vuiStepNavigator__triggerTitle {
|
|
5595
|
+
font-size: 15px;
|
|
5596
|
+
font-weight: 600;
|
|
5597
|
+
color: var(--vui-color-darker-shade);
|
|
5598
|
+
white-space: nowrap;
|
|
5599
|
+
}
|
|
5600
|
+
|
|
5601
|
+
.vuiStepNavigator__triggerCount {
|
|
5602
|
+
font-size: 14px;
|
|
5603
|
+
font-weight: 400;
|
|
5604
|
+
color: var(--vui-color-subdued-shade);
|
|
5605
|
+
white-space: nowrap;
|
|
5606
|
+
}
|
|
5607
|
+
|
|
5608
|
+
.vuiStepNavigator__caret {
|
|
5609
|
+
display: flex;
|
|
5610
|
+
transition: transform 0.2s;
|
|
5611
|
+
}
|
|
5612
|
+
.vuiStepNavigator__caret--open {
|
|
5613
|
+
transform: rotate(180deg);
|
|
5614
|
+
}
|
|
5615
|
+
|
|
5616
|
+
.vuiStepNavigator__popover {
|
|
5617
|
+
border-radius: 12px;
|
|
5618
|
+
border-color: var(--vui-color-border-light);
|
|
5619
|
+
}
|
|
5620
|
+
|
|
5621
|
+
.vuiStepNavigator__menu {
|
|
5622
|
+
width: 340px;
|
|
5623
|
+
max-width: 94vw;
|
|
5624
|
+
padding: 8px;
|
|
5625
|
+
}
|
|
5626
|
+
|
|
5528
5627
|
.vuiSteps {
|
|
5529
5628
|
width: 100%;
|
|
5530
5629
|
position: relative;
|
package/package.json
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { BiLink, BiLock, BiMessageRounded, BiPencil, BiShow, BiSolidMagicWand } from "react-icons/bi";
|
|
3
|
+
import { VuiStepNavigator, StepNavigatorSteps } from "../../../lib";
|
|
4
|
+
|
|
5
|
+
const steps: StepNavigatorSteps = [
|
|
6
|
+
{ id: "branding", title: "Branding", icon: <BiPencil />, isComplete: true },
|
|
7
|
+
{ id: "welcome", title: "Welcome", icon: <BiMessageRounded />, isComplete: true },
|
|
8
|
+
{ id: "prompts", title: "Suggested prompts", icon: <BiSolidMagicWand />, hasErrors: true },
|
|
9
|
+
{ id: "events", title: "Event visibility", icon: <BiShow /> },
|
|
10
|
+
{ id: "access", title: "Access & SSO", icon: <BiLock /> },
|
|
11
|
+
{ id: "url", title: "Public URL", icon: <BiLink /> }
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
export const BasicStepNavigator = () => {
|
|
15
|
+
const [activeStep, setActiveStep] = useState(1);
|
|
16
|
+
|
|
17
|
+
return <VuiStepNavigator steps={steps} activeStep={activeStep} onStepChange={(index) => setActiveStep(index)} />;
|
|
18
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BasicStepNavigator } from "./BasicStepNavigator";
|
|
2
|
+
|
|
3
|
+
const BasicStepNavigatorSource = require("!!raw-loader!./BasicStepNavigator");
|
|
4
|
+
|
|
5
|
+
export const stepNavigator = {
|
|
6
|
+
name: "Step navigator",
|
|
7
|
+
path: "/step-navigator",
|
|
8
|
+
example: {
|
|
9
|
+
component: <BasicStepNavigator />,
|
|
10
|
+
source: BasicStepNavigatorSource.default.toString()
|
|
11
|
+
}
|
|
12
|
+
};
|
package/src/docs/pages.tsx
CHANGED
|
@@ -65,6 +65,7 @@ import { spinner } from "./pages/spinner";
|
|
|
65
65
|
import { stat } from "./pages/stat";
|
|
66
66
|
import { status } from "./pages/status";
|
|
67
67
|
import { statList } from "./pages/statList";
|
|
68
|
+
import { stepNavigator } from "./pages/stepNavigator";
|
|
68
69
|
import { steps } from "./pages/steps";
|
|
69
70
|
import { stepsVertical } from "./pages/stepsVertical";
|
|
70
71
|
import { summary } from "./pages/summary";
|
|
@@ -111,7 +112,7 @@ export const categories: Category[] = [
|
|
|
111
112
|
},
|
|
112
113
|
{
|
|
113
114
|
name: "Navigation",
|
|
114
|
-
pages: [tabs, stepsVertical, steps, chip]
|
|
115
|
+
pages: [tabs, stepsVertical, steps, stepNavigator, chip]
|
|
115
116
|
},
|
|
116
117
|
{
|
|
117
118
|
name: "Content",
|