@primer/react
Version:
An implementation of GitHub's Primer Design System using React
387 lines (383 loc) • 12.2 kB
JavaScript
import { c } from 'react-compiler-runtime';
import React from 'react';
import { useId } from '../hooks/useId.js';
import { ListContext } from './shared.js';
import { useSlots } from '../hooks/useSlots.js';
import { invariant } from '../utils/invariant.js';
import { clsx } from 'clsx';
import classes from './ActionList.module.css.js';
import groupClasses from './Group.module.css.js';
import { GroupHeadingTrailingAction } from './GroupHeadingTrailingAction.js';
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import { useFeatureFlag } from '../FeatureFlags/useFeatureFlag.js';
const GROUP_HEADING_TRAILING_ACTION_FEATURE_FLAG = 'primer_react_action_list_group_heading_trailing_action';
const Heading = t0 => {
const $ = c(12);
let children;
let className;
let id;
let rest;
let t1;
if ($[0] !== t0) {
({
as: t1,
className,
children,
id,
...rest
} = t0);
$[0] = t0;
$[1] = children;
$[2] = className;
$[3] = id;
$[4] = rest;
$[5] = t1;
} else {
children = $[1];
className = $[2];
id = $[3];
rest = $[4];
t1 = $[5];
}
const Component = t1 === undefined ? "h3" : t1;
let t2;
if ($[6] !== Component || $[7] !== children || $[8] !== className || $[9] !== id || $[10] !== rest) {
t2 = /*#__PURE__*/jsx(Component, {
className: className,
id: id,
...rest,
children: children
});
$[6] = Component;
$[7] = children;
$[8] = className;
$[9] = id;
$[10] = rest;
$[11] = t2;
} else {
t2 = $[11];
}
return t2;
};
const HeadingWrap = ({
as = 'div',
children,
className,
...rest
}) => {
return /*#__PURE__*/React.createElement(as, {
...rest,
className
}, children);
};
const GroupContext = /*#__PURE__*/React.createContext({
groupHeadingId: undefined,
selectionVariant: undefined
});
const Group = t0 => {
var _ariaLabel, _title, _slots$groupHeading;
const $ = c(38);
let ariaLabel;
let auxiliaryText;
let className;
let props;
let role;
let selectionVariant;
let t1;
let title;
if ($[0] !== t0) {
({
title,
variant: t1,
auxiliaryText,
selectionVariant,
role,
className,
"aria-label": ariaLabel,
...props
} = t0);
$[0] = t0;
$[1] = ariaLabel;
$[2] = auxiliaryText;
$[3] = className;
$[4] = props;
$[5] = role;
$[6] = selectionVariant;
$[7] = t1;
$[8] = title;
} else {
ariaLabel = $[1];
auxiliaryText = $[2];
className = $[3];
props = $[4];
role = $[5];
selectionVariant = $[6];
t1 = $[7];
title = $[8];
}
const variant = t1 === undefined ? "subtle" : t1;
const id = useId();
const {
role: listRole
} = React.useContext(ListContext);
let t2;
if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
t2 = {
groupHeading: GroupHeading
};
$[9] = t2;
} else {
t2 = $[9];
}
const [slots, childrenWithoutSlots] = useSlots(props.children, t2);
let groupHeadingId = undefined;
if (slots.groupHeading) {
var _slots$groupHeading$p;
groupHeadingId = (_slots$groupHeading$p = slots.groupHeading.props.id) !== null && _slots$groupHeading$p !== void 0 ? _slots$groupHeading$p : id;
}
if (title) {
groupHeadingId = id;
}
let t3;
if ($[10] !== className) {
t3 = clsx(className, groupClasses.Group);
$[10] = className;
$[11] = t3;
} else {
t3 = $[11];
}
const t4 = listRole ? "none" : undefined;
let t5;
if ($[12] !== groupHeadingId || $[13] !== selectionVariant) {
t5 = {
selectionVariant,
groupHeadingId
};
$[12] = groupHeadingId;
$[13] = selectionVariant;
$[14] = t5;
} else {
t5 = $[14];
}
let t6;
if ($[15] !== auxiliaryText || $[16] !== slots.groupHeading || $[17] !== title || $[18] !== variant) {
t6 = title && !slots.groupHeading ? /*#__PURE__*/jsx(GroupHeading, {
variant: variant,
auxiliaryText: auxiliaryText,
_internalBackwardCompatibleTitle: title
}) : null;
$[15] = auxiliaryText;
$[16] = slots.groupHeading;
$[17] = title;
$[18] = variant;
$[19] = t6;
} else {
t6 = $[19];
}
let t7;
if ($[20] !== slots.groupHeading || $[21] !== title) {
t7 = !title && slots.groupHeading ? /*#__PURE__*/React.cloneElement(slots.groupHeading) : null;
$[20] = slots.groupHeading;
$[21] = title;
$[22] = t7;
} else {
t7 = $[22];
}
const t8 = listRole ? undefined : groupHeadingId;
const t9 = (_ariaLabel = ariaLabel) !== null && _ariaLabel !== void 0 ? _ariaLabel : listRole ? (_title = title) !== null && _title !== void 0 ? _title : (_slots$groupHeading = slots.groupHeading) === null || _slots$groupHeading === void 0 ? void 0 : _slots$groupHeading.props.children : undefined;
const t10 = role || listRole && "group";
const t11 = slots.groupHeading ? childrenWithoutSlots : props.children;
let t12;
if ($[23] !== t10 || $[24] !== t11 || $[25] !== t8 || $[26] !== t9) {
t12 = /*#__PURE__*/jsx("ul", {
"aria-labelledby": t8,
"aria-label": t9,
role: t10,
className: groupClasses.GroupList,
children: t11
});
$[23] = t10;
$[24] = t11;
$[25] = t8;
$[26] = t9;
$[27] = t12;
} else {
t12 = $[27];
}
let t13;
if ($[28] !== t12 || $[29] !== t5 || $[30] !== t6 || $[31] !== t7) {
t13 = /*#__PURE__*/jsxs(GroupContext.Provider, {
value: t5,
children: [t6, t7, t12]
});
$[28] = t12;
$[29] = t5;
$[30] = t6;
$[31] = t7;
$[32] = t13;
} else {
t13 = $[32];
}
let t14;
if ($[33] !== props || $[34] !== t13 || $[35] !== t3 || $[36] !== t4) {
t14 = /*#__PURE__*/jsx("li", {
className: t3,
"data-component": "ActionList.Group",
role: t4,
...props,
children: t13
});
$[33] = props;
$[34] = t13;
$[35] = t3;
$[36] = t4;
$[37] = t14;
} else {
t14 = $[37];
}
return t14;
};
/**
* Heading of a `Group`.
*
* As default, the role of ActionList is "list" and therefore group heading is rendered as a proper heading tag.
* If the role is "listbox" or "menu" (ActionMenu), the group heading is rendered as a div with presentation role and it is
* hidden from the accessibility tree due to the limitation of listbox children. https://w3c.github.io/aria/#listbox
* groups under menu or listbox are labelled by `aria-label`
*/
const GroupHeadingImpl = t0 => {
const $ = c(22);
let _internalBackwardCompatibleTitle;
let as;
let auxiliaryText;
let children;
let className;
let props;
let t1;
let t2;
if ($[0] !== t0) {
({
as,
variant: t1,
_internalBackwardCompatibleTitle,
auxiliaryText,
children,
className,
headingWrapElement: t2,
...props
} = t0);
$[0] = t0;
$[1] = _internalBackwardCompatibleTitle;
$[2] = as;
$[3] = auxiliaryText;
$[4] = children;
$[5] = className;
$[6] = props;
$[7] = t1;
$[8] = t2;
} else {
_internalBackwardCompatibleTitle = $[1];
as = $[2];
auxiliaryText = $[3];
children = $[4];
className = $[5];
props = $[6];
t1 = $[7];
t2 = $[8];
}
const variant = t1 === undefined ? "subtle" : t1;
const headingWrapElement = t2 === undefined ? "div" : t2;
const {
role: listRole
} = React.useContext(ListContext);
const {
groupHeadingId
} = React.useContext(GroupContext);
const trailingActionEnabled = useFeatureFlag(GROUP_HEADING_TRAILING_ACTION_FEATURE_FLAG);
let t3;
if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
t3 = {
trailingAction: GroupHeadingTrailingAction
};
$[9] = t3;
} else {
t3 = $[9];
}
const [slots, childrenWithoutSlots] = useSlots(children, t3);
const trailingAction = trailingActionEnabled ? slots.trailingAction : null;
const headingChildren = trailingActionEnabled ? childrenWithoutSlots : children;
if (trailingAction) {
!(listRole === undefined || listRole === "list") ? process.env.NODE_ENV !== "production" ? invariant(false, `ActionList.GroupHeading.TrailingAction can not be used inside an ActionList with an ARIA role of "${listRole}". Trailing actions on group headings are only supported in lists with the default "list" role.`) : invariant(false) : void 0;
}
const missingAsForList = (listRole === undefined || listRole === "list") && children !== undefined && as === undefined;
const unnecessaryAsForListboxOrMenu = listRole !== undefined && listRole !== "list" && children !== undefined && as !== undefined;
!!missingAsForList ? process.env.NODE_ENV !== "production" ? invariant(false, "You are setting a heading for a list, that requires a heading level. Please use 'as' prop to set a proper heading level.") : invariant(false) : void 0;
!!unnecessaryAsForListboxOrMenu ? process.env.NODE_ENV !== "production" ? invariant(false, `Looks like you are trying to set a heading level to a ${listRole} role. Group headings for ${listRole} type action lists are for representational purposes, and rendered as divs. Therefore they don't need a heading level.`) : invariant(false) : void 0;
let t4;
if ($[10] !== _internalBackwardCompatibleTitle || $[11] !== as || $[12] !== auxiliaryText || $[13] !== className || $[14] !== groupHeadingId || $[15] !== headingChildren || $[16] !== headingWrapElement || $[17] !== listRole || $[18] !== props || $[19] !== trailingAction || $[20] !== variant) {
var _internalBackwardComp, _internalBackwardComp2;
t4 = /*#__PURE__*/jsx(Fragment, {
children: listRole && listRole !== "list" ? /*#__PURE__*/jsxs(HeadingWrap, {
role: "presentation",
className: groupClasses.GroupHeadingWrap,
"aria-hidden": "true",
"data-variant": variant,
"data-component": "GroupHeadingWrap",
as: headingWrapElement,
...props,
children: [/*#__PURE__*/jsx("span", {
className: clsx(className, groupClasses.GroupHeading),
id: groupHeadingId,
children: (_internalBackwardComp = _internalBackwardCompatibleTitle) !== null && _internalBackwardComp !== void 0 ? _internalBackwardComp : headingChildren
}), auxiliaryText && /*#__PURE__*/jsx("div", {
className: classes.Description,
children: auxiliaryText
})]
}) : /*#__PURE__*/jsxs(HeadingWrap, {
className: groupClasses.GroupHeadingWrap,
"data-variant": variant,
"data-has-trailing-action": trailingAction ? "" : undefined,
as: headingWrapElement,
"data-component": "GroupHeadingWrap",
children: [/*#__PURE__*/jsx(Heading, {
className: clsx(className, groupClasses.GroupHeading),
as: as || "h3",
id: groupHeadingId,
...props,
children: (_internalBackwardComp2 = _internalBackwardCompatibleTitle) !== null && _internalBackwardComp2 !== void 0 ? _internalBackwardComp2 : headingChildren
}), auxiliaryText && /*#__PURE__*/jsx("div", {
className: classes.Description,
children: auxiliaryText
}), trailingAction ? /*#__PURE__*/jsx("span", {
className: groupClasses.GroupHeadingTrailingAction,
children: trailingAction
}) : null]
})
});
$[10] = _internalBackwardCompatibleTitle;
$[11] = as;
$[12] = auxiliaryText;
$[13] = className;
$[14] = groupHeadingId;
$[15] = headingChildren;
$[16] = headingWrapElement;
$[17] = listRole;
$[18] = props;
$[19] = trailingAction;
$[20] = variant;
$[21] = t4;
} else {
t4 = $[21];
}
return t4;
};
GroupHeadingImpl.displayName = 'ActionList.GroupHeading';
Group.displayName = 'ActionList.Group';
Group.__SLOT__ = Symbol('ActionList.Group');
GroupHeadingImpl.__SLOT__ = Symbol('ActionList.GroupHeading');
// Expose GroupHeadingTrailingAction as ActionList.GroupHeading.TrailingAction
// so the API mirrors the visual nesting (the action lives inside the heading).
const GroupHeading = Object.assign(GroupHeadingImpl, {
TrailingAction: GroupHeadingTrailingAction
});
export { Group, GroupContext, GroupHeading };