@vectara/vectara-ui 15.7.1 → 15.8.0

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.
@@ -44,8 +44,17 @@ export const VuiDrawer = (_a) => {
44
44
  onClose === null || onClose === void 0 ? void 0 : onClose();
45
45
  }, 0);
46
46
  };
47
+ // Handle outside clicks, but ignore clicks on notifications.
48
+ const handleClickOutside = (event) => {
49
+ const target = event.target;
50
+ // Check if the click is within a notification.
51
+ if (target.closest("[data-awareness='notification']")) {
52
+ return;
53
+ }
54
+ onCloseDelayed();
55
+ };
47
56
  const classes = classNames("vuiDrawer", `vuiDrawer--${color}`, className);
48
- return (_jsx(VuiPortal, { children: isOpen && (_jsx(VuiScreenBlock, { children: _jsx(FocusOn, Object.assign({ onEscapeKey: onCloseDelayed, onClickOutside: onCloseDelayed,
57
+ return (_jsx(VuiPortal, { children: isOpen && (_jsx(VuiScreenBlock, { children: _jsx(FocusOn, Object.assign({ onEscapeKey: onCloseDelayed, onClickOutside: handleClickOutside,
49
58
  // Enable manual focus return to work.
50
59
  returnFocus: false,
51
60
  // Enable focus on contents when it's open,
@@ -88,8 +88,9 @@ import { TEXT_COLOR, TEXT_SIZE, TITLE_SIZE } from "./typography/types";
88
88
  import { VuiTitle } from "./typography/Title";
89
89
  import { VuiToggle } from "./toggle/Toggle";
90
90
  import { VuiTooltip } from "./tooltip/Tooltip";
91
+ import { VuiInfoTooltip } from "./tooltip/InfoTooltip";
91
92
  import { VuiTopicButton } from "./topicButton/TopicButton";
92
93
  import { copyToClipboard } from "../utils/copyToClipboard";
93
94
  import { toRgb, toRgba } from "./context/Theme";
94
95
  export type { AnchorSide, AppContentPadding, ButtonColor, CalloutColor, ChatLanguage, ChatStyle, ChatTurn, CheckboxConfig, CodeEditorColorConfig, CodeEditorError, CodeLanguage, InfoListItemType, InfoListType, InfoTableColumnAlign, InfoTableRow, InfoTableRowType, LinkProps, MenuItem, OptionListItem, Pagination, RadioButtonConfig, SearchResult, SearchSuggestion, Sections, SectionItem, Stat, StepStatus, StepSize, TabSize, Tree, TreeItem, VuiStepProps };
95
- export { BADGE_COLOR, BUTTON_COLOR, BUTTON_SIZE, CALLOUT_COLOR, CALLOUT_SIZE, ICON_COLOR, ICON_SIZE, ICON_TYPE, 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, VuiButtonPrimary, VuiButtonSecondary, VuiButtonTertiary, VuiIconButton, VuiCallout, VuiCard, VuiChat, VuiCheckbox, VuiCode, VuiCodeEditor, VuiContextProvider, VuiCopyButton, VuiDatePicker, VuiDateRangePicker, VuiDrawer, VuiErrorBoundary, VuiFlexContainer, VuiFlexItem, VuiFormGroup, VuiGrid, VuiGridItem, VuiHorizontalRule, VuiIcon, VuiImage, VuiImagePreview, VuiInfoList, VuiInfoListItem, VuiInfoMenu, VuiInfoTable, VuiInProgress, VuiItemsInput, VuiLabel, VuiLink, VuiLinkInternal, VuiList, VuiMenu, VuiMenuItem, VuiModal, VuiNotifications, VuiNumberInput, VuiOptionsButton, VuiOptionsList, VuiOptionsListItem, VuiPagination, VuiPanel, VuiPasswordInput, VuiPopover, VuiPortal, VuiProgressBar, VuiPrompt, VuiRadioButton, VuiScreenBlock, VuiSearchInput, VuiSearchResult, VuiSearchSelect, VuiSelect, VuiSetting, VuiSimpleCard, VuiSimpleGrid, VuiSpacer, VuiSpinner, VuiStat, VuiStatList, VuiStatus, VuiSteps, VuiSummary, VuiSkeleton, VuiSummaryCitation, VuiSuperCheckboxGroup, VuiSuperRadioGroup, VuiTable, VuiTab, VuiTabbedRoutes, VuiTabs, VuiText, VuiTextArea, VuiTextColor, VuiTextInput, VuiTimeline, VuiTimelineItem, VuiTitle, VuiToggle, VuiTooltip, VuiTopicButton };
96
+ export { BADGE_COLOR, BUTTON_COLOR, BUTTON_SIZE, CALLOUT_COLOR, CALLOUT_SIZE, ICON_COLOR, ICON_SIZE, ICON_TYPE, 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, VuiButtonPrimary, VuiButtonSecondary, VuiButtonTertiary, VuiIconButton, VuiCallout, VuiCard, VuiChat, VuiCheckbox, VuiCode, VuiCodeEditor, VuiContextProvider, VuiCopyButton, VuiDatePicker, VuiDateRangePicker, VuiDrawer, VuiErrorBoundary, VuiFlexContainer, VuiFlexItem, VuiFormGroup, VuiGrid, VuiGridItem, VuiHorizontalRule, VuiIcon, VuiImage, VuiImagePreview, VuiInfoList, VuiInfoListItem, VuiInfoMenu, VuiInfoTable, VuiInfoTooltip, VuiInProgress, VuiItemsInput, VuiLabel, VuiLink, VuiLinkInternal, VuiList, VuiMenu, VuiMenuItem, VuiModal, VuiNotifications, VuiNumberInput, VuiOptionsButton, VuiOptionsList, VuiOptionsListItem, VuiPagination, VuiPanel, VuiPasswordInput, VuiPopover, VuiPortal, VuiProgressBar, VuiPrompt, VuiRadioButton, VuiScreenBlock, VuiSearchInput, VuiSearchResult, VuiSearchSelect, VuiSelect, VuiSetting, VuiSimpleCard, VuiSimpleGrid, VuiSpacer, VuiSpinner, VuiStat, VuiStatList, VuiStatus, VuiSteps, VuiSummary, VuiSkeleton, VuiSummaryCitation, VuiSuperCheckboxGroup, VuiSuperRadioGroup, VuiTable, VuiTab, VuiTabbedRoutes, VuiTabs, VuiText, VuiTextArea, VuiTextColor, VuiTextInput, VuiTimeline, VuiTimelineItem, VuiTitle, VuiToggle, VuiTooltip, VuiTopicButton };
@@ -81,7 +81,8 @@ import { TEXT_COLOR, TEXT_SIZE, TITLE_SIZE } from "./typography/types";
81
81
  import { VuiTitle } from "./typography/Title";
82
82
  import { VuiToggle } from "./toggle/Toggle";
83
83
  import { VuiTooltip } from "./tooltip/Tooltip";
84
+ import { VuiInfoTooltip } from "./tooltip/InfoTooltip";
84
85
  import { VuiTopicButton } from "./topicButton/TopicButton";
85
86
  import { copyToClipboard } from "../utils/copyToClipboard";
86
87
  import { toRgb, toRgba } from "./context/Theme";
87
- export { BADGE_COLOR, BUTTON_COLOR, BUTTON_SIZE, CALLOUT_COLOR, CALLOUT_SIZE, ICON_COLOR, ICON_SIZE, ICON_TYPE, 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, VuiButtonPrimary, VuiButtonSecondary, VuiButtonTertiary, VuiIconButton, VuiCallout, VuiCard, VuiChat, VuiCheckbox, VuiCode, VuiCodeEditor, VuiContextProvider, VuiCopyButton, VuiDatePicker, VuiDateRangePicker, VuiDrawer, VuiErrorBoundary, VuiFlexContainer, VuiFlexItem, VuiFormGroup, VuiGrid, VuiGridItem, VuiHorizontalRule, VuiIcon, VuiImage, VuiImagePreview, VuiInfoList, VuiInfoListItem, VuiInfoMenu, VuiInfoTable, VuiInProgress, VuiItemsInput, VuiLabel, VuiLink, VuiLinkInternal, VuiList, VuiMenu, VuiMenuItem, VuiModal, VuiNotifications, VuiNumberInput, VuiOptionsButton, VuiOptionsList, VuiOptionsListItem, VuiPagination, VuiPanel, VuiPasswordInput, VuiPopover, VuiPortal, VuiProgressBar, VuiPrompt, VuiRadioButton, VuiScreenBlock, VuiSearchInput, VuiSearchResult, VuiSearchSelect, VuiSelect, VuiSetting, VuiSimpleCard, VuiSimpleGrid, VuiSpacer, VuiSpinner, VuiStat, VuiStatList, VuiStatus, VuiSteps, VuiSummary, VuiSkeleton, VuiSummaryCitation, VuiSuperCheckboxGroup, VuiSuperRadioGroup, VuiTable, VuiTab, VuiTabbedRoutes, VuiTabs, VuiText, VuiTextArea, VuiTextColor, VuiTextInput, VuiTimeline, VuiTimelineItem, VuiTitle, VuiToggle, VuiTooltip, VuiTopicButton };
88
+ export { BADGE_COLOR, BUTTON_COLOR, BUTTON_SIZE, CALLOUT_COLOR, CALLOUT_SIZE, ICON_COLOR, ICON_SIZE, ICON_TYPE, 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, VuiButtonPrimary, VuiButtonSecondary, VuiButtonTertiary, VuiIconButton, VuiCallout, VuiCard, VuiChat, VuiCheckbox, VuiCode, VuiCodeEditor, VuiContextProvider, VuiCopyButton, VuiDatePicker, VuiDateRangePicker, VuiDrawer, VuiErrorBoundary, VuiFlexContainer, VuiFlexItem, VuiFormGroup, VuiGrid, VuiGridItem, VuiHorizontalRule, VuiIcon, VuiImage, VuiImagePreview, VuiInfoList, VuiInfoListItem, VuiInfoMenu, VuiInfoTable, VuiInfoTooltip, VuiInProgress, VuiItemsInput, VuiLabel, VuiLink, VuiLinkInternal, VuiList, VuiMenu, VuiMenuItem, VuiModal, VuiNotifications, VuiNumberInput, VuiOptionsButton, VuiOptionsList, VuiOptionsListItem, VuiPagination, VuiPanel, VuiPasswordInput, VuiPopover, VuiPortal, VuiProgressBar, VuiPrompt, VuiRadioButton, VuiScreenBlock, VuiSearchInput, VuiSearchResult, VuiSearchSelect, VuiSelect, VuiSetting, VuiSimpleCard, VuiSimpleGrid, VuiSpacer, VuiSpinner, VuiStat, VuiStatList, VuiStatus, VuiSteps, VuiSummary, VuiSkeleton, VuiSummaryCitation, VuiSuperCheckboxGroup, VuiSuperRadioGroup, VuiTable, VuiTab, VuiTabbedRoutes, VuiTabs, VuiText, VuiTextArea, VuiTextColor, VuiTextInput, VuiTimeline, VuiTimelineItem, VuiTitle, VuiToggle, VuiTooltip, VuiTopicButton };
@@ -37,5 +37,7 @@ export const VuiNotification = ({ color, message, onDismiss, children, hasCopyBu
37
37
  icon = null;
38
38
  }
39
39
  const copyValue = code ? `${message}\n\n${code.content}` : message;
40
- return (_jsx("div", Object.assign({ className: classes, "data-testid": `notification-${color}` }, { children: _jsxs(VuiFlexContainer, Object.assign({ alignItems: "start", spacing: "s" }, { children: [_jsx(VuiFlexItem, Object.assign({ grow: 1 }, { children: _jsxs(VuiFlexContainer, Object.assign({ alignItems: "start", spacing: "xs" }, { children: [icon, _jsxs("div", { children: [_jsx(VuiText, Object.assign({ preserveWhiteSpace: true }, { children: _jsx(VuiTextColor, Object.assign({ color: color }, { children: message })) })), code && (_jsxs(_Fragment, { children: [_jsx(VuiSpacer, { size: "s" }), _jsx(VuiCode, Object.assign({ language: code.language }, { children: code.content }))] })), hasCopyButton && (_jsxs(_Fragment, { children: [_jsx(VuiSpacer, { size: "s" }), _jsx(VuiCopyButton, { value: copyValue, size: "s", label: "Copy notification" })] })), children && (_jsxs(_Fragment, { children: [_jsx(VuiSpacer, { size: "s" }), children] })), link && (_jsxs(_Fragment, { children: [_jsx(VuiSpacer, { size: "s" }), _jsx(VuiLink, Object.assign({}, link))] }))] })] })) })), _jsx(VuiFlexItem, Object.assign({ grow: false, shrink: false }, { children: _jsx(VuiIconButton, { "aria-label": "Dismiss message", size: "xs", color: "neutral", icon: _jsx(VuiIcon, { children: _jsx(BiX, {}) }), onClick: () => onDismiss(), "data-testid": `dismissNotificationButton-${color}` }) }))] })) })));
40
+ // data-awareness="notification" enables notifications to be closed when a drawer is open,
41
+ // without triggering the drawer to close.
42
+ return (_jsx("div", Object.assign({ className: classes, "data-testid": `notification-${color}`, "data-awareness": "notification" }, { children: _jsxs(VuiFlexContainer, Object.assign({ alignItems: "start", spacing: "s" }, { children: [_jsx(VuiFlexItem, Object.assign({ grow: 1 }, { children: _jsxs(VuiFlexContainer, Object.assign({ alignItems: "start", spacing: "xs" }, { children: [icon, _jsxs("div", { children: [_jsx(VuiText, Object.assign({ preserveWhiteSpace: true }, { children: _jsx(VuiTextColor, Object.assign({ color: color }, { children: message })) })), code && (_jsxs(_Fragment, { children: [_jsx(VuiSpacer, { size: "s" }), _jsx(VuiCode, Object.assign({ language: code.language }, { children: code.content }))] })), hasCopyButton && (_jsxs(_Fragment, { children: [_jsx(VuiSpacer, { size: "s" }), _jsx(VuiCopyButton, { value: copyValue, size: "s", label: "Copy notification" })] })), children && (_jsxs(_Fragment, { children: [_jsx(VuiSpacer, { size: "s" }), children] })), link && (_jsxs(_Fragment, { children: [_jsx(VuiSpacer, { size: "s" }), _jsx(VuiLink, Object.assign({}, link))] }))] })] })) })), _jsx(VuiFlexItem, Object.assign({ grow: false, shrink: false }, { children: _jsx(VuiIconButton, { "aria-label": "Dismiss message", size: "xs", color: "neutral", icon: _jsx(VuiIcon, { children: _jsx(BiX, {}) }), onClick: () => onDismiss(), "data-testid": `dismissNotificationButton-${color}` }) }))] })) })));
41
43
  };
@@ -1,6 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Toaster } from "sonner";
3
+ import { VuiPortal } from "../portal/Portal";
3
4
  export const VuiNotifications = (props) => {
4
5
  const finalProps = Object.assign({ position: "top-right" }, props);
5
- return _jsx(Toaster, Object.assign({}, finalProps));
6
+ // Render inside portal so notifications can appear above everything else, including drawers.
7
+ return (_jsx(VuiPortal, { children: _jsx(Toaster, Object.assign({}, finalProps)) }));
6
8
  };
@@ -0,0 +1,4 @@
1
+ import { Props as TooltipProps } from "./Tooltip";
2
+ type Props = Omit<TooltipProps, "children">;
3
+ export declare const VuiInfoTooltip: (props: Props) => import("react/jsx-runtime").JSX.Element;
4
+ export {};
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { BiHelpCircle } from "react-icons/bi";
3
+ import { VuiIcon } from "../icon/Icon";
4
+ import { VuiTooltip } from "./Tooltip";
5
+ export const VuiInfoTooltip = (props) => {
6
+ return (_jsx(VuiTooltip, Object.assign({}, props, { children: _jsx(VuiIcon, Object.assign({ color: "subdued", size: "s" }, { children: _jsx(BiHelpCircle, {}) })) })));
7
+ };
@@ -6,12 +6,30 @@ import { VuiPortal } from "../portal/Portal";
6
6
  const generateTooltipId = () => {
7
7
  return `tooltip-${Math.random().toString(36).slice(2, 9)}`;
8
8
  };
9
+ // Naturally focusable elements that don't need tabIndex.
10
+ const FOCUSABLE_ELEMENTS = ["a", "button", "input", "select", "textarea"];
11
+ // Determine if the element needs tabIndex to be keyboard accessible.
12
+ const needsTabIndex = (element) => {
13
+ var _a;
14
+ if (!element || typeof element !== "object" || !("type" in element)) {
15
+ return false;
16
+ }
17
+ const child = element;
18
+ const elementType = typeof child.type === "string" ? child.type.toLowerCase() : "";
19
+ // Don't add tabIndex if element is naturally focusable.
20
+ if (FOCUSABLE_ELEMENTS.includes(elementType)) {
21
+ return false;
22
+ }
23
+ // Don't add tabIndex if it already has one.
24
+ if (((_a = child.props) === null || _a === void 0 ? void 0 : _a.tabIndex) !== undefined) {
25
+ return false;
26
+ }
27
+ return true;
28
+ };
9
29
  export const VuiTooltip = ({ children, darkTheme, position, tip, usePortal }) => {
10
30
  const { getThemeStyle } = useVuiContext();
11
31
  const [id] = useState(generateTooltipId());
12
- const target = cloneElement(children, {
13
- "data-tooltip-id": id
14
- });
32
+ const target = cloneElement(children, Object.assign({ "data-tooltip-id": id }, (needsTabIndex(children) && { tabIndex: 0 })));
15
33
  // Tooltips can be used in a dark-themed component, so we need to explicitly set
16
34
  // the light theme class in order to enable having a different theme than the
17
35
  // parent.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vectara/vectara-ui",
3
- "version": "15.7.1",
3
+ "version": "15.8.0",
4
4
  "homepage": "./",
5
5
  "description": "Vectara's design system, codified as a React and Sass component library",
6
6
  "author": "Vectara",
@@ -1,9 +1,11 @@
1
1
  import { useState } from "react";
2
2
  import {
3
+ addNotification,
3
4
  VuiButtonPrimary,
4
5
  VuiButtonSecondary,
5
6
  VuiDrawer,
6
7
  VuiFlexContainer,
8
+ VuiNotifications,
7
9
  VuiSpacer,
8
10
  VuiText,
9
11
  VuiToggle
@@ -51,6 +53,20 @@ export const PrimaryDrawer = () => {
51
53
  )
52
54
  }
53
55
  >
56
+ <VuiButtonSecondary
57
+ color="primary"
58
+ onClick={() => {
59
+ addNotification({
60
+ color: "primary",
61
+ message: "Just some information, FYI"
62
+ });
63
+ }}
64
+ >
65
+ Add notification
66
+ </VuiButtonSecondary>
67
+
68
+ <VuiSpacer size="m" />
69
+
54
70
  <VuiText>
55
71
  <p>I just thought you should know that your drawer is showing.</p>
56
72
  </VuiText>
@@ -186,6 +202,8 @@ export const PrimaryDrawer = () => {
186
202
  <FormGroup />
187
203
  <VuiSpacer size="l" />
188
204
  </VuiDrawer>
205
+
206
+ <VuiNotifications />
189
207
  </>
190
208
  );
191
209
  };
@@ -0,0 +1,5 @@
1
+ import { VuiInfoTooltip } from "../../../lib";
2
+
3
+ export const InfoTooltip = () => {
4
+ return <VuiInfoTooltip tip="This explains a term or feature." />;
5
+ };
@@ -1,6 +1,8 @@
1
1
  import { Tooltip } from "./Tooltip";
2
+ import { InfoTooltip } from "./InfoTooltip";
2
3
 
3
4
  const TooltipSource = require("!!raw-loader!./Tooltip");
5
+ const InfoTooltipSource = require("!!raw-loader!./InfoTooltip");
4
6
 
5
7
  export const tooltip = {
6
8
  name: "Tooltip",
@@ -10,6 +12,11 @@ export const tooltip = {
10
12
  name: "Tooltip",
11
13
  component: <Tooltip />,
12
14
  source: TooltipSource.default.toString()
15
+ },
16
+ {
17
+ name: "Info Tooltip",
18
+ component: <InfoTooltip />,
19
+ source: InfoTooltipSource.default.toString()
13
20
  }
14
21
  ]
15
22
  };