@tiny-design/react 1.1.2 → 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.
- package/es/drawer/drawer.js +3 -2
- package/es/drawer/drawer.js.map +1 -1
- package/es/index.d.ts +2 -1
- package/es/index.js +2 -1
- package/es/message/message.js +3 -2
- package/es/message/message.js.map +1 -1
- package/es/modal/modal.js +3 -2
- package/es/modal/modal.js.map +1 -1
- package/es/overlay/overlay.js +2 -2
- package/es/overlay/overlay.js.map +1 -1
- package/es/transition/index.js +1 -0
- package/es/transition/index.js.map +1 -1
- package/es/transition/transition.d.ts +20 -5
- package/es/transition/transition.js +33 -8
- package/es/transition/transition.js.map +1 -1
- package/es/transition/use-transition.js +137 -0
- package/es/transition/use-transition.js.map +1 -0
- package/es/waterfall/hooks/use-breakpoint.js +47 -0
- package/es/waterfall/hooks/use-breakpoint.js.map +1 -0
- package/es/waterfall/hooks/use-positions.js +28 -0
- package/es/waterfall/hooks/use-positions.js.map +1 -0
- package/es/waterfall/index.d.ts +2 -0
- package/es/waterfall/index.js +9 -0
- package/es/waterfall/index.js.map +1 -0
- package/es/waterfall/style/_index.scss +22 -0
- package/es/waterfall/style/index.css +16 -0
- package/es/waterfall/style/index.d.ts +1 -0
- package/es/waterfall/style/index.js +1 -0
- package/es/waterfall/types.d.ts +35 -0
- package/es/waterfall/waterfall.d.ts +8 -0
- package/es/waterfall/waterfall.js +151 -0
- package/es/waterfall/waterfall.js.map +1 -0
- package/lib/drawer/drawer.js +5 -4
- package/lib/drawer/drawer.js.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.js +2 -0
- package/lib/message/message.js +3 -2
- package/lib/message/message.js.map +1 -1
- package/lib/modal/modal.js +5 -4
- package/lib/modal/modal.js.map +1 -1
- package/lib/overlay/overlay.js +3 -3
- package/lib/overlay/overlay.js.map +1 -1
- package/lib/transition/index.js +1 -0
- package/lib/transition/index.js.map +1 -1
- package/lib/transition/transition.d.ts +20 -5
- package/lib/transition/transition.js +32 -7
- package/lib/transition/transition.js.map +1 -1
- package/lib/transition/use-transition.js +138 -0
- package/lib/transition/use-transition.js.map +1 -0
- package/lib/waterfall/hooks/use-breakpoint.js +49 -0
- package/lib/waterfall/hooks/use-breakpoint.js.map +1 -0
- package/lib/waterfall/hooks/use-positions.js +29 -0
- package/lib/waterfall/hooks/use-positions.js.map +1 -0
- package/lib/waterfall/index.js +8 -0
- package/lib/waterfall/index.js.map +1 -0
- package/lib/waterfall/style/_index.scss +22 -0
- package/lib/waterfall/style/index.css +16 -0
- package/lib/waterfall/style/index.d.ts +1 -0
- package/lib/waterfall/style/index.js +1 -0
- package/lib/waterfall/types.d.ts +35 -0
- package/lib/waterfall/waterfall.d.ts +8 -0
- package/lib/waterfall/waterfall.js +154 -0
- package/lib/waterfall/waterfall.js.map +1 -0
- package/package.json +3 -5
package/es/drawer/drawer.js
CHANGED
|
@@ -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(
|
|
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,
|
package/es/drawer/drawer.js.map
CHANGED
|
@@ -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
|
|
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"}
|
package/es/index.d.ts
CHANGED
|
@@ -80,10 +80,11 @@ import { Transition } from "./transition/transition.js";
|
|
|
80
80
|
import { Tree } from "./tree/tree.js";
|
|
81
81
|
import { DefaultTypo } from "./typography/index.js";
|
|
82
82
|
import { Upload } from "./upload/upload.js";
|
|
83
|
+
import { Waterfall } from "./waterfall/waterfall.js";
|
|
83
84
|
import { withLocale } from "./intl-provider/with-locale.js";
|
|
84
85
|
import { withSpin } from "./with-spin/with-spin.js";
|
|
85
86
|
import { en_US } from "./locale/en_US.js";
|
|
86
87
|
import { zh_CN } from "./locale/zh_CN.js";
|
|
87
88
|
import { useLocale } from "./_utils/use-locale.js";
|
|
88
89
|
import { ThemeMode, useTheme } from "./_utils/use-theme.js";
|
|
89
|
-
export { Alert, DefaultAnchor as Anchor, AspectRatio, AutoComplete, DefaultAvatar as Avatar, BackTop, Badge, DefaultBreadcrumb as Breadcrumb, DefaultButton as Button, Calendar, DefaultCard as Card, DefaultCarousel as Carousel, Cascader, DefaultCheckbox as Checkbox, Col, DefaultCollapse as Collapse, ColorPicker, ConfigProvider, CopyToClipboard, Countdown, DatePicker, DefaultDesc as Descriptions, Divider, Drawer, Dropdown, Empty, Flex, DefaultFlip as Flip, DefaultForm as Form, Image, DefaultInput as Input, InputNumber, InputOTP, InputPassword, IntlProvider, Keyboard, DefaultLayout as Layout, Link, DefaultList as List, Loader, _default as LoadingBar, type Locale, DefaultMenu as Menu, messageContainer as Message, ModalWithContext as Modal, DefaultSelect as NativeSelect, notificationContainer as Notification, Overlay, Pagination, PopConfirm, Popover, Progress, DefaultRadio as Radio, Rate, Result, Row, ScrollIndicator, Segmented, DefaultSelect$1 as Select, Skeleton, Slider, Space, DefaultSpeedDial as SpeedDial, Split, SplitButton, Statistic, DefaultSteps as Steps, Sticky, StrengthIndicator, Switch, Table, DefaultTabs as Tabs, DefaultTag as Tag, Textarea, type ThemeMode, TimePicker, DefaultTimeline as Timeline, Tooltip, Transfer, Transition, Tree, DefaultTypo as Typography, Upload, en_US, useLocale, useTheme, withLocale, withSpin, zh_CN };
|
|
90
|
+
export { Alert, DefaultAnchor as Anchor, AspectRatio, AutoComplete, DefaultAvatar as Avatar, BackTop, Badge, DefaultBreadcrumb as Breadcrumb, DefaultButton as Button, Calendar, DefaultCard as Card, DefaultCarousel as Carousel, Cascader, DefaultCheckbox as Checkbox, Col, DefaultCollapse as Collapse, ColorPicker, ConfigProvider, CopyToClipboard, Countdown, DatePicker, DefaultDesc as Descriptions, Divider, Drawer, Dropdown, Empty, Flex, DefaultFlip as Flip, DefaultForm as Form, Image, DefaultInput as Input, InputNumber, InputOTP, InputPassword, IntlProvider, Keyboard, DefaultLayout as Layout, Link, DefaultList as List, Loader, _default as LoadingBar, type Locale, DefaultMenu as Menu, messageContainer as Message, ModalWithContext as Modal, DefaultSelect as NativeSelect, notificationContainer as Notification, Overlay, Pagination, PopConfirm, Popover, Progress, DefaultRadio as Radio, Rate, Result, Row, ScrollIndicator, Segmented, DefaultSelect$1 as Select, Skeleton, Slider, Space, DefaultSpeedDial as SpeedDial, Split, SplitButton, Statistic, DefaultSteps as Steps, Sticky, StrengthIndicator, Switch, Table, DefaultTabs as Tabs, DefaultTag as Tag, Textarea, type ThemeMode, TimePicker, DefaultTimeline as Timeline, Tooltip, Transfer, Transition, Tree, DefaultTypo as Typography, Upload, Waterfall, en_US, useLocale, useTheme, withLocale, withSpin, zh_CN };
|
package/es/index.js
CHANGED
|
@@ -82,8 +82,9 @@ import transfer_default from "./transfer/index.js";
|
|
|
82
82
|
import tree_default from "./tree/index.js";
|
|
83
83
|
import DefaultTypo from "./typography/index.js";
|
|
84
84
|
import upload_default from "./upload/index.js";
|
|
85
|
+
import waterfall_default from "./waterfall/index.js";
|
|
85
86
|
import { withLocale } from "./intl-provider/with-locale.js";
|
|
86
87
|
import { withSpin } from "./with-spin/with-spin.js";
|
|
87
88
|
import zh_CN from "./locale/zh_CN.js";
|
|
88
89
|
import { useTheme } from "./_utils/use-theme.js";
|
|
89
|
-
export { alert_default as Alert, DefaultAnchor as Anchor, aspect_ratio_default as AspectRatio, auto_complete_default as AutoComplete, DefaultAvatar as Avatar, back_top_default as BackTop, badge_default as Badge, DefaultBreadcrumb as Breadcrumb, DefaultButton as Button, calendar_default as Calendar, DefaultCard as Card, DefaultCarousel as Carousel, cascader_default as Cascader, DefaultCheckbox as Checkbox, col_default as Col, DefaultCollapse as Collapse, color_picker_default as ColorPicker, config_provider_default as ConfigProvider, copy_to_clipboard_default as CopyToClipboard, countdown_default as Countdown, date_picker_default as DatePicker, DefaultDesc as Descriptions, divider_default as Divider, drawer_default as Drawer, dropdown_default as Dropdown, empty_default as Empty, flex_default as Flex, DefaultFlip as Flip, DefaultForm as Form, image_default as Image, DefaultInput as Input, input_number_default as InputNumber, input_otp_default as InputOTP, input_password_default as InputPassword, intl_provider_default as IntlProvider, keyboard_default as Keyboard, DefaultLayout as Layout, link_default as Link, DefaultList as List, loader_default as Loader, loading_bar_default as LoadingBar, DefaultMenu as Menu, message_default as Message, ModalWithContext as Modal, DefaultSelect as NativeSelect, notification_default as Notification, overlay_default as Overlay, pagination_default as Pagination, pop_confirm_default as PopConfirm, popover_default as Popover, Progress, DefaultRadio as Radio, rate_default as Rate, result_default as Result, row_default as Row, scroll_indicator_default as ScrollIndicator, segmented_default as Segmented, DefaultSelect$1 as Select, skeleton_default as Skeleton, slider_default as Slider, space_default as Space, DefaultSpeedDial as SpeedDial, split_default as Split, split_button_default as SplitButton, statistic_default as Statistic, DefaultSteps as Steps, sticky_default as Sticky, strength_indicator_default as StrengthIndicator, switch_default as Switch, table_default as Table, DefaultTabs as Tabs, DefaultTag as Tag, textarea_default as Textarea, time_picker_default as TimePicker, DefaultTimeline as Timeline, tooltip_default as Tooltip, transfer_default as Transfer, transition_default as Transition, tree_default as Tree, DefaultTypo as Typography, upload_default as Upload, en_US, useLocale, useTheme, withLocale, withSpin, zh_CN };
|
|
90
|
+
export { alert_default as Alert, DefaultAnchor as Anchor, aspect_ratio_default as AspectRatio, auto_complete_default as AutoComplete, DefaultAvatar as Avatar, back_top_default as BackTop, badge_default as Badge, DefaultBreadcrumb as Breadcrumb, DefaultButton as Button, calendar_default as Calendar, DefaultCard as Card, DefaultCarousel as Carousel, cascader_default as Cascader, DefaultCheckbox as Checkbox, col_default as Col, DefaultCollapse as Collapse, color_picker_default as ColorPicker, config_provider_default as ConfigProvider, copy_to_clipboard_default as CopyToClipboard, countdown_default as Countdown, date_picker_default as DatePicker, DefaultDesc as Descriptions, divider_default as Divider, drawer_default as Drawer, dropdown_default as Dropdown, empty_default as Empty, flex_default as Flex, DefaultFlip as Flip, DefaultForm as Form, image_default as Image, DefaultInput as Input, input_number_default as InputNumber, input_otp_default as InputOTP, input_password_default as InputPassword, intl_provider_default as IntlProvider, keyboard_default as Keyboard, DefaultLayout as Layout, link_default as Link, DefaultList as List, loader_default as Loader, loading_bar_default as LoadingBar, DefaultMenu as Menu, message_default as Message, ModalWithContext as Modal, DefaultSelect as NativeSelect, notification_default as Notification, overlay_default as Overlay, pagination_default as Pagination, pop_confirm_default as PopConfirm, popover_default as Popover, Progress, DefaultRadio as Radio, rate_default as Rate, result_default as Result, row_default as Row, scroll_indicator_default as ScrollIndicator, segmented_default as Segmented, DefaultSelect$1 as Select, skeleton_default as Skeleton, slider_default as Slider, space_default as Space, DefaultSpeedDial as SpeedDial, split_default as Split, split_button_default as SplitButton, statistic_default as Statistic, DefaultSteps as Steps, sticky_default as Sticky, strength_indicator_default as StrengthIndicator, switch_default as Switch, table_default as Table, DefaultTabs as Tabs, DefaultTag as Tag, textarea_default as Textarea, time_picker_default as TimePicker, DefaultTimeline as Timeline, tooltip_default as Tooltip, transfer_default as Transfer, transition_default as Transition, tree_default as Tree, DefaultTypo as Typography, upload_default as Upload, waterfall_default as Waterfall, en_US, useLocale, useTheme, withLocale, withSpin, zh_CN };
|
package/es/message/message.js
CHANGED
|
@@ -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(
|
|
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
|
|
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(
|
|
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,
|
package/es/modal/modal.js.map
CHANGED
|
@@ -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
|
|
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":";;;;;;;;;;;AAWA,MAAM,QAAQ,MAAM,YAAwC,OAAO,QAAQ;CACzE,MAAM,SAAS,WAAW;CAC1B,MAAM,EACJ,UAAU,OACV,QAAQ,KACR,WAAW,OACX,WAAW,MACX,iBAAiB,MACjB,WAAW,WACX,eAAe,MACf,cAAc,OAAO,MAAM,QAC3B,aAAa,OAAO,MAAM,YAC1B,iBAAiB,OACjB,YAAY,SACZ,SAAS,KACT,WACA,UAAU,cACV,SAAS,aACT,KACA,QACA,QACA,YACA,oBACA,mBACA,WACA,UACA,OACA,WACA,aACA,WACA,aACA,WAAW,kBACT;CACJ,MAAM,WAAW,eAAe;CAChC,MAAM,CAAC,cAAc,mBAAmB,SAAS,QAAQ;CAEzD,MAAM,YAAY,aAAa,SADT,WAAW,cAAc,CACO,WAAW,cAAc;CAC/E,MAAM,MAAM,WAAW,WAAW,WAAW,GAAG,GAAG,UAAU,aAAa,UAAU,CAAC;CACrF,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,eAAW,EAAiC;AAC5C;;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;AAGnD,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,SAAS,CAAC;CAEvB,MAAM,qBAAsC;AAC1C,MAAI,MAAM,eAAe,OAAO,CAC9B,QAAO;WACE,WAAW,KACpB,QAAO;MAEP,QACE,qBAAC,MAAD;GAAM,KAAI;GAAK,SAAQ;GAAM,WAAW,GAAG,UAAU;GAAW,OAAO;aAAvE,CACE,oBAAC,QAAD;IAAQ,SAAS;IAAU,WAAW,GAAG,UAAU;IAAe,GAAI;cACnE;IACM,CAAA,EACT,oBAAC,QAAD;IACE,SAAS;IACT,SAAS;IACT,SAAQ;IACR,WAAW,GAAG,UAAU;IACxB,GAAI;cACH;IACM,CAAA,CACJ;;;AAKb,QACE,oBAACA,iBAAD;EACE,eAAqB,gBAAgB,KAAK;EAC1C,cAAoB,gBAAgB,MAAM;EAClC;EACR,MAAM;EACN,eAAe;EACf,QAAQ;EACR,UAAU;EACV,gBAAgB,MAA8B;AAC5C,mBAAgB,YAAW,SAAS,EAAE;;EAExC,OAAO;YACP,oBAAC,OAAD;GAAU;GAAK,WAAW;GAAK,OAAO,EAAE,KAAK;aAC3C,oBAAC,OAAD;IAAK,OAAO;KAAE;KAAO,GAAG;KAAO;cAC7B,oBAACC,oBAAD;KACE,QAAQ;KACC;KACT,IAAI;KACJ,YAAY,GAAG,UAAU,YAAY;KACrC,eAAe;KACf,SAAS;eACT,qBAAC,OAAD;MACE,KAAK;MACL,WAAW,GAAG,UAAU;MACxB,MAAK;MACL,cAAW;MACX,mBAAiB,SAAS,UAAU,KAAA;MACpC,UAAU,MAAY,EAAE,iBAAiB;gBAN3C;OAOG,YACC,oBAAC,UAAD;QAAQ,MAAK;QAAS,WAAW,GAAG,UAAU;QAAc,SAAS;QAAU,cAAW;kBAAQ;QAEzF,CAAA;OAEV,UACC,oBAAC,OAAD;QAAK,WAAW,GAAG,UAAU;QAAW,OAAO;kBAC7C,oBAAC,OAAD;SAAK,WAAW,GAAG,UAAU;SAAU,IAAI;mBAAU;SAAa,CAAA;QAC9D,CAAA;OAER,oBAAC,OAAD;QAAK,WAAW,GAAG,UAAU;QAAS,OAAO;QAC1C;QACG,CAAA;OACL,cAAc;OACX;;KACK,CAAA;IACT,CAAA;GACF,CAAA;EACE,CAAA;EAEZ;AAEF,MAAM,cAAc"}
|
package/es/overlay/overlay.js
CHANGED
|
@@ -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(
|
|
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
|
|
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"}
|
package/es/transition/index.js
CHANGED
|
@@ -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":"
|
|
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
|
-
|
|
8
|
-
|
|
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
|
-
}
|
|
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 "
|
|
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,
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
|
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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
//#region src/waterfall/hooks/use-breakpoint.ts
|
|
3
|
+
const breakpointMap = {
|
|
4
|
+
xxl: "(min-width: 1600px)",
|
|
5
|
+
xl: "(min-width: 1200px)",
|
|
6
|
+
lg: "(min-width: 992px)",
|
|
7
|
+
md: "(min-width: 768px)",
|
|
8
|
+
sm: "(min-width: 576px)",
|
|
9
|
+
xs: "(max-width: 575.98px)"
|
|
10
|
+
};
|
|
11
|
+
const responsiveArray = [
|
|
12
|
+
"xxl",
|
|
13
|
+
"xl",
|
|
14
|
+
"lg",
|
|
15
|
+
"md",
|
|
16
|
+
"sm",
|
|
17
|
+
"xs"
|
|
18
|
+
];
|
|
19
|
+
function useBreakpoint() {
|
|
20
|
+
const [screens, setScreens] = useState({});
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
23
|
+
const queries = /* @__PURE__ */ new Map();
|
|
24
|
+
const update = () => {
|
|
25
|
+
const next = {};
|
|
26
|
+
for (const bp of responsiveArray) {
|
|
27
|
+
const mql = queries.get(bp);
|
|
28
|
+
if (mql) next[bp] = mql.matches;
|
|
29
|
+
}
|
|
30
|
+
setScreens(next);
|
|
31
|
+
};
|
|
32
|
+
for (const bp of responsiveArray) {
|
|
33
|
+
const mql = window.matchMedia(breakpointMap[bp]);
|
|
34
|
+
queries.set(bp, mql);
|
|
35
|
+
mql.addEventListener("change", update);
|
|
36
|
+
}
|
|
37
|
+
update();
|
|
38
|
+
return () => {
|
|
39
|
+
for (const [, mql] of queries) mql.removeEventListener("change", update);
|
|
40
|
+
};
|
|
41
|
+
}, []);
|
|
42
|
+
return screens;
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { useBreakpoint as default, responsiveArray };
|
|
46
|
+
|
|
47
|
+
//# sourceMappingURL=use-breakpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-breakpoint.js","names":[],"sources":["../../../src/waterfall/hooks/use-breakpoint.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport { Breakpoint } from '../types';\n\nconst breakpointMap: Record<Breakpoint, string> = {\n xxl: '(min-width: 1600px)',\n xl: '(min-width: 1200px)',\n lg: '(min-width: 992px)',\n md: '(min-width: 768px)',\n sm: '(min-width: 576px)',\n xs: '(max-width: 575.98px)',\n};\n\nconst responsiveArray: Breakpoint[] = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs'];\n\ntype Screens = Partial<Record<Breakpoint, boolean>>;\n\nexport { responsiveArray };\n\nexport default function useBreakpoint(): Screens {\n const [screens, setScreens] = useState<Screens>({});\n\n useEffect(() => {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return;\n\n const queries = new Map<Breakpoint, MediaQueryList>();\n\n const update = () => {\n const next: Screens = {};\n for (const bp of responsiveArray) {\n const mql = queries.get(bp);\n if (mql) {\n next[bp] = mql.matches;\n }\n }\n setScreens(next);\n };\n\n for (const bp of responsiveArray) {\n const mql = window.matchMedia(breakpointMap[bp]);\n queries.set(bp, mql);\n mql.addEventListener('change', update);\n }\n\n update();\n\n return () => {\n for (const [, mql] of queries) {\n mql.removeEventListener('change', update);\n }\n };\n }, []);\n\n return screens;\n}\n"],"mappings":";;AAGA,MAAM,gBAA4C;CAChD,KAAK;CACL,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACL;AAED,MAAM,kBAAgC;CAAC;CAAO;CAAM;CAAM;CAAM;CAAM;CAAK;AAM3E,SAAwB,gBAAyB;CAC/C,MAAM,CAAC,SAAS,cAAc,SAAkB,EAAE,CAAC;AAEnD,iBAAgB;AACd,MAAI,OAAO,WAAW,eAAe,OAAO,OAAO,eAAe,WAAY;EAE9E,MAAM,0BAAU,IAAI,KAAiC;EAErD,MAAM,eAAe;GACnB,MAAM,OAAgB,EAAE;AACxB,QAAK,MAAM,MAAM,iBAAiB;IAChC,MAAM,MAAM,QAAQ,IAAI,GAAG;AAC3B,QAAI,IACF,MAAK,MAAM,IAAI;;AAGnB,cAAW,KAAK;;AAGlB,OAAK,MAAM,MAAM,iBAAiB;GAChC,MAAM,MAAM,OAAO,WAAW,cAAc,IAAI;AAChD,WAAQ,IAAI,IAAI,IAAI;AACpB,OAAI,iBAAiB,UAAU,OAAO;;AAGxC,UAAQ;AAER,eAAa;AACX,QAAK,MAAM,GAAG,QAAQ,QACpB,KAAI,oBAAoB,UAAU,OAAO;;IAG5C,EAAE,CAAC;AAEN,QAAO"}
|