@v1nt1248/3nclient-lib 0.3.28 → 0.3.30

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 (111) hide show
  1. package/dist/chunks/ui3n-notification-Dr_3Td9N.js +279 -0
  2. package/dist/components/index.d.ts +12 -12
  3. package/dist/components/ui3n-autocomplete/types.d.ts +13 -0
  4. package/dist/components/ui3n-autocomplete/ui3n-autocomplete.d.ts +2 -2
  5. package/dist/components/ui3n-badge/types.d.ts +12 -0
  6. package/dist/components/ui3n-badge/ui3n-badge-simple.d.ts +1 -1
  7. package/dist/components/ui3n-badge/ui3n-badge.d.ts +1 -1
  8. package/dist/components/ui3n-breadcrumbs/types.d.ts +1 -1
  9. package/dist/components/ui3n-breadcrumbs/ui3n-breadcrumb.d.ts +2 -2
  10. package/dist/components/ui3n-button/types.d.ts +4 -2
  11. package/dist/components/ui3n-checkbox/types.d.ts +11 -0
  12. package/dist/components/ui3n-checkbox/ui3n-checkbox.d.ts +4 -1
  13. package/dist/components/ui3n-chip/types.d.ts +6 -1
  14. package/dist/components/ui3n-chip/ui3n-chip.d.ts +2 -0
  15. package/dist/components/ui3n-drop-files/types.d.ts +7 -0
  16. package/dist/components/ui3n-drop-files/ui3n-drop-files.d.ts +7 -1
  17. package/dist/components/ui3n-editable/types.d.ts +11 -0
  18. package/dist/components/ui3n-editable/ui3n-editable.d.ts +4 -2
  19. package/dist/components/ui3n-icon/types.d.ts +5 -1
  20. package/dist/components/ui3n-icon/ui3n-icon.d.ts +2 -2
  21. package/dist/components/ui3n-input/types.d.ts +4 -0
  22. package/dist/components/ui3n-input/ui3n-input.d.ts +4 -1
  23. package/dist/components/ui3n-input-file/types.d.ts +11 -0
  24. package/dist/components/ui3n-input-file/ui3n-input-file.d.ts +4 -1
  25. package/dist/components/ui3n-list/types.d.ts +4 -0
  26. package/dist/components/ui3n-menu/types.d.ts +9 -0
  27. package/dist/components/ui3n-menu/ui3n-menu.d.ts +2 -1
  28. package/dist/components/ui3n-notification/ui3n-notification.d.ts +2 -2
  29. package/dist/components/ui3n-progress/ui3n-progress-circular.d.ts +1 -1
  30. package/dist/components/ui3n-progress/ui3n-progress-linear.d.ts +1 -1
  31. package/dist/components/ui3n-radio-group/types.d.ts +18 -0
  32. package/dist/components/ui3n-radio-group/ui3n-radio-group.d.ts +3 -1
  33. package/dist/components/ui3n-radio-group/ui3n-radio.d.ts +6 -7
  34. package/dist/components/ui3n-scrollbar-vertical/types.d.ts +2 -0
  35. package/dist/components/ui3n-scrollbar-vertical/ui3n-scrollbar-vertical.d.ts +2 -0
  36. package/dist/components/ui3n-selector/types.d.ts +11 -0
  37. package/dist/components/ui3n-selector/ui3n-selector.d.ts +2 -2
  38. package/dist/components/ui3n-slider/types.d.ts +11 -0
  39. package/dist/components/ui3n-slider/ui3n-slider.d.ts +4 -1
  40. package/dist/components/ui3n-step-line-bar/types.d.ts +4 -0
  41. package/dist/components/ui3n-switch/types.d.ts +11 -0
  42. package/dist/components/ui3n-switch/ui3n-switch.d.ts +4 -1
  43. package/dist/components/ui3n-table/composables/useTable.d.ts +1 -0
  44. package/dist/components/ui3n-table/types.d.ts +4 -0
  45. package/dist/components/ui3n-table/ui3n-table-sort-icon.d.ts +4 -1
  46. package/dist/components/ui3n-tabs/types.d.ts +4 -0
  47. package/dist/components/ui3n-text/types.d.ts +11 -0
  48. package/dist/components/ui3n-text/ui3n-text.d.ts +4 -1
  49. package/dist/components/ui3n-tooltip/types.d.ts +4 -0
  50. package/dist/components/ui3n-tooltip/ui3n-tooltip.d.ts +4 -2
  51. package/dist/style.css +1 -1
  52. package/dist/ui3n-components.js +2121 -1696
  53. package/dist/ui3n-plugins.js +1 -1
  54. package/package.json +1 -1
  55. package/src/components/index.ts +29 -7
  56. package/src/components/ui3n-autocomplete/types.ts +14 -1
  57. package/src/components/ui3n-autocomplete/ui3n-autocomplete.vue +189 -55
  58. package/src/components/ui3n-badge/types.ts +10 -0
  59. package/src/components/ui3n-badge/ui3n-badge-simple.vue +54 -55
  60. package/src/components/ui3n-badge/ui3n-badge.vue +4 -0
  61. package/src/components/ui3n-breadcrumbs/types.ts +1 -1
  62. package/src/components/ui3n-breadcrumbs/ui3n-breadcrumb.vue +7 -5
  63. package/src/components/ui3n-button/types.ts +4 -2
  64. package/src/components/ui3n-button/ui3n-button.vue +24 -19
  65. package/src/components/ui3n-checkbox/types.ts +12 -0
  66. package/src/components/ui3n-checkbox/ui3n-checkbox.vue +79 -29
  67. package/src/components/ui3n-chip/types.ts +6 -1
  68. package/src/components/ui3n-chip/ui3n-chip.vue +64 -61
  69. package/src/components/ui3n-dialog/ui3n-dialog.vue +3 -3
  70. package/src/components/ui3n-drop-files/types.ts +8 -0
  71. package/src/components/ui3n-drop-files/ui3n-drop-files.vue +73 -29
  72. package/src/components/ui3n-editable/types.ts +12 -0
  73. package/src/components/ui3n-editable/ui3n-editable.vue +56 -24
  74. package/src/components/ui3n-icon/types.ts +5 -1
  75. package/src/components/ui3n-icon/ui3n-icon.vue +45 -50
  76. package/src/components/ui3n-input/types.ts +4 -0
  77. package/src/components/ui3n-input/ui3n-input.vue +14 -1
  78. package/src/components/ui3n-input-file/types.ts +12 -0
  79. package/src/components/ui3n-input-file/ui3n-input-file.vue +33 -16
  80. package/src/components/ui3n-list/types.ts +4 -0
  81. package/src/components/ui3n-list/ui3n-list.vue +3 -1
  82. package/src/components/ui3n-menu/types.ts +9 -0
  83. package/src/components/ui3n-menu/ui3n-menu.vue +169 -39
  84. package/src/components/ui3n-notification/ui3n-notification.vue +190 -175
  85. package/src/components/ui3n-progress/ui3n-progress-circular.vue +40 -22
  86. package/src/components/ui3n-progress/ui3n-progress-linear.vue +14 -7
  87. package/src/components/ui3n-radio-group/types.ts +20 -0
  88. package/src/components/ui3n-radio-group/ui3n-radio-group.vue +61 -48
  89. package/src/components/ui3n-radio-group/ui3n-radio.vue +60 -65
  90. package/src/components/ui3n-scrollbar-vertical/types.ts +2 -0
  91. package/src/components/ui3n-scrollbar-vertical/ui3n-scrollbar-vertical.vue +4 -4
  92. package/src/components/ui3n-selector/types.ts +12 -0
  93. package/src/components/ui3n-selector/ui3n-selector.vue +63 -40
  94. package/src/components/ui3n-slider/types.ts +12 -0
  95. package/src/components/ui3n-slider/ui3n-slider.vue +88 -39
  96. package/src/components/ui3n-step-line-bar/types.ts +4 -0
  97. package/src/components/ui3n-step-line-bar/ui3n-step-line-bar.vue +8 -10
  98. package/src/components/ui3n-switch/types.ts +12 -0
  99. package/src/components/ui3n-switch/ui3n-switch.vue +57 -25
  100. package/src/components/ui3n-table/composables/useTable.ts +17 -0
  101. package/src/components/ui3n-table/types.ts +4 -0
  102. package/src/components/ui3n-table/ui3n-table-sort-icon.vue +9 -8
  103. package/src/components/ui3n-table/ui3n-table.vue +48 -17
  104. package/src/components/ui3n-tabs/types.ts +4 -0
  105. package/src/components/ui3n-tabs/ui3n-tabs.vue +146 -108
  106. package/src/components/ui3n-text/types.ts +12 -0
  107. package/src/components/ui3n-text/ui3n-text.vue +56 -15
  108. package/src/components/ui3n-tooltip/types.ts +4 -0
  109. package/src/components/ui3n-tooltip/ui3n-tooltip.vue +61 -43
  110. package/src/components/ui3n-virtual-scroll/ui3n-virtual-scroll.vue +201 -17
  111. package/dist/chunks/ui3n-notification-DlDM-u-R.js +0 -276
