iep-ui
Version:
An enterprise-class UI design language and Vue-based implementation
562 lines (485 loc) • 18.7 kB
JavaScript
import _mergeJSXProps from 'babel-helper-vue-jsx-merge-props';
import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
import _defineProperty from 'babel-runtime/helpers/defineProperty';
import _typeof from 'babel-runtime/helpers/typeof';
import _extends from 'babel-runtime/helpers/extends';
import isStyleSupport from '../_util/styleChecker';
import PropTypes from '../_util/vue-types';
import { ConfigConsumerProps } from '../config-provider/configConsumerProps';
import LocaleReceiver from '../locale-provider/LocaleReceiver';
import { getOptionProps } from '../_util/props-util';
import copy from '../_util/copy-to-clipboard';
import TransButton from '../_util/transButton';
import raf from '../_util/raf';
import measure from './util';
import Tooltip from '../tooltip';
import omit from 'lodash/omit';
import ResizeObserver from '../vc-resize-observer';
import Typography from './Typography';
export var BaseType = 'secondary' | 'success' | 'warning' | 'danger';
var isLineClampSupport = isStyleSupport('webkitLineClamp');
var isTextOverflowSupport = isStyleSupport('textOverflow');
var ELLIPSIS_STR = '...';
export var baseProps = {
editable: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
copyable: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
prefixCls: PropTypes.string,
component: PropTypes.string,
type: PropTypes.oneOf(['secondary', 'success', 'danger', 'warning']),
disabled: PropTypes.bool,
ellipsis: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),
code: PropTypes.bool,
mark: PropTypes.bool,
underline: PropTypes.bool,
'delete': PropTypes.bool,
strong: PropTypes.bool,
keyboard: PropTypes.bool,
content: PropTypes.string
};
export default {
name: 'Base',
inheritAttrs: false,
inject: {
configProvider: { 'default': function _default() {
return ConfigConsumerProps;
} }
},
props: baseProps,
data: function data() {
return {
state: {
edit: false,
copied: false,
ellipsisText: '',
ellipsisContent: null,
isEllipsis: false,
expanded: false,
clientRendered: false,
//locale
expandStr: '',
copyStr: '',
copiedStr: '',
editStr: '',
copyId: undefined,
rafId: undefined,
prevProps: undefined,
originContent: ''
},
editIcon: undefined
};
},
computed: {
rowsAndContentListen: function rowsAndContentListen() {
return {
rows: this.ellipsisFunc.rows,
content: this.content
};
},
ellipsisFunc: function ellipsisFunc() {
var _getOptionProps = getOptionProps(this),
ellipsis = _getOptionProps.ellipsis;
if (!ellipsis) return {};
return _extends({
rows: 1,
expandable: false
}, (typeof ellipsis === 'undefined' ? 'undefined' : _typeof(ellipsis)) === 'object' ? ellipsis : null);
},
editableFunc: function editableFunc() {
var _getOptionProps2 = getOptionProps(this),
editable = _getOptionProps2.editable;
if (!editable) return { editing: this.state.edit };
return _extends({
editing: this.state.edit
}, (typeof editable === 'undefined' ? 'undefined' : _typeof(editable)) === 'object' ? editable : null);
},
canUseCSSEllipsis: function canUseCSSEllipsis() {
var _ellipsisFunc = this.ellipsisFunc,
rows = _ellipsisFunc.rows,
expandable = _ellipsisFunc.expandable,
suffix = _ellipsisFunc.suffix,
onEllipsis = _ellipsisFunc.onEllipsis,
tooltip = _ellipsisFunc.tooltip;
if (suffix || tooltip) return false;
if (this.$props.editable || this.$props.copyable || expandable || onEllipsis) {
return false;
}
if (rows === 1) {
return isTextOverflowSupport;
}
return isLineClampSupport;
}
},
mounted: function mounted() {
var _this = this;
this.state.clientRendered = true;
this.$watch('rowsAndContentListen', function () {
_this.resizeOnNextFrame();
}, {
deep: true,
immediate: true
});
},
beforeDestroy: function beforeDestroy() {
window.clearTimeout(this.state.copyId);
raf.cancel(this.state.rafId);
},
methods: {
getChildrenText: function getChildrenText() {
var _getOptionProps3 = getOptionProps(this),
ellipsis = _getOptionProps3.ellipsis,
editable = _getOptionProps3.editable,
content = _getOptionProps3.content;
return ellipsis || editable ? content : this.$refs.contentRef.$el.innerText;
},
// =============== Expand ===============
onExpandClick: function onExpandClick(e) {
var onExpand = this.ellipsisFunc.onExpand;
this.state.expanded = true;
if (onExpand) {
onExpand(e);
}
},
// ================ Edit ================
onEditClick: function onEditClick(e) {
e.preventDefault();
var _getOptionProps4 = getOptionProps(this),
content = _getOptionProps4.content;
this.state.originContent = content;
this.triggerEdit(true);
},
onEditChange: function onEditChange(value) {
this.onContentChange(value);
this.triggerEdit(false);
},
onContentChange: function onContentChange(value) {
var onChange = this.editableFunc.onChange;
var _getOptionProps5 = getOptionProps(this),
content = _getOptionProps5.content;
if (value !== content) {
this.$emit('update:content', value);
if (onChange) {
onChange(value);
}
}
},
onEditCancel: function onEditCancel() {
if (this.editableFunc.onCancel) {
this.editableFunc.onCancel();
}
this.triggerEdit(false);
},
// ================ Copy ================
onCopyClick: function onCopyClick(e) {
var _this2 = this;
e.preventDefault();
var copyable = this.$props.copyable;
var copyConfig = _extends({}, (typeof copyable === 'undefined' ? 'undefined' : _typeof(copyable)) === 'object' ? copyable : null);
if (copyConfig.text === undefined) {
copyConfig.text = this.getChildrenText();
}
copy(copyConfig.text || '');
this.state.copied = true;
this.$nextTick(function () {
if (copyConfig.onCopy) {
copyConfig.onCopy();
}
_this2.state.copyId = window.setTimeout(function () {
_this2.state.copied = false;
}, 3000);
});
},
triggerEdit: function triggerEdit(edit) {
var _this3 = this;
var onStart = this.editableFunc.onStart;
if (edit && onStart) {
onStart();
}
this.state.edit = edit;
this.$nextTick(function () {
if (!edit) {
_this3.editIcon ? _this3.editIcon.focus() : null;
}
});
},
// ============== Ellipsis ==============
resizeOnNextFrame: function resizeOnNextFrame() {
var _this4 = this;
raf.cancel(this.state.rafId);
this.state.rafId = raf(function () {
_this4.syncEllipsis();
});
},
syncEllipsis: function syncEllipsis() {
var _state = this.state,
ellipsisText = _state.ellipsisText,
isEllipsis = _state.isEllipsis;
var _ellipsisFunc2 = this.ellipsisFunc,
rows = _ellipsisFunc2.rows,
suffix = _ellipsisFunc2.suffix,
onEllipsis = _ellipsisFunc2.onEllipsis;
if (!rows || rows < 0 || !this.$refs.contentRef.$el || this.state.expanded || this.$props.content === undefined) return;
// Do not measure if css already support ellipsis
if (this.canUseCSSEllipsis) return;
var _measure = measure(this.$refs.contentRef.$el, { rows: rows, suffix: suffix }, this.$props.content, this.renderOperations(true), ELLIPSIS_STR),
content = _measure.content,
text = _measure.text,
ell = _measure.ell;
// console.log('ell:', this.$refs.contentRef.$el);
if (ellipsisText !== text || this.state.isEllipsis !== ell) {
this.state.ellipsisText = text;
this.state.ellipsisContent = content;
this.state.isEllipsis = ell;
if (isEllipsis !== ell && onEllipsis) {
onEllipsis(ell);
}
}
},
wrapperDecorations: function wrapperDecorations(_ref, content) {
var mark = _ref.mark,
code = _ref.code,
underline = _ref.underline,
del = _ref.del,
strong = _ref.strong,
keyboard = _ref.keyboard;
var h = this.$createElement;
var currentContent = content;
function wrap(needed, Tag) {
if (!needed) return;
currentContent = h(Tag, [currentContent]);
}
wrap(strong, 'strong');
wrap(underline, 'u');
wrap(del, 'del');
wrap(code, 'code');
wrap(mark, 'mark');
wrap(keyboard, 'kbd');
return currentContent;
},
renderExpand: function renderExpand(forceRender) {
var h = this.$createElement;
var _ellipsisFunc3 = this.ellipsisFunc,
expandable = _ellipsisFunc3.expandable,
symbol = _ellipsisFunc3.symbol;
var _getOptionProps6 = getOptionProps(this),
customizePrefixCls = _getOptionProps6.prefixCls;
var getPrefixCls = this.configProvider.getPrefixCls;
var prefixCls = getPrefixCls('typography', customizePrefixCls);
if (!expandable) return null;
// force render expand icon for measure usage or it will cause dead loop
if (!forceRender && (this.state.expanded || !this.state.isEllipsis)) return null;
var expandContent = (this.$slots.ellipsisSymbol ? this.$slots.ellipsisSymbol() : symbol) || this.state.expandStr;
return h(
'a',
{
key: 'expand',
'class': prefixCls + '-expand',
on: {
'click': this.onExpandClick
},
attrs: {
'aria-label': this.state.expandStr
}
},
[expandContent]
);
},
renderEdit: function renderEdit() {
var h = this.$createElement;
if (!this.$props.editable) return;
var _getOptionProps7 = getOptionProps(this),
customizePrefixCls = _getOptionProps7.prefixCls;
var getPrefixCls = this.configProvider.getPrefixCls;
var prefixCls = getPrefixCls('typography', customizePrefixCls);
var tooltip = this.$props.editable.tooltip;
var icon = this.$slots.editableIcon ? this.$slots.editableIcon() : h(EditOutlined, {
attrs: { role: 'button' }
});
var title = this.$slots.editableTooltip ? this.$slots.editableTooltip() : this.$state.editStr;
var ariaLabel = typeof title === 'string' ? title : '';
return h(
Tooltip,
{ key: 'edit', attrs: { title: tooltip === false ? '' : title }
},
[h(
TransButton,
{
ref: this.editIcon,
'class': prefixCls + '-edit',
on: {
'click': this.onEditClick
},
attrs: {
'aria-label': ariaLabel
}
},
[icon]
)]
);
},
renderCopy: function renderCopy() {
var h = this.$createElement;
if (!this.$props.copyable) return;
var _getOptionProps8 = getOptionProps(this),
customizePrefixCls = _getOptionProps8.prefixCls;
var getPrefixCls = this.configProvider.getPrefixCls;
var prefixCls = getPrefixCls('typography', customizePrefixCls);
var tooltip = this.$props.copyable.tooltip;
var defaultTitle = this.state.copied ? this.state.copiedStr : this.state.copyStr;
var title = this.$slots.copyableTooltip ? this.$slots.copyableTooltip({ copied: this.state.copied }) : defaultTitle;
var ariaLabel = typeof title === 'string' ? title : '';
var defaultIcon = this.state.copied ? h(CheckOutlined) : h(CopyOutlined);
var icon = this.$slots.copyableIcon ? this.$slots.copyableIcon({ copied: !!this.state.copied }) : defaultIcon;
return h(
Tooltip,
{ key: 'copy', attrs: { title: tooltip === false ? '' : title }
},
[h(
TransButton,
{
'class': [prefixCls + '-copy', _defineProperty({}, prefixCls + '-copy-success', this.state.copied)],
on: {
'click': this.onCopyClick
},
attrs: {
'aria-label': ariaLabel
}
},
[icon]
)]
);
},
renderEditInput: function renderEditInput() {
var h = this.$createElement;
var _$attrs = this.$attrs,
className = _$attrs['class'],
style = _$attrs.style;
var _editableFunc = this.editableFunc,
maxlength = _editableFunc.maxlength,
autoSize = _editableFunc.autoSize,
onEnd = _editableFunc.onEnd;
var _getOptionProps9 = getOptionProps(this),
customizePrefixCls = _getOptionProps9.prefixCls;
var getPrefixCls = this.configProvider.getPrefixCls;
var prefixCls = getPrefixCls('typography', customizePrefixCls);
return h(Editable, {
'class': className,
style: style,
attrs: { prefixCls: prefixCls.value,
value: this.$props.content,
originContent: this.state.originContent,
maxlength: maxlength,
autoSize: autoSize
},
on: {
'save': this.onEditChange,
'change': this.onContentChange,
'cancel': this.onEditCancel,
'end': onEnd
}
});
},
renderOperations: function renderOperations(forceRenderExpanded) {
return [this.renderExpand(forceRenderExpanded), this.renderEdit(), this.renderCopy()].filter(function (node) {
return node;
});
}
},
render: function render() {
var _this5 = this;
var h = arguments[0];
var _getOptionProps10 = getOptionProps(this),
customizePrefixCls = _getOptionProps10.prefixCls;
var getPrefixCls = this.configProvider.getPrefixCls;
var prefixCls = getPrefixCls('typography', customizePrefixCls);
var editing = this.editableFunc.editing;
var _children = this.$props.ellipsis || this.$props.editable ? this.$props.content !== undefined ? this.$props.content : this.$slots['default'] : this.$slots['default'] ? this.$slots['default'] : this.$props.content;
if (editing) {
return this.renderEditInput();
}
return h(LocaleReceiver, {
attrs: {
componentName: 'Text',
children: function children(locale) {
var _ref3;
var _$props$$attrs = _extends({}, _this5.$props, _this5.$attrs),
type = _$props$$attrs.type,
disabled = _$props$$attrs.disabled,
content = _$props$$attrs.content,
className = _$props$$attrs['class'],
style = _$props$$attrs.style,
restProps = _objectWithoutProperties(_$props$$attrs, ['type', 'disabled', 'content', 'class', 'style']);
var _ellipsisFunc4 = _this5.ellipsisFunc,
rows = _ellipsisFunc4.rows,
suffix = _ellipsisFunc4.suffix,
tooltip = _ellipsisFunc4.tooltip;
var edit = locale.edit,
copyStr = locale.copy,
copied = locale.copied,
expand = locale.expand;
_this5.state.editStr = edit;
_this5.state.copyStr = copyStr;
_this5.state.copiedStr = copied;
_this5.state.expandStr = expand;
var textProps = omit(restProps, ['prefixCls', 'editable', 'copyable', 'ellipsis', 'mark', 'code', 'delete', 'underline', 'strong', 'keyboard']);
var cssEllipsis = _this5.canUseCSSEllipsis;
var cssTextOverflow = rows === 1 && cssEllipsis;
var cssLineClamp = rows && rows > 1 && cssEllipsis;
var textNode = _children;
var ariaLabel = void 0;
// Only use js ellipsis when css ellipsis not support
if (rows && _this5.state.isEllipsis && !_this5.state.expanded && !cssEllipsis) {
var _title = restProps.title;
var restContent = _title || '';
if (!_title && (typeof _children === 'string' || typeof _children === 'number')) {
restContent = _children;
}
// show rest content as title on symbol
restContent = restContent ? restContent.slice((_this5.state.ellipsisContent || '').length) : null;
// We move full content to outer element to avoid repeat read the content by accessibility
textNode = [_this5.state.ellipsisContent, h(
'span',
{
attrs: { title: restContent, 'aria-hidden': 'true' }
},
[ELLIPSIS_STR]
), suffix];
} else {
textNode = [_children, suffix];
}
textNode = _this5.wrapperDecorations(_this5.$props, textNode);
var showTooltip = tooltip && rows && _this5.state.isEllipsis && !_this5.state.expanded && !cssEllipsis;
var title = _this5.$slots.ellipsisTooltip ? _this5.$slots.ellipsisTooltip() : tooltip;
console.log('showTooltip:', tooltip, rows, _this5.state.isEllipsis, !_this5.state.expanded, !cssEllipsis);
return h(
ResizeObserver,
{
on: {
'resize': _this5.resizeOnNextFrame
},
attrs: { disabled: !rows }
},
[h(
Typography,
_mergeJSXProps([{
ref: 'contentRef',
'class': [(_ref3 = {}, _defineProperty(_ref3, prefixCls + '-' + type, type), _defineProperty(_ref3, prefixCls + '-disabled', disabled), _defineProperty(_ref3, prefixCls + '-ellipsis', rows), _defineProperty(_ref3, prefixCls + '-single-line', rows === 1), _defineProperty(_ref3, prefixCls + '-ellipsis-single-line', cssTextOverflow), _defineProperty(_ref3, prefixCls + '-ellipsis-multiple-line', cssLineClamp), _ref3), className],
style: _extends({}, style, {
WebkitLineClamp: cssLineClamp ? rows : undefined
}),
attrs: { 'aria-label': ariaLabel
}
}, textProps]),
[showTooltip ? h(
Tooltip,
{
attrs: { title: tooltip === true ? _children : title }
},
[h('span', [textNode])]
) : textNode, _this5.renderOperations()]
)]
);
}
}
});
}
};