UNPKG

@loke/design-system

Version:

A design system with individually importable components

2 lines (1 loc) 24.7 kB
import React from"react";var toastsCounter=1;class Observer{subscribers;toasts;dismissedToasts;isToasterMounted;constructor(){this.subscribers=[],this.toasts=[],this.dismissedToasts=new Set,this.isToasterMounted=!1}markToasterMounted=()=>{this.isToasterMounted=!0};markToasterUnmounted=()=>{this.isToasterMounted=!1};checkToasterMounted=()=>{if(!this.isToasterMounted)return console.error("No Toaster component is mounted. Please mount a Toaster component before using toast functions."),!1;return!0};subscribe=(subscriber)=>{return this.subscribers.push(subscriber),()=>{let index=this.subscribers.indexOf(subscriber);this.subscribers.splice(index,1)}};publish=(data)=>{for(let subscriber of this.subscribers)subscriber(data)};addToast=(data)=>{this.publish(data),this.toasts=[...this.toasts,data]};create=(data)=>{let{message,...rest}=data,id=typeof data?.id==="number"||data.id&&data.id.length>0?data.id:toastsCounter++,alreadyExists=this.toasts.find((existingToast)=>{return existingToast.id===id}),dismissible=data.dismissible===void 0?!0:data.dismissible;if(this.dismissedToasts.has(id))this.dismissedToasts.delete(id);if(alreadyExists)this.toasts=this.toasts.map((existingToast)=>{if(existingToast.id===id)return this.publish({...existingToast,...data,id,title:message}),{...existingToast,...data,dismissible,id,title:message};return existingToast});else this.addToast({title:message,...rest,dismissible,id});return id};dismiss=(id)=>{if(id)this.dismissedToasts.add(id),requestAnimationFrame(()=>{for(let subscriber of this.subscribers)subscriber({dismiss:!0,id})});else for(let toast of this.toasts)for(let subscriber of this.subscribers)subscriber({dismiss:!0,id:toast.id});return id};message=(message,data)=>{return this.create({...data,message})};error=(message,data)=>{return this.create({...data,message,type:"error"})};success=(message,data)=>{return this.create({...data,message,type:"success"})};info=(message,data)=>{return this.create({...data,message,type:"info"})};warning=(message,data)=>{return this.create({...data,message,type:"warning"})};loading=(message,data)=>{return this.create({...data,message,type:"loading"})};promise=(promise,data)=>{if(!data)return;let id;if(data.loading!==void 0)id=this.create({...data,description:typeof data.description!=="function"?data.description:void 0,message:data.loading,promise,type:"loading"});let p=Promise.resolve(promise instanceof Function?promise():promise),shouldDismiss=id!==void 0,result,originalPromise=p.then(async(response)=>{if(result=["resolve",response],React.isValidElement(response))shouldDismiss=!1,this.create({id,message:response,type:"default"});else if(isHttpResponse(response)&&!response.ok){shouldDismiss=!1;let promiseData=typeof data.error==="function"?await data.error(Error(`HTTP error! status: ${response.status}`)):data.error,description=typeof data.description==="function"?await data.description(Error(`HTTP error! status: ${response.status}`)):data.description,toastSettings=typeof promiseData==="object"&&!React.isValidElement(promiseData)?promiseData:{message:promiseData};this.create({description,id,type:"error",...toastSettings})}else if(response instanceof Error){shouldDismiss=!1;let promiseData=typeof data.error==="function"?await data.error(response):data.error,description=typeof data.description==="function"?await data.description(response):data.description,toastSettings=typeof promiseData==="object"&&!React.isValidElement(promiseData)?promiseData:{message:promiseData};this.create({description,id,type:"error",...toastSettings})}else if(data.success!==void 0){shouldDismiss=!1;let promiseData=typeof data.success==="function"?await data.success(response):data.success,description=typeof data.description==="function"?await data.description(response):data.description,toastSettings=typeof promiseData==="object"&&!React.isValidElement(promiseData)?promiseData:{message:promiseData};this.create({description,id,type:"success",...toastSettings})}}).catch(async(error)=>{if(result=["reject",error],data.error!==void 0){shouldDismiss=!1;let promiseData=typeof data.error==="function"?await data.error(error):data.error,description=typeof data.description==="function"?await data.description(error):data.description,toastSettings=typeof promiseData==="object"&&!React.isValidElement(promiseData)?promiseData:{message:promiseData};this.create({description,id,type:"error",...toastSettings})}}).finally(()=>{if(shouldDismiss)this.dismiss(id),id=void 0;data.finally?.()}),unwrap=()=>new Promise((resolve,reject)=>originalPromise.then(()=>result[0]==="reject"?reject(result[1]):resolve(result[1])).catch(reject));if(typeof id!=="string"&&typeof id!=="number")return{unwrap};return Object.assign(id,{unwrap})};custom=(jsx,data)=>{let id=data?.id||toastsCounter++;return this.create({id,jsx:jsx(id),...data}),id};getActiveToasts=()=>{return this.toasts.filter((t)=>!this.dismissedToasts.has(t.id))}}var ToastState=new Observer,toastFunction=(message,data)=>{if(!ToastState.checkToasterMounted())return;let id=data?.id||toastsCounter++;return ToastState.addToast({title:message,...data,id}),id},isHttpResponse=(data)=>{return Boolean(data)&&typeof data==="object"&&data!==null&&"ok"in data&&typeof data.ok==="boolean"&&"status"in data&&typeof data.status==="number"},basicToast=toastFunction,getHistory=()=>ToastState.toasts,getToasts=()=>ToastState.getActiveToasts(),toast=Object.assign(basicToast,{custom:ToastState.custom,dismiss:ToastState.dismiss,error:ToastState.error,info:ToastState.info,loading:ToastState.loading,message:ToastState.message,promise:ToastState.promise,success:ToastState.success,warning:ToastState.warning},{getHistory,getToasts});import{Button}from"@loke/design-system/button";import{cn}from"@loke/design-system/cn";import{Spinner}from"@loke/design-system/spinner";import{AlertCircle,AlertTriangle,CheckCircle,Info,X}from"@loke/icons";import{useComposedRefs}from"@loke/ui/compose-refs";import{useCallbackRef}from"@loke/ui/use-callback-ref";import{useEscapeKeydown}from"@loke/ui/use-escape-keydown";import{useIsDocumentHidden}from"@loke/ui/use-is-document-hidden";import{useLayoutEffect}from"@loke/ui/use-layout-effect";import{usePrevious}from"@loke/ui/use-previous";import React2 from"react";import ReactDOM from"react-dom";import{jsx,jsxs}from"react/jsx-runtime";var VISIBLE_TOASTS_AMOUNT=3,VIEWPORT_OFFSET="24px",MOBILE_VIEWPORT_OFFSET="16px",TOAST_LIFETIME=4000,TOAST_WIDTH=356,GAP=14,SWIPE_THRESHOLD=45,TIME_BEFORE_UNMOUNT=400,getAsset=(type)=>{switch(type){case"success":return jsx(CheckCircle,{color:"primary"});case"info":return jsx(Info,{});case"warning":return jsx(AlertTriangle,{});case"error":return jsx(AlertCircle,{color:"accent"});default:return null}};function isAction(action){return action.label!==void 0}function assignOffset(defaultOffset,mobileOffset){let styles={};return[defaultOffset,mobileOffset].forEach((offset,index)=>{let isMobile=index===1,prefix=isMobile?"--mobile-offset":"--offset",defaultValue=isMobile?MOBILE_VIEWPORT_OFFSET:VIEWPORT_OFFSET;function assignAll(offsetValue){for(let key of["top","right","bottom","left"])styles[`${prefix}-${key}`]=typeof offsetValue==="number"?`${offsetValue}px`:offsetValue}if(typeof offset==="number"||typeof offset==="string")assignAll(offset);else if(typeof offset==="object")for(let key of["top","right","bottom","left"]){let offsetKey=key;if(offset[offsetKey]===void 0)styles[`${prefix}-${key}`]=defaultValue;else{let value=offset[offsetKey];styles[`${prefix}-${key}`]=typeof value==="number"?`${value}px`:value}}else assignAll(defaultValue)}),styles}function useToasts(){let[activeToasts,setActiveToasts]=React2.useState([]);return React2.useEffect(()=>{return ToastState.subscribe((toast2)=>{if(toast2.dismiss){setTimeout(()=>{ReactDOM.flushSync(()=>{setActiveToasts((toasts)=>toasts.filter((t)=>t.id!==toast2.id))})});return}setTimeout(()=>{ReactDOM.flushSync(()=>{setActiveToasts((prevToasts)=>{if(!toast2.id)return prevToasts;let toastWithId=toast2,indexOfExistingToast=prevToasts.findIndex((t)=>t.id===toastWithId.id);if(indexOfExistingToast!==-1)return[...prevToasts.slice(0,indexOfExistingToast),{...prevToasts[indexOfExistingToast],...toast2},...prevToasts.slice(indexOfExistingToast+1)];return[toastWithId,...prevToasts]})})})})},[]),{toasts:activeToasts}}var Toast=({toast:toast2,interacting,setHeights,visibleToasts,heights,index,toasts,expanded,removeToast,closeButton:closeButtonFromToaster,duration:durationFromToaster,gap,expandByDefault,icons,closeButtonAriaLabel="Close toast"})=>{let[swipeDirection,setSwipeDirection]=React2.useState(null),[swipeOutDirection,setSwipeOutDirection]=React2.useState(null),[mounted,setMounted]=React2.useState(!1),[removed,setRemoved]=React2.useState(!1),[swiping,setSwiping]=React2.useState(!1),[swipeOut,setSwipeOut]=React2.useState(!1),[isSwiped,setIsSwiped]=React2.useState(!1),[offsetBeforeRemove,setOffsetBeforeRemove]=React2.useState(0),[initialHeight,setInitialHeight]=React2.useState(0),remainingTime=React2.useRef(toast2.duration||durationFromToaster||TOAST_LIFETIME),dragStartTime=React2.useRef(null),toastRef=React2.useRef(null),isFront=index===0,isVisible=index+1<=visibleToasts,toastType=toast2.type,dismissible=toast2.dismissible!==!1,heightIndex=React2.useMemo(()=>heights.findIndex((height)=>height.toastId===toast2.id)||0,[heights,toast2.id]),closeButton=React2.useMemo(()=>toast2.closeButton??closeButtonFromToaster,[toast2.closeButton,closeButtonFromToaster]),duration=React2.useMemo(()=>toast2.duration||durationFromToaster||TOAST_LIFETIME,[toast2.duration,durationFromToaster]),[closeTimerStartTime,setCloseTimerStartTime]=React2.useState(0),previousCloseTimerStartTime=usePrevious(closeTimerStartTime),closeTimerStartTimeRef=React2.useRef(0),offset=React2.useRef(0),pointerStartRef=React2.useRef(null),toastsHeightBefore=React2.useMemo(()=>{return heights.reduce((prev,curr,reducerIndex)=>{if(reducerIndex>=heightIndex)return prev;return prev+curr.height},0)},[heights,heightIndex]),isDocumentHidden=useIsDocumentHidden(),disabled=toastType==="loading";offset.current=React2.useMemo(()=>heightIndex*(gap??1)+toastsHeightBefore,[heightIndex,toastsHeightBefore]),React2.useEffect(()=>{remainingTime.current=duration},[duration]),React2.useEffect(()=>{setMounted(!0)},[]),useLayoutEffect(()=>{let toastNode=toastRef.current;if(toastNode){let height=toastNode.getBoundingClientRect().height;return setInitialHeight(height),setHeights((h)=>[{height,toastId:toast2.id},...h]),()=>setHeights((h)=>h.filter((heightItem)=>heightItem.toastId!==toast2.id))}},[setHeights,toast2.id]),useLayoutEffect(()=>{if(!mounted)return;let toastNode=toastRef.current,originalHeight=toastNode.style.height;toastNode.style.height="auto";let newHeight=toastNode.getBoundingClientRect().height;toastNode.style.height=originalHeight,setInitialHeight(newHeight),setHeights((prevHeights)=>{if(!prevHeights.find((height)=>height.toastId===toast2.id))return[{height:newHeight,toastId:toast2.id},...prevHeights];return prevHeights.map((height)=>height.toastId===toast2.id?{...height,height:newHeight}:height)})},[mounted,toast2.title,toast2.description,setHeights,toast2.id]);let deleteToast=useCallbackRef(()=>{setRemoved(!0),setOffsetBeforeRemove(offset.current),setHeights((h)=>h.filter((height)=>height.toastId!==toast2.id)),setTimeout(()=>{removeToast(toast2)},TIME_BEFORE_UNMOUNT)});React2.useEffect(()=>{if(toast2.promise&&toastType==="loading"||toast2.duration===Number.POSITIVE_INFINITY||toast2.type==="loading")return;let timeoutId,pauseTimer=()=>{if(previousCloseTimerStartTime<closeTimerStartTime){let elapsedTime=Date.now()-closeTimerStartTime;remainingTime.current-=elapsedTime}setCloseTimerStartTime(Date.now())},startTimer=()=>{if(remainingTime.current===Number.POSITIVE_INFINITY)return;closeTimerStartTimeRef.current=Date.now(),timeoutId=setTimeout(()=>{toast2.onAutoClose?.(toast2),deleteToast()},remainingTime.current)};if(expanded||interacting||isDocumentHidden)pauseTimer();else startTimer();return()=>clearTimeout(timeoutId)},[expanded,interacting,toast2,toastType,isDocumentHidden,deleteToast]),React2.useEffect(()=>{if(toast2.delete)deleteToast()},[deleteToast,toast2.delete]);let icon=null;if(toastType){if(toast2.icon)icon=toast2.icon;if(icons&&toastType in icons)icon=icons[toastType];if(toastType)icon=getAsset(toastType)}let hasIcon=toast2.icon||toastType||toast2.promise,getY=()=>{if(removed&&!isFront&&!swipeOut&&!expanded)return"translateY(40%)";if(removed&&!isFront&&!swipeOut&&expanded)return"translateY(calc(var(--lift) * var(--offset) + var(--lift) * -100%))";if(removed&&isFront&&!swipeOut)return"translateY(calc(var(--lift) * -100%))";if(mounted&&expanded)return"translateY(calc(var(--lift) * var(--offset)))";if(!(expanded||isFront))return"translateY(calc(var(--lift-amount) * var(--toasts-before))) scale(calc(-1 * var(--scale)))";if(mounted)return"translateY(0)";return"translateY(100%)"},renderButton=(action,onClickHandler)=>{if(React2.isValidElement(action))return action;if(action&&isAction(action))return jsx(Button,{className:"h-6 px-2 text-xs",onClick:onClickHandler,size:"sm",variant:"outline",children:action.label});return null};return jsxs("li",{className:cn("break-anywhere absolute right-0 bottom-0 z-999999 box-border flex w-(--width) translate-y-full transform touch-none items-center gap-1.5 rounded-md border border-border bg-card p-4 text-foreground text-sm opacity-0 shadow-[0px_4px_12px_rgba(0,0,0,0.1)] outline-none transition-[transform_400ms,opacity_400ms,height_400ms,box-shadow_200ms]","focus-visible:shadow-[0px_4px_12px_rgba(0,0,0,0.1),0_0_0_2px_rgba(0,0,0,0.2)]",disabled&&"cursor-not-allowed",swiping&&"before:absolute before:top-1/2 before:right-[-100%] before:left-[-100%] before:z-[-1] before:h-full before:-translate-y-1/2 before:scale-y-[3] before:content-['']",removed&&"before:absolute before:inset-0 before:scale-y-2 before:content-['']",expanded&&"after:absolute after:bottom-full after:left-0 after:h-[calc(var(--gap)+1px)] after:w-full after:content-['']",mounted&&"translate-y-0 opacity-100 [&>*]:transition-opacity [&>*]:duration-400",!isVisible&&"pointer-events-none opacity-0",mounted&&expanded&&"transform-[translateY(calc(var(--lift)*var(--offset)))] h-[var(--initial-height)]",!(expanded||isFront)&&"transform-[translateY(calc(var(--lift-amount)*var(--toasts-before)))] z-[var(--z-index)] h-[var(--front-toast-height)] scale-[calc(1-var(--toasts-before)*0.05)]",!(expanded||isFront)&&"[&>*]:opacity-0",removed&&isFront&&!swipeOut&&"transform-[translateY(calc(var(--lift)*-100%))] opacity-0",removed&&!isFront&&!swipeOut&&expanded&&"transform-[translateY(calc(var(--lift)*var(--offset)+var(--lift)*-100%))] opacity-0",removed&&!isFront&&!swipeOut&&!expanded&&"transform-[translateY(40%)] opacity-0 transition-[transform_500ms,opacity_200ms]",removed&&"before:h-[calc(var(--initial-height)+20%)]",swiping&&"transform-[var(--y)_translateY(var(--swipe-amount-y,0px))_translateX(var(--swipe-amount-x,0px))] transition-none",isSwiped&&"select-none",swipeOut&&"animation-duration-200 animation-ease-out animation-fill-forwards",swipeOut&&swipeOutDirection==="right"&&"swipe-out-right",swipeOut&&swipeOutDirection==="down"&&"swipe-out-down",toastType==="error"&&"bg-destructive/90 text-destructive-foreground"),onDragEnd:()=>{setSwiping(!1),setSwipeDirection(null),pointerStartRef.current=null},onPointerDown:(event)=>{if(disabled||!dismissible)return;if(dragStartTime.current=new Date,setOffsetBeforeRemove(offset.current),event.target.setPointerCapture(event.pointerId),event.target.tagName==="BUTTON")return;setSwiping(!0),pointerStartRef.current={x:event.clientX,y:event.clientY}},onPointerMove:(event)=>{if(!(pointerStartRef.current&&dismissible))return;let isHighlighted=!1;if(window.getSelection()&&window.getSelection()!==null)isHighlighted=window.getSelection().toString().length>0;if(isHighlighted)return;let yDelta=event.clientY-pointerStartRef.current.y,xDelta=event.clientX-pointerStartRef.current.x,swipeDirections=["bottom","right"];if(!swipeDirection&&(Math.abs(xDelta)>1||Math.abs(yDelta)>1))setSwipeDirection(Math.abs(xDelta)>Math.abs(yDelta)?"x":"y");let swipeAmount={x:0,y:0},getDampening=(delta)=>{return 1/(1.5+Math.abs(delta)/20)};if(swipeDirection==="y"){if(swipeDirections.includes("top")||swipeDirections.includes("bottom"))if(swipeDirections.includes("top")&&yDelta<0||swipeDirections.includes("bottom")&&yDelta>0)swipeAmount.y=yDelta;else{let dampenedDelta=yDelta*getDampening(yDelta);swipeAmount.y=Math.abs(dampenedDelta)<Math.abs(yDelta)?dampenedDelta:yDelta}}else if(swipeDirection==="x"&&swipeDirections.includes("left")||swipeDirections.includes("right"))if(swipeDirections.includes("left")&&xDelta<0||swipeDirections.includes("right")&&xDelta>0)swipeAmount.x=xDelta;else{let dampenedDelta=xDelta*getDampening(xDelta);swipeAmount.x=Math.abs(dampenedDelta)<Math.abs(xDelta)?dampenedDelta:xDelta}if(Math.abs(swipeAmount.x)>0||Math.abs(swipeAmount.y)>0)setIsSwiped(!0);toastRef.current?.style.setProperty("--swipe-amount-x",`${swipeAmount.x}px`),toastRef.current?.style.setProperty("--swipe-amount-y",`${swipeAmount.y}px`)},onPointerUp:()=>{if(swipeOut||!dismissible)return;pointerStartRef.current=null;let swipeAmountX=Number(toastRef.current?.style.getPropertyValue("--swipe-amount-x").replace("px","")||0),swipeAmountY=Number(toastRef.current?.style.getPropertyValue("--swipe-amount-y").replace("px","")||0),timeTaken=Date.now()-(dragStartTime.current?dragStartTime.current.getTime():0),swipeAmount=swipeDirection==="x"?swipeAmountX:swipeAmountY,velocity=Math.abs(swipeAmount)/timeTaken;if(Math.abs(swipeAmount)>=SWIPE_THRESHOLD||velocity>0.11){if(setOffsetBeforeRemove(offset.current),swipeDirection==="x")toastRef.current?.style.setProperty("--swipe-amount-x","400px"),setSwipeOutDirection("right");else toastRef.current?.style.setProperty("--swipe-amount-y","300px"),setSwipeOutDirection("down");toast2.onDismiss?.(toast2),deleteToast(),setSwipeOut(!0);return}toastRef.current?.style.setProperty("--swipe-amount-x","0px"),toastRef.current?.style.setProperty("--swipe-amount-y","0px"),setIsSwiped(!1),setSwiping(!1),setSwipeDirection(null)},ref:toastRef,style:{"--initial-height":expandByDefault?"auto":`${initialHeight}px`,"--lift":-1,"--lift-amount":"calc(var(--lift) * var(--gap))","--offset":`${removed?offsetBeforeRemove:offset.current}px`,"--toasts-before":index,"--y":getY(),"--z-index":toasts.length-index},tabIndex:0,children:[closeButton&&toastType!=="loading"&&jsx("button",{"aria-label":closeButtonAriaLabel,className:"absolute top-1 right-1 z-1 flex transform cursor-pointer items-center justify-center rounded-full p-0 transition-[opacity_100ms,background_200ms,border-color_200ms] focus-visible:shadow-[0px_4px_12px_rgba(0,0,0,0.1),0_0_0_2px_rgba(0,0,0,0.2)] disabled:cursor-not-allowed",onClick:disabled||!dismissible?()=>{}:()=>{deleteToast(),toast2.onDismiss?.(toast2)},type:"button",children:icons?.close??jsx(X,{className:"text-muted",fill:"currentColor",size:"sm",strokeWidth:1})}),hasIcon&&jsxs("div",{className:"relative mr-3 -ml-1 flex h-4 w-4 shrink-0 items-center justify-start",children:[toast2.promise||toast2.type==="loading"&&!toast2.icon?toast2.icon||jsx(Spinner,{className:toastType!=="loading"?"hidden":""}):null,toast2.type!=="loading"?icon:null]}),jsxs("div",{className:"flex flex-col gap-0.5",children:[jsx("div",{className:"font-medium text-sm leading-normal group-[.toast]:font-semibold",children:typeof toast2.title==="function"?toast2.title():toast2.title}),toast2.description?jsx("div",{className:cn("font-normal text-xs leading-normal group-[.toast]:text-muted-foreground",toastType==="error"&&"group-[.toast]:text-destructive-foreground/80"),children:typeof toast2.description==="function"?toast2.description():toast2.description}):null]}),renderButton(toast2.cancel,(event)=>{if(!isAction(toast2.cancel))return;if(!dismissible)return;toast2.cancel.onClick?.(event),deleteToast()}),renderButton(toast2.action,(event)=>{if(!isAction(toast2.action))return;if(toast2.action.onClick?.(event),event.defaultPrevented)return;deleteToast()})]})},Toaster=React2.forwardRef(function({hotkey=["altKey","KeyT"],expand,closeButton,offset,mobileOffset,duration,visibleToasts=VISIBLE_TOASTS_AMOUNT,toastOptions,gap=GAP,icons,containerAriaLabel="Notifications"},forwardedRef){let[toasts,setToasts]=React2.useState([]),[heights,setHeights]=React2.useState([]),[expanded,setExpanded]=React2.useState(!1),[interacting,setInteracting]=React2.useState(!1),toasterRef=React2.useRef(null),composedRefs=useComposedRefs(toasterRef,forwardedRef),listRef=React2.useRef(null),hotkeyLabel=hotkey.join("+").replace(/Key/g,"").replace(/Digit/g,""),lastFocusedElementRef=React2.useRef(null),isFocusWithinRef=React2.useRef(!1);React2.useEffect(()=>{return ToastState.markToasterMounted(),()=>{ToastState.markToasterUnmounted()}},[]);let removeToast=useCallbackRef((toastToRemove)=>{setToasts((prevToasts)=>{if(!prevToasts.find((toast2)=>toast2.id===toastToRemove.id)?.delete)ToastState.dismiss(toastToRemove.id);return prevToasts.filter(({id})=>id!==toastToRemove.id)})});React2.useEffect(()=>{return ToastState.subscribe((toast2)=>{if(toast2.dismiss){requestAnimationFrame(()=>{setToasts((prevToasts)=>prevToasts.map((t)=>t.id===toast2.id?{...t,delete:!0}:t))});return}setTimeout(()=>{ReactDOM.flushSync(()=>{setToasts((prevToasts)=>{if(!toast2.id)return prevToasts;let toastWithId=toast2,indexOfExistingToast=prevToasts.findIndex((t)=>t.id===toastWithId.id);if(indexOfExistingToast!==-1)return[...prevToasts.slice(0,indexOfExistingToast),{...toasts[indexOfExistingToast],...toast2},...prevToasts.slice(indexOfExistingToast+1)];return[toastWithId,...prevToasts]})})})})},[toasts]),React2.useEffect(()=>{if(toasts.length<=1)setExpanded(!1)},[toasts]),React2.useEffect(()=>{let handleKeyDown=(event)=>{if(hotkey.every((key)=>{if(key==="KeyT")return event.code==="KeyT";return event[key]}))setExpanded(!0),listRef.current?.focus()};return document.addEventListener("keydown",handleKeyDown),()=>document.removeEventListener("keydown",handleKeyDown)},[hotkey]),useEscapeKeydown(()=>{if(document.activeElement===listRef.current||listRef.current?.contains(document.activeElement))setExpanded(!1)}),useLayoutEffect(()=>{if(listRef.current)return()=>{if(lastFocusedElementRef.current)lastFocusedElementRef.current.focus({preventScroll:!0}),lastFocusedElementRef.current=null,isFocusWithinRef.current=!1}},[listRef.current]);let lifted=expanded&&toasts.length>1&&!expand;return jsx("section",{"aria-atomic":"false","aria-label":`${containerAriaLabel} ${hotkeyLabel}`,"aria-live":"polite","aria-relevant":"additions text",ref:composedRefs,suppressHydrationWarning:!0,tabIndex:-1,children:jsx("ol",{className:cn("fixed right-[var(--offset-right)] bottom-[var(--offset-bottom)] z-[999999999] m-0 box-border w-[var(--width)] list-none p-0 outline-none transition-transform duration-400 ease-in",lifted&&"-translate-y-2 transform md:transform-none","max-sm:right-[var(--mobile-offset-right)] max-sm:left-[var(--mobile-offset-left)] max-sm:w-full",lifted&&"-translate-y-2 md:transform-none"),onBlur:(event)=>{if(isFocusWithinRef.current&&!event.currentTarget.contains(event.relatedTarget)){if(isFocusWithinRef.current=!1,lastFocusedElementRef.current)lastFocusedElementRef.current.focus({preventScroll:!0}),lastFocusedElementRef.current=null}},onDragEnd:()=>setExpanded(!1),onFocus:(event)=>{if(event.target instanceof HTMLElement&&event.target.dataset.dismissible==="false")return;if(!isFocusWithinRef.current)isFocusWithinRef.current=!0,lastFocusedElementRef.current=event.relatedTarget},onMouseEnter:()=>setExpanded(!0),onMouseLeave:()=>{if(!interacting)setExpanded(!1)},onMouseMove:()=>setExpanded(!0),onPointerDown:(event)=>{if(event.target instanceof HTMLElement&&event.target.dataset.dismissible==="false")return;setInteracting(!0)},onPointerUp:()=>setInteracting(!1),ref:listRef,style:{"--front-toast-height":`${heights[0]?.height||0}px`,"--gap":`${gap}px`,"--toast-button-margin-end":"0","--toast-button-margin-start":"auto","--toast-close-button-end":"unset","--toast-close-button-start":"0","--toast-close-button-transform":"translate(-35%, -35%)","--toast-icon-margin-end":"4px","--toast-icon-margin-start":"-3px","--toast-svg-margin-end":"0px","--toast-svg-margin-start":"-1px","--width":`${TOAST_WIDTH}px`,...assignOffset(offset,mobileOffset)},tabIndex:-1,children:toasts.map((toast2,index)=>jsx(Toast,{closeButton:Boolean(toastOptions?.closeButton??closeButton),closeButtonAriaLabel:toastOptions?.closeButtonAriaLabel,duration:toastOptions?.duration??duration,expandByDefault:Boolean(expand),expanded,gap,heights,icons,index,interacting,removeToast,setHeights,toast:toast2,toasts,visibleToasts},toast2.id))})})});export{useToasts,toast,Toaster};