react-box-overflow
Version:
Headless UI for automatically collapsing boxes when overflow in React.
98 lines (97 loc) • 3.59 kB
JavaScript
import React, { isValidElement, cloneElement, useContext, createElement, useMemo } from "react";
import { useOverflow } from "./useOverflow.js";
import { capitalizeFirstLetter } from "./utils.js";
const BoxOverflowContext = React.createContext({});
const fixedDisplayNameMap = {
rest: "BoxOverflowRest",
prefix: "BoxOverflowPrefix",
suffix: "BoxOverflowSuffix"
};
function genFixComponent(type) {
const Comp = (props) => {
var _a;
const { component = "div", ...restProps } = props;
const instance = useContext(BoxOverflowContext);
const idKey = (_a = instance.options) == null ? void 0 : _a.idAttribute;
return createElement(component, { ...restProps, [idKey]: type });
};
Comp.displayName = `BoxOverflow${capitalizeFirstLetter(type)}`;
return Comp;
}
const BoxOverflowItem = (props) => {
var _a;
const { component = "div", id: _id, ...restProps } = props;
const instance = useContext(BoxOverflowContext);
const idKey = (_a = instance.options) == null ? void 0 : _a.idAttribute;
const id = String(_id);
const style = {
...props.style,
...instance.getItemStyle(id)
};
return createElement(component, { ...restProps, [idKey]: id, style });
};
BoxOverflowItem.displayName = "BoxOverflowItem";
const BoxOverflowRest = (props) => {
var _a;
const { component = "div", children: _children, ...restProps } = props;
const instance = useContext(BoxOverflowContext);
const idKey = (_a = instance.options) == null ? void 0 : _a.idAttribute;
const style = instance.getRestStyle();
const rests = instance.getRests();
const children = useMemo(() => {
if (typeof _children === "function")
return _children(rests);
return _children;
}, [_children, rests]);
return createElement(component, { ...restProps, ...props, [idKey]: "rest", children, style: { ...props.style, ...style } });
};
BoxOverflowRest.displayName = "BoxOverflowRest";
function BoxOverflow(props) {
const { component, children, className, style, ...restProps } = props;
const containerRef = React.useRef(null);
const keyList = [];
const _children = [];
const fixItems = {};
React.Children.forEach(children, (child, index) => {
var _a;
if (isValidElement(child)) {
const displayName = child.type.displayName;
if (displayName === "BoxOverflowItem") {
const id = child.props.id ?? child.key ?? index;
const idStr = String(id);
_children.push(cloneElement(child, { key: idStr, id: idStr, ...child.props }));
keyList.push(idStr);
}
const type = (_a = Object.entries(fixedDisplayNameMap).find(([_, value]) => value === displayName)) == null ? void 0 : _a[0];
if (type)
fixItems[type] = cloneElement(child, { key: type });
}
});
const instance = useOverflow({
getIdByIndex: (index) => {
return keyList[index];
},
...restProps,
getContainer: () => containerRef.current
});
const _style = {
...instance.getContainerStyle(),
...style
};
const _component = component || "div";
return /* @__PURE__ */ React.createElement(BoxOverflowContext.Provider, { value: instance }, React.createElement(_component, {
children: [fixItems.prefix, ..._children, fixItems.rest, fixItems.suffix],
ref: containerRef,
className,
style: _style
}));
}
BoxOverflow.displayName = "BoxOverflow";
BoxOverflow.Rest = BoxOverflowRest;
BoxOverflow.Item = BoxOverflowItem;
BoxOverflow.Suffix = genFixComponent("suffix");
BoxOverflow.Prefix = genFixComponent("prefix");
export {
BoxOverflow
};
//# sourceMappingURL=BoxOverflow.js.map