Skip to content

Commit

Permalink
chore: fixes and adding draft1 of stories
Browse files Browse the repository at this point in the history
  • Loading branch information
macci001 committed Dec 25, 2024
1 parent 2a73f8a commit f479b3b
Show file tree
Hide file tree
Showing 9 changed files with 254 additions and 75 deletions.
29 changes: 6 additions & 23 deletions packages/components/toast/src/toast-provider.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import {ToastOptions, ToastQueue, useToastQueue} from "@react-stately/toast";
import {ToastVariantProps} from "@nextui-org/theme";

import {ToastRegion} from "./toast-region";
import {ToastType} from "./use-toast";
import {ToastProps} from "./use-toast";

let globalToastQueue: ToastQueue<ToastType> | null = null;
let globalToastQueue: ToastQueue<ToastProps> | null = null;

interface ToastProviderProps {
maxVisibleToasts?: number;
Expand All @@ -30,31 +29,15 @@ export const ToastProvider = ({maxVisibleToasts = 5}: ToastProviderProps) => {
return <ToastRegion toastQueue={toastQueue} />;
};

export const addToast = ({
title,
description,
priority,
timeout,
...config
}: {
title: string;
description: string;
} & ToastOptions &
ToastVariantProps) => {
export const addToast = ({...props}: ToastProps & ToastOptions) => {
if (!globalToastQueue) {
return;
}

const content: ToastType = {
title,
description,
config: config,
};

const options: Partial<ToastOptions> = {
timeout,
priority,
timeout: props?.timeout,
priority: props?.priority,
};

globalToastQueue.add(content, options);
globalToastQueue.add(props, options);
};
10 changes: 4 additions & 6 deletions packages/components/toast/src/toast-region.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import {useToastRegion, AriaToastRegionProps} from "@react-aria/toast";
import {QueuedToast, ToastState} from "@react-stately/toast";

import Toast from "./toast";
import {ToastType} from "./use-toast";
import {ToastProps} from "./use-toast";

interface ToastRegionProps<T> extends AriaToastRegionProps {
toastQueue: ToastState<T>;
}

export function ToastRegion<T extends ToastType>({toastQueue, ...props}: ToastRegionProps<T>) {
export function ToastRegion<T extends ToastProps>({toastQueue, ...props}: ToastRegionProps<T>) {
const ref = useRef(null);
const {regionProps} = useToastRegion(props, toastQueue, ref);

Expand All @@ -20,10 +20,8 @@ export function ToastRegion<T extends ToastType>({toastQueue, ...props}: ToastRe
ref={ref}
className="fixed bottom-6 right-6 w-screen flex flex-col items-end justify-center"
>
{toastQueue.visibleToasts.map((toast: QueuedToast<ToastType>) => {
return (
<Toast key={toast.key} state={toastQueue} toast={toast} {...toast.content.config} />
);
{toastQueue.visibleToasts.map((toast: QueuedToast<ToastProps>) => {
return <Toast key={toast.key} state={toastQueue} toast={toast} {...toast.content} />;
})}
</div>
</>
Expand Down
25 changes: 22 additions & 3 deletions packages/components/toast/src/toast.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
import {forwardRef} from "@nextui-org/system";
import {Button, ButtonProps} from "@nextui-org/button";
import {CloseIcon} from "@nextui-org/shared-icons";
import {
CloseIcon,
DangerIcon,
InfoFilledIcon,
SuccessIcon,
WarningIcon,
} from "@nextui-org/shared-icons";
import {motion, AnimatePresence} from "framer-motion";
import {Progress} from "@nextui-org/progress";
import {cloneElement, isValidElement} from "react";

import {UseToastProps, useToast} from "./use-toast";

export interface ToastProps extends UseToastProps {}

const iconMap = {
primary: InfoFilledIcon,
secondary: InfoFilledIcon,
success: SuccessIcon,
warning: WarningIcon,
danger: DangerIcon,
} as const;

const Toast = forwardRef<"div", ToastProps>((props, ref) => {
const {
Component,
Icon,
icon,
domRef,
endContent,
closeProgressBarValue,
color,
getToastProps,
getContentProps,
getTitleProps,
Expand All @@ -33,6 +49,9 @@ const Toast = forwardRef<"div", ToastProps>((props, ref) => {
exit: {opacity: 0, y: 50},
};

const customIcon = icon && isValidElement(icon) ? cloneElement(icon, getIconProps()) : null;
const IconComponent = iconMap[color] || iconMap.primary;

return (
<AnimatePresence>
<motion.div
Expand All @@ -44,7 +63,7 @@ const Toast = forwardRef<"div", ToastProps>((props, ref) => {
>
<Component ref={domRef} {...getToastProps()}>
<main {...getContentProps()}>
<Icon {...getIconProps()} />
{customIcon || <IconComponent {...getIconProps()} />}
<div>
<div {...getTitleProps()}>{props.toast.content.title}</div>
<div {...getDescriptionProps()}>{props.toast.content.description}</div>
Expand Down
38 changes: 16 additions & 22 deletions packages/components/toast/src/use-toast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,26 @@ import {ReactNode, useCallback, useEffect, useMemo, useState} from "react";
import {useToast as useToastAria, AriaToastProps} from "@react-aria/toast";
import {mergeProps} from "@react-aria/utils";
import {QueuedToast, ToastState} from "@react-stately/toast";
import {InfoFilledIcon} from "@nextui-org/shared-icons";

export type ToastType = {
title: string;
description: string;
config: ToastVariantProps;
};

interface Props<T> extends HTMLNextUIProps<"div"> {
/**
* Ref to the DOM node.
*/

export interface ToastProps extends ToastVariantProps {
ref?: ReactRef<HTMLElement | null>;
toast: QueuedToast<T>;
state: ToastState<T>;
title?: string;
description?: string;
classNames?: SlotsToClasses<ToastSlots>;
/**
* Content to be displayed in the end side of the alert
*/
endContent?: ReactNode;
icon?: ReactNode;
}

interface Props<T> extends HTMLNextUIProps<"div">, ToastProps {
toast: QueuedToast<T>;
state: ToastState<T>;
}

export type UseToastProps<T = ToastType> = Props<T> &
export type UseToastProps<T = ToastProps> = Props<T> &
ToastVariantProps &
Omit<AriaToastProps<T>, "div">;

export function useToast<T extends ToastType>(originalProps: UseToastProps<T>) {
export function useToast<T extends ToastProps>(originalProps: UseToastProps<T>) {
const [props, variantProps] = mapPropsVariants(originalProps, toastTheme.variantKeys);

const [closeProgressBarValue, setCloseProgressBarValue] = useState(0);
Expand All @@ -56,7 +49,7 @@ export function useToast<T extends ToastType>(originalProps: UseToastProps<T>) {
const {ref, as, className, classNames, toast, endContent, ...otherProps} = props;

const Component = as || "div";
let Icon = InfoFilledIcon;
const icon: ReactNode = props.icon;

const domRef = useDOMRef(ref);
const baseStyles = clsx(className, classNames?.base);
Expand Down Expand Up @@ -108,7 +101,7 @@ export function useToast<T extends ToastType>(originalProps: UseToastProps<T>) {

const getIconProps: PropGetter = useCallback(
(props = {}) => ({
className: slots.content({class: classNames?.icon}),
className: slots.icon({class: classNames?.icon}),
...props,
}),
[],
Expand Down Expand Up @@ -166,11 +159,12 @@ export function useToast<T extends ToastType>(originalProps: UseToastProps<T>) {

return {
Component,
Icon,
icon,
styles,
domRef,
classNames,
closeProgressBarValue,
color: variantProps["color"],
getToastProps,
getTitleProps,
getContentProps,
Expand Down
Loading

0 comments on commit f479b3b

Please sign in to comment.