Editable.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  2. import { createVNode as _createVNode } from "vue";
  3. import KeyCode from '../_util/KeyCode';
  4. import TextArea from '../input/TextArea';
  5. import EnterOutlined from "@ant-design/icons-vue/es/icons/EnterOutlined";
  6. import { defineComponent, ref, reactive, watch, onMounted, toRefs } from 'vue';
  7. import classNames from '../_util/classNames';
  8. // CSSINJS
  9. import useStyle from './style';
  10. const editableProps = () => ({
  11. prefixCls: String,
  12. value: String,
  13. maxlength: Number,
  14. autoSize: {
  15. type: [Boolean, Object]
  16. },
  17. onSave: Function,
  18. onCancel: Function,
  19. onEnd: Function,
  20. onChange: Function,
  21. originContent: String,
  22. direction: String,
  23. component: String
  24. });
  25. const Editable = defineComponent({
  26. compatConfig: {
  27. MODE: 3
  28. },
  29. name: 'Editable',
  30. inheritAttrs: false,
  31. props: editableProps(),
  32. // emits: ['save', 'cancel', 'end', 'change'],
  33. setup(props, _ref) {
  34. let {
  35. emit,
  36. slots,
  37. attrs
  38. } = _ref;
  39. const {
  40. prefixCls
  41. } = toRefs(props);
  42. const state = reactive({
  43. current: props.value || '',
  44. lastKeyCode: undefined,
  45. inComposition: false,
  46. cancelFlag: false
  47. });
  48. watch(() => props.value, current => {
  49. state.current = current;
  50. });
  51. const textArea = ref();
  52. onMounted(() => {
  53. var _a;
  54. if (textArea.value) {
  55. const resizableTextArea = (_a = textArea.value) === null || _a === void 0 ? void 0 : _a.resizableTextArea;
  56. const innerTextArea = resizableTextArea === null || resizableTextArea === void 0 ? void 0 : resizableTextArea.textArea;
  57. innerTextArea.focus();
  58. const {
  59. length
  60. } = innerTextArea.value;
  61. innerTextArea.setSelectionRange(length, length);
  62. }
  63. });
  64. function saveTextAreaRef(node) {
  65. textArea.value = node;
  66. }
  67. function onChange(_ref2) {
  68. let {
  69. target: {
  70. value
  71. }
  72. } = _ref2;
  73. state.current = value.replace(/[\r\n]/g, '');
  74. emit('change', state.current);
  75. }
  76. function onCompositionStart() {
  77. state.inComposition = true;
  78. }
  79. function onCompositionEnd() {
  80. state.inComposition = false;
  81. }
  82. function onKeyDown(e) {
  83. const {
  84. keyCode
  85. } = e;
  86. if (keyCode === KeyCode.ENTER) {
  87. e.preventDefault();
  88. }
  89. // We don't record keyCode when IME is using
  90. if (state.inComposition) return;
  91. state.lastKeyCode = keyCode;
  92. }
  93. function onKeyUp(e) {
  94. const {
  95. keyCode,
  96. ctrlKey,
  97. altKey,
  98. metaKey,
  99. shiftKey
  100. } = e;
  101. // Check if it's a real key
  102. if (state.lastKeyCode === keyCode && !state.inComposition && !ctrlKey && !altKey && !metaKey && !shiftKey) {
  103. if (keyCode === KeyCode.ENTER) {
  104. confirmChange();
  105. emit('end');
  106. } else if (keyCode === KeyCode.ESC) {
  107. state.current = props.originContent;
  108. emit('cancel');
  109. }
  110. }
  111. }
  112. function onBlur() {
  113. confirmChange();
  114. }
  115. function confirmChange() {
  116. emit('save', state.current.trim());
  117. }
  118. // style
  119. const [wrapSSR, hashId] = useStyle(prefixCls);
  120. return () => {
  121. const textAreaClassName = classNames({
  122. [`${prefixCls.value}`]: true,
  123. [`${prefixCls.value}-edit-content`]: true,
  124. [`${prefixCls.value}-rtl`]: props.direction === 'rtl',
  125. [props.component ? `${prefixCls.value}-${props.component}` : '']: true
  126. }, attrs.class, hashId.value);
  127. return wrapSSR(_createVNode("div", _objectSpread(_objectSpread({}, attrs), {}, {
  128. "class": textAreaClassName
  129. }), [_createVNode(TextArea, {
  130. "ref": saveTextAreaRef,
  131. "maxlength": props.maxlength,
  132. "value": state.current,
  133. "onChange": onChange,
  134. "onKeydown": onKeyDown,
  135. "onKeyup": onKeyUp,
  136. "onCompositionstart": onCompositionStart,
  137. "onCompositionend": onCompositionEnd,
  138. "onBlur": onBlur,
  139. "rows": 1,
  140. "autoSize": props.autoSize === undefined || props.autoSize
  141. }, null), slots.enterIcon ? slots.enterIcon({
  142. className: `${props.prefixCls}-edit-content-confirm`
  143. }) : _createVNode(EnterOutlined, {
  144. "class": `${props.prefixCls}-edit-content-confirm`
  145. }, null)]));
  146. };
  147. }
  148. });
  149. export default Editable;