feat: update typography
parent
2191656479
commit
5771e505c7
|
@ -155,5 +155,6 @@ export default function calculateNodeHeight(
|
||||||
minHeight: `${minHeight}px`,
|
minHeight: `${minHeight}px`,
|
||||||
maxHeight: `${maxHeight}px`,
|
maxHeight: `${maxHeight}px`,
|
||||||
overflowY,
|
overflowY,
|
||||||
|
resize: 'none',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,8 @@ import {
|
||||||
watchEffect,
|
watchEffect,
|
||||||
nextTick,
|
nextTick,
|
||||||
CSSProperties,
|
CSSProperties,
|
||||||
toRaw,
|
|
||||||
computed,
|
computed,
|
||||||
|
toRaw,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
import { AutoSizeType } from '../input/ResizableTextArea';
|
import { AutoSizeType } from '../input/ResizableTextArea';
|
||||||
import useConfigInject from '../_util/hooks/useConfigInject';
|
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||||
|
@ -37,29 +37,19 @@ export type BaseType = 'secondary' | 'success' | 'warning' | 'danger';
|
||||||
const isLineClampSupport = isStyleSupport('webkitLineClamp');
|
const isLineClampSupport = isStyleSupport('webkitLineClamp');
|
||||||
const isTextOverflowSupport = isStyleSupport('textOverflow');
|
const isTextOverflowSupport = isStyleSupport('textOverflow');
|
||||||
|
|
||||||
function toArray(value: any) {
|
|
||||||
let ret = value;
|
|
||||||
if (value === undefined) {
|
|
||||||
ret = [];
|
|
||||||
} else if (!Array.isArray(value)) {
|
|
||||||
ret = [value];
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CopyConfig {
|
interface CopyConfig {
|
||||||
text?: string;
|
text?: string;
|
||||||
onCopy?: () => void;
|
onCopy?: () => void;
|
||||||
icon?: VNodeTypes;
|
tooltip?: boolean;
|
||||||
tooltips?: boolean | VNodeTypes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EditConfig {
|
interface EditConfig {
|
||||||
editing?: boolean;
|
editing?: boolean;
|
||||||
icon?: VNodeTypes;
|
tooltip?: boolean;
|
||||||
tooltip?: boolean | VNodeTypes;
|
|
||||||
onStart?: () => void;
|
onStart?: () => void;
|
||||||
onChange?: (value: string) => void;
|
onChange?: (value: string) => void;
|
||||||
|
onCancel?: () => void;
|
||||||
|
onEnd?: () => void;
|
||||||
maxlength?: number;
|
maxlength?: number;
|
||||||
autoSize?: boolean | AutoSizeType;
|
autoSize?: boolean | AutoSizeType;
|
||||||
}
|
}
|
||||||
|
@ -71,7 +61,7 @@ export interface EllipsisConfig {
|
||||||
symbol?: VNodeTypes;
|
symbol?: VNodeTypes;
|
||||||
onExpand?: EventHandlerNonNull;
|
onExpand?: EventHandlerNonNull;
|
||||||
onEllipsis?: (ellipsis: boolean) => void;
|
onEllipsis?: (ellipsis: boolean) => void;
|
||||||
tooltip?: boolean | VNodeTypes;
|
tooltip?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BlockProps extends TypographyProps {
|
export interface BlockProps extends TypographyProps {
|
||||||
|
@ -107,7 +97,8 @@ const ELLIPSIS_STR = '...';
|
||||||
const Base = defineComponent<InternalBlockProps>({
|
const Base = defineComponent<InternalBlockProps>({
|
||||||
name: 'Base',
|
name: 'Base',
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
setup(props, { slots, attrs }) {
|
emits: ['update:content'],
|
||||||
|
setup(props, { slots, attrs, emit }) {
|
||||||
const { prefixCls } = useConfigInject('typography', props);
|
const { prefixCls } = useConfigInject('typography', props);
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
|
@ -127,6 +118,8 @@ const Base = defineComponent<InternalBlockProps>({
|
||||||
copyId: undefined,
|
copyId: undefined,
|
||||||
rafId: undefined,
|
rafId: undefined,
|
||||||
prevProps: undefined,
|
prevProps: undefined,
|
||||||
|
|
||||||
|
originContent: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const contentRef = ref();
|
const contentRef = ref();
|
||||||
|
@ -186,7 +179,7 @@ const Base = defineComponent<InternalBlockProps>({
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChildrenText(): string {
|
function getChildrenText(): string {
|
||||||
return props.ellipsis || props.editable ? props.content : contentRef.value.text;
|
return props.ellipsis || props.editable ? props.content : contentRef.value?.$el?.innerText;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============== Expand ===============
|
// =============== Expand ===============
|
||||||
|
@ -197,15 +190,21 @@ const Base = defineComponent<InternalBlockProps>({
|
||||||
}
|
}
|
||||||
// ================ Edit ================
|
// ================ Edit ================
|
||||||
function onEditClick() {
|
function onEditClick() {
|
||||||
|
state.originContent = props.content;
|
||||||
triggerEdit(true);
|
triggerEdit(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onEditChange(value: string) {
|
function onEditChange(value: string) {
|
||||||
const { onChange } = editable.value;
|
onContentChange(value);
|
||||||
onChange?.(value);
|
|
||||||
|
|
||||||
triggerEdit(false);
|
triggerEdit(false);
|
||||||
}
|
}
|
||||||
|
function onContentChange(value: string) {
|
||||||
|
const { onChange } = editable.value;
|
||||||
|
if (value !== props.content) {
|
||||||
|
onChange?.(value);
|
||||||
|
emit('update:content', value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function onEditCancel() {
|
function onEditCancel() {
|
||||||
triggerEdit(false);
|
triggerEdit(false);
|
||||||
|
@ -290,7 +289,14 @@ const Base = defineComponent<InternalBlockProps>({
|
||||||
const syncEllipsis = () => {
|
const syncEllipsis = () => {
|
||||||
const { ellipsisText, isEllipsis } = state;
|
const { ellipsisText, isEllipsis } = state;
|
||||||
const { rows, suffix, onEllipsis } = ellipsis.value;
|
const { rows, suffix, onEllipsis } = ellipsis.value;
|
||||||
if (!rows || rows < 0 || !contentRef.value?.$el || state.expanded) return;
|
if (
|
||||||
|
!rows ||
|
||||||
|
rows < 0 ||
|
||||||
|
!contentRef.value?.$el ||
|
||||||
|
state.expanded ||
|
||||||
|
props.content === undefined
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
// Do not measure if css already support ellipsis
|
// Do not measure if css already support ellipsis
|
||||||
if (canUseCSSEllipsis.value) return;
|
if (canUseCSSEllipsis.value) return;
|
||||||
|
@ -365,9 +371,9 @@ const Base = defineComponent<InternalBlockProps>({
|
||||||
function renderEdit() {
|
function renderEdit() {
|
||||||
if (!props.editable) return;
|
if (!props.editable) return;
|
||||||
|
|
||||||
const { icon, tooltip } = props.editable as EditConfig;
|
const { tooltip } = props.editable as EditConfig;
|
||||||
|
const icon = slots.editableIcon ? slots.editableIcon() : <EditOutlined role="button" />;
|
||||||
const title = tooltip || state.editStr;
|
const title = slots.editableTooltip ? slots.editableTooltip() : state.editStr;
|
||||||
const ariaLabel = typeof title === 'string' ? title : '';
|
const ariaLabel = typeof title === 'string' ? title : '';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -378,7 +384,7 @@ const Base = defineComponent<InternalBlockProps>({
|
||||||
onClick={onEditClick}
|
onClick={onEditClick}
|
||||||
aria-label={ariaLabel}
|
aria-label={ariaLabel}
|
||||||
>
|
>
|
||||||
{icon || <EditOutlined role="button" />}
|
{icon}
|
||||||
</TransButton>
|
</TransButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
);
|
);
|
||||||
|
@ -387,17 +393,19 @@ const Base = defineComponent<InternalBlockProps>({
|
||||||
function renderCopy() {
|
function renderCopy() {
|
||||||
if (!props.copyable) return;
|
if (!props.copyable) return;
|
||||||
|
|
||||||
const { tooltips } = props.copyable as CopyConfig;
|
const { tooltip } = props.copyable as CopyConfig;
|
||||||
let tooltipNodes = toArray(tooltips) as VNodeTypes[];
|
const defaultTitle = state.copied ? state.copiedStr : state.copyStr;
|
||||||
if (tooltipNodes.length === 0) {
|
const title = slots.copyableTooltip
|
||||||
tooltipNodes = [state.copyStr, state.copiedStr];
|
? slots.copyableTooltip({ copied: state.copied })
|
||||||
}
|
: defaultTitle;
|
||||||
const title = state.copied ? tooltipNodes[1] : tooltipNodes[0];
|
|
||||||
const ariaLabel = typeof title === 'string' ? title : '';
|
const ariaLabel = typeof title === 'string' ? title : '';
|
||||||
const icons = toArray((props.copyable as CopyConfig).icon);
|
const defaultIcon = state.copied ? <CheckOutlined /> : <CopyOutlined />;
|
||||||
|
const icon = slots.copyableIcon
|
||||||
|
? slots.copyableIcon({ copied: !!state.copied })
|
||||||
|
: defaultIcon;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip key="copy" title={tooltips === false ? '' : title}>
|
<Tooltip key="copy" title={tooltip === false ? '' : title}>
|
||||||
<TransButton
|
<TransButton
|
||||||
class={[
|
class={[
|
||||||
`${prefixCls.value}-copy`,
|
`${prefixCls.value}-copy`,
|
||||||
|
@ -406,7 +414,7 @@ const Base = defineComponent<InternalBlockProps>({
|
||||||
onClick={onCopyClick}
|
onClick={onCopyClick}
|
||||||
aria-label={ariaLabel}
|
aria-label={ariaLabel}
|
||||||
>
|
>
|
||||||
{state.copied ? icons[1] || <CheckOutlined /> : icons[0] || <CopyOutlined />}
|
{icon}
|
||||||
</TransButton>
|
</TransButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
);
|
);
|
||||||
|
@ -422,9 +430,11 @@ const Base = defineComponent<InternalBlockProps>({
|
||||||
style={style}
|
style={style}
|
||||||
prefixCls={prefixCls.value}
|
prefixCls={prefixCls.value}
|
||||||
value={props.content}
|
value={props.content}
|
||||||
|
originContent={state.originContent}
|
||||||
maxlength={maxlength}
|
maxlength={maxlength}
|
||||||
autoSize={autoSize}
|
autoSize={autoSize}
|
||||||
onSave={onEditChange}
|
onSave={onEditChange}
|
||||||
|
onChange={onContentChange}
|
||||||
onCancel={onEditCancel}
|
onCancel={onEditCancel}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -438,7 +448,9 @@ const Base = defineComponent<InternalBlockProps>({
|
||||||
const { editing } = editable.value;
|
const { editing } = editable.value;
|
||||||
const children =
|
const children =
|
||||||
props.ellipsis || props.editable
|
props.ellipsis || props.editable
|
||||||
? props.content
|
? 'content' in props
|
||||||
|
? props.content
|
||||||
|
: slots.default?.()
|
||||||
: slots.default
|
: slots.default
|
||||||
? slots.default()
|
? slots.default()
|
||||||
: props.content;
|
: props.content;
|
||||||
|
@ -450,7 +462,7 @@ const Base = defineComponent<InternalBlockProps>({
|
||||||
<LocaleReceiver
|
<LocaleReceiver
|
||||||
componentName="Text"
|
componentName="Text"
|
||||||
children={(locale: Locale) => {
|
children={(locale: Locale) => {
|
||||||
const { type, disabled, title, content, class: className, style, ...restProps } = {
|
const { type, disabled, content, class: className, style, ...restProps } = {
|
||||||
...props,
|
...props,
|
||||||
...attrs,
|
...attrs,
|
||||||
};
|
};
|
||||||
|
@ -485,26 +497,25 @@ const Base = defineComponent<InternalBlockProps>({
|
||||||
|
|
||||||
// Only use js ellipsis when css ellipsis not support
|
// Only use js ellipsis when css ellipsis not support
|
||||||
if (rows && state.isEllipsis && !state.expanded && !cssEllipsis) {
|
if (rows && state.isEllipsis && !state.expanded && !cssEllipsis) {
|
||||||
ariaLabel = title;
|
const { title } = restProps;
|
||||||
if (!title) {
|
let restContent = title || '';
|
||||||
ariaLabel = content;
|
|
||||||
|
if (!title && (typeof children === 'string' || typeof children === 'number')) {
|
||||||
|
restContent = String(children);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// show rest content as title on symbol
|
||||||
|
restContent = restContent?.slice(String(state.ellipsisContent || '').length);
|
||||||
// We move full content to outer element to avoid repeat read the content by accessibility
|
// We move full content to outer element to avoid repeat read the content by accessibility
|
||||||
textNode = (
|
textNode = (
|
||||||
<span title={ariaLabel} aria-hidden="true">
|
<>
|
||||||
{toRaw(state.ellipsisContent)}
|
{toRaw(state.ellipsisContent)}
|
||||||
{ELLIPSIS_STR}
|
<span title={restContent} aria-hidden="true">
|
||||||
|
{ELLIPSIS_STR}
|
||||||
|
</span>
|
||||||
{suffix}
|
{suffix}
|
||||||
</span>
|
</>
|
||||||
);
|
);
|
||||||
// If provided tooltip, we need wrap with span to let Tooltip inject events
|
|
||||||
if (tooltip) {
|
|
||||||
textNode = (
|
|
||||||
<Tooltip title={tooltip === true ? children : tooltip}>
|
|
||||||
<span>{textNode}</span>
|
|
||||||
</Tooltip>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
textNode = (
|
textNode = (
|
||||||
<>
|
<>
|
||||||
|
@ -516,6 +527,9 @@ const Base = defineComponent<InternalBlockProps>({
|
||||||
|
|
||||||
textNode = wrapperDecorations(props, textNode);
|
textNode = wrapperDecorations(props, textNode);
|
||||||
|
|
||||||
|
const showTooltip =
|
||||||
|
tooltip && rows && state.isEllipsis && !state.expanded && !cssEllipsis;
|
||||||
|
const title = slots.ellipsisTooltip ? slots.ellipsisTooltip() : tooltip;
|
||||||
return (
|
return (
|
||||||
<ResizeObserver onResize={resizeOnNextFrame} disabled={!rows}>
|
<ResizeObserver onResize={resizeOnNextFrame} disabled={!rows}>
|
||||||
<Typography
|
<Typography
|
||||||
|
@ -535,7 +549,13 @@ const Base = defineComponent<InternalBlockProps>({
|
||||||
aria-label={ariaLabel}
|
aria-label={ariaLabel}
|
||||||
{...textProps}
|
{...textProps}
|
||||||
>
|
>
|
||||||
{textNode}
|
{showTooltip ? (
|
||||||
|
<Tooltip title={tooltip === true ? children : title}>
|
||||||
|
<span>{textNode}</span>
|
||||||
|
</Tooltip>
|
||||||
|
) : (
|
||||||
|
textNode
|
||||||
|
)}
|
||||||
{renderOperations()}
|
{renderOperations()}
|
||||||
</Typography>
|
</Typography>
|
||||||
</ResizeObserver>
|
</ResizeObserver>
|
||||||
|
|
|
@ -12,8 +12,11 @@ const Editable = defineComponent({
|
||||||
autoSize: PropTypes.oneOfType([PropTypes.looseBool, PropTypes.object]),
|
autoSize: PropTypes.oneOfType([PropTypes.looseBool, PropTypes.object]),
|
||||||
onSave: PropTypes.func,
|
onSave: PropTypes.func,
|
||||||
onCancel: PropTypes.func,
|
onCancel: PropTypes.func,
|
||||||
|
onEnd: PropTypes.func,
|
||||||
|
onChange: PropTypes.func,
|
||||||
|
originContent: PropTypes.string,
|
||||||
},
|
},
|
||||||
emits: ['save', 'cancel'],
|
emits: ['save', 'cancel', 'end', 'change'],
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
current: props.value || '',
|
current: props.value || '',
|
||||||
|
@ -21,9 +24,6 @@ const Editable = defineComponent({
|
||||||
inComposition: false,
|
inComposition: false,
|
||||||
cancelFlag: false,
|
cancelFlag: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
let cancelFlag: boolean = false;
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.value,
|
() => props.value,
|
||||||
current => {
|
current => {
|
||||||
|
@ -49,6 +49,7 @@ const Editable = defineComponent({
|
||||||
|
|
||||||
function onChange({ target: { value } }) {
|
function onChange({ target: { value } }) {
|
||||||
state.current = value.replace(/[\r\n]/g, '');
|
state.current = value.replace(/[\r\n]/g, '');
|
||||||
|
emit('change', state.current);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onCompositionStart() {
|
function onCompositionStart() {
|
||||||
|
@ -61,6 +62,9 @@ const Editable = defineComponent({
|
||||||
|
|
||||||
function onKeyDown(e: KeyboardEvent) {
|
function onKeyDown(e: KeyboardEvent) {
|
||||||
const { keyCode } = e;
|
const { keyCode } = e;
|
||||||
|
if (keyCode === KeyCode.ENTER) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
// We don't record keyCode when IME is using
|
// We don't record keyCode when IME is using
|
||||||
if (state.inComposition) return;
|
if (state.inComposition) return;
|
||||||
|
|
||||||
|
@ -81,18 +85,16 @@ const Editable = defineComponent({
|
||||||
) {
|
) {
|
||||||
if (keyCode === KeyCode.ENTER) {
|
if (keyCode === KeyCode.ENTER) {
|
||||||
confirmChange();
|
confirmChange();
|
||||||
|
emit('end');
|
||||||
} else if (keyCode === KeyCode.ESC) {
|
} else if (keyCode === KeyCode.ESC) {
|
||||||
// avoid chrome trigger blur
|
state.current = props.originContent;
|
||||||
cancelFlag = true;
|
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onBlur() {
|
function onBlur() {
|
||||||
if (!cancelFlag) {
|
confirmChange();
|
||||||
confirmChange();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function confirmChange() {
|
function confirmChange() {
|
||||||
|
@ -100,7 +102,7 @@ const Editable = defineComponent({
|
||||||
}
|
}
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<div class={[`${props.prefixCls}, ${props.prefixCls}-edit-content`]}>
|
<div class={`${props.prefixCls} ${props.prefixCls}-edit-content`}>
|
||||||
<TextArea
|
<TextArea
|
||||||
ref={saveTextAreaRef}
|
ref={saveTextAreaRef}
|
||||||
maxlength={props.maxlength}
|
maxlength={props.maxlength}
|
||||||
|
|
|
@ -26,7 +26,6 @@ const Text: FunctionalComponent<TextProps> = (props, { slots, attrs }) => {
|
||||||
component: 'span',
|
component: 'span',
|
||||||
...attrs,
|
...attrs,
|
||||||
};
|
};
|
||||||
|
|
||||||
return <Base {...textProps} v-slots={slots}></Base>;
|
return <Base {...textProps} v-slots={slots}></Base>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { mount } from '@vue/test-utils';
|
import { mount } from '@vue/test-utils';
|
||||||
import { asyncExpect, sleep } from '@/tests/utils';
|
import { asyncExpect, sleep } from '@/tests/utils';
|
||||||
import KeyCode from '../../_util/KeyCode';
|
import KeyCode from '../../_util/KeyCode';
|
||||||
import copy from 'copy-to-clipboard';
|
import copy from '../_util/copy-to-clipboard';
|
||||||
import Title from '../Title';
|
import Title from '../Title';
|
||||||
import AParagraph from '../Paragraph';
|
import AParagraph from '../Paragraph';
|
||||||
import Base from '../Base';
|
import Base from '../Base';
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { createApp, CSSProperties, VNodeTypes } from 'vue';
|
import { createApp, CSSProperties, VNodeTypes } from 'vue';
|
||||||
import toArray from '../vc-util/Children/toArray';
|
|
||||||
|
|
||||||
interface MeasureResult {
|
interface MeasureResult {
|
||||||
finished: boolean;
|
finished: boolean;
|
||||||
|
@ -11,7 +10,6 @@ interface Option {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We only handle element & text node.
|
// We only handle element & text node.
|
||||||
const ELEMENT_NODE = 1;
|
|
||||||
const TEXT_NODE = 3;
|
const TEXT_NODE = 3;
|
||||||
const COMMENT_NODE = 8;
|
const COMMENT_NODE = 8;
|
||||||
|
|
||||||
|
@ -39,25 +37,10 @@ function styleToString(style: CSSStyleDeclaration) {
|
||||||
return styleNames.map(name => `${name}: ${style.getPropertyValue(name)};`).join('');
|
return styleNames.map(name => `${name}: ${style.getPropertyValue(name)};`).join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
function mergeChildren(children: VNodeTypes[]) {
|
|
||||||
const childList = [];
|
|
||||||
|
|
||||||
children.forEach(child => {
|
|
||||||
const prevChild = childList[childList.length - 1];
|
|
||||||
if (typeof child === 'string' && typeof prevChild === 'string') {
|
|
||||||
childList[childList.length - 1] += child;
|
|
||||||
} else {
|
|
||||||
childList.push(child);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return childList;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default (
|
export default (
|
||||||
originEle: HTMLElement,
|
originEle: HTMLElement,
|
||||||
option: Option,
|
option: Option,
|
||||||
content: VNodeTypes,
|
content: string,
|
||||||
fixedContent: VNodeTypes[],
|
fixedContent: VNodeTypes[],
|
||||||
ellipsisStr: string,
|
ellipsisStr: string,
|
||||||
): {
|
): {
|
||||||
|
@ -98,13 +81,12 @@ export default (
|
||||||
ellipsisContainer.style.webkitLineClamp = 'none';
|
ellipsisContainer.style.webkitLineClamp = 'none';
|
||||||
|
|
||||||
// Render in the fake container
|
// Render in the fake container
|
||||||
const contentList: VNodeTypes[] = mergeChildren(toArray(content as []));
|
|
||||||
const vm = createApp({
|
const vm = createApp({
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div style={wrapperStyle}>
|
<div style={wrapperStyle}>
|
||||||
<span style={wrapperStyle}>
|
<span style={wrapperStyle}>
|
||||||
{contentList}
|
{content}
|
||||||
{suffix}
|
{suffix}
|
||||||
</span>
|
</span>
|
||||||
<span style={wrapperStyle}>{fixedContent}</span>
|
<span style={wrapperStyle}>{fixedContent}</span>
|
||||||
|
@ -125,8 +107,6 @@ export default (
|
||||||
vm.unmount();
|
vm.unmount();
|
||||||
return { content, text: ellipsisContainer.innerHTML, ellipsis: false };
|
return { content, text: ellipsisContainer.innerHTML, ellipsis: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
// We should clone the childNode since they're controlled by React and we can't reuse it without warning
|
|
||||||
const childNodes = Array.prototype.slice
|
const childNodes = Array.prototype.slice
|
||||||
.apply(ellipsisContainer.childNodes[0].childNodes[0].cloneNode(true).childNodes)
|
.apply(ellipsisContainer.childNodes[0].childNodes[0].cloneNode(true).childNodes)
|
||||||
.filter(({ nodeType, data }) => nodeType !== COMMENT_NODE && data !== '');
|
.filter(({ nodeType, data }) => nodeType !== COMMENT_NODE && data !== '');
|
||||||
|
@ -193,26 +173,26 @@ export default (
|
||||||
return measureText(textNode, fullText, startLoc, midLoc, lastSuccessLoc);
|
return measureText(textNode, fullText, startLoc, midLoc, lastSuccessLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
function measureNode(childNode: ChildNode, index: number): MeasureResult {
|
function measureNode(childNode: ChildNode): MeasureResult {
|
||||||
const type = childNode.nodeType;
|
const type = childNode.nodeType;
|
||||||
|
// console.log('type', type);
|
||||||
|
// if (type === ELEMENT_NODE) {
|
||||||
|
// // We don't split element, it will keep if whole element can be displayed.
|
||||||
|
// appendChildNode(childNode);
|
||||||
|
// if (inRange()) {
|
||||||
|
// return {
|
||||||
|
// finished: false,
|
||||||
|
// vNode: contentList[index],
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
if (type === ELEMENT_NODE) {
|
// // Clean up if can not pull in
|
||||||
// We don't split element, it will keep if whole element can be displayed.
|
// ellipsisContentHolder.removeChild(childNode);
|
||||||
appendChildNode(childNode);
|
// return {
|
||||||
if (inRange()) {
|
// finished: true,
|
||||||
return {
|
// vNode: null,
|
||||||
finished: false,
|
// };
|
||||||
vNode: contentList[index],
|
// }
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up if can not pull in
|
|
||||||
ellipsisContentHolder.removeChild(childNode);
|
|
||||||
return {
|
|
||||||
finished: true,
|
|
||||||
vNode: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (type === TEXT_NODE) {
|
if (type === TEXT_NODE) {
|
||||||
const fullText = childNode.textContent || '';
|
const fullText = childNode.textContent || '';
|
||||||
const textNode = document.createTextNode(fullText);
|
const textNode = document.createTextNode(fullText);
|
||||||
|
@ -227,8 +207,8 @@ export default (
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
childNodes.some((childNode, index) => {
|
childNodes.some(childNode => {
|
||||||
const { finished, vNode } = measureNode(childNode, index);
|
const { finished, vNode } = measureNode(childNode);
|
||||||
if (vNode) {
|
if (vNode) {
|
||||||
ellipsisChildren.push(vNode);
|
ellipsisChildren.push(vNode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import demo from '../v2-doc/src/docs/typography/demo/text.vue';
|
import demo from '../v2-doc/src/docs/typography/demo/ellipsis.vue';
|
||||||
// import Affix from '../components/affix';
|
// import Affix from '../components/affix';
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
|
Loading…
Reference in New Issue