From b9aef7fe63ef3c8bee50145c565d9892a8554127 Mon Sep 17 00:00:00 2001 From: zhouyun1 Date: Fri, 20 Oct 2023 11:04:16 +0800 Subject: [PATCH] feat(drawer): add onOutsideClick api (#2629) --- .changeset/kind-beers-check.md | 5 ++ .changeset/shy-crabs-clean.md | 5 ++ packages/ui/drawer/src/Drawer.tsx | 17 +++- packages/ui/drawer/stories/index.stories.tsx | 1 + .../drawer/stories/outside-click.stories.tsx | 90 +++++++++++++++++++ 5 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 .changeset/kind-beers-check.md create mode 100644 .changeset/shy-crabs-clean.md create mode 100644 packages/ui/drawer/stories/outside-click.stories.tsx diff --git a/.changeset/kind-beers-check.md b/.changeset/kind-beers-check.md new file mode 100644 index 000000000..78f4b8fe3 --- /dev/null +++ b/.changeset/kind-beers-check.md @@ -0,0 +1,5 @@ +--- +"@hi-ui/hiui": patch +--- + +Drawer feat: add onOutsideClick api diff --git a/.changeset/shy-crabs-clean.md b/.changeset/shy-crabs-clean.md new file mode 100644 index 000000000..cfecfaa86 --- /dev/null +++ b/.changeset/shy-crabs-clean.md @@ -0,0 +1,5 @@ +--- +"@hi-ui/drawer": minor +--- + +feat: add onOutsideClick api diff --git a/packages/ui/drawer/src/Drawer.tsx b/packages/ui/drawer/src/Drawer.tsx index f7f8c5d3a..3ccc25767 100644 --- a/packages/ui/drawer/src/Drawer.tsx +++ b/packages/ui/drawer/src/Drawer.tsx @@ -10,6 +10,8 @@ import { useToggle } from '@hi-ui/use-toggle' import { isNumeric } from '@hi-ui/type-assertion' import { CloseOutlined } from '@hi-ui/icons' import { IconButton } from '@hi-ui/icon-button' +import { mergeRefs } from '@hi-ui/react-utils' +import { useOutsideClick } from '@hi-ui/use-outside-click' import { DrawerPlacementEnum } from './types' const DRAWER_PREFIX = getPrefixCls('drawer') @@ -42,6 +44,7 @@ export const Drawer = forwardRef( showMask = true, placement = 'right', drawerConfig, + onOutsideClick, ...rest }, ref @@ -70,6 +73,11 @@ export const Drawer = forwardRef( } }, [visible, transitionVisibleAction, transitionExitedAction]) + const modalProps = getModalProps(rootProps, ref) + const innerRef = React.useRef(null) + + useOutsideClick(innerRef, onOutsideClick) + const onExitedLatest = useLatestCallback(onExitedProp) const onExited = useCallback(() => { transitionExitedAction.on() @@ -95,7 +103,10 @@ export const Drawer = forwardRef( >
, 'title'>, UseM * 是否展示右上角关闭按钮 */ closeable?: boolean + /** + * 外界元素点击数触发 + */ + onOutsideClick?: (evt: Event) => void /** * 自定义关闭时 icon。暂不对外暴露 * @private diff --git a/packages/ui/drawer/stories/index.stories.tsx b/packages/ui/drawer/stories/index.stories.tsx index 5d8e66884..c321b8f94 100644 --- a/packages/ui/drawer/stories/index.stories.tsx +++ b/packages/ui/drawer/stories/index.stories.tsx @@ -4,6 +4,7 @@ import Drawer from '../src' export * from './basic.stories' export * from './header.stories' export * from './mask.stories' +export * from './outside-click.stories' export * from './container.stories' export * from './nested.stories' export * from './extra.stories' diff --git a/packages/ui/drawer/stories/outside-click.stories.tsx b/packages/ui/drawer/stories/outside-click.stories.tsx new file mode 100644 index 000000000..2d7b4bd85 --- /dev/null +++ b/packages/ui/drawer/stories/outside-click.stories.tsx @@ -0,0 +1,90 @@ +import React from 'react' +import Drawer from '../src' +import Button from '@hi-ui/button' +import Tree, { TreeDataItem } from '@hi-ui/tree' + +/** + * @title 点击外部事件处理 + * @desc 常用于无蒙层模式下,切换列表项详情内容 + */ +export const OutsideClick = () => { + const [visible, setVisible] = React.useState(false) + const [data] = React.useState([ + { + id: 1, + title: '小米', + children: [ + { + id: 2, + title: '研发', + disabled: true, + children: [ + { id: 3, title: '后端', disabled: true }, + { id: 4, title: '运维' }, + { id: 5, title: '前端' }, + ], + }, + { id: 6, title: '产品' }, + ], + }, + { + id: 11, + title: '大米', + children: [ + { id: 22, title: '可视化' }, + { id: 66, title: 'HiUI' }, + ], + }, + ]) + const [currentData, setCurrentData] = React.useState() + const wrapperRef = React.useRef(null) + + return ( + <> +

OutsideClick

+
+
+ { + // console.log('node', node) + + if (id) { + setVisible(true) + setCurrentData(node?.raw) + } else { + setVisible(false) + } + }} + /> +
+ setVisible(false)} + // 点击列表外部内容时关闭抽屉 + onOutsideClick={(e) => { + // console.log('target', e.target) + + if (!wrapperRef.current?.contains(e.target as Element)) { + setVisible(false) + } + }} + footer={ +
+ + +
+ } + > + {currentData?.title} +
+
+ + ) +}