@@ -1,65 +1,78 @@
1
1
  <script setup lang="ts">
2
- import { provide, ref, watch } from 'vue';
3
- import type {
4
- Ui3nRadioGroupProps,
5
- Ui3nRadioGroupEmits,
6
- Ui3nRadioGroupSlots,
7
- Ui3nRadioValue,
8
- } from './types';
2
+ import { computed, provide, ref, watch } from 'vue';
3
+ import type {
4
+ Ui3nRadioGroupProps,
5
+ Ui3nRadioGroupEmits,
6
+ Ui3nRadioGroupSlots,
7
+ Ui3nRadioGroupExpose,
8
+ Ui3nRadioValue,
9
+ } from './types';
9
10
 
10
- const props = withDefaults(defineProps<Ui3nRadioGroupProps>(), {
11
- direction: 'vertical',
12
- disabled: false,
13
- });
14
- const emits = defineEmits<Ui3nRadioGroupEmits>();
15
- defineSlots<Ui3nRadioGroupSlots>();
11
+ const props = withDefaults(defineProps<Ui3nRadioGroupProps>(), {
12
+ direction: 'vertical',
13
+ disabled: false,
14
+ });
15
+ const emits = defineEmits<Ui3nRadioGroupEmits>();
16
+ defineSlots<Ui3nRadioGroupSlots>();
16
17
 
