Files
v10/dist/default/utils/use-render.js

73 lines
2.5 KiB
JavaScript

"use client";
import { composeRefs } from "./use-composed-refs.js";
import { mergeProps } from "./merge-props.js";
import { getStateDataAttrs } from "@videojs/core/dom";
import { cloneElement, createElement, isValidElement } from "react";
import { isFunction } from "@videojs/utils/predicate";
//#region src/utils/use-render.tsx
/** Check if a value is a render prop (function or React element). */
function isRenderProp(value) {
return isFunction(value) || isValidElement(value);
}
function resolveClassName(className, state) {
return isFunction(className) ? className(state) : className;
}
function resolveStyle(style, state) {
return isFunction(style) ? style(state) : style;
}
function getElementRef(element) {
const elementAny = element;
return elementAny.ref ?? elementAny.props?.ref;
}
/**
* Render a UI component element.
*
* Handles:
* - Default tag rendering
* - Render prop (element or function)
* - Props merging (event handlers chained, className concatenated, style merged)
* - Ref composition
* - className/style as functions of state
*
* @public
* @example
* ```tsx
* return renderElement('button', componentProps, {
* state,
* ref: [forwardedRef, buttonRef],
* props: [{ type: 'button' }, elementProps, getButtonProps],
* });
* ```
*/
function renderElement(element, componentProps, params) {
const { className: classNameProp, style: styleProp, render } = componentProps;
const { state, ref, props, stateAttrMap } = params;
const className = resolveClassName(classNameProp, state);
const style = resolveStyle(styleProp, state);
const mergedProps = mergeProps(stateAttrMap ? getStateDataAttrs(state, stateAttrMap) : {}, ...Array.isArray(props) ? props : props ? [props] : []);
if (className !== void 0) mergedProps.className = mergedProps.className ? `${mergedProps.className} ${className}` : className;
if (style !== void 0) mergedProps.style = mergedProps.style ? {
...mergedProps.style,
...style
} : style;
if (isFunction(render)) {
const mergedRef = composeRefs(ref, mergedProps.ref);
return render({
...mergedProps,
ref: mergedRef
}, state);
}
if (isValidElement(render)) {
const elementRef = getElementRef(render);
const mergedRef = composeRefs(ref, mergedProps.ref, elementRef);
const elementProps = mergeProps(mergedProps, render.props);
elementProps.ref = mergedRef;
return cloneElement(render, elementProps);
}
mergedProps.ref = composeRefs(ref, mergedProps.ref);
return createElement(element, mergedProps);
}
//#endregion
export { isRenderProp, renderElement };
//# sourceMappingURL=use-render.js.map