fix: review typography
parent
7129b6f2db
commit
e8bdcab8d9
|
@ -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;
|
|
@ -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;
|
|
@ -10,7 +10,7 @@ import PropTypes from '../_util/vue-types';
|
||||||
import Typography, { TypographyProps } from './Typography';
|
import Typography, { TypographyProps } from './Typography';
|
||||||
import ResizeObserver from '../vc-resize-observer';
|
import ResizeObserver from '../vc-resize-observer';
|
||||||
import Tooltip from '../tooltip';
|
import Tooltip from '../tooltip';
|
||||||
import copy from 'copy-to-clipboard';
|
import copy from '../_util/copy-to-clipboard';
|
||||||
import { defaultConfigProvider } from '../config-provider';
|
import { defaultConfigProvider } from '../config-provider';
|
||||||
import CheckOutlined from '@ant-design/icons-vue/CheckOutlined';
|
import CheckOutlined from '@ant-design/icons-vue/CheckOutlined';
|
||||||
import CopyOutlined from '@ant-design/icons-vue/CopyOutlined';
|
import CopyOutlined from '@ant-design/icons-vue/CopyOutlined';
|
||||||
|
@ -40,7 +40,7 @@ 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) {
|
function toArray(value: any) {
|
||||||
let ret = value;
|
let ret = value;
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
ret = [];
|
ret = [];
|
||||||
|
@ -67,13 +67,14 @@ interface EditConfig {
|
||||||
autoSize?: boolean | AutoSizeType;
|
autoSize?: boolean | AutoSizeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EllipsisConfig {
|
export interface EllipsisConfig {
|
||||||
rows?: number;
|
rows?: number;
|
||||||
expandable?: boolean;
|
expandable?: boolean;
|
||||||
suffix?: string;
|
suffix?: string;
|
||||||
symbol?: VNodeTypes;
|
symbol?: VNodeTypes;
|
||||||
onExpand?: EventHandlerNonNull;
|
onExpand?: EventHandlerNonNull;
|
||||||
onEllipsis?: (ellipsis: boolean) => void;
|
onEllipsis?: (ellipsis: boolean) => void;
|
||||||
|
tooltip?: VNodeTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BlockProps extends TypographyProps {
|
export interface BlockProps extends TypographyProps {
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
import { FunctionalComponent } from 'vue';
|
import { FunctionalComponent } from 'vue';
|
||||||
import Base, { BlockProps } from './Base';
|
import Base, { BlockProps } from './Base';
|
||||||
|
|
||||||
const Paragraph: FunctionalComponent<BlockProps> = (props, { slots }) => {
|
const Paragraph: FunctionalComponent<BlockProps> = (props, { slots, attrs }) => {
|
||||||
const paragraphProps = {
|
const paragraphProps = {
|
||||||
...props,
|
...props,
|
||||||
component: 'div',
|
component: 'div',
|
||||||
|
...attrs,
|
||||||
};
|
};
|
||||||
|
|
||||||
return <Base {...paragraphProps}>{slots.default?.()}</Base>;
|
return <Base {...paragraphProps}>{slots.default?.()}</Base>;
|
||||||
};
|
};
|
||||||
|
|
||||||
Paragraph.displayName = 'ATypographyParagraph';
|
Paragraph.displayName = 'ATypographyParagraph';
|
||||||
|
Paragraph.inheritAttrs = false;
|
||||||
|
|
||||||
export default Paragraph;
|
export default Paragraph;
|
||||||
|
|
|
@ -1,27 +1,35 @@
|
||||||
import { FunctionalComponent } from 'vue';
|
import { FunctionalComponent } from 'vue';
|
||||||
|
import omit from 'omit.js';
|
||||||
import warning from '../_util/warning';
|
import warning from '../_util/warning';
|
||||||
import Base, { BlockProps } from './Base';
|
import Base, { BlockProps, EllipsisConfig } from './Base';
|
||||||
|
|
||||||
export interface TextProps extends BlockProps {
|
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;
|
const { ellipsis } = props;
|
||||||
warning(
|
warning(
|
||||||
typeof ellipsis !== 'object',
|
typeof ellipsis !== 'object' ||
|
||||||
|
!ellipsis ||
|
||||||
|
(!('expandable' in ellipsis) && !('rows' in ellipsis)),
|
||||||
'Typography.Text',
|
'Typography.Text',
|
||||||
'`ellipsis` is only support boolean value.',
|
'`ellipsis` do not support `expandable` or `rows` props.',
|
||||||
);
|
);
|
||||||
const textProps = {
|
const textProps = {
|
||||||
...props,
|
...props,
|
||||||
ellipsis: !!ellipsis,
|
ellipsis:
|
||||||
|
ellipsis && typeof ellipsis === 'object'
|
||||||
|
? omit(ellipsis as any, ['expandable', 'rows'])
|
||||||
|
: ellipsis,
|
||||||
component: 'span',
|
component: 'span',
|
||||||
|
...attrs,
|
||||||
};
|
};
|
||||||
|
|
||||||
return <Base {...textProps}>{slots.default?.()}</Base>;
|
return <Base {...textProps}>{slots.default?.()}</Base>;
|
||||||
};
|
};
|
||||||
|
|
||||||
Text.displayName = 'ATypographyText';
|
Text.displayName = 'ATypographyText';
|
||||||
|
Text.inheritAttrs = false;
|
||||||
|
|
||||||
export default Text;
|
export default Text;
|
||||||
|
|
|
@ -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'>;
|
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;
|
const { level = 1, ...restProps } = props;
|
||||||
let component: string;
|
let component: string;
|
||||||
if (TITLE_ELE_LIST.indexOf(level) !== -1) {
|
if (TITLE_ELE_LIST.indexOf(level) !== -1) {
|
||||||
|
@ -20,11 +20,13 @@ const Title: FunctionalComponent<TitleProps> = (props, { slots }) => {
|
||||||
const titleProps = {
|
const titleProps = {
|
||||||
...restProps,
|
...restProps,
|
||||||
component,
|
component,
|
||||||
|
attrs,
|
||||||
};
|
};
|
||||||
|
|
||||||
return <Base {...titleProps}>{slots.default?.()}</Base>;
|
return <Base {...titleProps}>{slots.default?.()}</Base>;
|
||||||
};
|
};
|
||||||
|
|
||||||
Title.displayName = 'ATypographyTitle';
|
Title.displayName = 'ATypographyTitle';
|
||||||
|
Title.inheritAttrs = false;
|
||||||
|
|
||||||
export default Title;
|
export default Title;
|
||||||
|
|
|
@ -210,7 +210,6 @@
|
||||||
"@simonwep/pickr": "~1.8.0",
|
"@simonwep/pickr": "~1.8.0",
|
||||||
"array-tree-filter": "^2.1.0",
|
"array-tree-filter": "^2.1.0",
|
||||||
"async-validator": "^3.3.0",
|
"async-validator": "^3.3.0",
|
||||||
"copy-to-clipboard": "^3.3.1",
|
|
||||||
"dom-align": "^1.10.4",
|
"dom-align": "^1.10.4",
|
||||||
"dom-scroll-into-view": "^2.0.0",
|
"dom-scroll-into-view": "^2.0.0",
|
||||||
"is-mobile": "^2.2.1",
|
"is-mobile": "^2.2.1",
|
||||||
|
|
Loading…
Reference in New Issue