17
- const groupValue = ref<Ui3nRadioValue>(props.modelValue);
18
+ const groupValue = ref<Ui3nRadioValue>(props.modelValue);
18
19
 
19
- function updateGroupValue(value: Ui3nRadioValue): void {
20
- groupValue.value = value;
21
- emits('update:modelValue', value);
22
- emits('change', value);
23
- }
20
+ function updateGroupValue(value: Ui3nRadioValue): void {
21
+ groupValue.value = value;
22
+ emits('update:modelValue', value);
23
+ emits('change', value);
24
+ }
24
25
 
25
- provide(`radio-group-${props.name}`, {
26
- groupValue,
27
- updateGroupValue,
28
- });
26
+ provide(`radio-group-${props.name}`, {
27
+ groupValue: computed(() => groupValue.value),
28
+ updateGroupValue,
29
+ });
29
30
 
30
- watch(
31
- () => props.modelValue,
32
- (val: Ui3nRadioValue) => {
33
- if (val !== groupValue.value) {
34
- groupValue.value = val;
35
- }
36
- },
37
- );
31
+ function clear() {
32
+ updateGroupValue('' as unknown as Ui3nRadioValue);
33
+ }
34
+
35
+ defineExpose<Ui3nRadioGroupExpose>({
36
+ clear,
37
+ });
38
+
39
+ watch(
40
+ () => props.modelValue,
41
+ (val: Ui3nRadioValue) => {
42
+ if (val !== groupValue.value) {
43
+ groupValue.value = val;
44
+ }
45
+ },
46
+ );
47
+
48
+ watch(
49
+ () => props.name,
50
+ newName => {
51
+ if (!newName) {
52
+ clear();
53
+ }
54
+ },
55
+ );
38
56
  </script>
39
57
 
40
58
  <template>
41
- <div
42
- :class="[
43
- $style.ui3nRadioGroup,
44
- direction === 'horizontal' && $style.horizontal,
45
- ]"
46
- >
59
+ <div :class="[$style.ui3nRadioGroup, direction === 'horizontal' && $style.horizontal]">
47
60
  <slot />
48
61
  </div>
49
62
  </template>
50
63
 
51
64
  <style lang="scss" module>
