ariakit-react-utils
Version:
Ariakit React utils
122 lines (115 loc) • 2.83 kB
JavaScript
;
var React = require('react');
var misc = require('ariakit-utils/misc');
var jsxRuntime = require('react/jsx-runtime');
function isRenderProp(children) {
return typeof children === "function";
}
/**
* Creates a type-safe component with the `as` prop and `React.forwardRef`.
*
* @example
* import { createComponent } from "ariakit-react-utils/system";
*
* type Props = {
* as?: "div";
* customProp?: boolean;
* };
*
* const Component = createComponent<Props>(({ customProp, ...props }) => {
* return <div {...props} />;
* });
*
* <Component as="button" customProp />
*/
function createComponent(render) {
const Role = (props, ref) => render({
ref,
...props
});
return /*#__PURE__*/React.forwardRef(Role);
}
/**
* Creates a React element that supports the `as` prop, children as a
* function (render props) and a `wrapElement` function.
*
* @example
* import { createElement } from "ariakit-react-utils/system";
*
* function Component() {
* const props = {
* as: "button" as const,
* children: (htmlProps) => <button {...htmlProps} />,
* wrapElement: (element) => <div>{element}</div>,
* };
* return createElement("div", props);
* }
*/
function createElement(Type, props) {
const {
as: As,
wrapElement,
...rest
} = props;
let element;
if (As && typeof As !== "string") {
element = /*#__PURE__*/jsxRuntime.jsx(As, {
...rest
});
} else if (isRenderProp(props.children)) {
const {
children,
...otherProps
} = rest;
element = props.children(otherProps);
} else if (As) {
element = /*#__PURE__*/jsxRuntime.jsx(As, {
...rest
});
} else {
element = /*#__PURE__*/jsxRuntime.jsx(Type, {
...rest
});
}
if (wrapElement) {
return wrapElement(element);
}
return element;
}
/**
* Creates a component hook that accepts props and returns props so they can be
* passed to a React element.
*
* @example
* import { Options, createHook } from "ariakit-react-utils/system";
*
* type Props = Options<"div"> & {
* customProp?: boolean;
* };
*
* const useComponent = createHook<Props>(({ customProp, ...props }) => {
* return props;
* });
*
* const props = useComponent({ as: "button", customProp: true });
*/
function createHook(useProps) {
const useRole = function (props) {
if (props === void 0) {
props = {};
}
const htmlProps = useProps(props);
const copy = {};
for (const prop in htmlProps) {
if (misc.hasOwnProperty(htmlProps, prop) && htmlProps[prop] !== undefined) {
// @ts-expect-error
copy[prop] = htmlProps[prop];
}
}
return copy;
};
return useRole;
}
exports.createComponent = createComponent;
exports.createElement = createElement;
exports.createHook = createHook;