十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

点击嵌套 Popover 的下拉导致外层 Popover 关闭怎么解决

点击嵌套 Popover 的下拉导致外层 Popover 关闭怎么解决 点击嵌套 Popover 的下拉导致外层 Popover 关闭怎么解决【免费下载链接】mantineA fully featured React components library项目地址: https://gitcode.com/GitHub_Trending/ma/mantine在 Mantine 中当Popover.Dropdown里放了一个Select、DatePicker、Menu等自带下拉的组件时点击内层下拉会立刻把外层 Popover 关掉。本文给出这个问题的原因和官方修复方法把内层组件的下拉改为不经过 Portal 渲染withinPortal{false}使内层下拉成为外层 Popover 的后代节点外层就不会再把它当作外部点击。问题现象典型结构是外层Popover的Popover.Dropdown中渲染一个Selectimport { Button, Popover, Select } from mantine/core; function Demo() { return ( Popover width{200} positionbottom withArrow shadowmd Popover.Target ButtonToggle popover/Button /Popover.Target Popover.Dropdown Select placeholderChoose your framework data{[ { value: react, label: React }, { value: vue, label: Vue }, { value: angular, label: Angular }, ]} / /Popover.Dropdown /Popover ); }打开外层 Popover 后点击Select输入框时Select的下拉还没展开外层 Popover 就已经关闭了。可参考仓库中的官方 FAQ nested-popover-closes。原因内层下拉被 Portal 挂到了 document.body两个机制共同导致了这个问题下拉默认渲染在 Portal 中。Mantine 7.0.0 起Popover、HoverCard、Tooltip等所有 overlay 组件的withinPortal默认为true见 7.0.0 changelog下拉通过Portal挂到document.body上。这样做的目的是让下拉能浮在所有元素之上即使父元素有overflow: hidden也能正确定位。Popover 用 use-click-outside 检测外部点击。Popover组件内部通过 use-click-outside hook 监听mousedown、touchstart事件只有当点击路径同时包含 target 和 dropdown 两个节点时才不关闭见 Popover 源码。而内层Select的下拉被渲染到了document.body不在外层 Popover 的 target/dropdown 节点之内于是点击内层下拉被外层判定为外部点击外层 Popover 随之关闭。这一点与 Popover 官方文档 的 Nested popovers 小节一致嵌套 Popover 要求子组件不通过 Portal 渲染否则 outside clicks 会关掉所有 Popover。修复给内层组件设置 withinPortal{false}官方 FAQ 的修复方法是在内层下拉组件上设置withinPortal{false}让它渲染在外层Popover.Dropdown内部而不是document.body。注意withinPortal不一定直接暴露在你的组件上。以Select为例这个选项藏在comboboxProps里Select 文档 的 Inside Popover 小节import { Button, Popover, Select } from mantine/core; function Demo() { return ( Popover width{200} positionbottom withArrow shadowmd Popover.Target ButtonToggle popover/Button /Popover.Target Popover.Dropdown Select comboboxProps{{ withinPortal: false }} placeholderChoose your framework data{[ { value: react, label: React }, { value: vue, label: Vue }, { value: angular, label: Angular }, ]} / /Popover.Dropdown /Popover ); }完整的修复示例见 NestedPopovers.demo.tsx 中的NestedPopoversWorking。不同组件对应的 propwithinPortal{false}要设置在哪取决于你使用的组件如何把 prop 传给底层的Popover/Combobox内层组件写法依据Select/MultiSelect/Cascader等 Combobox 组件comboboxProps{{ withinPortal: false }}select.mdx、cascader.mdxAutocompletewithinPortal: falseautocomplete.mdx其他 overlay 组件popoverProps{{ withinPortal: false }}如ColorInput在 7.0.0 起通过popoverProps传递7.0.0 changelog官方 FAQ 的原话是这个选项可能是另一个 prop 的一部分例如Select的comboboxProps需要查看你正在使用的组件文档确认应该用哪个 prop。验证方式修改后在浏览器中实际操作打开外层 Popover再点击内层Select输入框。预期结果是内层下拉正常展开、选中选项时外层 Popover 保持打开而不再是内层下拉一出现外层就消失。限制说明修复对象是内层下拉组件不要给外层Popover设置withinPortal{false}那是改变外层自身的渲染位置不是本问题的解决方式。该方案只解决点击内层下拉导致外层关闭的问题。外层 Popover 自身仍受closeOnClickOutside默认true控制真正点击到两个 Popover 之外的区域时外层依旧会关闭这是正常行为。如果内层组件文档中没有暴露对应的透传 prop以该组件的文档为准查找禁用 Portal 的方式不要在源文档未说明的情况下猜测 prop 名。更多上下文见 Popover 文档的 Nested popovers 小节 和 FAQ 原文。【免费下载链接】mantineA fully featured React components library项目地址: https://gitcode.com/GitHub_Trending/ma/mantine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表