eco-vue-js 0.11.9 → 0.11.11

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.
@@ -34,6 +34,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
34
34
  hideInput: { type: Boolean },
35
35
  noWrap: { type: Boolean },
36
36
  textTransparent: { type: Boolean },
37
+ textParts: {},
37
38
  title: {},
38
39
  titleIcon: {},
39
40
  description: {},
@@ -44,6 +44,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
44
44
  allowPaste: { type: Boolean },
45
45
  noWrap: { type: Boolean },
46
46
  textTransparent: { type: Boolean },
47
+ textParts: {},
47
48
  title: {},
48
49
  titleIcon: {},
49
50
  description: {},
@@ -49,6 +49,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
49
49
  allowPaste: { type: Boolean },
50
50
  noWrap: { type: Boolean },
51
51
  textTransparent: { type: Boolean },
52
+ textParts: {},
52
53
  title: {},
53
54
  titleIcon: {},
54
55
  description: {},
@@ -45,6 +45,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
45
45
  allowPaste: { type: Boolean },
46
46
  noWrap: { type: Boolean },
47
47
  textTransparent: { type: Boolean },
48
+ textParts: {},
48
49
  title: {},
49
50
  titleIcon: {},
50
51
  description: {},
@@ -45,6 +45,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
45
45
  allowPaste: { type: Boolean },
46
46
  noWrap: { type: Boolean },
47
47
  textTransparent: { type: Boolean },
48
+ textParts: {},
48
49
  title: {},
49
50
  titleIcon: {},
50
51
  description: {},
