@v1nt1248/3nclient-lib 0.3.29 → 0.3.31

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.
Files changed (190) hide show
  1. package/dist/chunks/{ui3n-notification-Dr_3Td9N.js → ui3n-notification-DPC5Ke4b.js} +96 -97
  2. package/dist/{components → src/components}/index.d.ts +3 -3
  3. package/dist/{components → src/components}/ui3n-autocomplete/types.d.ts +5 -0
  4. package/dist/{components → src/components}/ui3n-breadcrumbs/types.d.ts +2 -0
  5. package/dist/{components → src/components}/ui3n-dialog/types.d.ts +1 -1
  6. package/dist/{components → src/components}/ui3n-editable/types.d.ts +1 -1
  7. package/dist/{components → src/components}/ui3n-editable/ui3n-editable.d.ts +1 -1
  8. package/dist/{components → src/components}/ui3n-editable/useContentEditable.d.ts +1 -1
  9. package/dist/{components → src/components}/ui3n-input/types.d.ts +2 -2
  10. package/dist/{components → src/components}/ui3n-menu/types.d.ts +21 -1
  11. package/dist/{components → src/components}/ui3n-menu/ui3n-menu.d.ts +3 -0
  12. package/dist/{components → src/components}/ui3n-mobile-menu/ui3n-mobile-menu.d.ts +2 -2
  13. package/dist/{components → src/components}/ui3n-notification/types.d.ts +0 -4
  14. package/dist/src/components/ui3n-notification/ui3n-notification-container.d.ts +11 -0
  15. package/dist/{components → src/components}/ui3n-notification/ui3n-notification.d.ts +1 -1
  16. package/dist/{components → src/components}/ui3n-progress/ui3n-progress-circular.d.ts +3 -3
  17. package/dist/{components → src/components}/ui3n-progress/ui3n-progress-linear.d.ts +2 -0
  18. package/dist/{components → src/components}/ui3n-selector/types.d.ts +1 -11
  19. package/dist/{components → src/components}/ui3n-step-line-bar/ui3n-step-line-bar.d.ts +1 -0
  20. package/dist/{components → src/components}/ui3n-switch/ui3n-switch.d.ts +2 -6
  21. package/dist/{components → src/components}/ui3n-table/composables/useTable.d.ts +4 -3
  22. package/dist/{components → src/components}/ui3n-text/ui3n-text.d.ts +1 -0
  23. package/dist/{components → src/components}/ui3n-tooltip/ui3n-tooltip.d.ts +1 -0
  24. package/dist/{index.d.ts → src/index.d.ts} +1 -1
  25. package/dist/{plugins → src/plugins}/dialogs/dialogs.d.ts +2 -2
  26. package/dist/{plugins → src/plugins}/dialogs/store-dialog.d.ts +2 -2
  27. package/dist/{plugins → src/plugins}/dialogs/types.d.ts +1 -1
  28. package/dist/{plugins → src/plugins}/notifications/store-notifications.d.ts +1 -1
  29. package/dist/{plugins → src/plugins}/notifications/types.d.ts +1 -1
  30. package/dist/{ui3n-components.d.ts → src/ui3n-components.d.ts} +1 -1
  31. package/dist/{ui3n-plugins.d.ts → src/ui3n-plugins.d.ts} +5 -5
  32. package/dist/{utils → src/utils}/files/create-video-thumbnail.d.ts +1 -1
  33. package/dist/{utils → src/utils}/for-vue/try-on-scope-dispose.d.ts +1 -1
  34. package/dist/{utils → src/utils}/for-vue/unref-element.d.ts +1 -1
  35. package/dist/src/utils/processes/scheduler-yield.d.ts +1 -0
  36. package/dist/{utils → src/utils}/processes/task-runner.d.ts +1 -1
  37. package/dist/style.css +1 -1
  38. package/dist/ui3n-components.js +1196 -1137
  39. package/dist/ui3n-plugins.js +56 -43
  40. package/package.json +2 -2
  41. package/src/components/index.ts +9 -2
  42. package/src/components/ui3n-autocomplete/types.ts +5 -0
  43. package/src/components/ui3n-autocomplete/ui3n-autocomplete.vue +9 -5
  44. package/src/components/ui3n-breadcrumbs/types.ts +2 -0
  45. package/src/components/ui3n-breadcrumbs/ui3n-breadcrumb.vue +45 -35
  46. package/src/components/ui3n-breadcrumbs/ui3n-breadcrumbs.vue +12 -1
  47. package/src/components/ui3n-checkbox/ui3n-checkbox.vue +33 -67
  48. package/src/components/ui3n-editable/ui3n-editable.vue +68 -46
  49. package/src/components/ui3n-emoji/ui3n-emoji.vue +21 -27
  50. package/src/components/ui3n-icon/ui3n-icon.vue +13 -5
  51. package/src/components/ui3n-input/types.ts +2 -2
  52. package/src/components/ui3n-input/ui3n-input.vue +15 -9
  53. package/src/components/ui3n-menu/types.ts +24 -1
  54. package/src/components/ui3n-menu/ui3n-menu.vue +133 -11
  55. package/src/components/ui3n-mobile-menu/ui3n-mobile-menu.vue +87 -38
  56. package/src/components/ui3n-notification/types.ts +0 -4
  57. package/src/components/ui3n-notification/ui3n-notification-container.vue +62 -0
  58. package/src/components/ui3n-notification/ui3n-notification.vue +74 -70
  59. package/src/components/ui3n-progress/ui3n-progress-circular.vue +80 -120
  60. package/src/components/ui3n-progress/ui3n-progress-linear.vue +32 -15
  61. package/src/components/ui3n-radio-group/ui3n-radio-group.vue +2 -1
  62. package/src/components/ui3n-radio-group/ui3n-radio.vue +38 -47
  63. package/src/components/ui3n-scrollbar-horizontal/{ui3n-scroolbar-horizontal.vue → ui3n-scrollbar-horizontal.vue} +6 -8
  64. package/src/components/ui3n-scrollbar-vertical/ui3n-scrollbar-vertical.vue +10 -6
  65. package/src/components/ui3n-selector/types.ts +1 -10
  66. package/src/components/ui3n-selector/ui3n-selector.vue +49 -47
  67. package/src/components/ui3n-slider/ui3n-slider.vue +6 -9
  68. package/src/components/ui3n-step-line-bar/ui3n-step-line-bar.vue +5 -1
  69. package/src/components/ui3n-switch/ui3n-switch.vue +24 -19
  70. package/src/components/ui3n-table/composables/useTable.ts +37 -22
  71. package/src/components/ui3n-table/ui3n-table-sort-icon.vue +6 -1
  72. package/src/components/ui3n-table/ui3n-table.vue +3 -1
  73. package/src/components/ui3n-tabs/ui3n-tabs.vue +0 -23
  74. package/src/components/ui3n-text/ui3n-text.vue +36 -8
  75. package/src/components/ui3n-tooltip/ui3n-tooltip.vue +39 -18
  76. package/src/components/ui3n-virtual-scroll/ui3n-virtual-scroll.vue +2 -2
  77. package/dist/utils/processes/scheduler-yield.d.ts +0 -1
  78. /package/dist/{components → src/components}/ui3n-autocomplete/ui3n-autocomplete.d.ts +0 -0
  79. /package/dist/{components → src/components}/ui3n-badge/types.d.ts +0 -0
  80. /package/dist/{components → src/components}/ui3n-badge/ui3n-badge-simple.d.ts +0 -0
  81. /package/dist/{components → src/components}/ui3n-badge/ui3n-badge.d.ts +0 -0
  82. /package/dist/{components → src/components}/ui3n-breadcrumbs/ui3n-breadcrumb.d.ts +0 -0
  83. /package/dist/{components → src/components}/ui3n-breadcrumbs/ui3n-breadcrumbs.d.ts +0 -0
  84. /package/dist/{components → src/components}/ui3n-button/constants.d.ts +0 -0
  85. /package/dist/{components → src/components}/ui3n-button/types.d.ts +0 -0
  86. /package/dist/{components → src/components}/ui3n-button/ui3n-button.d.ts +0 -0
  87. /package/dist/{components → src/components}/ui3n-checkbox/types.d.ts +0 -0
  88. /package/dist/{components → src/components}/ui3n-checkbox/ui3n-checkbox.d.ts +0 -0
  89. /package/dist/{components → src/components}/ui3n-chip/types.d.ts +0 -0
  90. /package/dist/{components → src/components}/ui3n-chip/ui3n-chip.d.ts +0 -0
  91. /package/dist/{components → src/components}/ui3n-dialog/ui3n-dialog-provider.d.ts +0 -0
  92. /package/dist/{components → src/components}/ui3n-dialog/ui3n-dialog.d.ts +0 -0
  93. /package/dist/{components → src/components}/ui3n-dialog/util.d.ts +0 -0
  94. /package/dist/{components → src/components}/ui3n-drop-files/types.d.ts +0 -0
  95. /package/dist/{components → src/components}/ui3n-drop-files/ui3n-drop-files.d.ts +0 -0
  96. /package/dist/{components → src/components}/ui3n-emoji/types.d.ts +0 -0
  97. /package/dist/{components → src/components}/ui3n-emoji/ui3n-emoji.d.ts +0 -0
  98. /package/dist/{components → src/components}/ui3n-icon/types.d.ts +0 -0
  99. /package/dist/{components → src/components}/ui3n-icon/ui3n-icon.d.ts +0 -0
  100. /package/dist/{components → src/components}/ui3n-input/ui3n-input.d.ts +0 -0
  101. /package/dist/{components → src/components}/ui3n-input-file/types.d.ts +0 -0
  102. /package/dist/{components → src/components}/ui3n-input-file/ui3n-input-file.d.ts +0 -0
  103. /package/dist/{components → src/components}/ui3n-list/types.d.ts +0 -0
  104. /package/dist/{components → src/components}/ui3n-list/ui3n-list.d.ts +0 -0
  105. /package/dist/{components → src/components}/ui3n-mobile-menu/types.d.ts +0 -0
  106. /package/dist/{components → src/components}/ui3n-mobile-menu-item/types.d.ts +0 -0
  107. /package/dist/{components → src/components}/ui3n-mobile-menu-item/ui3n-mobile-menu-item.d.ts +0 -0
  108. /package/dist/{components → src/components}/ui3n-progress/types.d.ts +0 -0
  109. /package/dist/{components → src/components}/ui3n-radio-group/types.d.ts +0 -0
  110. /package/dist/{components → src/components}/ui3n-radio-group/ui3n-radio-group.d.ts +0 -0
  111. /package/dist/{components → src/components}/ui3n-radio-group/ui3n-radio.d.ts +0 -0
  112. /package/dist/{components → src/components}/ui3n-scrollbar-horizontal/types.d.ts +0 -0
  113. /package/dist/{components/ui3n-scrollbar-horizontal/ui3n-scroolbar-horizontal.d.ts → src/components/ui3n-scrollbar-horizontal/ui3n-scrollbar-horizontal.d.ts} +0 -0
  114. /package/dist/{components → src/components}/ui3n-scrollbar-vertical/types.d.ts +0 -0
  115. /package/dist/{components → src/components}/ui3n-scrollbar-vertical/ui3n-scrollbar-vertical.d.ts +0 -0
  116. /package/dist/{components → src/components}/ui3n-selector/ui3n-selector.d.ts +0 -0
  117. /package/dist/{components → src/components}/ui3n-slider/types.d.ts +0 -0
  118. /package/dist/{components → src/components}/ui3n-slider/ui3n-slider.d.ts +0 -0
  119. /package/dist/{components → src/components}/ui3n-step-line-bar/types.d.ts +0 -0
  120. /package/dist/{components → src/components}/ui3n-switch/types.d.ts +0 -0
  121. /package/dist/{components → src/components}/ui3n-table/types.d.ts +0 -0
  122. /package/dist/{components → src/components}/ui3n-table/ui3n-table-sort-icon.d.ts +0 -0
  123. /package/dist/{components → src/components}/ui3n-table/ui3n-table.d.ts +0 -0
  124. /package/dist/{components → src/components}/ui3n-tabs/types.d.ts +0 -0
  125. /package/dist/{components → src/components}/ui3n-tabs/ui3n-tabs.d.ts +0 -0
  126. /package/dist/{components → src/components}/ui3n-text/types.d.ts +0 -0
  127. /package/dist/{components → src/components}/ui3n-tooltip/types.d.ts +0 -0
  128. /package/dist/{components → src/components}/ui3n-virtual-scroll/types.d.ts +0 -0
  129. /package/dist/{components → src/components}/ui3n-virtual-scroll/ui3n-virtual-scroll.d.ts +0 -0
  130. /package/dist/{composables → src/composables}/index.d.ts +0 -0
  131. /package/dist/{composables → src/composables}/useDblClickHandler.d.ts +0 -0
  132. /package/dist/{constants → src/constants}/emoticons.d.ts +0 -0
  133. /package/dist/{constants → src/constants}/general.d.ts +0 -0
  134. /package/dist/{constants → src/constants}/index.d.ts +0 -0
  135. /package/dist/{constants → src/constants}/plugins-keys.d.ts +0 -0
  136. /package/dist/{demo → src/demo}/constants.d.ts +0 -0
  137. /package/dist/{directives → src/directives}/index.d.ts +0 -0
  138. /package/dist/{directives → src/directives}/ui3n-click-outside.d.ts +0 -0
  139. /package/dist/{directives → src/directives}/ui3n-html.d.ts +0 -0
  140. /package/dist/{directives → src/directives}/ui3n-long-press.d.ts +0 -0
  141. /package/dist/{directives → src/directives}/ui3n-resize.d.ts +0 -0
  142. /package/dist/{directives → src/directives}/ui3n-ripple.d.ts +0 -0
  143. /package/dist/{directives → src/directives}/ui3n-title.d.ts +0 -0
  144. /package/dist/{plugins → src/plugins}/index.d.ts +0 -0
  145. /package/dist/{plugins → src/plugins}/notifications/notifications.d.ts +0 -0
  146. /package/dist/{plugins → src/plugins}/vue-bus/store-vue-bus.d.ts +0 -0
  147. /package/dist/{plugins → src/plugins}/vue-bus/types.d.ts +0 -0
  148. /package/dist/{plugins → src/plugins}/vue-bus/vue-bus.d.ts +0 -0
  149. /package/dist/{types → src/types}/components.types.d.ts +0 -0
  150. /package/dist/{types → src/types}/directives.types.d.ts +0 -0
  151. /package/dist/{types → src/types}/index.d.ts +0 -0
  152. /package/dist/{types → src/types}/plugins.types.d.ts +0 -0
  153. /package/dist/{types → src/types}/utils.types.d.ts +0 -0
  154. /package/dist/{ui3n-utils.d.ts → src/ui3n-utils.d.ts} +0 -0
  155. /package/dist/{utils → src/utils}/copy-to-clipboard.d.ts +0 -0
  156. /package/dist/{utils → src/utils}/debounce.d.ts +0 -0
  157. /package/dist/{utils → src/utils}/execute-function.d.ts +0 -0
  158. /package/dist/{utils → src/utils}/files/b64-to-blob.d.ts +0 -0
  159. /package/dist/{utils → src/utils}/files/blob-from-data-url.d.ts +0 -0
  160. /package/dist/{utils → src/utils}/files/blob-to-b64.d.ts +0 -0
  161. /package/dist/{utils → src/utils}/files/file-to-uint8array.d.ts +0 -0
  162. /package/dist/{utils → src/utils}/files/format-file-size.d.ts +0 -0
  163. /package/dist/{utils → src/utils}/files/get-file-extension.d.ts +0 -0
  164. /package/dist/{utils → src/utils}/files/is-file-archive.d.ts +0 -0
  165. /package/dist/{utils → src/utils}/files/is-file-audio.d.ts +0 -0
  166. /package/dist/{utils → src/utils}/files/is-file-image.d.ts +0 -0
  167. /package/dist/{utils → src/utils}/files/is-file-video.d.ts +0 -0
  168. /package/dist/{utils → src/utils}/files/mime-types.d.ts +0 -0
  169. /package/dist/{utils → src/utils}/files/resize-image.d.ts +0 -0
  170. /package/dist/{utils → src/utils}/files/uint8-to-data-url.d.ts +0 -0
  171. /package/dist/{utils → src/utils}/for-web3n.d.ts +0 -0
  172. /package/dist/{utils → src/utils}/get-random-id.d.ts +0 -0
  173. /package/dist/{utils → src/utils}/index.d.ts +0 -0
  174. /package/dist/{utils → src/utils}/processes/deferred.d.ts +0 -0
  175. /package/dist/{utils → src/utils}/processes/named-procs.d.ts +0 -0
  176. /package/dist/{utils → src/utils}/processes/single.d.ts +0 -0
  177. /package/dist/{utils → src/utils}/processes/sleep.d.ts +0 -0
  178. /package/dist/{utils → src/utils}/remove-whitespace-in-string.d.ts +0 -0
  179. /package/dist/{utils → src/utils}/round.d.ts +0 -0
  180. /package/dist/{utils → src/utils}/sqlite-on-3nstorage/index.d.ts +0 -0
  181. /package/dist/{utils → src/utils}/sqlite-on-3nstorage/types.d.ts +0 -0
  182. /package/dist/{utils → src/utils}/textarea-max-rows.d.ts +0 -0
  183. /package/dist/{utils → src/utils}/ui/capitalize.d.ts +0 -0
  184. /package/dist/{utils → src/utils}/ui/generate-color.d.ts +0 -0
  185. /package/dist/{utils → src/utils}/ui/has-slot-content.d.ts +0 -0
  186. /package/dist/{utils → src/utils}/ui/html2text.d.ts +0 -0
  187. /package/dist/{utils → src/utils}/ui/invert-color.d.ts +0 -0
  188. /package/dist/{utils → src/utils}/ui/mark-search.d.ts +0 -0
  189. /package/dist/{utils → src/utils}/ui/prepare-date-as-string.d.ts +0 -0
  190. /package/dist/{utils → src/utils}/ui/selection.d.ts +0 -0
