@v-c/textarea 0.0.5 → 0.0.7

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,208 +1,146 @@
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";
4
- import omit from "@v-c/util/dist/omit";
2
+ import { Fragment, computed, createVNode, defineComponent, mergeDefaults, mergeProps, shallowRef, watch } from "vue";
3
+ import { clsx } from "@v-c/util";
4
+ import { getAttrStyleAndClass, toPropsRefs } from "@v-c/util/dist/props-util";
5
5
  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;
6
+ import { KeyCodeStr } from "@v-c/util/dist/KeyCode.ts";
7
+ var TextArea_default = /* @__PURE__ */ defineComponent((props, { expose, attrs }) => {
8
+ const { count, showCount } = toPropsRefs(props, "count", "showCount");
9
+ const value = shallowRef(props?.value ?? props?.defaultValue ?? "");
10
+ watch(() => props.value, () => {
11
+ value.value = props.value;
11
12
  });
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));
13
+ const formatValue = computed(() => value.value === void 0 || value.value === null ? "" : String(value.value));
20
14
  const focused = shallowRef(false);
21
15
  const compositionRef = shallowRef(false);
22
- const textareaResized = shallowRef(false);
16
+ const textareaResized = shallowRef();
23
17
  const holderRef = shallowRef();
24
18
  const resizableTextAreaRef = shallowRef();
25
- const getTextArea = () => resizableTextAreaRef.value?.textArea();
19
+ const getTextArea = () => resizableTextAreaRef.value?.textArea;
26
20
  const focus = () => {
27
- getTextArea()?.focus();
21
+ getTextArea().focus();
28
22
  };
29
23
  expose({
30
- resizableTextArea: computed(() => resizableTextAreaRef.value),
24
+ resizableTextArea: resizableTextAreaRef,
31
25
  focus,
32
26
  blur: () => {
33
- getTextArea()?.blur();
27
+ getTextArea().blur();
34
28
  },
35
- nativeElement: computed(() => holderRef.value?.nativeElement || getTextArea() || null)
29
+ nativeElement: computed(() => holderRef.value?.nativeElement || getTextArea())
36
30
  });