@@ -1 +1 @@
1
- {"version":3,"file":"WInput.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/Input/WInput.vue"],"names":[],"mappings":"AAoOA;AAsdA,OAAO,KAAK,EAAC,UAAU,EAAE,aAAa,EAAC,MAAM,SAAS,CAAA;yBAarC,IAAI,SAAS,SAAS,GAAG,MAAM,EAC/C,aAAa,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAC9D,YAAY,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,EAC3G,eAAe,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EACjE;WAmrBO,mBAAmB,CAAC,oCAAkE,CAAC,4BAA2B;oBACzG,OAAO,KAAK,EAAE,gBAAgB;qBAtkB7B,IAAI;oBAOL,IAAI;+BA2DS,aAAa;+BACb,MAAM,aAAa,MAAM;;;;;;;MAmgBc,GAAG,IAAI;WACpE,GAAG;;uBA1DgB,GAAG;0BACA,GAAG;wBACJ,GAAG;;;YAEH,GAAG;;mCA/cF,aAAa;YA8cb,GAAG;;;YAEJ,GAAG;uBACJ,GAAG;wBACF,GAAG;uBACJ,GAAG;uBACH,GAAG;wBACF,GAAG;;;YAnnB1B,oBAAoB,SAAS,4CAAa,SAAS,GAAG,IAAI;YAC1D,gBAAgB,SAAS,aAAa,GAAG,IAAI;YAC7C,aAAa,SAAS,aAAa,GAAG,IAAI;YAC1C,eAAe,SAAS,aAAa,GAAG,IAAI;YAC5C,iBAAiB,SAAS,aAAa,GAAG,IAAI;YAC9C,oBAAoB,SAAS,aAAa,GAAG,IAAI;YACjD,aAAa,GAAG,IAAI;YACpB,OAAO,SAAS,UAAU,GAAG,SAAS,GAAG,IAAI;YAC7C,MAAM,SAAS,UAAU,GAAG,IAAI;YAChC,OAAO,SAAS,UAAU,GAAG,IAAI;YACjC,WAAW,SAAS,UAAU,GAAG,IAAI;YACrC,cAAc,SAAS,UAAU,GAAG,IAAI;YACxC,cAAc,SAAS,KAAK,GAAG,IAAI;YACnC,OAAO,GAAG,IAAI;;EA0pBhB,KACQ,OAAO,KAAK,EAAE,KAAK,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC,OAAO,WAAW,CAAC,CAAA;CAAE;AA9rBzE,wBA8rB4E;AAC5E,KAAK,mBAAmB,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,GAAG,EAAE,CAAC"}
1
+ {"version":3,"file":"WInput.vue.d.ts","sourceRoot":"","sources":["../../../../src/components/Input/WInput.vue"],"names":[],"mappings":"AAqOA;AAwdA,OAAO,KAAK,EAAC,UAAU,EAAE,aAAa,EAAC,MAAM,SAAS,CAAA;yBAYrC,IAAI,SAAS,SAAS,GAAG,MAAM,EAC/C,aAAa,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAC9D,YAAY,mBAAmB,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,EAC3G,eAAe,WAAW,CAAC,OAAO,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,EACjE;WAurBO,mBAAmB,CAAC,oCAAkE,CAAC,4BAA2B;oBACzG,OAAO,KAAK,EAAE,gBAAgB;qBAxkB7B,IAAI;oBAOL,IAAI;+BA2DS,aAAa;+BACb,MAAM,aAAa,MAAM;;;;;;;MAqgBc,GAAG,IAAI;WACpE,GAAG;;uBA1DgB,GAAG;0BACA,GAAG;wBACJ,GAAG;;;YAEH,GAAG;;mCAjdF,aAAa;YAgdb,GAAG;;;YAEJ,GAAG;uBACJ,GAAG;wBACF,GAAG;uBACJ,GAAG;uBACH,GAAG;wBACF,GAAG;;;YArnB1B,oBAAoB,SAAS,4CAAa,SAAS,GAAG,IAAI;YAC1D,gBAAgB,SAAS,aAAa,GAAG,IAAI;YAC7C,aAAa,SAAS,aAAa,GAAG,IAAI;YAC1C,eAAe,SAAS,aAAa,GAAG,IAAI;YAC5C,iBAAiB,SAAS,aAAa,GAAG,IAAI;YAC9C,oBAAoB,SAAS,aAAa,GAAG,IAAI;YACjD,aAAa,GAAG,IAAI;YACpB,OAAO,SAAS,UAAU,GAAG,SAAS,GAAG,IAAI;YAC7C,MAAM,SAAS,UAAU,GAAG,IAAI;YAChC,OAAO,SAAS,UAAU,GAAG,IAAI;YACjC,WAAW,SAAS,UAAU,GAAG,IAAI;YACrC,cAAc,SAAS,UAAU,GAAG,IAAI;YACxC,cAAc,SAAS,KAAK,GAAG,IAAI;YACnC,OAAO,GAAG,IAAI;;EA4pBhB,KACQ,OAAO,KAAK,EAAE,KAAK,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC,OAAO,WAAW,CAAC,CAAA;CAAE;AAlsBzE,wBAksB4E;AAC5E,KAAK,mBAAmB,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,GAAG,EAAE,CAAC"}
@@ -1,10 +1,9 @@
1
- import { defineComponent, useTemplateRef, ref, watch, nextTick, onMounted, onBeforeUnmount, computed, createBlock, openBlock, mergeProps, createSlots, withCtx, renderSlot, unref, createElementVNode, normalizeClass, createElementBlock, createCommentVNode, toDisplayString, normalizeProps, guardReactiveProps, resolveDynamicComponent, withModifiers, withKeys } from 'vue';
1
+ import { defineComponent, defineAsyncComponent, useTemplateRef, ref, watch, nextTick, onMounted, onBeforeUnmount, computed, createBlock, openBlock, mergeProps, createSlots, withCtx, renderSlot, unref, createElementVNode, normalizeClass, createElementBlock, createCommentVNode, toDisplayString, normalizeProps, guardReactiveProps, resolveDynamicComponent, withModifiers, withKeys } from 'vue';
2
2
  import _sfc_main$1 from '../FieldWrapper/WFieldWrapper.vue.js';
3
3
  import { useTabActiveListener } from '../Tabs/use/useTabActiveListener.js';
4
4
  import { Notify } from '../../utils/Notify.js';
5
5
  import { useComponentStates } from '../../utils/useComponentStates.js';
6
- import _sfc_main$2 from './components/ContentEditable.vue.js';
7
- import _sfc_main$3 from './components/InputActions.vue.js';
6
+ import _sfc_main$2 from './components/InputActions.vue.js';
8
7
 
9
8
  const _hoisted_1 = { class: "relative flex min-h-full flex-1" };