@@ -23,19 +23,17 @@
23
23
 
24
24
  const inEdit = ref(false);
25
25
 
26
- const cssMinWidth = computed(() => `${minWidth}px`);
27
-
28
- const cssMaxWidth = computed(() => {
29
- if (!props.maxWidth) {
30
- return '100%';
31
- }
32
-
33
- const maxWidthAsNumber = Number(props.maxWidth);
34
- if (Number.isNaN(maxWidthAsNumber)) {
35
- return props.maxWidth as string;
26
+ const inlineStyles = computed(() => {
27
+ let maxWidthStr = '100%';
28
+ if (props.maxWidth) {
29
+ const maxWidthAsNumber = Number(props.maxWidth);
30
+ maxWidthStr = Number.isNaN(maxWidthAsNumber) ? (props.maxWidth as string) : `${maxWidthAsNumber}px`;
36
31
  }
37
32
 
38
- return `${maxWidthAsNumber}px`;
33
+ return {
34
+ '--ui3n-editable-min-width': `${minWidth}px`,
35
+ '--ui3n-editable-max-width': maxWidthStr,
36
+ };
39
37
  });
40
38
 
41
39
  const isContentTruncated = computed(() => {
@@ -55,8 +53,12 @@
55
53
  });
56
54
 
57
55
  function setInputWidth() {
58
- hiddenEl.value!.textContent = value.value || props.placeholder || '...';
59
- const newWidth = Math.max(hiddenEl.value!.scrollWidth, minWidth);
56
+ if (!hiddenEl.value) {
57
+ return;
58
+ }
59
+
60
+ hiddenEl.value.textContent = value.value || props.placeholder || '';
61
+ const newWidth = Math.max(hiddenEl.value.scrollWidth + 48, minWidth);
60
62
  inputElWidth.value = `${newWidth}px`;
61
63
  }
62
64
 
@@ -78,8 +80,7 @@
78
80
  }
79
81
 
80
82
  function onInput(ev: Event) {
81
- // @ts-ignore
82
- value.value = ev.target!.value || '';
83
+ value.value = (ev.target as HTMLInputElement).value || '';
83
84
  setInputWidth();
84
85
  }
85
86
 
@@ -96,6 +97,7 @@
96
97
  initialValue.value = value.value;
97
98
  emits('update:modelValue', value.value);
98
99
  }
100
+
99
101
  emits('done');
100
102
  inEdit.value = false;
101
103
  }
