UNPKG

@yamada-ui/react

Version:

React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion

1 lines • 12.5 kB
{"version":3,"file":"snacks.cjs","names":["createSlotComponent","snacksStyle","height","AnimatePresence","motion","varAttr","createTransition","CloseButton"],"sources":["../../../../src/components/snacks/snacks.tsx"],"sourcesContent":["\"use client\"\n\nimport type { Dispatch, RefObject, SetStateAction } from \"react\"\nimport type { CSSProps, HTMLStyledProps, SimpleDirection } from \"../../core\"\nimport type { Merge } from \"../../utils\"\nimport type { CloseButtonProps } from \"../close-button\"\nimport type { HTMLMotionProps } from \"../motion\"\nimport type { SnacksStyle } from \"./snacks.style\"\nimport type { Snack, UseSnacksReturn } from \"./use-snacks\"\nimport { AnimatePresence, useIsPresent } from \"motion/react\"\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\nimport { createSlotComponent, varAttr } from \"../../core\"\nimport { useTimeout } from \"../../hooks/use-timeout\"\nimport { dataAttr, handlerAll, noop, useUpdateEffect } from \"../../utils\"\nimport { Alert } from \"../alert\"\nimport { CloseButton } from \"../close-button\"\nimport { createTransition, motion } from \"../motion\"\nimport { snacksStyle } from \"./snacks.style\"\n\ninterface ComponentContext {\n direction: SimpleDirection\n elMapRef: RefObject<Map<number, HTMLDivElement | null>>\n setExist: Dispatch<SetStateAction<boolean>>\n startIndex: number\n}\n\nexport interface SnacksProps extends HTMLMotionProps {\n /**\n * The snacks created by `useSnacks`.\n */\n snacks: UseSnacksReturn[\"snacks\"]\n /**\n * The CSS `gap` property.\n *\n * @default 'md'\n */\n gap?: CSSProps[\"gap\"]\n /**\n * A property that provides spacing between the top and bottom.\n *\n * @default [0, \"lg\"]\n */\n gutter?: [CSSProps[\"paddingTop\"], CSSProps[\"paddingBottom\"]]\n /**\n * If `true`, apply gutter value to negative margins\n *\n * @default true\n */\n negativeMargins?: boolean\n /**\n * Props for the snacks list element.\n */\n listProps?: HTMLMotionProps\n}\n\nconst {\n ComponentContext,\n PropsContext: SnacksPropsContext,\n useComponentContext,\n usePropsContext: useSnacksPropsContext,\n withContext,\n withProvider,\n} = createSlotComponent<SnacksProps, SnacksStyle, ComponentContext>(\n \"snacks\",\n snacksStyle,\n)\n\nexport { SnacksPropsContext, useSnacksPropsContext }\n\nexport const Snacks = withProvider<\"div\", SnacksProps>(\n ({\n snacks: { direction = \"start\", items, startIndex = 0 },\n listProps,\n ...rest\n }) => {\n const count = items.length\n const elMapRef = useRef<Map<number, HTMLDivElement | null>>(new Map())\n const [height, setHeight] = useState(0)\n const [exist, setExist] = useState(!!count)\n const show = !!count || exist\n const context = useMemo(\n () => ({ direction, elMapRef, setExist, startIndex }),\n [direction, startIndex],\n )\n\n const onExitComplete = useCallback(() => {\n if (!count) setExist(false)\n }, [count])\n\n useEffect(() => {\n let height = 0\n\n if (!count) return\n\n const els = [...elMapRef.current.values()].slice(0, count)\n\n for (const el of els) {\n if (!el) continue\n\n let { offsetHeight, offsetTop } = el\n\n offsetHeight += offsetTop\n\n if (offsetHeight > height) height = offsetHeight\n }\n\n setHeight(height)\n }, [count, direction])\n\n useUpdateEffect(() => {\n if (!!count) setExist(true)\n }, [count])\n\n return (\n <ComponentContext value={context}>\n <AnimatePresence initial={false}>\n {show ? (\n <motion.div {...rest}>\n <SnackList custom={{ height }} {...listProps}>\n <AnimatePresence onExitComplete={onExitComplete}>\n {items.map((props, index) => {\n return (\n <Snack\n key={props.id}\n index={index}\n lastIndex={count - index - 1}\n {...props}\n />\n )\n })}\n </AnimatePresence>\n </SnackList>\n </motion.div>\n ) : null}\n </AnimatePresence>\n </ComponentContext>\n )\n },\n \"root\",\n)(\n {\n animate: \"animate\",\n exit: \"exit\",\n initial: \"initial\",\n variants: {\n animate: {\n padding: \"var(--top) 0 var(--bottom)\",\n transition: { duration: 0.4 },\n },\n exit: { padding: 0 },\n initial: { padding: 0 },\n },\n },\n ({ gap, gutter = [0, \"lg\"], negativeMargins = true, ...rest }) => ({\n \"data-negative\": dataAttr(negativeMargins),\n \"--bottom\": varAttr(gutter[1], \"spaces\", \"0px\"),\n \"--gap\": varAttr(gap, \"spaces\"),\n \"--top\": varAttr(gutter[0], \"spaces\", \"0px\"),\n ...rest,\n }),\n)\n\ninterface SnackListProps extends HTMLMotionProps {}\n\nconst SnackList = withContext<\"div\", SnackListProps>(\n motion.div,\n \"list\",\n)({\n animate: \"animate\",\n exit: \"exit\",\n initial: \"initial\",\n role: \"list\",\n variants: {\n animate: ({ height }) => ({\n height,\n opacity: 1,\n transition: { duration: 0.4 },\n }),\n exit: { height: 0, opacity: 0 },\n initial: { height: 0, opacity: 1 },\n },\n})\n\ninterface SnackProps\n extends Merge<HTMLMotionProps, Merge<Alert.RootProps, Snack>> {\n index: number\n lastIndex: number\n}\n\nconst Snack = withContext<\"div\", SnackProps>(\n ({\n variant = \"plain\",\n closable = true,\n description,\n duration: durationProp = null,\n loadingScheme,\n status,\n title,\n withIcon = true,\n closeButtonProps,\n contentProps,\n descriptionProps,\n iconProps,\n loadingProps,\n titleProps,\n onClose: onCloseProp,\n onCloseComplete,\n ...rest\n }) => {\n const [duration, setDuration] = useState(durationProp)\n const present = useIsPresent()\n const onClose = present ? onCloseProp : noop\n\n const onMouseEnter = useCallback(() => {\n setDuration(null)\n }, [])\n\n const onMouseLeave = useCallback(() => {\n setDuration(durationProp)\n }, [durationProp])\n\n useUpdateEffect(() => {\n if (!present) onCloseComplete?.()\n }, [present])\n\n useUpdateEffect(() => {\n setDuration(durationProp)\n }, [durationProp])\n\n useTimeout(onClose, duration)\n\n return (\n <Alert.Root\n as={motion.div}\n variant={variant}\n status={status}\n {...rest}\n onMouseEnter={handlerAll(rest.onMouseEnter, onMouseEnter)}\n onMouseLeave={handlerAll(rest.onMouseLeave, onMouseLeave)}\n >\n {withIcon ? (\n loadingScheme ? (\n <Alert.Loading loadingScheme={loadingScheme} {...loadingProps} />\n ) : (\n <Alert.Icon {...iconProps} />\n )\n ) : null}\n\n <SnackContent data-close-button={dataAttr(closable)} {...contentProps}>\n {title ? (\n <Alert.Title me=\"0\" {...titleProps}>\n {title}\n </Alert.Title>\n ) : null}\n\n {description ? (\n <Alert.Description {...descriptionProps}>\n {description}\n </Alert.Description>\n ) : null}\n </SnackContent>\n\n {closable ? (\n <SnackCloseButton\n data-variant={variant}\n {...closeButtonProps}\n onClick={handlerAll(closeButtonProps?.onClick, onClose)}\n />\n ) : null}\n </Alert.Root>\n )\n },\n \"item\",\n)(\n {\n animate: \"animate\",\n exit: \"exit\",\n initial: \"initial\",\n layout: true,\n role: \"listitem\",\n variants: {\n animate: ({ index }) => ({\n opacity: 1,\n transition: createTransition.enter()(!index ? 0.2 : 0, 0.4),\n y: 0,\n }),\n exit: {\n opacity: 0,\n transition: createTransition.exit()(undefined, 0.2),\n },\n initial: ({ direction, index }) => ({\n opacity: 0,\n ...(index ? { y: (direction === \"start\" ? -1 : 1) * 16 } : {}),\n }),\n },\n },\n ({ index, lastIndex, ...rest }) => {\n const ref = useRef<HTMLDivElement>(null)\n const { direction, elMapRef, startIndex } = useComponentContext()\n\n useEffect(() => {\n const elMap = elMapRef.current\n\n elMap.set(index, ref.current)\n\n return () => {\n elMap.delete(index)\n }\n }, [elMapRef, index])\n\n return {\n ref,\n \"--index\": direction === \"start\" ? lastIndex : index,\n \"--z-index\": startIndex + index,\n custom: { direction, index },\n ...rest,\n }\n },\n)\n\nexport interface SnackContentProps extends HTMLStyledProps {}\n\nconst SnackContent = withContext<\"div\", SnackContentProps>(\"div\", \"content\")()\n\nexport interface SnackCloseButtonProps extends CloseButtonProps {}\n\nconst SnackCloseButton = withContext<\"button\", SnackCloseButtonProps>(\n CloseButton,\n \"closeButton\",\n)()\n"],"mappings":"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"}