10
9
  const _sfc_main = /* @__PURE__ */ defineComponent({
@@ -38,6 +37,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
38
37
  hideInput: { type: Boolean },
39
38
  noWrap: { type: Boolean },
40
39
  textTransparent: { type: Boolean },
40
+ textParts: {},
41
41
  title: {},
42
42
  titleIcon: {},
43
43
  description: {},
@@ -62,6 +62,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
62
62
  },
63
63
  emits: ["update:model-value", "keypress:enter", "keypress:up", "keypress:down", "keypress:delete", "keypress:backspace", "click:clear", "focus", "blur", "click", "mousedown", "click:suffix", "select:input", "paste"],
64
64
  setup(__props, { expose: __expose, emit: __emit }) {
65
+ const ContentEditable = defineAsyncComponent(() => import('./components/ContentEditable.vue.js'));
65
66
  const props = __props;
66
67
  const emit = __emit;
67
68
  const { isReadonly, isDisabled } = useComponentStates(props);
@@ -307,7 +308,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
307
308
  }, [
308
309
  createElementVNode("div", _hoisted_1, [
309
310
  renderSlot(_ctx.$slots, "before", normalizeProps(guardReactiveProps({ modelValue: _ctx.modelValue }))),
310
- (openBlock(), createBlock(resolveDynamicComponent(_ctx.textarea ? _sfc_main$2 : "input"), {
311
+ (openBlock(), createBlock(resolveDynamicComponent(_ctx.textarea ? unref(ContentEditable) : "input"), {
311
312
  id,
312
313
  ref: "input",
313
314
  class: normalizeClass(["w-input min-h-full flex-1 basis-auto appearance-none border-none bg-[inherit] outline-0 placeholder:text-gray-400 disabled:cursor-not-allowed dark:placeholder:text-gray-500", {
@@ -328,6 +329,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
328
329
  max: _ctx.max,
329
330
  spellcheck: _ctx.spellcheck ? "true" : "false",
330
331
  "max-length": _ctx.maxLength,
332
+ "text-parts": _ctx.textParts,
331
333
  onInput: handleInputEvent,
332
334
  onKeypress: _cache[0] || (_cache[0] = withKeys(withModifiers(($event) => !unref(isDisabled) && !unref(isReadonly) && _ctx.$emit("keypress:enter", $event), ["exact"]), ["enter"])),
333
335
  onKeydown: [
@@ -353,13 +355,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
353
355
  onMousedown: _cache[5] || (_cache[5] = withModifiers(($event) => _ctx.$emit("mousedown", $event), ["stop"])),
354
356
  onSelect: _cache[6] || (_cache[6] = withModifiers(($event) => _ctx.$emit("select:input", $event), ["stop"])),
355
357
  "onUpdate:modelValue": updateModelValue
356
- }, null, 40, ["id", "class", "value", "placeholder", "type", "name", "disabled", "readonly", "autocomplete", "size", "step", "min", "max", "spellcheck", "max-length", "onFocus", "onBlur"])),
358
+ }, null, 40, ["id", "class", "value", "placeholder", "type", "name", "disabled", "readonly", "autocomplete", "size", "step", "min", "max", "spellcheck", "max-length", "text-parts", "onFocus", "onBlur"])),
357
359
  renderSlot(_ctx.$slots, "after")
358
360
  ])
359
361
  ], 2)
360
362
  ], 2)
361
363
  ], 2),
