fix: review typography

zkwolf-typography
tangjinzhou 2021-03-12 22:48:18 +08:00
parent e8bdcab8d9
commit 2515077386
8 changed files with 99 additions and 42 deletions

View File

@ -577,20 +577,22 @@ const Base = defineComponent<InternalBlockProps>({
},
});
Base.props = {
export const baseProps = () => ({
editable: PropTypes.oneOfType([PropTypes.looseBool, PropTypes.object]),
copyable: PropTypes.oneOfType([PropTypes.looseBool, PropTypes.object]),
prefixCls: PropTypes.string,
component: PropTypes.string,
type: PropTypes.oneOf(['secondary', 'danger', 'warning']),
disabled: PropTypes.bool,
disabled: PropTypes.looseBool,
ellipsis: PropTypes.oneOfType([PropTypes.looseBool, PropTypes.object]),
code: PropTypes.bool,
mark: PropTypes.bool,
underline: PropTypes.bool,
delete: PropTypes.bool,
strong: PropTypes.bool,
keyboard: PropTypes.bool,
};
code: PropTypes.looseBool,
mark: PropTypes.looseBool,
underline: PropTypes.looseBool,
delete: PropTypes.looseBool,
strong: PropTypes.looseBool,
keyboard: PropTypes.looseBool,
});
Base.props = baseProps();
export default Base;

View File

