@trackunit/react-components 0.4.32 → 0.4.34

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/index.cjs.js CHANGED
@@ -1437,6 +1437,14 @@ const cvaBreadcrumbForMediumScreen = cssClassVarianceUtilities.cvaMerge(["flex"]
1437
1437
  },
1438
1438
  });
1439
1439
 
1440
+ /**
1441
+ * BreadcrumbItem is a helper component that renders the individual breadcrumb item.
1442
+ */
1443
+ const BreadcrumbItem = ({ item, dataTestId }) => {
1444
+ const id = sharedUtils.uuidv4();
1445
+ return (jsxRuntime.jsx("div", { className: cvaBreadcrumbItem(), "data-testid": dataTestId, id: `${item.props.label}-${id}`, children: item }));
1446
+ };
1447
+
1440
1448
  /**
1441
1449
  * BreadcrumbForLargeScreen is a helper component that renders the breadcrumb items for large screens.
1442
1450
  */
@@ -1519,13 +1527,6 @@ const BreadcrumbContainer = ({ dataTestId, breadcrumbItems }) => {
1519
1527
  }
1520
1528
  return jsxRuntime.jsx(BreadcrumbForLargeScreen, { breadcrumbItems: breadcrumbItems, dataTestId: `largeScreen-${dataTestId}` });
1521
1529
  };
1522
- /**
1523
- * BreadcrumbItem is a helper component that renders the individual breadcrumb item.
1524
- */
1525
- const BreadcrumbItem = ({ item, dataTestId }) => {
1526
- const id = sharedUtils.uuidv4();
1527
- return (jsxRuntime.jsx("div", { className: cvaBreadcrumbItem(), "data-testid": dataTestId, id: `${item.props.label}-${id}`, children: item }));
1528
- };
1529
1530
 