362
- !_ctx.seamless || focused ? (openBlock(), createBlock(_sfc_main$3, {
364
+ !_ctx.seamless || focused ? (openBlock(), createBlock(_sfc_main$2, {
363
365
  key: 1,
364
366
  "model-value": _ctx.modelValue,
365
367
  loading: _ctx.loading,
@@ -44,6 +44,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
44
44
  hideInput: { type: Boolean },
45
45
  noWrap: { type: Boolean },
46
46
  textTransparent: { type: Boolean },
47
+ textParts: {},
47
48
  title: {},
48
49
  titleIcon: {},
49
50
  description: {},
@@ -40,6 +40,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
40
40
  hideInput: { type: Boolean },
41
41
  noWrap: { type: Boolean },
42
42
  textTransparent: { type: Boolean },
43
+ textParts: {},
43
44
  title: {},
44
45
  titleIcon: {},
45
46
  description: {},
@@ -46,6 +46,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
46
46
  hideInput: { type: Boolean },
47
47
  noWrap: { type: Boolean },
48
48
  textTransparent: { type: Boolean },
49
+ textParts: {},
49
50
  title: {},
50
51
  titleIcon: {},
51
52
  description: {},
@@ -43,6 +43,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
43
43
  hideInput: { type: Boolean },
44
44
  noWrap: { type: Boolean },
45
45
  textTransparent: { type: Boolean },
46
+ textParts: {},
46
47
  title: {},
47
48
  titleIcon: {},
48
49
  description: {},
@@ -1,8 +1,9 @@
1
- import { WrapSelection } from '../types';
1
+ import { TextPart, WrapSelection } from '../types';
2
2
  type __VLS_Props = {
3
3
  value: string;
4
4
  placeholder: string;
5
5
  maxLength: number;
6
+ textParts: TextPart[] | undefined;
6
7
  };
7
8
  declare const _default: import('vue').DefineComponent<__VLS_Props, {
8
9
  focus: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"ContentEditable.vue.d.ts","sourceRoot":"","sources":["../../../../../src/components/Input/components/ContentEditable.vue"],"names":[],"mappings":"AAqBA;AAyLA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,UAAU,CAAA;AAI3C,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;CAClB,CAAC;;;;2BAkH4B,aAAa,KAAG,IAAI;2BAnBpB,MAAM,aAAa,MAAM;;;;;;;;;;;;;;;;;;;AAqIvD,wBAUG"}
1
+ {"version":3,"file":"ContentEditable.vue.d.ts","sourceRoot":"","sources":["../../../../../src/components/Input/components/ContentEditable.vue"],"names":[],"mappings":"AAiBA;AA+RA,OAAO,KAAK,EAAC,QAAQ,EAAE,aAAa,EAAC,MAAM,UAAU,CAAA;AAIrD,KAAK,WAAW,GAAG;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAA;CAClC,CAAC;;;;2BAsN4B,aAAa,KAAG,IAAI;2BAnBpB,MAAM,aAAa,MAAM;;;;;;;;;;;;;;;;;;;AA2IvD,wBAUG"}
@@ -1,148 +1,5 @@
1
- import { defineComponent, useTemplateRef, ref, createElementBlock, openBlock, nextTick } from 'vue';
1
+ import _sfc_main from './ContentEditable.vue2.js';
2
+
2
3
 
3
- const _hoisted_1 = ["textContent", "placeholder"];
4
- const _sfc_main = /* @__PURE__ */ defineComponent({
5
- __name: "ContentEditable",
6
- props: {
7
- value: {},
8
- placeholder: {},
9
- maxLength: {}
10
- },
11
- emits: ["update:model-value", "focus", "blur", "keydown"],
12
- setup(__props, { expose: __expose, emit: __emit }) {
13
- const props = __props;
14
- const emit = __emit;
15
- const elementRef = useTemplateRef("element");
16
- const focused = ref(false);
17
- const insertParagraph = (e) => {
18
- if (e.inputType === "insertParagraph") {
19
- e.preventDefault();
20
- insertPlain("\n");
21
- }
22
- };
23
- const onInput = (e) => {
24
- e.stopImmediatePropagation();
25
- if (!(e.target instanceof HTMLDivElement)) return;
26
- const text = e.target.textContent?.replace(/\r\n?/g, "\n") ?? "";
27
- if (text === props.value) return;
28
- if (props.maxLength && typeof text === "string" && text.length > props.maxLength) {
29
- e.preventDefault();
30
- const substring = text.substring(0, props.maxLength);
31
- if (e.target) e.target.textContent = substring;
32
- emit("update:model-value", substring);
33
- } else {
34
- emit("update:model-value", text);
35
- }
36
- };
37
- const onPaste = async (e) => {
38
- e.preventDefault();
39
- navigator.clipboard.readText();
40
- const text = (e.clipboardData?.getData("text/plain") || await navigator.clipboard.readText()).replace(/\r\n?/g, "\n");
41
- insertPlain(text);
42
- };
43
- const insertPlain = (text) => {
44
- const root = elementRef.value;
45
- if (!root) return;
46
- const { start, end } = getSelectionOffsets();
47
- const next = (props.value ?? "").slice(0, start) + text + ((props.value ?? "").slice(end) || " ");
48
- const caretAfter = start + text.length;
49
- emit("update:model-value", next);
50
- nextTick(() => setCaret(caretAfter));
51
- };
52
- const getSelectionOffsets = () => {
53
- const selection = window.getSelection();
54
- if (!elementRef.value || !selection || selection.rangeCount === 0) return { start: 0, end: 0 };
55
- const range = selection.getRangeAt(0);
56
- const pre = range.cloneRange();
57
- pre.selectNodeContents(elementRef.value);
58
- pre.setEnd(range.startContainer, range.startOffset);
59
- const start = pre.toString().length;
60
- const selected = range.toString().length;
61
- return { start, end: start + selected };
62
- };
63
- const getNodeOffset = (index) => {
64
- if (!elementRef.value || index === void 0) return void 0;
65
- if (!elementRef.value.firstChild) elementRef.value.appendChild(document.createTextNode(""));
66
- const walker = document.createTreeWalker(elementRef.value, NodeFilter.SHOW_TEXT, null);
67
- let node, offset = index;
68
- while (node = walker.nextNode()) {
69
- const len = node.nodeValue?.length ?? 0;
70
- if (offset <= len) return { node, offset };
71
- offset -= len;
72
- }
73
- const last = elementRef.value.lastChild;
74
- if (!last) return void 0;
75
- return { node: last, offset: last.nodeType === Node.TEXT_NODE && last.nodeValue ? last.nodeValue.length : last.childNodes.length };
76
- };
77
- const setCaret = (indexStart, indexEnd) => {
78
- const start = getNodeOffset(indexStart);
79
- if (start === void 0) return;
80
- const range = document.createRange();
81
- range.setStart(start.node, start.offset);
82
- const end = getNodeOffset(indexEnd);
83
- if (end !== void 0) range.setEnd(end.node, end.offset);
84
- else range.collapse(true);
85
- const selection = window.getSelection();
86
- selection?.removeAllRanges();
87
- selection?.addRange(range);
88
- };
89
- let offsetsOld = null;
90
- const wrapSelection = (value) => {
91
- const root = elementRef.value;
92
- if (!root) return;
93
- let offsets = getSelectionOffsets();
94
- if (focused.value || !offsetsOld) offsetsOld = offsets;
95
- else offsets = offsetsOld;
96
- const currentText = props.value ?? "";
97
- const selectedText = currentText.slice(offsets.start, offsets.end);
98
- const beforeSelection = currentText.slice(0, offsets.start);
99
- const afterSelection = currentText.slice(offsets.end);
100
- const newText = beforeSelection + (value.start || "") + selectedText + (value.end || "") + afterSelection;
101
- const cursorPosition = offsets.start + (value.end ? (value.start?.length ?? 0) + selectedText.length : 0);
102
- emit("update:model-value", newText);
103
- nextTick(() => setCaret(cursorPosition));
104
- };
105
- const focus = () => {
106
- elementRef.value?.focus();
107
- };
108
- const blur = () => {
109
- elementRef.value?.blur();
110
- };
111
- __expose({
112
- focus,
113
- blur,
114
- wrapSelection,
115
- setCaret,
116
- getSelectionOffsets,
117
- get offsetWidth() {
118
- return elementRef.value?.offsetWidth ?? 0;
119
- }
120
- });
121
- return (_ctx, _cache) => {
122
- return openBlock(), createElementBlock("div", {
123
- ref: "element",
124
- contenteditable: "true",
125
- role: "textbox",
126
- "aria-multiline": "true",
127
- spellcheck: "false",
128
- textContent: _ctx.value,
129
- placeholder: _ctx.placeholder,
130
- class: "relative whitespace-pre empty:before:pointer-events-none empty:before:text-gray-400 empty:before:[content:attr(placeholder)] dark:empty:before:text-gray-500",
131
- onInput,
132
- onBeforeinput: insertParagraph,
133
- onPaste,
134
- onKeydown: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("keydown", $event)),
135
- onFocus: _cache[1] || (_cache[1] = ($event) => {
136
- _ctx.$emit("focus", $event);
137
- focused.value = true;
138
- }),
139
- onBlur: _cache[2] || (_cache[2] = ($event) => {
140
- _ctx.$emit("blur", $event);
141
- focused.value = false;
142
- })
143
- }, null, 40, _hoisted_1);
144
- };
145
- }
146
- });
147
4
 
148
5
  export { _sfc_main as default };
@@ -1,5 +1,225 @@
1
- import _sfc_main from './ContentEditable.vue.js';
2
-
1
+ import { defineComponent, useTemplateRef, ref, watch, onMounted, createElementBlock, openBlock, nextTick } from 'vue';
3
2
 
3
+ const _hoisted_1 = ["placeholder"];
4
+ const _sfc_main = /* @__PURE__ */ defineComponent({
5
+ __name: "ContentEditable",
6
+ props: {
7
+ value: {},
8
+ placeholder: {},
9
+ maxLength: {},
10
+ textParts: {}
11
+ },
12
+ emits: ["update:model-value", "focus", "blur", "keydown"],
13
+ setup(__props, { expose: __expose, emit: __emit }) {
14
+ const props = __props;
15
+ const emit = __emit;
16
+ const elementRef = useTemplateRef("element");
17
+ const focused = ref(false);
18
+ const updateTextParts = () => {
19
+ if (!elementRef.value || !props.textParts) return;
20
+ const offsets = getSelectionOffsets();
21
+ const existingNodes = Array.from(elementRef.value.childNodes);
22
+ let nodeIndex = 0;
23
+ for (const item of props.textParts) {
24
+ const existingNode = existingNodes[nodeIndex];
25
+ if (typeof item === "string") {
26
+ const displayText = item.replace(/\n$/g, "\n ");
27
+ if (existingNode?.nodeType === Node.TEXT_NODE) {
28
+ if (existingNode.textContent !== displayText) {
29
+ existingNode.textContent = displayText;
30
+ }
31
+ } else {
32
+ const textNode = document.createTextNode(displayText);
33
+ elementRef.value.insertBefore(textNode, existingNode || null);
34
+ }
35
+ } else {
36
+ if (existingNode?.nodeType === Node.ELEMENT_NODE && existingNode.tagName.toLowerCase() === item.tag.toLowerCase()) {
37
+ const element = existingNode;
38
+ if (element.textContent !== item.value) {
39
+ element.textContent = item.value;
40
+ }
41
+ const contentEditable = item.edit ? "plaintext-only" : "false";
42
+ if (element.getAttribute("contenteditable") !== contentEditable) {
43
+ element.setAttribute("contenteditable", contentEditable);
44
+ }
45
+ if (element.className !== (item.class || "")) {
46
+ element.className = item.class || "";
47
+ }
48
+ } else {
49
+ const element = document.createElement(item.tag);
50
+ element.textContent = item.value;
51
+ element.setAttribute("contenteditable", item.edit ? "plaintext-only" : "false");
52
+ if (item.class) element.className = item.class;
53
+ elementRef.value.insertBefore(element, existingNode || null);
54
+ }
55
+ }
56
+ nodeIndex++;
57
+ }
58
+ while (nodeIndex < existingNodes.length) {
59
+ elementRef.value.removeChild(existingNodes[nodeIndex]);
60
+ nodeIndex++;
61
+ }
62
+ if (focused.value) setCaret(offsets.start, offsets.end !== offsets.start ? void 0 : offsets.end);
63
+ };
64
+ watch(() => props.textParts, updateTextParts, { immediate: true });
65
+ const updateTextValue = (value) => {
66
+ if (props.textParts || !elementRef.value) return;
67
+ if (elementRef.value.textContent !== value) {
68
+ const offsets = getSelectionOffsets();
69
+ elementRef.value.textContent = value;
70
+ if (focused.value) setCaret(offsets.start, offsets.end !== offsets.start ? void 0 : offsets.end);
71
+ }
72
+ };
73
+ watch(() => props.value, updateTextValue, { immediate: true });
74
+ const textPartsToText = (parts) => {
75
+ return parts.map((part) => typeof part === "string" ? part : part.value).join("");
76
+ };
77
+ const getCurrentText = () => {
78
+ return props.textParts ? textPartsToText(props.textParts) : props.value;
79
+ };
80
+ const lineBreakEvents = ["insertParagraph", "insertLineBreak"];
81
+ const insertParagraph = (e) => {
82
+ if (lineBreakEvents.includes(e.inputType)) {
83
+ e.preventDefault();
84
+ insertPlain("\n");
85
+ }
86
+ };
87
+ const regexDifferentEnding = /\r\n?/g;
88
+ const regexSpaces = /\n \n/g;
89
+ const regexEnding = / +$/gm;
90
+ const normalizeText = (text) => {
91
+ return text.replace(regexDifferentEnding, "\n").replace(regexSpaces, "\n\n").replace(regexEnding, "");
92
+ };
93
+ const onInput = (e) => {
94
+ e.stopImmediatePropagation();
95
+ if (!(e.target instanceof HTMLDivElement)) return;
96
+ const rawText = e.target.textContent ?? "";
97
+ const text = normalizeText(rawText);
98
+ const currentText = getCurrentText();
99
+ if (text === currentText) return;
100
+ if (props.maxLength && typeof text === "string" && text.length > props.maxLength) {
101
+ e.preventDefault();
102
+ const substring = text.substring(0, props.maxLength);
103
+ if (!props.textParts) updateTextValue(substring);
104
+ else updateTextParts();
105
+ emit("update:model-value", substring);
106
+ } else {
107
+ emit("update:model-value", text);
108
+ }
109
+ };
110
+ const onPaste = async (e) => {
111
+ e.preventDefault();
112
+ navigator.clipboard.readText();
113
+ const text = (e.clipboardData?.getData("text/plain") || await navigator.clipboard.readText()).replace(/\r\n?/g, "\n");
114
+ insertPlain(text);
115
+ };
116
+ const insertPlain = (text) => {
117
+ const root = elementRef.value;
118
+ if (!root) return;
119
+ const { start, end } = getSelectionOffsets();
120
+ const currentText = getCurrentText();
121
+ const next = (currentText ?? "").slice(0, start) + text + ((currentText ?? "").slice(end) || " ");
122
+ const caretAfter = start + text.length;
123
+ emit("update:model-value", props.maxLength && next.length > props.maxLength ? next.substring(0, props.maxLength) : next);
124
+ nextTick(() => setCaret(props.maxLength ? Math.min(caretAfter, props.maxLength) : caretAfter));
125
+ };
126
+ const getSelectionOffsets = () => {
127
+ const selection = window.getSelection();
128
+ if (!elementRef.value || !selection || selection.rangeCount === 0) return { start: 0, end: 0 };
129
+ const range = selection.getRangeAt(0);
130
+ const pre = range.cloneRange();
131
+ pre.selectNodeContents(elementRef.value);
132
+ pre.setEnd(range.startContainer, range.startOffset);
133
+ const start = pre.toString().length;
134
+ const selected = range.toString().length;
135
+ return { start, end: start + selected };
136
+ };
137
+ const getNodeOffset = (index) => {
138
+ if (!elementRef.value || index === void 0) return void 0;
139
+ if (!elementRef.value.firstChild) elementRef.value.appendChild(document.createTextNode(""));
140
+ const walker = document.createTreeWalker(elementRef.value, NodeFilter.SHOW_TEXT, null);
141
+ let node, offset = index;
142
+ while (node = walker.nextNode()) {
143
+ const len = node.nodeValue?.length ?? 0;
144
+ if (offset <= len) return { node, offset };
145
+ offset -= len;
146
+ }
147
+ const last = elementRef.value.lastChild;
148
+ if (!last) return void 0;
149
+ return { node: last, offset: last.nodeType === Node.TEXT_NODE && last.nodeValue ? last.nodeValue.length : last.childNodes.length };
150
+ };
151
+ const setCaret = (indexStart, indexEnd) => {
152
+ const start = getNodeOffset(indexStart);
153
+ if (start === void 0) return;
154
+ const range = document.createRange();
155
+ range.setStart(start.node, start.offset);
156
+ const end = getNodeOffset(indexEnd);
157
+ if (end !== void 0) range.setEnd(end.node, end.offset);
158
+ else range.collapse(true);
159
+ const selection = window.getSelection();
160
+ selection?.removeAllRanges();
161
+ selection?.addRange(range);
162
+ };
163
+ let offsetsOld = null;
164
+ const wrapSelection = (value) => {
165
+ const root = elementRef.value;
166
+ if (!root) return;
167
+ let offsets = getSelectionOffsets();
168
+ if (focused.value || !offsetsOld) offsetsOld = offsets;
169
+ else offsets = offsetsOld;
170
+ const currentText = getCurrentText() ?? "";
171
+ const selectedText = currentText.slice(offsets.start, offsets.end);
172
+ const beforeSelection = currentText.slice(0, offsets.start);
173
+ const afterSelection = currentText.slice(offsets.end);
174
+ const newText = beforeSelection + (value.start || "") + selectedText + (value.end || "") + afterSelection;
175
+ const cursorPosition = offsets.start + (value.end ? (value.start?.length ?? 0) + selectedText.length : 0);
176
+ emit("update:model-value", newText);
177
+ nextTick(() => setCaret(cursorPosition));
178
+ };
179
+ const focus = () => {
180
+ elementRef.value?.focus();
181
+ };
182
+ const blur = () => {
183
+ elementRef.value?.blur();
184
+ };
185
+ onMounted(() => {
186
+ updateTextValue(props.value);
187
+ updateTextParts();
188
+ });
189
+ __expose({
190
+ focus,
191
+ blur,
192
+ wrapSelection,
193
+ setCaret,
194
+ getSelectionOffsets,
195
+ get offsetWidth() {
196
+ return elementRef.value?.offsetWidth ?? 0;
197
+ }
198
+ });
199
+ return (_ctx, _cache) => {
200
+ return openBlock(), createElementBlock("div", {
201
+ ref: "element",
202
+ contenteditable: "plaintext-only",
203
+ role: "textbox",
204
+ "aria-multiline": "true",
205
+ spellcheck: "false",
206
+ placeholder: _ctx.placeholder,
207
+ class: "relative whitespace-pre",
208
+ onInput,
209
+ onBeforeinput: _cache[0] || (_cache[0] = ($event) => insertParagraph($event)),
210
+ onPaste,
211
+ onKeydown: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("keydown", $event)),
212
+ onFocus: _cache[2] || (_cache[2] = ($event) => {
213
+ _ctx.$emit("focus", $event);
214
+ focused.value = true;
215
+ }),
216
+ onBlur: _cache[3] || (_cache[3] = ($event) => {
217
+ _ctx.$emit("blur", $event);
218
+ focused.value = false;
219
+ })
220
+ }, null, 40, _hoisted_1);
221
+ };
222
+ }
223
+ });
4
224
 
5
225
  export { _sfc_main as default };
@@ -29,6 +29,7 @@ export interface InputProps<Type extends InputType> extends Omit<FieldWrapperPro
29
29
  hideInput?: boolean;
30
30
  noWrap?: boolean;
31
31
  textTransparent?: boolean;
32
+ textParts?: TextPart[];
32
33
  }
33
34
  export interface InputAsyncProps<Type extends InputType> extends InputProps<Type> {
34
35
  validate?: ValidateFn | ValidateFn[];
@@ -60,4 +61,10 @@ export type WrapSelection = {
60
61
  start?: string;
61
62
  end?: string;
62
63
  };
64
+ export type TextPart = {
65
+ value: string;
66
+ tag: keyof HTMLElementTagNameMap;
67
+ edit?: boolean;
68
+ class?: string;
69
+ } | string;
63
70
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/Input/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,uBAAuB,CAAA;AAC5D,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,iCAAiC,CAAA;AACtE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,KAAK,CAAA;AAElC,MAAM,WAAW,UAAU,CAAC,IAAI,SAAS,SAAS,CAAE,SAAQ,IAAI,CAAC,iBAAiB,EAAE,YAAY,CAAC;IAC/F,UAAU,CAAC,EAAE,CAAC,IAAI,SAAS,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC,GAAG,SAAS,CAAA;IAClE,IAAI,CAAC,EAAE,IAAI,CAAA;IAEX,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,OAAO,CAAA;IAEhB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IAEZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;IAC7B,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B;AAED,MAAM,WAAW,eAAe,CAAC,IAAI,SAAS,SAAS,CAAE,SAAQ,UAAU,CAAC,IAAI,CAAC;IAC/E,QAAQ,CAAC,EAAE,UAAU,GAAG,UAAU,EAAE,CAAA;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,iBAAiB,CAAC,IAAI,SAAS,SAAS,CAAE,SAAQ,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,QAAQ,GAAG,aAAa,GAAG,YAAY,CAAC,CAAC;IACjL,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,iBAAiB,CAAC,IAAI,SAAS,SAAS,EAAE,MAAM,CAAE,SAAQ,iBAAiB,CAAC,IAAI,CAAC;IAChG,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,QAAQ,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAA;IAChF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAC,CAAC,CAAA;CACnF;AAED,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IACnF,UAAU,CAAC,EAAE,IAAI,GAAG,SAAS,CAAA;IAC7B,OAAO,CAAC,EAAE,IAAI,CAAA;IACd,OAAO,CAAC,EAAE,IAAI,CAAA;CACf;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;CACb,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/Input/types.ts"],"names":[],"mappings":"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"}
@@ -61,6 +61,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
61
61
  allowPaste: { type: Boolean },
62
62
  noWrap: { type: Boolean },
63
63
  textTransparent: { type: Boolean },
64
+ textParts: {},
64
65
  title: {},
65
66
  titleIcon: {},
66
67
  description: {},
@@ -53,6 +53,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
53
53
  allowPaste: { type: Boolean },
54
54
  noWrap: { type: Boolean },
55
55
  textTransparent: { type: Boolean },
56
+ textParts: {},
56
57
  title: {},
57
58
  titleIcon: {},
58
59
  description: {},
@@ -50,6 +50,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
50
50
  allowPaste: { type: Boolean },
51
51
  noWrap: { type: Boolean },
52
52
  textTransparent: { type: Boolean },
53
+ textParts: {},
53
54
  title: {},
54
55
  titleIcon: {},
55
56
  description: {},
@@ -46,6 +46,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
46
46
  allowPaste: { type: Boolean },
47
47
  noWrap: { type: Boolean },
48
48
  textTransparent: { type: Boolean },
49
+ textParts: {},
49
50
  title: {},
50
51
  titleIcon: {},
51
52
  description: {},
@@ -46,6 +46,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
46
46
  allowPaste: { type: Boolean },
47
47
  noWrap: { type: Boolean },
48
48
  textTransparent: { type: Boolean },
49
+ textParts: {},
49
50
  title: {},
50
51
  titleIcon: {},
51
52
  description: {},
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "type": "git",
5
5
  "url": "https://github.com/rsmple/eco-vue-js.git"
6
6
  },
7
- "version": "0.11.9",
7
+ "version": "0.11.11",
8
8
  "dependencies": {
9
9
  "@stylistic/eslint-plugin": "5.2.3",
10
10
  "@tanstack/eslint-plugin-query": "5.83.1",