@primer/react
Version:
An implementation of GitHub's Primer Design System using React
75 lines (72 loc) • 2.69 kB
JavaScript
import React, { forwardRef, useRef, useContext } from 'react';
import { UnderlineNavContext } from './UnderlineNavContext.js';
import useIsomorphicLayoutEffect from '../utils/useIsomorphicLayoutEffect.js';
import { UnderlineItem } from '../internal/components/UnderlineTabbedInterface.js';
import classes from './UnderlineNavItem.module.css.js';
import { jsx } from 'react/jsx-runtime';
const UnderlineNavItem = /*#__PURE__*/forwardRef(({
as: Component = 'a',
href = '#',
children,
counter,
onSelect,
'aria-current': ariaCurrent,
icon: Icon,
leadingVisual,
...props
}, forwardedRef) => {
const backupRef = useRef(null);
const ref = forwardedRef !== null && forwardedRef !== void 0 ? forwardedRef : backupRef;
const {
setChildrenWidth,
setNoIconChildrenWidth,
loadingCounters,
iconsVisible
} = useContext(UnderlineNavContext);
useIsomorphicLayoutEffect(() => {
if (ref.current) {
const domRect = ref.current.getBoundingClientRect();
const icon = Array.from(ref.current.children).find(child => child.getAttribute('data-component') === 'icon');
const content = Array.from(ref.current.children).find(child => child.getAttribute('data-component') === 'text');
const text = content.textContent;
const iconWidthWithMargin = icon ? icon.getBoundingClientRect().width + Number(getComputedStyle(icon).marginRight.slice(0, -2)) + Number(getComputedStyle(icon).marginLeft.slice(0, -2)) : 0;
setChildrenWidth({
text,
width: domRect.width
});
setNoIconChildrenWidth({
text,
width: domRect.width - iconWidthWithMargin
});
}
}, [ref, setChildrenWidth, setNoIconChildrenWidth]);
const keyDownHandler = React.useCallback(event => {
if ((event.key === ' ' || event.key === 'Enter') && !event.defaultPrevented && typeof onSelect === 'function') {
onSelect(event);
}
}, [onSelect]);
const clickHandler = React.useCallback(event => {
if (!event.defaultPrevented && typeof onSelect === 'function') {
onSelect(event);
}
}, [onSelect]);
return /*#__PURE__*/jsx("li", {
className: classes.UnderlineNavItem,
children: /*#__PURE__*/jsx(UnderlineItem, {
ref: ref,
as: Component,
href: href,
"aria-current": ariaCurrent,
onKeyDown: keyDownHandler,
onClick: clickHandler,
counter: counter,
icon: leadingVisual !== null && leadingVisual !== void 0 ? leadingVisual : Icon,
loadingCounters: loadingCounters,
iconsVisible: iconsVisible,
...props,
children: children
})
});
});
UnderlineNavItem.displayName = 'UnderlineNavItem';
export { UnderlineNavItem };