@ -34,14 +34,16 @@ const Editable = defineComponent({
const textArea = ref();
onMounted(() => {
const resizableTextArea = textArea.value?.resizableTextArea;
const innerTextArea = resizableTextArea?.textArea;
innerTextArea.focus();
const { length } = innerTextArea.value;
innerTextArea.setSelectionRange(length, length);
if (textArea.value) {
const resizableTextArea = textArea.value?.resizableTextArea;
const innerTextArea = resizableTextArea?.textArea;
innerTextArea.focus();
const { length } = innerTextArea.value;
innerTextArea.setSelectionRange(length, length);
}
});
function saveTextAreaRef(node) {
function saveTextAreaRef(node: any) {
textArea.value = node;
}
@ -62,10 +64,6 @@ const Editable = defineComponent({
// We don't record keyCode when IME is using
if (state.inComposition) return;
if (keyCode === KeyCode.ENTER) {
e.preventDefault();
}
state.lastKeyCode = keyCode;
}

View File

@ -0,0 +1,35 @@
import { AnchorHTMLAttributes, FunctionalComponent } from 'vue';
import warning from '../_util/warning';
import Base, { baseProps, BlockProps } from './Base';
import Omit from 'omit.js';
import PropTypes from '../_util/vue-types';
export interface LinkProps extends BlockProps, Omit<AnchorHTMLAttributes, 'type'> {
ellipsis?: boolean;
}
const Link: FunctionalComponent<LinkProps> = (props, { slots, attrs }) => {
const { ellipsis, rel, ...restProps } = { ...props, ...attrs };
warning(
typeof ellipsis !== 'object',
'Typography.Link',
'`ellipsis` only supports boolean value.',
);
const mergedProps = {
...restProps,
rel: rel === undefined && restProps.target === '_blank' ? 'noopener noreferrer' : rel,
ellipsis: !!ellipsis,
component: 'a',
};
// https://github.com/ant-design/ant-design/issues/26622
// @ts-ignore
delete mergedProps.navigate;
return <Base {...mergedProps}>{slots.default?.()}</Base>;
};
Link.displayName = 'ATypographyText';
Link.inheritAttrs = false;
Link.props = Omit({ ...baseProps(), ellipsis: PropTypes.looseBool }, ['component']);
export default Link;

View File

@ -1,5 +1,6 @@
import Omit from 'omit.js';
import { FunctionalComponent } from 'vue';
import Base, { BlockProps } from './Base';
import Base, { BlockProps, baseProps } from './Base';
const Paragraph: FunctionalComponent<BlockProps> = (props, { slots, attrs }) => {
const paragraphProps = {
@ -13,5 +14,6 @@ const Paragraph: FunctionalComponent<BlockProps> = (props, { slots, attrs }) =>
Paragraph.displayName = 'ATypographyParagraph';
Paragraph.inheritAttrs = false;
Paragraph.props = Omit(baseProps(), ['component']);
export default Paragraph;

View File

@ -1,7 +1,8 @@
import { FunctionalComponent } from 'vue';
import omit from 'omit.js';
import warning from '../_util/warning';
import Base, { BlockProps, EllipsisConfig } from './Base';
import Base, { baseProps, BlockProps, EllipsisConfig } from './Base';
import Omit from 'omit.js';
export interface TextProps extends BlockProps {
ellipsis?: boolean | Omit<EllipsisConfig, 'expandable' | 'rows' | 'onExpand'>;
@ -31,5 +32,6 @@ const Text: FunctionalComponent<TextProps> = (props, { slots, attrs }) => {
Text.displayName = 'ATypographyText';
Text.inheritAttrs = false;
Text.props = Omit(baseProps(), ['component']);
export default Text;

View File

@ -1,7 +1,9 @@
import Omit from 'omit.js';
import { FunctionalComponent } from 'vue';
import { tupleNum } from '../_util/type';
import PropTypes from '../_util/vue-types';
import warning from '../_util/warning';
import Base, { BlockProps } from './Base';
import Base, { baseProps, BlockProps } from './Base';
const TITLE_ELE_LIST = tupleNum(1, 2, 3, 4, 5);
@ -20,7 +22,7 @@ const Title: FunctionalComponent<TitleProps> = (props, { slots, attrs }) => {
const titleProps = {
...restProps,
component,
attrs,
...attrs,
};
return <Base {...titleProps}>{slots.default?.()}</Base>;
@ -28,5 +30,6 @@ const Title: FunctionalComponent<TitleProps> = (props, { slots, attrs }) => {
Title.displayName = 'ATypographyTitle';
Title.inheritAttrs = false;
Title.props = Omit({ ...baseProps(), level: PropTypes.number }, ['component', 'strong']);
export default Title;

View File

@ -1,4 +1,5 @@
import { createApp, CSSProperties, VNodeTypes } from 'vue';
import toArray from '../vc-util/Children/toArray';
interface MeasureResult {
finished: boolean;
@ -14,19 +15,7 @@ const ELEMENT_NODE = 1;
const TEXT_NODE = 3;
const COMMENT_NODE = 8;
export function toArray(children) {
const c = [];
children.forEach(child => {
if (child.text) {
c.push(child);
} else {
c.push(child);
}
});
return c;
}
let ellipsisContainer = null;
let ellipsisContainer: HTMLParagraphElement;
const wrapperStyle: CSSProperties = {
padding: 0,
@ -109,7 +98,7 @@ export default (
ellipsisContainer.style.webkitLineClamp = 'none';
// Render in the fake container
const contentList: VNodeTypes[] = mergeChildren(toArray(content));
const contentList: VNodeTypes[] = mergeChildren(toArray(content as []));
const vm = createApp({
render() {
return (
@ -133,7 +122,7 @@ export default (
// Skip ellipsis if already match
if (inRange()) {
vm.unmount(ellipsisContainer);
vm.unmount();
return { content, text: ellipsisContainer.innerHTML, ellipsis: false };
}
@ -145,7 +134,7 @@ export default (
ellipsisContainer.childNodes[0].childNodes[1].cloneNode(true).childNodes,
);
vm.unmount(ellipsisContainer);
vm.unmount();
// ========================= Find match ellipsis content =========================
const ellipsisChildren = [];
@ -200,9 +189,8 @@ export default (
if (inRange()) {
return measureText(textNode, fullText, midLoc, endLoc, midLoc);
} else {
return measureText(textNode, fullText, startLoc, midLoc, lastSuccessLoc);
}
return measureText(textNode, fullText, startLoc, midLoc, lastSuccessLoc);
}
function measureNode(childNode: ChildNode, index: number): MeasureResult {
@ -224,7 +212,8 @@ export default (
finished: true,
vNode: null,
};
} else if (type === TEXT_NODE) {
}
if (type === TEXT_NODE) {
const fullText = childNode.textContent || '';
const textNode = document.createTextNode(fullText);
appendChildNode(textNode);

View File

@ -0,0 +1,26 @@
import { VNodeTypes } from '@vue/runtime-core';
import { isFragment } from '../../_util/props-util';
export interface Option {
keepEmpty?: boolean;
}
export default function toArray(children: any[], option: Option = {}): any[] {
let ret: VNodeTypes[] = [];
children.forEach((child: any) => {
if ((child === undefined || child === null) && !option.keepEmpty) {
return;
}
debugger;
if (Array.isArray(child)) {
ret = ret.concat(toArray(child));
} else if (isFragment(child) && child.props) {
ret = ret.concat(toArray(child.props.children, option));
} else {
ret.push(child);
}
});
return ret;
}