@primer/react
Version:
An implementation of GitHub's Primer Design System using React
210 lines (203 loc) • 6.4 kB
JavaScript
import { c } from 'react-compiler-runtime';
import React, { createElement } from 'react';
import { Group } from './Group.js';
import { Item } from './Item.js';
import { Divider } from './Divider.js';
import { clsx } from 'clsx';
import classes from './List.module.css.js';
import { jsxs, jsx } from 'react/jsx-runtime';
/**
* Asserts that the given value fulfills the `GroupedListProps` contract.
* @param props A value which fulfills either the `ListPropsBase` or the `GroupedListProps` contract.
*/
function isGroupedListProps(props) {
return 'groupMetadata' in props;
}
/**
* Contract for props passed to the `List` component.
*/
// Base styles for the List component
const listStyles = {
fontSize: 'var(--text-body-size-medium, 14px)',
// 14px font-size * 1.428571429 = 20px line height
// TODO: When rem-based spacing on a 4px scale lands, replace hardcoded '20px'
lineHeight: '20px'
};
/**
* Returns style objects for `List` children matching the given `List` style variation.
* @param variant `List` style variation.
*/
function useListVariant(variant = 'inset') {
switch (variant) {
case 'full':
return {
headerStyle: {
paddingLeft: 'var(--base-size-8, 8px)',
paddingRight: 'var(--base-size-8, 8px)'
},
itemStyle: {
borderRadius: 0
}
};
default:
return {
firstGroupStyle: {
marginTop: 'var(--base-size-8, 8px)'
},
lastGroupStyle: {
marginBottom: 'var(--base-size-8, 8px)'
},
itemStyle: {
marginLeft: 'var(--base-size-8, 8px)',
marginRight: 'var(--base-size-8, 8px)'
}
};
}
}
/**
* Lists `Item`s, either grouped or ungrouped, with a `Divider` between each `Group`.
*/
const List = /*#__PURE__*/React.forwardRef((props, forwardedRef) => {
const $ = c(14);
const {
style,
...restProps
} = props;
const {
firstGroupStyle,
lastGroupStyle,
headerStyle,
itemStyle
} = useListVariant(restProps.variant);
const renderGroup = groupProps => {
var _ref;
const GroupComponent = ((_ref = "renderGroup" in groupProps && groupProps.renderGroup) !== null && _ref !== void 0 ? _ref : restProps.renderGroup) || Group;
return /*#__PURE__*/createElement(GroupComponent, {
...groupProps,
key: groupProps.groupId
});
};
const renderItem = (itemProps, item, itemIndex) => {
var _ref2, _ref3, _itemProps$id;
const ItemComponent = "renderItem" in itemProps && itemProps.renderItem || restProps.renderItem || Item;
const key = (_ref2 = (_ref3 = "key" in itemProps ? itemProps.key : undefined) !== null && _ref3 !== void 0 ? _ref3 : (_itemProps$id = itemProps.id) === null || _itemProps$id === void 0 ? void 0 : _itemProps$id.toString()) !== null && _ref2 !== void 0 ? _ref2 : itemIndex.toString();
return /*#__PURE__*/createElement(ItemComponent, {
showDivider: restProps.showItemDividers,
selectionVariant: restProps.selectionVariant,
...itemProps,
key: key,
style: itemStyle,
item: item
});
};
let groups = [];
if (!isGroupedListProps(restProps)) {
let t0;
if ($[0] !== renderItem) {
t0 = (item_0, index) => renderItem(item_0, item_0, index);
$[0] = renderItem;
$[1] = t0;
} else {
t0 = $[1];
}
groups = [{
items: restProps.items.map(t0),
groupId: "0"
}];
} else {
const groupMap = restProps.groupMetadata.reduce(_temp, new Map());
for (const itemProps_0 of restProps.items) {
var _group$items$length, _group$items, _group$items2;
const group = groupMap.get(itemProps_0.groupId);
const itemIndex_0 = (_group$items$length = group === null || group === void 0 ? void 0 : (_group$items = group.items) === null || _group$items === void 0 ? void 0 : _group$items.length) !== null && _group$items$length !== void 0 ? _group$items$length : 0;
groupMap.set(itemProps_0.groupId, {
...group,
items: [...((_group$items2 = group === null || group === void 0 ? void 0 : group.items) !== null && _group$items2 !== void 0 ? _group$items2 : []), renderItem({
showDivider: group === null || group === void 0 ? void 0 : group.showItemDividers,
...(group && "renderItem" in group && {
renderItem: group.renderItem
}),
...itemProps_0
}, itemProps_0, itemIndex_0)]
});
}
groups = [...groupMap.values()];
}
let t0;
if ($[2] !== props.className) {
t0 = clsx(classes.List, props.className);
$[2] = props.className;
$[3] = t0;
} else {
t0 = $[3];
}
let t1;
if ($[4] !== style) {
t1 = style || {};
$[4] = style;
$[5] = t1;
} else {
t1 = $[5];
}
let t2;
if ($[6] !== t1) {
t2 = {
...listStyles,
...t1
};
$[6] = t1;
$[7] = t2;
} else {
t2 = $[7];
}
const t4 = groups.map((t3, index_0) => {
const {
header,
...groupProps_0
} = t3;
const hasFilledHeader = (header === null || header === void 0 ? void 0 : header.variant) === "filled";
const shouldShowDivider = index_0 > 0 && !hasFilledHeader;
return /*#__PURE__*/jsxs(React.Fragment, {
children: [shouldShowDivider ? /*#__PURE__*/jsx(Divider, {}, `${groupProps_0.groupId}-divider`) : null, renderGroup({
style: {
...(index_0 === 0 && firstGroupStyle),
...(index_0 === groups.length - 1 && lastGroupStyle),
...(index_0 > 0 && !shouldShowDivider && {
marginTop: "var(--base-size-8, 8px)"
})
},
...(header && {
header: {
...header,
style: headerStyle
}
}),
...groupProps_0
})]
}, groupProps_0.groupId);
});
let t5;
if ($[8] !== forwardedRef || $[9] !== restProps || $[10] !== t0 || $[11] !== t2 || $[12] !== t4) {
t5 = /*#__PURE__*/jsx("div", {
...restProps,
ref: forwardedRef,
className: t0,
style: t2,
children: t4
});
$[8] = forwardedRef;
$[9] = restProps;
$[10] = t0;
$[11] = t2;
$[12] = t4;
$[13] = t5;
} else {
t5 = $[13];
}
return t5;
});
List.displayName = 'ActionList';
function _temp(groupAccumulator, groupMetadata) {
return groupAccumulator.set(groupMetadata.groupId, groupMetadata);
}
export { List };