@v-c/textarea 0.0.6 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/TextArea.js CHANGED
@@ -1,210 +1,171 @@
1
1
  import ResizableTextArea_default from "./ResizableTextArea.js";
2
- import { Fragment, computed, createVNode, defineComponent, mergeDefaults, mergeProps, nextTick, shallowRef, watch } from "vue";
3
- import { classNames } from "@v-c/util";
2
+ import { Fragment, computed, createVNode, defineComponent, mergeDefaults, mergeProps, shallowRef, watch } from "vue";
3
+ import { clsx } from "@v-c/util";
4
4
  import omit from "@v-c/util/dist/omit";
5
+ import { getAttrStyleAndClass, toPropsRefs } from "@v-c/util/dist/props-util";
5
6
  import { BaseInput, resolveOnChange, useCount } from "@v-c/input";
6
- var defaults = { prefixCls: "vc-textarea" };
7
- var TextArea_default = /* @__PURE__ */ defineComponent((props, { attrs, expose, slots, emit }) => {
8
- const stateValue = shallowRef(props.value ?? props.defaultValue);
9
- watch(() => props.value, (newValue) => {
10
- if ("value" in props || {}) stateValue.value = newValue;
7
+ import { KeyCodeStr } from "@v-c/util/dist/KeyCode";
8
+ var TextArea_default = /* @__PURE__ */ defineComponent((props, { expose, attrs }) => {
9
+ const { count, showCount } = toPropsRefs(props, "count", "showCount");
10
+ const value = shallowRef(props?.value ?? props?.defaultValue ?? "");
11
+ watch(() => props.value, () => {
12
+ value.value = props.value;
11
13
  });
12
- const setValue = (val, callback) => {
13
- if (stateValue.value === val) return;
14
- if (props.value === void 0) stateValue.value = val;
15
- nextTick(() => {
16
- callback?.();
17
- });
18
- };
19
- const formatValue = computed(() => stateValue.value === void 0 || stateValue.value === null ? "" : String(stateValue.value));
14
+ const formatValue = computed(() => value.value === void 0 || value.value === null ? "" : String(value.value));
20
15
  const focused = shallowRef(false);
21
16
  const compositionRef = shallowRef(false);
22
- const textareaResized = shallowRef(false);
17
+ const textareaResized = shallowRef();
23
18
  const holderRef = shallowRef();
24
19
  const resizableTextAreaRef = shallowRef();
25
20
  const getTextArea = () => resizableTextAreaRef.value?.textArea;
26
21
  const focus = () => {
27
- getTextArea()?.focus();
22
+ getTextArea().focus();
28
23
  };
29
24
  expose({
30
25
  resizableTextArea: resizableTextAreaRef,
31
26
  focus,
32
27
  blur: () => {
33
- getTextArea()?.blur();
28
+ getTextArea().blur();
34
29
  },
35
- nativeElement: computed(() => holderRef.value?.nativeElement || getTextArea() || null)
30
+ nativeElement: computed(() => holderRef.value?.nativeElement || getTextArea())
36
31
  });
37
- watch(() => props.disabled, (newDisabled) => {
38
- focused.value = !newDisabled && focused.value;
32
+ watch(() => props.disabled, () => {
33
+ const prev = focused.value;
34
+ if (props.disabled && prev) focused.value = !props?.disabled && prev;
35
+ }, {
36
+ immediate: true,
37
+ flush: "post"
39
38
  });
40
39
  const selection = shallowRef(null);
41
- watch(selection, (newSelection) => {
42
- if (newSelection) getTextArea()?.setSelectionRange(...newSelection);
40
+ watch(selection, () => {
41
+ if (selection.value) getTextArea().setSelectionRange(...selection.value);
43
42
  });
44
- const countConfig = useCount(computed(() => props.count), computed(() => props.showCount));
43
+ const countConfig = useCount(count, showCount);
45
44
  const mergedMax = computed(() => countConfig.value.max ?? props.maxLength);
46
45
  const hasMaxLength = computed(() => Number(mergedMax.value) > 0);
47
46
  const valueLength = computed(() => countConfig.value.strategy(formatValue.value));
48
47
  const isOutOfRange = computed(() => !!mergedMax.value && valueLength.value > mergedMax.value);
49
- const onChange = (e) => {
50
- props.onChange?.(e);
51
- };
52
48
  const triggerChange = (e, currentValue) => {
53
49
  let cutValue = currentValue;
54
- const cfg = countConfig.value;
55
- if (!compositionRef.value && cfg.exceedFormatter && cfg.max && cfg.strategy(currentValue) > cfg.max) {
56
- cutValue = cfg.exceedFormatter(currentValue, { max: cfg.max });
57
- if (currentValue !== cutValue) selection.value = [getTextArea()?.selectionStart || 0, getTextArea()?.selectionEnd || 0];
50
+ if (!compositionRef.value && countConfig.value.exceedFormatter && countConfig.value.max && countConfig.value.strategy(currentValue) > countConfig.value.max) {
51
+ cutValue = countConfig.value.exceedFormatter(currentValue, { max: countConfig.value.max });
52
+ const textarea$1 = getTextArea();
53
+ if (currentValue !== cutValue) selection.value = [textarea$1.selectionStart || 0, textarea$1.selectionEnd || 0];
58
54
  }
59
- setValue(cutValue);
60
- emit("update:value", cutValue);
61
- nextTick(() => {
62
- resizableTextAreaRef.value?.setValue?.(cutValue);
63
- });
64
- resolveOnChange(e.currentTarget, e, onChange, cutValue);
55
+ const textarea = getTextArea();
56
+ if (!compositionRef.value && textarea && textarea.value !== cutValue) textarea.value = cutValue;
57
+ value.value = cutValue;
58
+ resolveOnChange(e.currentTarget, e, props.onChange, cutValue);
65
59
  };
66
- const onInternalCompositionStart = (e) => {
60
+ const onInternalCompositionStart = () => {
67
61
  compositionRef.value = true;
68
- props.onCompositionStart?.(e);
69
62
  };
70
63
  const onInternalCompositionEnd = (e) => {
71
64
  compositionRef.value = false;
72
- triggerChange(e, e.target.value);
73
- props.onCompositionEnd?.(e);
65
+ triggerChange(e, e.currentTarget.value);
74
66
  };
75
67
  const onInternalChange = (e) => {
76
68
  triggerChange(e, e.target.value);
77
69
  };
78
70
  const handleKeyDown = (e) => {
79
- if (e.key === "Enter" && props.onPressEnter && !e.isComposing) props.onPressEnter?.(e);
80
- props.onKeyDown?.(e);
71
+ const { onPressEnter } = props;
72
+ if (e.key === KeyCodeStr.Enter && onPressEnter && !e.isComposing) onPressEnter(e);
73
+ props?.onKeydown?.(e);
81
74
  };
82
- const handleFocus = (e) => {
75
+ const handleFocus = () => {
83
76
  focused.value = true;
84
- props.onFocus?.(e);
85
77
  };
86
- const handleBlur = (e) => {
78
+ const handleBlur = () => {
87
79
  focused.value = false;
88
- props.onBlur?.(e);
89
80
  };
90
81
  const handleReset = (e) => {
91
- resolveOnChange(getTextArea(), e, onChange);
92
- setValue("", () => focus());
93
- emit("update:value", "");
82
+ value.value = "";
83
+ focus();
84
+ resolveOnChange(getTextArea(), e, props.onChange);
94
85
  };
95
86
  const handleResize = (size) => {
96
- props.onResize?.(size);
87
+ props?.onResize?.(size);
97
88
  if (getTextArea()?.style.height) textareaResized.value = true;
98
89
  };
99
- const mergedAllowClear = computed(() => {
100
- if (!props.allowClear) return props.allowClear;
101
- const clearIcon = slots.clearIcon?.();
102
- if (clearIcon) return {
103
- ...typeof props.allowClear === "object" ? props.allowClear : {},
104
- clearIcon
105
- };
106
- return props.allowClear;
107
- });
108
90
  return () => {
109
- const { allowClear, maxLength, prefixCls = defaults.prefixCls, showCount, disabled, hidden, classNames: classNames$1, styles, onClear, readOnly, autoSize, suffix } = props;
110
- const { class: attrClass, style: attrStyle,...restAttrs } = attrs;
111
- const mergedClassName = props.className || attrClass;
112
- const mergedStyle = {
113
- ...props.style,
114
- ...attrStyle
115
- };
116
- let suffixNode = slots.suffix?.() ?? suffix;
91
+ const { suffix, classNames, styles, prefixCls = "vc-textarea", allowClear, autoSize, showCount: showCount$1, disabled, hidden, readOnly, onClear, maxLength } = props;
92
+ const { style, restAttrs, className } = getAttrStyleAndClass(attrs);
93
+ let suffixNode = suffix;
117
94
  let dataCount;
118
95
  if (countConfig.value.show) {
119
- if (countConfig.value.showFormatter) dataCount = countConfig.value.showFormatter({
96
+ if (countConfig.value.showFormatter) dataCount = countConfig.value.showFormatter?.({
120
97
  value: formatValue.value,
121
98
  count: valueLength.value,
122
99
  maxLength: mergedMax.value
123
100
  });
124
101
  else dataCount = `${valueLength.value}${hasMaxLength.value ? ` / ${mergedMax.value}` : ""}`;
125
102
  suffixNode = createVNode(Fragment, null, [suffixNode, createVNode("span", {
126
- "class": classNames(`${prefixCls}-data-count`, classNames$1?.count),
103
+ "class": clsx(`${prefixCls}-data-count`, classNames?.count),
127
104
  "style": styles?.count
128
105
  }, [dataCount])]);
129
106
  }
130
- const isPureTextArea = !autoSize && !showCount && !allowClear;
131
- const baseInputClassNames = {
132
- ...classNames$1,
133
- affixWrapper: classNames(classNames$1?.affixWrapper, {
134
- [`${prefixCls}-show-count`]: showCount,
135
- [`${prefixCls}-textarea-allow-clear`]: allowClear
136
- })
107
+ const isPureTextArea = !autoSize && !showCount$1 && !allowClear;
108
+ const textareaProps = {
109
+ onKeydown: handleKeyDown,
110
+ onFocus: handleFocus,
111
+ onBlur: handleBlur,
112
+ onCompositionstart: onInternalCompositionStart,
113
+ onCompositionend: onInternalCompositionEnd
137
114
  };
138
- const inputAttrs = omit(restAttrs, [
139
- "class",
140
- "style",
141
- "onFocus",
142
- "onBlur",
143
- "onChange",
144
- "onCompositionstart",
145
- "onCompositionend",
146
- "onKeydown",
147
- "onKeyup",
148
- "onInput"
149
- ]);
150
- const restProps = omit(props, [
151
- "class",
152
- "style",
153
- "onFocus",
154
- "onBlur",
155
- "onChange",
156
- "onCompositionEnd",
157
- "onCompositionStart",
158
- "onKeyDown",
159
- "allowClear",
160
- "maxLength",
161
- "prefixCls",
162
- "showCount",
163
- "disabled",
164
- "hidden",
165
- "classNames",
166
- "styles",
167
- "onClear",
168
- "readOnly",
169
- "autoSize",
170
- "suffix",
171
- "onResize"
172
- ]);
173
115
  return createVNode(BaseInput, {
174
116
  "ref": holderRef,
175
117
  "value": formatValue.value,
176
- "allowClear": mergedAllowClear.value,
118
+ "allowClear": allowClear,
177
119
  "handleReset": handleReset,
178
120
  "suffix": suffixNode,
179
121
  "prefixCls": prefixCls,
180
- "classNames": baseInputClassNames,
122
+ "classNames": {
123
+ ...classNames,
124
+ affixWrapper: clsx(classNames?.affixWrapper, {
125
+ [`${prefixCls}-show-count`]: showCount$1,
126
+ [`${prefixCls}-textarea-allow-clear`]: allowClear
127
+ })
128
+ },
181
129
  "disabled": disabled,
182
130
  "focused": focused.value,
183
- "class": classNames([mergedClassName], isOutOfRange.value && `${prefixCls}-out-of-range`),
131
+ "class": clsx(className, isOutOfRange.value && `${prefixCls}-out-of-range`),
184
132
  "style": {
185
- ...mergedStyle,
133
+ ...style,
186
134
  ...textareaResized.value && !isPureTextArea ? { height: "auto" } : {}
187
135
  },
188
136
  "dataAttrs": { affixWrapper: { "data-count": typeof dataCount === "string" ? dataCount : void 0 } },
189
137
  "hidden": hidden,
190
138
  "readOnly": readOnly,
191
139
  "onClear": onClear
192
- }, { default: () => [createVNode(ResizableTextArea_default, mergeProps(inputAttrs, restProps, {
193
- "value": stateValue.value,
140
+ }, { default: () => [createVNode(ResizableTextArea_default, mergeProps(restAttrs, omit(props, [
141
+ "suffix",
142
+ "classNames",
143
+ "styles",
144
+ "prefixCls",
145
+ "allowClear",
146
+ "autoSize",
147
+ "showCount",
148
+ "disabled",
149
+ "hidden",
150
+ "readOnly",
151
+ "onClear",
152
+ "maxLength",
153
+ "onResize",
154
+ "onChange",
155
+ "onKeydown",
156
+ "onPressEnter"
157
+ ]), {
194
158
  "autoSize": autoSize,
195
159
  "maxLength": maxLength,
196
- "onKeydown": handleKeyDown,
197
- "onChange": onInternalChange,
198
- "onFocus": handleFocus,
199
- "onBlur": handleBlur,
200
- "onCompositionstart": onInternalCompositionStart,
201
- "onCompositionend": onInternalCompositionEnd,
202
- "class": classNames(classNames$1?.textarea),
160
+ "onChange": onInternalChange
161
+ }, textareaProps, {
162
+ "class": clsx(classNames?.textarea),
203
163
  "style": {
204
- ...styles?.textarea,
205
- resize: attrStyle?.resize
164
+ resize: style?.resize,
165
+ ...styles?.textarea
206
166
  },
207
167
  "disabled": disabled,
168
+ "value": value.value,
208
169
  "prefixCls": prefixCls,
209
170
  "onResize": handleResize,
210
171
  "ref": resizableTextAreaRef,
@@ -214,12 +175,12 @@ var TextArea_default = /* @__PURE__ */ defineComponent((props, { attrs, expose,
214
175
  }, {
215
176
  props: /* @__PURE__ */ mergeDefaults({
216
177
  value: {
217
- type: [String, Number],
178
+ type: null,
218
179
  required: false,
219
180
  default: void 0
220
181
  },
221
182
  defaultValue: {
222
- type: [String, Number],
183
+ type: null,
223
184
  required: false,
224
185
  default: void 0
225
186
  },
@@ -228,6 +189,11 @@ var TextArea_default = /* @__PURE__ */ defineComponent((props, { attrs, expose,
228
189
  required: false,
229
190
  default: void 0
230
191
  },
192
+ disabled: {
193
+ type: Boolean,
194
+ required: false,
195
+ default: void 0
196
+ },
231
197
  autoSize: {
232
198
  type: [Boolean, Object],
233
199
  required: false,
@@ -243,16 +209,6 @@ var TextArea_default = /* @__PURE__ */ defineComponent((props, { attrs, expose,
243
209
  required: false,
244
210
  default: void 0
245
211
  },
246
- onClear: {
247
- type: Function,
248
- required: false,
249
- default: void 0
250
- },
251
- readOnly: {
252
- type: Boolean,
253
- required: false,
254
- default: void 0
255
- },
256
212
  classNames: {
257
213
  type: Object,
258
214
  required: false,
@@ -268,106 +224,68 @@ var TextArea_default = /* @__PURE__ */ defineComponent((props, { attrs, expose,
268
224
  required: false,
269
225
  default: void 0
270
226
  },
271
- showCount: {
272
- type: [Boolean, Object],
273
- required: false,
274
- default: void 0
275
- },
276
- count: {
277
- type: Object,
278
- required: false,
279
- default: void 0
280
- },
281
- maxLength: {
282
- type: Number,
283
- required: false,
284
- default: void 0
285
- },
286
227
  suffix: {
287
- type: [
288
- String,
289
- Number,
290
- null,
291
- Boolean,
292
- Array
293
- ],
228
+ type: null,
294
229
  required: false,
295
- skipCheck: true,
296
230
  default: void 0
297
231
  },
298
- disabled: {
299
- type: Boolean,
232
+ showCount: {
233
+ type: [Boolean, Object],
300
234
  required: false,
301
235
  default: void 0
302
236
  },
303
- hidden: {
304
- type: Boolean,
237
+ count: {
238
+ type: null,
305
239
  required: false,
306
240
  default: void 0
307
241
  },
308
- onChange: {
242
+ onClear: {
309
243
  type: Function,
310
244
  required: false,
311
245
  default: void 0
312
246
  },
313
- onFocus: {
247
+ onChange: {
314
248
  type: Function,
315
249
  required: false,
316
250
  default: void 0
317
251
  },
318
- onBlur: {
319
- type: Function,
252
+ maxLength: {
253
+ type: Number,
320
254
  required: false,
321
255
  default: void 0
322
256
  },
323
- onCompositionStart: {
324
- type: Function,
257
+ minLength: {
258
+ type: Number,
325
259
  required: false,
326
260
  default: void 0
327
261
  },
328
- onCompositionEnd: {
329
- type: Function,
262
+ hidden: {
263
+ type: Boolean,
330
264
  required: false,
331
265
  default: void 0
332
266
  },
333
- onKeyDown: {
334
- type: Function,
267
+ readOnly: {
268
+ type: Boolean,
335
269
  required: false,
336
270
  default: void 0
337
271
  },
338
- className: {
272
+ placeholder: {
339
273
  type: String,
340
274
  required: false,
341
275
  default: void 0
342
276
  },
343
- class: {
344
- type: null,
345
- required: false,
346
- default: void 0
347
- },
348
- style: {
349
- type: null,
277
+ autoFocus: {
278
+ type: Boolean,
350
279
  required: false,
351
280
  default: void 0
352
281
  },
353
- placeholder: {
354
- type: String,
282
+ onKeydown: {
283
+ type: Function,
355
284
  required: false,
356
285
  default: void 0
357
286
  }
358
- }, defaults),
287
+ }, { prefixCls: "vc-textarea" }),
359
288
  name: "TextArea",
360
- inheritAttrs: false,
361
- emits: [
362
- "update:value",
363
- "change",
364
- "compositionStart",
365
- "compositionEnd",
366
- "pressEnter",
367
- "keydown",
368
- "focus",
369
- "blur",
370
- "resize"
371
- ]
289
+ inheritAttrs: false
372
290
  });
373
291
  export { TextArea_default as default };
@@ -34,7 +34,7 @@ var SIZING_STYLE = [
34
34
  var computedStyleCache = {};
35
35
  var hiddenTextarea;
36
36
  function calculateNodeStyling(node, useCache = false) {
37
- const nodeRef = node.getAttribute("id") || node.getAttribute("data-id") || node.getAttribute("name");
37
+ const nodeRef = node.getAttribute("id") || node.getAttribute("data-reactid") || node.getAttribute("name");
38
38
  if (useCache && computedStyleCache[nodeRef]) return computedStyleCache[nodeRef];
39
39
  const style = window.getComputedStyle(node);
40
40
  const boxSizing = style.getPropertyValue("box-sizing") || style.getPropertyValue("-moz-box-sizing") || style.getPropertyValue("-webkit-box-sizing");
@@ -33,7 +33,7 @@ var SIZING_STYLE = [
33
33
  var computedStyleCache = {};
34
34
  var hiddenTextarea;
35
35
  function calculateNodeStyling(node, useCache = false) {
36
- const nodeRef = node.getAttribute("id") || node.getAttribute("data-id") || node.getAttribute("name");
36
+ const nodeRef = node.getAttribute("id") || node.getAttribute("data-reactid") || node.getAttribute("name");
37
37
  if (useCache && computedStyleCache[nodeRef]) return computedStyleCache[nodeRef];
38
38
  const style = window.getComputedStyle(node);
39
39
  const boxSizing = style.getPropertyValue("box-sizing") || style.getPropertyValue("-moz-box-sizing") || style.getPropertyValue("-webkit-box-sizing");
@@ -1,58 +1,49 @@
1
- import { CountConfig, ShowCountFormatter } from '@v-c/input';
2
- import { VueNode } from '@v-c/util/dist/type';
1
+ import { BaseInputProps, CommonInputProps, InputProps } from '@v-c/input';
2
+ import { ChangeEventHandler } from '@v-c/util/dist/EventInterface';
3
3
  import { CSSProperties } from 'vue';
4
4
  export interface AutoSizeType {
5
5
  minRows?: number;
6
6
  maxRows?: number;
7
7
  }
8
+ export interface ResizableTextAreaRef {
9
+ textArea: HTMLTextAreaElement;
10
+ }
8
11
  export interface TextAreaProps {
9
- value?: string | number;
10
- defaultValue?: string | number;
12
+ value?: any;
13
+ defaultValue?: any;
11
14
  prefixCls?: string;
15
+ disabled?: boolean;
12
16
  autoSize?: boolean | AutoSizeType;
13
- onPressEnter?: (e: KeyboardEvent) => void;
17
+ onPressEnter?: (e: any) => void;
14
18
  onResize?: (size: {
15
19
  width: number;
16
20
  height: number;
17
21
  }) => void;
18
- onClear?: () => void;
19
- readOnly?: boolean;
20
- classNames?: {
21
- affixWrapper?: string;
22
+ classNames?: CommonInputProps['classNames'] & {
22
23
  textarea?: string;
23
24
  count?: string;
24
25
  };
25
26
  styles?: {
26
- affixWrapper?: CSSProperties;
27
27
  textarea?: CSSProperties;
28
28
  count?: CSSProperties;
29
29
  };
30
- allowClear?: boolean | {
31
- clearIcon?: VueNode;
32
- };
33
- showCount?: boolean | {
34
- formatter: ShowCountFormatter;
35
- };
36
- count?: CountConfig;
30
+ allowClear?: BaseInputProps['allowClear'];
31
+ suffix?: BaseInputProps['suffix'];
32
+ showCount?: InputProps['showCount'];
33
+ count?: InputProps['count'];
34
+ onClear?: InputProps['onClear'];
35
+ onChange?: ChangeEventHandler;
37
36
  maxLength?: number;
38
- suffix?: VueNode;
39
- disabled?: boolean;
37
+ minLength?: number;
40
38
  hidden?: boolean;
41
- onChange?: (e: Event) => void;
42
- onFocus?: (e: FocusEvent) => void;
43
- onBlur?: (e: FocusEvent) => void;
44
- onCompositionStart?: (e: CompositionEvent) => void;
45
- onCompositionEnd?: (e: CompositionEvent) => void;
46
- onKeyDown?: (e: KeyboardEvent) => void;
47
- className?: string;
48
- class?: any;
49
- style?: CSSProperties;
39
+ readOnly?: boolean;
50
40
  placeholder?: string;
41
+ autoFocus?: boolean;
42
+ onKeydown?: (e: KeyboardEvent) => void;
51
43
  }
52
44
  export interface TextAreaRef {
53
- resizableTextArea?: any;
45
+ resizableTextArea: ResizableTextAreaRef;
54
46
  focus: () => void;
55
47
  blur: () => void;
56
- nativeElement: HTMLElement | null;
48
+ nativeElement: HTMLElement;
57
49
  }
58
- export type HTMLTextareaProps = HTMLTextAreaElement;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@v-c/textarea",
3
3
  "type": "module",
4
- "version": "0.0.6",
4
+ "version": "0.0.8",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -25,7 +25,7 @@
25
25
  "dependencies": {
26
26
  "@v-c/input": "^0.0.2",
27
27
  "@v-c/resize-observer": "^1.0.0",
28
- "@v-c/util": "^1.0.0"
28
+ "@v-c/util": "^1.0.1"
29
29
  },
30
30
  "scripts": {
31
31
  "build": "vite build",