@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.
@@ -20,5 +20,4 @@
20
20
  flex-direction: column;
21
21
  align-items: center;
22
22
  overflow-y: auto;
23
- scrollbar-gutter: stable;
24
23
  }
@@ -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 };
@@ -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 StepsVertical = {
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 && (_jsx(VuiIcon, Object.assign({ size: "s", color: "danger", "data-testid": `${stepTestId}-error` }, { children: _jsx(BiError, {}) }))) }, { children: title }), id));
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
  };
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vectara/vectara-ui",
3
- "version": "20.1.0",
3
+ "version": "20.2.1",
4
4
  "homepage": "./",
5
5
  "description": "Vectara's design system, codified as a React and Sass component library",
6
6
  "author": "Vectara",
@@ -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
+ };
@@ -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",