1530
1531
  const cvaCard = cssClassVarianceUtilities.cvaMerge([
1531
1532
  "flex",
@@ -3738,7 +3739,7 @@ const PopoverContent = React.forwardRef(function PopoverContent({ className, dat
3738
3739
  var _a;
3739
3740
  const { context: floatingContext, customProps, ...context } = usePopoverContext();
3740
3741
  const ref = react.useMergeRefs([context.refs.setFloating, propRef]);
3741
- return (jsxRuntime.jsx(react.FloatingPortal, { id: portalId !== null && portalId !== void 0 ? portalId : "tu-floating-ui", children: context.isOpen ? (jsxRuntime.jsx(react.FloatingFocusManager, { closeOnFocusOut: false, context: floatingContext, guards: false, modal: context.isModal, order: ["reference", "content"], returnFocus: false, children: jsxRuntime.jsx("div", { "aria-describedby": context.descriptionId, "aria-labelledby": context.labelId, className: cvaPopoverContainer({ className: className !== null && className !== void 0 ? className : customProps.className }), "data-testid": (_a = dataTestId !== null && dataTestId !== void 0 ? dataTestId : customProps.dataTestId) !== null && _a !== void 0 ? _a : "popover-content", ref: ref, style: {
3742
+ return (jsxRuntime.jsx(react.FloatingPortal, { id: portalId !== null && portalId !== void 0 ? portalId : "tu-floating-ui", children: context.isOpen ? (jsxRuntime.jsx(react.FloatingFocusManager, { closeOnFocusOut: false, context: floatingContext, guards: true, modal: context.isModal, order: ["reference", "content"], returnFocus: true, children: jsxRuntime.jsx("div", { "aria-describedby": context.descriptionId, "aria-labelledby": context.labelId, className: cvaPopoverContainer({ className: className !== null && className !== void 0 ? className : customProps.className }), "data-testid": (_a = dataTestId !== null && dataTestId !== void 0 ? dataTestId : customProps.dataTestId) !== null && _a !== void 0 ? _a : "popover-content", ref: ref, style: {
3742
3743
  position: context.strategy,
3743
3744
  top: context.y,
3744
3745
  left: context.x,
@@ -4035,6 +4036,36 @@ const KPICard = ({ asChild = false, title, value, loading, unit, iconName, iconB
4035
4036
  return (jsxRuntime.jsxs(Comp, { className: cvaKPICardContainer({ className, isClickable: Boolean(asChild || onClick) }), "data-testid": `${dataTestId}-comp`, onClick: onClick, ...rest, children: [tooltipLabel ? (jsxRuntime.jsx(Tooltip, { className: "w-full", label: tooltipLabel, placement: "bottom", children: jsxRuntime.jsx(CardContent, {}) })) : (jsxRuntime.jsx(CardContent, {})), !loading && jsxRuntime.jsx(reactSlot.Slottable, { children: rest.children })] }));
4036
4037
  };
4037
4038
 
4039
+ const cvaMenuList = cssClassVarianceUtilities.cvaMerge([
4040
+ "shadow",
4041
+ "rounded-lg",
4042
+ "z-popover",
4043
+ "bg-white",
4044
+ "border",
4045
+ "border-slate-300",
4046
+ "grid",
4047
+ "min-w-[200px]",
4048
+ "max-w-[300px]",
4049
+ "p-1",
4050
+ ], {
4051
+ variants: {
4052
+ stickyHeader: {
4053
+ true: "grid-rows-min-fr grid overflow-y-hidden",
4054
+ false: "",
4055
+ },
4056
+ },
4057
+ });
4058
+ const cvaMenuListDivider = cssClassVarianceUtilities.cvaMerge(["mx-[-4px]", "my-1", "min-h-px", "bg-slate-300"]);
4059
+ const cvaMenuListMultiSelect = cssClassVarianceUtilities.cvaMerge("hover:!bg-blue-200");
4060
+ const cvaMenuListItem = cssClassVarianceUtilities.cvaMerge("max-w-[290px]");
4061
+
4062
+ /**
4063
+ * The MenuDivider component is used to separate items in a menu list.
4064
+ */
4065
+ const MenuDivider = () => {
4066
+ return jsxRuntime.jsx("div", { className: cvaMenuListDivider(), "data-testid": "menu-divider" });
4067
+ };
4068
+
4038
4069
  /**
4039
4070
  * Applies standardized interaction-related styles to an element.
4040
4071
  *
@@ -4087,44 +4118,107 @@ const cvaInteractableItem = cssClassVarianceUtilities.cvaMerge("", {
4087
4118
  },
4088
4119
  });
4089
4120
 
4090
- const cvaMenuItemStyle = cssClassVarianceUtilities.cvaMerge(["py-2", "px-2", "w-full", "h-auto", "flex", "flex-row", "items-center", "gap-x-2", "select-none", "rounded"], {
4121
+ /**
4122
+ * Extends the cvaInteractableItem variant in order to set the padding, width, height, cursor, and other styles particular to the MenuItem component.
4123
+ * The cvaInteractableItem variant is used to set the standardized styles that change through interaction with the element (background color, hover, focus, and disabled).
4124
+ */
4125
+ const cvaMenuItem = (props) => {
4126
+ const { size, selected, disabled, focused, className, variant } = props !== null && props !== void 0 ? props : {};
4127
+ return tailwindMerge.twMerge(cvaMenuItemStyle({ size, variant, selected, disabled }), cvaInteractableItem({ selected, disabled, cursor: "pointer", focused }), className);
4128
+ };
4129
+ const cvaMenuItemStyle = cssClassVarianceUtilities.cvaMerge(["py-2", "px-2", "h-auto", "flex", "flex-row", "items-center", "gap-x-2", "select-none", "rounded", "text-sm"], {
4091
4130
  variants: {
4092
4131
  size: {
4093
4132
  small: "py-1",
4094
4133
  medium: "py-2",
4095
4134
  },
4135
+ variant: {
4136
+ primary: [],
4137
+ danger: [
4138
+ "text-danger-600",
4139
+ "hover:!bg-danger-100",
4140
+ "focus:!bg-danger-200",
4141
+ "hover:!text-danger-700",
4142
+ "focus:!text-danger-800",
4143
+ ],
4144
+ },
4145
+ selected: {
4146
+ true: "",
4147
+ false: "",
4148
+ },
4149
+ disabled: {
4150
+ true: "text-black opacity-50",
4151
+ false: "",
4152
+ },
4153
+ },
4154
+ compoundVariants: [
4155
+ {
4156
+ /* danger not multi-select enabled */
4157
+ selected: true,
4158
+ variant: "danger",
4159
+ className: ["!bg-white"],
4160
+ },
4161
+ ],
4162
+ defaultVariants: {
4163
+ variant: "primary",
4164
+ selected: false,
4165
+ disabled: false,
4096
4166
  },
4097
4167
  });
4098
- /**
4099
- * Extends the cvaInteractableItem variant in order to set the padding, width, height, cursor, and other styles particular to the MenuItem component.
4100
- * The cvaInteractableItem variant is used to set the standardized styles that change through interaction with the element (background color, hover, focus, and disabled).
4101
- */
4102
- const cvaMenuItem = (props) => {
4103
- const { size, selected, disabled, focused, className } = props !== null && props !== void 0 ? props : {};
4104
- return tailwindMerge.twMerge(cvaMenuItemStyle({ size }), cvaInteractableItem({ selected, disabled, cursor: "pointer", focused }), className);
4105
- };
4106
- const cvaMenuItemLabel = cssClassVarianceUtilities.cvaMerge([
4107
- "flex-grow",
4108
- "text-gray-700",
4109
- "text-ellipsis",
4110
- "truncate",
4111
- "group-hover:text-gray-900",
4112
- "group-active:text-gray-700",
4113
- ]);
4114
- const cvaMenuItemSuffix = cssClassVarianceUtilities.cvaMerge(["self-center", "flex-grow-0", "text-slate-400", "text-sm"], {
4168
+ const cvaMenuItemLabel = cssClassVarianceUtilities.cvaMerge(["flex-grow", "truncate", "text-black", "font-normal"], {
4169
+ variants: {
4170
+ variant: {
4171
+ primary: [],
4172
+ danger: ["text-danger-600", "hover:text-danger-700", "focus:bg-danger-200", "focus:text-danger-800"],
4173
+ },
4174
+ disabled: {
4175
+ true: "text-black opacity-50",
4176
+ false: "",
4177
+ },
4178
+ },
4179
+ defaultVariants: {
4180
+ variant: "primary",
4181
+ disabled: false,
4182
+ },
4183
+ });
4184
+ const cvaMenuItemPrefix = cssClassVarianceUtilities.cvaMerge(["text-secondary-400", "hover:text-secondary-500", "focus:text-secondary-500", "h-min", "leading-[0]"], {
4115
4185
  variants: {
4116
4186
  selected: {
4117
- true: "text-primary-600 hover:text-primary-700",
4187
+ true: "text-secondary-600",
4188
+ false: "",
4189
+ },
4190
+ variant: {
4191
+ primary: [],
4192
+ danger: ["text-danger-600", "hover:text-danger-700", "focus:bg-danger-200", "focus:text-danger-800"],
4193
+ },
4194
+ disabled: {
4195
+ true: "text-secondary opacity-50",
4118
4196
  false: "",
4119
4197
  },
4120
4198
  },
4199
+ defaultVariants: {
4200
+ variant: "primary",
4201
+ disabled: false,
4202
+ },
4121
4203
  });
4122
- const cvaMenuItemPrefix = cssClassVarianceUtilities.cvaMerge(["self-center", "flex-grow-0", "text-slate-400", "group-hover:text-slate-600", "h-min", "leading-[0]", "text-sm"], {
4204
+ const cvaMenuItemSuffix = cssClassVarianceUtilities.cvaMerge(["text-secondary-400", "text-sm"], {
4123
4205
  variants: {
4124
4206
  selected: {
4125
- true: "text-primary-600 hover:text-primary-700",
4207
+ true: "text-secondary-600",
4126
4208
  false: "",
4127
4209
  },
4210
+ variant: {
4211
+ primary: [],
4212
+ danger: ["text-danger-600", "hover:text-danger-700", "focus:bg-danger-200", "focus:text-danger-800"],
4213
+ },
4214
+ disabled: {
4215
+ true: "text-secondary opacity-50",
4216
+ false: "",
4217
+ },
4218
+ },
4219
+ defaultVariants: {
4220
+ variant: "primary",
4221
+ disabled: false,
4128
4222
  },
4129
4223
  });
4130
4224
 
@@ -4134,46 +4228,81 @@ const cvaMenuItemPrefix = cssClassVarianceUtilities.cvaMerge(["self-center", "fl
4134
4228
  * @param {MenuItemProps} props - The props for the MenuItem component
4135
4229
  * @returns {JSX.Element} MenuItem component
4136
4230
  */
4137
- const MenuItem = ({ className, dataTestId, label, size, children, selected, prefix, suffix, disabled, onClick, stopPropagation = true, id, tabIndex, }) => {
4138
- return (jsxRuntime.jsxs("div", { className: cvaMenuItem({
4231
+ const MenuItem = ({ className, dataTestId, label, size, children, selected, prefix, suffix, disabled, onClick, stopPropagation = true, id, tabIndex, variant = "primary", }) => {
4232
+ /* Handle tab navigation */
4233
+ const handleKeyDown = (e) => {
4234
+ if (e.key === "Enter" && onClick && !disabled) {
4235
+ stopPropagation && e.stopPropagation();
4236
+ // eslint-disable-next-line local-rules/no-typescript-assertion
4237
+ onClick(e);
4238
+ }
4239
+ };
4240
+ return (jsxRuntime.jsxs("div", { "aria-disabled": disabled, className: cvaMenuItem({
4139
4241
  selected,
4140
4242
  disabled,
4141
4243
  size,
4142
4244
  className,
4143
- }), "data-testid": dataTestId !== null && dataTestId !== void 0 ? dataTestId : "menu-item", id: id, onClick: e => {
4245
+ variant,
4246
+ }), "data-testid": dataTestId ? `${dataTestId}-menu-item` : "menu-item", id: id, onClick: e => {
4144
4247
  stopPropagation && e.stopPropagation();
4145
4248
  onClick === null || onClick === void 0 ? void 0 : onClick(e);
4146
- }, role: "menuitem", tabIndex: tabIndex !== null && tabIndex !== void 0 ? tabIndex : 0, children: [prefix ? (jsxRuntime.jsx("div", { className: cvaMenuItemPrefix({ selected }), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, children: prefix })) : null, children && typeof children !== "string" ? (children) : (jsxRuntime.jsx("div", { className: cvaMenuItemLabel(), "data-testid": dataTestId ? `${dataTestId}-label` : null, children: children !== null && children !== void 0 ? children : label })), suffix ? (jsxRuntime.jsx("div", { className: cvaMenuItemSuffix({ selected }), "data-testid": dataTestId ? `${dataTestId}-suffix` : null, children: suffix })) : null] }));
4249
+ }, onKeyDown: handleKeyDown, role: "menuitem", tabIndex: disabled ? -1 : tabIndex !== null && tabIndex !== void 0 ? tabIndex : 0, children: [prefix ? (jsxRuntime.jsx("div", { className: cvaMenuItemPrefix({ selected, variant, disabled }), "data-testid": dataTestId ? `${dataTestId}-prefix` : "menu-item-prefix", children: prefix })) : null, children && typeof children !== "string" ? (children) : (jsxRuntime.jsx("div", { className: cvaMenuItemLabel({ variant, disabled }), "data-testid": dataTestId ? `${dataTestId}-label` : "menu-item-label", children: children !== null && children !== void 0 ? children : label })), suffix ? (jsxRuntime.jsx("div", { className: cvaMenuItemSuffix({ selected, variant, disabled }), "data-testid": dataTestId ? `${dataTestId}-suffix` : "menu-item-suffix", children: suffix })) : null] }));
4147
4250
  };
4148
4251
 
4149
- const cvaMenuList = cssClassVarianceUtilities.cvaMerge(["shadow-md", "rounded-lg", "z-popover", "bg-white", "border", "border-slate-300", "grid"], {
4150
- variants: {
4151
- stickyHeader: {
4152
- true: "grid-rows-min-fr grid overflow-y-hidden",
4153
- false: "",
4154
- },
4155
- },
4156
- });
4157
- const cvaMenuListDivider = cssClassVarianceUtilities.cvaMerge([
4158
- "file:w-full",
4159
- "selection:col-span-full",
4160
- "selection:h-px",
4161
- "selection:bg-slate-200",
4162
- ]);
4163
-
4164
4252
  /**
4165
- * The MenuList component is used for menus and selects.
4166
-
4253
+ * The MenuList is a popover menu that appears above all other content on the page. The menu offers a list of actions or functions that a user can access by clicking on a trigger.
4254
+ *
4255
+ * **When to use**
4256
+ * - Use the MenuList if you have limited space and need to display overflow actions in a list.
4257
+ * - Use the MenuList for actions that are not essential to completing workflows.
4258
+ * - Don’t use the MenuList to display single or multi-select items within form components. For dropdowns within select components, use SelectDropdown (component not available yet).
4259
+ *
4167
4260
  * @param {MenuListProps} props - The props for the MenuList component
4168
4261
  * @returns {JSX.Element} MenuList component
4169
4262
  */
4170
- const MenuList = ({ dataTestId, className, children, withStickyHeader = false, showDivider = false, ...args }) => {
4263
+ const MenuList = ({ dataTestId, className, children, withStickyHeader = false, isMulti = false, selectedItems: controlledSelectedItems, onSelectionChange, ...args }) => {
4171
4264
  const childrenArr = React.Children.toArray(children);
4172
- const isLastItem = (index) => index === childrenArr.length - 1;
4173
- return (jsxRuntime.jsx("div", { className: cvaMenuList({ stickyHeader: withStickyHeader, className }), "data-testid": dataTestId, onClick: args.onClick, role: "list", tabIndex: 0, children: React.Children.map(childrenArr, (menuItem, index) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [menuItem, showDivider && !isLastItem(index) ? jsxRuntime.jsx("hr", { className: cvaMenuListDivider() }) : null] }))) }));
4265
+ const [internalSelectedItems, setInternalSelectedItems] = React.useState(controlledSelectedItems !== null && controlledSelectedItems !== void 0 ? controlledSelectedItems : []);
4266
+ const selectedItems = controlledSelectedItems !== null && controlledSelectedItems !== void 0 ? controlledSelectedItems : internalSelectedItems;
4267
+ const handleItemClick = React.useCallback((id, disabled) => {
4268
+ if (disabled) {
4269
+ return;
4270
+ }
4271
+ const newSelectedItems = isMulti
4272
+ ? selectedItems.includes(id)
4273
+ ? selectedItems.filter(item => item !== id)
4274
+ : [...selectedItems, id]
4275
+ : [id];
4276
+ if (onSelectionChange) {
4277
+ onSelectionChange(newSelectedItems);
4278
+ }
4279
+ else {
4280
+ setInternalSelectedItems(newSelectedItems);
4281
+ }
4282
+ }, [isMulti, selectedItems, onSelectionChange]);
4283
+ return (jsxRuntime.jsx("div", { className: cvaMenuList({ stickyHeader: withStickyHeader, className }), "data-testid": dataTestId ? `${dataTestId}-menu-list` : "menu-list", onClick: args.onClick, role: "list", tabIndex: 0, children: childrenArr.map((menuItem, index) => {
4284
+ var _a;
4285
+ if (React.isValidElement(menuItem)) {
4286
+ const isSelected = selectedItems.includes((_a = menuItem.props.id) !== null && _a !== void 0 ? _a : `${index}`) || menuItem.props.selected;
4287
+ return (jsxRuntime.jsx("div", { children: React.cloneElement(menuItem, {
4288
+ ...menuItem.props,
4289
+ onClick: (event) => {
4290
+ var _a, _b, _c;
4291
+ (_b = (_a = menuItem.props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a, event);
4292
+ handleItemClick((_c = menuItem.props.id) !== null && _c !== void 0 ? _c : `${index}`, menuItem.props.disabled);
4293
+ },
4294
+ className: isMulti && isSelected
4295
+ ? cvaMenuListMultiSelect({ className: menuItem.props.className })
4296
+ : cvaMenuListItem({ className: menuItem.props.className }),
4297
+ selected: isSelected,
4298
+ suffix: isMulti && isSelected ? (jsxRuntime.jsx(Icon, { className: "h-5 text-blue-600", name: "Check", size: "medium", type: "solid" })) : null,
4299
+ }) }, index));
4300
+ }
4301
+ return null;
4302
+ }) }));
4174
4303
  };
4175
4304
 
4176
- const cvaMoreMenu = cssClassVarianceUtilities.cvaMerge(["p-4"]);
4305
+ const cvaMoreMenu = cssClassVarianceUtilities.cvaMerge(["p-0"]);
4177
4306
 
4178
4307
  /**
4179
4308
  * A kebab menu component.
@@ -4191,7 +4320,7 @@ const MoreMenu = ({ className, dataTestId, popoverProps, iconProps = {
4191
4320
  variant: "secondary",
4192
4321
  }, customButton, customPortalId, children, }) => {
4193
4322
  const actionMenuRef = React.useRef(null);
4194
- return (jsxRuntime.jsx("div", { className: cvaMoreMenu({ className }), "data-testid": dataTestId, ref: actionMenuRef, children: jsxRuntime.jsxs(Popover, { ...popoverProps, children: [jsxRuntime.jsx(PopoverTrigger, { children: customButton !== null && customButton !== void 0 ? customButton : jsxRuntime.jsx(IconButton, { ...iconButtonProps, icon: jsxRuntime.jsx(Icon, { name: "EllipsisHorizontal", ...iconProps }) }) }), jsxRuntime.jsx(PopoverContent, { portalId: customPortalId, children: close => (typeof children === "function" ? children(close) : children) })] }) }));
4323
+ return (jsxRuntime.jsx("div", { className: cvaMoreMenu({ className }), "data-testid": dataTestId, ref: actionMenuRef, children: jsxRuntime.jsxs(Popover, { placement: "bottom-end", ...popoverProps, children: [jsxRuntime.jsx(PopoverTrigger, { children: customButton !== null && customButton !== void 0 ? customButton : (jsxRuntime.jsx(IconButton, { dataTestId: "more-menu-icon", ...iconButtonProps, icon: jsxRuntime.jsx(Icon, { name: "EllipsisHorizontal", ...iconProps }) })) }), jsxRuntime.jsx(PopoverContent, { portalId: customPortalId, children: close => (typeof children === "function" ? children(close) : children) })] }) }));
4195
4324
  };
4196
4325
 
4197
4326
  const cvaNotice = cssClassVarianceUtilities.cvaMerge(["flex", "items-center"]);
@@ -4607,7 +4736,7 @@ const Sidebar = ({ childContainerClassName, children, breakpoint = "lg", classNa
4607
4736
  }) }), overflowItemCount > 0 ? (jsxRuntime.jsx(MoreMenu, { iconButtonProps: {
4608
4737
  circular: false,
4609
4738
  variant: "ghost-neutral",
4610
- }, popoverProps: { placement: "bottom-end" }, ...moreMenuProps, className: tailwindMerge.twMerge(moreMenuProps === null || moreMenuProps === void 0 ? void 0 : moreMenuProps.className, "!p-0"), dataTestId: dataTestId ? `${dataTestId}-more-menu` : undefined, children: close => (jsxRuntime.jsx(MenuList, { ...menuListProps, dataTestId: dataTestId ? `${dataTestId}-menu-list` : undefined, children: React.Children.map(children, child => {
4739
+ }, ...moreMenuProps, className: moreMenuProps === null || moreMenuProps === void 0 ? void 0 : moreMenuProps.className, dataTestId: dataTestId ? `${dataTestId}-more-menu` : undefined, children: close => (jsxRuntime.jsx(MenuList, { ...menuListProps, dataTestId: dataTestId, children: React.Children.map(children, child => {
4611
4740
  return itemOverflowMap[child.props.id]
4612
4741
  ? React.cloneElement(child, {
4613
4742
  onClick: () => {
@@ -4615,6 +4744,7 @@ const Sidebar = ({ childContainerClassName, children, breakpoint = "lg", classNa
4615
4744
  (_b = (_a = child.props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a);
4616
4745
  close();
4617
4746
  },
4747
+ className: "w-full",
4618
4748
  })
4619
4749
  : null;
4620
4750
  }) })) })) : null] }));
@@ -5026,7 +5156,6 @@ exports.Alert = Alert;
5026
5156
  exports.Badge = Badge;
5027
5157
  exports.Breadcrumb = Breadcrumb;
5028
5158
  exports.BreadcrumbContainer = BreadcrumbContainer;
5029
- exports.BreadcrumbItem = BreadcrumbItem;
5030
5159
  exports.Button = Button;
5031
5160
  exports.Card = Card;
5032
5161
  exports.CardBody = CardBody;
@@ -5044,6 +5173,7 @@ exports.Icon = Icon;
5044
5173
  exports.IconButton = IconButton;
5045
5174
  exports.Indicator = Indicator;
5046
5175
  exports.KPICard = KPICard;
5176
+ exports.MenuDivider = MenuDivider;
5047
5177
  exports.MenuItem = MenuItem;
5048
5178
  exports.MenuList = MenuList;
5049
5179
  exports.MoreMenu = MoreMenu;
package/index.esm.js CHANGED
@@ -1417,6 +1417,14 @@ const cvaBreadcrumbForMediumScreen = cvaMerge(["flex"], {
1417
1417
  },
1418
1418
  });
1419
1419
 
1420
+ /**
1421
+ * BreadcrumbItem is a helper component that renders the individual breadcrumb item.
1422
+ */
1423
+ const BreadcrumbItem = ({ item, dataTestId }) => {
1424
+ const id = uuidv4();
1425
+ return (jsx("div", { className: cvaBreadcrumbItem(), "data-testid": dataTestId, id: `${item.props.label}-${id}`, children: item }));
1426
+ };
1427
+
1420
1428
  /**
1421
1429
  * BreadcrumbForLargeScreen is a helper component that renders the breadcrumb items for large screens.
1422
1430
  */
@@ -1499,13 +1507,6 @@ const BreadcrumbContainer = ({ dataTestId, breadcrumbItems }) => {
1499
1507
  }
1500
1508
  return jsx(BreadcrumbForLargeScreen, { breadcrumbItems: breadcrumbItems, dataTestId: `largeScreen-${dataTestId}` });
1501
1509
  };
1502
- /**
1503
- * BreadcrumbItem is a helper component that renders the individual breadcrumb item.
1504
- */
1505
- const BreadcrumbItem = ({ item, dataTestId }) => {
1506
- const id = uuidv4();
1507
- return (jsx("div", { className: cvaBreadcrumbItem(), "data-testid": dataTestId, id: `${item.props.label}-${id}`, children: item }));
1508
- };
1509
1510
 
1510
1511
  const cvaCard = cvaMerge([
1511
1512
  "flex",
@@ -3718,7 +3719,7 @@ const PopoverContent = React__default.forwardRef(function PopoverContent({ class
3718
3719
  var _a;
3719
3720
  const { context: floatingContext, customProps, ...context } = usePopoverContext();
3720
3721
  const ref = useMergeRefs([context.refs.setFloating, propRef]);
3721
- return (jsx(FloatingPortal, { id: portalId !== null && portalId !== void 0 ? portalId : "tu-floating-ui", children: context.isOpen ? (jsx(FloatingFocusManager, { closeOnFocusOut: false, context: floatingContext, guards: false, modal: context.isModal, order: ["reference", "content"], returnFocus: false, children: jsx("div", { "aria-describedby": context.descriptionId, "aria-labelledby": context.labelId, className: cvaPopoverContainer({ className: className !== null && className !== void 0 ? className : customProps.className }), "data-testid": (_a = dataTestId !== null && dataTestId !== void 0 ? dataTestId : customProps.dataTestId) !== null && _a !== void 0 ? _a : "popover-content", ref: ref, style: {
3722
+ return (jsx(FloatingPortal, { id: portalId !== null && portalId !== void 0 ? portalId : "tu-floating-ui", children: context.isOpen ? (jsx(FloatingFocusManager, { closeOnFocusOut: false, context: floatingContext, guards: true, modal: context.isModal, order: ["reference", "content"], returnFocus: true, children: jsx("div", { "aria-describedby": context.descriptionId, "aria-labelledby": context.labelId, className: cvaPopoverContainer({ className: className !== null && className !== void 0 ? className : customProps.className }), "data-testid": (_a = dataTestId !== null && dataTestId !== void 0 ? dataTestId : customProps.dataTestId) !== null && _a !== void 0 ? _a : "popover-content", ref: ref, style: {
3722
3723
  position: context.strategy,
3723
3724
  top: context.y,
3724
3725
  left: context.x,
@@ -4015,6 +4016,36 @@ const KPICard = ({ asChild = false, title, value, loading, unit, iconName, iconB
4015
4016
  return (jsxs(Comp, { className: cvaKPICardContainer({ className, isClickable: Boolean(asChild || onClick) }), "data-testid": `${dataTestId}-comp`, onClick: onClick, ...rest, children: [tooltipLabel ? (jsx(Tooltip, { className: "w-full", label: tooltipLabel, placement: "bottom", children: jsx(CardContent, {}) })) : (jsx(CardContent, {})), !loading && jsx(Slottable, { children: rest.children })] }));
4016
4017
  };
4017
4018
 
4019
+ const cvaMenuList = cvaMerge([
4020
+ "shadow",
4021
+ "rounded-lg",
4022
+ "z-popover",
4023
+ "bg-white",
4024
+ "border",
4025
+ "border-slate-300",
4026
+ "grid",
4027
+ "min-w-[200px]",
4028
+ "max-w-[300px]",
4029
+ "p-1",
4030
+ ], {
4031
+ variants: {
4032
+ stickyHeader: {
4033
+ true: "grid-rows-min-fr grid overflow-y-hidden",
4034
+ false: "",
4035
+ },
4036
+ },
4037
+ });
4038
+ const cvaMenuListDivider = cvaMerge(["mx-[-4px]", "my-1", "min-h-px", "bg-slate-300"]);
4039
+ const cvaMenuListMultiSelect = cvaMerge("hover:!bg-blue-200");
4040
+ const cvaMenuListItem = cvaMerge("max-w-[290px]");
4041
+
4042
+ /**
4043
+ * The MenuDivider component is used to separate items in a menu list.
4044
+ */
4045
+ const MenuDivider = () => {
4046
+ return jsx("div", { className: cvaMenuListDivider(), "data-testid": "menu-divider" });
4047
+ };
4048
+
4018
4049
  /**
4019
4050
  * Applies standardized interaction-related styles to an element.
4020
4051
  *
@@ -4067,44 +4098,107 @@ const cvaInteractableItem = cvaMerge("", {
4067
4098
  },
4068
4099
  });
4069
4100
 
4070
- const cvaMenuItemStyle = cvaMerge(["py-2", "px-2", "w-full", "h-auto", "flex", "flex-row", "items-center", "gap-x-2", "select-none", "rounded"], {
4101
+ /**
4102
+ * Extends the cvaInteractableItem variant in order to set the padding, width, height, cursor, and other styles particular to the MenuItem component.
4103
+ * The cvaInteractableItem variant is used to set the standardized styles that change through interaction with the element (background color, hover, focus, and disabled).
4104
+ */
4105
+ const cvaMenuItem = (props) => {
4106
+ const { size, selected, disabled, focused, className, variant } = props !== null && props !== void 0 ? props : {};
4107
+ return twMerge(cvaMenuItemStyle({ size, variant, selected, disabled }), cvaInteractableItem({ selected, disabled, cursor: "pointer", focused }), className);
4108
+ };
4109
+ const cvaMenuItemStyle = cvaMerge(["py-2", "px-2", "h-auto", "flex", "flex-row", "items-center", "gap-x-2", "select-none", "rounded", "text-sm"], {
4071
4110
  variants: {
4072
4111
  size: {
4073
4112
  small: "py-1",
4074
4113
  medium: "py-2",
4075
4114
  },
4115
+ variant: {
4116
+ primary: [],
4117
+ danger: [
4118
+ "text-danger-600",
4119
+ "hover:!bg-danger-100",
4120
+ "focus:!bg-danger-200",
4121
+ "hover:!text-danger-700",
4122
+ "focus:!text-danger-800",
4123
+ ],
4124
+ },
4125
+ selected: {
4126
+ true: "",
4127
+ false: "",
4128
+ },
4129
+ disabled: {
4130
+ true: "text-black opacity-50",
4131
+ false: "",
4132
+ },
4133
+ },
4134
+ compoundVariants: [
4135
+ {
4136
+ /* danger not multi-select enabled */
4137
+ selected: true,
4138
+ variant: "danger",
4139
+ className: ["!bg-white"],
4140
+ },
4141
+ ],
4142
+ defaultVariants: {
4143
+ variant: "primary",
4144
+ selected: false,
4145
+ disabled: false,
4076
4146
  },
4077
4147
  });
4078
- /**
4079
- * Extends the cvaInteractableItem variant in order to set the padding, width, height, cursor, and other styles particular to the MenuItem component.
4080
- * The cvaInteractableItem variant is used to set the standardized styles that change through interaction with the element (background color, hover, focus, and disabled).
4081
- */
4082
- const cvaMenuItem = (props) => {
4083
- const { size, selected, disabled, focused, className } = props !== null && props !== void 0 ? props : {};
4084
- return twMerge(cvaMenuItemStyle({ size }), cvaInteractableItem({ selected, disabled, cursor: "pointer", focused }), className);
4085
- };
4086
- const cvaMenuItemLabel = cvaMerge([
4087
- "flex-grow",
4088
- "text-gray-700",
4089
- "text-ellipsis",
4090
- "truncate",
4091
- "group-hover:text-gray-900",
4092
- "group-active:text-gray-700",
4093
- ]);
4094
- const cvaMenuItemSuffix = cvaMerge(["self-center", "flex-grow-0", "text-slate-400", "text-sm"], {
4148
+ const cvaMenuItemLabel = cvaMerge(["flex-grow", "truncate", "text-black", "font-normal"], {
4149
+ variants: {
4150
+ variant: {
4151
+ primary: [],
4152
+ danger: ["text-danger-600", "hover:text-danger-700", "focus:bg-danger-200", "focus:text-danger-800"],
4153
+ },
4154
+ disabled: {
4155
+ true: "text-black opacity-50",
4156
+ false: "",
4157
+ },
4158
+ },
4159
+ defaultVariants: {
4160
+ variant: "primary",
4161
+ disabled: false,
4162
+ },
4163
+ });
4164
+ const cvaMenuItemPrefix = cvaMerge(["text-secondary-400", "hover:text-secondary-500", "focus:text-secondary-500", "h-min", "leading-[0]"], {
4095
4165
  variants: {
4096
4166
  selected: {
4097
- true: "text-primary-600 hover:text-primary-700",
4167
+ true: "text-secondary-600",
4168
+ false: "",
4169
+ },
4170
+ variant: {
4171
+ primary: [],
4172
+ danger: ["text-danger-600", "hover:text-danger-700", "focus:bg-danger-200", "focus:text-danger-800"],
4173
+ },
4174
+ disabled: {
4175
+ true: "text-secondary opacity-50",
4098
4176
  false: "",
4099
4177
  },
4100
4178
  },
4179
+ defaultVariants: {
4180
+ variant: "primary",
4181
+ disabled: false,
4182
+ },
4101
4183
  });
4102
- const cvaMenuItemPrefix = cvaMerge(["self-center", "flex-grow-0", "text-slate-400", "group-hover:text-slate-600", "h-min", "leading-[0]", "text-sm"], {
4184
+ const cvaMenuItemSuffix = cvaMerge(["text-secondary-400", "text-sm"], {
4103
4185
  variants: {
4104
4186
  selected: {
4105
- true: "text-primary-600 hover:text-primary-700",
4187
+ true: "text-secondary-600",
4106
4188
  false: "",
4107
4189
  },
4190
+ variant: {
4191
+ primary: [],
4192
+ danger: ["text-danger-600", "hover:text-danger-700", "focus:bg-danger-200", "focus:text-danger-800"],
4193
+ },
4194
+ disabled: {
4195
+ true: "text-secondary opacity-50",
4196
+ false: "",
4197
+ },
4198
+ },
4199
+ defaultVariants: {
4200
+ variant: "primary",
4201
+ disabled: false,
4108
4202
  },
4109
4203
  });
4110
4204
 
@@ -4114,46 +4208,81 @@ const cvaMenuItemPrefix = cvaMerge(["self-center", "flex-grow-0", "text-slate-40
4114
4208
  * @param {MenuItemProps} props - The props for the MenuItem component
4115
4209
  * @returns {JSX.Element} MenuItem component
4116
4210
  */
4117
- const MenuItem = ({ className, dataTestId, label, size, children, selected, prefix, suffix, disabled, onClick, stopPropagation = true, id, tabIndex, }) => {
4118
- return (jsxs("div", { className: cvaMenuItem({
4211
+ const MenuItem = ({ className, dataTestId, label, size, children, selected, prefix, suffix, disabled, onClick, stopPropagation = true, id, tabIndex, variant = "primary", }) => {
4212
+ /* Handle tab navigation */
4213
+ const handleKeyDown = (e) => {
4214
+ if (e.key === "Enter" && onClick && !disabled) {
4215
+ stopPropagation && e.stopPropagation();
4216
+ // eslint-disable-next-line local-rules/no-typescript-assertion
4217
+ onClick(e);
4218
+ }
4219
+ };
4220
+ return (jsxs("div", { "aria-disabled": disabled, className: cvaMenuItem({
4119
4221
  selected,
4120
4222
  disabled,
4121
4223
  size,
4122
4224
  className,
4123
- }), "data-testid": dataTestId !== null && dataTestId !== void 0 ? dataTestId : "menu-item", id: id, onClick: e => {
4225
+ variant,
4226
+ }), "data-testid": dataTestId ? `${dataTestId}-menu-item` : "menu-item", id: id, onClick: e => {
4124
4227
  stopPropagation && e.stopPropagation();
4125
4228
  onClick === null || onClick === void 0 ? void 0 : onClick(e);
4126
- }, role: "menuitem", tabIndex: tabIndex !== null && tabIndex !== void 0 ? tabIndex : 0, children: [prefix ? (jsx("div", { className: cvaMenuItemPrefix({ selected }), "data-testid": dataTestId ? `${dataTestId}-prefix` : null, children: prefix })) : null, children && typeof children !== "string" ? (children) : (jsx("div", { className: cvaMenuItemLabel(), "data-testid": dataTestId ? `${dataTestId}-label` : null, children: children !== null && children !== void 0 ? children : label })), suffix ? (jsx("div", { className: cvaMenuItemSuffix({ selected }), "data-testid": dataTestId ? `${dataTestId}-suffix` : null, children: suffix })) : null] }));
4229
+ }, onKeyDown: handleKeyDown, role: "menuitem", tabIndex: disabled ? -1 : tabIndex !== null && tabIndex !== void 0 ? tabIndex : 0, children: [prefix ? (jsx("div", { className: cvaMenuItemPrefix({ selected, variant, disabled }), "data-testid": dataTestId ? `${dataTestId}-prefix` : "menu-item-prefix", children: prefix })) : null, children && typeof children !== "string" ? (children) : (jsx("div", { className: cvaMenuItemLabel({ variant, disabled }), "data-testid": dataTestId ? `${dataTestId}-label` : "menu-item-label", children: children !== null && children !== void 0 ? children : label })), suffix ? (jsx("div", { className: cvaMenuItemSuffix({ selected, variant, disabled }), "data-testid": dataTestId ? `${dataTestId}-suffix` : "menu-item-suffix", children: suffix })) : null] }));
4127
4230
  };
4128
4231
 
4129
- const cvaMenuList = cvaMerge(["shadow-md", "rounded-lg", "z-popover", "bg-white", "border", "border-slate-300", "grid"], {
4130
- variants: {
4131
- stickyHeader: {
4132
- true: "grid-rows-min-fr grid overflow-y-hidden",
4133
- false: "",
4134
- },
4135
- },
4136
- });
4137
- const cvaMenuListDivider = cvaMerge([
4138
- "file:w-full",
4139
- "selection:col-span-full",
4140
- "selection:h-px",
4141
- "selection:bg-slate-200",
4142
- ]);
4143
-
4144
4232
  /**
4145
- * The MenuList component is used for menus and selects.
4146
-
4233
+ * The MenuList is a popover menu that appears above all other content on the page. The menu offers a list of actions or functions that a user can access by clicking on a trigger.
4234
+ *
4235
+ * **When to use**
4236
+ * - Use the MenuList if you have limited space and need to display overflow actions in a list.
4237
+ * - Use the MenuList for actions that are not essential to completing workflows.
4238
+ * - Don’t use the MenuList to display single or multi-select items within form components. For dropdowns within select components, use SelectDropdown (component not available yet).
4239
+ *
4147
4240
  * @param {MenuListProps} props - The props for the MenuList component
4148
4241
  * @returns {JSX.Element} MenuList component
4149
4242
  */
4150
- const MenuList = ({ dataTestId, className, children, withStickyHeader = false, showDivider = false, ...args }) => {
4243
+ const MenuList = ({ dataTestId, className, children, withStickyHeader = false, isMulti = false, selectedItems: controlledSelectedItems, onSelectionChange, ...args }) => {
4151
4244
  const childrenArr = Children.toArray(children);
4152
- const isLastItem = (index) => index === childrenArr.length - 1;
4153
- return (jsx("div", { className: cvaMenuList({ stickyHeader: withStickyHeader, className }), "data-testid": dataTestId, onClick: args.onClick, role: "list", tabIndex: 0, children: Children.map(childrenArr, (menuItem, index) => (jsxs(Fragment, { children: [menuItem, showDivider && !isLastItem(index) ? jsx("hr", { className: cvaMenuListDivider() }) : null] }))) }));
4245
+ const [internalSelectedItems, setInternalSelectedItems] = useState(controlledSelectedItems !== null && controlledSelectedItems !== void 0 ? controlledSelectedItems : []);
4246
+ const selectedItems = controlledSelectedItems !== null && controlledSelectedItems !== void 0 ? controlledSelectedItems : internalSelectedItems;
4247
+ const handleItemClick = useCallback((id, disabled) => {
4248
+ if (disabled) {
4249
+ return;
4250
+ }
4251
+ const newSelectedItems = isMulti
4252
+ ? selectedItems.includes(id)
4253
+ ? selectedItems.filter(item => item !== id)
4254
+ : [...selectedItems, id]
4255
+ : [id];
4256
+ if (onSelectionChange) {
4257
+ onSelectionChange(newSelectedItems);
4258
+ }
4259
+ else {
4260
+ setInternalSelectedItems(newSelectedItems);
4261
+ }
4262
+ }, [isMulti, selectedItems, onSelectionChange]);
4263
+ return (jsx("div", { className: cvaMenuList({ stickyHeader: withStickyHeader, className }), "data-testid": dataTestId ? `${dataTestId}-menu-list` : "menu-list", onClick: args.onClick, role: "list", tabIndex: 0, children: childrenArr.map((menuItem, index) => {
4264
+ var _a;
4265
+ if (isValidElement(menuItem)) {
4266
+ const isSelected = selectedItems.includes((_a = menuItem.props.id) !== null && _a !== void 0 ? _a : `${index}`) || menuItem.props.selected;
4267
+ return (jsx("div", { children: cloneElement(menuItem, {
4268
+ ...menuItem.props,
4269
+ onClick: (event) => {
4270
+ var _a, _b, _c;
4271
+ (_b = (_a = menuItem.props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a, event);
4272
+ handleItemClick((_c = menuItem.props.id) !== null && _c !== void 0 ? _c : `${index}`, menuItem.props.disabled);
4273
+ },
4274
+ className: isMulti && isSelected
4275
+ ? cvaMenuListMultiSelect({ className: menuItem.props.className })
4276
+ : cvaMenuListItem({ className: menuItem.props.className }),
4277
+ selected: isSelected,
4278
+ suffix: isMulti && isSelected ? (jsx(Icon, { className: "h-5 text-blue-600", name: "Check", size: "medium", type: "solid" })) : null,
4279
+ }) }, index));
4280
+ }
4281
+ return null;
4282
+ }) }));
4154
4283
  };
4155
4284
 
4156
- const cvaMoreMenu = cvaMerge(["p-4"]);
4285
+ const cvaMoreMenu = cvaMerge(["p-0"]);
4157
4286
 
4158
4287
  /**
4159
4288
  * A kebab menu component.
@@ -4171,7 +4300,7 @@ const MoreMenu = ({ className, dataTestId, popoverProps, iconProps = {
4171
4300
  variant: "secondary",
4172
4301
  }, customButton, customPortalId, children, }) => {
4173
4302
  const actionMenuRef = useRef(null);
4174
- return (jsx("div", { className: cvaMoreMenu({ className }), "data-testid": dataTestId, ref: actionMenuRef, children: jsxs(Popover, { ...popoverProps, children: [jsx(PopoverTrigger, { children: customButton !== null && customButton !== void 0 ? customButton : jsx(IconButton, { ...iconButtonProps, icon: jsx(Icon, { name: "EllipsisHorizontal", ...iconProps }) }) }), jsx(PopoverContent, { portalId: customPortalId, children: close => (typeof children === "function" ? children(close) : children) })] }) }));
4303
+ return (jsx("div", { className: cvaMoreMenu({ className }), "data-testid": dataTestId, ref: actionMenuRef, children: jsxs(Popover, { placement: "bottom-end", ...popoverProps, children: [jsx(PopoverTrigger, { children: customButton !== null && customButton !== void 0 ? customButton : (jsx(IconButton, { dataTestId: "more-menu-icon", ...iconButtonProps, icon: jsx(Icon, { name: "EllipsisHorizontal", ...iconProps }) })) }), jsx(PopoverContent, { portalId: customPortalId, children: close => (typeof children === "function" ? children(close) : children) })] }) }));
4175
4304
  };
4176
4305
 
4177
4306
  const cvaNotice = cvaMerge(["flex", "items-center"]);
@@ -4587,7 +4716,7 @@ const Sidebar = ({ childContainerClassName, children, breakpoint = "lg", classNa
4587
4716
  }) }), overflowItemCount > 0 ? (jsx(MoreMenu, { iconButtonProps: {
4588
4717
  circular: false,
4589
4718
  variant: "ghost-neutral",
4590
- }, popoverProps: { placement: "bottom-end" }, ...moreMenuProps, className: twMerge(moreMenuProps === null || moreMenuProps === void 0 ? void 0 : moreMenuProps.className, "!p-0"), dataTestId: dataTestId ? `${dataTestId}-more-menu` : undefined, children: close => (jsx(MenuList, { ...menuListProps, dataTestId: dataTestId ? `${dataTestId}-menu-list` : undefined, children: React__default.Children.map(children, child => {
4719
+ }, ...moreMenuProps, className: moreMenuProps === null || moreMenuProps === void 0 ? void 0 : moreMenuProps.className, dataTestId: dataTestId ? `${dataTestId}-more-menu` : undefined, children: close => (jsx(MenuList, { ...menuListProps, dataTestId: dataTestId, children: React__default.Children.map(children, child => {
4591
4720
  return itemOverflowMap[child.props.id]
4592
4721
  ? React__default.cloneElement(child, {
4593
4722
  onClick: () => {
@@ -4595,6 +4724,7 @@ const Sidebar = ({ childContainerClassName, children, breakpoint = "lg", classNa
4595
4724
  (_b = (_a = child.props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a);
4596
4725
  close();
4597
4726
  },
4727
+ className: "w-full",
4598
4728
  })
4599
4729
  : null;
4600
4730
  }) })) })) : null] }));
@@ -5002,4 +5132,4 @@ const cvaClickable = cvaMerge([
5002
5132
  },
5003
5133
  });
5004
5134
 
5005
- export { Alert, Badge, Breadcrumb, BreadcrumbContainer, BreadcrumbItem, Button, Card, CardBody, CardFooter, CardHeader, Collapse, CompletionStatusIndicator, CopyableText, Drawer, EmptyState, EmptyValue, ExternalLink, Heading, Icon, IconButton, Indicator, KPICard, MenuItem, MenuList, MoreMenu, Notice, PackageNameStoryComponent, Page, PageContent, PageHeader, Pagination, Polygon, Popover, PopoverContent, PopoverTitle, PopoverTrigger, Prompt, ROLE_CARD, SectionHeader, Sidebar, SkeletonLines, Spacer, Spinner, StarButton, Tab, TabContent, TabList, Tabs, Tag, Text, Timeline, TimelineElement, ToggleGroup, ToggleItem, Tooltip, ValueBar, VirtualizedList, WidgetBody, cvaButton, cvaButtonPrefixSuffix, cvaButtonSpinner, cvaButtonSpinnerContainer, cvaClickable, cvaIconButton, cvaIndicator, cvaIndicatorIcon, cvaIndicatorIconBackground, cvaIndicatorLabel, cvaIndicatorPing, cvaInteractableItem, cvaMenuItem, cvaMenuItemLabel, cvaMenuItemPrefix, cvaMenuItemStyle, cvaMenuItemSuffix, docs, getDevicePixelRatio, getValueBarColorByValue, iconColorNames, iconPalette, setLocalStorage, useClickOutside, useContinuousTimeout, useDebounce, useDevicePixelRatio, useGeometry, useHover, useIsFirstRender, useIsFullscreen, useIsTextCutOff, useLocalStorage, useLocalStorageReducer, useOptionallyElevatedState, useOverflowItems, usePopoverContext, usePrevious, usePrompt, useResize, useSelfUpdatingRef, useTimeout, useViewportSize, useWindowActivity };
5135
+ export { Alert, Badge, Breadcrumb, BreadcrumbContainer, Button, Card, CardBody, CardFooter, CardHeader, Collapse, CompletionStatusIndicator, CopyableText, Drawer, EmptyState, EmptyValue, ExternalLink, Heading, Icon, IconButton, Indicator, KPICard, MenuDivider, MenuItem, MenuList, MoreMenu, Notice, PackageNameStoryComponent, Page, PageContent, PageHeader, Pagination, Polygon, Popover, PopoverContent, PopoverTitle, PopoverTrigger, Prompt, ROLE_CARD, SectionHeader, Sidebar, SkeletonLines, Spacer, Spinner, StarButton, Tab, TabContent, TabList, Tabs, Tag, Text, Timeline, TimelineElement, ToggleGroup, ToggleItem, Tooltip, ValueBar, VirtualizedList, WidgetBody, cvaButton, cvaButtonPrefixSuffix, cvaButtonSpinner, cvaButtonSpinnerContainer, cvaClickable, cvaIconButton, cvaIndicator, cvaIndicatorIcon, cvaIndicatorIconBackground, cvaIndicatorLabel, cvaIndicatorPing, cvaInteractableItem, cvaMenuItem, cvaMenuItemLabel, cvaMenuItemPrefix, cvaMenuItemStyle, cvaMenuItemSuffix, docs, getDevicePixelRatio, getValueBarColorByValue, iconColorNames, iconPalette, setLocalStorage, useClickOutside, useContinuousTimeout, useDebounce, useDevicePixelRatio, useGeometry, useHover, useIsFirstRender, useIsFullscreen, useIsTextCutOff, useLocalStorage, useLocalStorageReducer, useOptionallyElevatedState, useOverflowItems, usePopoverContext, usePrevious, usePrompt, useResize, useSelfUpdatingRef, useTimeout, useViewportSize, useWindowActivity };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-components",
3
- "version": "0.4.32",
3
+ "version": "0.4.34",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -1,4 +1,4 @@
1
- import { BreadcrumbContainerProps, BreadcrumbItemRenderProps, BreadcrumbProps } from "./utils/types";
1
+ import { BreadcrumbContainerProps, BreadcrumbProps } from "./utils/types";
2
2
  /**
3
3
  * The breadcrumb component shows a user's location in a website or application. Breadcrumbs are particularly useful when a large amount of content is organized in a hierarchical manner. They streamline navigation, minimize the steps required to revisit previous pages, and offer contextual insights to the users.
4
4
  *
@@ -19,7 +19,3 @@ export declare const Breadcrumb: ({ className, dataTestId, breadcrumbItems, back
19
19
  * @param {BreadcrumbContainerProps} props - The props for the BreadcrumbContainer component
20
20
  */
21
21
  export declare const BreadcrumbContainer: ({ dataTestId, breadcrumbItems }: BreadcrumbContainerProps) => import("react/jsx-runtime").JSX.Element;
22
- /**
23
- * BreadcrumbItem is a helper component that renders the individual breadcrumb item.
24
- */
25
- export declare const BreadcrumbItem: ({ item, dataTestId }: BreadcrumbItemRenderProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,5 @@
1
+ import { BreadcrumbItemRenderProps } from "./utils/types";
2
+ /**
3
+ * BreadcrumbItem is a helper component that renders the individual breadcrumb item.
4
+ */
5
+ export declare const BreadcrumbItem: ({ item, dataTestId }: BreadcrumbItemRenderProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * The MenuDivider component is used to separate items in a menu list.
3
+ */
4
+ export declare const MenuDivider: () => import("react/jsx-runtime").JSX.Element;
@@ -1,7 +1,10 @@
1
- import * as React from "react";
2
1
  import { CommonProps, Size } from "../../../common";
3
2
  type MenuItemSize = Extract<Size, "small" | "medium">;
3
+ export type MenuItemVariant = "primary" | "danger";
4
4
  export interface MenuItemProps extends CommonProps {
5
+ /**
6
+ * The unique id for the menu item
7
+ */
5
8
  id?: string;
6
9
  /**
7
10
  * Label of the menu item
@@ -51,7 +54,14 @@ export interface MenuItemProps extends CommonProps {
51
54
  * used in Menu and Select components
52
55
  */
53
56
  stopPropagation?: boolean;
57
+ /**
58
+ * The tab index of the menu item.
59
+ */
54
60
  tabIndex?: number;
61
+ /**
62
+ * The button's variant. Values are primary and danger.
63
+ */
64
+ variant?: MenuItemVariant;
55
65
  }
56
66
  /**
57
67
  * The MenuItem component is used to display a menu, primarily meant to be used in a list form.
@@ -59,5 +69,5 @@ export interface MenuItemProps extends CommonProps {
59
69
  * @param {MenuItemProps} props - The props for the MenuItem component
60
70
  * @returns {JSX.Element} MenuItem component
61
71
  */
62
- export declare const MenuItem: ({ className, dataTestId, label, size, children, selected, prefix, suffix, disabled, onClick, stopPropagation, id, tabIndex, }: MenuItemProps) => import("react/jsx-runtime").JSX.Element;
72
+ export declare const MenuItem: ({ className, dataTestId, label, size, children, selected, prefix, suffix, disabled, onClick, stopPropagation, id, tabIndex, variant, }: MenuItemProps) => import("react/jsx-runtime").JSX.Element;
63
73
  export {};
@@ -1,22 +1,35 @@
1
1
  import { type VariantProps } from "@trackunit/css-class-variance-utilities";
2
2
  import { MappedOmit } from "@trackunit/shared-utils";
3
3
  import { cvaInteractableItem } from "../../InteractableItem/InteractableItem.variants";
4
- export declare const cvaMenuItemStyle: (props?: ({
5
- size?: "small" | "medium" | null | undefined;
6
- } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
4
+ import { MenuItemVariant } from "./MenuItem";
7
5
  type CvaMenuItemProps = Partial<MappedOmit<VariantProps<typeof cvaInteractableItem>, "cursor">> & {
8
6
  size?: "small" | "medium";
7
+ variant?: MenuItemVariant;
8
+ selected?: boolean | null | undefined;
9
9
  };
10
10
  /**
11
11
  * Extends the cvaInteractableItem variant in order to set the padding, width, height, cursor, and other styles particular to the MenuItem component.
12
12
  * The cvaInteractableItem variant is used to set the standardized styles that change through interaction with the element (background color, hover, focus, and disabled).
13
13
  */
14
14
  export declare const cvaMenuItem: (props?: CvaMenuItemProps) => string;
15
- export declare const cvaMenuItemLabel: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
16
- export declare const cvaMenuItemSuffix: (props?: ({
15
+ export declare const cvaMenuItemStyle: (props?: ({
16
+ size?: "small" | "medium" | null | undefined;
17
+ variant?: "primary" | "danger" | null | undefined;
17
18
  selected?: boolean | null | undefined;
19
+ disabled?: boolean | null | undefined;
20
+ } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
21
+ export declare const cvaMenuItemLabel: (props?: ({
22
+ variant?: "primary" | "danger" | null | undefined;
23
+ disabled?: boolean | null | undefined;
18
24
  } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
19
25
  export declare const cvaMenuItemPrefix: (props?: ({
20
26
  selected?: boolean | null | undefined;
27
+ variant?: "primary" | "danger" | null | undefined;
28
+ disabled?: boolean | null | undefined;
29
+ } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
30
+ export declare const cvaMenuItemSuffix: (props?: ({
31
+ selected?: boolean | null | undefined;
32
+ variant?: "primary" | "danger" | null | undefined;
33
+ disabled?: boolean | null | undefined;
21
34
  } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
22
35
  export {};
@@ -1,17 +1,9 @@
1
1
  import { CommonProps } from "../../../common";
2
- import { MenuItemProps } from "../MenuItem/MenuItem";
3
- export interface MenuListItemProps extends MenuItemProps {
4
- showDivider?: boolean;
5
- }
6
2
  export interface MenuListProps extends CommonProps {
7
3
  /**
8
4
  * List of menu items to be rendered.
9
5
  */
10
6
  children: React.ReactNode;
11
- /**
12
- * List of menu items to be rendered.
13
- */
14
- showDivider?: boolean;
15
7
  /**
16
8
  * When enabled the menu list padding will be removed, and a grid will be applied to keep the first column "sticky".
17
9
  *
@@ -20,11 +12,30 @@ export interface MenuListProps extends CommonProps {
20
12
  withStickyHeader?: boolean;
21
13
  /** Click handler - typically used to trigger close action. when propagation is NOT prevented on menuItem */
22
14
  onClick?: () => void;
15
+ /**
16
+ * Enable multi-selection in the menu list.
17
+ *
18
+ * @default false
19
+ */
20
+ isMulti?: boolean;
21
+ /**
22
+ * Array of IDs representing the currently selected items.
23
+ */
24
+ selectedItems?: string[];
25
+ /**
26
+ * Callback triggered when selected items change.
27
+ */
28
+ onSelectionChange?: (selected: string[]) => void;
23
29
  }
24
30
  /**
25
- * The MenuList component is used for menus and selects.
26
-
31
+ * The MenuList is a popover menu that appears above all other content on the page. The menu offers a list of actions or functions that a user can access by clicking on a trigger.
32
+ *
33
+ * **When to use**
34
+ * - Use the MenuList if you have limited space and need to display overflow actions in a list.
35
+ * - Use the MenuList for actions that are not essential to completing workflows.
36
+ * - Don’t use the MenuList to display single or multi-select items within form components. For dropdowns within select components, use SelectDropdown (component not available yet).
37
+ *
27
38
  * @param {MenuListProps} props - The props for the MenuList component
28
39
  * @returns {JSX.Element} MenuList component
29
40
  */
30
- export declare const MenuList: ({ dataTestId, className, children, withStickyHeader, showDivider, ...args }: MenuListProps) => JSX.Element;
41
+ export declare const MenuList: ({ dataTestId, className, children, withStickyHeader, isMulti, selectedItems: controlledSelectedItems, onSelectionChange, ...args }: MenuListProps) => JSX.Element;
@@ -2,3 +2,5 @@ export declare const cvaMenuList: (props?: ({
2
2
  stickyHeader?: boolean | null | undefined;
3
3
  } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
4
4
  export declare const cvaMenuListDivider: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
5
+ export declare const cvaMenuListMultiSelect: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
6
+ export declare const cvaMenuListItem: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
@@ -1,3 +1,4 @@
1
+ export * from "./MenuDivider/MenuDivider";
1
2
  export * from "./MenuItem/MenuItem";
2
3
  export * from "./MenuList/MenuList";
3
4
  export * from "./MoreMenu/MoreMenu";