@@ -109,6 +111,7 @@
109
111
  value.value = initialValue.value;
110
112
  emits('update:modelValue', value.value);
111
113
  }
114
+
112
115
  emits('cancel');
113
116
  inEdit.value = false;
114
117
  }
@@ -165,7 +168,13 @@
165
168
  <div
166
169
  :id="id"
167
170
  v-ui3n-click-outside="onClickOutside"
168
- :class="[$style.ui3nEditable, disabled && $style.ui3nEditableDisabled]"
171
+ :class="[
172
+ $style.ui3nEditable,
173
+ disabled && $style.ui3nEditableDisabled,
174
+ inEdit && $style.ui3nEditableInEdit,
175
+ inEdit && !isValid && $style.ui3nEditableInEditWarning,
176
+ ]"
177
+ :style="inlineStyles"
169
178
  @focusin="emits('focusin', $event)"
170
179
  >
171
180
  <input
@@ -183,7 +192,7 @@
183
192
 
184
193
  <input
185
194
  ref="inputEl"
186
- :class="[$style.input, inEdit && $style.inEdit, inEdit && !isValid && $style.inEditWarning]"
195
+ :class="$style.input"
187
196
  :style="{ width: inputElWidth }"
188
197
  :value="value"
189
198
  :placeholder="placeholder"
