@v1nt1248/3nclient-lib 0.3.28 → 0.3.29

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 +8 -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 +4 -0
  27. package/dist/components/ui3n-menu/ui3n-menu.d.ts +1 -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 +2066 -1690
  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 +9 -1
  57. package/src/components/ui3n-autocomplete/ui3n-autocomplete.vue +182 -51
  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 +4 -0
  83. package/src/components/ui3n-menu/ui3n-menu.vue +43 -32
  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
@@ -4,9 +4,10 @@
4
4
  import Ui3nTooltip from '../ui3n-tooltip/ui3n-tooltip.vue';
5
5
  import { round } from '@/utils';
6
6
  import type { Nullable } from '@/types';
7
- import type { UI3nSliderProps, UI3nSliderEmits } from './types';
7
+ import type { UI3nSliderProps, UI3nSliderEmits, UI3nSliderExpose } from './types';
8
8
 
9
9
  const props = withDefaults(defineProps<UI3nSliderProps>(), {
10
+ name: undefined,
10
11
  min: 0,
11
12
  max: 100,
12
13
  labelVisible: 'normal',
@@ -34,14 +35,9 @@
34
35
  const innerValue = ref<number | [number, number]>(0);
35
36
  const selectedPointer = ref<Nullable<1 | 2>>(null);
36
37
 
37
- const sliderHeight = computed(() => {
38
- const height = Math.max(Number(props.trackHeight), Number(props.thumbSize));
39
- return `${height}px`;
40
- });
41
- const trackHeightCss = computed(() => `${props.trackHeight}px`);
42
38
  const thumbSizeCss = computed(() => `${props.thumbSize}px`);
43
39
  const diff = computed(() => Number(props.max) - Number(props.min));
44
- const innerStep = computed(() => props.step ? Number(props.step) : diff.value / 100);
40
+ const innerStep = computed(() => (props.step ? Number(props.step) : diff.value / 100));
45
41
 
46
42
  const activeBlockStyle = computed(() => {
47
43
  const style = {} as Record<'left' | 'width', string>;
@@ -51,15 +47,14 @@
51
47
  if (minVal <= Number(props.min)) {
52
48
  style.left = '0px';
53
49
  } else if (minVal < Number(props.max)) {
54
- style.left = `${round((minVal - Number(props.min)) / diff.value * 100, 0)}%`;
50
+ style.left = `${round(((minVal - Number(props.min)) / diff.value) * 100, 0)}%`;
55
51
  }
56
52
 
57
53
  if (maxVal >= Number(props.max)) {
58
- style.width = minVal <= Number(props.min)
59
- ? '100%'
60
- : `${round((Number(props.max) - minVal) / diff.value * 100, 0)}%`;
54
+ style.width =
55
+ minVal <= Number(props.min) ? '100%' : `${round(((Number(props.max) - minVal) / diff.value) * 100, 0)}%`;
61
56
  } else if (maxVal > Number(props.min)) {
62
- style.width = `${round((maxVal - minVal) / diff.value * 100, 0)}%`;
57
+ style.width = `${round(((maxVal - minVal) / diff.value) * 100, 0)}%`;
63
58
  }
64
59
 
65
60
  return style;
@@ -73,30 +68,32 @@
73
68
  style.width = '100%';
74
69
  } else {
75
70
  style.left = '0px';
76
- style.width = `${round(((innerValue.value as number) - Number(props.min)) / diff.value * 100, 0)}%`;
71
+ style.width = `${round((((innerValue.value as number) - Number(props.min)) / diff.value) * 100, 0)}%`;
77
72
  }
78
73
 
79
74
  return style;
80
75
  }) as ComputedRef<Record<string, string>>;
81
76
 
82
- const pointer1PositionCss = computed(() => props.range
83
- ? `calc(${activeBlockStyle.value.left} - calc(${thumbSizeCss.value} / 2))`
84
- : `calc(${activeBlockStyle.value.width} - calc(${thumbSizeCss.value} / 2))`,
77
+ const pointer1PositionCss = computed(() =>
78
+ props.range
79
+ ? `calc(${activeBlockStyle.value.left} - calc(${thumbSizeCss.value} / 2))`
80
+ : `calc(${activeBlockStyle.value.width} - calc(${thumbSizeCss.value} / 2))`,
85
81
  );
86
- const pointer2PositionCss = computed(() => props.range
87
- ? `calc(${activeBlockStyle.value.width} + ${activeBlockStyle.value.left} - calc(${thumbSizeCss.value} / 2))`
88
- : '200%',
82
+ const pointer2PositionCss = computed(() =>
83
+ props.range
84
+ ? `calc(${activeBlockStyle.value.width} + ${activeBlockStyle.value.left} - calc(${thumbSizeCss.value} / 2))`
85
+ : '200%',
89
86
  );
90
87
 
91
88
  const label1Text = computed(() => {
92
89
  if (props.range) {
93
90
  const val = (innerValue.value as [number, number])[0];
94
- return props.transformValueMethod
95
- ? props.transformValueMethod(val)
96
- : `${val}`;
91
+ return props.transformValueMethod ? props.transformValueMethod(val) : `${val}`;
97
92
  }
98
93
 
99
- return props.transformValueMethod ? props.transformValueMethod(innerValue.value as number) : `${innerValue.value}`;
94
+ return props.transformValueMethod
95
+ ? props.transformValueMethod(innerValue.value as number)
96
+ : `${innerValue.value}`;
100
97
  });
101
98
  const label2Text = computed(() => {
102
99
  if (!props.range) {
@@ -104,7 +101,23 @@
104
101
  }
105
102
 
106
103
  const val = (innerValue.value as [number, number])[1];
107
- return props.transformValueMethod ? props.transformValueMethod(val) : `${val}`;
104
+ return props.transformValueMethod ? props.transformValueMethod(val) : `${val}`;
105
+ });
106
+
107
+ const sliderStyle = computed(() => {
108
+ const height = Math.max(Number(props.trackHeight), Number(props.thumbSize));
109
+ return {
110
+ '--ui3n-slider-height': `${height}px`,
111
+ '--ui3n-slider-label-color': props.labelColor,
112
+ '--ui3n-slider-label-text-color': props.labelTextColor,
113
+ '--ui3n-slider-active-color': props.activeColor,
114
+ '--ui3n-slider-track-color': props.trackColor,
115
+ '--ui3n-slider-track-height': `${props.trackHeight}px`,
116
+ '--ui3n-slider-thumb-size': `${props.thumbSize}px`,
117
+ '--ui3n-slider-thumb-color': props.thumbColor,
118
+ '--ui3n-slider-pointer1-position': pointer1PositionCss.value,
119
+ '--ui3n-slider-pointer2-position': pointer2PositionCss.value,
120
+ };
108
121
  });
109
122
 
110
123
  function onMouseenter(pointer: 1 | 2) {
@@ -152,7 +165,8 @@
152
165
  }
153
166
 
154
167
  const sliderRefClientRect = sliderRef.value!.getBoundingClientRect();
155
- const getValue = (leftPosition: number): number => Math.round(leftPosition / sliderRefClientRect.width * diff.value) + Number(props.min);
168
+ const getValue = (leftPosition: number): number =>
169
+ Math.round((leftPosition / sliderRefClientRect.width) * diff.value) + Number(props.min);
156
170
 
157
171
  let newLeft = event.clientX - shiftX.value[`${selectedPointer.value}`] - sliderRefClientRect.left;
158
172
  if (newLeft < 0) {
@@ -187,7 +201,7 @@
187
201
  function onTimelineClick(event: MouseEvent) {
188
202
  const { x } = event;
189
203
  const { x: sliderElStart, width: sliderElWidth } = sliderRef.value!.getBoundingClientRect();
190
- const selectedValue = Math.round((x - sliderElStart) / sliderElWidth * diff.value) + Number(props.min);
204
+ const selectedValue = Math.round(((x - sliderElStart) / sliderElWidth) * diff.value) + Number(props.min);
191
205
 
192
206
  if (props.range) {
193
207
  const [minVal, maxVal] = innerValue.value as [number, number];
@@ -204,9 +218,30 @@
204
218
  emits('update:modelValue', innerValue.value);
205
219
  }
206
220
 
221
+ function clear() {
222
+ const resetValue = props.range
223
+ ? ([Number(props.min), Number(props.min)] as [number, number])
224
+ : Number(props.min);
225
+ innerValue.value = resetValue;
226
+ emits('update:modelValue', resetValue);
227
+ }
228
+
229
+ defineExpose<UI3nSliderExpose>({
230
+ clear,
231
+ });
232
+
233
+ watch(
234
+ () => props.name,
235
+ newName => {
236
+ if (!newName) {
237
+ clear();
238
+ }
239
+ },
240
+ );
241
+
207
242
  watch(
208
243
  () => JSON.stringify(props.modelValue),
209
- (val) => {
244
+ val => {
210
245
  if (props.range) {
211
246
  if (val !== JSON.stringify(innerValue.value)) {
212
247
  innerValue.value = cloneDeep(props.modelValue);
@@ -220,7 +255,8 @@
220
255
  if (newVal !== innerValue.value) {
221
256
  innerValue.value = newVal;
222
257
  }
223
- }, {
258
+ },
259
+ {
224
260
  immediate: true,
225
261
  },
226
262
  );
@@ -229,9 +265,33 @@
229
265
  <template>
230
266
  <div
231
267
  ref="sliderEl"
268
+ :id="id"
269
+ :style="sliderStyle"
232
270
  :class="[$style.ui3nSlider, disabled && $style.disabled]"
233
271
  @click.stop.prevent="onTimelineClick"
234
272
  >
273
+ <template v-if="name">
274
+ <template v-if="range">
275
+ <input
276
+ type="hidden"
277
+ :name="`${name}_min`"
278
+ :value="(innerValue as [number, number])[0]"
279
+ />
280
+ <input
281
+ type="hidden"
282
+ :name="`${name}_max`"
283
+ :value="(innerValue as [number, number])[1]"
284
+ />
285
+ </template>
286
+ <template v-else>
287
+ <input
288
+ type="hidden"
289
+ :name="name"
290
+ :value="innerValue as number"
291
+ />
292
+ </template>
293
+ </template>
294
+
235
295
  <div :class="$style.track">
236
296
  <div
237
297
  :class="$style.active"
@@ -290,17 +350,6 @@
290
350
 
291
351
  <style lang="scss" module>
292
352
  .ui3nSlider {
293
- --ui3n-slider-height: v-bind(sliderHeight);
294
- --ui3n-slider-label-color: v-bind(labelColor);
295
- --ui3n-slider-label-text-color: v-bind(labelTextColor);
296
- --ui3n-slider-active-color: v-bind(activeColor);
297
- --ui3n-slider-track-color: v-bind(trackColor);
298
- --ui3n-slider-track-height: v-bind(trackHeightCss);
299
- --ui3n-slider-thumb-size: v-bind(thumbSizeCss);
300
- --ui3n-slider-thumb-color: v-bind(thumbColor);
301
- --ui3n-slider-pointer1-position: v-bind(pointer1PositionCss);
302
- --ui3n-slider-pointer2-position: v-bind(pointer2PositionCss);
303
-
304
353
  position: relative;
305
354
  width: 100%;
306
355
  height: var(--ui3n-slider-height);
@@ -2,6 +2,10 @@
2
2
  * Step line bar component properties
3
3
  */
4
4
  export interface Ui3nStepLineBarProps {
5
+ /**
6
+ * Root element id
7
+ */
8
+ id?: string;
5
9
  /**
6
10
  * Step label
7
11
  */
@@ -1,16 +1,16 @@
1
1
  <script lang="ts" setup>
2
2
  import type { Ui3nStepLineBarProps } from './types';
3
3
 
4
- withDefaults(
5
- defineProps<Ui3nStepLineBarProps>(),
6
- {
7
- current: 1,
8
- },
9
- );
4
+ const props = withDefaults(defineProps<Ui3nStepLineBarProps>(), {
5
+ current: 1,
6
+ });
10
7
  </script>
11
8
 
12
9
  <template>
13
- <div :class="$style.ui3nStepLineBar">
10
+ <div
11
+ :id="id"
12
+ :class="$style.ui3nStepLineBar"
13
+ >
14
14
  <div :class="$style.label">
15
15
  {{ label }}
16
16
  </div>
@@ -27,8 +27,6 @@
27
27
 
28
28
  <style lang="scss" module>
29
29
  .ui3nStepLineBar {
30
- --ui3n-step-line-bar-steps: v-bind(steps);
31
-
32
30
  position: relative;
33
31
  width: 100%;
34
32
  }
@@ -54,7 +52,7 @@
54
52
 
55
53
  .step {
56
54
  position: relative;
57
- width: calc((100% - (calc(var(--ui3n-step-line-bar-steps) - 1) * var(--spacing-s))) / var(--ui3n-step-line-bar-steps));
55
+ flex: 1;
58
56
  height: var(--spacing-xs);
59
57
  border-radius: var(--spacing-xs);
60
58
  background-color: var(--color-bg-control-secondary-default);
@@ -4,6 +4,14 @@ import { VNode } from 'vue';
4
4
  * Switch component properties
5
5
  */
6
6
  export interface Ui3nSwitchProps {
7
+ /**
8
+ * Root element id
9
+ */
10
+ id?: string;
11
+ /**
12
+ * HTML name attribute for form submission
13
+ */
14
+ name?: string;
7
15
  /**
8
16
  * Current switch value
9
17
  */
@@ -46,3 +54,7 @@ export interface Ui3nSwitchSlots {
46
54
  */
47
55
  default: () => VNode;
48
56
  }
57
+
58
+ export interface Ui3nSwitchExpose {
59
+ clear: () => void;
60
+ }
@@ -1,15 +1,13 @@
1
1
  <script lang="ts" setup>
2
- import { onMounted, ref, watch, useSlots } from 'vue';
3
- import type { Ui3nSwitchEmits, Ui3nSwitchProps, Ui3nSwitchSlots } from './types';
4
-
5
- const props = withDefaults(
6
- defineProps<Ui3nSwitchProps>(),
7
- {
8
- size: 16,
9
- color: 'var(--color-icon-control-accent-default)',
10
- disabled: false,
11
- },
12
- );
2
+ import { computed, ref, watch, useSlots } from 'vue';
3
+ import type { Ui3nSwitchEmits, Ui3nSwitchProps, Ui3nSwitchSlots, Ui3nSwitchExpose } from './types';
4
+
5
+ const props = withDefaults(defineProps<Ui3nSwitchProps>(), {
6
+ name: undefined,
7
+ size: 16,
8
+ color: 'var(--color-icon-control-accent-default)',
9
+ disabled: false,
10
+ });
13
11
 
14
12
  const emits = defineEmits<Ui3nSwitchEmits>();
15
13
 
@@ -19,18 +17,10 @@
19
17
  const switchEl = ref<HTMLDivElement | null>(null);
20
18
  const val = ref<boolean>(false);
21
19
 
22
- onMounted(() => {
23
- if (switchEl.value) {
24
- switchEl.value.style.setProperty('--ui3n-switch-color', `${props.color}`);
25
- props.size && switchEl.value.style.setProperty('--ui3n-switch-size', `${props.size}px`);
26
- }
27
- });
28
-
29
- watch(
30
- () => props.modelValue,
31
- newValue => val.value = newValue,
32
- { immediate: true },
33
- );
20
+ const switchStyle = computed(() => ({
21
+ '--ui3n-switch-color': props.color,
22
+ '--ui3n-switch-size': `${props.size}px`,
23
+ }));
34
24
 
35
25
  function change(ev: Event) {
36
26
  ev.preventDefault();
@@ -39,13 +29,55 @@
39
29
  emits('change', val.value);
40
30
  emits('update:modelValue', val.value);
41
31
  }
32
+
33
+ function clear() {
34
+ val.value = false;
35
+ emits('change', false);
36
+ emits('update:modelValue', false);
37
+ }
38
+
39
+ defineExpose<Ui3nSwitchExpose>({
40
+ clear,
41
+ });
42
+
43
+ watch(
44
+ () => props.name,
45
+ newName => {
46
+ if (!newName) {
47
+ clear();
48
+ }
49
+ },
50
+ );
51
+
52
+ watch(
53
+ () => props.modelValue,
54
+ newValue => (val.value = newValue),
55
+ { immediate: true },
56
+ );
42
57
  </script>
43
58
 
44
59
  <template>
45
60
  <div
46
61
  ref="switchEl"
47
- :class="[$style.ui3nSwitch, val && $style.checked, !slots.default && $style.noLabel, disabled && $style.disabled]"
62
+ :id="id"
63
+ :style="switchStyle"
64
+ :class="[
65
+ $style.ui3nSwitch,
66
+ val && $style.checked,
67
+ !slots.default && $style.noLabel,
68
+ disabled && $style.disabled,
69
+ ]"
48
70
  >
71
+ <input
72
+ v-if="name"
73
+ type="checkbox"
74
+ hidden
75
+ :name="name"
76
+ :checked="val"
77
+ :disabled="disabled"
78
+ :value="val ? 'on' : ''"
79
+ />
80
+
49
81
  <div
50
82
  :class="$style.body"
51
83
  :tabindex="disabled ? -1 : 0"
@@ -75,7 +107,7 @@
75
107
  display: flex;
76
108
  justify-content: flex-start;
77
109
  align-items: center;
78
- gap: var(--spacing-s);
110
+ gap: 8px;
79
111
  }
80
112
 
81
113
  .body {
@@ -199,6 +199,22 @@ export function useTable<T extends Ui3nTableBodyBaseItem>(props: Ui3nTableProps<
199
199
  emits('change:sort', currentConfig.value.sortOrder as Ui3nTableSort<T>);
200
200
  }
201
201
 
202
+ function clear() {
203
+ isRowKeyUsed.value && ((selectedRows.value as Array<T[keyof T]>) = []);
204
+ !isRowKeyUsed.value && (selectedRows.value as Set<T>).clear();
205
+ hasGroupActionsRow.value = false;
206
+ emits('select:row', []);
207
+ }
208
+
209
+ watch(
210
+ () => props.config?.tableName,
211
+ newTableName => {
212
+ if (!newTableName) {
213
+ clear();
214
+ }
215
+ },
216
+ );
217
+
202
218
  watch(
203
219
  tableColumnWidth,
204
220
  (val, oVal) => {
@@ -237,5 +253,6 @@ export function useTable<T extends Ui3nTableBodyBaseItem>(props: Ui3nTableProps<
237
253
  processSelection,
238
254
  toggleSelectedRows,
239
255
  changeSortOrder,
256
+ clear,
240
257
  };
241
258
  }
@@ -309,4 +309,8 @@ export type Ui3nTableExpose<T extends Ui3nTableBodyBaseItem> = {
309
309
  * Close group actions row
310
310
  */
311
311
  closeGroupActionsRow: () => void;
312
+ /**
313
+ * Clear all selected rows
314
+ */
315
+ clear: () => void;
312
316
  };
@@ -3,10 +3,12 @@
3
3
  import Ui3nIcon from '../ui3n-icon/ui3n-icon.vue';
4
4
  import type { Ui3nTableSortIconProps } from './types';
5
5
 
6
- const props = defineProps<Ui3nTableSortIconProps>();
6
+ const props = withDefaults(defineProps<Ui3nTableSortIconProps>(), {
7
+ size: 16,
8
+ color: 'var(--color-icon-table-primary-default)',
9
+ });
7
10
 
8
- const iconSize = computed(() => props.size ? +props.size : 16);
9
- const iconColor = computed(() => props.color || 'var(--color-icon-table-primary-default)');
11
+ const iconName = computed(() => (props.value === 'asc' ? 'round-arrow-upward' : 'round-arrow-downward'));
10
12
  </script>
11
13
 
12
14
  <template>
@@ -15,11 +17,10 @@
15
17
  name="fade"
16
18
  >
17
19
  <ui3n-icon
18
- :key="value === 'asc' ? 'round-arrow-upward' : 'round-arrow-downward'"
19
- :icon="value === 'asc' ? 'round-arrow-upward' : 'round-arrow-downward'"
20
- :width="iconSize"
21
- :height="iconSize"
22
- :color="iconColor"
20
+ :key="iconName"
21
+ :icon="iconName"
22
+ :size="Number(size)"
23
+ :color="color"
23
24
  />
24
25
  </transition>
25
26
  </template>
@@ -1,7 +1,13 @@
1
1
  <script setup lang="ts" generic="T extends Ui3nTableBodyBaseItem">
2
2
  import size from 'lodash/size';
3
3
  import { useTable } from './composables/useTable';
4
- import type { Ui3nTableBodyBaseItem, Ui3nTableEmits, Ui3nTableProps, Ui3nTableSlots, Ui3nTableExpose } from './types';
4
+ import type {
5
+ Ui3nTableBodyBaseItem,
6
+ Ui3nTableEmits,
7
+ Ui3nTableProps,
8
+ Ui3nTableSlots,
9
+ Ui3nTableExpose,
10
+ } from './types';
5
11
  import Ui3nButton from '../ui3n-button/ui3n-button.vue';
6
12
  import Ui3nCheckbox from '../ui3n-checkbox/ui3n-checkbox.vue';
7
13
  import Ui3nTableSortIcon from './ui3n-table-sort-icon.vue';
@@ -27,6 +33,7 @@
27
33
  processSelection,
28
34
  toggleSelectedRows,
29
35
  changeSortOrder,
36
+ clear,
30
37
  } = useTable(props, emits);
31
38
 
32
39
  const eventHandlers = {
@@ -39,6 +46,7 @@
39
46
  selectedRowsArray,
40
47
  hasGroupActionsRow,
41
48
  closeGroupActionsRow,
49
+ clear,
42
50
  });
43
51
  </script>
44
52
 
@@ -47,6 +55,19 @@
47
55
  ref="tableEl"
48
56
  :class="$style.ui3nTable"
49
57
  >
58
+ <fieldset
59
+ v-if="config?.tableName && selectedRowsSize > 0"
60
+ :class="$style.hiddenBlock"
61
+ >
62
+ <input
63
+ v-for="(row, rowIndex) in selectedRowsArray"
64
+ :key="getRowKey(row, rowIndex)"
65
+ type="hidden"
66
+ :name="config.selectable === 'multiple' ? `${config.tableName}[]` : config.tableName"
67
+ :value="String(getRowKey(row, rowIndex))"
68
+ />
69
+ </fieldset>
70
+
50
71
  <div :class="[$style.header, showGroupActionsRow && $style.withGroupActions]">
51
72
  <!-- group actions -->
52
73
  <div
@@ -112,9 +133,7 @@
112
133
  <div :class="$style.body">
113
134
  <template v-if="config?.showNoDataMessage && !size(body.content)">
114
135
  <slot name="no-data">
115
- <div :class="$style.noData">
116
- No data
117
- </div>
136
+ <div :class="$style.noData">No data</div>
118
137
  </slot>
119
138
  </template>
120
139
 
@@ -204,8 +223,13 @@
204
223
  --ui3n-table-group-actions-bg-color: var(--color-bg-block-primary-default);
205
224
  --ui3n-table-header-bg-color: var(--color-bg-table-header-default);
206
225
  --ui3n-table-header-color: var(--color-text-table-primary-default);
226
+ --ui3n-table-header-font-size: 14px;
227
+ --ui3n-table-padding-inline: 16px;
207
228
  --ui3n-table-row-color: var(--color-text-table-primary-default);
208
229
  --ui3n-table-row-bg-color-selected: var(--color-bg-control-primary-hover);
230
+ --ui3n-table-row-checkbox-width: 16px;
231
+ --ui3n-table-cell-font-size: 12px;
232
+ --ui3n-table-nodata-height: 48px;
209
233
  --ui3n-table-nodata-color: var(--color-text-control-secondary-default);
210
234
 
211
235
  position: relative;
@@ -219,6 +243,13 @@
219
243
  align-items: stretch;
220
244
  }
221
245
 
246
+ .hiddenBlock {
247
+ display: none;
248
+ border: none;
249
+ padding: 0;
250
+ margin: 0;
251
+ }
252
+
222
253
  .header {
223
254
  position: sticky;
224
255
  top: 0;
@@ -228,7 +259,7 @@
228
259
  display: grid;
229
260
  grid-template-columns: var(--ui3n-table-columns-width);
230
261
  background-color: var(--ui3n-table-header-bg-color);
231
- padding-left: var(--spacing-m);
262
+ padding-left: var(--ui3n-table-padding-inline);
232
263
  z-index: 5;
233
264
 
234
265
  &.withGroupActions {
@@ -238,7 +269,7 @@
238
269
  }
239
270
 
240
271
  .headerItemWrapper:not(:first-child) {
241
- padding: 0 var(--spacing-xs);
272
+ padding: 0 calc(var(--ui3n-table-padding-inline) / 4);
242
273
  }
243
274
  }
244
275
 
@@ -267,7 +298,7 @@
267
298
 
268
299
  .headerText {
269
300
  display: block;
270
- font-size: var(--font-14);
301
+ font-size: var(--ui3n-table-header-font-size);
271
302
  font-weight: 500;
272
303
  color: var(--ui3n-table-header-color);
273
304
  @include mixins.text-overflow-ellipsis();
@@ -275,7 +306,7 @@
275
306
 
276
307
  .sortableActive {
277
308
  .headerItem {
278
- gap: var(--spacing-s);
309
+ gap: 8px;
279
310
  }
280
311
  }
281
312
 
@@ -286,7 +317,7 @@
286
317
  display: flex;
287
318
  width: 100%;
288
319
  height: var(--ui3n-table-group-actions-height);
289
- padding: 0 var(--spacing-m);
320
+ padding: 0 var(--ui3n-table-padding-inline);
290
321
  justify-content: space-between;
291
322
  align-items: center;
292
323
  background-color: var(--ui3n-table-group-actions-bg-color);
@@ -298,7 +329,7 @@
298
329
  .groupActionsBody {
299
330
  display: flex;
300
331
  height: 100%;
301
- padding: 0 var(--spacing-s);
332
+ padding: 0 calc(var(--ui3n-table-padding-inline) / 2);
302
333
  flex-grow: 1;
303
334
  }
304
335
 
@@ -318,7 +349,7 @@
318
349
  background-color: transparent;
319
350
 
320
351
  &:not(.customRow) {
321
- padding-left: var(--spacing-m);
352
+ padding-left: var(--ui3n-table-padding-inline);
322
353
  display: grid;
323
354
  grid-template-columns: var(--ui3n-table-columns-width);
324
355
  }
@@ -340,7 +371,7 @@
340
371
  position: absolute;
341
372
  top: 0;
342
373
  left: 16px;
343
- width: var(--spacing-m);
374
+ width: var(--ui3n-table-row-checkbox-width);
344
375
  height: 100%;
345
376
  display: flex;
346
377
  justify-content: flex-start;
@@ -356,12 +387,12 @@
356
387
  align-items: center;
357
388
 
358
389
  &.bodyItemFirst {
359
- padding-left: var(--spacing-ml);
390
+ padding-left: calc(var(--ui3n-table-padding-inline) * 1.5);
360
391
  }
361
392
  }
362
393
 
363
394
  .cell {
364
- font-size: var(--font-12);
395
+ font-size: var(--ui3n-table-cell-font-size);
365
396
  font-weight: 400;
366
397
  color: var(--ui3n-table-row-color);
367
398
  }
@@ -369,12 +400,12 @@
369
400
  .noData {
370
401
  position: relative;
371
402
  width: 100%;
372
- height: var(--spacing-xxl);
373
- padding-top: var(--spacing-ml);
403
+ height: var(--ui3n-table-nodata-height);
404
+ padding-top: 24px;
374
405
  display: flex;
375
406
  justify-content: center;
376
407
  align-items: center;
377
- font-size: var(--font-12);
408
+ font-size: var(--ui3n-table-cell-font-size);
378
409
  font-weight: 600;
379
410
  color: var(--ui3n-table-nodata-color);
380
411
  }
@@ -4,6 +4,10 @@ import { VNode } from 'vue';
4
4
  * Tabs component properties
5
5
  */
6
6
  export interface Ui3nTabsProps {
7
+ /**
8
+ * Root element id
9
+ */
10
+ id?: string;
7
11
  /**
8
12
  * Current active tab index
9
13
  */