Skip to content

Commit 17fab98

Browse files
committed
handle extra props
1 parent 9589579 commit 17fab98

File tree

3 files changed

+40
-5
lines changed

3 files changed

+40
-5
lines changed

.changeset/mighty-chefs-sneeze.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@zemd/react-slottable": patch
3+
---
4+
5+
handle extra props from useSlot options

src/use-slot.test.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,32 @@ describe("useSlot", () => {
8787

8888
expect(container.querySelector("[data-testid='option-div']")).toBeTruthy();
8989
});
90+
91+
test("should merge extraProps from third argument", () => {
92+
const CustomDiv = (props: React.HTMLProps<HTMLDivElement>) => (
93+
<div data-testid="extra-props-div" id="initial-id" {...props} />
94+
);
95+
96+
const props = { slotProps: { root: { id: "props-id" } } };
97+
98+
const { result } = renderHook(() =>
99+
useSlot("root", props, {
100+
slot: CustomDiv,
101+
id: "custom-id",
102+
"aria-label": "custom-label",
103+
}),
104+
);
105+
106+
const Component = result.current;
107+
const { container } = render(
108+
<Component id="default-id">Test Content</Component>,
109+
);
110+
const element = container.querySelector(
111+
"[data-testid='extra-props-div']",
112+
) as HTMLElement;
113+
114+
expect(element).toHaveAttribute("id", "custom-id");
115+
expect(element).toHaveAttribute("aria-label", "custom-label");
116+
expect(element).toHaveTextContent("Test Content");
117+
});
90118
});

src/use-slot.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ type SlotPropsProps<T extends Record<string, any>> = {
3232
*/
3333
export function useSlot<
3434
ArgSlotType extends ElementType,
35-
ArgSlotOptions extends SlotOptions<ArgSlotType>,
35+
ArgExtraProps extends Partial<ComponentProps<ArgSlotType>>,
36+
ArgSlotOptions extends SlotOptions<ArgSlotType> & ArgExtraProps,
3637
ReturnComponent extends ArgSlotOptions extends SlotOptions<infer T>
3738
? T
3839
: ElementType,
@@ -42,13 +43,13 @@ export function useSlot<
4243
props: Prettify<
4344
SlotsProps<ArgSlotsKeys> & SlotPropsProps<Record<keyof ArgSlotsKeys, any>> // & { [k: string]: any }
4445
>,
45-
options: ArgSlotOptions = {} as ArgSlotOptions,
46+
{ slot, ...extraProps }: ArgSlotOptions = {} as ArgSlotOptions,
4647
): ReturnComponent {
4748
const { slots, slotProps } = props;
4849

4950
const Slot = React.useMemo(() => {
50-
return (slots?.[name] ?? options.slot ?? SlotFragment) as ReturnComponent;
51-
}, [name, slots, options.slot]);
51+
return (slots?.[name] ?? slot ?? SlotFragment) as ReturnComponent;
52+
}, [name, slots, slot]);
5253

5354
return React.useMemo<ReturnComponent>(() => {
5455
const WrappedComponent: FC<ComponentProps<ReturnComponent>> = (
@@ -57,9 +58,10 @@ export function useSlot<
5758
const mergedProps: ComponentProps<ReturnComponent> = {
5859
...wrappedProps,
5960
...slotProps?.[name],
61+
...extraProps,
6062
};
6163
return <Slot {...mergedProps} />;
6264
};
6365
return WrappedComponent as ReturnComponent;
64-
}, [Slot, name, slotProps]);
66+
}, [Slot, name, slotProps, extraProps]);
6567
}

0 commit comments

Comments
 (0)