UNPKG

@primer/react

Version:

An implementation of GitHub's Primer Design System using React

824 lines (820 loc) • 23.3 kB
import { c } from 'react-compiler-runtime'; import React from 'react'; import { useId } from '../hooks/useId.js'; import { useSlots } from '../hooks/useSlots.js'; import { ActionListContainerContext } from './ActionListContainerContext.js'; import { Description } from './Description.js'; import { GroupContext } from './Group.js'; import { Selection } from './Selection.js'; import { TrailingVisual, LeadingVisual, VisualOrIndicator } from './Visuals.js'; import { ListContext, ItemContext } from './shared.js'; import { TrailingAction } from './TrailingAction.js'; import { ConditionalWrapper } from '../internal/components/ConditionalWrapper.js'; import { invariant } from '../utils/invariant.js'; import VisuallyHidden from '../_VisuallyHidden.js'; import classes from './ActionList.module.css.js'; import { clsx } from 'clsx'; import { fixedForwardRef } from '../utils/modern-polymorphic.js'; import { TooltipContext, Tooltip } from '../TooltipV2/Tooltip.js'; import { jsx, jsxs, Fragment } from 'react/jsx-runtime'; /** * Wraps button-semantic items with Tooltip, disabled when not truncated * For non-button-semantic items, renders children directly. */ const ConditionalTooltip = /*#__PURE__*/React.forwardRef(function ConditionalTooltip(t0, forwardedRef) { const $ = c(4); const { text, enabled, children } = t0; if (!enabled || !text) { return children; } const t1 = text || ""; let t2; if ($[0] !== children || $[1] !== forwardedRef || $[2] !== t1) { t2 = /*#__PURE__*/jsx(Tooltip, { ref: forwardedRef, text: t1, direction: "e", delay: "medium", children: children }); $[0] = children; $[1] = forwardedRef; $[2] = t1; $[3] = t2; } else { t2 = $[3]; } return t2; }); const SubItem = t0 => { const $ = c(2); const { children } = t0; let t1; if ($[0] !== children) { t1 = /*#__PURE__*/jsx(Fragment, { children: children }); $[0] = children; $[1] = t1; } else { t1 = $[1]; } return t1; }; SubItem.displayName = 'ActionList.SubItem'; const ButtonItemContainer = /*#__PURE__*/React.forwardRef((t0, forwardedRef) => { const $ = c(9); let children; let props; let style; if ($[0] !== t0) { ({ children, style, ...props } = t0); $[0] = t0; $[1] = children; $[2] = props; $[3] = style; } else { children = $[1]; props = $[2]; style = $[3]; } const t1 = forwardedRef; let t2; if ($[4] !== children || $[5] !== props || $[6] !== style || $[7] !== t1) { t2 = /*#__PURE__*/jsx("button", { type: "button", ref: t1, style: style, ...props, children: children }); $[4] = children; $[5] = props; $[6] = style; $[7] = t1; $[8] = t2; } else { t2 = $[8]; } return t2; }); const DivItemContainer = /*#__PURE__*/React.forwardRef((t0, forwardedRef) => { const $ = c(7); let children; let props; if ($[0] !== t0) { ({ children, ...props } = t0); $[0] = t0; $[1] = children; $[2] = props; } else { children = $[1]; props = $[2]; } const t1 = forwardedRef; let t2; if ($[3] !== children || $[4] !== props || $[5] !== t1) { t2 = /*#__PURE__*/jsx("div", { ref: t1, ...props, children: children }); $[3] = children; $[4] = props; $[5] = t1; $[6] = t2; } else { t2 = $[6]; } return t2; }); const baseSlots = { leadingVisual: LeadingVisual, trailingVisual: TrailingVisual, trailingAction: TrailingAction, subItem: SubItem }; const slotsConfig = { ...baseSlots, description: Description }; // Pre-allocated array for selectableRoles check, avoids per-render allocation const selectableRoles = ['menuitemradio', 'menuitemcheckbox', 'option', 'treeitem']; const listRoleTypes = ['listbox', 'menu', 'list', 'tree']; const UnwrappedItem = (t0, forwardedRef) => { var _slots$trailingVisual, _slots$description$pr, _slots$description; const $ = c(159); let _PrivateItemWrapper; let className; let id; let inactiveText; let loading; let onSelectUser; let props; let role; let t1; let t2; let t3; let t4; let t5; if ($[0] !== t0) { const { variant: t6, size: t7, disabled: t8, inactiveText: t9, selected: t10, active: t11, onSelect: t12, id: t13, role: t14, loading: t15, _PrivateItemWrapper: t16, className: t17, groupId: _groupId, renderItem: _renderItem, handleAddItem: _handleAddItem, ...t18 } = t0; t1 = t6; t2 = t7; t3 = t8; inactiveText = t9; t4 = t10; t5 = t11; onSelectUser = t12; id = t13; role = t14; loading = t15; _PrivateItemWrapper = t16; className = t17; props = t18; $[0] = t0; $[1] = _PrivateItemWrapper; $[2] = className; $[3] = id; $[4] = inactiveText; $[5] = loading; $[6] = onSelectUser; $[7] = props; $[8] = role; $[9] = t1; $[10] = t2; $[11] = t3; $[12] = t4; $[13] = t5; } else { _PrivateItemWrapper = $[1]; className = $[2]; id = $[3]; inactiveText = $[4]; loading = $[5]; onSelectUser = $[6]; props = $[7]; role = $[8]; t1 = $[9]; t2 = $[10]; t3 = $[11]; t4 = $[12]; t5 = $[13]; } const variant = t1 === undefined ? "default" : t1; const size = t2 === undefined ? "medium" : t2; const disabled = t3 === undefined ? false : t3; const selected = t4 === undefined ? undefined : t4; const active = t5 === undefined ? false : t5; const [partialSlots, childrenWithoutSlots] = useSlots(props.children, slotsConfig); let t6; if ($[14] !== partialSlots) { t6 = { description: undefined, ...partialSlots }; $[14] = partialSlots; $[15] = t6; } else { t6 = $[15]; } const slots = t6; const { container, afterSelect, selectionAttribute, defaultTrailingVisual } = React.useContext(ActionListContainerContext); let t7; if ($[16] !== defaultTrailingVisual) { t7 = defaultTrailingVisual ? /*#__PURE__*/jsx(TrailingVisual, { children: defaultTrailingVisual }) : null; $[16] = defaultTrailingVisual; $[17] = t7; } else { t7 = $[17]; } const wrappedDefaultTrailingVisual = t7; const trailingVisual = (_slots$trailingVisual = slots.trailingVisual) !== null && _slots$trailingVisual !== void 0 ? _slots$trailingVisual : wrappedDefaultTrailingVisual; const { role: listRole, selectionVariant: listSelectionVariant } = React.useContext(ListContext); const { selectionVariant: groupSelectionVariant } = React.useContext(GroupContext); const inactive = Boolean(inactiveText); const menuContext = container === "ActionMenu" || container === "SelectPanel" || container === "FilteredActionList"; let t8; if ($[18] !== inactive || $[19] !== listRole) { t8 = inactive && !(listRole !== undefined && ["menu", "listbox"].includes(listRole)); $[18] = inactive; $[19] = listRole; $[20] = t8; } else { t8 = $[20]; } const showInactiveIndicator = t8; let t9; if ($[21] !== onSelectUser) { t9 = (event, afterSelect_0) => { if (typeof onSelectUser === "function") { onSelectUser(event); } if (event.defaultPrevented) { return; } if (typeof afterSelect_0 === "function") { afterSelect_0(event); } }; $[21] = onSelectUser; $[22] = t9; } else { t9 = $[22]; } const onSelect = t9; const selectionVariant = groupSelectionVariant ? groupSelectionVariant : listSelectionVariant; let inferredItemRole; if (container === "ActionMenu") { if (selectionVariant === "single") { inferredItemRole = "menuitemradio"; } else { if (selectionVariant === "multiple") { inferredItemRole = "menuitemcheckbox"; } else { inferredItemRole = "menuitem"; } } } else { if (listRole === "listbox") { if (selectionVariant !== undefined && !role) { inferredItemRole = "option"; } } else { if (listRole === "tablist") { inferredItemRole = "tab"; } } } const itemRole = role || inferredItemRole; if (slots.trailingAction) { !!menuContext ? process.env.NODE_ENV !== "production" ? invariant(false, "ActionList.TrailingAction can not be used within a list with an ARIA role of \"menu\" or \"listbox\".") : invariant(false) : void 0; } let inferredSelectionAttribute; if (itemRole === "menuitemradio" || itemRole === "menuitemcheckbox") { inferredSelectionAttribute = "aria-checked"; } else { if (itemRole === "option") { inferredSelectionAttribute = "aria-selected"; } } const itemSelectionAttribute = selectionAttribute || inferredSelectionAttribute; const listItemSemantics = itemRole === "option" || itemRole === "menuitem" || itemRole === "menuitemradio" || itemRole === "menuitemcheckbox" || itemRole === "tab"; let t10; if ($[23] !== inactive || $[24] !== listItemSemantics || $[25] !== listRole) { t10 = listRole && listRoleTypes.includes(listRole) || inactive || listItemSemantics; $[23] = inactive; $[24] = listItemSemantics; $[25] = listRole; $[26] = t10; } else { t10 = $[26]; } const listSemantics = t10; const buttonSemantics = !listSemantics && !_PrivateItemWrapper; let t11; if ($[27] !== afterSelect || $[28] !== disabled || $[29] !== inactive || $[30] !== loading || $[31] !== onSelect) { t11 = event_0 => { if (disabled || inactive || loading) { return; } onSelect(event_0, afterSelect); }; $[27] = afterSelect; $[28] = disabled; $[29] = inactive; $[30] = loading; $[31] = onSelect; $[32] = t11; } else { t11 = $[32]; } const clickHandler = t11; let t12; if ($[33] !== afterSelect || $[34] !== disabled || $[35] !== inactive || $[36] !== loading || $[37] !== onSelect) { t12 = event_1 => { if (disabled || inactive || loading) { return; } if (event_1.key === " " || event_1.key === "Enter") { if (event_1.key === " ") { event_1.preventDefault(); event_1.defaultPrevented = false; } onSelect(event_1, afterSelect); } }; $[33] = afterSelect; $[34] = disabled; $[35] = inactive; $[36] = loading; $[37] = onSelect; $[38] = t12; } else { t12 = $[38]; } const keyPressHandler = t12; const itemId = useId(id); const labelId = `${itemId}--label`; const inlineDescriptionId = `${itemId}--inline-description`; const blockDescriptionId = `${itemId}--block-description`; const trailingVisualId = `${itemId}--trailing-visual`; const inactiveWarningId = inactive && !showInactiveIndicator ? `${itemId}--warning-message` : undefined; const [truncatedText, setTruncatedText] = React.useState(undefined); const DefaultItemWrapper = listSemantics ? DivItemContainer : ButtonItemContainer; const ItemWrapper = _PrivateItemWrapper || DefaultItemWrapper; let t13; if ($[39] !== itemRole || $[40] !== itemSelectionAttribute) { t13 = itemSelectionAttribute && itemRole && selectableRoles.includes(itemRole); $[39] = itemRole; $[40] = itemSelectionAttribute; $[41] = t13; } else { t13 = $[41]; } const includeSelectionAttribute = t13; const focusable = showInactiveIndicator ? true : undefined; const descriptionVariant = (_slots$description$pr = (_slots$description = slots.description) === null || _slots$description === void 0 ? void 0 : _slots$description.props.variant) !== null && _slots$description$pr !== void 0 ? _slots$description$pr : "inline"; const hasTrailingVisualSlot = Boolean(slots.trailingVisual); const hasDescriptionSlot = Boolean(slots.description); let parts; if ($[42] !== hasTrailingVisualSlot || $[43] !== labelId || $[44] !== trailingVisualId) { parts = [labelId]; if (hasTrailingVisualSlot) { parts.push(trailingVisualId); } $[42] = hasTrailingVisualSlot; $[43] = labelId; $[44] = trailingVisualId; $[45] = parts; } else { parts = $[45]; } const ariaLabelledBy = parts.join(" "); let parts_0; if ($[46] !== blockDescriptionId || $[47] !== descriptionVariant || $[48] !== hasDescriptionSlot || $[49] !== inactiveWarningId || $[50] !== inlineDescriptionId) { parts_0 = []; if (hasDescriptionSlot && descriptionVariant === "block") { parts_0.push(blockDescriptionId); } if (hasDescriptionSlot && descriptionVariant === "inline") { parts_0.push(inlineDescriptionId); } if (inactiveWarningId) { parts_0.push(inactiveWarningId); } $[46] = blockDescriptionId; $[47] = descriptionVariant; $[48] = hasDescriptionSlot; $[49] = inactiveWarningId; $[50] = inlineDescriptionId; $[51] = parts_0; } else { parts_0 = $[51]; } const ariaDescribedBy = parts_0.length > 0 ? parts_0.join(" ") : undefined; const t14 = !buttonSemantics ? keyPressHandler : undefined; const t15 = disabled ? true : undefined; const t16 = inactive ? true : undefined; const t17 = loading && !inactive ? true : undefined; const t18 = focusable ? undefined : 0; let t19; if ($[52] !== includeSelectionAttribute || $[53] !== itemSelectionAttribute || $[54] !== selected) { t19 = includeSelectionAttribute && { [itemSelectionAttribute]: selected }; $[52] = includeSelectionAttribute; $[53] = itemSelectionAttribute; $[54] = selected; $[55] = t19; } else { t19 = $[55]; } let t20; if ($[56] !== ariaDescribedBy || $[57] !== ariaLabelledBy || $[58] !== clickHandler || $[59] !== itemId || $[60] !== itemRole || $[61] !== t14 || $[62] !== t15 || $[63] !== t16 || $[64] !== t17 || $[65] !== t18 || $[66] !== t19) { t20 = { onClick: clickHandler, onKeyPress: t14, "aria-disabled": t15, "data-inactive": t16, "data-loading": t17, tabIndex: t18, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...t19, role: itemRole, id: itemId }; $[56] = ariaDescribedBy; $[57] = ariaLabelledBy; $[58] = clickHandler; $[59] = itemId; $[60] = itemRole; $[61] = t14; $[62] = t15; $[63] = t16; $[64] = t17; $[65] = t18; $[66] = t19; $[67] = t20; } else { t20 = $[67]; } const menuItemProps = t20; let t21; if ($[68] !== _PrivateItemWrapper || $[69] !== forwardedRef || $[70] !== itemRole || $[71] !== listSemantics || $[72] !== menuItemProps || $[73] !== props) { t21 = _PrivateItemWrapper ? { role: itemRole ? "none" : undefined, ...props } : listSemantics && { ...menuItemProps, ...props, ref: forwardedRef } || {}; $[68] = _PrivateItemWrapper; $[69] = forwardedRef; $[70] = itemRole; $[71] = listSemantics; $[72] = menuItemProps; $[73] = props; $[74] = t21; } else { t21 = $[74]; } const containerProps = t21; let t22; if ($[75] !== _PrivateItemWrapper || $[76] !== forwardedRef || $[77] !== listSemantics || $[78] !== menuItemProps || $[79] !== props) { t22 = _PrivateItemWrapper ? menuItemProps : !listSemantics && { ...menuItemProps, ...props, ref: forwardedRef }; $[75] = _PrivateItemWrapper; $[76] = forwardedRef; $[77] = listSemantics; $[78] = menuItemProps; $[79] = props; $[80] = t22; } else { t22 = $[80]; } const wrapperProps = t22; const t23 = Boolean(inactiveText); const t24 = buttonSemantics ? setTruncatedText : undefined; let t25; if ($[81] !== blockDescriptionId || $[82] !== disabled || $[83] !== inlineDescriptionId || $[84] !== size || $[85] !== t23 || $[86] !== t24 || $[87] !== trailingVisualId || $[88] !== variant) { t25 = { variant, size, disabled, inactive: t23, inlineDescriptionId, blockDescriptionId, trailingVisualId, setTruncatedText: t24 }; $[81] = blockDescriptionId; $[82] = disabled; $[83] = inlineDescriptionId; $[84] = size; $[85] = t23; $[86] = t24; $[87] = trailingVisualId; $[88] = variant; $[89] = t25; } else { t25 = $[89]; } const itemContextValue = t25; const t26 = listSemantics ? forwardedRef : null; const t27 = variant === "danger" ? variant : undefined; const t28 = active ? true : undefined; const t29 = inactiveText ? true : undefined; const t30 = disabled ? true : undefined; const t31 = slots.subItem ? true : undefined; const t32 = slots.description ? true : false; let t33; if ($[90] !== className) { t33 = clsx(classes.ActionListItem, className); $[90] = className; $[91] = t33; } else { t33 = $[91]; } let t34; let t35; if ($[92] === Symbol.for("react.memo_cache_sentinel")) { t34 = {}; t35 = /*#__PURE__*/jsx("span", { className: classes.Spacer }); $[92] = t34; $[93] = t35; } else { t34 = $[92]; t35 = $[93]; } let t36; if ($[94] !== selected) { t36 = /*#__PURE__*/jsx(Selection, { selected: selected, className: classes.LeadingAction }); $[94] = selected; $[95] = t36; } else { t36 = $[95]; } const t37 = showInactiveIndicator ? inactiveText : undefined; const t38 = Boolean(slots.leadingVisual); let t39; if ($[96] !== labelId || $[97] !== loading || $[98] !== slots.leadingVisual || $[99] !== t37 || $[100] !== t38) { t39 = /*#__PURE__*/jsx(VisualOrIndicator, { inactiveText: t37, itemHasLeadingVisual: t38, labelId: labelId, loading: loading, position: "leading", children: slots.leadingVisual }); $[96] = labelId; $[97] = loading; $[98] = slots.leadingVisual; $[99] = t37; $[100] = t38; $[101] = t39; } else { t39 = $[101]; } const t40 = !!slots.description; let t41; if ($[102] !== inactive || $[103] !== loading) { t41 = loading === true && !inactive && /*#__PURE__*/jsx(VisuallyHidden, { children: "Loading" }); $[102] = inactive; $[103] = loading; $[104] = t41; } else { t41 = $[104]; } let t42; if ($[105] !== childrenWithoutSlots || $[106] !== labelId || $[107] !== t41) { t42 = /*#__PURE__*/jsxs("span", { id: labelId, className: classes.ItemLabel, "data-component": "ActionList.Item.Label", children: [childrenWithoutSlots, t41] }); $[105] = childrenWithoutSlots; $[106] = labelId; $[107] = t41; $[108] = t42; } else { t42 = $[108]; } let t43; if ($[109] !== descriptionVariant || $[110] !== slots.description || $[111] !== t40 || $[112] !== t42) { t43 = /*#__PURE__*/jsxs(ConditionalWrapper, { if: t40, className: classes.ItemDescriptionWrap, "data-description-variant": descriptionVariant, children: [t42, slots.description] }); $[109] = descriptionVariant; $[110] = slots.description; $[111] = t40; $[112] = t42; $[113] = t43; } else { t43 = $[113]; } const t44 = showInactiveIndicator ? inactiveText : undefined; const t45 = Boolean(slots.leadingVisual); let t46; if ($[114] !== labelId || $[115] !== loading || $[116] !== t44 || $[117] !== t45 || $[118] !== trailingVisual) { t46 = /*#__PURE__*/jsx(VisualOrIndicator, { inactiveText: t44, itemHasLeadingVisual: t45, labelId: labelId, loading: loading, position: "trailing", children: trailingVisual }); $[114] = labelId; $[115] = loading; $[116] = t44; $[117] = t45; $[118] = trailingVisual; $[119] = t46; } else { t46 = $[119]; } let t47; if ($[120] !== inactiveText || $[121] !== inactiveWarningId || $[122] !== showInactiveIndicator) { t47 = !showInactiveIndicator && inactiveText ? /*#__PURE__*/jsx("span", { className: classes.InactiveWarning, id: inactiveWarningId, children: inactiveText }) : null; $[120] = inactiveText; $[121] = inactiveWarningId; $[122] = showInactiveIndicator; $[123] = t47; } else { t47 = $[123]; } let t48; if ($[124] !== t43 || $[125] !== t46 || $[126] !== t47) { t48 = /*#__PURE__*/jsxs("span", { className: classes.ActionListSubContent, "data-component": "ActionList.Item--DividerContainer", children: [t43, t46, t47] }); $[124] = t43; $[125] = t46; $[126] = t47; $[127] = t48; } else { t48 = $[127]; } let t49; if ($[128] !== t36 || $[129] !== t39 || $[130] !== t48) { t49 = /*#__PURE__*/jsxs(TooltipContext.Provider, { value: t34, children: [t35, t36, t39, t48] }); $[128] = t36; $[129] = t39; $[130] = t48; $[131] = t49; } else { t49 = $[131]; } let t50; if ($[132] !== ItemWrapper || $[133] !== forwardedRef || $[134] !== size || $[135] !== t49 || $[136] !== wrapperProps) { t50 = /*#__PURE__*/jsx(ItemWrapper, { ...wrapperProps, className: classes.ActionListContent, "data-size": size, ref: forwardedRef, children: t49 }); $[132] = ItemWrapper; $[133] = forwardedRef; $[134] = size; $[135] = t49; $[136] = wrapperProps; $[137] = t50; } else { t50 = $[137]; } let t51; if ($[138] !== buttonSemantics || $[139] !== forwardedRef || $[140] !== t50 || $[141] !== truncatedText) { t51 = /*#__PURE__*/jsx(ConditionalTooltip, { ref: forwardedRef, text: truncatedText, enabled: buttonSemantics, children: t50 }); $[138] = buttonSemantics; $[139] = forwardedRef; $[140] = t50; $[141] = truncatedText; $[142] = t51; } else { t51 = $[142]; } const t52 = !inactive && !loading && !menuContext && Boolean(slots.trailingAction) && slots.trailingAction; let t53; if ($[143] !== containerProps || $[144] !== slots.subItem || $[145] !== t26 || $[146] !== t27 || $[147] !== t28 || $[148] !== t29 || $[149] !== t30 || $[150] !== t31 || $[151] !== t32 || $[152] !== t33 || $[153] !== t51 || $[154] !== t52) { t53 = /*#__PURE__*/jsxs("li", { ...containerProps, ref: t26, "data-component": "ActionList.Item", "data-variant": t27, "data-active": t28, "data-inactive": t29, "data-is-disabled": t30, "data-has-subitem": t31, "data-has-description": t32, className: t33, children: [t51, t52, slots.subItem] }); $[143] = containerProps; $[144] = slots.subItem; $[145] = t26; $[146] = t27; $[147] = t28; $[148] = t29; $[149] = t30; $[150] = t31; $[151] = t32; $[152] = t33; $[153] = t51; $[154] = t52; $[155] = t53; } else { t53 = $[155]; } let t54; if ($[156] !== itemContextValue || $[157] !== t53) { t54 = /*#__PURE__*/jsx(ItemContext.Provider, { value: itemContextValue, children: t53 }); $[156] = itemContextValue; $[157] = t53; $[158] = t54; } else { t54 = $[158]; } return t54; }; const Item = Object.assign(fixedForwardRef(UnwrappedItem), { displayName: 'ActionList.Item', __SLOT__: Symbol('ActionList.Item') }); export { Item, SubItem };