@sprinklrjs/spaceweb 14.11.3 → 14.11.4

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/menu/menu-item.js CHANGED
@@ -19,12 +19,24 @@ var classNames_1 = tslib_1.__importDefault(require("../classNames"));
19
19
  function resolveMenuActions(getActionsElement, item) {
20
20
  if (!getActionsElement)
21
21
  return null;
22
+ var menuActions;
22
23
  if (typeof getActionsElement === 'function') {
23
24
  if (item == null)
24
25
  return null;
25
- return getActionsElement({ item: item });
26
+ menuActions = getActionsElement({ item: item });
26
27
  }
27
- return getActionsElement;
28
+ else {
29
+ menuActions = getActionsElement;
30
+ }
31
+ return menuActions.filter(function (action) {
32
+ // If array item is null | undefined
33
+ if (!action)
34
+ return false;
35
+ // If action object in array as no actionEl
36
+ if ('actionEl' in action && !action.actionEl)
37
+ return false;
38
+ return true;
39
+ });
28
40
  }
29
41
  var listItemOverrides = {
30
42
  ListItem: {
@@ -63,10 +75,17 @@ var ACTION_CONTAINER_HANDLER_PROPS = {
63
75
  },
64
76
  };
65
77
  function MenuActionContainer(_a) {
66
- var sharedProps = _a.sharedProps, endEnhancer = _a.endEnhancer, renderedActions = _a.renderedActions;
67
- return ((0, jsx_runtime_1.jsxs)(box_1.Box, tslib_1.__assign({ className: (0, classNames_1.default)('flex items-center gap-1 pointer-events-none', 'group-hover:visible group-hover:pointer-events-auto', 'group-focus-within:visible group-focus-within:pointer-events-auto',
68
- // Use visibility (not opacity) so alwaysVisible children can override with `visible`.
69
- sharedProps.$highlighted ? 'visible pointer-events-auto' : 'invisible'), "data-menu-action-container": "true", role: "group" }, ACTION_CONTAINER_HANDLER_PROPS, { children: [renderedActions.map(function (action) { return ((0, jsx_runtime_1.jsx)(box_1.Box, tslib_1.__assign({ className: action.props.alwaysVisible ? 'visible opacity-100 pointer-events-auto' : undefined }, { children: action }), action.key)); }), typeof endEnhancer === 'function' ? endEnhancer(sharedProps) : endEnhancer !== null && endEnhancer !== void 0 ? endEnhancer : null] })));
78
+ var sharedProps = _a.sharedProps, renderedActions = _a.renderedActions;
79
+ return ((0, jsx_runtime_1.jsx)(box_1.Box, tslib_1.__assign({ className: ['flex items-center', sharedProps.$highlighted ? 'pointer-events-auto' : 'pointer-events-none'], "data-menu-action-container": "true" }, ACTION_CONTAINER_HANDLER_PROPS, { children: renderedActions.map(function (action, index) {
80
+ var _a;
81
+ var _b = 'actionEl' in action ? action : { actionEl: action, alwaysVisible: false }, actionEl = _b.actionEl, alwaysVisible = _b.alwaysVisible;
82
+ return ((0, jsx_runtime_1.jsx)(box_1.Box, tslib_1.__assign({
83
+ // Only show actions that are always visible or whose parent item is highlighted
84
+ className: [
85
+ index === 0 ? 'ml-0' : 'ml-1',
86
+ alwaysVisible || sharedProps.$highlighted ? 'visible' : 'invisible w-0 ml-0',
87
+ ] }, { children: React.cloneElement(actionEl, { tabIndex: -1 }) }), (_a = actionEl.key) !== null && _a !== void 0 ? _a : "menu-action-".concat(index)));
88
+ }) })));
70
89
  }
71
90
  function buildListItemAriaProps(itemRole, selected, ChildMenu) {
72
91
  var props = {};
@@ -78,28 +97,10 @@ function buildListItemAriaProps(itemRole, selected, ChildMenu) {
78
97
  }
79
98
  return props;
80
99
  }
81
- function flattenActionElements(actions) {
82
- return React.Children.toArray(actions).flatMap(function (node) {
83
- if (React.isValidElement(node)) {
84
- return node.type === React.Fragment ? flattenActionElements(node.props.children) : [node];
85
- }
86
- return [];
87
- });
88
- }
89
100
  function useResolvedMenuEndEnhancer(resolvedItemActions, shouldRenderActions, endEnhancer, ChildMenu) {
90
- var renderedActions = (0, react_1.useMemo)(function () {
91
- return shouldRenderActions
92
- ? flattenActionElements(resolvedItemActions).map(function (action, index) {
93
- var _a;
94
- return React.cloneElement(action, {
95
- key: (_a = action.key) !== null && _a !== void 0 ? _a : "menu-action-".concat(index),
96
- });
97
- })
98
- : null;
99
- }, [resolvedItemActions, shouldRenderActions]);
100
101
  return (0, react_1.useMemo)(function () {
101
102
  if (shouldRenderActions) {
102
- return function (sharedProps) { return ((0, jsx_runtime_1.jsx)(MenuActionContainer, { sharedProps: sharedProps, endEnhancer: endEnhancer, renderedActions: renderedActions !== null && renderedActions !== void 0 ? renderedActions : [] })); };
103
+ return function (sharedProps) { return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(MenuActionContainer, { sharedProps: sharedProps, renderedActions: resolvedItemActions !== null && resolvedItemActions !== void 0 ? resolvedItemActions : [] }), typeof endEnhancer === 'function' ? endEnhancer(sharedProps) : endEnhancer !== null && endEnhancer !== void 0 ? endEnhancer : null] })); };
103
104
  }
