goodteditor-ui 1.0.88 → 1.0.91

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/index.d.ts CHANGED
@@ -22,6 +22,7 @@ import Select from './src/components/ui/Select.vue';
22
22
  import TimePicker from './src/components/ui/TimePicker.vue';
23
23
  import Tooltip from './src/components/ui/Tooltip.vue';
24
24
  import Grid from './src/components/ui/Grid.vue';
25
+ import EditableText from './src/components/ui/EditableText.vue';
25
26
  import { WysiwygEditor, WysiwygConsts, WysiwygRenderMixins } from './src/components/ui/WysiwygEditor';
26
27
  // utils stuff
27
28
  import FormComponent from './src/components/ui/utils/FormComponent';
@@ -56,5 +57,6 @@ export {
56
57
  TimePicker,
57
58
  Tooltip,
58
59
  Grid,
60
+ EditableText,
59
61
  WysiwygEditor
60
62
  };
package/index.js CHANGED
@@ -22,6 +22,7 @@ import Select from './src/components/ui/Select.vue';
22
22
  import TimePicker from './src/components/ui/TimePicker.vue';
23
23
  import Tooltip from './src/components/ui/Tooltip.vue';
24
24
  import Grid from './src/components/ui/Grid.vue';
25
+ import EditableText from './src/components/ui/EditableText.vue';
25
26
  import { WysiwygEditor, WysiwygConsts, WysiwygRenderMixins } from './src/components/ui/WysiwygEditor';
26
27
  // utils stuff
27
28
  import FormComponent from './src/components/ui/utils/FormComponent';
