Skip to content

Commit

Permalink
Merge pull request #93 from bobbychan/fix/modal
Browse files Browse the repository at this point in the history
Fix/modal
  • Loading branch information
bobbychan committed Apr 24, 2024
2 parents 9253d9e + e841d69 commit 7f933ba
Show file tree
Hide file tree
Showing 14 changed files with 121 additions and 267 deletions.
6 changes: 6 additions & 0 deletions .changeset/warm-papayas-live.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@alice-ui/react": patch
"@alice-ui/theme": patch
---

remove framer motion
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ Requirements:

- [React 18](https://reactjs.org/) or later
- [Tailwind CSS 3](https://tailwindcss.com/) or later
- [Framer Motion 4](https://www.framer.com/motion/) or later

---

Expand All @@ -19,7 +18,7 @@ To use AliceUI in your project, you need to follow the following steps:
Run the following command:

```sh
pnpm add @alice-ui/react framer-motion
pnpm add @alice-ui/react
```

### Tailwind CSS Setup
Expand Down Expand Up @@ -80,4 +79,3 @@ After modifying the `.npmrc` file, you need to run `pnpm install` again to ensur
- [TailwindCSS](https://tailwindcss.com)
- [Tailwind Variants](https://www.tailwind-variants.org)
- [React Aria Components](https://react-spectrum.adobe.com/react-aria/index.html)
- [Framer Motion](https://www.framer.com/motion)
2 changes: 0 additions & 2 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
"postpack": "clean-package restore"
},
"peerDependencies": {
"framer-motion": ">=4.0.0",
"react": ">=18",
"react-dom": ">=18"
},
Expand All @@ -59,7 +58,6 @@
},
"devDependencies": {
"clean-package": "^2.2.0",
"framer-motion": "^11.1.2",
"rimraf": "^5.0.1"
},
"clean-package": "../../clean-package.config.json"
Expand Down
48 changes: 6 additions & 42 deletions packages/react/src/button/button.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,12 @@
import type { ButtonVariantProps } from '@alice-ui/theme';
import { button } from '@alice-ui/theme';
import {
ForwardedRef,
ReactNode,
cloneElement,
forwardRef,
isValidElement,
useCallback,
useMemo,
} from 'react';
import { ForwardedRef, ReactNode, cloneElement, forwardRef, isValidElement, useMemo } from 'react';
import type { ButtonProps as AriaButtonProps } from 'react-aria-components';
import { Button as AriaButton } from 'react-aria-components';
import { Ripple, useRipple } from '../ripple';
import type { SpinnerProps } from '../spinner';
import { Spinner } from '../spinner';

export interface ButtonProps extends AriaButtonProps, Omit<ButtonVariantProps, 'isInGroup'> {
/**
* Whether the button should display a ripple effect on press.
* @default false
*/
disableRipple?: boolean;
/**
* The button start content.
*/
Expand Down Expand Up @@ -63,22 +49,11 @@ function Button(props: ButtonProps, ref: ForwardedRef<HTMLButtonElement>) {
startContent: startContentProp,
endContent: endContentProp,
disableAnimation,
disableRipple,
className,
children,
...otherProps
} = props;

const { onClick: onRippleClickHandler, ripples } = useRipple();

const handleClick = useCallback(
(e: React.MouseEvent<HTMLDivElement>) => {
if (disableRipple || disableAnimation || isLoading) return;
onRippleClickHandler(e);
},
[disableRipple, disableAnimation, isLoading, onRippleClickHandler],
);

const styles = useMemo(
() =>
button({
Expand Down Expand Up @@ -106,23 +81,12 @@ function Button(props: ButtonProps, ref: ForwardedRef<HTMLButtonElement>) {
const endContent = getIconClone(endContentProp);

return (
// @ts-ignore
<AriaButton ref={ref} className={styles} {...otherProps}>
{({ isDisabled }) => (
<>
{startContent}
{isLoading && spinnerPlacement === 'start' && <div className="shrink-0">{spinner}</div>}
<>{children}</>
{isLoading && spinnerPlacement === 'end' && spinner}
{endContent}
{(!disableRipple || !isDisabled) && (
<>
<div aria-hidden className="absolute inset-0 h-full w-full" onClick={handleClick} />
<Ripple ripples={ripples} />
</>
)}
</>
)}
{startContent}
{isLoading && spinnerPlacement === 'start' && <div className="shrink-0">{spinner}</div>}
<>{children}</>
{isLoading && spinnerPlacement === 'end' && spinner}
{endContent}
</AriaButton>
);
}
Expand Down
29 changes: 1 addition & 28 deletions packages/react/src/card/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,20 @@ import {
ElementType,
ForwardedRef,
HTMLAttributes,
MouseEvent,
ReactNode,
createContext,
forwardRef,
useMemo,
} from 'react';
import { useButton, useFocusRing, useHover } from 'react-aria';
import { ContextValue, useContextProps } from 'react-aria-components';
import { Ripple, useRipple } from '../ripple';

export interface Props extends HTMLAttributes<HTMLButtonElement> {
elementType?: string;
/**
* Usually the Card parts, `CardHeader`, `CardBody` and `CardFooter`.
*/
children?: ReactNode | ReactNode[];
/**
* Whether the card should show a ripple animation on press, this prop is ignored if `disableAnimation` is true or `isPressable` is false.
* @default false
*/
disableRipple?: boolean;

/**
* Whether the card should allow text selection on press. (only for pressable cards)
* @default true
Expand Down Expand Up @@ -64,16 +56,7 @@ function Card(props: CardProps, ref: ForwardedRef<HTMLDivElement>) {
[props, ref] = useContextProps(props, ref, CardContext);
const ctx = props as CardContextValue;

const {
elementType,
children,
disableRipple = false,
autoFocus,
className,
classNames,
onPress,
...cardProps
} = props;
const { elementType, children, autoFocus, className, classNames, onPress, ...cardProps } = props;

const variantProps = filterVariantProps(props, card.variantKeys);

Expand All @@ -85,14 +68,6 @@ function Card(props: CardProps, ref: ForwardedRef<HTMLDivElement>) {

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

const { onClick: onRippleClickHandler, ripples } = useRipple();

const handleClick = (e: MouseEvent<HTMLDivElement>) => {
if (!props.disableAnimation && !disableRipple && props.isPressable) {
onRippleClickHandler(e);
}
};

const { buttonProps, isPressed } = useButton(
{
elementType: Component,
Expand Down Expand Up @@ -152,10 +127,8 @@ function Card(props: CardProps, ref: ForwardedRef<HTMLDivElement>) {
data-hovered={dataAttr(isHovered)}
data-focused={dataAttr(isFocused)}
data-focus-visible={dataAttr(isFocusVisible)}
onClick={handleClick}
>
<CardContext.Provider value={context}>{children}</CardContext.Provider>
{ctx.isPressable && !ctx.disableAnimation && !disableRipple && <Ripple ripples={ripples} />}
</Component>
);
}
Expand Down
66 changes: 12 additions & 54 deletions packages/react/src/drawer/drawer.tsx
Original file line number Diff line number Diff line change
@@ -1,79 +1,37 @@
import { clsx } from '@alice-ui/shared-utils';
import type { DrawerSlots, DrawerVariantProps, SlotsToClasses } from '@alice-ui/theme';
import { drawer } from '@alice-ui/theme';
import type { HTMLMotionProps } from 'framer-motion';
import { AnimatePresence, LazyMotion, domAnimation, m } from 'framer-motion';
import { ForwardedRef, forwardRef, useMemo } from 'react';
import type { ModalOverlayProps } from 'react-aria-components';
import { Modal as AriaModal, ModalOverlay } from 'react-aria-components';
import { InternalModalContext } from '../modal/modal';
import { fadeInOut, slideHorizontal, slideVertical } from './drawer-transition';

export interface DrawerProps extends ModalOverlayProps, DrawerVariantProps {
/**
* The props to modify the framer motion animation. Use the `variants` API to create your own animation.
*/
motionProps?: HTMLMotionProps<'section'>;
/**
* Classes object to style the modal and its children.
*/
classNames?: SlotsToClasses<DrawerSlots>;
}

// Wrap React Aria modal components so they support framer-motion values.
// const MotionModal = motion(AriaModal);
const MotionModalOverlay = m(ModalOverlay);

function Drawer(props: DrawerProps, ref: ForwardedRef<HTMLDivElement>) {
const {
children,
classNames,
className,
placement,
backdrop = 'opaque',
motionProps,
isOpen,
...otherProps
} = props;
const { children, classNames, className, placement, backdrop = 'opaque', ...otherProps } = props;

const slots = useMemo(() => drawer({ placement, backdrop }), [backdrop, placement]);

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

return (
<AnimatePresence>
{isOpen && (
<LazyMotion features={domAnimation}>
<MotionModalOverlay
isOpen
animate="enter"
exit="exit"
initial="exit"
variants={fadeInOut}
{...otherProps}
className={slots.backdrop({ class: classNames?.backdrop })}
>
<m.div
className={slots.base({ class: baseStyles })}
data-placement={placement}
animate="enter"
exit="exit"
initial="exit"
variants={
placement === 'top' || placement === 'bottom' ? slideVertical : slideHorizontal
}
{...motionProps}
>
<InternalModalContext.Provider value={{ slots, classNames }}>
<AriaModal ref={ref} style={{ height: '100%' }}>
{children}
</AriaModal>
</InternalModalContext.Provider>
</m.div>
</MotionModalOverlay>
</LazyMotion>
)}
</AnimatePresence>
<ModalOverlay {...otherProps} className={slots.backdrop({ class: classNames?.backdrop })}>
<InternalModalContext.Provider value={{ slots, classNames }}>
<AriaModal
ref={ref}
className={slots.base({ class: baseStyles })}
data-placement={placement}
>
{children}
</AriaModal>
</InternalModalContext.Provider>
</ModalOverlay>
);
}

Expand Down
53 changes: 9 additions & 44 deletions packages/react/src/modal/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,11 @@ import type {
SlotsToClasses,
} from '@alice-ui/theme';
import { modal } from '@alice-ui/theme';
import type { HTMLMotionProps } from 'framer-motion';
import { AnimatePresence, LazyMotion, domAnimation, m } from 'framer-motion';
import { ForwardedRef, createContext, forwardRef, useMemo } from 'react';
import type { ModalOverlayProps } from 'react-aria-components';
import { Modal as AriaModal, ModalOverlay } from 'react-aria-components';
import { fadeInOut, scaleInOut } from './modal-transition';

export interface ModalProps extends ModalOverlayProps, ModalVariantProps {
/**
* The props to modify the framer motion animation. Use the `variants` API to create your own animation.
*/
motionProps?: HTMLMotionProps<'section'>;
/**
* Classes object to style the modal and its children.
*/
Expand All @@ -35,10 +28,6 @@ export const InternalModalContext = createContext<InternalModalContextValue>(
{} as InternalModalContextValue,
);

// Wrap React Aria modal components so they support framer-motion values.
// const MotionModal = motion(AriaModal);
const MotionModalOverlay = m(ModalOverlay);

function Modal(props: ModalProps, ref: ForwardedRef<HTMLDivElement>) {
const {
children,
Expand All @@ -50,8 +39,6 @@ function Modal(props: ModalProps, ref: ForwardedRef<HTMLDivElement>) {
shadow,
backdrop = 'opaque',
scrollBehavior,
motionProps,
isOpen,
...otherProps
} = props;

Expand All @@ -63,37 +50,15 @@ function Modal(props: ModalProps, ref: ForwardedRef<HTMLDivElement>) {
const baseStyles = clsx(classNames?.base, className);

return (
<AnimatePresence>
{isOpen && (
<LazyMotion features={domAnimation}>
<MotionModalOverlay
isOpen
animate="enter"
exit="exit"
initial="exit"
variants={fadeInOut}
{...otherProps}
className={slots.backdrop({ class: classNames?.backdrop })}
>
<m.div
className={slots.wrapper({ class: classNames?.wrapper })}
data-placement={placement}
animate="enter"
exit="exit"
initial="exit"
variants={scaleInOut}
{...motionProps}
>
<InternalModalContext.Provider value={{ slots, classNames }}>
<AriaModal ref={ref} className={slots.base({ class: baseStyles })}>
{children}
</AriaModal>
</InternalModalContext.Provider>
</m.div>
</MotionModalOverlay>
</LazyMotion>
)}
</AnimatePresence>
<ModalOverlay {...otherProps} className={slots.backdrop({ class: classNames?.backdrop })}>
<div className={slots.wrapper({ class: classNames?.wrapper })} data-placement={placement}>
<InternalModalContext.Provider value={{ slots, classNames }}>
<AriaModal ref={ref} className={slots.base({ class: baseStyles })}>
{children}
</AriaModal>
</InternalModalContext.Provider>
</div>
</ModalOverlay>
);
}

Expand Down
6 changes: 3 additions & 3 deletions packages/react/src/ripple/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import Ripple from './ripple';
// import Ripple from './ripple';

// export types
export type { RippleProps } from './ripple';
// export type { RippleProps } from './ripple';

// export hooks
export { useRipple } from './use-ripple';

// export component
export { Ripple };
// export { Ripple };
Loading

0 comments on commit 7f933ba

Please sign in to comment.