37
- watch(() => props.disabled, (newDisabled) => {
38
- focused.value = !newDisabled && focused.value;
31
+ watch(() => props.disabled, () => {
32
+ const prev = focused.value;
33
+ if (props.disabled && prev) focused.value = !props?.disabled && prev;
34
+ }, {
35
+ immediate: true,
36
+ flush: "post"
39
37
  });
40
38
  const selection = shallowRef(null);
41
- watch(selection, (newSelection) => {
42
- if (newSelection) getTextArea()?.setSelectionRange(...newSelection);
39
+ watch(selection, () => {
40
+ if (selection.value) getTextArea().setSelectionRange(...selection.value);
43
41
  });
44
- const countConfig = useCount(computed(() => props.count), computed(() => props.showCount));
42
+ const countConfig = useCount(count, showCount);
45
43
  const mergedMax = computed(() => countConfig.value.max ?? props.maxLength);
46
44
  const hasMaxLength = computed(() => Number(mergedMax.value) > 0);
47
45
  const valueLength = computed(() => countConfig.value.strategy(formatValue.value));
48
46
  const isOutOfRange = computed(() => !!mergedMax.value && valueLength.value > mergedMax.value);
49
- const onChange = (e) => {
50
- props.onChange?.(e);
51
- };
52
47
  const triggerChange = (e, currentValue) => {
53
48
  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];
49
+ if (!compositionRef.value && countConfig.value.exceedFormatter && countConfig.value.max && countConfig.value.strategy(currentValue) > countConfig.value.max) {
50
+ cutValue = countConfig.value.exceedFormatter(currentValue, { max: countConfig.value.max });
51
+ if (currentValue !== cutValue) selection.value = [getTextArea().selectionStart || 0, getTextArea().selectionEnd || 0];
58
52
  }
59
- setValue(cutValue);
60
- emit("update:value", cutValue);
61
- nextTick(() => {
62
- resizableTextAreaRef.value?.setValue?.(cutValue);
63
- });
64
- resolveOnChange(e.currentTarget, e, onChange, cutValue);
53
+ value.value = cutValue;
54
+ resolveOnChange(e.currentTarget, e, props.onChange, cutValue);
65
55
  };
66
- const onInternalCompositionStart = (e) => {
56
+ const onInternalCompositionStart = () => {
67
57
  compositionRef.value = true;
68
- props.onCompositionStart?.(e);
69
58
  };
70
59
  const onInternalCompositionEnd = (e) => {
71
60
  compositionRef.value = false;
72
- triggerChange(e, e.target.value);
73
- props.onCompositionEnd?.(e);
61
+ triggerChange(e, e.currentTarget.value);
74
62
  };
75
63
  const onInternalChange = (e) => {
76
64
  triggerChange(e, e.target.value);
77
65
  };
78
66
  const handleKeyDown = (e) => {
79
- if (e.key === "Enter" && props.onPressEnter && !e.isComposing) props.onPressEnter?.(e);
80
- props.onKeyDown?.(e);
67
+ const { onPressEnter } = props;
68
+ if (e.key === KeyCodeStr.Enter && onPressEnter && !e.isComposing) onPressEnter(e);
81
69
  };
82
- const handleFocus = (e) => {
70
+ const handleFocus = () => {
83
71
  focused.value = true;
84
- props.onFocus?.(e);
85
72
  };
86
- const handleBlur = (e) => {
73
+ const handleBlur = () => {
87
74
  focused.value = false;
88
- props.onBlur?.(e);
89
75
  };
90
76
  const handleReset = (e) => {
91
- resolveOnChange(getTextArea(), e, onChange);
92
- setValue("", () => focus());
93
- emit("update:value", "");
77
+ value.value = "";
78
+ focus();
79
+ resolveOnChange(getTextArea(), e, props.onChange);
94
80
  };
95
81
  const handleResize = (size) => {
96
- props.onResize?.(size);
82
+ props?.onResize?.(size);
97
83
  if (getTextArea()?.style.height) textareaResized.value = true;
98
84
  };
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
85
  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;
86
+ const { suffix, className, classNames, styles, prefixCls = "vc-textarea", allowClear, autoSize, showCount: showCount$1, disabled, hidden, readOnly, onClear, maxLength } = props;
87
+ const { style, restAttrs } = getAttrStyleAndClass(attrs);
88
+ let suffixNode = suffix;
117
89
  let dataCount;
118
90
  if (countConfig.value.show) {
119
- if (countConfig.value.showFormatter) dataCount = countConfig.value.showFormatter({
91
+ if (countConfig.value.showFormatter) dataCount = countConfig.value.showFormatter?.({
120
92
  value: formatValue.value,
121
93
  count: valueLength.value,
122
94
  maxLength: mergedMax.value
123
95
  });
124
96
  else dataCount = `${valueLength.value}${hasMaxLength.value ? ` / ${mergedMax.value}` : ""}`;
125
97
  suffixNode = createVNode(Fragment, null, [suffixNode, createVNode("span", {
126
- "class": classNames(`${prefixCls}-data-count`, classNames$1?.count),
98
+ "class": clsx(`${prefixCls}-data-count`, classNames?.count),
127
99
  "style": styles?.count
128
100
  }, [dataCount])]);
129
101
  }
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
- })
102
+ const isPureTextArea = !autoSize && !showCount$1 && !allowClear;
103
+ const textareaProps = {
104
+ onKeydown: handleKeyDown,
105
+ onFocus: handleFocus,
106
+ onBlur: handleBlur,
107
+ onCompositionstart: onInternalCompositionStart,
108
+ onCompositionend: onInternalCompositionEnd
137
109
  };
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
110
  return createVNode(BaseInput, {
174
111
  "ref": holderRef,
175
112
  "value": formatValue.value,
176
- "allowClear": mergedAllowClear.value,
113
+ "allowClear": allowClear,
177
114
  "handleReset": handleReset,
178
115
  "suffix": suffixNode,
179
116
  "prefixCls": prefixCls,
180
- "classNames": baseInputClassNames,
117
+ "classNames": {
118
+ ...classNames,
119
+ affixWrapper: clsx(classNames?.affixWrapper, {
120
+ [`${prefixCls}-show-count`]: showCount$1,
121
+ [`${prefixCls}-textarea-allow-clear`]: allowClear
122
+ })
123
+ },
181
124
  "disabled": disabled,
182
125
  "focused": focused.value,
183
- "class": classNames([mergedClassName], isOutOfRange.value && `${prefixCls}-out-of-range`),
126
+ "class": clsx(className, isOutOfRange.value && `${prefixCls}-out-of-range`),
184
127
  "style": {
185
- ...mergedStyle,
128
+ ...style,
186
129
  ...textareaResized.value && !isPureTextArea ? { height: "auto" } : {}
187
130
  },
188
131
  "dataAttrs": { affixWrapper: { "data-count": typeof dataCount === "string" ? dataCount : void 0 } },
189
132
  "hidden": hidden,
190
133
  "readOnly": readOnly,
191
134
  "onClear": onClear
192
- }, { default: () => [createVNode(ResizableTextArea_default, mergeProps(inputAttrs, restProps, {
193
- "value": stateValue.value,
135
+ }, { default: () => [createVNode(ResizableTextArea_default, mergeProps(restAttrs, {
194
136
  "autoSize": autoSize,
195
137
  "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),
138
+ "onChange": onInternalChange
139
+ }, textareaProps, {
140
+ "className": clsx(classNames?.textarea),
203
141
  "style": {
204
- ...styles?.textarea,
205
- resize: attrStyle?.resize
142
+ resize: style?.resize,
143
+ ...styles?.textarea
206
144
  },
207
145
  "disabled": disabled,
208
146
  "prefixCls": prefixCls,
@@ -214,12 +152,12 @@ var TextArea_default = /* @__PURE__ */ defineComponent((props, { attrs, expose,
214
152
  }, {
215
153
  props: /* @__PURE__ */ mergeDefaults({
216
154
  value: {
217
- type: [String, Number],
155
+ type: null,
218
156
  required: false,
219
157
  default: void 0
220
158
  },
221
159
  defaultValue: {
222
- type: [String, Number],
160
+ type: null,
223
161
  required: false,
224
162
  default: void 0
225
163
  },
@@ -228,28 +166,28 @@ var TextArea_default = /* @__PURE__ */ defineComponent((props, { attrs, expose,
228
166
  required: false,
229
167
  default: void 0
230
168
  },
231
- autoSize: {
232
- type: [Boolean, Object],
169
+ disabled: {
170
+ type: Boolean,
233
171
  required: false,
234
172
  default: void 0
235
173
  },
236
- onPressEnter: {
237
- type: Function,
174
+ className: {
175
+ type: String,
238
176
  required: false,
239
177
  default: void 0
240
178
  },
241
- onResize: {
242
- type: Function,
179
+ autoSize: {
180
+ type: [Boolean, Object],
243
181
  required: false,
244
182
  default: void 0
245
183
  },
246
- onClear: {
184
+ onPressEnter: {
247
185
  type: Function,
248
186
  required: false,
249
187
  default: void 0
250
188
  },
251
- readOnly: {
252
- type: Boolean,
189
+ onResize: {
190
+ type: Function,
253
191
  required: false,
254
192
  default: void 0
255
193
  },
@@ -268,106 +206,53 @@ var TextArea_default = /* @__PURE__ */ defineComponent((props, { attrs, expose,
268
206
  required: false,
269
207
  default: void 0
270
208
  },
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
209
  suffix: {
287
- type: [
288
- String,
289
- Number,
290
- null,
291
- Boolean,
292
- Array
293
- ],
294
- required: false,
295
- skipCheck: true,
296
- default: void 0
297
- },
298
- disabled: {
299
- type: Boolean,
300
- required: false,
301
- default: void 0
302
- },
303
- hidden: {
304
- type: Boolean,
305
- required: false,
306
- default: void 0
307
- },
308
- onChange: {
309
- type: Function,
310
- required: false,
311
- default: void 0
312
- },
313
- onFocus: {
314
- type: Function,
210
+ type: null,
315
211
  required: false,
316
212
  default: void 0
317
213
  },
318
- onBlur: {
319
- type: Function,
214
+ showCount: {
215
+ type: [Boolean, Object],
320
216
  required: false,
321
217
  default: void 0
322
218
  },
323
- onCompositionStart: {
324
- type: Function,
219
+ count: {
220
+ type: null,
325
221
  required: false,
326
222
  default: void 0
327
223
  },
328
- onCompositionEnd: {
224
+ onClear: {
329
225
  type: Function,
330
226
  required: false,
331
227
  default: void 0
332
228
  },
333
- onKeyDown: {
229
+ onChange: {
334
230
  type: Function,
335
231
  required: false,
336
232
  default: void 0
337
233
  },
338
- className: {
339
- type: String,
234
+ maxLength: {
235
+ type: Number,
340
236
  required: false,
341
237
  default: void 0
342
238
  },
343
- class: {
344
- type: null,
239
+ minLength: {
240
+ type: Number,
345
241
  required: false,
346
242
  default: void 0
347
243
  },
348
- style: {
349
- type: null,
244
+ hidden: {
245
+ type: Boolean,
350
246
  required: false,
351
247
  default: void 0
352
248
  },
353
- placeholder: {
354
- type: String,
249
+ readOnly: {
250
+ type: Boolean,
355
251
  required: false,
356
252
  default: void 0
357
253
  }
358
- }, defaults),
254
+ }, { prefixCls: "vc-textarea" }),
359
255
  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
- ]
256
+ inheritAttrs: false
372
257
  });
373
258
  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,47 @@
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;
16
+ className?: string;
12
17
  autoSize?: boolean | AutoSizeType;
13
- onPressEnter?: (e: KeyboardEvent) => void;
18
+ onPressEnter?: (e: any) => void;
14
19
  onResize?: (size: {
15
20
  width: number;
16
21
  height: number;
17
22
  }) => void;
18
- onClear?: () => void;
19
- readOnly?: boolean;
20
- classNames?: {
21
- affixWrapper?: string;
23
+ classNames?: CommonInputProps['classNames'] & {
22
24
  textarea?: string;
23
25
  count?: string;
24
26
  };
25
27
  styles?: {
26
- affixWrapper?: CSSProperties;
27
28
  textarea?: CSSProperties;
28
29
  count?: CSSProperties;
29
30
  };
30
- allowClear?: boolean | {
31
- clearIcon?: VueNode;
32
- };
33
- showCount?: boolean | {
34
- formatter: ShowCountFormatter;
35
- };
36
- count?: CountConfig;
31
+ allowClear?: BaseInputProps['allowClear'];
32
+ suffix?: BaseInputProps['suffix'];
33
+ showCount?: InputProps['showCount'];
34
+ count?: InputProps['count'];
35
+ onClear?: InputProps['onClear'];
36
+ onChange?: ChangeEventHandler;
37
37
  maxLength?: number;
38
- suffix?: VueNode;
39
- disabled?: boolean;
38
+ minLength?: number;
40
39
  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;
50
- placeholder?: string;
40
+ readOnly?: boolean;
51
41
  }
52
42
  export interface TextAreaRef {
53
- resizableTextArea?: any;
43
+ resizableTextArea: ResizableTextAreaRef;
54
44
  focus: () => void;
55
45
  blur: () => void;
56
- nativeElement: HTMLElement | null;
46
+ nativeElement: HTMLElement;
57
47
  }
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.5",
4
+ "version": "0.0.7",
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",