Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions packages/react/src/components/alert-dialog/alert-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
Pressable as PressablePrimitive,
} from "react-aria-components/Modal";

import {enableChildProps, forwardChildProps} from "../../utils/children";
import {composeSlotClassName, composeTwRenderProps} from "../../utils/compose";
import {dom} from "../../utils/dom";
import {CloseButton} from "../close-button";
Expand All @@ -43,7 +44,8 @@ const AlertDialogContext = createContext<AlertDialogContext>({});
* -----------------------------------------------------------------------------------------------*/
interface AlertDialogRootProps extends ComponentPropsWithRef<typeof AlertDialogTriggerPrimitive> {}

const AlertDialogRoot = ({children, ...props}: AlertDialogRootProps) => {
const AlertDialogRoot = enableChildProps((inputProps: AlertDialogRootProps) => {
const {children, ...props} = forwardChildProps(inputProps);
const alertDialogContext = useMemo<AlertDialogContext>(
() => ({slots: alertDialogVariants(), placement: undefined}),
[],
Expand All @@ -56,7 +58,7 @@ const AlertDialogRoot = ({children, ...props}: AlertDialogRootProps) => {
</AlertDialogTriggerPrimitive>
</AlertDialogContext>
);
};
});

/* -------------------------------------------------------------------------------------------------
* AlertDialog Trigger
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {Chip} from "../chip";
import {Description} from "../description";
import {Dropdown} from "../dropdown";
import {Label} from "../label";
import {Tooltip} from "../tooltip";

import {ButtonGroup} from "./";

Expand Down Expand Up @@ -298,6 +299,21 @@ export const WithoutSeparator: Story = {
),
};

export const WithTooltips: Story = {
render: () => (
<ButtonGroup size="sm" variant="secondary">
<Tooltip>
<Button>First</Button>
<Tooltip.Content>First action</Tooltip.Content>
</Tooltip>
<Tooltip>
<Button>Second</Button>
<Tooltip.Content>Second action</Tooltip.Content>
</Tooltip>
</ButtonGroup>
),
};

export const Examples: Story = {
render: () => (
<div className="flex flex-col items-start gap-8">
Expand Down
10 changes: 5 additions & 5 deletions packages/react/src/components/button-group/button-group.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {useSlottedContext} from "react-aria-components/slots";
import {ToggleButtonGroupContext as RACToggleButtonGroupContext} from "react-aria-components/ToggleButtonGroup";

import {composeSlotClassName, composeTwRenderProps} from "../../utils";
import {supportsChildProps, withChildProps} from "../../utils/children";
import {dom} from "../../utils/dom";

/* -------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -60,16 +61,15 @@ const ButtonGroupRoot = ({
[fullWidth, orientation],
);

// Wrap only direct children with context provider
// Mark only direct children that can consume or forward the group marker.
const wrappedChildren = Children.map(children as React.ReactNode, (child) => {
if (!isValidElement(child)) {
if (!isValidElement(child) || !supportsChildProps(child)) {
return child;
}

// Clone the child and add the special prop
return React.cloneElement(child, {
return withChildProps(child, {
[BUTTON_GROUP_CHILD]: true,
} as any);
});
});

return (
Expand Down
30 changes: 16 additions & 14 deletions packages/react/src/components/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {use} from "react";
import {Button as ButtonPrimitive} from "react-aria-components/Button";

import {composeTwRenderProps} from "../../utils";
import {enableChildProps, mergeChildProps} from "../../utils/children";
import {BUTTON_GROUP_CHILD, ButtonGroupContext} from "../button-group";

/* -------------------------------------------------------------------------------------------------
Expand All @@ -17,19 +18,20 @@ interface ButtonRootProps extends ComponentPropsWithRef<typeof ButtonPrimitive>,
[BUTTON_GROUP_CHILD]?: boolean;
}

const ButtonRoot = ({
children,
className,
fullWidth,
isDisabled,
isIconOnly,
size,
slot,
style,
variant,
[BUTTON_GROUP_CHILD]: isButtonGroupChild,
...rest
}: ButtonRootProps) => {
const ButtonRoot = enableChildProps((inputProps: ButtonRootProps) => {
const {
children,
className,
fullWidth,
isDisabled,
isIconOnly,
size,
slot,
style,
variant,
[BUTTON_GROUP_CHILD]: isButtonGroupChild,
...rest
} = mergeChildProps(inputProps);
const buttonGroupContext = use(ButtonGroupContext);

// Only use context if this button is a direct child of ButtonGroup
Expand Down Expand Up @@ -62,7 +64,7 @@ const ButtonRoot = ({
{(renderProps) => (typeof children === "function" ? children(renderProps) : children)}
</ButtonPrimitive>
);
};
});

/* -------------------------------------------------------------------------------------------------
* Exports
Expand Down
10 changes: 6 additions & 4 deletions packages/react/src/components/drawer/drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
Modal as ModalPrimitive,
} from "react-aria-components/Modal";

import {enableChildProps, forwardChildProps} from "../../utils/children";
import {composeSlotClassName, composeTwRenderProps} from "../../utils/compose";
import {dom} from "../../utils/dom";
import {CloseButton} from "../close-button";
Expand Down Expand Up @@ -219,7 +220,8 @@ interface DrawerRootProps extends ComponentPropsWithRef<typeof DrawerTriggerPrim
state?: UseOverlayStateReturn;
}

const DrawerRoot = ({children, state, ...props}: DrawerRootProps) => {
const DrawerRoot = enableChildProps(({children, state, ...props}: DrawerRootProps) => {
const {children: forwardedChildren, ...rootProps} = forwardChildProps({children, ...props});
const drawerContext = useMemo<DrawerContext>(
() => ({slots: drawerVariants(), placement: undefined, isDismissable: true}),
[],
Expand All @@ -232,12 +234,12 @@ const DrawerRoot = ({children, state, ...props}: DrawerRootProps) => {

return (
<DrawerContext value={drawerContext}>
<DrawerTriggerPrimitive data-slot="drawer-root" {...mergeProps(props, controlledProps)}>
{children}
<DrawerTriggerPrimitive data-slot="drawer-root" {...mergeProps(rootProps, controlledProps)}>
{forwardedChildren}
</DrawerTriggerPrimitive>
</DrawerContext>
);
};
});

DrawerRoot.displayName = "HeroUI.Drawer";

Expand Down
6 changes: 4 additions & 2 deletions packages/react/src/components/dropdown/dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
SubmenuTrigger as SubmenuTriggerPrimitive,
} from "react-aria-components/Menu";

import {enableChildProps, forwardChildProps} from "../../utils/children";
import {composeTwRenderProps} from "../../utils/compose";
import {MenuItemIndicator, MenuItemRoot, MenuItemSubmenuIndicator} from "../menu-item";
import {MenuSectionRoot} from "../menu-section";
Expand All @@ -36,15 +37,16 @@ interface DropdownRootProps
className?: string;
}

const DropdownRoot = ({children, ...props}: DropdownRootProps) => {
const DropdownRoot = enableChildProps((inputProps: DropdownRootProps) => {
const {children, ...props} = forwardChildProps(inputProps);
const slots = React.useMemo(() => dropdownVariants(), []);

return (
<DropdownContext value={{slots}}>
<MenuTriggerPrimitive {...props}>{children}</MenuTriggerPrimitive>
</DropdownContext>
);
};
});

/* -------------------------------------------------------------------------------------------------
* Dropdown Trigger (Button wrapper)
Expand Down
10 changes: 6 additions & 4 deletions packages/react/src/components/modal/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
Pressable as PressablePrimitive,
} from "react-aria-components/Modal";

import {enableChildProps, forwardChildProps} from "../../utils/children";
import {composeSlotClassName, composeTwRenderProps} from "../../utils/compose";
import {dom} from "../../utils/dom";
import {CloseButton} from "../close-button";
Expand All @@ -46,7 +47,8 @@ interface ModalRootProps extends ComponentPropsWithRef<typeof ModalTriggerPrimit
state?: UseOverlayStateReturn;
}

const ModalRoot = ({children, state, ...props}: ModalRootProps) => {
const ModalRoot = enableChildProps(({children, state, ...props}: ModalRootProps) => {
const {children: forwardedChildren, ...rootProps} = forwardChildProps({children, ...props});
const modalContext = useMemo<ModalContext>(
() => ({slots: modalVariants(), placement: undefined}),
[],
Expand All @@ -59,12 +61,12 @@ const ModalRoot = ({children, state, ...props}: ModalRootProps) => {

return (
<ModalContext value={modalContext}>
<ModalTriggerPrimitive data-slot="modal-root" {...mergeProps(props, controlledProps)}>
{children}
<ModalTriggerPrimitive data-slot="modal-root" {...mergeProps(rootProps, controlledProps)}>
{forwardedChildren}
</ModalTriggerPrimitive>
</ModalContext>
);
};
});

/* -------------------------------------------------------------------------------------------------
* Modal Trigger
Expand Down
9 changes: 4 additions & 5 deletions packages/react/src/components/popover/popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
Pressable as PressablePrimitive,
} from "react-aria-components/Popover";

import {enableChildProps, forwardChildProps} from "../../utils/children";
import {composeSlotClassName, composeTwRenderProps} from "../../utils/compose";
import {dom} from "../../utils/dom";
import {SurfaceContext} from "../surface";
Expand All @@ -36,10 +37,8 @@ const PopoverContext = createContext<PopoverContext>({});
* -----------------------------------------------------------------------------------------------*/
type PopoverRootProps = ComponentPropsWithRef<typeof PopoverTriggerPrimitive>;

const PopoverRoot = ({
children,
...props
}: ComponentPropsWithRef<typeof PopoverTriggerPrimitive>) => {
const PopoverRoot = enableChildProps((inputProps: PopoverRootProps) => {
const {children, ...props} = forwardChildProps(inputProps);
const slots = React.useMemo(() => popoverVariants(), []);

return (
Expand All @@ -49,7 +48,7 @@ const PopoverRoot = ({
</PopoverTriggerPrimitive>
</PopoverContext>
);
};
});

/* -------------------------------------------------------------------------------------------------
* Popover Content
Expand Down
11 changes: 4 additions & 7 deletions packages/react/src/components/tooltip/tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
} from "react-aria-components/Tooltip";

import {useCSSVariable} from "../../hooks/use-css-variable";
import {enableChildProps, forwardChildProps} from "../../utils/children";
import {composeSlotClassName, composeTwRenderProps} from "../../utils/compose";
import {parseCSSTime} from "../../utils/css";
import {dom} from "../../utils/dom";
Expand All @@ -33,12 +34,8 @@ const TooltipContext = createContext<TooltipContext>({});
* -----------------------------------------------------------------------------------------------*/
type TooltipRootProps = ComponentPropsWithRef<typeof TooltipTriggerPrimitive>;

const TooltipRoot = ({
children,
closeDelay,
delay,
...props
}: ComponentPropsWithRef<typeof TooltipTriggerPrimitive>) => {
const TooltipRoot = enableChildProps((inputProps: TooltipRootProps) => {
const {children, closeDelay, delay, ...props} = forwardChildProps(inputProps);
const slots = React.useMemo(() => tooltipVariants(), []);

const cssDelay = useCSSVariable("--tooltip-delay");
Expand All @@ -59,7 +56,7 @@ const TooltipRoot = ({
</TooltipTriggerPrimitive>
</TooltipContext>
);
};
});

/* -------------------------------------------------------------------------------------------------
* Tooltip Content
Expand Down
Loading
Loading