@tiny-design/react 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,10 @@
1
1
  import { ConfigContext } from "../config-provider/config-context.js";
2
2
  import { getPrefixCls } from "../_utils/general.js";
3
+ import transition_default from "../transition/index.js";
3
4
  import overlay_default from "../overlay/index.js";
4
5
  import React, { useContext, useEffect, useId, useRef, useState } from "react";
5
6
  import classNames from "classnames";
6
7
  import { jsx, jsxs } from "react/jsx-runtime";
7
- import { CSSTransition } from "react-transition-group";
8
8
  //#region src/drawer/drawer.tsx
9
9
  const Drawer = React.forwardRef((props, ref) => {
10
10
  const { visible, placement = "right", size = 256, closable = true, unmountOnClose = true, maskType = "default", maskClosable = true, onClose, prefixCls: customisedCls, afterClose, zIndex = 1e3, header, footer, className, maskStyle, style, children } = props;
@@ -70,11 +70,12 @@ const Drawer = React.forwardRef((props, ref) => {
70
70
  ...style,
71
71
  ...sty
72
72
  },
73
- children: /* @__PURE__ */ jsx(CSSTransition, {
73
+ children: /* @__PURE__ */ jsx(transition_default, {
74
74
  appear: true,
75
75
  nodeRef,
76
76
  in: drawerVisible,
77
77
  timeout: 0,
78
+ unmountOnExit: false,
78
79
  classNames: `${prefixCls}__content_move`,
79
80
  children: /* @__PURE__ */ jsxs("div", {
80
81
  ref: nodeRef,
@@ -1 +1 @@
1
- {"version":3,"file":"drawer.js","names":["Overlay"],"sources":["../../src/drawer/drawer.tsx"],"sourcesContent":["import React, { useContext, useEffect, useId, useRef, useState } from 'react';\nimport classNames from 'classnames';\nimport { CSSTransition } from 'react-transition-group';\nimport Overlay from '../overlay';\nimport { ConfigContext } from '../config-provider/config-context';\nimport { getPrefixCls } from '../_utils/general';\nimport { DrawerProps } from './types';\n\nconst Drawer = React.forwardRef<HTMLDivElement, DrawerProps>((props, ref) => {\n const {\n visible,\n placement = 'right',\n size = 256,\n closable = true,\n unmountOnClose = true,\n maskType = 'default',\n maskClosable = true,\n onClose,\n prefixCls: customisedCls,\n afterClose,\n zIndex = 1000,\n header,\n footer,\n className,\n maskStyle,\n style,\n children,\n } = props;\n const [drawerVisible, setDrawerVisible] = useState(visible);\n const configContext = useContext(ConfigContext);\n const prefixCls = getPrefixCls('drawer', configContext.prefixCls, customisedCls);\n const cls = classNames(prefixCls, className, `${prefixCls}_${placement}`);\n const sty: React.CSSProperties =\n placement === 'top' || placement === 'bottom' ? { height: size } : { width: size };\n const nodeRef = useRef<HTMLDivElement>(null);\n const previousFocusRef = useRef<HTMLElement | null>(null);\n const titleId = useId();\n\n // Focus trap + Escape key\n useEffect(() => {\n if (!visible) return;\n previousFocusRef.current = document.activeElement as HTMLElement;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n onClose?.(e as unknown as React.MouseEvent);\n return;\n }\n if (e.key === 'Tab' && nodeRef.current) {\n const focusable = nodeRef.current.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n if (focusable.length === 0) return;\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n if (e.shiftKey) {\n if (document.activeElement === first) { e.preventDefault(); last.focus(); }\n } else {\n if (document.activeElement === last) { e.preventDefault(); first.focus(); }\n }\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n\n requestAnimationFrame(() => {\n if (nodeRef.current) {\n const focusable = nodeRef.current.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n if (focusable.length > 0) focusable[0].focus();\n }\n });\n\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n previousFocusRef.current?.focus();\n };\n }, [visible, onClose]);\n\n return (\n <Overlay\n onEnter={(): void => setDrawerVisible(true)}\n onExit={(): void => setDrawerVisible(false)}\n zIndex={zIndex}\n type={maskType}\n unmountOnExit={unmountOnClose}\n isShow={visible}\n onExited={afterClose}\n clickCallback={(e: React.MouseEvent): void => {\n maskClosable && onClose ? onClose(e) : undefined;\n }}\n style={maskStyle}>\n <div ref={ref} className={cls} style={{ ...style, ...sty }}>\n <CSSTransition\n appear={true}\n nodeRef={nodeRef}\n in={drawerVisible}\n timeout={0}\n classNames={`${prefixCls}__content_move`}>\n <div\n ref={nodeRef}\n className={`${prefixCls}__content`}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={header ? titleId : undefined}\n onClick={(e) => e.stopPropagation()}>\n {closable && (\n <button type=\"button\" className={`${prefixCls}__close-btn`} onClick={onClose} aria-label=\"Close\">\n ✕\n </button>\n )}\n {header && <div className={`${prefixCls}__header`} id={titleId}>{header}</div>}\n <div className={`${prefixCls}__body`}>{children}</div>\n {footer && <div className={`${prefixCls}__footer`}>{footer}</div>}\n </div>\n </CSSTransition>\n </div>\n </Overlay>\n );\n});\n\nDrawer.displayName = 'Drawer';\n\nexport default Drawer;\n"],"mappings":";;;;;;;;AAQA,MAAM,SAAS,MAAM,YAAyC,OAAO,QAAQ;CAC3E,MAAM,EACJ,SACA,YAAY,SACZ,OAAO,KACP,WAAW,MACX,iBAAiB,MACjB,WAAW,WACX,eAAe,MACf,SACA,WAAW,eACX,YACA,SAAS,KACT,QACA,QACA,WACA,WACA,OACA,aACE;CACJ,MAAM,CAAC,eAAe,oBAAoB,SAAS,QAAQ;CAE3D,MAAM,YAAY,aAAa,UADT,WAAW,cAAc,CACQ,WAAW,cAAc;CAChF,MAAM,MAAM,WAAW,WAAW,WAAW,GAAG,UAAU,GAAG,YAAY;CACzE,MAAM,MACJ,cAAc,SAAS,cAAc,WAAW,EAAE,QAAQ,MAAM,GAAG,EAAE,OAAO,MAAM;CACpF,MAAM,UAAU,OAAuB,KAAK;CAC5C,MAAM,mBAAmB,OAA2B,KAAK;CACzD,MAAM,UAAU,OAAO;AAGvB,iBAAgB;AACd,MAAI,CAAC,QAAS;AACd,mBAAiB,UAAU,SAAS;EAEpC,MAAM,iBAAiB,MAAqB;AAC1C,OAAI,EAAE,QAAQ,UAAU;AACtB,cAAU,EAAiC;AAC3C;;AAEF,OAAI,EAAE,QAAQ,SAAS,QAAQ,SAAS;IACtC,MAAM,YAAY,QAAQ,QAAQ,iBAChC,6EACD;AACD,QAAI,UAAU,WAAW,EAAG;IAC5B,MAAM,QAAQ,UAAU;IACxB,MAAM,OAAO,UAAU,UAAU,SAAS;AAC1C,QAAI,EAAE;SACA,SAAS,kBAAkB,OAAO;AAAE,QAAE,gBAAgB;AAAE,WAAK,OAAO;;eAEpE,SAAS,kBAAkB,MAAM;AAAE,OAAE,gBAAgB;AAAE,WAAM,OAAO;;;;AAI9E,WAAS,iBAAiB,WAAW,cAAc;AAEnD,8BAA4B;AAC1B,OAAI,QAAQ,SAAS;IACnB,MAAM,YAAY,QAAQ,QAAQ,iBAChC,6EACD;AACD,QAAI,UAAU,SAAS,EAAG,WAAU,GAAG,OAAO;;IAEhD;AAEF,eAAa;AACX,YAAS,oBAAoB,WAAW,cAAc;AACtD,oBAAiB,SAAS,OAAO;;IAElC,CAAC,SAAS,QAAQ,CAAC;AAEtB,QACE,oBAACA,iBAAD;EACE,eAAqB,iBAAiB,KAAK;EAC3C,cAAoB,iBAAiB,MAAM;EACnC;EACR,MAAM;EACN,eAAe;EACf,QAAQ;EACR,UAAU;EACV,gBAAgB,MAA8B;AAC5C,mBAAgB,WAAU,QAAQ,EAAE;;EAEtC,OAAO;YACP,oBAAC,OAAD;GAAU;GAAK,WAAW;GAAK,OAAO;IAAE,GAAG;IAAO,GAAG;IAAK;aACxD,oBAAC,eAAD;IACE,QAAQ;IACC;IACT,IAAI;IACJ,SAAS;IACT,YAAY,GAAG,UAAU;cACzB,qBAAC,OAAD;KACE,KAAK;KACL,WAAW,GAAG,UAAU;KACxB,MAAK;KACL,cAAW;KACX,mBAAiB,SAAS,UAAU,KAAA;KACpC,UAAU,MAAM,EAAE,iBAAiB;eANrC;MAOG,YACC,oBAAC,UAAD;OAAQ,MAAK;OAAS,WAAW,GAAG,UAAU;OAAc,SAAS;OAAS,cAAW;iBAAQ;OAExF,CAAA;MAEV,UAAU,oBAAC,OAAD;OAAK,WAAW,GAAG,UAAU;OAAW,IAAI;iBAAU;OAAa,CAAA;MAC9E,oBAAC,OAAD;OAAK,WAAW,GAAG,UAAU;OAAU;OAAe,CAAA;MACrD,UAAU,oBAAC,OAAD;OAAK,WAAW,GAAG,UAAU;iBAAY;OAAa,CAAA;MAC7D;;IACQ,CAAA;GACZ,CAAA;EACE,CAAA;EAEZ;AAEF,OAAO,cAAc"}
1
+ {"version":3,"file":"drawer.js","names":["Overlay","Transition"],"sources":["../../src/drawer/drawer.tsx"],"sourcesContent":["import React, { useContext, useEffect, useId, useRef, useState } from 'react';\nimport classNames from 'classnames';\nimport Transition from '../transition';\nimport Overlay from '../overlay';\nimport { ConfigContext } from '../config-provider/config-context';\nimport { getPrefixCls } from '../_utils/general';\nimport { DrawerProps } from './types';\n\nconst Drawer = React.forwardRef<HTMLDivElement, DrawerProps>((props, ref) => {\n const {\n visible,\n placement = 'right',\n size = 256,\n closable = true,\n unmountOnClose = true,\n maskType = 'default',\n maskClosable = true,\n onClose,\n prefixCls: customisedCls,\n afterClose,\n zIndex = 1000,\n header,\n footer,\n className,\n maskStyle,\n style,\n children,\n } = props;\n const [drawerVisible, setDrawerVisible] = useState(visible);\n const configContext = useContext(ConfigContext);\n const prefixCls = getPrefixCls('drawer', configContext.prefixCls, customisedCls);\n const cls = classNames(prefixCls, className, `${prefixCls}_${placement}`);\n const sty: React.CSSProperties =\n placement === 'top' || placement === 'bottom' ? { height: size } : { width: size };\n const nodeRef = useRef<HTMLDivElement>(null);\n const previousFocusRef = useRef<HTMLElement | null>(null);\n const titleId = useId();\n\n // Focus trap + Escape key\n useEffect(() => {\n if (!visible) return;\n previousFocusRef.current = document.activeElement as HTMLElement;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n onClose?.(e as unknown as React.MouseEvent);\n return;\n }\n if (e.key === 'Tab' && nodeRef.current) {\n const focusable = nodeRef.current.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n if (focusable.length === 0) return;\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n if (e.shiftKey) {\n if (document.activeElement === first) { e.preventDefault(); last.focus(); }\n } else {\n if (document.activeElement === last) { e.preventDefault(); first.focus(); }\n }\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n\n requestAnimationFrame(() => {\n if (nodeRef.current) {\n const focusable = nodeRef.current.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n if (focusable.length > 0) focusable[0].focus();\n }\n });\n\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n previousFocusRef.current?.focus();\n };\n }, [visible, onClose]);\n\n return (\n <Overlay\n onEnter={(): void => setDrawerVisible(true)}\n onExit={(): void => setDrawerVisible(false)}\n zIndex={zIndex}\n type={maskType}\n unmountOnExit={unmountOnClose}\n isShow={visible}\n onExited={afterClose}\n clickCallback={(e: React.MouseEvent): void => {\n maskClosable && onClose ? onClose(e) : undefined;\n }}\n style={maskStyle}>\n <div ref={ref} className={cls} style={{ ...style, ...sty }}>\n <Transition\n appear={true}\n nodeRef={nodeRef}\n in={drawerVisible}\n timeout={0}\n unmountOnExit={false}\n classNames={`${prefixCls}__content_move`}>\n <div\n ref={nodeRef}\n className={`${prefixCls}__content`}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={header ? titleId : undefined}\n onClick={(e) => e.stopPropagation()}>\n {closable && (\n <button type=\"button\" className={`${prefixCls}__close-btn`} onClick={onClose} aria-label=\"Close\">\n ✕\n </button>\n )}\n {header && <div className={`${prefixCls}__header`} id={titleId}>{header}</div>}\n <div className={`${prefixCls}__body`}>{children}</div>\n {footer && <div className={`${prefixCls}__footer`}>{footer}</div>}\n </div>\n </Transition>\n </div>\n </Overlay>\n );\n});\n\nDrawer.displayName = 'Drawer';\n\nexport default Drawer;\n"],"mappings":";;;;;;;;AAQA,MAAM,SAAS,MAAM,YAAyC,OAAO,QAAQ;CAC3E,MAAM,EACJ,SACA,YAAY,SACZ,OAAO,KACP,WAAW,MACX,iBAAiB,MACjB,WAAW,WACX,eAAe,MACf,SACA,WAAW,eACX,YACA,SAAS,KACT,QACA,QACA,WACA,WACA,OACA,aACE;CACJ,MAAM,CAAC,eAAe,oBAAoB,SAAS,QAAQ;CAE3D,MAAM,YAAY,aAAa,UADT,WAAW,cAAc,CACQ,WAAW,cAAc;CAChF,MAAM,MAAM,WAAW,WAAW,WAAW,GAAG,UAAU,GAAG,YAAY;CACzE,MAAM,MACJ,cAAc,SAAS,cAAc,WAAW,EAAE,QAAQ,MAAM,GAAG,EAAE,OAAO,MAAM;CACpF,MAAM,UAAU,OAAuB,KAAK;CAC5C,MAAM,mBAAmB,OAA2B,KAAK;CACzD,MAAM,UAAU,OAAO;AAGvB,iBAAgB;AACd,MAAI,CAAC,QAAS;AACd,mBAAiB,UAAU,SAAS;EAEpC,MAAM,iBAAiB,MAAqB;AAC1C,OAAI,EAAE,QAAQ,UAAU;AACtB,cAAU,EAAiC;AAC3C;;AAEF,OAAI,EAAE,QAAQ,SAAS,QAAQ,SAAS;IACtC,MAAM,YAAY,QAAQ,QAAQ,iBAChC,6EACD;AACD,QAAI,UAAU,WAAW,EAAG;IAC5B,MAAM,QAAQ,UAAU;IACxB,MAAM,OAAO,UAAU,UAAU,SAAS;AAC1C,QAAI,EAAE;SACA,SAAS,kBAAkB,OAAO;AAAE,QAAE,gBAAgB;AAAE,WAAK,OAAO;;eAEpE,SAAS,kBAAkB,MAAM;AAAE,OAAE,gBAAgB;AAAE,WAAM,OAAO;;;;AAI9E,WAAS,iBAAiB,WAAW,cAAc;AAEnD,8BAA4B;AAC1B,OAAI,QAAQ,SAAS;IACnB,MAAM,YAAY,QAAQ,QAAQ,iBAChC,6EACD;AACD,QAAI,UAAU,SAAS,EAAG,WAAU,GAAG,OAAO;;IAEhD;AAEF,eAAa;AACX,YAAS,oBAAoB,WAAW,cAAc;AACtD,oBAAiB,SAAS,OAAO;;IAElC,CAAC,SAAS,QAAQ,CAAC;AAEtB,QACE,oBAACA,iBAAD;EACE,eAAqB,iBAAiB,KAAK;EAC3C,cAAoB,iBAAiB,MAAM;EACnC;EACR,MAAM;EACN,eAAe;EACf,QAAQ;EACR,UAAU;EACV,gBAAgB,MAA8B;AAC5C,mBAAgB,WAAU,QAAQ,EAAE;;EAEtC,OAAO;YACP,oBAAC,OAAD;GAAU;GAAK,WAAW;GAAK,OAAO;IAAE,GAAG;IAAO,GAAG;IAAK;aACxD,oBAACC,oBAAD;IACE,QAAQ;IACC;IACT,IAAI;IACJ,SAAS;IACT,eAAe;IACf,YAAY,GAAG,UAAU;cACzB,qBAAC,OAAD;KACE,KAAK;KACL,WAAW,GAAG,UAAU;KACxB,MAAK;KACL,cAAW;KACX,mBAAiB,SAAS,UAAU,KAAA;KACpC,UAAU,MAAM,EAAE,iBAAiB;eANrC;MAOG,YACC,oBAAC,UAAD;OAAQ,MAAK;OAAS,WAAW,GAAG,UAAU;OAAc,SAAS;OAAS,cAAW;iBAAQ;OAExF,CAAA;MAEV,UAAU,oBAAC,OAAD;OAAK,WAAW,GAAG,UAAU;OAAW,IAAI;iBAAU;OAAa,CAAA;MAC9E,oBAAC,OAAD;OAAK,WAAW,GAAG,UAAU;OAAU;OAAe,CAAA;MACrD,UAAU,oBAAC,OAAD;OAAK,WAAW,GAAG,UAAU;iBAAY;OAAa,CAAA;MAC7D;;IACK,CAAA;GACT,CAAA;EACE,CAAA;EAEZ;AAEF,OAAO,cAAc"}
@@ -1,10 +1,10 @@
1
1
  import { ConfigContext } from "../config-provider/config-context.js";
2
2
  import { getPrefixCls } from "../_utils/general.js";
3
3
  import { CheckCircle, CloseCircle, InfoCircle, LoadingCircle, WarningCircle } from "../_utils/components.js";
4
+ import transition_default from "../transition/index.js";
4
5
  import React, { useContext, useEffect, useRef, useState } from "react";
5
6
  import classNames from "classnames";
6
7
  import { jsx, jsxs } from "react/jsx-runtime";
7
- import { CSSTransition } from "react-transition-group";
8
8
  //#region src/message/message.tsx
9
9
  const Message = (props) => {
10
10
  const { type, icon, content, duration, willUnmount, extra, className, style, prefixCls: customisedCls } = props;
@@ -49,11 +49,12 @@ const Message = (props) => {
49
49
  window.clearTimeout(timer);
50
50
  };
51
51
  }, [duration, willUnmount]);
52
- return /* @__PURE__ */ jsx(CSSTransition, {
52
+ return /* @__PURE__ */ jsx(transition_default, {
53
53
  nodeRef: ref,
54
54
  in: visible,
55
55
  appear: true,
56
56
  timeout: 0,
57
+ unmountOnExit: false,
57
58
  classNames: `${prefixCls}_fade-slide`,
58
59
  children: /* @__PURE__ */ jsxs("div", {
59
60
  role: "alert",
@@ -1 +1 @@
1
- {"version":3,"file":"message.js","names":[],"sources":["../../src/message/message.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState, useContext } from 'react';\nimport classNames from 'classnames';\nimport { CSSTransition } from 'react-transition-group';\nimport { ConfigContext } from '../config-provider/config-context';\nimport { getPrefixCls } from '../_utils/general';\nimport {\n CheckCircle,\n CloseCircle,\n InfoCircle,\n LoadingCircle,\n WarningCircle,\n} from '../_utils/components';\nimport { MessageProps } from './types';\n\nconst Message = (props: MessageProps): JSX.Element => {\n const {\n type,\n icon,\n content,\n duration,\n willUnmount,\n extra,\n className,\n style,\n prefixCls: customisedCls,\n } = props;\n const configContext = useContext(ConfigContext);\n const prefixCls = getPrefixCls('message', configContext.prefixCls, customisedCls);\n const cls = classNames(prefixCls, className);\n const ref = useRef<HTMLDivElement | null>(null);\n const [visible, setVisible] = useState(true);\n\n const renderIcon = (): React.ReactNode => {\n if (React.isValidElement(icon)) {\n return icon;\n } else if (typeof type === 'string') {\n switch (type) {\n case 'success':\n return <CheckCircle size={16} className={`${prefixCls}__icon`} />;\n case 'info':\n return <InfoCircle size={16} className={`${prefixCls}__icon`} />;\n case 'warning':\n return <WarningCircle size={16} className={`${prefixCls}__icon`} />;\n case 'error':\n return <CloseCircle size={16} className={`${prefixCls}__icon`} />;\n case 'loading':\n return (\n <LoadingCircle\n size={16}\n className={classNames(`${prefixCls}__icon`, {\n [`${prefixCls}__icon_loading`]: type === 'loading',\n })}\n />\n );\n }\n }\n\n return null;\n };\n\n useEffect(() => {\n const node = ref.current;\n const height = (node && node.offsetHeight) || 0;\n const timer = window.setTimeout(() => {\n setVisible(false);\n willUnmount(height);\n }, duration);\n\n return (): void => {\n window.clearTimeout(timer);\n };\n }, [duration, willUnmount]);\n\n return (\n <CSSTransition nodeRef={ref} in={visible} appear={true} timeout={0} classNames={`${prefixCls}_fade-slide`}>\n <div role=\"alert\" className={cls} style={style} ref={ref}>\n {renderIcon()}\n <span className={`${prefixCls}__content`}>{content}</span>\n {extra && <div className={`${prefixCls}__extra`}>{extra}</div>}\n </div>\n </CSSTransition>\n );\n};\n\nMessage.displayName = 'Message';\n\nexport default Message;\n"],"mappings":";;;;;;;;AAcA,MAAM,WAAW,UAAqC;CACpD,MAAM,EACJ,MACA,MACA,SACA,UACA,aACA,OACA,WACA,OACA,WAAW,kBACT;CAEJ,MAAM,YAAY,aAAa,WADT,WAAW,cAAc,CACS,WAAW,cAAc;CACjF,MAAM,MAAM,WAAW,WAAW,UAAU;CAC5C,MAAM,MAAM,OAA8B,KAAK;CAC/C,MAAM,CAAC,SAAS,cAAc,SAAS,KAAK;CAE5C,MAAM,mBAAoC;AACxC,MAAI,MAAM,eAAe,KAAK,CAC5B,QAAO;WACE,OAAO,SAAS,SACzB,SAAQ,MAAR;GACE,KAAK,UACH,QAAO,oBAAC,aAAD;IAAa,MAAM;IAAI,WAAW,GAAG,UAAU;IAAW,CAAA;GACnE,KAAK,OACH,QAAO,oBAAC,YAAD;IAAY,MAAM;IAAI,WAAW,GAAG,UAAU;IAAW,CAAA;GAClE,KAAK,UACH,QAAO,oBAAC,eAAD;IAAe,MAAM;IAAI,WAAW,GAAG,UAAU;IAAW,CAAA;GACrE,KAAK,QACH,QAAO,oBAAC,aAAD;IAAa,MAAM;IAAI,WAAW,GAAG,UAAU;IAAW,CAAA;GACnE,KAAK,UACH,QACE,oBAAC,eAAD;IACE,MAAM;IACN,WAAW,WAAW,GAAG,UAAU,SAAS,GACzC,GAAG,UAAU,kBAAkB,SAAS,WAC1C,CAAC;IACF,CAAA;;AAKV,SAAO;;AAGT,iBAAgB;EACd,MAAM,OAAO,IAAI;EACjB,MAAM,SAAU,QAAQ,KAAK,gBAAiB;EAC9C,MAAM,QAAQ,OAAO,iBAAiB;AACpC,cAAW,MAAM;AACjB,eAAY,OAAO;KAClB,SAAS;AAEZ,eAAmB;AACjB,UAAO,aAAa,MAAM;;IAE3B,CAAC,UAAU,YAAY,CAAC;AAE3B,QACE,oBAAC,eAAD;EAAe,SAAS;EAAK,IAAI;EAAS,QAAQ;EAAM,SAAS;EAAG,YAAY,GAAG,UAAU;YAC3F,qBAAC,OAAD;GAAK,MAAK;GAAQ,WAAW;GAAY;GAAY;aAArD;IACG,YAAY;IACb,oBAAC,QAAD;KAAM,WAAW,GAAG,UAAU;eAAa;KAAe,CAAA;IACzD,SAAS,oBAAC,OAAD;KAAK,WAAW,GAAG,UAAU;eAAW;KAAY,CAAA;IAC1D;;EACQ,CAAA;;AAIpB,QAAQ,cAAc"}
1
+ {"version":3,"file":"message.js","names":["Transition"],"sources":["../../src/message/message.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState, useContext } from 'react';\nimport classNames from 'classnames';\nimport Transition from '../transition';\nimport { ConfigContext } from '../config-provider/config-context';\nimport { getPrefixCls } from '../_utils/general';\nimport {\n CheckCircle,\n CloseCircle,\n InfoCircle,\n LoadingCircle,\n WarningCircle,\n} from '../_utils/components';\nimport { MessageProps } from './types';\n\nconst Message = (props: MessageProps): JSX.Element => {\n const {\n type,\n icon,\n content,\n duration,\n willUnmount,\n extra,\n className,\n style,\n prefixCls: customisedCls,\n } = props;\n const configContext = useContext(ConfigContext);\n const prefixCls = getPrefixCls('message', configContext.prefixCls, customisedCls);\n const cls = classNames(prefixCls, className);\n const ref = useRef<HTMLDivElement | null>(null);\n const [visible, setVisible] = useState(true);\n\n const renderIcon = (): React.ReactNode => {\n if (React.isValidElement(icon)) {\n return icon;\n } else if (typeof type === 'string') {\n switch (type) {\n case 'success':\n return <CheckCircle size={16} className={`${prefixCls}__icon`} />;\n case 'info':\n return <InfoCircle size={16} className={`${prefixCls}__icon`} />;\n case 'warning':\n return <WarningCircle size={16} className={`${prefixCls}__icon`} />;\n case 'error':\n return <CloseCircle size={16} className={`${prefixCls}__icon`} />;\n case 'loading':\n return (\n <LoadingCircle\n size={16}\n className={classNames(`${prefixCls}__icon`, {\n [`${prefixCls}__icon_loading`]: type === 'loading',\n })}\n />\n );\n }\n }\n\n return null;\n };\n\n useEffect(() => {\n const node = ref.current;\n const height = (node && node.offsetHeight) || 0;\n const timer = window.setTimeout(() => {\n setVisible(false);\n willUnmount(height);\n }, duration);\n\n return (): void => {\n window.clearTimeout(timer);\n };\n }, [duration, willUnmount]);\n\n return (\n <Transition nodeRef={ref} in={visible} appear={true} timeout={0} unmountOnExit={false} classNames={`${prefixCls}_fade-slide`}>\n <div role=\"alert\" className={cls} style={style} ref={ref}>\n {renderIcon()}\n <span className={`${prefixCls}__content`}>{content}</span>\n {extra && <div className={`${prefixCls}__extra`}>{extra}</div>}\n </div>\n </Transition>\n );\n};\n\nMessage.displayName = 'Message';\n\nexport default Message;\n"],"mappings":";;;;;;;;AAcA,MAAM,WAAW,UAAqC;CACpD,MAAM,EACJ,MACA,MACA,SACA,UACA,aACA,OACA,WACA,OACA,WAAW,kBACT;CAEJ,MAAM,YAAY,aAAa,WADT,WAAW,cAAc,CACS,WAAW,cAAc;CACjF,MAAM,MAAM,WAAW,WAAW,UAAU;CAC5C,MAAM,MAAM,OAA8B,KAAK;CAC/C,MAAM,CAAC,SAAS,cAAc,SAAS,KAAK;CAE5C,MAAM,mBAAoC;AACxC,MAAI,MAAM,eAAe,KAAK,CAC5B,QAAO;WACE,OAAO,SAAS,SACzB,SAAQ,MAAR;GACE,KAAK,UACH,QAAO,oBAAC,aAAD;IAAa,MAAM;IAAI,WAAW,GAAG,UAAU;IAAW,CAAA;GACnE,KAAK,OACH,QAAO,oBAAC,YAAD;IAAY,MAAM;IAAI,WAAW,GAAG,UAAU;IAAW,CAAA;GAClE,KAAK,UACH,QAAO,oBAAC,eAAD;IAAe,MAAM;IAAI,WAAW,GAAG,UAAU;IAAW,CAAA;GACrE,KAAK,QACH,QAAO,oBAAC,aAAD;IAAa,MAAM;IAAI,WAAW,GAAG,UAAU;IAAW,CAAA;GACnE,KAAK,UACH,QACE,oBAAC,eAAD;IACE,MAAM;IACN,WAAW,WAAW,GAAG,UAAU,SAAS,GACzC,GAAG,UAAU,kBAAkB,SAAS,WAC1C,CAAC;IACF,CAAA;;AAKV,SAAO;;AAGT,iBAAgB;EACd,MAAM,OAAO,IAAI;EACjB,MAAM,SAAU,QAAQ,KAAK,gBAAiB;EAC9C,MAAM,QAAQ,OAAO,iBAAiB;AACpC,cAAW,MAAM;AACjB,eAAY,OAAO;KAClB,SAAS;AAEZ,eAAmB;AACjB,UAAO,aAAa,MAAM;;IAE3B,CAAC,UAAU,YAAY,CAAC;AAE3B,QACE,oBAACA,oBAAD;EAAY,SAAS;EAAK,IAAI;EAAS,QAAQ;EAAM,SAAS;EAAG,eAAe;EAAO,YAAY,GAAG,UAAU;YAC9G,qBAAC,OAAD;GAAK,MAAK;GAAQ,WAAW;GAAY;GAAY;aAArD;IACG,YAAY;IACb,oBAAC,QAAD;KAAM,WAAW,GAAG,UAAU;eAAa;KAAe,CAAA;IACzD,SAAS,oBAAC,OAAD;KAAK,WAAW,GAAG,UAAU;eAAW;KAAY,CAAA;IAC1D;;EACK,CAAA;;AAIjB,QAAQ,cAAc"}
package/es/modal/modal.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { ConfigContext } from "../config-provider/config-context.js";
2
2
  import { getPrefixCls } from "../_utils/general.js";
3
+ import transition_default from "../transition/index.js";
3
4
  import Button from "../button/button.js";
4
5
  import { useLocale } from "../_utils/use-locale.js";
5
6
  import overlay_default from "../overlay/index.js";
@@ -7,7 +8,6 @@ import Flex from "../flex/flex.js";
7
8
  import React, { useContext, useEffect, useId, useRef, useState } from "react";
8
9
  import classNames from "classnames";
9
10
  import { jsx, jsxs } from "react/jsx-runtime";
10
- import { CSSTransition } from "react-transition-group";
11
11
  //#region src/modal/modal.tsx
12
12
  const Modal = React.forwardRef((props, ref) => {
13
13
  const locale = useLocale();
@@ -99,11 +99,12 @@ const Modal = React.forwardRef((props, ref) => {
99
99
  width,
100
100
  ...style
101
101
  },
102
- children: /* @__PURE__ */ jsx(CSSTransition, {
102
+ children: /* @__PURE__ */ jsx(transition_default, {
103
103
  appear: true,
104
104
  nodeRef,
105
105
  in: modalVisible,
106
106
  classNames: `${prefixCls}__content_${animation}`,
107
+ unmountOnExit: false,
107
108
  timeout: 0,
108
109
  children: /* @__PURE__ */ jsxs("div", {
109
110
  ref: nodeRef,
@@ -1 +1 @@
1
- {"version":3,"file":"modal.js","names":["Overlay"],"sources":["../../src/modal/modal.tsx"],"sourcesContent":["import React, { useContext, useEffect, useId, useRef, useState } from 'react';\nimport classNames from 'classnames';\nimport { CSSTransition } from 'react-transition-group';\nimport Overlay from '../overlay';\nimport Button from '../button/button';\nimport Flex from '../flex/flex';\nimport { ConfigContext } from '../config-provider/config-context';\nimport { getPrefixCls } from '../_utils/general';\nimport { useLocale } from '../_utils/use-locale';\nimport { ModalProps } from './types';\n\nconst Modal = React.forwardRef<HTMLDivElement, ModalProps>((props, ref) => {\n const locale = useLocale();\n const {\n visible = false,\n width = 520,\n centered = false,\n closable = true,\n unmountOnClose = true,\n maskType = 'default',\n maskClosable = true,\n confirmText = locale.Modal.okText,\n cancelText = locale.Modal.cancelText,\n confirmLoading = false,\n animation = 'slide',\n zIndex = 1000,\n onConfirm,\n onCancel: onCancelProp,\n onClose: onCloseProp,\n top,\n header,\n footer,\n afterClose,\n confirmButtonProps,\n cancelButtonProps,\n className,\n children,\n style,\n maskStyle,\n headerStyle,\n bodyStyle,\n footerStyle,\n prefixCls: customisedCls,\n } = props;\n const onCancel = onCloseProp ?? onCancelProp;\n const [modalVisible, setModalVisible] = useState(visible);\n const configContext = useContext(ConfigContext);\n const prefixCls = getPrefixCls('modal', configContext.prefixCls, customisedCls);\n const cls = classNames(prefixCls, className, { [`${prefixCls}_centered`]: centered });\n const nodeRef = useRef<HTMLDivElement>(null);\n const previousFocusRef = useRef<HTMLElement | null>(null);\n const titleId = useId();\n\n // Focus trap + Escape key\n useEffect(() => {\n if (!visible) return;\n previousFocusRef.current = document.activeElement as HTMLElement;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n onCancel?.(e as unknown as React.MouseEvent);\n return;\n }\n if (e.key === 'Tab' && nodeRef.current) {\n const focusable = nodeRef.current.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n if (focusable.length === 0) return;\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n if (e.shiftKey) {\n if (document.activeElement === first) { e.preventDefault(); last.focus(); }\n } else {\n if (document.activeElement === last) { e.preventDefault(); first.focus(); }\n }\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n\n // Focus first focusable element\n requestAnimationFrame(() => {\n if (nodeRef.current) {\n const focusable = nodeRef.current.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n if (focusable.length > 0) focusable[0].focus();\n }\n });\n\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n previousFocusRef.current?.focus();\n };\n }, [visible, onCancel]);\n\n const renderFooter = (): React.ReactNode => {\n if (React.isValidElement(footer)) {\n return footer;\n } else if (footer === null) {\n return null;\n } else {\n return (\n <Flex gap=\"sm\" justify='end' className={`${prefixCls}__footer`} style={footerStyle}>\n <Button onClick={onCancel} className={`${prefixCls}__footer-btn`} {...cancelButtonProps}>\n {cancelText}\n </Button>\n <Button\n loading={confirmLoading}\n onClick={onConfirm}\n btnType=\"primary\"\n className={`${prefixCls}__footer-btn`}\n {...confirmButtonProps}>\n {confirmText}\n </Button>\n </Flex>\n );\n }\n };\n\n return (\n <Overlay\n onEnter={(): void => setModalVisible(true)}\n onExit={(): void => setModalVisible(false)}\n zIndex={zIndex}\n type={maskType}\n unmountOnExit={unmountOnClose}\n isShow={visible}\n onExited={afterClose}\n clickCallback={(e: React.MouseEvent): void => {\n maskClosable && onCancel ? onCancel(e) : undefined;\n }}\n style={maskStyle}>\n <div ref={ref} className={cls} style={{ top }}>\n <div style={{ width, ...style }}>\n <CSSTransition\n appear={true}\n nodeRef={nodeRef}\n in={modalVisible}\n classNames={`${prefixCls}__content_${animation}`}\n timeout={0}>\n <div\n ref={nodeRef}\n className={`${prefixCls}__content`}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={header ? titleId : undefined}\n onClick={(e): void => e.stopPropagation()}>\n {closable && (\n <button type=\"button\" className={`${prefixCls}__close-btn`} onClick={onCancel} aria-label=\"Close\">\n ✕\n </button>\n )}\n {header && (\n <div className={`${prefixCls}__header`} style={headerStyle}>\n <div className={`${prefixCls}__title`} id={titleId}>{header}</div>\n </div>\n )}\n <div className={`${prefixCls}__body`} style={bodyStyle}>\n {children}\n </div>\n {renderFooter()}\n </div>\n </CSSTransition>\n </div>\n </div>\n </Overlay>\n );\n});\n\nModal.displayName = 'Modal';\n\nexport default Modal;\n"],"mappings":"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"}
1
+ {"version":3,"file":"modal.js","names":["Overlay","Transition"],"sources":["../../src/modal/modal.tsx"],"sourcesContent":["import React, { useContext, useEffect, useId, useRef, useState } from 'react';\nimport classNames from 'classnames';\nimport Transition from '../transition';\nimport Overlay from '../overlay';\nimport Button from '../button/button';\nimport Flex from '../flex/flex';\nimport { ConfigContext } from '../config-provider/config-context';\nimport { getPrefixCls } from '../_utils/general';\nimport { useLocale } from '../_utils/use-locale';\nimport { ModalProps } from './types';\n\nconst Modal = React.forwardRef<HTMLDivElement, ModalProps>((props, ref) => {\n const locale = useLocale();\n const {\n visible = false,\n width = 520,\n centered = false,\n closable = true,\n unmountOnClose = true,\n maskType = 'default',\n maskClosable = true,\n confirmText = locale.Modal.okText,\n cancelText = locale.Modal.cancelText,\n confirmLoading = false,\n animation = 'slide',\n zIndex = 1000,\n onConfirm,\n onCancel: onCancelProp,\n onClose: onCloseProp,\n top,\n header,\n footer,\n afterClose,\n confirmButtonProps,\n cancelButtonProps,\n className,\n children,\n style,\n maskStyle,\n headerStyle,\n bodyStyle,\n footerStyle,\n prefixCls: customisedCls,\n } = props;\n const onCancel = onCloseProp ?? onCancelProp;\n const [modalVisible, setModalVisible] = useState(visible);\n const configContext = useContext(ConfigContext);\n const prefixCls = getPrefixCls('modal', configContext.prefixCls, customisedCls);\n const cls = classNames(prefixCls, className, { [`${prefixCls}_centered`]: centered });\n const nodeRef = useRef<HTMLDivElement>(null);\n const previousFocusRef = useRef<HTMLElement | null>(null);\n const titleId = useId();\n\n // Focus trap + Escape key\n useEffect(() => {\n if (!visible) return;\n previousFocusRef.current = document.activeElement as HTMLElement;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n onCancel?.(e as unknown as React.MouseEvent);\n return;\n }\n if (e.key === 'Tab' && nodeRef.current) {\n const focusable = nodeRef.current.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n if (focusable.length === 0) return;\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n if (e.shiftKey) {\n if (document.activeElement === first) { e.preventDefault(); last.focus(); }\n } else {\n if (document.activeElement === last) { e.preventDefault(); first.focus(); }\n }\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n\n // Focus first focusable element\n requestAnimationFrame(() => {\n if (nodeRef.current) {\n const focusable = nodeRef.current.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n if (focusable.length > 0) focusable[0].focus();\n }\n });\n\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n previousFocusRef.current?.focus();\n };\n }, [visible, onCancel]);\n\n const renderFooter = (): React.ReactNode => {\n if (React.isValidElement(footer)) {\n return footer;\n } else if (footer === null) {\n return null;\n } else {\n return (\n <Flex gap=\"sm\" justify='end' className={`${prefixCls}__footer`} style={footerStyle}>\n <Button onClick={onCancel} className={`${prefixCls}__footer-btn`} {...cancelButtonProps}>\n {cancelText}\n </Button>\n <Button\n loading={confirmLoading}\n onClick={onConfirm}\n btnType=\"primary\"\n className={`${prefixCls}__footer-btn`}\n {...confirmButtonProps}>\n {confirmText}\n </Button>\n </Flex>\n );\n }\n };\n\n return (\n <Overlay\n onEnter={(): void => setModalVisible(true)}\n onExit={(): void => setModalVisible(false)}\n zIndex={zIndex}\n type={maskType}\n unmountOnExit={unmountOnClose}\n isShow={visible}\n onExited={afterClose}\n clickCallback={(e: React.MouseEvent): void => {\n maskClosable && onCancel ? onCancel(e) : undefined;\n }}\n style={maskStyle}>\n <div ref={ref} className={cls} style={{ top }}>\n <div style={{ width, ...style }}>\n <Transition\n appear={true}\n nodeRef={nodeRef}\n in={modalVisible}\n classNames={`${prefixCls}__content_${animation}`}\n unmountOnExit={false}\n timeout={0}>\n <div\n ref={nodeRef}\n className={`${prefixCls}__content`}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={header ? titleId : undefined}\n onClick={(e): void => e.stopPropagation()}>\n {closable && (\n <button type=\"button\" className={`${prefixCls}__close-btn`} onClick={onCancel} aria-label=\"Close\">\n ✕\n </button>\n )}\n {header && (\n <div className={`${prefixCls}__header`} style={headerStyle}>\n <div className={`${prefixCls}__title`} id={titleId}>{header}</div>\n </div>\n )}\n <div className={`${prefixCls}__body`} style={bodyStyle}>\n {children}\n </div>\n {renderFooter()}\n </div>\n </Transition>\n </div>\n </div>\n </Overlay>\n );\n});\n\nModal.displayName = 'Modal';\n\nexport default Modal;\n"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  import { ConfigContext } from "../config-provider/config-context.js";
2
2
  import { getPrefixCls } from "../_utils/general.js";
3
+ import transition_default from "../transition/index.js";
3
4
  import portal_default from "../portal/index.js";
4
5
  import { useContext, useEffect, useRef } from "react";
5
6
  import classNames from "classnames";
6
7
  import { jsx } from "react/jsx-runtime";
7
- import { CSSTransition } from "react-transition-group";
8
8
  //#region src/overlay/overlay.tsx
9
9
  let scrollLockCount = 0;
10
10
  const Overlay = (props) => {
@@ -27,7 +27,7 @@ const Overlay = (props) => {
27
27
  }
28
28
  };
29
29
  }, [isShow]);
30
- return /* @__PURE__ */ jsx(portal_default, { children: /* @__PURE__ */ jsx(CSSTransition, {
30
+ return /* @__PURE__ */ jsx(portal_default, { children: /* @__PURE__ */ jsx(transition_default, {
31
31
  appear: true,
32
32
  nodeRef,
33
33
  onEnter,
@@ -1 +1 @@
1
- {"version":3,"file":"overlay.js","names":["Portal"],"sources":["../../src/overlay/overlay.tsx"],"sourcesContent":["import { useContext, useEffect, useRef } from 'react';\nimport classNames from 'classnames';\nimport Portal from '../portal';\nimport { CSSTransition } from 'react-transition-group';\nimport { ConfigContext } from '../config-provider/config-context';\nimport { getPrefixCls } from '../_utils/general';\nimport { OverlayProps } from './types';\n\nlet scrollLockCount = 0;\n\nconst Overlay = (props: OverlayProps): JSX.Element => {\n const {\n isShow = false,\n blurred = false,\n unmountOnExit = true,\n zIndex = 1000,\n type = 'default',\n clickCallback,\n onEnter,\n onEntered,\n onExit,\n onExited,\n children,\n style,\n prefixCls: customisedCls,\n } = props;\n const configContext = useContext(ConfigContext);\n const prefixCls = getPrefixCls('overlay', configContext.prefixCls, customisedCls);\n const cls = classNames(prefixCls, `${prefixCls}_${type}`, { [`${prefixCls}_blurred`]: blurred });\n const nodeRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (isShow) {\n scrollLockCount++;\n document.body.style.overflow = 'hidden';\n }\n return () => {\n if (isShow) {\n scrollLockCount--;\n if (scrollLockCount <= 0) {\n scrollLockCount = 0;\n document.body.style.overflow = '';\n }\n }\n };\n }, [isShow]);\n\n return (\n <Portal>\n <CSSTransition\n appear={true}\n nodeRef={nodeRef}\n onEnter={onEnter}\n onEntered={onEntered}\n onExit={onExit}\n onExited={onExited}\n in={isShow}\n mountOnEnter={true}\n unmountOnExit={unmountOnExit}\n classNames={`${prefixCls}_fade`}\n timeout={{ exit: 300, enter: 0 }}>\n <div ref={nodeRef} tabIndex={-1} className={cls} onClick={clickCallback} style={{ zIndex, ...style }}>\n {children}\n </div>\n </CSSTransition>\n </Portal>\n );\n};\n\nOverlay.displayName = 'Overlay';\n\nexport default Overlay;\n"],"mappings":";;;;;;;;AAQA,IAAI,kBAAkB;AAEtB,MAAM,WAAW,UAAqC;CACpD,MAAM,EACJ,SAAS,OACT,UAAU,OACV,gBAAgB,MAChB,SAAS,KACT,OAAO,WACP,eACA,SACA,WACA,QACA,UACA,UACA,OACA,WAAW,kBACT;CAEJ,MAAM,YAAY,aAAa,WADT,WAAW,cAAc,CACS,WAAW,cAAc;CACjF,MAAM,MAAM,WAAW,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,GAAG,UAAU,YAAY,SAAS,CAAC;CAChG,MAAM,UAAU,OAAuB,KAAK;AAE5C,iBAAgB;AACd,MAAI,QAAQ;AACV;AACA,YAAS,KAAK,MAAM,WAAW;;AAEjC,eAAa;AACX,OAAI,QAAQ;AACV;AACA,QAAI,mBAAmB,GAAG;AACxB,uBAAkB;AAClB,cAAS,KAAK,MAAM,WAAW;;;;IAIpC,CAAC,OAAO,CAAC;AAEZ,QACE,oBAACA,gBAAD,EAAA,UACE,oBAAC,eAAD;EACE,QAAQ;EACC;EACA;EACE;EACH;EACE;EACV,IAAI;EACJ,cAAc;EACC;EACf,YAAY,GAAG,UAAU;EACzB,SAAS;GAAE,MAAM;GAAK,OAAO;GAAG;YAChC,oBAAC,OAAD;GAAK,KAAK;GAAS,UAAU;GAAI,WAAW;GAAK,SAAS;GAAe,OAAO;IAAE;IAAQ,GAAG;IAAO;GACjG;GACG,CAAA;EACQ,CAAA,EACT,CAAA;;AAIb,QAAQ,cAAc"}
1
+ {"version":3,"file":"overlay.js","names":["Portal","Transition"],"sources":["../../src/overlay/overlay.tsx"],"sourcesContent":["import { useContext, useEffect, useRef } from 'react';\nimport classNames from 'classnames';\nimport Portal from '../portal';\nimport Transition from '../transition';\nimport { ConfigContext } from '../config-provider/config-context';\nimport { getPrefixCls } from '../_utils/general';\nimport { OverlayProps } from './types';\n\nlet scrollLockCount = 0;\n\nconst Overlay = (props: OverlayProps): JSX.Element => {\n const {\n isShow = false,\n blurred = false,\n unmountOnExit = true,\n zIndex = 1000,\n type = 'default',\n clickCallback,\n onEnter,\n onEntered,\n onExit,\n onExited,\n children,\n style,\n prefixCls: customisedCls,\n } = props;\n const configContext = useContext(ConfigContext);\n const prefixCls = getPrefixCls('overlay', configContext.prefixCls, customisedCls);\n const cls = classNames(prefixCls, `${prefixCls}_${type}`, { [`${prefixCls}_blurred`]: blurred });\n const nodeRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (isShow) {\n scrollLockCount++;\n document.body.style.overflow = 'hidden';\n }\n return () => {\n if (isShow) {\n scrollLockCount--;\n if (scrollLockCount <= 0) {\n scrollLockCount = 0;\n document.body.style.overflow = '';\n }\n }\n };\n }, [isShow]);\n\n return (\n <Portal>\n <Transition\n appear={true}\n nodeRef={nodeRef}\n onEnter={onEnter}\n onEntered={onEntered}\n onExit={onExit}\n onExited={onExited}\n in={isShow}\n mountOnEnter={true}\n unmountOnExit={unmountOnExit}\n classNames={`${prefixCls}_fade`}\n timeout={{ exit: 300, enter: 0 }}>\n <div ref={nodeRef} tabIndex={-1} className={cls} onClick={clickCallback} style={{ zIndex, ...style }}>\n {children}\n </div>\n </Transition>\n </Portal>\n );\n};\n\nOverlay.displayName = 'Overlay';\n\nexport default Overlay;\n"],"mappings":";;;;;;;;AAQA,IAAI,kBAAkB;AAEtB,MAAM,WAAW,UAAqC;CACpD,MAAM,EACJ,SAAS,OACT,UAAU,OACV,gBAAgB,MAChB,SAAS,KACT,OAAO,WACP,eACA,SACA,WACA,QACA,UACA,UACA,OACA,WAAW,kBACT;CAEJ,MAAM,YAAY,aAAa,WADT,WAAW,cAAc,CACS,WAAW,cAAc;CACjF,MAAM,MAAM,WAAW,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,GAAG,UAAU,YAAY,SAAS,CAAC;CAChG,MAAM,UAAU,OAAuB,KAAK;AAE5C,iBAAgB;AACd,MAAI,QAAQ;AACV;AACA,YAAS,KAAK,MAAM,WAAW;;AAEjC,eAAa;AACX,OAAI,QAAQ;AACV;AACA,QAAI,mBAAmB,GAAG;AACxB,uBAAkB;AAClB,cAAS,KAAK,MAAM,WAAW;;;;IAIpC,CAAC,OAAO,CAAC;AAEZ,QACE,oBAACA,gBAAD,EAAA,UACE,oBAACC,oBAAD;EACE,QAAQ;EACC;EACA;EACE;EACH;EACE;EACV,IAAI;EACJ,cAAc;EACC;EACf,YAAY,GAAG,UAAU;EACzB,SAAS;GAAE,MAAM;GAAK,OAAO;GAAG;YAChC,oBAAC,OAAD;GAAK,KAAK;GAAS,UAAU;GAAI,WAAW;GAAK,SAAS;GAAe,OAAO;IAAE;IAAQ,GAAG;IAAO;GACjG;GACG,CAAA;EACK,CAAA,EACN,CAAA;;AAIb,QAAQ,cAAc"}
@@ -1,5 +1,6 @@
1
1
  import '../style/base.css';
2
2
  import './style/index.css';
3
+ import "./use-transition.js";
3
4
  import Transition from "./transition.js";
4
5
  //#region src/transition/index.tsx
5
6
  var transition_default = Transition;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/transition/index.tsx"],"sourcesContent":["import Transition from './transition';\n\nexport type { AnimationName, TransitionProps } from './transition';\nexport default Transition;\n"],"mappings":";;AAGA,IAAA,qBAAe"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/transition/index.tsx"],"sourcesContent":["import Transition from './transition';\n\nexport type { AnimationName, TransitionProps } from './transition';\nexport { default as useTransition } from './use-transition';\nexport type { TransitionState, UseTransitionOptions, UseTransitionResult } from './use-transition';\nexport default Transition;\n"],"mappings":";;;AAKA,IAAA,qBAAe"}
@@ -1,16 +1,31 @@
1
1
  import React from "react";
2
- import { CSSTransitionProps } from "react-transition-group/CSSTransition";
3
2
 
4
3
  //#region src/transition/transition.d.ts
5
4
  type AnimationName = 'zoom-center-top' | 'zoom-center-bottom' | 'zoom-center-left' | 'zoom-center-right' | 'zoom-top-start' | 'zoom-top' | 'zoom-top-end' | 'zoom-bottom-start' | 'zoom-bottom' | 'zoom-bottom-end' | 'zoom-left-start' | 'zoom-left' | 'zoom-left-end' | 'zoom-right-start' | 'zoom-right' | 'zoom-right-end' | 'slide-up' | 'slide-down';
6
5
  type TransitionProps = {
7
- /** Animation prefix */prefix?: string; /** Preset animation name */
8
- animation?: AnimationName; /** Prevent the transition conflict with the inner component */
6
+ in?: boolean;
7
+ timeout?: number | {
8
+ enter: number;
9
+ exit: number;
10
+ };
11
+ appear?: boolean;
12
+ unmountOnExit?: boolean;
13
+ mountOnEnter?: boolean; /** Animation prefix */
14
+ prefix?: string; /** Preset animation name */
15
+ animation?: AnimationName; /** Custom class name base (overrides prefix + animation) */
16
+ classNames?: string; /** Prevent the transition conflict with the inner component */
9
17
  wrapper?: boolean;
18
+ nodeRef?: React.RefObject<HTMLElement | null>;
19
+ onEnter?: () => void;
20
+ onEntering?: () => void;
21
+ onEntered?: () => void;
22
+ onExit?: () => void;
23
+ onExiting?: () => void;
24
+ onExited?: () => void;
10
25
  children?: React.ReactNode;
11
- } & Partial<CSSTransitionProps<HTMLElement>>;
26
+ };
12
27
  declare const Transition: {
13
- (props: TransitionProps): React.ReactElement;
28
+ (props: TransitionProps): React.ReactElement | null;
14
29
  displayName: string;
15
30
  };
16
31
  //#endregion
@@ -1,18 +1,43 @@
1
- import "react";
1
+ import useTransition from "./use-transition.js";
2
+ import React from "react";
2
3
  import { jsx } from "react/jsx-runtime";
3
- import { CSSTransition } from "react-transition-group";
4
4
  //#region src/transition/transition.tsx
5
+ function getTransitionClasses(base, state) {
6
+ switch (state) {
7
+ case "enter": return `${base}-enter`;
8
+ case "entering": return `${base}-enter ${base}-enter-active`;
9
+ case "entered": return `${base}-enter-done`;
10
+ case "exit": return `${base}-exit`;
11
+ case "exiting": return `${base}-exit ${base}-exit-active`;
12
+ case "exited": return `${base}-exit-done`;
13
+ default: return "";
14
+ }
15
+ }
5
16
  const Transition = (props) => {
6
- const { timeout = 300, unmountOnExit = true, appear = true, prefix = "ty", animation, classNames, nodeRef, children, wrapper, ...otherProps } = props;
7
- return /* @__PURE__ */ jsx(CSSTransition, {
8
- ...otherProps,
17
+ const { in: inProp = false, timeout = 300, unmountOnExit = true, mountOnEnter, appear = true, prefix = "ty", animation, classNames: classNamesProp, nodeRef, children, wrapper, onEnter, onEntering, onEntered, onExit, onExiting, onExited } = props;
18
+ const { state, shouldMount } = useTransition({
19
+ in: inProp,
9
20
  timeout,
10
21
  appear,
11
22
  unmountOnExit,
12
- nodeRef,
13
- classNames: classNames ? classNames : `${prefix}-${animation}`,
14
- children: wrapper ? /* @__PURE__ */ jsx("div", { children }) : children
23
+ mountOnEnter,
24
+ onEnter,
25
+ onEntering,
26
+ onEntered,
27
+ onExit,
28
+ onExiting,
29
+ onExited,
30
+ nodeRef
15
31
  });
32
+ if (!shouldMount) return null;
33
+ const transitionClasses = getTransitionClasses(classNamesProp ? classNamesProp : `${prefix}-${animation}`, state);
34
+ const child = wrapper ? /* @__PURE__ */ jsx("div", { children }) : children;
35
+ if (React.isValidElement(child)) {
36
+ const existingClassName = child.props.className || "";
37
+ const mergedClassName = existingClassName ? `${existingClassName} ${transitionClasses}`.trim() : transitionClasses;
38
+ return React.cloneElement(child, { className: mergedClassName || void 0 });
39
+ }
40
+ return child;
16
41
  };
17
42
  Transition.displayName = "Transition";
18
43
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"transition.js","names":[],"sources":["../../src/transition/transition.tsx"],"sourcesContent":["import React from 'react';\nimport { CSSTransition } from 'react-transition-group';\nimport { CSSTransitionProps } from 'react-transition-group/CSSTransition';\n\nexport type AnimationName =\n | 'zoom-center-top'\n | 'zoom-center-bottom'\n | 'zoom-center-left'\n | 'zoom-center-right'\n | 'zoom-top-start'\n | 'zoom-top'\n | 'zoom-top-end'\n | 'zoom-bottom-start'\n | 'zoom-bottom'\n | 'zoom-bottom-end'\n | 'zoom-left-start'\n | 'zoom-left'\n | 'zoom-left-end'\n | 'zoom-right-start'\n | 'zoom-right'\n | 'zoom-right-end'\n | 'slide-up'\n | 'slide-down';\n\nexport type TransitionProps = {\n /** Animation prefix */\n prefix?: string;\n\n /** Preset animation name */\n animation?: AnimationName;\n\n /** Prevent the transition conflict with the inner component */\n wrapper?: boolean;\n children?: React.ReactNode;\n} & Partial<CSSTransitionProps<HTMLElement>>;\n\nconst Transition = (props: TransitionProps): React.ReactElement => {\n const {\n timeout = 300,\n unmountOnExit = true,\n appear = true,\n prefix = 'ty',\n animation,\n classNames,\n nodeRef,\n children,\n wrapper,\n ...otherProps\n } = props;\n\n return (\n <CSSTransition\n {...(otherProps as CSSTransitionProps<HTMLElement>)}\n timeout={timeout}\n appear={appear}\n unmountOnExit={unmountOnExit}\n nodeRef={nodeRef}\n classNames={classNames ? classNames : `${prefix}-${animation}`}>\n {wrapper ? <div>{children}</div> : (children as React.ReactElement)}\n </CSSTransition>\n );\n};\n\nTransition.displayName = 'Transition';\n\nexport default Transition;\n"],"mappings":";;;;AAoCA,MAAM,cAAc,UAA+C;CACjE,MAAM,EACJ,UAAU,KACV,gBAAgB,MAChB,SAAS,MACT,SAAS,MACT,WACA,YACA,SACA,UACA,SACA,GAAG,eACD;AAEJ,QACE,oBAAC,eAAD;EACE,GAAK;EACI;EACD;EACO;EACN;EACT,YAAY,aAAa,aAAa,GAAG,OAAO,GAAG;YAClD,UAAU,oBAAC,OAAD,EAAM,UAAe,CAAA,GAAI;EACtB,CAAA;;AAIpB,WAAW,cAAc"}
1
+ {"version":3,"file":"transition.js","names":[],"sources":["../../src/transition/transition.tsx"],"sourcesContent":["import React from 'react';\nimport useTransition, { TransitionState } from './use-transition';\n\nexport type AnimationName =\n | 'zoom-center-top'\n | 'zoom-center-bottom'\n | 'zoom-center-left'\n | 'zoom-center-right'\n | 'zoom-top-start'\n | 'zoom-top'\n | 'zoom-top-end'\n | 'zoom-bottom-start'\n | 'zoom-bottom'\n | 'zoom-bottom-end'\n | 'zoom-left-start'\n | 'zoom-left'\n | 'zoom-left-end'\n | 'zoom-right-start'\n | 'zoom-right'\n | 'zoom-right-end'\n | 'slide-up'\n | 'slide-down';\n\nexport type TransitionProps = {\n in?: boolean;\n timeout?: number | { enter: number; exit: number };\n appear?: boolean;\n unmountOnExit?: boolean;\n mountOnEnter?: boolean;\n\n /** Animation prefix */\n prefix?: string;\n\n /** Preset animation name */\n animation?: AnimationName;\n\n /** Custom class name base (overrides prefix + animation) */\n classNames?: string;\n\n /** Prevent the transition conflict with the inner component */\n wrapper?: boolean;\n\n nodeRef?: React.RefObject<HTMLElement | null>;\n\n onEnter?: () => void;\n onEntering?: () => void;\n onEntered?: () => void;\n onExit?: () => void;\n onExiting?: () => void;\n onExited?: () => void;\n\n children?: React.ReactNode;\n};\n\nfunction getTransitionClasses(base: string, state: TransitionState): string {\n switch (state) {\n case 'enter':\n return `${base}-enter`;\n case 'entering':\n return `${base}-enter ${base}-enter-active`;\n case 'entered':\n return `${base}-enter-done`;\n case 'exit':\n return `${base}-exit`;\n case 'exiting':\n return `${base}-exit ${base}-exit-active`;\n case 'exited':\n return `${base}-exit-done`;\n default:\n return '';\n }\n}\n\nconst Transition = (props: TransitionProps): React.ReactElement | null => {\n const {\n in: inProp = false,\n timeout = 300,\n unmountOnExit = true,\n mountOnEnter,\n appear = true,\n prefix = 'ty',\n animation,\n classNames: classNamesProp,\n nodeRef,\n children,\n wrapper,\n onEnter,\n onEntering,\n onEntered,\n onExit,\n onExiting,\n onExited,\n } = props;\n\n const { state, shouldMount } = useTransition({\n in: inProp,\n timeout,\n appear,\n unmountOnExit,\n mountOnEnter,\n onEnter,\n onEntering,\n onEntered,\n onExit,\n onExiting,\n onExited,\n nodeRef,\n });\n\n if (!shouldMount) {\n return null;\n }\n\n const base = classNamesProp ? classNamesProp : `${prefix}-${animation}`;\n const transitionClasses = getTransitionClasses(base, state);\n\n const child = wrapper ? <div>{children}</div> : children;\n\n if (React.isValidElement(child)) {\n const existingClassName = (child.props as { className?: string }).className || '';\n const mergedClassName = existingClassName\n ? `${existingClassName} ${transitionClasses}`.trim()\n : transitionClasses;\n\n return React.cloneElement(child as React.ReactElement<{ className?: string }>, {\n className: mergedClassName || undefined,\n });\n }\n\n return child as React.ReactElement;\n};\n\nTransition.displayName = 'Transition';\n\nexport default Transition;\n"],"mappings":";;;;AAsDA,SAAS,qBAAqB,MAAc,OAAgC;AAC1E,SAAQ,OAAR;EACE,KAAK,QACH,QAAO,GAAG,KAAK;EACjB,KAAK,WACH,QAAO,GAAG,KAAK,SAAS,KAAK;EAC/B,KAAK,UACH,QAAO,GAAG,KAAK;EACjB,KAAK,OACH,QAAO,GAAG,KAAK;EACjB,KAAK,UACH,QAAO,GAAG,KAAK,QAAQ,KAAK;EAC9B,KAAK,SACH,QAAO,GAAG,KAAK;EACjB,QACE,QAAO;;;AAIb,MAAM,cAAc,UAAsD;CACxE,MAAM,EACJ,IAAI,SAAS,OACb,UAAU,KACV,gBAAgB,MAChB,cACA,SAAS,MACT,SAAS,MACT,WACA,YAAY,gBACZ,SACA,UACA,SACA,SACA,YACA,WACA,QACA,WACA,aACE;CAEJ,MAAM,EAAE,OAAO,gBAAgB,cAAc;EAC3C,IAAI;EACJ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;AAEF,KAAI,CAAC,YACH,QAAO;CAIT,MAAM,oBAAoB,qBADb,iBAAiB,iBAAiB,GAAG,OAAO,GAAG,aACP,MAAM;CAE3D,MAAM,QAAQ,UAAU,oBAAC,OAAD,EAAM,UAAe,CAAA,GAAG;AAEhD,KAAI,MAAM,eAAe,MAAM,EAAE;EAC/B,MAAM,oBAAqB,MAAM,MAAiC,aAAa;EAC/E,MAAM,kBAAkB,oBACpB,GAAG,kBAAkB,GAAG,oBAAoB,MAAM,GAClD;AAEJ,SAAO,MAAM,aAAa,OAAqD,EAC7E,WAAW,mBAAmB,KAAA,GAC/B,CAAC;;AAGJ,QAAO;;AAGT,WAAW,cAAc"}
@@ -0,0 +1,137 @@
1
+ import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
2
+ //#region src/transition/use-transition.ts
3
+ function normalizeTimeout(timeout) {
4
+ if (timeout == null) return {
5
+ enter: 300,
6
+ exit: 300
7
+ };
8
+ if (typeof timeout === "number") return {
9
+ enter: timeout,
10
+ exit: timeout
11
+ };
12
+ return timeout;
13
+ }
14
+ function useTransition(options) {
15
+ const { in: inProp, timeout, appear = true, unmountOnExit = true, mountOnEnter = false, onEnter, onEntering, onEntered, onExit, onExiting, onExited, nodeRef } = options;
16
+ const normalizedTimeout = normalizeTimeout(timeout);
17
+ const getInitialState = () => {
18
+ if (inProp) return appear ? "enter" : "entered";
19
+ if (unmountOnExit || mountOnEnter) return "unmounted";
20
+ return "exited";
21
+ };
22
+ const [state, setState] = useState(getInitialState);
23
+ const rafRef = useRef(0);
24
+ const timerRef = useRef(0);
25
+ const transitionEndRef = useRef(null);
26
+ const initialMountRef = useRef(true);
27
+ const callbacksRef = useRef({
28
+ onEnter,
29
+ onEntering,
30
+ onEntered,
31
+ onExit,
32
+ onExiting,
33
+ onExited
34
+ });
35
+ callbacksRef.current = {
36
+ onEnter,
37
+ onEntering,
38
+ onEntered,
39
+ onExit,
40
+ onExiting,
41
+ onExited
42
+ };
43
+ const cleanup = useCallback(() => {
44
+ if (rafRef.current) {
45
+ cancelAnimationFrame(rafRef.current);
46
+ rafRef.current = 0;
47
+ }
48
+ if (timerRef.current) {
49
+ clearTimeout(timerRef.current);
50
+ timerRef.current = 0;
51
+ }
52
+ if (transitionEndRef.current && nodeRef?.current) {
53
+ nodeRef.current.removeEventListener("transitionend", transitionEndRef.current);
54
+ transitionEndRef.current = null;
55
+ }
56
+ }, [nodeRef]);
57
+ const waitForTransition = useCallback((phase, done) => {
58
+ const safetyDuration = phase === "enter" ? normalizedTimeout.enter : normalizedTimeout.exit;
59
+ if (safetyDuration === 0) {
60
+ done();
61
+ return;
62
+ }
63
+ const finish = () => {
64
+ cleanup();
65
+ done();
66
+ };
67
+ const node = nodeRef?.current;
68
+ if (node) {
69
+ const handler = (e) => {
70
+ if (e.target === node) finish();
71
+ };
72
+ transitionEndRef.current = handler;
73
+ node.addEventListener("transitionend", handler);
74
+ }
75
+ timerRef.current = window.setTimeout(finish, safetyDuration + 50);
76
+ }, [
77
+ cleanup,
78
+ nodeRef,
79
+ normalizedTimeout.enter,
80
+ normalizedTimeout.exit
81
+ ]);
82
+ useLayoutEffect(() => {
83
+ if (state === "enter") {
84
+ callbacksRef.current.onEnter?.();
85
+ rafRef.current = requestAnimationFrame(() => {
86
+ setState("entering");
87
+ callbacksRef.current.onEntering?.();
88
+ waitForTransition("enter", () => {
89
+ setState("entered");
90
+ callbacksRef.current.onEntered?.();
91
+ });
92
+ });
93
+ }
94
+ }, [state]);
95
+ useLayoutEffect(() => {
96
+ if (state === "exit") {
97
+ callbacksRef.current.onExit?.();
98
+ rafRef.current = requestAnimationFrame(() => {
99
+ setState("exiting");
100
+ callbacksRef.current.onExiting?.();
101
+ waitForTransition("exit", () => {
102
+ setState((prev) => {
103
+ if (prev === "exiting") {
104
+ callbacksRef.current.onExited?.();
105
+ return unmountOnExit ? "unmounted" : "exited";
106
+ }
107
+ return prev;
108
+ });
109
+ });
110
+ });
111
+ }
112
+ }, [state]);
113
+ useEffect(() => {
114
+ if (initialMountRef.current) {
115
+ initialMountRef.current = false;
116
+ return;
117
+ }
118
+ if (inProp) {
119
+ cleanup();
120
+ setState("enter");
121
+ } else {
122
+ cleanup();
123
+ setState("exit");
124
+ }
125
+ }, [inProp]);
126
+ useEffect(() => {
127
+ return cleanup;
128
+ }, [cleanup]);
129
+ return {
130
+ state,
131
+ shouldMount: state !== "unmounted"
132
+ };
133
+ }
134
+ //#endregion
135
+ export { useTransition as default };
136
+
137
+ //# sourceMappingURL=use-transition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-transition.js","names":[],"sources":["../../src/transition/use-transition.ts"],"sourcesContent":["import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';\n\nexport type TransitionState =\n | 'unmounted'\n | 'enter'\n | 'entering'\n | 'entered'\n | 'exit'\n | 'exiting'\n | 'exited';\n\nexport interface UseTransitionOptions {\n in: boolean;\n timeout?: number | { enter: number; exit: number };\n appear?: boolean;\n unmountOnExit?: boolean;\n mountOnEnter?: boolean;\n onEnter?: () => void;\n onEntering?: () => void;\n onEntered?: () => void;\n onExit?: () => void;\n onExiting?: () => void;\n onExited?: () => void;\n nodeRef?: React.RefObject<HTMLElement | null>;\n}\n\nexport interface UseTransitionResult {\n state: TransitionState;\n shouldMount: boolean;\n}\n\nfunction normalizeTimeout(\n timeout: number | { enter: number; exit: number } | undefined\n): { enter: number; exit: number } {\n if (timeout == null) return { enter: 300, exit: 300 };\n if (typeof timeout === 'number') return { enter: timeout, exit: timeout };\n return timeout;\n}\n\nfunction useTransition(options: UseTransitionOptions): UseTransitionResult {\n const {\n in: inProp,\n timeout,\n appear = true,\n unmountOnExit = true,\n mountOnEnter = false,\n onEnter,\n onEntering,\n onEntered,\n onExit,\n onExiting,\n onExited,\n nodeRef,\n } = options;\n\n const normalizedTimeout = normalizeTimeout(timeout);\n\n // Determine initial state\n const getInitialState = (): TransitionState => {\n if (inProp) {\n return appear ? 'enter' : 'entered';\n }\n if (unmountOnExit || mountOnEnter) {\n return 'unmounted';\n }\n return 'exited';\n };\n\n const [state, setState] = useState<TransitionState>(getInitialState);\n const rafRef = useRef<number>(0);\n const timerRef = useRef<number>(0);\n const transitionEndRef = useRef<(() => void) | null>(null);\n const initialMountRef = useRef(true);\n\n // Store latest callbacks in refs to avoid re-triggering effects\n const callbacksRef = useRef({\n onEnter,\n onEntering,\n onEntered,\n onExit,\n onExiting,\n onExited,\n });\n callbacksRef.current = {\n onEnter,\n onEntering,\n onEntered,\n onExit,\n onExiting,\n onExited,\n };\n\n const cleanup = useCallback(() => {\n if (rafRef.current) {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = 0;\n }\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n timerRef.current = 0;\n }\n if (transitionEndRef.current && nodeRef?.current) {\n nodeRef.current.removeEventListener('transitionend', transitionEndRef.current);\n transitionEndRef.current = null;\n }\n }, [nodeRef]);\n\n const waitForTransition = useCallback(\n (phase: 'enter' | 'exit', done: () => void) => {\n const safetyDuration =\n phase === 'enter' ? normalizedTimeout.enter : normalizedTimeout.exit;\n\n // timeout=0 means \"don't wait\" — advance immediately.\n // This matches react-transition-group's behavior where timeout=0\n // skips straight to the done state, letting CSS handle the animation\n // via the base element's transition property.\n if (safetyDuration === 0) {\n done();\n return;\n }\n\n const finish = () => {\n cleanup();\n done();\n };\n\n // Try transitionend listener first\n const node = nodeRef?.current;\n if (node) {\n const handler = (e: Event) => {\n if ((e as TransitionEvent).target === node) {\n finish();\n }\n };\n transitionEndRef.current = handler as () => void;\n node.addEventListener('transitionend', handler);\n }\n\n // Safety timeout fallback\n timerRef.current = window.setTimeout(finish, safetyDuration + 50);\n },\n [cleanup, nodeRef, normalizedTimeout.enter, normalizedTimeout.exit]\n );\n\n // Continue the enter animation after DOM is committed (state === 'enter').\n // useLayoutEffect fires synchronously after DOM mutations, guaranteeing\n // the child is mounted and refs are populated before onEnter runs.\n useLayoutEffect(() => {\n if (state === 'enter') {\n callbacksRef.current.onEnter?.();\n\n // Single rAF: useLayoutEffect runs before paint, so one rAF is enough\n // to ensure the browser has painted the -enter class before we add -enter-active.\n rafRef.current = requestAnimationFrame(() => {\n setState('entering');\n callbacksRef.current.onEntering?.();\n\n waitForTransition('enter', () => {\n setState('entered');\n callbacksRef.current.onEntered?.();\n });\n });\n }\n }, [state]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Continue the exit animation after DOM reflects exit state\n useLayoutEffect(() => {\n if (state === 'exit') {\n callbacksRef.current.onExit?.();\n\n rafRef.current = requestAnimationFrame(() => {\n setState('exiting');\n callbacksRef.current.onExiting?.();\n\n waitForTransition('exit', () => {\n setState((prev) => {\n if (prev === 'exiting') {\n callbacksRef.current.onExited?.();\n return unmountOnExit ? 'unmounted' : 'exited';\n }\n return prev;\n });\n });\n });\n }\n }, [state]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // React to `in` prop changes — only set the initial phase state.\n // The useLayoutEffect above handles the rest after DOM commit.\n useEffect(() => {\n if (initialMountRef.current) {\n initialMountRef.current = false;\n // On initial mount with appear=true, state is already 'enter' from getInitialState,\n // and the useLayoutEffect above will pick it up.\n return;\n }\n\n if (inProp) {\n cleanup();\n setState('enter');\n } else {\n cleanup();\n setState('exit');\n }\n }, [inProp]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Cleanup on unmount\n useEffect(() => {\n return cleanup;\n }, [cleanup]);\n\n const shouldMount = state !== 'unmounted';\n\n return { state, shouldMount };\n}\n\nexport default useTransition;\n"],"mappings":";;AA+BA,SAAS,iBACP,SACiC;AACjC,KAAI,WAAW,KAAM,QAAO;EAAE,OAAO;EAAK,MAAM;EAAK;AACrD,KAAI,OAAO,YAAY,SAAU,QAAO;EAAE,OAAO;EAAS,MAAM;EAAS;AACzE,QAAO;;AAGT,SAAS,cAAc,SAAoD;CACzE,MAAM,EACJ,IAAI,QACJ,SACA,SAAS,MACT,gBAAgB,MAChB,eAAe,OACf,SACA,YACA,WACA,QACA,WACA,UACA,YACE;CAEJ,MAAM,oBAAoB,iBAAiB,QAAQ;CAGnD,MAAM,wBAAyC;AAC7C,MAAI,OACF,QAAO,SAAS,UAAU;AAE5B,MAAI,iBAAiB,aACnB,QAAO;AAET,SAAO;;CAGT,MAAM,CAAC,OAAO,YAAY,SAA0B,gBAAgB;CACpE,MAAM,SAAS,OAAe,EAAE;CAChC,MAAM,WAAW,OAAe,EAAE;CAClC,MAAM,mBAAmB,OAA4B,KAAK;CAC1D,MAAM,kBAAkB,OAAO,KAAK;CAGpC,MAAM,eAAe,OAAO;EAC1B;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;AACF,cAAa,UAAU;EACrB;EACA;EACA;EACA;EACA;EACA;EACD;CAED,MAAM,UAAU,kBAAkB;AAChC,MAAI,OAAO,SAAS;AAClB,wBAAqB,OAAO,QAAQ;AACpC,UAAO,UAAU;;AAEnB,MAAI,SAAS,SAAS;AACpB,gBAAa,SAAS,QAAQ;AAC9B,YAAS,UAAU;;AAErB,MAAI,iBAAiB,WAAW,SAAS,SAAS;AAChD,WAAQ,QAAQ,oBAAoB,iBAAiB,iBAAiB,QAAQ;AAC9E,oBAAiB,UAAU;;IAE5B,CAAC,QAAQ,CAAC;CAEb,MAAM,oBAAoB,aACvB,OAAyB,SAAqB;EAC7C,MAAM,iBACJ,UAAU,UAAU,kBAAkB,QAAQ,kBAAkB;AAMlE,MAAI,mBAAmB,GAAG;AACxB,SAAM;AACN;;EAGF,MAAM,eAAe;AACnB,YAAS;AACT,SAAM;;EAIR,MAAM,OAAO,SAAS;AACtB,MAAI,MAAM;GACR,MAAM,WAAW,MAAa;AAC5B,QAAK,EAAsB,WAAW,KACpC,SAAQ;;AAGZ,oBAAiB,UAAU;AAC3B,QAAK,iBAAiB,iBAAiB,QAAQ;;AAIjD,WAAS,UAAU,OAAO,WAAW,QAAQ,iBAAiB,GAAG;IAEnE;EAAC;EAAS;EAAS,kBAAkB;EAAO,kBAAkB;EAAK,CACpE;AAKD,uBAAsB;AACpB,MAAI,UAAU,SAAS;AACrB,gBAAa,QAAQ,WAAW;AAIhC,UAAO,UAAU,4BAA4B;AAC3C,aAAS,WAAW;AACpB,iBAAa,QAAQ,cAAc;AAEnC,sBAAkB,eAAe;AAC/B,cAAS,UAAU;AACnB,kBAAa,QAAQ,aAAa;MAClC;KACF;;IAEH,CAAC,MAAM,CAAC;AAGX,uBAAsB;AACpB,MAAI,UAAU,QAAQ;AACpB,gBAAa,QAAQ,UAAU;AAE/B,UAAO,UAAU,4BAA4B;AAC3C,aAAS,UAAU;AACnB,iBAAa,QAAQ,aAAa;AAElC,sBAAkB,cAAc;AAC9B,eAAU,SAAS;AACjB,UAAI,SAAS,WAAW;AACtB,oBAAa,QAAQ,YAAY;AACjC,cAAO,gBAAgB,cAAc;;AAEvC,aAAO;OACP;MACF;KACF;;IAEH,CAAC,MAAM,CAAC;AAIX,iBAAgB;AACd,MAAI,gBAAgB,SAAS;AAC3B,mBAAgB,UAAU;AAG1B;;AAGF,MAAI,QAAQ;AACV,YAAS;AACT,YAAS,QAAQ;SACZ;AACL,YAAS;AACT,YAAS,OAAO;;IAEjB,CAAC,OAAO,CAAC;AAGZ,iBAAgB;AACd,SAAO;IACN,CAAC,QAAQ,CAAC;AAIb,QAAO;EAAE;EAAO,aAFI,UAAU;EAED"}
@@ -1,11 +1,11 @@
1
1
  import { ConfigContext } from "../config-provider/config-context.js";
2
2
  import { getPrefixCls } from "../_utils/general.js";
3
+ import transition_default from "../transition/index.js";
3
4
  import useBreakpoint, { responsiveArray } from "./hooks/use-breakpoint.js";
4
5
  import usePositions from "./hooks/use-positions.js";
5
6
  import React, { useCallback, useContext, useEffect, useRef, useState } from "react";
6
7
  import classNames from "classnames";
7
- import { jsx } from "react/jsx-runtime";
8
- import { CSSTransition, TransitionGroup } from "react-transition-group";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
9
  //#region src/waterfall/waterfall.tsx
10
10
  const Waterfall = React.forwardRef((props, ref) => {
11
11
  const { prefixCls: customisedCls, className, style, columns = 3, gutter = 0, items, itemRender, onLayoutChange, ...otherProps } = props;
@@ -69,6 +69,31 @@ const Waterfall = React.forwardRef((props, ref) => {
69
69
  items,
70
70
  onLayoutChange
71
71
  ]);
72
+ const prevItemsRef = useRef(items || []);
73
+ const [exitingItems, setExitingItems] = useState(/* @__PURE__ */ new Map());
74
+ useEffect(() => {
75
+ const currentKeys = new Set((items || []).map((item, i) => item.key ?? i));
76
+ const removed = /* @__PURE__ */ new Map();
77
+ prevItemsRef.current.forEach((item, index) => {
78
+ const key = item.key ?? index;
79
+ if (!currentKeys.has(key)) removed.set(key, item);
80
+ });
81
+ if (removed.size > 0) setExitingItems((prev) => {
82
+ const next = new Map(prev);
83
+ removed.forEach((item, key) => next.set(key, item));
84
+ return next;
85
+ });
86
+ prevItemsRef.current = items || [];
87
+ }, [items]);
88
+ const handleExited = useCallback((key) => {
89
+ itemRefsMap.current.delete(key);
90
+ setExitingItems((prev) => {
91
+ const next = new Map(prev);
92
+ next.delete(key);
93
+ return next;
94
+ });
95
+ collectItemSizes();
96
+ }, [collectItemSizes]);
72
97
  const cls = classNames(prefixCls, className);
73
98
  const containerStyle = {
74
99
  ...style,
@@ -76,49 +101,47 @@ const Waterfall = React.forwardRef((props, ref) => {
76
101
  height: totalHeight || void 0
77
102
  };
78
103
  const mergedItems = items || [];
79
- return /* @__PURE__ */ jsx("div", {
104
+ const renderItem = (item, index, isExiting) => {
105
+ const key = item.key ?? index;
106
+ const position = itemPositions.get(key);
107
+ const hasPosition = !!position;
108
+ const columnIndex = position?.column ?? 0;
109
+ const itemStyle = {
110
+ position: "absolute",
111
+ width: `calc((100% - ${horizontalGutter * (columnCount - 1)}px) / ${columnCount})`,
112
+ left: `calc((100% - ${horizontalGutter * (columnCount - 1)}px) / ${columnCount} * ${columnIndex} + ${horizontalGutter * columnIndex}px)`,
113
+ top: position?.top ?? 0,
114
+ transition: hasPosition ? "top 0.3s ease, left 0.3s ease, opacity 0.3s ease" : "none",
115
+ opacity: hasPosition ? 1 : 0
116
+ };
117
+ const content = item.children ?? itemRender?.({
118
+ ...item,
119
+ index,
120
+ column: columnIndex
121
+ });
122
+ return /* @__PURE__ */ jsx(transition_default, {
123
+ in: !isExiting,
124
+ timeout: 300,
125
+ appear: false,
126
+ unmountOnExit: true,
127
+ classNames: `${prefixCls}__item-fade`,
128
+ onExited: () => handleExited(key),
129
+ children: /* @__PURE__ */ jsx("div", {
130
+ ref: (el) => setItemRef(key, el),
131
+ className: `${prefixCls}__item`,
132
+ style: itemStyle,
133
+ children: content
134
+ })
135
+ }, key);
136
+ };
137
+ return /* @__PURE__ */ jsxs("div", {
80
138
  ref,
81
139
  ...otherProps,
82
140
  className: cls,
83
141
  style: containerStyle,
84
142
  onLoad: collectItemSizes,
85
143
  onError: collectItemSizes,
86
- children: /* @__PURE__ */ jsx(TransitionGroup, {
87
- component: null,
88
- children: mergedItems.map((item, index) => {
89
- const key = item.key ?? index;
90
- const position = itemPositions.get(key);
91
- const hasPosition = !!position;
92
- const columnIndex = position?.column ?? 0;
93
- const itemStyle = {
94
- position: "absolute",
95
- width: `calc((100% - ${horizontalGutter * (columnCount - 1)}px) / ${columnCount})`,
96
- left: `calc((100% - ${horizontalGutter * (columnCount - 1)}px) / ${columnCount} * ${columnIndex} + ${horizontalGutter * columnIndex}px)`,
97
- top: position?.top ?? 0,
98
- transition: hasPosition ? "top 0.3s ease, left 0.3s ease, opacity 0.3s ease" : "none",
99
- opacity: hasPosition ? 1 : 0
100
- };
101
- const content = item.children ?? itemRender?.({
102
- ...item,
103
- index,
104
- column: columnIndex
105
- });
106
- return /* @__PURE__ */ jsx(CSSTransition, {
107
- timeout: 300,
108
- classNames: `${prefixCls}__item-fade`,
109
- onExited: () => {
110
- itemRefsMap.current.delete(key);
111
- collectItemSizes();
112
- },
113
- children: /* @__PURE__ */ jsx("div", {
114
- ref: (el) => setItemRef(key, el),
115
- className: `${prefixCls}__item`,
116
- style: itemStyle,
117
- children: content
118
- })
119
- }, key);
120
- })
121
- })
144
+ children: [mergedItems.map((item, index) => renderItem(item, index, false)), Array.from(exitingItems.entries()).map(([key, item]) => renderItem(item, Number(key), true))]
122
145
  });
123
146
  });
124
147
  Waterfall.displayName = "Waterfall";