@@ -56,5 +57,6 @@ export {
56
57
  TimePicker,
57
58
  Tooltip,
58
59
  Grid,
60
+ EditableText,
59
61
  WysiwygEditor
60
62
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "goodteditor-ui",
3
- "version": "1.0.88",
3
+ "version": "1.0.91",
4
4
  "main": "index.js",
5
5
  "homepage": "https://goodt-ui.netlify.app/",
6
6
  "scripts": {
@@ -0,0 +1,21 @@
1
+ ```vue
2
+ <template>
3
+ <div class="pad-l5">
4
+ <p>model: {{ model }}</p>
5
+ <ui-editable-text v-model="model" v-bind="options"></ui-editable-text>
6
+ </div>
7
+ </template>
8
+ <script>
9
+ import UiEditableText from './EditableText.vue';
10
+
11
+ export default {
12
+ components: { UiEditableText },
13
+ data: () => ({
14
+ model: 'hello world',
15
+ options: {
16
+ size: 'large'
17
+ }
18
+ }),
19
+ };
20
+ </script>
21
+ ```
@@ -0,0 +1,135 @@
1
+ <template>
2
+ <div class="ui-editable-text" @click="onRootClick">
3
+ <div class="ui-editable-text-label cursor-pointer text-truncate" :class="labelClass">
4
+ <!--
5
+ @slot
6
+ @binding {string} value current value
7
+ -->
8
+ <slot v-bind="{ value }">{{ value }}</slot>
9
+ </div>
10
+ <input
11
+ v-if="isEditable"
12
+ :value="value"
13
+ :class="inputClass"
14
+ class="ui-editable-text-input input h-100"
15
+ type="text"
16
+ ref="input"
17
+ @change="onValueChange" />
18
+ </div>
19
+ </template>
20
+ <script>
21
+ import { domEvent } from './utils/Helpers';
22
+
23
+ const Size = {
24
+ SMALL: { name: 'small', labelClass: ['text-small'], inputClass: ['input-small'] },
25
+ NORMAL: { name: 'normal', labelClass: [], inputClass: [] },
26
+ LARGE: { name: 'large', labelClass: ['text-large'], inputClass: ['input-large'] },
27
+ };
28
+
29
+ export default {
30
+ props: {
31
+ /**
32
+ * @vmodel
33
+ * @example lorem ipsum sit dolor
34
+ */
35
+ value: {
36
+ type: String,
37
+ default: ''
38
+ },
39
+ /**
40
+ * @default normal
41
+ * @values small,normal,large
42
+ */
43
+ size: {
44
+ type: String,
45
+ default: Size.NORMAL.name,
46
+ validator: (val) =>
47
+ Object.values(Size)
48
+ .map(({ name }) => name)
49
+ .includes(val)
50
+ }
51
+ },
52
+ data: () => ({
53
+ isEditable: false,
54
+ onDocClickDisposable: null
55
+ }),
56
+ computed: {
57
+ labelClass() {
58
+ const { isEditable, size } = this;
59
+ const classes = [];
60
+ const sizeDef = Object.values(Size).find(({ name }) => name === size);
61
+
62
+ classes.push(...sizeDef.labelClass);
63
+
64
+ if (isEditable) {
65
+ classes.push('invisible');
66
+ }
67
+
68
+ return classes;
69
+ },
70
+ inputClass() {
71
+ const sizeDef = Object.values(Size).find(({ name }) => name === this.size);
72
+ return sizeDef.inputClass;
73
+ }
74
+ },
75
+ beforeDestroy() {
76
+ const { onDocClickDisposable } = this;
77
+ if (onDocClickDisposable != null) {
78
+ onDocClickDisposable();
79
+ }
80
+ },
81
+ methods: {
82
+ onRootClick() {
83
+ if (this.isEditable) {
84
+ return;
85
+ }
86
+ this.isEditable = true;
87
+ this.$nextTick(() => {
88
+ const { input } = this.$refs;
89
+ input.select();
90
+ setTimeout(() => {
91
+ this.onDocClickDisposable = domEvent(document, 'click', this.onDocClick);
92
+ });
93
+ });
94
+ },
95
+ onValueChange({ target }) {
96
+ const { value: valueNew } = target;
97
+ if (this.value !== valueNew) {
98
+ this.$emit('input', valueNew);
99
+ this.$emit('change', valueNew);
100
+ }
101
+ this.isEditable = false;
102
+ this.onDocClickDisposable();
103
+ },
104
+ onDocClick({ target }) {
105
+ if (this.$el.contains(target)) {
106
+ return;
107
+ }
108
+ this.isEditable = false;
109
+ this.onDocClickDisposable();
110
+ }
111
+ }
112
+ };
113
+ </script>
114
+ <style lang="less" scoped>
115
+ .ui-editable-text {
116
+ position: relative;
117
+ display: inline-flex;
118
+
119
+ &-label {
120
+ &:hover {
121
+ color: var(--color-primary);
122
+ }
123
+ }
124
+ &-input {
125
+ position: absolute;
126
+ top: 0;
127
+ left: -0.5rem;
128
+ width: calc(100% + 1rem);
129
+ border: none;
130
+ padding-top: 0;
131
+ padding-bottom: 0;
132
+ min-height: auto;
133
+ }
134
+ }
135
+ </style>
@@ -77,6 +77,18 @@ const generateGetBoundingClientRect = (x = 0, y = 0) => () => ({
77
77
  left: x,
78
78
  });
79
79
 
80
+ /**
81
+ * @param {EventTarget} target
82
+ * @param {string} type
83
+ * @param {EventListenerOrEventListenerObject} listener
84
+ * @param {AddEventListenerOptions} options
85
+ * @returns
86
+ */
87
+ const domEvent = (target, type, listener, options = undefined) => {
88
+ target.addEventListener(type, listener, options);
89
+ return () => target.removeEventListener(type, listener, options);
90
+ };
91
+
80
92
  export {
81
93
  scrollIntoView,
82
94
  isDateValid,
@@ -85,6 +97,7 @@ export {
85
97
  Position,
86
98
  TriggerOn,
87
99
  debounce,
100
+ domEvent,
88
101
  useIntersectionObserver,
89
102
  generateGetBoundingClientRect,
90
103
  };