104
105
  if (endEnhancer)
105
106
  return endEnhancer;
@@ -107,7 +108,7 @@ function useResolvedMenuEndEnhancer(resolvedItemActions, shouldRenderActions, en
107
108
  return (0, jsx_runtime_1.jsx)(chevron_down_1.default, { size: 14, className: "transform -rotate-90" });
108
109
  }
109
110
  return undefined;
110
- }, [ChildMenu, endEnhancer, renderedActions, shouldRenderActions]);
111
+ }, [ChildMenu, endEnhancer, resolvedItemActions, shouldRenderActions]);
111
112
  }
112
113
  function useMenuItemInteractionHandlers(onMouseOver, ownRef, setHighlightedItem, setNestedMenuOpen) {
113
114
  var onMouseOverRef = (0, useLatest_1.useLatest)(onMouseOver);
@@ -129,12 +130,13 @@ function useMenuItemInteractionHandlers(onMouseOver, ownRef, setHighlightedItem,
129
130
  return { handleMouseOver: handleMouseOver, handleMouseMove: handleMouseMove, resetMenu: resetMenu, closeNestedMenu: closeNestedMenu };
130
131
  }
131
132
  var MenuItem = React.forwardRef(function MenuItem(_a, ref) {
133
+ var _b;
132
134
  var selected = _a.selected, highlighted = _a.highlighted, overrides = _a.overrides, getChildMenu = _a.getChildMenu, onMouseEnter = _a.onMouseEnter, onMouseLeave = _a.onMouseLeave, onMouseOver = _a.onMouseOver, endEnhancer = _a.endEnhancer, hideInlineActions = _a.hideInlineActions, renderAll = _a.renderAll, explicitRole = _a.role, $item = _a.$item, restProps = tslib_1.__rest(_a, ["selected", "highlighted", "overrides", "getChildMenu", "onMouseEnter", "onMouseLeave", "onMouseOver", "endEnhancer", "hideInlineActions", "renderAll", "role", "$item"]);
133
- var _b = tslib_1.__read((0, react_1.useState)(false), 2), hovered = _b[0], setHovered = _b[1];
135
+ var _c = tslib_1.__read((0, react_1.useState)(false), 2), hovered = _c[0], setHovered = _c[1];
134
136
  var ChildMenu = getChildMenu === null || getChildMenu === void 0 ? void 0 : getChildMenu();
135
137
  var ownRef = (0, react_1.useRef)(null);
136
138
  var itemRef = (0, useCombinedRef_1.default)(ref, ownRef);
137
- var _c = (0, MenuContext_1.useMenuContext)(), getActionsElement = _c.getActionsElement, highlightedItem = _c.highlightedItem, setHighlightedItem = _c.setHighlightedItem, setMenuContainerRef = _c.setMenuContainerRef, listItemFocusVisible = _c.listItemFocusVisible, nestedMenuOpen = _c.nestedMenuOpen, setNestedMenuOpen = _c.setNestedMenuOpen;
139
+ var _d = (0, MenuContext_1.useMenuContext)(), getActionsElement = _d.getActionsElement, highlightedItem = _d.highlightedItem, setHighlightedItem = _d.setHighlightedItem, setMenuContainerRef = _d.setMenuContainerRef, listItemFocusVisible = _d.listItemFocusVisible, nestedMenuOpen = _d.nestedMenuOpen, setNestedMenuOpen = _d.setNestedMenuOpen;
138
140
  var itemRole = explicitRole !== null && explicitRole !== void 0 ? explicitRole : 'menuitem';
139
141
  (0, react_1.useEffect)(function () {
140
142
  var _a, _b;
@@ -142,12 +144,12 @@ var MenuItem = React.forwardRef(function MenuItem(_a, ref) {
142
144
  }, [setMenuContainerRef]);
143
145
  var isItemHighlighted = highlighted || (highlightedItem !== null && highlightedItem === ownRef.current);
144
146
  var resolvedItemActions = (0, react_1.useMemo)(function () { return resolveMenuActions(getActionsElement, $item); }, [getActionsElement, $item]);
145
- var shouldRenderActions = Boolean(resolvedItemActions) && !ChildMenu && !hideInlineActions;
147
+ var shouldRenderActions = ((_b = resolvedItemActions === null || resolvedItemActions === void 0 ? void 0 : resolvedItemActions.length) !== null && _b !== void 0 ? _b : 0) > 0 && !ChildMenu && !hideInlineActions;
146
148
  var resolvedEndEnhancer = useResolvedMenuEndEnhancer(resolvedItemActions, shouldRenderActions, endEnhancer, ChildMenu);
147
149
  var mergedOverrides = (0, react_1.useMemo)(function () { return (0, overrides_1.mergeOverrides)(listItemOverrides, overrides); }, [overrides]);
148
- var _d = tslib_1.__read((0, overrides_1.useOverrides)(mergedOverrides === null || mergedOverrides === void 0 ? void 0 : mergedOverrides.ListItem, list_item_1.default), 2), ListItemOverride = _d[0], listItemProps = _d[1];
149
- var _e = tslib_1.__read((0, overrides_1.useOverrides)(mergedOverrides === null || mergedOverrides === void 0 ? void 0 : mergedOverrides.Popover, popover_1.Popover), 2), PopoverOverride = _e[0], popoverProps = _e[1];
150
- var _f = useMenuItemInteractionHandlers(onMouseOver, ownRef, setHighlightedItem, setNestedMenuOpen), handleMouseOver = _f.handleMouseOver, handleMouseMove = _f.handleMouseMove, resetMenu = _f.resetMenu, closeNestedMenu = _f.closeNestedMenu;
150
+ var _e = tslib_1.__read((0, overrides_1.useOverrides)(mergedOverrides === null || mergedOverrides === void 0 ? void 0 : mergedOverrides.ListItem, list_item_1.default), 2), ListItemOverride = _e[0], listItemProps = _e[1];
151
+ var _f = tslib_1.__read((0, overrides_1.useOverrides)(mergedOverrides === null || mergedOverrides === void 0 ? void 0 : mergedOverrides.Popover, popover_1.Popover), 2), PopoverOverride = _f[0], popoverProps = _f[1];
152
+ var _g = useMenuItemInteractionHandlers(onMouseOver, ownRef, setHighlightedItem, setNestedMenuOpen), handleMouseOver = _g.handleMouseOver, handleMouseMove = _g.handleMouseMove, resetMenu = _g.resetMenu, closeNestedMenu = _g.closeNestedMenu;
151
153
  var id = (0, useUniqueId_1.default)();
152
154
  var listItem = ((0, jsx_runtime_1.jsx)(ListItemOverride, tslib_1.__assign({ id: id.toString(), ref: itemRef, role: itemRole, selected: selected, "data-haschildmenu": Boolean(ChildMenu), "data-hasactions": shouldRenderActions, highlighted: isItemHighlighted, "$outlined": isItemHighlighted && listItemFocusVisible, endEnhancer: resolvedEndEnhancer, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, "$item": $item }, buildListItemAriaProps(itemRole, selected, ChildMenu), restProps, { onMouseOver: handleMouseOver, onMouseMove: handleMouseMove }, listItemProps)));
153
155
  var handleMouseEnter = (0, useCombinedHandler_1.default)(function () { return setHovered(true); }, onMouseEnter);
package/menu/menu.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  import type { MenuRef } from './types';
3
3
  import type { ClassName, Styles } from '../types';
4
4
  declare const _default: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<Omit<import("../list").ListProps, "overrides"> & {
5
- getActionsElement?: import("./types").MenuItemActions<import("./types").MenuActionItem>;
5
+ getActionsElement?: import("./types").MenuItemActions<import("./types").MenuActionItem> | undefined;
6
6
  disableNavigationOnMount?: boolean | undefined;
7
7
  focusWhenNavigationEnabled?: boolean | undefined;
8
8
  keyboardFocusRestoreTarget?: HTMLElement | null | undefined;
package/menu/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Dispatch, MutableRefObject, ReactElement, ReactNode, SetStateAction } from 'react';
1
+ import type { Dispatch, MutableRefObject, ReactElement, SetStateAction } from 'react';
2
2
  import type { ListItemProps, ListItemSharedProps, ListProps } from '../list';
3
3
  import type { Override } from '../overrides';
4
4
  import type { PopoverProps } from '../popover';
@@ -32,7 +32,15 @@ export type MenuItemActionsParams<TItem extends MenuActionItem = MenuActionItem>
32
32
  * Inline row actions: a static node for every row, or `({ item }) => …` for per-row actions
33
33
  * (permissions, conditional buttons, etc.). Function form requires `$item` on {@link MenuItem}.
34
34
  */
35
- export type MenuItemActions<TItem extends MenuActionItem = MenuActionItem> = ReactNode | ((params: MenuItemActionsParams<TItem>) => ReactNode);
35
+ export type MenuItemActionsConfig = (ReactElement | null | undefined | {
36
+ actionEl: ReactElement | null | undefined;
37
+ alwaysVisible?: boolean;
38
+ })[];
39
+ export type ResolvedMenuItemActionsConfig = (ReactElement | {
40
+ actionEl: ReactElement;
41
+ alwaysVisible?: boolean;
42
+ })[];
43
+ export type MenuItemActions<TItem extends MenuActionItem = MenuActionItem> = MenuItemActionsConfig | ((params: MenuItemActionsParams<TItem>) => MenuItemActionsConfig);
36
44
  export type MenuProps = Omit<ListProps, 'overrides'> & {
37
45
  /**
38
46
  * Action buttons rendered for each MenuItem (skips submenu items). Pass `({ item }) => …` to vary actions per row.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sprinklrjs/spaceweb",
3
- "version": "14.11.3",
3
+ "version": "14.11.4",
4
4
  "description": "Components for SpaceWeb",
5
5
  "main": "index.js",
6
6
  "module": "./esm/index.js",
@@ -16,6 +16,7 @@
16
16
  "clean": "rm -rf dist && rm -f tsconfig.build.tsbuildinfo",
17
17
  "test": "jest",
18
18
  "test:watch": "jest --watch",
19
+ "test-a11y": "jest --config jest.a11y.config.js",
19
20
  "//": "COLLECT_COVERAGE needs to be true to include VRT in the tests run during coverage",
20
21
  "test:coverage": "COLLECT_COVERAGE=true jest --coverage",
21
22
  "tsc": "tsc",
@@ -99,7 +100,7 @@
99
100
  "ts-node": "^10.4.0"
100
101
  },
101
102
  "peerDependencies": {
102
- "@sprinklrjs/spaceweb-themes": "14.11.3",
103
+ "@sprinklrjs/spaceweb-themes": "14.11.4",
103
104
  "react": ">=17.0.2 <19.0.0",
104
105
  "react-dom": ">=17.0.2 <19.0.0"
105
106
  }
@@ -114,7 +114,7 @@ export declare const CollapsibleSelectMenu: ({ overrides, value, items: groupedI
114
114
  virtual?: boolean | undefined;
115
115
  overscanCount?: number | undefined;
116
116
  selectOnTab?: boolean | undefined;
117
- getActionsElement?: import("../../menu").MenuItemActions;
117
+ getActionsElement?: import("../../menu").MenuItemActions | undefined;
118
118
  inputElement?: HTMLInputElement | null | undefined;
119
119
  } & {
120
120
  $onPaginate?: ((event: UIEvent<HTMLElement>, itemGroup: string) => void) | undefined;
@@ -64,8 +64,10 @@ declare const _default: React.MemoExoticComponent<React.ForwardRefExoticComponen
64
64
  Checkbox?: Override<Omit<{
65
65
  'aria-describedby'?: string | undefined;
66
66
  'aria-errormessage'?: string | undefined;
67
+ 'aria-hidden'?: boolean | "false" | "true" | undefined;
67
68
  ariaLabel?: string | undefined;
68
69
  'aria-label'?: string | undefined;
70
+ tabIndex?: number | undefined;
69
71
  children?: React.ReactNode;
70
72
  containsInteractiveElement?: boolean | undefined;
71
73
  overrides?: import("../../checkbox").CheckboxOverrides | undefined;
package/tag/tag.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  /// <reference types="react" />
2
2
  declare const Tag: import("react").ForwardRefExoticComponent<Omit<{
3
3
  closeable?: boolean | undefined;
4
+ closeAriaLabel?: string | undefined;
4
5
  isFocused?: boolean | undefined;
5
6
  isHovered?: boolean | undefined;
6
7
  children?: import("react").ReactNode;
package/tag/tag.js CHANGED
@@ -19,7 +19,7 @@ var locale_1 = require("../locale");
19
19
  var useTruncateWithTooltip_1 = require("../truncateWithTooltip/hooks/useTruncateWithTooltip");
20
20
  var utils_1 = require("./utils");
21
21
  var Tag = (0, react_1.forwardRef)(function (props, ref) {
22
- var children = props.children, _a = props.closeable, closeable = _a === void 0 ? true : _a, _size = props.size, _b = props.shape, shape = _b === void 0 ? 'default' : _b, _c = props.isFocused, isFocused = _c === void 0 ? false : _c, _d = props.isHovered, isHovered = _d === void 0 ? false : _d, onActionClick = props.onActionClick, onActionKeyDown = props.onActionKeyDown, _e = props.onClick, onClick = _e === void 0 ? null : _e, _f = props.onKeyDown, onKeyDown = _f === void 0 ? null : _f, overrides = props.overrides, title = props.title, _g = props.variant, variant = _g === void 0 ? 'light' : _g, _h = props.intent, intent = _h === void 0 ? 'default' : _h, _j = props.appearance, appearance = _j === void 0 ? 'gray' : _j, className = props.className, startEnhancer = props.startEnhancer, noTooltipOnTruncation = props.noTooltipOnTruncation, restProps = tslib_1.__rest(props, ["children", "closeable", "size", "shape", "isFocused", "isHovered", "onActionClick", "onActionKeyDown", "onClick", "onKeyDown", "overrides", "title", "variant", "intent", "appearance", "className", "startEnhancer", "noTooltipOnTruncation"]);
22
+ var children = props.children, _a = props.closeable, closeable = _a === void 0 ? true : _a, closeAriaLabel = props.closeAriaLabel, _size = props.size, _b = props.shape, shape = _b === void 0 ? 'default' : _b, _c = props.isFocused, isFocused = _c === void 0 ? false : _c, _d = props.isHovered, isHovered = _d === void 0 ? false : _d, onActionClick = props.onActionClick, onActionKeyDown = props.onActionKeyDown, _e = props.onClick, onClick = _e === void 0 ? null : _e, _f = props.onKeyDown, onKeyDown = _f === void 0 ? null : _f, overrides = props.overrides, title = props.title, _g = props.variant, variant = _g === void 0 ? 'light' : _g, _h = props.intent, intent = _h === void 0 ? 'default' : _h, _j = props.appearance, appearance = _j === void 0 ? 'gray' : _j, className = props.className, startEnhancer = props.startEnhancer, noTooltipOnTruncation = props.noTooltipOnTruncation, restProps = tslib_1.__rest(props, ["children", "closeable", "closeAriaLabel", "size", "shape", "isFocused", "isHovered", "onActionClick", "onActionKeyDown", "onClick", "onKeyDown", "overrides", "title", "variant", "intent", "appearance", "className", "startEnhancer", "noTooltipOnTruncation"]);
23
23
  var _k = (0, useFocusVisible_1.useFocusVisible)(), $isFocusVisible = _k.$isFocusVisible, onBlur = _k.onBlur, onFocus = _k.onFocus;
24
24
  var theme = (0, style_1.useStyle)().theme;
25
25
  var locale = (0, locale_1.useLocale)();
@@ -69,7 +69,7 @@ var Tag = (0, react_1.forwardRef)(function (props, ref) {
69
69
  actionIconButtonOverrides,
70
70
  ], style: {
71
71
  '--sw-color': theme.spr.iconTertiary,
72
- }, "aria-label": locale.tag.closeAriaLabel, tabIndex: actionProps === null || actionProps === void 0 ? void 0 : actionProps.tabIndex }, { children: (0, jsx_runtime_1.jsx)(ActionIcon, tslib_1.__assign({ size: clearableIconSize }, actionIconProps)) })) }))) : null] })));
72
+ }, "aria-label": closeAriaLabel !== null && closeAriaLabel !== void 0 ? closeAriaLabel : locale.tag.closeAriaLabel, tabIndex: actionProps === null || actionProps === void 0 ? void 0 : actionProps.tabIndex }, { children: (0, jsx_runtime_1.jsx)(ActionIcon, tslib_1.__assign({ size: clearableIconSize }, actionIconProps)) })) }))) : null] })));
73
73
  });
74
74
  Tag.displayName = 'Tag';
75
75
  Tag.__standard = 'Component';
package/tag/types.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import * as React from 'react';
2
- import { AvatarProps } from '../avatar';
3
- import { Override } from '../overrides';
4
- import { ClassName, SpacewebComponentProps } from '../types';
1
+ import type * as React from 'react';
2
+ import type { AvatarProps } from '../avatar';
3
+ import type { Override } from '../overrides';
4
+ import type { ClassName, SpacewebComponentProps } from '../types';
5
5
  export type Intent = 'success' | 'error' | 'warning' | 'info' | 'default' | 'ai';
6
6
  export type Appearance = 'gray' | 'white' | 'outline';
7
7
  export type Variant = 'solid' | 'light';
@@ -16,6 +16,7 @@ export type TagOverrides = {
16
16
  };
17
17
  export type TagProps = SpacewebComponentProps<{
18
18
  closeable?: boolean;
19
+ closeAriaLabel?: string;
19
20
  isFocused?: boolean;
20
21
  isHovered?: boolean;
21
22
  children?: React.ReactNode;