fix(client): ellipsis with tooltip
This commit is contained in:
parent
d7a9608663
commit
60a915b50c
@ -10,7 +10,7 @@ import { useCollectionField } from './hooks';
|
|||||||
const InternalField: React.FC = (props) => {
|
const InternalField: React.FC = (props) => {
|
||||||
const field = useField<Field>();
|
const field = useField<Field>();
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const { uiSchema } = useCollectionField();
|
const { name, uiSchema } = useCollectionField();
|
||||||
const component = useComponent(uiSchema?.['x-component']);
|
const component = useComponent(uiSchema?.['x-component']);
|
||||||
const compile = useCompile();
|
const compile = useCompile();
|
||||||
const setFieldProps = (key, value) => {
|
const setFieldProps = (key, value) => {
|
||||||
@ -34,9 +34,10 @@ const InternalField: React.FC = (props) => {
|
|||||||
setRequired();
|
setRequired();
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
field.dataSource = uiSchema.enum;
|
field.dataSource = uiSchema.enum;
|
||||||
const originalProps = compile(uiSchema['x-component-props']);
|
const originalProps = compile(uiSchema['x-component-props']) || {};
|
||||||
const componentProps = field.componentProps;
|
const componentProps = merge(originalProps, field.componentProps || {});
|
||||||
field.component = [component, merge(originalProps, componentProps)];
|
field.component = [component, componentProps];
|
||||||
|
// console.log('componentProps', uiSchema?.title, field.componentProps);
|
||||||
}, [uiSchema?.title, uiSchema?.description, uiSchema?.required]);
|
}, [uiSchema?.title, uiSchema?.description, uiSchema?.required]);
|
||||||
if (!uiSchema) {
|
if (!uiSchema) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
import { Popover } from 'antd';
|
||||||
|
import React, { CSSProperties, useState } from 'react';
|
||||||
|
|
||||||
|
const ellipsisDefaultStyle: CSSProperties = {
|
||||||
|
overflow: 'hidden',
|
||||||
|
overflowWrap: 'break-word',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
wordBreak: 'break-all',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const EllipsisWithTooltip = (props) => {
|
||||||
|
const [ellipsis, setEllipsis] = useState(false);
|
||||||
|
const [visible, setVisible] = useState(false);
|
||||||
|
if (!props.ellipsis) {
|
||||||
|
return <>{props.children}</>;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Popover
|
||||||
|
visible={ellipsis && visible}
|
||||||
|
onVisibleChange={(visible) => {
|
||||||
|
setVisible(ellipsis && visible);
|
||||||
|
}}
|
||||||
|
content={props.children}
|
||||||
|
overlayStyle={{
|
||||||
|
width: 300,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{ ...ellipsisDefaultStyle }}
|
||||||
|
onMouseEnter={(e) => {
|
||||||
|
const el = e.target as any;
|
||||||
|
setEllipsis(el.scrollWidth > el.clientWidth);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</div>
|
||||||
|
</Popover>
|
||||||
|
);
|
||||||
|
};
|
@ -1,9 +1,8 @@
|
|||||||
import { usePrefixCls } from '@formily/antd/lib/__builtins__';
|
import { usePrefixCls } from '@formily/antd/lib/__builtins__';
|
||||||
import { Popover } from 'antd';
|
|
||||||
import { InputProps, TextAreaProps } from 'antd/lib/input';
|
import { InputProps, TextAreaProps } from 'antd/lib/input';
|
||||||
import cls from 'classnames';
|
import cls from 'classnames';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React from 'react';
|
||||||
import { useCompile } from '../../hooks/useCompile';
|
import { EllipsisWithTooltip } from './EllipsisWithTooltip';
|
||||||
|
|
||||||
type Composed = {
|
type Composed = {
|
||||||
Input: React.FC<InputProps & { ellipsis?: any }>;
|
Input: React.FC<InputProps & { ellipsis?: any }>;
|
||||||
@ -15,25 +14,11 @@ export const ReadPretty: Composed = () => null;
|
|||||||
|
|
||||||
ReadPretty.Input = (props) => {
|
ReadPretty.Input = (props) => {
|
||||||
const prefixCls = usePrefixCls('description-input', props);
|
const prefixCls = usePrefixCls('description-input', props);
|
||||||
const domRef = React.useRef<HTMLInputElement>(null);
|
|
||||||
const compile = useCompile();
|
|
||||||
const [ellipsis, setEllipsis] = useState(false);
|
|
||||||
const content = compile(props.value);
|
|
||||||
const ellipsisContent = (
|
|
||||||
<Popover content={content} style={{ width: 100 }}>
|
|
||||||
<span className={'input-ellipsis'}>{content}</span>
|
|
||||||
</Popover>
|
|
||||||
);
|
|
||||||
useEffect(() => {
|
|
||||||
if (domRef.current?.scrollWidth > domRef.current?.clientWidth) {
|
|
||||||
setEllipsis(true);
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
return (
|
return (
|
||||||
<div className={cls(prefixCls, props.className)} style={props.style}>
|
<div className={cls(prefixCls, props.className)} style={props.style}>
|
||||||
{props.addonBefore}
|
{props.addonBefore}
|
||||||
{props.prefix}
|
{props.prefix}
|
||||||
<span ref={domRef}>{ellipsis ? ellipsisContent : content}</span>
|
<EllipsisWithTooltip ellipsis={props.ellipsis}>{props.value}</EllipsisWithTooltip>
|
||||||
{props.suffix}
|
{props.suffix}
|
||||||
{props.addonAfter}
|
{props.addonAfter}
|
||||||
</div>
|
</div>
|
||||||
@ -41,32 +26,13 @@ ReadPretty.Input = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ReadPretty.TextArea = (props) => {
|
ReadPretty.TextArea = (props) => {
|
||||||
|
console.log('EllipsisWithTooltip', props.ellipsis);
|
||||||
const prefixCls = usePrefixCls('description-textarea', props);
|
const prefixCls = usePrefixCls('description-textarea', props);
|
||||||
const domRef = React.useRef<HTMLInputElement>(null);
|
|
||||||
const [ellipsis, setEllipsis] = useState(false);
|
|
||||||
const ellipsisProp = props.ellipsis === true ? {} : props.ellipsis;
|
|
||||||
const ellipsisContent = (
|
|
||||||
<Popover content={props.value}>
|
|
||||||
<span
|
|
||||||
className={'input-ellipsis'}
|
|
||||||
style={{
|
|
||||||
...ellipsisProp,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{props.text || props.value}
|
|
||||||
</span>
|
|
||||||
</Popover>
|
|
||||||
);
|
|
||||||
useEffect(() => {
|
|
||||||
if (domRef.current?.scrollWidth > domRef.current?.clientWidth) {
|
|
||||||
setEllipsis(true);
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
return (
|
return (
|
||||||
<div className={cls(prefixCls, props.className)} style={props.style}>
|
<div className={cls(prefixCls, props.className)} style={props.style}>
|
||||||
{props.addonBefore}
|
{props.addonBefore}
|
||||||
{props.prefix}
|
{props.prefix}
|
||||||
<span ref={domRef}>{ellipsis ? ellipsisContent : props.value}</span>
|
<EllipsisWithTooltip ellipsis={props.ellipsis}>{props.value}</EllipsisWithTooltip>
|
||||||
{props.suffix}
|
{props.suffix}
|
||||||
{props.addonAfter}
|
{props.addonAfter}
|
||||||
</div>
|
</div>
|
||||||
|
@ -87,6 +87,20 @@ export const components = {
|
|||||||
row: (props) => {
|
row: (props) => {
|
||||||
return <tr {...props} />;
|
return <tr {...props} />;
|
||||||
},
|
},
|
||||||
|
cell: (props) => (
|
||||||
|
<td
|
||||||
|
{...props}
|
||||||
|
className={classNames(
|
||||||
|
props.className,
|
||||||
|
css`
|
||||||
|
max-width: 300px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
`,
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -228,7 +242,14 @@ export const TableArray: React.FC<any> = observer((props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div
|
||||||
|
className={css`
|
||||||
|
.ant-table {
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
>
|
||||||
<ReactDragListView
|
<ReactDragListView
|
||||||
handleSelector={'.drag-handle'}
|
handleSelector={'.drag-handle'}
|
||||||
onDragEnd={async (fromIndex, toIndex) => {
|
onDragEnd={async (fromIndex, toIndex) => {
|
||||||
|
@ -61,6 +61,28 @@ export const useTableColumnInitializerFields = () => {
|
|||||||
return fields
|
return fields
|
||||||
.filter((field) => field?.interface && field?.interface !== 'subTable')
|
.filter((field) => field?.interface && field?.interface !== 'subTable')
|
||||||
.map((field) => {
|
.map((field) => {
|
||||||
|
const componentProps = {};
|
||||||
|
if (field?.uiSchema['x-component']?.startsWith?.('Input')) {
|
||||||
|
componentProps['ellipsis'] = true;
|
||||||
|
}
|
||||||
|
if (field.interface === 'attachment') {
|
||||||
|
componentProps['size'] = 'small';
|
||||||
|
return {
|
||||||
|
type: 'item',
|
||||||
|
title: field?.uiSchema?.title || field.name,
|
||||||
|
component: 'CollectionFieldInitializer',
|
||||||
|
find: findTableColumn,
|
||||||
|
remove: removeTableColumn,
|
||||||
|
schema: {
|
||||||
|
name: field.name,
|
||||||
|
'x-collection-field': `${name}.${field.name}`,
|
||||||
|
'x-component': 'CollectionField',
|
||||||
|
'x-component-props': {
|
||||||
|
...componentProps,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as SchemaInitializerItemOptions;
|
||||||
|
}
|
||||||
if (field.target) {
|
if (field.target) {
|
||||||
return {
|
return {
|
||||||
field,
|
field,
|
||||||
@ -73,13 +95,12 @@ export const useTableColumnInitializerFields = () => {
|
|||||||
name: field.name,
|
name: field.name,
|
||||||
'x-collection-field': `${name}.${field.name}`,
|
'x-collection-field': `${name}.${field.name}`,
|
||||||
'x-component': 'CollectionField',
|
'x-component': 'CollectionField',
|
||||||
|
'x-component-props': {
|
||||||
|
...componentProps,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
} as SchemaInitializerItemOptions;
|
} as SchemaInitializerItemOptions;
|
||||||
}
|
}
|
||||||
const componentProps = {};
|
|
||||||
if (field.interface === 'attachment') {
|
|
||||||
componentProps['size'] = 'small';
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
type: 'item',
|
type: 'item',
|
||||||
title: field?.uiSchema?.title || field.name,
|
title: field?.uiSchema?.title || field.name,
|
||||||
|
Loading…
Reference in New Issue
Block a user