Skip to content

Commit

Permalink
refactor: button & card ripple (#4284)
Browse files Browse the repository at this point in the history
* chore: update use-button.ts

* chore: update use-ripple.ts

* chore: update use-card.ts

* chore: add changeset
  • Loading branch information
sudongyuer authored Dec 10, 2024
1 parent aa5ea19 commit dfefdd6
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 25 deletions.
7 changes: 7 additions & 0 deletions .changeset/rude-cobras-grab.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@nextui-org/button": patch
"@nextui-org/ripple": patch
"@nextui-org/card": patch
---

Refactor Button & Card Ripple
16 changes: 8 additions & 8 deletions packages/components/button/src/use-button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {useDOMRef, filterDOMProps} from "@nextui-org/react-utils";
import {button} from "@nextui-org/theme";
import {isValidElement, cloneElement, useMemo} from "react";
import {useAriaButton} from "@nextui-org/use-aria-button";
import {useHover} from "@react-aria/interactions";
import {PressEvent, useHover} from "@react-aria/interactions";
import {SpinnerProps} from "@nextui-org/spinner";
import {useRipple} from "@nextui-org/ripple";

Expand Down Expand Up @@ -135,22 +135,22 @@ export function useButton(props: UseButtonProps) {
],
);

const {onClick: onRippleClickHandler, onClear: onClearRipple, ripples} = useRipple();
const {onPress: onRipplePressHandler, onClear: onClearRipple, ripples} = useRipple();

const handleClick = useCallback(
(e: React.MouseEvent<HTMLButtonElement>) => {
const handlePress = useCallback(
(e: PressEvent) => {
if (disableRipple || isDisabled || disableAnimation) return;
domRef.current && onRippleClickHandler(e);
domRef.current && onRipplePressHandler(e);
},
[disableRipple, isDisabled, disableAnimation, domRef, onRippleClickHandler],
[disableRipple, isDisabled, disableAnimation, domRef, onRipplePressHandler],
);

const {buttonProps: ariaButtonProps, isPressed} = useAriaButton(
{
elementType: as,
isDisabled,
onPress,
onClick: chain(onClick, handleClick),
onPress: chain(onPress, handlePress),
onClick: onClick,
...otherProps,
} as AriaButtonProps,
domRef,
Expand Down
24 changes: 13 additions & 11 deletions packages/components/card/src/use-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import type {AriaButtonProps} from "@nextui-org/use-aria-button";
import type {RippleProps} from "@nextui-org/ripple";

import {card} from "@nextui-org/theme";
import {MouseEvent, ReactNode, useCallback, useMemo} from "react";
import {ReactNode, useCallback, useMemo} from "react";
import {chain, mergeProps} from "@react-aria/utils";
import {useFocusRing} from "@react-aria/focus";
import {useHover} from "@react-aria/interactions";
import {PressEvent, useHover} from "@react-aria/interactions";
import {useAriaButton} from "@nextui-org/use-aria-button";
import {
HTMLNextUIProps,
Expand Down Expand Up @@ -96,20 +96,22 @@ export function useCard(originalProps: UseCardProps) {

const baseStyles = clsx(classNames?.base, className);

const {onClick: onRippleClickHandler, onClear: onClearRipple, ripples} = useRipple();
const {onClear: onClearRipple, onPress: onRipplePressHandler, ripples} = useRipple();

const handleClick = (e: MouseEvent<HTMLDivElement>) => {
if (!disableAnimation && !disableRipple && domRef.current) {
onRippleClickHandler(e);
}
};
const handlePress = useCallback(
(e: PressEvent) => {
if (disableRipple || disableAnimation) return;
domRef.current && onRipplePressHandler(e);
},
[disableRipple, disableAnimation, domRef, onRipplePressHandler],
);

const {buttonProps, isPressed} = useAriaButton(
{
onPress,
onPress: chain(onPress, handlePress),
elementType: as,
isDisabled: !originalProps.isPressable,
onClick: chain(onClick, handleClick),
onClick: onClick,
allowTextSelectionOnPress,
...otherProps,
} as unknown as AriaButtonProps<"button">,
Expand Down Expand Up @@ -209,7 +211,7 @@ export function useCard(originalProps: UseCardProps) {
isPressable: originalProps.isPressable,
isHoverable: originalProps.isHoverable,
disableRipple,
handleClick,
handlePress,
isFocusVisible,
getCardProps,
getRippleProps,
Expand Down
12 changes: 6 additions & 6 deletions packages/components/ripple/src/use-ripple.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {getUniqueID} from "@nextui-org/shared-utils";
import React, {useCallback, useState} from "react";
import {PressEvent} from "@react-types/shared";

export type RippleType = {
key: React.Key;
Expand All @@ -13,19 +14,18 @@ export interface UseRippleProps {}
export function useRipple(props: UseRippleProps = {}) {
const [ripples, setRipples] = useState<RippleType[]>([]);

const onClick = useCallback((event: React.MouseEvent<HTMLElement, MouseEvent>) => {
const trigger = event.currentTarget;
const onPress = useCallback((event: PressEvent) => {
const trigger = event.target;

const size = Math.max(trigger.clientWidth, trigger.clientHeight);
const rect = trigger.getBoundingClientRect();

setRipples((prevRipples) => [
...prevRipples,
{
key: getUniqueID(prevRipples.length.toString()),
size,
x: event.clientX - rect.left - size / 2,
y: event.clientY - rect.top - size / 2,
x: event.x - size / 2,
y: event.y - size / 2,
},
]);
}, []);
Expand All @@ -34,7 +34,7 @@ export function useRipple(props: UseRippleProps = {}) {
setRipples((prevState) => prevState.filter((ripple) => ripple.key !== key));
}, []);

return {ripples, onClick, onClear, ...props};
return {ripples, onClear, onPress, ...props};
}

export type UseRippleReturn = ReturnType<typeof useRipple>;

0 comments on commit dfefdd6

Please sign in to comment.