@aplus-frontend/antdv
Version:
Vue basic component library maintained based on ant-design-vue
530 lines (529 loc) • 18.4 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.baseProps = void 0;
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
var _vue = require("vue");
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _LocaleReceiver = _interopRequireDefault(require("../locale-provider/LocaleReceiver"));
var _warning = _interopRequireDefault(require("../_util/warning"));
var _transButton = _interopRequireDefault(require("../_util/transButton"));
var _raf = _interopRequireDefault(require("../_util/raf"));
var _styleChecker = require("../_util/styleChecker");
var _Editable = _interopRequireDefault(require("./Editable"));
var _util = _interopRequireDefault(require("./util"));
var _Typography = _interopRequireDefault(require("./Typography"));
var _vcResizeObserver = _interopRequireDefault(require("../vc-resize-observer"));
var _tooltip = _interopRequireDefault(require("../tooltip"));
var _copyToClipboard = _interopRequireDefault(require("../_util/copy-to-clipboard"));
var _CheckOutlined = _interopRequireDefault(require("@ant-design/icons-vue/lib/icons/CheckOutlined"));
var _CopyOutlined = _interopRequireDefault(require("@ant-design/icons-vue/lib/icons/CopyOutlined"));
var _EditOutlined = _interopRequireDefault(require("@ant-design/icons-vue/lib/icons/EditOutlined"));
var _useConfigInject = _interopRequireDefault(require("../config-provider/hooks/useConfigInject"));
var _omit = _interopRequireDefault(require("../_util/omit"));
var _useMergedState = _interopRequireDefault(require("../_util/hooks/useMergedState"));
var _propsUtil = require("../_util/props-util");
var __rest = void 0 && (void 0).__rest || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
}
return t;
};
const isLineClampSupport = (0, _styleChecker.isStyleSupport)('webkitLineClamp');
const isTextOverflowSupport = (0, _styleChecker.isStyleSupport)('textOverflow');
const ELLIPSIS_STR = '...';
const baseProps = () => ({
editable: {
type: [Boolean, Object],
default: undefined
},
copyable: {
type: [Boolean, Object],
default: undefined
},
prefixCls: String,
component: String,
type: String,
disabled: {
type: Boolean,
default: undefined
},
ellipsis: {
type: [Boolean, Object],
default: undefined
},
code: {
type: Boolean,
default: undefined
},
mark: {
type: Boolean,
default: undefined
},
underline: {
type: Boolean,
default: undefined
},
delete: {
type: Boolean,
default: undefined
},
strong: {
type: Boolean,
default: undefined
},
keyboard: {
type: Boolean,
default: undefined
},
content: String,
'onUpdate:content': Function
});
exports.baseProps = baseProps;
const Base = (0, _vue.defineComponent)({
compatConfig: {
MODE: 3
},
name: 'TypographyBase',
inheritAttrs: false,
props: baseProps(),
// emits: ['update:content'],
setup(props, _ref) {
let {
slots,
attrs,
emit
} = _ref;
const {
prefixCls,
direction
} = (0, _useConfigInject.default)('typography', props);
const state = (0, _vue.reactive)({
copied: false,
ellipsisText: '',
ellipsisContent: null,
isEllipsis: false,
expanded: false,
clientRendered: false,
//locale
expandStr: '',
copyStr: '',
copiedStr: '',
editStr: '',
copyId: undefined,
rafId: undefined,
prevProps: undefined,
originContent: ''
});
const contentRef = (0, _vue.ref)();
const editIcon = (0, _vue.ref)();
const ellipsis = (0, _vue.computed)(() => {
const ellipsis = props.ellipsis;
if (!ellipsis) return {};
return (0, _extends2.default)({
rows: 1,
expandable: false
}, typeof ellipsis === 'object' ? ellipsis : null);
});
(0, _vue.onMounted)(() => {
state.clientRendered = true;
syncEllipsis();
});
(0, _vue.onBeforeUnmount)(() => {
clearTimeout(state.copyId);
_raf.default.cancel(state.rafId);
});
(0, _vue.watch)([() => ellipsis.value.rows, () => props.content], () => {
(0, _vue.nextTick)(() => {
resizeOnNextFrame();
});
}, {
flush: 'post',
deep: true
});
(0, _vue.watchEffect)(() => {
if (props.content === undefined) {
(0, _warning.default)(!props.editable, 'Typography', 'When `editable` is enabled, please use `content` instead of children');
(0, _warning.default)(!props.ellipsis, 'Typography', 'When `ellipsis` is enabled, please use `content` instead of children');
}
});
function getChildrenText() {
var _a;
return props.ellipsis || props.editable ? props.content : (_a = (0, _propsUtil.findDOMNode)(contentRef.value)) === null || _a === void 0 ? void 0 : _a.innerText;
}
// =============== Expand ===============
function onExpandClick(e) {
const {
onExpand
} = ellipsis.value;
state.expanded = true;
onExpand === null || onExpand === void 0 ? void 0 : onExpand(e);
}
// ================ Edit ================
function onEditClick(e) {
e.preventDefault();
state.originContent = props.content;
triggerEdit(true);
}
function onEditChange(value) {
onContentChange(value);
triggerEdit(false);
}
function onContentChange(value) {
const {
onChange
} = editable.value;
if (value !== props.content) {
emit('update:content', value);
onChange === null || onChange === void 0 ? void 0 : onChange(value);
}
}
function onEditCancel() {
var _a, _b;
(_b = (_a = editable.value).onCancel) === null || _b === void 0 ? void 0 : _b.call(_a);
triggerEdit(false);
}
// ================ Copy ================
function onCopyClick(e) {
e.preventDefault();
e.stopPropagation();
const {
copyable
} = props;
const copyConfig = (0, _extends2.default)({}, typeof copyable === 'object' ? copyable : null);
if (copyConfig.text === undefined) {
copyConfig.text = getChildrenText();
}
(0, _copyToClipboard.default)(copyConfig.text || '');
state.copied = true;
(0, _vue.nextTick)(() => {
if (copyConfig.onCopy) {
copyConfig.onCopy(e);
}
state.copyId = setTimeout(() => {
state.copied = false;
}, 3000);
});
}
const editable = (0, _vue.computed)(() => {
const editable = props.editable;
if (!editable) return {
editing: false
};
return (0, _extends2.default)({}, typeof editable === 'object' ? editable : null);
});
const [editing, setEditing] = (0, _useMergedState.default)(false, {
value: (0, _vue.computed)(() => {
return editable.value.editing;
})
});
function triggerEdit(edit) {
const {
onStart
} = editable.value;
if (edit && onStart) {
onStart();
}
setEditing(edit);
}
(0, _vue.watch)(editing, val => {
var _a;
if (!val) {
(_a = editIcon.value) === null || _a === void 0 ? void 0 : _a.focus();
}
}, {
flush: 'post'
});
// ============== Ellipsis ==============
function resizeOnNextFrame(sizeInfo) {
if (sizeInfo) {
const {
width,
height
} = sizeInfo;
if (!width || !height) return;
}
_raf.default.cancel(state.rafId);
state.rafId = (0, _raf.default)(() => {
// Do not bind `syncEllipsis`. It need for test usage on prototype
syncEllipsis();
});
}
const canUseCSSEllipsis = (0, _vue.computed)(() => {
const {
rows,
expandable,
suffix,
onEllipsis,
tooltip
} = ellipsis.value;
if (suffix || tooltip) return false;
// Can't use css ellipsis since we need to provide the place for button
if (props.editable || props.copyable || expandable || onEllipsis) {
return false;
}
if (rows === 1) {
return isTextOverflowSupport;
}
return isLineClampSupport;
});
const syncEllipsis = () => {
const {
ellipsisText,
isEllipsis
} = state;
const {
rows,
suffix,
onEllipsis
} = ellipsis.value;
if (!rows || rows < 0 || !(0, _propsUtil.findDOMNode)(contentRef.value) || state.expanded || props.content === undefined) return;
// Do not measure if css already support ellipsis
if (canUseCSSEllipsis.value) return;
const {
content,
text,
ellipsis: ell
} = (0, _util.default)((0, _propsUtil.findDOMNode)(contentRef.value), {
rows,
suffix
}, props.content, renderOperations(true), ELLIPSIS_STR);
if (ellipsisText !== text || state.isEllipsis !== ell) {
state.ellipsisText = text;
state.ellipsisContent = content;
state.isEllipsis = ell;
if (isEllipsis !== ell && onEllipsis) {
onEllipsis(ell);
}
}
};
function wrapperDecorations(_ref2, content) {
let {
mark,
code,
underline,
delete: del,
strong,
keyboard
} = _ref2;
let currentContent = content;
function wrap(needed, Tag) {
if (!needed) return;
const _currentContent = function () {
return currentContent;
}();
currentContent = (0, _vue.createVNode)(Tag, null, {
default: () => [_currentContent]
});
}
wrap(strong, 'strong');
wrap(underline, 'u');
wrap(del, 'del');
wrap(code, 'code');
wrap(mark, 'mark');
wrap(keyboard, 'kbd');
return currentContent;
}
function renderExpand(forceRender) {
const {
expandable,
symbol
} = ellipsis.value;
if (!expandable) return null;
// force render expand icon for measure usage or it will cause dead loop
if (!forceRender && (state.expanded || !state.isEllipsis)) return null;
const expandContent = (slots.ellipsisSymbol ? slots.ellipsisSymbol() : symbol) || state.expandStr;
return (0, _vue.createVNode)("a", {
"key": "expand",
"class": `${prefixCls.value}-expand`,
"onClick": onExpandClick,
"aria-label": state.expandStr
}, [expandContent]);
}
function renderEdit() {
if (!props.editable) return;
const {
tooltip,
triggerType = ['icon']
} = props.editable;
const icon = slots.editableIcon ? slots.editableIcon() : (0, _vue.createVNode)(_EditOutlined.default, {
"role": "button"
}, null);
const title = slots.editableTooltip ? slots.editableTooltip() : state.editStr;
const ariaLabel = typeof title === 'string' ? title : '';
return triggerType.indexOf('icon') !== -1 ? (0, _vue.createVNode)(_tooltip.default, {
"key": "edit",
"title": tooltip === false ? '' : title
}, {
default: () => [(0, _vue.createVNode)(_transButton.default, {
"ref": editIcon,
"class": `${prefixCls.value}-edit`,
"onClick": onEditClick,
"aria-label": ariaLabel
}, {
default: () => [icon]
})]
}) : null;
}
function renderCopy() {
if (!props.copyable) return;
const {
tooltip
} = props.copyable;
const defaultTitle = state.copied ? state.copiedStr : state.copyStr;
const title = slots.copyableTooltip ? slots.copyableTooltip({
copied: state.copied
}) : defaultTitle;
const ariaLabel = typeof title === 'string' ? title : '';
const defaultIcon = state.copied ? (0, _vue.createVNode)(_CheckOutlined.default, null, null) : (0, _vue.createVNode)(_CopyOutlined.default, null, null);
const icon = slots.copyableIcon ? slots.copyableIcon({
copied: !!state.copied
}) : defaultIcon;
return (0, _vue.createVNode)(_tooltip.default, {
"key": "copy",
"title": tooltip === false ? '' : title
}, {
default: () => [(0, _vue.createVNode)(_transButton.default, {
"class": [`${prefixCls.value}-copy`, {
[`${prefixCls.value}-copy-success`]: state.copied
}],
"onClick": onCopyClick,
"aria-label": ariaLabel
}, {
default: () => [icon]
})]
});
}
function renderEditInput() {
const {
class: className,
style
} = attrs;
const {
maxlength,
autoSize,
onEnd
} = editable.value;
return (0, _vue.createVNode)(_Editable.default, {
"class": className,
"style": style,
"prefixCls": prefixCls.value,
"value": props.content,
"originContent": state.originContent,
"maxlength": maxlength,
"autoSize": autoSize,
"onSave": onEditChange,
"onChange": onContentChange,
"onCancel": onEditCancel,
"onEnd": onEnd,
"direction": direction.value,
"component": props.component
}, {
enterIcon: slots.editableEnterIcon
});
}
function renderOperations(forceRenderExpanded) {
return [renderExpand(forceRenderExpanded), renderEdit(), renderCopy()].filter(node => node);
}
return () => {
var _a;
const {
triggerType = ['icon']
} = editable.value;
const children = props.ellipsis || props.editable ? props.content !== undefined ? props.content : (_a = slots.default) === null || _a === void 0 ? void 0 : _a.call(slots) : slots.default ? slots.default() : props.content;
if (editing.value) {
return renderEditInput();
}
return (0, _vue.createVNode)(_LocaleReceiver.default, {
"componentName": "Text",
"children": locale => {
const _a = (0, _extends2.default)((0, _extends2.default)({}, props), attrs),
{
type,
disabled,
content,
class: className,
style
} = _a,
restProps = __rest(_a, ["type", "disabled", "content", "class", "style"]);
const {
rows,
suffix,
tooltip
} = ellipsis.value;
const {
edit,
copy: copyStr,
copied,
expand
} = locale;
state.editStr = edit;
state.copyStr = copyStr;
state.copiedStr = copied;
state.expandStr = expand;
const textProps = (0, _omit.default)(restProps, ['prefixCls', 'editable', 'copyable', 'ellipsis', 'mark', 'code', 'delete', 'underline', 'strong', 'keyboard', 'onUpdate:content']);
const cssEllipsis = canUseCSSEllipsis.value;
const cssTextOverflow = rows === 1 && cssEllipsis;
const cssLineClamp = rows && rows > 1 && cssEllipsis;
let textNode = children;
let ariaLabel;
// Only use js ellipsis when css ellipsis not support
if (rows && state.isEllipsis && !state.expanded && !cssEllipsis) {
const {
title
} = restProps;
let restContent = title || '';
if (!title && (typeof children === 'string' || typeof children === 'number')) {
restContent = String(children);
}
// show rest content as title on symbol
restContent = restContent === null || restContent === void 0 ? void 0 : restContent.slice(String(state.ellipsisContent || '').length);
// We move full content to outer element to avoid repeat read the content by accessibility
textNode = (0, _vue.createVNode)(_vue.Fragment, null, [(0, _vue.toRaw)(state.ellipsisContent), (0, _vue.createVNode)("span", {
"title": restContent,
"aria-hidden": "true"
}, [ELLIPSIS_STR]), suffix]);
} else {
textNode = (0, _vue.createVNode)(_vue.Fragment, null, [children, suffix]);
}
textNode = wrapperDecorations(props, textNode);
const showTooltip = tooltip && rows && state.isEllipsis && !state.expanded && !cssEllipsis;
const title = slots.ellipsisTooltip ? slots.ellipsisTooltip() : tooltip;
return (0, _vue.createVNode)(_vcResizeObserver.default, {
"onResize": resizeOnNextFrame,
"disabled": !rows
}, {
default: () => [(0, _vue.createVNode)(_Typography.default, (0, _objectSpread2.default)({
"ref": contentRef,
"class": [{
[`${prefixCls.value}-${type}`]: type,
[`${prefixCls.value}-disabled`]: disabled,
[`${prefixCls.value}-ellipsis`]: rows,
[`${prefixCls.value}-single-line`]: rows === 1 && !state.isEllipsis,
[`${prefixCls.value}-ellipsis-single-line`]: cssTextOverflow,
[`${prefixCls.value}-ellipsis-multiple-line`]: cssLineClamp
}, className],
"style": (0, _extends2.default)((0, _extends2.default)({}, style), {
WebkitLineClamp: cssLineClamp ? rows : undefined
}),
"aria-label": ariaLabel,
"direction": direction.value,
"onClick": triggerType.indexOf('text') !== -1 ? onEditClick : () => {}
}, textProps), {
default: () => [showTooltip ? (0, _vue.createVNode)(_tooltip.default, {
"title": tooltip === true ? children : title
}, {
default: () => [(0, _vue.createVNode)("span", null, [textNode])]
}) : textNode, renderOperations()]
})]
});
}
}, null);
};
}
});
var _default = exports.default = Base;
;