UNPKG

@navinc/base-react-components

Version:
72 lines (71 loc) 3.46 kB
var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import { jsx as _jsx } from "react/jsx-runtime"; /* Code copied and modified from https://github.com/radix-ui/primitives/issues/1825#issuecomment-1577723288 This is not a solid API and subject to change if a maintained implementation is found, so let's keep it internal. Not using radix-ui's Slot primitive as it does not support nested Slottables. */ import { composeRefs } from '@radix-ui/react-compose-refs'; import { forwardRef, Children, cloneElement, isValidElement, } from 'react'; function mergeProps(slotProps, childProps) { // all child props should override const overrideProps = Object.assign({}, childProps); for (const propName in childProps) { const slotPropValue = slotProps[propName]; const childPropValue = childProps[propName]; const isHandler = /^on[A-Z]/.test(propName); if (isHandler) { // if the handler exists on both, we compose them if (slotPropValue && childPropValue) { overrideProps[propName] = (...args) => { childPropValue(...args); slotPropValue(...args); }; } // but if it exists only on the slot, we use only this one else if (slotPropValue) { overrideProps[propName] = slotPropValue; } } // if it's `style`, we merge them else if (propName === 'style') { overrideProps[propName] = Object.assign(Object.assign({}, slotPropValue), childPropValue); } else if (propName === 'className') { overrideProps[propName] = [slotPropValue, childPropValue].filter(Boolean).join(' '); } } return Object.assign(Object.assign({}, slotProps), overrideProps); } const SlotClone = forwardRef((props, forwardedRef) => { const { children } = props, slotProps = __rest(props, ["children"]); if (isValidElement(children)) { return cloneElement(children, Object.assign(Object.assign({}, mergeProps(slotProps, children.props)), { ['ref']: forwardedRef ? composeRefs(forwardedRef, children.ref) : children.ref })); } return Children.count(children) > 1 ? Children.only(null) : null; }); SlotClone.displayName = 'SlotClone'; const Slot = forwardRef((props, forwardedRef) => { const { asChild, child, children, defaultComponent } = props, slotProps = __rest(props, ["asChild", "child", "children", "defaultComponent"]); const Component = asChild ? SlotClone : defaultComponent; /* eslint-disable no-nested-ternary -- copied code */ return (_jsx(Component, Object.assign({}, slotProps, { ref: forwardedRef, children: asChild ? isValidElement(child) ? cloneElement(child, undefined, children(child.props.children)) : null : children(child) }))); /* eslint-enable no-nested-ternary -- copied code */ }); Slot.displayName = 'Slot'; export { Slot }; //# sourceMappingURL=slot.js.map