From c2ed461ab85985985ef645f34dc7ee45f7666663 Mon Sep 17 00:00:00 2001 From: Allen Date: Thu, 14 Jul 2022 13:16:35 +0800 Subject: [PATCH] =?UTF-8?q?feat=20popover=20=E6=96=B0=E5=A2=9E=20container?= =?UTF-8?q?Selector=20=E7=94=A8=E4=BA=8E=E6=8C=87=E5=AE=9A=E6=8C=82?= =?UTF-8?q?=E8=BD=BD=E4=BD=8D=E7=BD=AE=20(#4871)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/zh-CN/components/form/select.md | 79 ++++++++++--------- packages/amis-core/src/components/Overlay.tsx | 18 ++++- packages/amis-core/src/utils/position.ts | 9 +++ .../amis-ui/src/components/Pagination.tsx | 9 +++ packages/amis-ui/src/components/Select.tsx | 3 + packages/amis/src/renderers/Pagination.tsx | 6 ++ 6 files changed, 83 insertions(+), 41 deletions(-) diff --git a/docs/zh-CN/components/form/select.md b/docs/zh-CN/components/form/select.md index c49cf7699..8c42ae779 100755 --- a/docs/zh-CN/components/form/select.md +++ b/docs/zh-CN/components/form/select.md @@ -996,45 +996,46 @@ leftOptions 动态加载,默认 source 接口是返回 options 部分,而 le 除了支持 [普通表单项属性表](./formitem#%E5%B1%9E%E6%80%A7%E8%A1%A8) 中的配置以外,还支持下面一些配置 -| 属性名 | 类型 | 默认值 | 说明 | -| ------------------ | --------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| options | `Array`或`Array` | | [选项组](./options#%E9%9D%99%E6%80%81%E9%80%89%E9%A1%B9%E7%BB%84-options) | -| source | [API](../../../docs/types/api) 或 [数据映射](../../../docs/concepts/data-mapping) | | [动态选项组](./options#%E5%8A%A8%E6%80%81%E9%80%89%E9%A1%B9%E7%BB%84-source) | -| autoComplete | [API](../../../docs/types/api) | | [自动提示补全](./options#%E8%87%AA%E5%8A%A8%E8%A1%A5%E5%85%A8-autocomplete) | -| delimiter | `string` | `false` | [拼接符](./options#%E6%8B%BC%E6%8E%A5%E7%AC%A6-delimiter) | -| labelField | `string` | `"label"` | [选项标签字段](./options#%E9%80%89%E9%A1%B9%E6%A0%87%E7%AD%BE%E5%AD%97%E6%AE%B5-labelfield) | -| valueField | `string` | `"value"` | [选项值字段](./options#%E9%80%89%E9%A1%B9%E5%80%BC%E5%AD%97%E6%AE%B5-valuefield) | -| joinValues | `boolean` | `true` | [拼接值](./options#%E6%8B%BC%E6%8E%A5%E5%80%BC-joinvalues) | -| extractValue | `boolean` | `false` | [提取值](./options#%E6%8F%90%E5%8F%96%E5%A4%9A%E9%80%89%E5%80%BC-extractvalue) | -| checkAll | `boolean` | `false` | 是否支持全选 | -| checkAllLabel | `string` | `全选` | 全选的文字 | -| checkAllBySearch | `boolean` | `false` | 有检索时只全选检索命中的项 | -| defaultCheckAll | `boolean` | `false` | 默认是否全选 | -| creatable | `boolean` | `false` | [新增选项](./options#%E5%89%8D%E7%AB%AF%E6%96%B0%E5%A2%9E-creatable) | -| multiple | `boolean` | `false` | [多选](./options#多选-multiple) | -| searchable | `boolean` | `false` | [检索](./options#检索-searchable) | -| createBtnLabel | `string` | `"新增选项"` | [新增选项](./options#%E6%96%B0%E5%A2%9E%E9%80%89%E9%A1%B9) | -| addControls | Array<[表单项](./formitem)> | | [自定义新增表单项](./options#%E8%87%AA%E5%AE%9A%E4%B9%89%E6%96%B0%E5%A2%9E%E8%A1%A8%E5%8D%95%E9%A1%B9-addcontrols) | -| addApi | [API](../../docs/types/api) | | [配置新增选项接口](./options#%E9%85%8D%E7%BD%AE%E6%96%B0%E5%A2%9E%E6%8E%A5%E5%8F%A3-addapi) | -| editable | `boolean` | `false` | [编辑选项](./options#%E5%89%8D%E7%AB%AF%E7%BC%96%E8%BE%91-editable) | -| editControls | Array<[表单项](./formitem)> | | [自定义编辑表单项](./options#%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BC%96%E8%BE%91%E8%A1%A8%E5%8D%95%E9%A1%B9-editcontrols) | -| editApi | [API](../../docs/types/api) | | [配置编辑选项接口](./options#%E9%85%8D%E7%BD%AE%E7%BC%96%E8%BE%91%E6%8E%A5%E5%8F%A3-editapi) | -| removable | `boolean` | `false` | [删除选项](./options#%E5%88%A0%E9%99%A4%E9%80%89%E9%A1%B9) | -| deleteApi | [API](../../docs/types/api) | | [配置删除选项接口](./options#%E9%85%8D%E7%BD%AE%E5%88%A0%E9%99%A4%E6%8E%A5%E5%8F%A3-deleteapi) | -| autoFill | `object` | | [自动填充](./options#%E8%87%AA%E5%8A%A8%E5%A1%AB%E5%85%85-autofill) | -| menuTpl | `string` | | 支持配置自定义菜单 | -| clearable | `boolean` | | 单选模式下是否支持清空 | -| hideSelected | `boolean` | `false` | 隐藏已选选项 | -| mobileClassName | `string` | | 移动端浮层类名 | -| selectMode | `string` | `` | 可选:`group`、`table`、`tree`、`chained`、`associated`。分别为:列表形式、表格形式、树形选择形式、级联选择形式,关联选择形式(与级联选择的区别在于,级联是无限极,而关联只有一级,关联左边可以是个 tree)。 | -| searchResultMode | `string` | | 如果不设置将采用 `selectMode` 的值,可以单独配置,参考 `selectMode`,决定搜索结果的展示形式。 | -| columns | `Array` | | 当展示形式为 `table` 可以用来配置展示哪些列,跟 table 中的 columns 配置相似,只是只有展示功能。 | -| leftOptions | `Array` | | 当展示形式为 `associated` 时用来配置左边的选项集。 | -| leftMode | `string` | | 当展示形式为 `associated` 时用来配置左边的选择形式,支持 `list` 或者 `tree`。默认为 `list`。 | -| rightMode | `string` | | 当展示形式为 `associated` 时用来配置右边的选择形式,可选:`list`、`table`、`tree`、`chained`。 | -| maxTagCount | `number` | | 标签的最大展示数量,超出数量后以收纳浮层的方式展示,仅在多选模式开启后生效 | -| overflowTagPopover | `TooltipObject` | `{"placement": "top", "trigger": "hover", "showArrow": false, "offset": [0, -10]}` | 收纳浮层的配置属性,详细配置参考[Tooltip](../tooltip#属性表) | -| optionClassName | `string` | | 选项 CSS 类名 | +| 属性名 | 类型 | 默认值 | 说明 | +| ------------------------ | --------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| options | `Array`或`Array` | | [选项组](./options#%E9%9D%99%E6%80%81%E9%80%89%E9%A1%B9%E7%BB%84-options) | +| source | [API](../../../docs/types/api) 或 [数据映射](../../../docs/concepts/data-mapping) | | [动态选项组](./options#%E5%8A%A8%E6%80%81%E9%80%89%E9%A1%B9%E7%BB%84-source) | +| autoComplete | [API](../../../docs/types/api) | | [自动提示补全](./options#%E8%87%AA%E5%8A%A8%E8%A1%A5%E5%85%A8-autocomplete) | +| delimiter | `string` | `false` | [拼接符](./options#%E6%8B%BC%E6%8E%A5%E7%AC%A6-delimiter) | +| labelField | `string` | `"label"` | [选项标签字段](./options#%E9%80%89%E9%A1%B9%E6%A0%87%E7%AD%BE%E5%AD%97%E6%AE%B5-labelfield) | +| valueField | `string` | `"value"` | [选项值字段](./options#%E9%80%89%E9%A1%B9%E5%80%BC%E5%AD%97%E6%AE%B5-valuefield) | +| joinValues | `boolean` | `true` | [拼接值](./options#%E6%8B%BC%E6%8E%A5%E5%80%BC-joinvalues) | +| extractValue | `boolean` | `false` | [提取值](./options#%E6%8F%90%E5%8F%96%E5%A4%9A%E9%80%89%E5%80%BC-extractvalue) | +| checkAll | `boolean` | `false` | 是否支持全选 | +| checkAllLabel | `string` | `全选` | 全选的文字 | +| checkAllBySearch | `boolean` | `false` | 有检索时只全选检索命中的项 | +| defaultCheckAll | `boolean` | `false` | 默认是否全选 | +| creatable | `boolean` | `false` | [新增选项](./options#%E5%89%8D%E7%AB%AF%E6%96%B0%E5%A2%9E-creatable) | +| multiple | `boolean` | `false` | [多选](./options#多选-multiple) | +| searchable | `boolean` | `false` | [检索](./options#检索-searchable) | +| createBtnLabel | `string` | `"新增选项"` | [新增选项](./options#%E6%96%B0%E5%A2%9E%E9%80%89%E9%A1%B9) | +| addControls | Array<[表单项](./formitem)> | | [自定义新增表单项](./options#%E8%87%AA%E5%AE%9A%E4%B9%89%E6%96%B0%E5%A2%9E%E8%A1%A8%E5%8D%95%E9%A1%B9-addcontrols) | +| addApi | [API](../../docs/types/api) | | [配置新增选项接口](./options#%E9%85%8D%E7%BD%AE%E6%96%B0%E5%A2%9E%E6%8E%A5%E5%8F%A3-addapi) | +| editable | `boolean` | `false` | [编辑选项](./options#%E5%89%8D%E7%AB%AF%E7%BC%96%E8%BE%91-editable) | +| editControls | Array<[表单项](./formitem)> | | [自定义编辑表单项](./options#%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BC%96%E8%BE%91%E8%A1%A8%E5%8D%95%E9%A1%B9-editcontrols) | +| editApi | [API](../../docs/types/api) | | [配置编辑选项接口](./options#%E9%85%8D%E7%BD%AE%E7%BC%96%E8%BE%91%E6%8E%A5%E5%8F%A3-editapi) | +| removable | `boolean` | `false` | [删除选项](./options#%E5%88%A0%E9%99%A4%E9%80%89%E9%A1%B9) | +| deleteApi | [API](../../docs/types/api) | | [配置删除选项接口](./options#%E9%85%8D%E7%BD%AE%E5%88%A0%E9%99%A4%E6%8E%A5%E5%8F%A3-deleteapi) | +| autoFill | `object` | | [自动填充](./options#%E8%87%AA%E5%8A%A8%E5%A1%AB%E5%85%85-autofill) | +| menuTpl | `string` | | 支持配置自定义菜单 | +| clearable | `boolean` | | 单选模式下是否支持清空 | +| hideSelected | `boolean` | `false` | 隐藏已选选项 | +| mobileClassName | `string` | | 移动端浮层类名 | +| selectMode | `string` | `` | 可选:`group`、`table`、`tree`、`chained`、`associated`。分别为:列表形式、表格形式、树形选择形式、级联选择形式,关联选择形式(与级联选择的区别在于,级联是无限极,而关联只有一级,关联左边可以是个 tree)。 | +| searchResultMode | `string` | | 如果不设置将采用 `selectMode` 的值,可以单独配置,参考 `selectMode`,决定搜索结果的展示形式。 | +| columns | `Array` | | 当展示形式为 `table` 可以用来配置展示哪些列,跟 table 中的 columns 配置相似,只是只有展示功能。 | +| leftOptions | `Array` | | 当展示形式为 `associated` 时用来配置左边的选项集。 | +| leftMode | `string` | | 当展示形式为 `associated` 时用来配置左边的选择形式,支持 `list` 或者 `tree`。默认为 `list`。 | +| rightMode | `string` | | 当展示形式为 `associated` 时用来配置右边的选择形式,可选:`list`、`table`、`tree`、`chained`。 | +| maxTagCount | `number` | | 标签的最大展示数量,超出数量后以收纳浮层的方式展示,仅在多选模式开启后生效 | +| overflowTagPopover | `TooltipObject` | `{"placement": "top", "trigger": "hover", "showArrow": false, "offset": [0, -10]}` | 收纳浮层的配置属性,详细配置参考[Tooltip](../tooltip#属性表) | +| optionClassName | `string` | | 选项 CSS 类名 | +| popOverContainerSelector | `string` | | 弹层挂载位置选择器,会通过`querySelector`获取 | ## 事件表 diff --git a/packages/amis-core/src/components/Overlay.tsx b/packages/amis-core/src/components/Overlay.tsx index 4204ed5e7..25200d93c 100644 --- a/packages/amis-core/src/components/Overlay.tsx +++ b/packages/amis-core/src/components/Overlay.tsx @@ -179,6 +179,7 @@ interface OverlayProps { rootClose?: boolean; onHide?(props: any, ...args: any[]): any; container?: React.ReactNode | Function; + containerSelector?: string; target?: React.ReactNode | Function; watchTargetSizeChange?: boolean; offset?: [number, number]; @@ -235,9 +236,20 @@ export default class Overlay extends React.Component< } } + @autobind + getContainerSelector() { + const containerSelector = this.props.containerSelector; + let container = null; + + if (typeof containerSelector === 'string') { + container = document.querySelector(containerSelector); + } + + return container; + } + render() { const { - container, containerPadding, target, placement, @@ -249,7 +261,9 @@ export default class Overlay extends React.Component< offset, ...props } = this.props; - + const container = this.getContainerSelector() + ? this.getContainerSelector + : this.props.container; const mountOverlay = props.show || (Transition && !this.state.exited); if (!mountOverlay) { // Don't bother showing anything if we don't have to. diff --git a/packages/amis-core/src/utils/position.ts b/packages/amis-core/src/utils/position.ts index da5f5862a..0992edff0 100644 --- a/packages/amis-core/src/utils/position.ts +++ b/packages/amis-core/src/utils/position.ts @@ -25,6 +25,15 @@ export function position(node: HTMLElement, offsetParent?: HTMLElement) { const parent: HTMLElement = offsetParent || getOffsetParent(node); offset = getOffset(node); + if (parent === node) { + return { + top: 0, + left: 0, + width: offset.width, + height: offset.height + }; + } + if (nodeName(parent) !== 'html') parentOffset = getOffset(parent); const borderTop = String( getComputedStyle(parent).getPropertyValue('border-top-width') || 0 diff --git a/packages/amis-ui/src/components/Pagination.tsx b/packages/amis-ui/src/components/Pagination.tsx index f185e42ca..644cdeecc 100644 --- a/packages/amis-ui/src/components/Pagination.tsx +++ b/packages/amis-ui/src/components/Pagination.tsx @@ -86,6 +86,13 @@ export interface BasicPaginationProps { disabled?: boolean; hasNext?: boolean; + + /** + * 弹层挂载节点 + * @default false + */ + popOverContainerSelector?: string; + onPageChange?: (page: number, perPage?: number) => void; } export interface PaginationProps @@ -257,6 +264,7 @@ export class Pagination extends React.Component< className, disabled, hasNext, + popOverContainerSelector, translate: __ } = this.props; const {pageNum, perPage} = this.state; @@ -475,6 +483,7 @@ export class Pagination extends React.Component< disabled={disabled} value={perPage} options={selection} + popOverContainerSelector={popOverContainerSelector} onChange={(p: any) => { this.setState({ perPage: p.value, diff --git a/packages/amis-ui/src/components/Select.tsx b/packages/amis-ui/src/components/Select.tsx index 1925cc2ab..b1b2a36f6 100644 --- a/packages/amis-ui/src/components/Select.tsx +++ b/packages/amis-ui/src/components/Select.tsx @@ -332,6 +332,7 @@ interface SelectProps extends OptionProps, ThemeProps, LocaleProps { inline: boolean; disabled: boolean; popOverContainer?: any; + popOverContainerSelector?: string; overlayPlacement?: string; onChange: (value: void | string | Option | Array