52
- .ui3nRadioGroup {
53
- position: relative;
54
- display: flex;
55
- flex-direction: column;
56
- justify-content: flex-start;
57
- align-items: flex-start;
58
- gap: var(--spacing-xs);
65
+ .ui3nRadioGroup {
66
+ position: relative;
67
+ display: flex;
68
+ flex-direction: column;
69
+ justify-content: flex-start;
70
+ align-items: flex-start;
71
+ gap: 4px;
59
72
 
60
- &.horizontal {
61
- flex-direction: row;
62
- column-gap: var(--spacing-s);
73
+ &.horizontal {
74
+ flex-direction: row;
75
+ column-gap: 8px;
76
+ }
63
77
  }
64
- }
65
78
  </style>
@@ -1,10 +1,10 @@
1
1
  <script lang="ts" setup>
2
- import { computed, getCurrentInstance, inject, onBeforeMount, onMounted, ref, useSlots, watch } from 'vue';
3
- import type { Ref } from 'vue';
4
- import type { Nullable } from '../../types';
5
- import type { Ui3nRadioEmits, Ui3nRadioProps, Ui3nRadioSlots, Ui3nRadioValue } from './types';
2
+ import { computed, getCurrentInstance, inject, onBeforeMount, ref, useSlots, watch } from 'vue';
3
+ import type { ComputedRef } from 'vue';
4
+ import type { Ui3nRadioEmits, Ui3nRadioProps, Ui3nRadioSlots, Ui3nRadioValue, Ui3nRadioExpose } from './types';
6
5
 
7
6
  const props = withDefaults(defineProps<Ui3nRadioProps>(), {
7
+ name: undefined,
8
8
  modelValue: false,
9
9
  checkedValue: true,
10
10
  uncheckedValue: false,
@@ -20,27 +20,30 @@
20
20
  const instance = getCurrentInstance();
21
21
  const isComponentPartOfGroup =
22
22
  instance?.parent?.type.__name === 'Ui3nRadioGroup' || instance?.parent?.type.__name === 'ui3n-radio-group';
23
- const groupName = isComponentPartOfGroup ? instance?.parent?.props.name : '';
24
-
25
- const radioEl = ref<HTMLDivElement | null>(null);
23
+ const groupName = (isComponentPartOfGroup ? instance?.parent?.props.name : '') as string;
26
24
 
27
25
  const {
28
26
  groupValue,
29
27
  updateGroupValue,
30
28
  }: {
31
- groupValue: Nullable<Ref<Ui3nRadioValue>>;
32
- updateGroupValue: Nullable<(value: Ui3nRadioValue) => void>;
29
+ groupValue: ComputedRef<Ui3nRadioValue> | null;
30
+ updateGroupValue: ((value: Ui3nRadioValue) => void) | null;
33
31
  } = groupName
34
32
  ? inject(`radio-group-${groupName}`)!
35
33
  : {
36
- groupValue: null,
37
- updateGroupValue: null,
38
- };
34
+ groupValue: null,
35
+ updateGroupValue: null,
36
+ };
39
37
 
40
38
  const val = ref<Ui3nRadioValue>(groupName ? groupValue!.value : props.modelValue);
41
39
 
42
40
  const isOn = computed(() => val.value === props.checkedValue);
43
41
 
42
+ const radioStyle = computed(() => ({
43
+ '--ui3n-radio-size': `${props.size}px`,
44
+ '--ui3n-radio-color': props.color,
45
+ }));
46
+
44
47
  function change(ev: Event) {
45
48
  ev.preventDefault();
46
49
 
@@ -57,15 +60,29 @@
57
60
 
58
61
  val.value = props.checkedValue;
59
62
  updateGroupValue!(val.value);
63
+ }
60
64
 
61
- // if (groupName) {
62
- // isOn.value && updateGroupValue!(val.value);
63
- // } else {
64
- // emits('change', val.value);
65
- // emits('update:modelValue', val.value);
66
- // }
65
+ function clear() {
66
+ val.value = props.uncheckedValue;
67
+ if (!groupName) {
68
+ emits('change', val.value);
69
+ emits('update:modelValue', val.value);
70
+ }
67
71
  }
68
72
 
73
+ defineExpose<Ui3nRadioExpose>({
74
+ clear,
75
+ });
76
+
77
+ watch(
78
+ () => props.name,
79
+ newName => {
80
+ if (!newName && !groupName) {
81
+ clear();
82
+ }
83
+ },
84
+ );
85
+
69
86
  onBeforeMount(() => {
70
87
  if (
71
88
  // @ts-ignore
@@ -73,14 +90,7 @@
73
90
  // @ts-ignore
74
91
  (!slots.checkedIcon && slots.uncheckedIcon)
75
92
  ) {
76
- throw Error('[Ui3nRadio] Both checkedIcon and uncheckedIcon slots must have values ​​defined.');
77
- }
78
- });
79
-
80
- onMounted(() => {
81
- if (radioEl.value) {
82
- radioEl.value.style.setProperty('--ui3n-radio-size', `${props.size}px`);
83
- radioEl.value.style.setProperty('--ui3n-radio-color', props.color);
93
+ throw Error('[Ui3nRadio] Both checkedIcon and uncheckedIcon slots must have values defined.');
84
94
  }
85
95
  });
86
96
 
@@ -93,24 +103,6 @@
93
103
  },
94
104
  );
