@primer/react
Version:
An implementation of GitHub's Primer Design System using React
246 lines (243 loc) • 8.96 kB
JavaScript
import { c } from 'react-compiler-runtime';
import React, { useRef, useState } from 'react';
import SegmentedControlButton from './SegmentedControlButton.js';
import { SegmentedControlIconButton } from './SegmentedControlIconButton.js';
import { ActionList } from '../ActionList/index.js';
import { useTheme } from '../ThemeProvider.js';
import { useResponsiveValue } from '../hooks/useResponsiveValue.js';
import { isElement } from 'react-is';
import classes from './SegmentedControl.module.css.js';
import { clsx } from 'clsx';
import { BoxWithFallback } from '../internal/components/BoxWithFallback.js';
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
import { ActionMenu } from '../ActionMenu/ActionMenu.js';
const Root = t0 => {
const $ = c(30);
let ariaLabel;
let ariaLabelledby;
let children;
let className;
let fullWidth;
let onChange;
let rest;
let size;
let sxProp;
let t1;
if ($[0] !== t0) {
({
"aria-label": ariaLabel,
"aria-labelledby": ariaLabelledby,
children,
fullWidth,
onChange,
size,
sx: sxProp,
variant: t1,
className,
...rest
} = t0);
$[0] = t0;
$[1] = ariaLabel;
$[2] = ariaLabelledby;
$[3] = children;
$[4] = className;
$[5] = fullWidth;
$[6] = onChange;
$[7] = rest;
$[8] = size;
$[9] = sxProp;
$[10] = t1;
} else {
ariaLabel = $[1];
ariaLabelledby = $[2];
children = $[3];
className = $[4];
fullWidth = $[5];
onChange = $[6];
rest = $[7];
size = $[8];
sxProp = $[9];
t1 = $[10];
}
const variant = t1 === undefined ? "default" : t1;
const segmentedControlContainerRef = useRef(null);
const {
theme
} = useTheme();
let t2;
if ($[11] !== children || $[12] !== onChange) {
t2 = onChange === undefined || React.Children.toArray(children).some(_temp);
$[11] = children;
$[12] = onChange;
$[13] = t2;
} else {
t2 = $[13];
}
const isUncontrolled = t2;
const responsiveVariant = useResponsiveValue(variant, "default");
const isFullWidth = useResponsiveValue(fullWidth, false);
let t3;
if ($[14] !== children) {
const selectedSegments = React.Children.toArray(children).map(_temp2);
const hasSelectedButton = selectedSegments.some(_temp3);
t3 = hasSelectedButton ? selectedSegments.indexOf(true) : 0;
$[14] = children;
$[15] = t3;
} else {
t3 = $[15];
}
const selectedIndexExternal = t3;
const [selectedIndexInternalState, setSelectedIndexInternalState] = useState(selectedIndexExternal);
const selectedIndex = isUncontrolled ? selectedIndexInternalState : selectedIndexExternal;
let t4;
if ($[16] !== ariaLabel || $[17] !== ariaLabelledby || $[18] !== children || $[19] !== className || $[20] !== isFullWidth || $[21] !== isUncontrolled || $[22] !== onChange || $[23] !== responsiveVariant || $[24] !== rest || $[25] !== selectedIndex || $[26] !== size || $[27] !== sxProp || $[28] !== (theme === null || theme === void 0 ? void 0 : theme.colors)) {
const selectedChild = /*#__PURE__*/React.isValidElement(React.Children.toArray(children)[selectedIndex]) ? React.Children.toArray(children)[selectedIndex] : undefined;
const getChildIcon = _temp4;
const getChildText = _temp5;
if (!ariaLabel && !ariaLabelledby) {
console.warn("Use the `aria-label` or `aria-labelledby` prop to provide an accessible label for assistive technologies");
}
t4 = responsiveVariant === "dropdown" ? /*#__PURE__*/jsx(Fragment, {
children: /*#__PURE__*/jsxs(ActionMenu, {
children: [/*#__PURE__*/jsx(ActionMenu.Button, {
"aria-label": ariaLabel && `${getChildText(selectedChild)}, ${ariaLabel}`,
leadingVisual: getChildIcon(selectedChild),
children: getChildText(selectedChild)
}), /*#__PURE__*/jsx(ActionMenu.Overlay, {
"aria-labelledby": ariaLabelledby,
children: /*#__PURE__*/jsx(ActionList, {
selectionVariant: "single",
children: React.Children.map(children, (child_1, index) => {
const ChildIcon = getChildIcon(child_1);
if (! /*#__PURE__*/React.isValidElement(child_1)) {
return null;
}
return /*#__PURE__*/jsxs(ActionList.Item, {
selected: index === selectedIndex,
onSelect: event => {
isUncontrolled && setSelectedIndexInternalState(index);
onChange && onChange(index);
child_1.props.onClick && child_1.props.onClick(event);
},
children: [ChildIcon, " ", getChildText(child_1)]
}, `segmented-control-action-btn-${index}`);
})
})
})]
})
}) : /*#__PURE__*/jsx(BoxWithFallback, {
as: "ul",
sx: sxProp,
"aria-label": ariaLabel,
"aria-labelledby": ariaLabelledby,
ref: segmentedControlContainerRef,
className: clsx(classes.SegmentedControl, className),
"data-full-width": isFullWidth || undefined,
"data-size": size,
...rest,
children: React.Children.map(children, (child_2, index_0) => {
if (! /*#__PURE__*/React.isValidElement(child_2)) {
return null;
}
const sharedChildProps = {
onClick: onChange ? event_0 => {
onChange(index_0);
isUncontrolled && setSelectedIndexInternalState(index_0);
child_2.props.onClick && child_2.props.onClick(event_0);
} : event_1 => {
child_2.props.onClick && child_2.props.onClick(event_1);
isUncontrolled && setSelectedIndexInternalState(index_0);
},
selected: index_0 === selectedIndex,
style: {
"--separator-color": index_0 === selectedIndex || index_0 === selectedIndex - 1 ? "transparent" : theme === null || theme === void 0 ? void 0 : theme.colors.border.default,
...child_2.props.style
},
sx: child_2.props.sx
};
if (responsiveVariant === "hideLabels" && /*#__PURE__*/React.isValidElement(child_2) && child_2.type === SegmentedControlButton) {
const {
"aria-label": childAriaLabel,
leadingIcon,
children: childPropsChildren,
...restChildProps
} = child_2.props;
const {
sx: sharedSxProp,
...restSharedChildProps
} = sharedChildProps;
if (!leadingIcon) {
console.warn("A `leadingIcon` prop is required when hiding visible labels");
} else {
return /*#__PURE__*/jsx(SegmentedControlIconButton, {
"aria-label": childAriaLabel || childPropsChildren,
icon: leadingIcon,
sx: {
...sharedSxProp,
width: !isFullWidth ? "32px" : "100%"
},
...restSharedChildProps,
...restChildProps
});
}
}
return /*#__PURE__*/React.cloneElement(child_2, sharedChildProps);
})
});
$[16] = ariaLabel;
$[17] = ariaLabelledby;
$[18] = children;
$[19] = className;
$[20] = isFullWidth;
$[21] = isUncontrolled;
$[22] = onChange;
$[23] = responsiveVariant;
$[24] = rest;
$[25] = selectedIndex;
$[26] = size;
$[27] = sxProp;
$[28] = theme === null || theme === void 0 ? void 0 : theme.colors;
$[29] = t4;
} else {
t4 = $[29];
}
return t4;
};
Root.displayName = 'SegmentedControl';
const SegmentedControl = Object.assign(Root, {
Button: SegmentedControlButton,
IconButton: SegmentedControlIconButton
});
function _temp(child) {
return /*#__PURE__*/React.isValidElement(child) && child.props.defaultSelected !== undefined;
}
function _temp2(child_0) {
return /*#__PURE__*/React.isValidElement(child_0) && (child_0.props.defaultSelected || child_0.props.selected);
}
function _temp3(isSelected) {
return isSelected;
}
function _temp4(childArg) {
if (/*#__PURE__*/React.isValidElement(childArg) && childArg.type === SegmentedControlButton && childArg.props.leadingIcon) {
if (isElement(childArg.props.leadingIcon)) {
return childArg.props.leadingIcon;
} else {
const LeadingIcon = childArg.props.leadingIcon;
return /*#__PURE__*/jsx(LeadingIcon, {});
}
}
if (/*#__PURE__*/React.isValidElement(childArg) && childArg.type === SegmentedControlIconButton) {
if (isElement(childArg.props.icon)) ; else {
const Icon = childArg.props.icon;
return /*#__PURE__*/jsx(Icon, {});
}
}
return null;
}
function _temp5(childArg_0) {
if (/*#__PURE__*/React.isValidElement(childArg_0) && childArg_0.type === SegmentedControlButton) {
return childArg_0.props.children;
}
return /*#__PURE__*/React.isValidElement(childArg_0) ? childArg_0.props["aria-label"] : null;
}
export { SegmentedControl };