fix: review typography

zkwolf-typography
tanjinzhou 2021-03-12 18:02:16 +08:00
parent 7129b6f2db
commit e8bdcab8d9
7 changed files with 186 additions and 12 deletions

View File

@ -0,0 +1,121 @@
import deselectCurrent from './toggle-selection';
interface Options {
debug?: boolean;
message?: string;
format?: string; // MIME type
onCopy?: (clipboardData: object) => void;
}
const clipboardToIE11Formatting = {
'text/plain': 'Text',
'text/html': 'Url',
default: 'Text',
};
const defaultMessage = 'Copy to clipboard: #{key}, Enter';
function format(message: string) {
const copyKey = (/mac os x/i.test(navigator.userAgent) ? '⌘' : 'Ctrl') + '+C';
return message.replace(/#{\s*key\s*}/g, copyKey);
}
function copy(text: string, options?: Options): boolean {
let debug,
message,
reselectPrevious,
range,
selection,
mark,
success = false;
if (!options) {
options = {};
}
debug = options.debug || false;
try {
reselectPrevious = deselectCurrent();
range = document.createRange();
selection = document.getSelection();
mark = document.createElement('span');
mark.textContent = text;
// reset user styles for span element
mark.style.all = 'unset';
// prevents scrolling to the end of the page
mark.style.position = 'fixed';
mark.style.top = 0;
mark.style.clip = 'rect(0, 0, 0, 0)';
// used to preserve spaces and line breaks
mark.style.whiteSpace = 'pre';
// do not inherit user-select (it may be `none`)
mark.style.webkitUserSelect = 'text';
mark.style.MozUserSelect = 'text';
mark.style.msUserSelect = 'text';
mark.style.userSelect = 'text';
mark.addEventListener('copy', function(e) {
e.stopPropagation();
if (options.format) {
e.preventDefault();
if (typeof e.clipboardData === 'undefined') {
// IE 11
debug && console.warn('unable to use e.clipboardData');
debug && console.warn('trying IE specific stuff');
(window as any).clipboardData.clearData();
const format =
clipboardToIE11Formatting[options.format] || clipboardToIE11Formatting['default'];
(window as any).clipboardData.setData(format, text);
} else {
// all other browsers
e.clipboardData.clearData();
e.clipboardData.setData(options.format, text);
}
}
if (options.onCopy) {
e.preventDefault();
options.onCopy(e.clipboardData);
}
});
document.body.appendChild(mark);
range.selectNodeContents(mark);
selection.addRange(range);
const successful = document.execCommand('copy');
if (!successful) {
throw new Error('copy command was unsuccessful');
}
success = true;
} catch (err) {
debug && console.error('unable to copy using execCommand: ', err);
debug && console.warn('trying IE specific stuff');
try {
(window as any).clipboardData.setData(options.format || 'text', text);
options.onCopy && options.onCopy((window as any).clipboardData);
success = true;
} catch (err) {
debug && console.error('unable to copy using clipboardData: ', err);
debug && console.error('falling back to prompt');
message = format('message' in options ? options.message : defaultMessage);
window.prompt(message, text);
}
} finally {
if (selection) {
if (typeof selection.removeRange == 'function') {
selection.removeRange(range);
} else {
selection.removeAllRanges();
}
}
if (mark) {
document.body.removeChild(mark);
}
reselectPrevious();
}
return success;
}
export default copy;

View File

@ -0,0 +1,41 @@
// copy from https://github.com/sudodoki/toggle-selection
// refactor to esm
const deselectCurrent = (): (() => void) => {
const selection = document.getSelection();
if (!selection.rangeCount) {
return function() {};
}
let active = document.activeElement as any;
const ranges = [];
for (let i = 0; i < selection.rangeCount; i++) {
ranges.push(selection.getRangeAt(i));
}
switch (
active.tagName.toUpperCase() // .toUpperCase handles XHTML
) {
case 'INPUT':
case 'TEXTAREA':
active.blur();
break;
default:
active = null;
break;
}
selection.removeAllRanges();
return function() {
selection.type === 'Caret' && selection.removeAllRanges();
if (!selection.rangeCount) {
ranges.forEach(function(range) {
selection.addRange(range);
});
}
active && active.focus();
};
};
export default deselectCurrent;

View File

@ -10,7 +10,7 @@ import PropTypes from '../_util/vue-types';
import Typography, { TypographyProps } from './Typography';
import ResizeObserver from '../vc-resize-observer';
import Tooltip from '../tooltip';
import copy from 'copy-to-clipboard';
import copy from '../_util/copy-to-clipboard';
import { defaultConfigProvider } from '../config-provider';
import CheckOutlined from '@ant-design/icons-vue/CheckOutlined';
import CopyOutlined from '@ant-design/icons-vue/CopyOutlined';
@ -40,7 +40,7 @@ export type BaseType = 'secondary' | 'success' | 'warning' | 'danger';
const isLineClampSupport = isStyleSupport('webkitLineClamp');
const isTextOverflowSupport = isStyleSupport('textOverflow');
function toArray(value) {
function toArray(value: any) {
let ret = value;
if (value === undefined) {
ret = [];
@ -67,13 +67,14 @@ interface EditConfig {
autoSize?: boolean | AutoSizeType;
}
interface EllipsisConfig {
export interface EllipsisConfig {
rows?: number;
expandable?: boolean;
suffix?: string;
symbol?: VNodeTypes;
onExpand?: EventHandlerNonNull;
onEllipsis?: (ellipsis: boolean) => void;
tooltip?: VNodeTypes;
}
export interface BlockProps extends TypographyProps {

View File

@ -1,15 +1,17 @@
import { FunctionalComponent } from 'vue';
import Base, { BlockProps } from './Base';
const Paragraph: FunctionalComponent<BlockProps> = (props, { slots }) => {
const Paragraph: FunctionalComponent<BlockProps> = (props, { slots, attrs }) => {
const paragraphProps = {
...props,
component: 'div',
...attrs,
};
return <Base {...paragraphProps}>{slots.default?.()}</Base>;
};
Paragraph.displayName = 'ATypographyParagraph';
Paragraph.inheritAttrs = false;
export default Paragraph;

View File

@ -1,27 +1,35 @@
import { FunctionalComponent } from 'vue';
import omit from 'omit.js';
import warning from '../_util/warning';
import Base, { BlockProps } from './Base';
import Base, { BlockProps, EllipsisConfig } from './Base';
export interface TextProps extends BlockProps {
ellipsis: boolean;
ellipsis?: boolean | Omit<EllipsisConfig, 'expandable' | 'rows' | 'onExpand'>;
}
const Text: FunctionalComponent<TextProps> = (props, { slots }) => {
const Text: FunctionalComponent<TextProps> = (props, { slots, attrs }) => {
const { ellipsis } = props;
warning(
typeof ellipsis !== 'object',
typeof ellipsis !== 'object' ||
!ellipsis ||
(!('expandable' in ellipsis) && !('rows' in ellipsis)),
'Typography.Text',
'`ellipsis` is only support boolean value.',
'`ellipsis` do not support `expandable` or `rows` props.',
);
const textProps = {
...props,
ellipsis: !!ellipsis,
ellipsis:
ellipsis && typeof ellipsis === 'object'
? omit(ellipsis as any, ['expandable', 'rows'])
: ellipsis,
component: 'span',
...attrs,
};
return <Base {...textProps}>{slots.default?.()}</Base>;
};
Text.displayName = 'ATypographyText';
Text.inheritAttrs = false;
export default Text;

View File

@ -7,7 +7,7 @@ const TITLE_ELE_LIST = tupleNum(1, 2, 3, 4, 5);
export type TitleProps = Omit<BlockProps & { level?: typeof TITLE_ELE_LIST[number] }, 'strong'>;
const Title: FunctionalComponent<TitleProps> = (props, { slots }) => {
const Title: FunctionalComponent<TitleProps> = (props, { slots, attrs }) => {
const { level = 1, ...restProps } = props;
let component: string;
if (TITLE_ELE_LIST.indexOf(level) !== -1) {
@ -20,11 +20,13 @@ const Title: FunctionalComponent<TitleProps> = (props, { slots }) => {
const titleProps = {
...restProps,
component,
attrs,
};
return <Base {...titleProps}>{slots.default?.()}</Base>;
};
Title.displayName = 'ATypographyTitle';
Title.inheritAttrs = false;
export default Title;

View File

@ -210,7 +210,6 @@
"@simonwep/pickr": "~1.8.0",
"array-tree-filter": "^2.1.0",
"async-validator": "^3.3.0",
"copy-to-clipboard": "^3.3.1",
"dom-align": "^1.10.4",
"dom-scroll-into-view": "^2.0.0",
"is-mobile": "^2.2.1",