95
105
 
96
- watch(
97
- () => props.size,
98
- newValue => {
99
- if (radioEl.value) {
100
- radioEl.value.style.setProperty('--ui3n-radio-size', `${newValue}px`);
101
- }
102
- },
103
- );
104
-
105
- watch(
106
- () => props.color,
107
- newValue => {
108
- if (radioEl.value) {
109
- radioEl.value.style.setProperty('--ui3n-radio-color', newValue);
110
- }
111
- },
112
- );
113
-
114
106
  watch(
115
107
  () => groupValue?.value,
116
108
  newVal => {
@@ -124,9 +116,18 @@
124
116
  <template>
125
117
  <!-- eslint-disable max-len -->
126
118
  <div
127
- ref="radioEl"
119
+ :style="radioStyle"
128
120
  :class="[$style.ui3nRadio, disabled && $style.disabled, !slots.default && $style.noLabel]"
129
121
  >
122
+ <input
123
+ type="radio"
124
+ hidden
125
+ :name="groupName || name"
126
+ :checked="isOn"
127
+ :value="String(checkedValue)"
128
+ :disabled="disabled"
129
+ />
130
+
130
131
  <div
131
132
  :class="[$style.body, disabled && $style.bodyDisabled]"
132
133
  :tabindex="disabled ? -1 : 0"
@@ -139,7 +140,6 @@
139
140
  name="checkedIcon"
140
141
  >
141
142
  <svg
142
- xmlns="http://www.w3.org/2000/svg"
143
143
  :width="Number(size) - 4"
144
144
  :height="Number(size) - 4"
145
145
  viewBox="0 0 24 24"
@@ -157,7 +157,6 @@
157
157
  name="uncheckedIcon"
158
158
  >
159
159
  <svg
160
- xmlns="http://www.w3.org/2000/svg"
161
160
  :width="Number(size) - 4"
162
161
  :height="Number(size) - 4"
163
162
  viewBox="0 0 24 24"
@@ -181,18 +180,14 @@
181
180
  @use '../../assets/styles/mixins' as mixins;
182
181
 
183
182
  .ui3nRadio {
184
- --ui3n-radio-size: 16px;
185
- --ui3n-radio-color: var(--color-icon-control-accent-default);
186
- --ui3n-radio-text-size: 12px;
187
- --ui3n-radio-text-color: var(--color-text-control-primary-default);
188
- --ui3n-radio-text-weight: 500;
183
+ --ui3n-radio-min-height: 24px;
189
184
 
190
185
  position: relative;
191
186
  display: flex;
192
187
  justify-content: flex-start;
193
188
  align-items: center;
194
- min-height: var(--spacing-vl);
195
- gap: var(--spacing-s);
189
+ min-height: var(--ui3n-radio-min-height);
190
+ gap: 8px;
196
191
 
197
192
  &.disabled {
198
193
  --ui3n-radio-color: var(--color-icon-control-primary-disabled) !important;
@@ -213,10 +208,10 @@
213
208
  .body {
214
209
  position: relative;
215
210
  display: flex;
216
- width: var(--ui3n-radio-size);
217
- min-width: var(--ui3n-radio-size);
218
- height: var(--ui3n-radio-size);
219
- min-height: var(--ui3n-radio-size);
211
+ width: var(--ui3n-radio-size, 16px);
212
+ min-width: var(--ui3n-radio-size, 16px);
213
+ height: var(--ui3n-radio-size, 16px);
214
+ min-height: var(--ui3n-radio-size, 16px);
220
215
  justify-content: center;
221
216
  align-items: center;
222
217
  border-radius: 50%;
@@ -229,18 +224,18 @@
229
224
  }
230
225
 
231
226
  .label {
232
- font-size: var(--ui3n-radio-text-size);
233
- font-weight: var(--ui3n-radio-text-weight);
234
- color: var(--ui3n-radio-text-color);
227
+ font-size: 12px;
228
+ font-weight: 500;
229
+ color: var(--color-text-control-primary-default);
235
230
  user-select: none;
236
231
  }
237
232
 
238
233
  .icon {
239
234
  color: var(--ui3n-radio-color);
240
- min-height: calc(var(--ui3n-radion-size) - 2px);
241
- height: calc(var(--ui3n-radion-size) - 2px);
242
- min-width: calc(var(--ui3n-checkbox-size) - 2px);
243
- width: calc(var(--ui3n-radion-size) - 2px);
235
+ min-height: calc(var(--ui3n-radio-size, 16px) - 2px);
236
+ height: calc(var(--ui3n-radio-size, 16px) - 2px);
237
+ min-width: calc(var(--ui3n-radio-size, 16px) - 2px);
238
+ width: calc(var(--ui3n-radio-size, 16px) - 2px);
244
239
  cursor: pointer;
245
240
  }
246
241
 
@@ -13,6 +13,7 @@ export interface Ui3nScrollbarVerticalProps {
13
13
  trackWidth?: number;
14
14
  trackRadius?: number | string;
15
15
  trackColor?: string;
16
+ autoUpdate?: boolean;
16
17
  }
17
18
 
18
19
  /**
@@ -35,4 +36,5 @@ export interface Ui3nScrollbarVerticalSlots {
35
36
  export interface Ui3nScrollbarVerticalExpose {
36
37
  scrollTo(options: ScrollToOptions): void;
37
38
  getContainer(): HTMLDivElement;
39
+ updateMetrics(): void;
38
40
  }
@@ -19,6 +19,7 @@
19
19
  trackWidth: 6,
20
20
  trackRadius: 4,
21
21
  trackColor: 'transparent',
22
+ autoUpdate: true,
22
23
  });
23
24
  const emits = defineEmits<Ui3nScrollbarVerticalEmits>();
24
25
  defineSlots<Ui3nScrollbarVerticalSlots>();
@@ -137,7 +138,6 @@
137
138
 
138
139
  containerRef.value.scrollTo({
139
140
  top: targetScrollTop,
140
- behavior: 'smooth',
141
141
  });
142
142
  }
143
143
 
@@ -201,7 +201,7 @@
201
201
  resizeObserver = new ResizeObserver(updateMetrics);
202
202
  resizeObserver.observe(containerRef.value);
203
203
 
204
- if (containerRef.value.firstElementChild) {
204
+ if (props.autoUpdate && containerRef.value.firstElementChild) {
205
205
  resizeObserver.observe(containerRef.value.firstElementChild);
206
206
  }
207
207
  }
@@ -224,8 +224,8 @@
224
224
  scrollTo: (options: ScrollToOptions) => {
225
225
  containerRef.value?.scrollTo(options);
226
226
  },
227
-
228
227
  getContainer: () => containerRef.value!,
228
+ updateMetrics,
229
229
  });
230
230
  </script>
231
231
 
@@ -255,7 +255,7 @@
255
255
  <div
256
256
  ref="trackRef"
257
257
  :class="[$style.track, { [$style.trackVisible]: isBarVisible }]"
258
- @mousedown="onTrackClick"
258
+ @pointerdown="onTrackClick"
259
259
  >
260
260
  <div
261
261
  ref="thumbRef"
@@ -27,6 +27,14 @@ export type Ui3nSelectorValue<T extends Ui3nSelectorOptionBase> = T | T[keyof T]
27
27
  * Selector component properties
28
28
  */
29
29
  export interface Ui3nSelectorProps<T extends Ui3nSelectorOptionBase> {
30
+ /**
31
+ * Root element id
32
+ */
33
+ id?: string;
34
+ /**
35
+ * HTML name attribute for form submission
36
+ */
37
+ name?: string;
30
38
  /**
31
39
  * Current selector value
32
40
  */
@@ -147,3 +155,7 @@ export interface Ui3nSelectorSlots<T extends Ui3nSelectorOptionBase> {
147
155
  */
148
156
  selection?: (props: { value: Ui3nSelectorValue<T>; selectedItem: T | undefined }) => VNode;
149
157
  }
158
+
159
+ export interface Ui3nSelectorExpose {
160
+ clear: () => void;
161
+ }
@@ -1,19 +1,3 @@
1
- <!--
2
- Copyright (C) 2026 3NSoft Inc.
3
-
4
- This program is free software: you can redistribute it and/or modify it under
5
- the terms of the GNU General Public License as published by the Free Software
6
- Foundation, either version 3 of the License, or (at your option) any later
7
- version.
8
-
9
- This program is distributed in the hope that it will be useful, but
10
- WITHOUT ANY WARRANTY; without even the implied warranty of
11
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
- See the GNU General Public License for more details.
13
-
14
- You should have received a copy of the GNU General Public License along with
15
- this program. If not, see <http://www.gnu.org/licenses/>.
16
- -->
17
1
  <script setup lang="ts" generic="T extends Ui3nSelectorOptionBase">
18
2
  import { ref, computed, type ComputedRef, useTemplateRef, watch } from 'vue';
19
3
  import isEmpty from 'lodash/isEmpty';
@@ -25,6 +9,7 @@
25
9
  Ui3nSelectorProps,
26
10
  Ui3nSelectorEmits,
27
11
  Ui3nSelectorSlots,
12
+ Ui3nSelectorExpose,
28
13
  Ui3nSelectorItemDisplayingFunction,
29
14
  } from './types';
30
15
  import Ui3nButton from '../ui3n-button/ui3n-button.vue';
@@ -32,6 +17,7 @@
32
17
  import Ui3nMenu from '../ui3n-menu/ui3n-menu.vue';
33
18
 
34
19
  const props = withDefaults(defineProps<Ui3nSelectorProps<T>>(), {
20
+ name: undefined,
35
21
  label: '',
36
22
  items: () => [] as T[],
37
23
  itemValue: 'id',
@@ -219,6 +205,23 @@
219
205
  }
220
206
  }
221
207
 
208
+ function clear() {
209
+ resetValue();
210
+ }
211
+
212
+ defineExpose<Ui3nSelectorExpose>({
213
+ clear,
214
+ });
215
+
216
+ watch(
217
+ () => props.name,
218
+ newName => {
219
+ if (!newName) {
220
+ clear();
221
+ }
222
+ },
223
+ );
224
+
222
225
  watch(
223
226
  () => isMenuOpen.value,
224
227
  (val, oVal) => {
@@ -245,7 +248,17 @@
245
248
  </script>
246
249
 
247
250
  <template>
248
- <div :class="$style.ui3nSelector">
251
+ <div
252
+ :id="id"
253
+ :class="$style.ui3nSelector"
254
+ >
255
+ <input
256
+ v-if="name && modelValue"
257
+ type="hidden"
258
+ :name="name"
259
+ :value="typeof modelValue === 'object' ? JSON.stringify(modelValue) : String(modelValue)"
260
+ />
261
+
249
262
  <label
250
263
  v-if="label"
251
264
  :class="$style.label"
@@ -362,7 +375,15 @@
362
375
  @use '@/assets/styles/mixins' as mixins;
363
376
 
364
377
  .ui3nSelector {
365
- --selector-activator-height: 32px;
378
+ --ui3n-selector-activator-height: 32px;
379
+ --ui3n-selector-border-radius: calc(var(--ui3n-selector-activator-height) / 2.5);
380
+ --ui3n-selector-font-size: 12px;
381
+ --ui3n-selector-trigger-padding: 0 24px 0 8px;
382
+ --ui3n-selector-trigger-font-size: 13px;
383
+ --ui3n-selector-item-min-height: 32px;
384
+ --ui3n-selector-item-padding: 4px;
385
+ --ui3n-selector-item-font-size: 13px;
386
+ --ui3n-selector-item-border-radius: 4px;
366
387
 
367
388
  position: relative;
368
389
  width: 100%;
@@ -371,35 +392,37 @@
371
392
  .label {
372
393
  display: block;
373
394
  width: 100%;
374
- font-size: var(--font-12);
395
+ font-size: var(--ui3n-selector-font-size);
375
396
  font-weight: 500;
376
- line-height: var(--font-16);
397
+ line-height: 1.33;
377
398
  color: var(--color-text-control-primary-default);
378
- margin-bottom: var(--spacing-xs);
399
+ margin-bottom: 4px;
379
400
  }
380
401
 
381
402
  .menu {
382
403
  width: 100%;
383
404
  max-width: 100% !important;
405
+ border-radius: var(--ui3n-selector-border-radius);
384
406
 
385
407
  & > div {
386
408
  max-width: 100% !important;
409
+ border-radius: var(--ui3n-selector-border-radius);
387
410
  }
388
411
  }
389
412
 
390
413
  .trigger {
391
414
  display: flex;
392
415
  width: 100%;
393
- height: var(--selector-activator-height);
394
- padding: 0 var(--spacing-ml) 0 var(--spacing-s);
416
+ height: var(--ui3n-selector-activator-height);
417
+ padding: var(--ui3n-selector-trigger-padding);
395
418
  justify-content: flex-start;
396
419
  align-items: center;
397
420
  background-color: var(--color-bg-control-secondary-default);
398
- border-radius: var(--spacing-xs);
421
+ border-radius: var(--ui3n-selector-border-radius);
399
422
  color: var(--color-text-control-primary-default);
400
- font-size: var(--font-13);
423
+ font-size: var(--ui3n-selector-trigger-font-size);
401
424
  font-weight: 400;
402
- line-height: var(--font-16);
425
+ line-height: 1.23;
403
426
  transition: all 0.2s ease-in-out;
404
427
  cursor: pointer;
405
428
  @include mixins.text-overflow-ellipsis();
@@ -423,13 +446,13 @@
423
446
  }
424
447
 
425
448
  &.clearable {
426
- padding-right: calc(var(--spacing-xxl) + var(--spacing-xs));
449
+ padding-right: 52px;
427
450
  }
428
451
 
429
452
  .clearBtn {
430
453
  position: absolute;
431
- top: var(--spacing-xs);
432
- right: var(--spacing-ml);
454
+ top: 4px;
455
+ right: 24px;
433
456
  }
434
457
 
435
458
  &.triggerFocused {
@@ -442,32 +465,32 @@
442
465
  position: relative;
443
466
  width: 100%;
444
467
  background-color: var(--color-bg-block-primary-default);
445
- padding: var(--spacing-xs);
468
+ padding: var(--ui3n-selector-body-padding);
446
469
 
447
470
  .noData {
448
471
  display: flex;
449
- min-height: var(--spacing-l);
472
+ min-height: var(--ui3n-selector-item-min-height);
450
473
  justify-content: flex-start;
451
474
  align-items: center;
452
- padding: var(--spacing-xs) var(--spacing-s);
453
- font-size: var(--font-13);
454
- line-height: var(--font-16);
475
+ padding: var(--ui3n-selector-item-padding) calc(var(--ui3n-selector-item-padding) * 2);
476
+ font-size: var(--ui3n-selector-item-font-size);
477
+ line-height: 1.33;
455
478
  font-weight: 500;
456
479
  color: var(--color-text-control-primary-default);
457
- border-radius: var(--spacing-xs);
480
+ border-radius: var(--ui3n-selector-item-border-radius);
458
481
  }
459
482
 
460
483
  .item {
461
484
  display: flex;
462
- min-height: var(--spacing-l);
485
+ min-height: var(--ui3n-selector-item-min-height);
463
486
  justify-content: flex-start;
464
487
  align-items: center;
465
- padding: var(--spacing-xs) var(--spacing-s);
466
- font-size: var(--font-13);
467
- line-height: var(--font-16);
488
+ padding: var(--ui3n-selector-item-padding) calc(var(--ui3n-selector-item-padding) * 2);
489
+ font-size: var(--ui3n-selector-item-font-size);
490
+ line-height: 1.33;
468
491
  font-weight: 500;
469
492
  color: var(--color-text-control-primary-default);
470
- border-radius: var(--spacing-xs);
493
+ border-radius: var(--ui3n-selector-item-border-radius);
471
494
  user-select: none;
472
495
  cursor: pointer;
473
496
 
@@ -1,4 +1,12 @@
1
1
  export interface UI3nSliderProps {
2
+ /**
3
+ * Root element id
4
+ */
5
+ id?: string;
6
+ /**
7
+ * HTML name attribute for form submission
8
+ */
9
+ name?: string;
2
10
  /**
3
11
  * Current slider value
4
12
  */
@@ -70,3 +78,7 @@ export interface UI3nSliderEmits {
70
78
  */
71
79
  (event: 'update:modelValue', value: number | [number, number]): void;
72
80
  }
81
+
82
+ export interface UI3nSliderExpose {
83
+ clear: () => void;
84
+ }