UNPKG

2.79 kBJavaScriptView Raw
1'use client';
2
3import useForkRef from '@mui/utils/useForkRef';
4import appendOwnerState from '@mui/utils/appendOwnerState';
5import resolveComponentProps from '@mui/utils/resolveComponentProps';
6import mergeSlotProps from '@mui/utils/mergeSlotProps';
7/**
8 * An internal function to create a Material UI slot.
9 *
10 * This is an advanced version of Base UI `useSlotProps` because Material UI allows leaf component to be customized via `component` prop
11 * while Base UI does not need to support leaf component customization.
12 *
13 * @param {string} name: name of the slot
14 * @param {object} parameters
15 * @returns {[Slot, slotProps]} The slot's React component and the slot's props
16 *
17 * Note: the returned slot's props
18 * - will never contain `component` prop.
19 * - might contain `as` prop.
20 */
21export default function useSlot(
22/**
23 * The slot's name. All Material UI components should have `root` slot.
24 *
25 * If the name is `root`, the logic behaves differently from other slots,
26 * e.g. the `externalForwardedProps` are spread to `root` slot but not other slots.
27 */
28name, parameters) {
29 const {
30 className,
31 elementType: initialElementType,
32 ownerState,
33 externalForwardedProps,
34 getSlotOwnerState,
35 internalForwardedProps,
36 ...useSlotPropsParams
37 } = parameters;
38 const {
39 component: rootComponent,
40 slots = {
41 [name]: undefined
42 },
43 slotProps = {
44 [name]: undefined
45 },
46 ...other
47 } = externalForwardedProps;
48 const elementType = slots[name] || initialElementType;
49
50 // `slotProps[name]` can be a callback that receives the component's ownerState.
51 // `resolvedComponentsProps` is always a plain object.
52 const resolvedComponentsProps = resolveComponentProps(slotProps[name], ownerState);
53 const {
54 props: {
55 component: slotComponent,
56 ...mergedProps
57 },
58 internalRef
59 } = mergeSlotProps({
60 className,
61 ...useSlotPropsParams,
62 externalForwardedProps: name === 'root' ? other : undefined,
63 externalSlotProps: resolvedComponentsProps
64 });
65 const ref = useForkRef(internalRef, resolvedComponentsProps?.ref, parameters.ref);
66 const slotOwnerState = getSlotOwnerState ? getSlotOwnerState(mergedProps) : {};
67 const finalOwnerState = {
68 ...ownerState,
69 ...slotOwnerState
70 };
71 const LeafComponent = name === 'root' ? slotComponent || rootComponent : slotComponent;
72 const props = appendOwnerState(elementType, {
73 ...(name === 'root' && !rootComponent && !slots[name] && internalForwardedProps),
74 ...(name !== 'root' && !slots[name] && internalForwardedProps),
75 ...mergedProps,
76 ...(LeafComponent && {
77 as: LeafComponent
78 }),
79 ref
80 }, finalOwnerState);
81 Object.keys(slotOwnerState).forEach(propName => {
82 delete props[propName];
83 });
84 return [elementType, props];
85}
\No newline at end of file