diff --git a/.changeset/proud-terms-help.md b/.changeset/proud-terms-help.md
new file mode 100644
index 0000000000..497dc7d9f6
--- /dev/null
+++ b/.changeset/proud-terms-help.md
@@ -0,0 +1,5 @@
+---
+"@heroui/system-rsc": patch
+---
+
+override with slots (#5785)
diff --git a/packages/core/system-rsc/__tests__/extend-variants.test.tsx b/packages/core/system-rsc/__tests__/extend-variants.test.tsx
index 7b139f418c..30f80cfb61 100644
--- a/packages/core/system-rsc/__tests__/extend-variants.test.tsx
+++ b/packages/core/system-rsc/__tests__/extend-variants.test.tsx
@@ -253,4 +253,75 @@ describe("extendVariants function - with slots", () => {
expect(baseEl).toHaveClass("shadow-xs");
expect(headerEl).toHaveClass("rounded-none");
});
+
+ test("should override base component slots with direct slots option", () => {
+ const Card2 = extendVariants(Card, {
+ slots: {
+ header: "!font-bold !text-lg",
+ footer: "!bg-red-500",
+ },
+ });
+
+ const {getByTestId} = render(Card Content);
+
+ const headerEl = getByTestId("header");
+ const footerEl = getByTestId("footer");
+
+ expect(headerEl).toHaveClass("!font-bold");
+ expect(headerEl).toHaveClass("!text-lg");
+ expect(footerEl).toHaveClass("!bg-red-500");
+ });
+
+ test("should merge direct slots with variant-based slots", () => {
+ const Card2 = extendVariants(Card, {
+ slots: {
+ header: "!font-bold",
+ },
+ variants: {
+ shadow: {
+ xl: {
+ base: "shadow-xl",
+ },
+ },
+ },
+ defaultVariants: {
+ shadow: "xl",
+ },
+ });
+
+ const {getByTestId} = render(Card Content);
+
+ const baseEl = getByTestId("base");
+ const headerEl = getByTestId("header");
+
+ expect(baseEl).toHaveClass("shadow-xl");
+ expect(headerEl).toHaveClass("!font-bold");
+ });
+
+ test("direct slots should override variant-based slots for the same slot", () => {
+ const Card2 = extendVariants(Card, {
+ slots: {
+ base: "!bg-blue-500",
+ },
+ variants: {
+ shadow: {
+ xl: {
+ base: "shadow-xl",
+ },
+ },
+ },
+ defaultVariants: {
+ shadow: "xl",
+ },
+ });
+
+ const {getByTestId} = render(Card Content);
+
+ const baseEl = getByTestId("base");
+
+ // Direct slots should be applied
+ expect(baseEl).toHaveClass("!bg-blue-500");
+ // Variant-based slots should also be applied (they merge)
+ expect(baseEl).toHaveClass("shadow-xl");
+ });
});
diff --git a/packages/core/system-rsc/src/extend-variants.js b/packages/core/system-rsc/src/extend-variants.js
index 5bd43f14d8..3a1561853e 100644
--- a/packages/core/system-rsc/src/extend-variants.js
+++ b/packages/core/system-rsc/src/extend-variants.js
@@ -101,9 +101,12 @@ function getClassNamesWithProps({
}
export function extendVariants(BaseComponent, styles = {}, opts = {}) {
- const {variants, defaultVariants, compoundVariants} = styles || {};
+ const {variants, defaultVariants, compoundVariants, slots: directSlots} = styles || {};
+
+ const inferredSlots = getSlots(variants);
+
+ const slots = directSlots ? {...inferredSlots, ...directSlots} : inferredSlots;
- const slots = getSlots(variants);
const hasSlots = typeof slots === "object" && Object.keys(slots).length !== 0;
const ForwardedComponent = React.forwardRef((originalProps = {}, ref) => {