@@ -248,13 +257,14 @@
248
257
  @use '../../assets/styles/mixins' as mixins;
249
258
 
250
259
  .ui3nEditable {
251
- --ui3n-editable-min-width: v-bind(cssMinWidth);
252
- --ui3n-editable-max-width: v-bind(cssMaxWidth);
260
+ --ui3n-editable-min-width: 60px;
261
+ --ui3n-editable-max-width: 100%;
253
262
  --ui3n-editable-height: 24px;
254
263
  --ui3n-editable-font-size: 12px;
255
264
  --ui3n-editable-border-radius: 4px;
256
- --ui3n-editable-padding-base: 4px;
257
- --ui3n-editable-padding: 4px 44px 4px 4px;
265
+ //--ui3n-editable-padding-base: 4px;
266
+ //--ui3n-editable-padding: 0 4px;
267
+ //--ui3n-editable-padding: 4px 44px 4px 4px;
258
268
  --ui3n-editable-button-size: 16px;
259
269
 
260
270
  position: relative;
@@ -265,9 +275,22 @@
265
275
  border-radius: var(--ui3n-editable-border-radius);
266
276
  font-size: var(--ui3n-editable-font-size);
267
277
  font-weight: 400;
268
- line-height: 1.33;
278
+ line-height: var(--ui3n-editable-height);
269
279
  color: var(--color-text-table-primary-default);
270
280
  overflow: hidden;
281
+ border: 1px solid transparent;
282
+
283
+ &.ui3nEditableInEdit {
284
+ background-color: var(--color-bg-control-primary-default, #fff);
285
+
286
+ &:not(.ui3nEditableInEditWarning) {
287
+ border: 1px solid var(--color-border-table-accent-default);
288
+ }
289
+
290
+ &.ui3nEditableInEditWarning {
291
+ border: 1px solid var(--error-content-default);
292
+ }
293
+ }
271
294
  }
272
295
 
273
296
  .ui3nEditableDisabled {
@@ -277,15 +300,23 @@
277
300
 
278
301
  .content {
279
302
  position: relative;
303
+ box-sizing: border-box;
280
304
  height: var(--ui3n-editable-height);
281
305
  min-width: var(--ui3n-editable-min-width);
282
306
  max-width: var(--ui3n-editable-max-width);
283
- padding: var(--ui3n-editable-padding);
307
+ padding: 0 24px 0 4px;
284
308
  border-radius: var(--ui3n-editable-border-radius);
285
309
  display: flex;
286
310
  justify-content: flex-start;
287
311
  align-items: center;
288
312
  cursor: pointer;
313
+ border: 1px solid transparent;
314
+
315
+ span {
316
+ display: block;
317
+ max-width: 100%;
318
+ @include mixins.text-overflow-ellipsis();
319
+ }
289
320
 
290
321
  &.contentEmpty {
291
322
  color: var(--color-text-table-secondary-default);
@@ -298,43 +329,28 @@
298
329
  opacity: 1;
299
330
  }
300
331
  }
301
-
302
- span {
303
- display: block;
304
- max-width: 100%;
305
- @include mixins.text-overflow-ellipsis();
306
- }
307
332
  }
308
333
 
309
334
  .input {
310
335
  position: relative;
336
+ height: 100%;
337
+ box-sizing: border-box;
311
338
  min-width: var(--ui3n-editable-min-width);
312
- max-width: calc(100% - 52px);
313
- padding: var(--ui3n-editable-padding);
339
+ max-width: 100%;
340
+ padding: 0 44px 0 4px;
341
+ font-family: inherit;
314
342
  font-size: var(--ui3n-editable-font-size);
315
343
  font-weight: 400;
316
- line-height: 1.33;
344
+ line-height: var(--ui3n-editable-height);
317
345
  border-radius: var(--ui3n-editable-border-radius);
346
+ background-color: transparent;
347
+ border: none;
318
348
 
319
349
  &::placeholder {
320
350
  color: var(--color-text-table-secondary-default);
321
351
  }
322
352
 
323
- &.inEdit {
324
- padding-top: calc(var(--ui3n-editable-padding-base) - 1px);
325
- padding-bottom: calc(var(--ui3n-editable-padding-base) - 1px);
326
-
327
- &:not(.inEditWarning) {
328
- border: 1px solid var(--color-border-table-accent-default);
329
- }
330
-
331
- &.inEditWarning {
332
- border: 1px solid var(--error-content-default);
333
- }
334
- }
335
-
336
353
  &:focus-visible {
337
- border: none;
338
354
  outline: none;
339
355
  }
340
356
  }
@@ -342,6 +358,12 @@
342
358
  .hidden {
343
359
  position: absolute;
344
360
  visibility: hidden;
361
+ padding: 0;
362
+ font-family: inherit;
363
+ font-size: var(--ui3n-editable-font-size);
364
+ font-weight: 400;
365
+ line-height: var(--ui3n-editable-height);
366
+ white-space: pre;
345
367
  }
346
368
 
347
369
  .btn {
@@ -1,26 +1,32 @@
1
1
  <script lang="ts" setup>
2
- import { computed, onMounted, ref, watch } from 'vue';
2
+ import { computed, ref, watch } from 'vue';
3
3
  import { emoticons } from '@/constants/emoticons';
4
4
  import type { Ui3nEmojiEmits, Ui3nEmojiProps } from './types';
5
5
 
6
- const props = withDefaults(
7
- defineProps<Ui3nEmojiProps>(),
8
- {
9
- size: 16,
10
- readonly: false,
11
- },
12
- );
6
+ const props = withDefaults(defineProps<Ui3nEmojiProps>(), {
7
+ size: 16,
8
+ readonly: false,
9
+ });
13
10
  const emits = defineEmits<Ui3nEmojiEmits>();
14
11
 
15
12
  const emojiElement = ref<HTMLDivElement | null>(null);
16
13
  const emojiData = computed(() => emoticons[props.emoji]);
17
14
 
18
- onMounted(() => {
19
- if (emojiElement.value) {
20
- emojiElement.value.style.setProperty('--ui3n-emoji-size', `${props.size}px`);
21
- }
15
+ const inlineStyles = computed(() => {
16
+ const isNumeric = !isNaN(Number(props.size));
17
+ const sizeStr = isNumeric ? `${props.size}px` : String(props.size);
18
+
19
+ return {
20
+ '--ui3n-emoji-size': sizeStr,
21
+ 'line-height': sizeStr,
22
+ };
22
23
  });
23
24
 
25
+ function onClick(ev: Event) {
26
+ ev.stopPropagation();
27
+ emits('click', ev);
28
+ }
29
+
24
30
  watch(
25
31
  () => props.emoji,
26
32
  newValue => {
@@ -30,27 +36,14 @@
30
36
  },
31
37
  { immediate: true },
32
38
  );
33
-
34
- watch(
35
- () => props.size,
36
- (newValue, prevValue) => {
37
- if (emojiElement.value && newValue && newValue !== prevValue) {
38
- emojiElement.value.style.setProperty('--ui3n-emoji-size', `${newValue}px`);
39
- }
40
- },
41
- );
42
-
43
- const onClick = (ev: Event) => {
44
- ev.stopImmediatePropagation();
45
- emits('click', ev);
46
- };
47
39
  </script>
48
40
 
49
41
  <template>
50
42
  <div
51
43
  ref="emojiElement"
52
44
  :class="[$style.ui3nEmoji, readonly && $style.readonly]"
53
- v-on="readonly ? {} : { 'click': onClick }"
45
+ :style="inlineStyles"
46
+ v-on="readonly ? {} : { click: onClick }"
54
47
  >
55
48
  {{ emojiData && emojiData.value }}
56
49
  </div>
@@ -69,6 +62,7 @@
69
62
  justify-content: center;
70
63
  align-items: center;
71
64
  cursor: pointer;
65
+ user-select: none;
72
66
  }
73
67
 
74
68
  .readonly {
@@ -9,25 +9,32 @@
9
9
  });
10
10
  const emits = defineEmits<Ui3nIconEmits>();
11
11
 
12
- const widthVal = computed(() => props.size || props.width || 16);
13
- const heightVal = computed(() => props.size || props.height || 16);
12
+ const rawWidth = computed(() => props.size || props.width || 16);
13
+ const rawHeight = computed(() => props.size || props.height || 16);
14
14
 
15
15
  const iconStyle = computed(() => {
16
16
  const value: Record<string, string> = {
17
- '--ui3n-icon-width': `${widthVal.value}px`,
18
- '--ui3n-icon-height': `${heightVal.value}px`,
17
+ '--ui3n-icon-width': formatUnit(rawWidth.value),
18
+ '--ui3n-icon-height': formatUnit(rawHeight.value),
19
19
  '--ui3n-icon-color': props.color,
20
20
  };
21
+
21
22
  const transformData = [];
22
23
  props.horizontalFlip && transformData.push('rotateY(180deg)');
23
24
  props.verticalFlip && transformData.push('rotateX(180deg)');
24
25
  props.rotate && transformData.push(`rotate(${props.rotate}deg)`);
26
+
25
27
  if (transformData.length) {
26
28
  value.transform = transformData.join(' ');
27
29
  }
28
30
 
29
31
  return value;
30
32
  });
33
+
34
+ function formatUnit(val: string | number): string {
35
+ const isNumeric = !isNaN(Number(val));
36
+ return isNumeric ? `${val}px` : String(val);
37
+ }
31
38
  </script>
32
39
 
33
40
  <template>
@@ -43,7 +50,8 @@
43
50
 
44
51
  <style lang="scss" module>
45
52
  .ui3nIcon {
46
- display: block;
53
+ display: inline-block;
54
+ vertical-align: middle;
47
55
  min-width: var(--ui3n-icon-width);
48
56
  width: var(--ui3n-icon-width);
49
57
 
@@ -153,11 +153,11 @@ export interface Ui3nInputSlots {
153
153
  /**
154
154
  * Slot for prepend icon (displayed at the start of the input)
155
155
  */
156
- 'prepend-icon'?: () => VNode[];
156
+ 'prepend-icon'?: () => VNode;
157
157
  /**
158
158
  * Slot for append icon (displayed at the end of the input)
159
159
  */
160
- 'append-icon'?: () => VNode[];
160
+ 'append-icon'?: () => VNode;
161
161
  }
162
162
 
163
163
  export interface Ui3nInputExpose {
@@ -61,7 +61,7 @@
61
61
  return (event.target as HTMLInputElement).value;
62
62
  }
63
63
 
64
- function validate(value: string) {
64
+ function validate(value: string, forceEmit = false) {
65
65
  const errors: string[] = [];
66
66
  for (const rule of props.rules) {
67
67
  if (typeof rule !== 'function') {
@@ -77,7 +77,7 @@
77
77
  }
78
78
 
79
79
  errorMessage.value = errors.join('. ');
80
- if (isDirty.value || props.validateAtStartup) {
80
+ if (isDirty.value || props.validateAtStartup || forceEmit) {
81
81
  emits('update:valid', errors.length === 0);
82
82
  }
83
83
  }
@@ -152,12 +152,13 @@
152
152
 
153
153
  onMounted(() => {
154
154
  internalValue.value = props.modelValue ?? '';
155
+
155
156
  if (inputElement.value) {
156
- inputElement.value.value = internalValue.value;
157
+ emits('init', inputElement.value);
158
+
157
159
  if (props.autofocus) {
158
160
  inputElement.value.focus();
159
161
  }
160
- emits('init', inputElement.value);
161
162
  }
162
163
 
163
164
  if (props.validateAtStartup) {
@@ -172,11 +173,7 @@
172
173
  const normalized = val ?? '';
173
174
  if (normalized !== internalValue.value) {
174
175
  internalValue.value = normalized;
175
-
176
- if (inputElement.value) {
177
- inputElement.value.value = normalized;
178
- }
179
- validate(normalized);
176
+ validate(normalized, true);
180
177
  }
181
178
  },
182
179
  );
@@ -231,6 +228,7 @@
231
228
  :name="name"
232
229
  :maxlength="maxlength"
233
230
  :minlength="minlength"
231
+ :value="internalValue"
234
232
  :class="$style.ui3nInputField"
235
233
  @input="onInput"
236
234
  @keydown.enter="onEnterKeydown"
@@ -456,6 +454,14 @@
456
454
  .inputWrapper {
457
455
  outline: 1px solid var(--error-content-default);
458
456
  }
457
+
458
+ &:focus-within {
459
+ .inputWrapper {
460
+ background-color: var(--color-bg-control-secondary-focused);
461
+ outline: 1px solid var(--error-content-default);
462
+ box-shadow: 0 0 0 1px var(--error-content-default);
463
+ }
464
+ }
459
465
  }
460
466
 
461
467
  .success {
@@ -1,5 +1,21 @@
1
1
  import type { Ref, VNode } from 'vue';
2
2
 
3
+ export interface Ui3nVirtualElement {
4
+ getBoundingClientRect: () =>
5
+ | DOMRect
6
+ | {
7
+ x: number;
8
+ y: number;
9
+ top: number;
10
+ left: number;
11
+ right: number;
12
+ bottom: number;
13
+ width: number;
14
+ height: number;
15
+ };
16
+ contextElement?: HTMLElement;
17
+ }
18
+
3
19
  /**
4
20
  * Menu component properties
5
21
  */
@@ -15,7 +31,7 @@ export interface Ui3nMenuProps {
15
31
  /**
16
32
  * Trigger element
17
33
  */
18
- triggerElement?: HTMLElement;
34
+ triggerElement?: HTMLElement | Ui3nVirtualElement;
19
35
  /**
20
36
  * Position strategy
21
37
  * @default 'absolute'
@@ -31,6 +47,11 @@ export interface Ui3nMenuProps {
31
47
  * @default true
32
48
  */
33
49
  allowFlip?: boolean;
50
+ /**
51
+ * Whether to lock scroll when menu is open
52
+ * @default false
53
+ */
54
+ lockScroll?: boolean;
34
55
  /**
35
56
  * Offset X
36
57
  * @default 0
@@ -74,6 +95,8 @@ export interface Ui3nMenuProps {
74
95
  * Menu component emits
75
96
  */
76
97
  export interface Ui3nMenuEmits {
98
+ /** Called when the menu is clicked */
99
+ (ev: 'click', value: Event): void;
77
100
  /**
78
101
  * Emitted when menu opens
79
102
  */
@@ -1,11 +1,12 @@
1
1
  <script lang="ts" setup>
2
- import { computed, ref, watch, useTemplateRef } from 'vue';
2
+ import { computed, onUnmounted, ref, watch, useTemplateRef } from 'vue';
3
3
  import { autoUpdate, flip, useFloating, offset, shift } from '@floating-ui/vue';
4
4
  import { default as vClickOutside } from '../../directives/ui3n-click-outside';
5
5
  import { Nullable } from '@/types';
6
- import type { Ui3nMenuEmits, Ui3nMenuProps, Ui3nMenuSlots, Ui3nMenuExpose } from './types';
6
+ import type { Ui3nMenuEmits, Ui3nMenuProps, Ui3nMenuSlots, Ui3nMenuExpose, Ui3nVirtualElement } from './types';
7
7
 
8
8
  const props = withDefaults(defineProps<Ui3nMenuProps>(), {
9
+ lockScroll: false,
9
10
  positionStrategy: 'absolute',
10
11
  offsetX: 0,
11
12
  offsetY: 0,
@@ -23,10 +24,27 @@
23
24
  const menuContentElement = useTemplateRef<HTMLDivElement>('menu-content-element');
24
25
  const isShow = ref(false);
25
26
 
26
- const outerTriggerElement = ref<Nullable<HTMLElement>>(props.triggerElement || null);
27
+ const outerTriggerElement = ref<Nullable<HTMLElement | Ui3nVirtualElement>>(props.triggerElement || null);
27
28
 
28
29
  const usedTriggerElement = computed(() => outerTriggerElement.value || menuTriggerElement.value);
29
30
 
31
+ const nativeHtmlTriggerElement = computed<HTMLElement | null>(() => {
32
+ const trigger = usedTriggerElement.value;
33
+ if (!trigger) {
34
+ return null;
35
+ }
36
+
37
+ if (trigger instanceof HTMLElement) {
38
+ return trigger;
39
+ }
40
+
41
+ if ('contextElement' in trigger && trigger.contextElement instanceof HTMLElement) {
42
+ return trigger.contextElement;
43
+ }
44
+
45
+ return null;
46
+ });
47
+
30
48
  const middleware = computed(() => {
31
49
  const list = [
32
50
  offset({
@@ -72,6 +90,96 @@
72
90
  };
73
91
  });
74
92
 
93
+ function preventScrollEvent(e: Event) {
94
+ e.preventDefault();
95
+ }
96
+
97
+ function getVerticalScrollParent(element: HTMLElement | null): HTMLElement {
98
+ if (!element) {
99
+ return document.body;
100
+ }
101
+
102
+ let parent: HTMLElement | null = element.parentElement;
103
+
104
+ while (parent && parent !== document.body && parent !== document.documentElement) {
105
+ const style = window.getComputedStyle(parent);
106
+
107
+ if (/(auto|scroll)/.test(style.overflowY || style.overflow)) {
108
+ if (parent.scrollHeight > parent.clientHeight) {
109
+ return parent;
110
+ }
111
+ }
112
+ parent = parent.parentElement;
113
+ }
114
+
115
+ return document.body;
116
+ }
117
+
118
+ function lockScroll() {
119
+ if (!props.lockScroll) {
120
+ return;
121
+ }
122
+
123
+ const scrollParent = getVerticalScrollParent(nativeHtmlTriggerElement.value);
124
+
125
+ if (scrollParent) {
126
+ const currentLocks = Number(scrollParent.dataset.scrollLocksCount || '0');
127
+
128
+ if (currentLocks === 0) {
129
+ scrollParent.dataset.scrollLocksCount = '1';
130
+ scrollParent.dataset.originalOverscroll = scrollParent.style.overscrollBehaviorY || '';
131
+ scrollParent.style.overscrollBehaviorY = 'contain';
132
+
133
+ if (scrollParent === document.body) {
134
+ document.addEventListener('wheel', preventScrollEvent, { passive: false });
135
+ document.addEventListener('touchmove', preventScrollEvent, { passive: false });
136
+ } else {
137
+ scrollParent.addEventListener('wheel', preventScrollEvent, { passive: false });
138
+ scrollParent.addEventListener('touchmove', preventScrollEvent, { passive: false });
139
+ }
140
+ } else {
141
+ scrollParent.dataset.scrollLocksCount = String(currentLocks + 1);
142
+ }
143
+ }
144
+ }
145
+
146
+ function unlockScroll() {
147
+ const scrollParent = getVerticalScrollParent(nativeHtmlTriggerElement.value);
148
+
149
+ if (!scrollParent) {
150
+ return;
151
+ }
152
+
153
+ const currentLocks = Number(scrollParent.dataset.scrollLocksCount || '0');
154
+
155
+ if (currentLocks > 0) {
156
+ const newLocks = currentLocks - 1;
157
+
158
+ if (newLocks === 0) {
159
+ const originalOverscroll = scrollParent.dataset.originalOverscroll;
160
+
161
+ if (originalOverscroll) {
162
+ scrollParent.style.overscrollBehaviorY = originalOverscroll;
163
+ } else {
164
+ scrollParent.style.removeProperty('overscroll-behavior-y');
165
+ }
166
+
167
+ if (scrollParent === document.body) {
168
+ document.removeEventListener('wheel', preventScrollEvent);
169
+ document.removeEventListener('touchmove', preventScrollEvent);
170
+ } else {
171
+ scrollParent.removeEventListener('wheel', preventScrollEvent);
172
+ scrollParent.removeEventListener('touchmove', preventScrollEvent);
173
+ }
174
+
175
+ delete scrollParent.dataset.scrollLocksCount;
176
+ delete scrollParent.dataset.originalOverscroll;
177
+ } else {
178
+ scrollParent.dataset.scrollLocksCount = String(newLocks);
179
+ }
180
+ }
181
+ }
182
+
75
183
  function toggleMenu() {
76
184
  if (props.disabled) {
77
185
  return;
@@ -89,7 +197,7 @@
89
197
  }
90
198
 
91
199
  function onClickOutside(event: MouseEvent) {
92
- if (usedTriggerElement.value?.contains(event.target as Node)) {
200
+ if (nativeHtmlTriggerElement.value?.contains(event.target as Node)) {
93
201
  return;
94
202
  }
95
203
 
@@ -101,15 +209,23 @@
101
209
  }
102
210
  }
103
211
 
104
- watch(isPositioned, val => {
105
- val ? emits('opened') : emits('closed');
106
- });
212
+ watch(
213
+ () => isShow.value,
214
+ val => {
215
+ if (val) {
216
+ lockScroll();
217
+ } else {
218
+ unlockScroll();
219
+ }
220
+ },
221
+ );
107
222
 
108
223
  watch(
109
224
  () => props.modelValue,
110
225
  val => {
111
- if (isShow.value !== val) {
226
+ if (val !== undefined && isShow.value !== val) {
112
227
  isShow.value = val;
228
+ val ? emits('open') : emits('close');
113
229
  }
114
230
  },
115
231
  { immediate: true },
@@ -131,6 +247,10 @@
131
247
  }
132
248
  });
133
249
 
250
+ onUnmounted(() => {
251
+ unlockScroll();
252
+ });
253
+
134
254
  defineExpose<Ui3nMenuExpose>({
135
255
  isPositioned,
136
256
  update,
@@ -142,6 +262,7 @@
142
262
  ref="menu-element"
143
263
  :id="id"
144
264
  :class="$style.ui3nMenu"
265
+ @click="emits('click', $event)"
145
266
  >
146
267
  <div
147
268
  ref="menu-trigger-element"
@@ -171,13 +292,14 @@
171
292
  --ui3n-menu-content-bg: var(--color-bg-control-secondary-default);
172
293
 
173
294
  position: relative;
174
- max-width: max-content;
295
+ width: max-content;
296
+ display: inline-block;
175
297
  overflow: visible;
176
298
  }
177
299
 
178
300
  .ui3nMenuTrigger {
179
301
  position: relative;
180
- max-width: max-content;
302
+ width: 100%;
181
303
 
182
304
  &.ui3nMenuTriggerDisabled {
183
305
  pointer-events: none;
@@ -187,7 +309,7 @@
187
309
 
188
310
  .ui3nMenuContent {
189
311
  position: absolute;
190
- border-radius: var(--ui3n-menu-content-border-raduis);
312
+ border-radius: var(--ui3n-menu-content-border-radius);
191
313
  background-color: var(--ui3n-menu-content-bg);
192
314
  z-index: var(--ui3n-menu-zIndex, 1000);
193
315
  overflow: hidden;