From 564fe24c8a03e287a2e776b302ebcfee6dd5c002 Mon Sep 17 00:00:00 2001 From: katherinehhh Date: Sat, 22 Apr 2023 10:36:21 +0800 Subject: [PATCH] style: automatically omit table cell content based on width (#1646) * style: automatically omit cell content based on width * fix: cell tooltips are only displayed when the width is exceeded * chore: multiple select ellipsis in table collection * fix: no automatic thumbnail when table column content exceeds width * refactor: table ellipsis * refactor: isOverflowTooltip --- .../collection-manager/CollectionField.tsx | 10 -------- .../collection-manager/interfaces/checkbox.ts | 7 ++++++ .../interfaces/checkboxGroup.ts | 9 ++++++- .../interfaces/createdBy.ts | 6 ++++- .../collection-manager/interfaces/email.ts | 9 ++++++- .../interfaces/multipleSelect.ts | 9 ++++++- .../collection-manager/interfaces/select.ts | 7 ++++++ .../interfaces/updatedBy.ts | 6 ++++- .../antd/checkbox/Checkbox.tsx | 24 ++++++++---------- .../antd/input/EllipsisWithTooltip.tsx | 25 +++++++++++++++++-- .../antd/select/ReadPretty.tsx | 14 +++++++---- 11 files changed, 90 insertions(+), 36 deletions(-) diff --git a/packages/core/client/src/collection-manager/CollectionField.tsx b/packages/core/client/src/collection-manager/CollectionField.tsx index e912de790..af8029c6c 100644 --- a/packages/core/client/src/collection-manager/CollectionField.tsx +++ b/packages/core/client/src/collection-manager/CollectionField.tsx @@ -58,16 +58,6 @@ const InternalField: React.FC = (props) => { const originalProps = compile(uiSchema['x-component-props']) || {}; const componentProps = merge(originalProps, field.componentProps || {}); field.component = [component, componentProps]; - - // if (interfaceType === 'input') { - // field.componentProps.ellipsis = true; - // } else if (interfaceType === 'textarea') { - // field.componentProps.ellipsis = true; - // } else if (interfaceType === 'markdown') { - // field.componentProps.ellipsis = true; - // } else if (interfaceType === 'attachment') { - // field.componentProps.size = 'small'; - // } }, [JSON.stringify(uiSchema)]); if (!uiSchema) { return null; diff --git a/packages/core/client/src/collection-manager/interfaces/checkbox.ts b/packages/core/client/src/collection-manager/interfaces/checkbox.ts index 6f3d783a1..511d71fda 100644 --- a/packages/core/client/src/collection-manager/interfaces/checkbox.ts +++ b/packages/core/client/src/collection-manager/interfaces/checkbox.ts @@ -1,3 +1,4 @@ +import { ISchema } from '@formily/react'; import { defaultProps, operators } from './properties'; import { IField } from './types'; @@ -23,4 +24,10 @@ export const checkbox: IField = { filterable: { operators: operators.boolean, }, + schemaInitialize(schema: ISchema, { block }) { + if (['Table', 'Kanban'].includes(block)) { + schema['x-component-props'] = schema['x-component-props'] || {}; + schema['x-component-props']['ellipsis'] = true; + } + }, }; diff --git a/packages/core/client/src/collection-manager/interfaces/checkboxGroup.ts b/packages/core/client/src/collection-manager/interfaces/checkboxGroup.ts index 539a250e7..15dfbabd6 100644 --- a/packages/core/client/src/collection-manager/interfaces/checkboxGroup.ts +++ b/packages/core/client/src/collection-manager/interfaces/checkboxGroup.ts @@ -1,3 +1,4 @@ +import { ISchema } from '@formily/react'; import { dataSource, defaultProps, operators } from './properties'; import { IField } from './types'; @@ -17,7 +18,7 @@ export const checkboxGroup: IField = { 'x-component': 'Checkbox.Group', }, }, - availableTypes:['array'], + availableTypes: ['array'], hasDefaultValue: true, properties: { ...defaultProps, @@ -26,4 +27,10 @@ export const checkboxGroup: IField = { filterable: { operators: operators.array, }, + schemaInitialize(schema: ISchema, { block }) { + if (['Table', 'Kanban'].includes(block)) { + schema['x-component-props'] = schema['x-component-props'] || {}; + schema['x-component-props']['ellipsis'] = true; + } + }, }; diff --git a/packages/core/client/src/collection-manager/interfaces/createdBy.ts b/packages/core/client/src/collection-manager/interfaces/createdBy.ts index 07b5569ad..9fc357ab9 100644 --- a/packages/core/client/src/collection-manager/interfaces/createdBy.ts +++ b/packages/core/client/src/collection-manager/interfaces/createdBy.ts @@ -56,9 +56,13 @@ export const createdBy: IField = { }, ], }, - schemaInitialize(schema: ISchema, { readPretty }) { + schemaInitialize(schema: ISchema, { block }) { schema['properties'] = { viewer: cloneDeep(recordPickerViewer), }; + if (['Table', 'Kanban'].includes(block)) { + schema['x-component-props'] = schema['x-component-props'] || {}; + schema['x-component-props']['ellipsis'] = true; + } }, }; diff --git a/packages/core/client/src/collection-manager/interfaces/email.ts b/packages/core/client/src/collection-manager/interfaces/email.ts index fa6a1a1b0..2f026d015 100644 --- a/packages/core/client/src/collection-manager/interfaces/email.ts +++ b/packages/core/client/src/collection-manager/interfaces/email.ts @@ -1,3 +1,4 @@ +import { ISchema } from '@formily/react'; import { defaultProps, operators, unique } from './properties'; import { IField } from './types'; @@ -18,7 +19,7 @@ export const email: IField = { 'x-validator': 'email', }, }, - availableTypes:['string'], + availableTypes: ['string'], hasDefaultValue: true, properties: { ...defaultProps, @@ -27,4 +28,10 @@ export const email: IField = { filterable: { operators: operators.string, }, + schemaInitialize(schema: ISchema, { block }) { + if (['Table', 'Kanban'].includes(block)) { + schema['x-component-props'] = schema['x-component-props'] || {}; + schema['x-component-props']['ellipsis'] = true; + } + }, }; diff --git a/packages/core/client/src/collection-manager/interfaces/multipleSelect.ts b/packages/core/client/src/collection-manager/interfaces/multipleSelect.ts index 44bcc1887..e4ecd8711 100644 --- a/packages/core/client/src/collection-manager/interfaces/multipleSelect.ts +++ b/packages/core/client/src/collection-manager/interfaces/multipleSelect.ts @@ -1,3 +1,4 @@ +import { ISchema } from '@formily/react'; import { dataSource, defaultProps, operators } from './properties'; import { IField } from './types'; @@ -21,7 +22,7 @@ export const multipleSelect: IField = { enum: [], }, }, - availableTypes:['array'], + availableTypes: ['array'], hasDefaultValue: true, properties: { ...defaultProps, @@ -30,4 +31,10 @@ export const multipleSelect: IField = { filterable: { operators: operators.array, }, + schemaInitialize(schema: ISchema, { block }) { + if (['Table', 'Kanban'].includes(block)) { + schema['x-component-props'] = schema['x-component-props'] || {}; + schema['x-component-props']['ellipsis'] = true; + } + }, }; diff --git a/packages/core/client/src/collection-manager/interfaces/select.ts b/packages/core/client/src/collection-manager/interfaces/select.ts index 7141c4c7d..605c8e7f5 100644 --- a/packages/core/client/src/collection-manager/interfaces/select.ts +++ b/packages/core/client/src/collection-manager/interfaces/select.ts @@ -1,3 +1,4 @@ +import { ISchema } from '@formily/react'; import { dataSource, defaultProps, operators } from './properties'; import { IField } from './types'; @@ -27,4 +28,10 @@ export const select: IField = { filterable: { operators: operators.enumType, }, + schemaInitialize(schema: ISchema, { block }) { + if (['Table', 'Kanban'].includes(block)) { + schema['x-component-props'] = schema['x-component-props'] || {}; + schema['x-component-props']['ellipsis'] = true; + } + }, }; diff --git a/packages/core/client/src/collection-manager/interfaces/updatedBy.ts b/packages/core/client/src/collection-manager/interfaces/updatedBy.ts index 5b58133ae..32ddff4e6 100644 --- a/packages/core/client/src/collection-manager/interfaces/updatedBy.ts +++ b/packages/core/client/src/collection-manager/interfaces/updatedBy.ts @@ -55,9 +55,13 @@ export const updatedBy: IField = { }, ], }, - schemaInitialize(schema: ISchema, { readPretty }) { + schemaInitialize(schema: ISchema, { block }) { schema['properties'] = { viewer: cloneDeep(recordPickerViewer), }; + if (['Table', 'Kanban'].includes(block)) { + schema['x-component-props'] = schema['x-component-props'] || {}; + schema['x-component-props']['ellipsis'] = true; + } }, }; diff --git a/packages/core/client/src/schema-component/antd/checkbox/Checkbox.tsx b/packages/core/client/src/schema-component/antd/checkbox/Checkbox.tsx index e8e163763..39e9abb4f 100644 --- a/packages/core/client/src/schema-component/antd/checkbox/Checkbox.tsx +++ b/packages/core/client/src/schema-component/antd/checkbox/Checkbox.tsx @@ -5,6 +5,7 @@ import { Checkbox as AntdCheckbox, Tag } from 'antd'; import type { CheckboxGroupProps, CheckboxProps } from 'antd/lib/checkbox'; import uniq from 'lodash/uniq'; import React from 'react'; +import { EllipsisWithTooltip } from '../input/EllipsisWithTooltip'; type ComposedCheckbox = React.FC & { Group?: React.FC; @@ -18,12 +19,10 @@ export const Checkbox: ComposedCheckbox = connect( }; return ; }, - mapProps( - { - value: 'checked', - onInput: 'onChange', - }, - ), + mapProps({ + value: 'checked', + onInput: 'onChange', + }), mapReadPretty((props) => { if (props.value) { return ; @@ -36,21 +35,18 @@ Checkbox.__ANT_CHECKBOX = true; Checkbox.Group = connect( AntdCheckbox.Group, - mapProps( - { - dataSource: 'options', - }, - ), + mapProps({ + dataSource: 'options', + }), mapReadPretty((props) => { if (!isValid(props.value)) { return null; } - const { options = [] } = props; const field = useField(); const dataSource = field.dataSource || []; const value = uniq(field.value ? field.value : []); return ( -
+ {dataSource .filter((option) => value.includes(option.value)) .map((option, key) => ( @@ -58,7 +54,7 @@ Checkbox.Group = connect( {option.label} ))} -
+ ); }), ); diff --git a/packages/core/client/src/schema-component/antd/input/EllipsisWithTooltip.tsx b/packages/core/client/src/schema-component/antd/input/EllipsisWithTooltip.tsx index b5b5e9bae..4b4244a8d 100644 --- a/packages/core/client/src/schema-component/antd/input/EllipsisWithTooltip.tsx +++ b/packages/core/client/src/schema-component/antd/input/EllipsisWithTooltip.tsx @@ -1,6 +1,14 @@ import { Popover } from 'antd'; -import React, { CSSProperties, forwardRef, useImperativeHandle, useState } from 'react'; +import React, { CSSProperties, forwardRef, useImperativeHandle, useState, useRef } from 'react'; +const getContentWidth = (element) => { + if (element) { + const range = document.createRange(); + range.selectNodeContents(element); + const contentWidth = range.getBoundingClientRect().width; + return contentWidth; + } +}; const ellipsisDefaultStyle: CSSProperties = { overflow: 'hidden', overflowWrap: 'break-word', @@ -14,9 +22,11 @@ interface IEllipsisWithTooltipProps { popoverContent: unknown; children: any; } + export const EllipsisWithTooltip = forwardRef((props: Partial, ref: any) => { const [ellipsis, setEllipsis] = useState(false); const [visible, setVisible] = useState(false); + const elRef: any = useRef(); useImperativeHandle(ref, () => { return { setPopoverVisible: setVisible, @@ -26,6 +36,13 @@ export const EllipsisWithTooltip = forwardRef((props: Partial{props.children}; } const { popoverContent } = props; + + const isOverflowTooltip = () => { + const contentWidth = getContentWidth(elRef.current); + const offsetWidth = elRef.current?.offsetWidth; + return contentWidth > offsetWidth; + }; + return (
{ const el = e.target as any; - setEllipsis(el.scrollWidth > el.clientWidth); + const isShowTooltips = isOverflowTooltip(); + if (isShowTooltips) { + setEllipsis(el.scrollWidth >= el.clientWidth); + } }} > {props.children} diff --git a/packages/core/client/src/schema-component/antd/select/ReadPretty.tsx b/packages/core/client/src/schema-component/antd/select/ReadPretty.tsx index 150a02724..bc671620a 100644 --- a/packages/core/client/src/schema-component/antd/select/ReadPretty.tsx +++ b/packages/core/client/src/schema-component/antd/select/ReadPretty.tsx @@ -5,6 +5,7 @@ import { Tag } from 'antd'; import React from 'react'; import { useCompile } from '../../hooks'; import { defaultFieldNames, getCurrentOptions } from './shared'; +import { EllipsisWithTooltip } from '../input/EllipsisWithTooltip'; type Composed = { Select?: React.FC; @@ -24,13 +25,16 @@ export const ReadPretty = observer((props: any) => { } const dataSource = field.dataSource || props.options || []; const options = getCurrentOptions(field.value, dataSource, fieldNames); + return (
- {options.map((option, key) => ( - - {compile(option[fieldNames.label])} - - ))} + + {options.map((option, key) => ( + + {compile(option[fieldNames.label])} + + ))} +
); });