@v1nt1248/3nclient-lib 0.3.25 → 0.3.28

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 (61) hide show
  1. package/README.md +2 -0
  2. package/dist/chunks/emoticons-DMgiBINj.js +2517 -0
  3. package/dist/chunks/plugins-keys-jqAZ5D94.js +4466 -0
  4. package/dist/chunks/ui3n-notification-DlDM-u-R.js +276 -0
  5. package/dist/components/index.d.ts +39 -35
  6. package/dist/components/ui3n-scrollbar-horizontal/types.d.ts +22 -0
  7. package/dist/components/ui3n-scrollbar-horizontal/ui3n-scroolbar-horizontal.d.ts +41 -0
  8. package/dist/components/ui3n-scrollbar-vertical/types.d.ts +34 -0
  9. package/dist/components/ui3n-scrollbar-vertical/ui3n-scrollbar-vertical.d.ts +41 -0
  10. package/dist/index.d.ts +37 -33
  11. package/dist/mixins.scss +102 -0
  12. package/dist/style.css +1 -1
  13. package/dist/ui3n-components.d.ts +37 -33
  14. package/dist/ui3n-components.js +2496 -18935
  15. package/dist/ui3n-plugins.js +60 -4121
  16. package/dist/ui3n-utils.js +5 -7911
  17. package/dist/variables.css +2 -2
  18. package/package.json +6 -13
  19. package/src/components/index.ts +24 -0
  20. package/src/components/ui3n-list/types.ts +1 -1
  21. package/src/components/ui3n-list/ui3n-list.vue +4 -11
  22. package/src/components/ui3n-scrollbar-horizontal/types.ts +26 -0
  23. package/src/components/ui3n-scrollbar-horizontal/ui3n-scroolbar-horizontal.vue +337 -0
  24. package/src/components/ui3n-scrollbar-vertical/types.ts +38 -0
  25. package/src/components/ui3n-scrollbar-vertical/ui3n-scrollbar-vertical.vue +337 -0
  26. package/src/components/ui3n-virtual-scroll/ui3n-virtual-scroll.vue +52 -58
  27. package/dist/components/ui3n-autocomplete/{ui3n-autocomplete.vue.d.ts → ui3n-autocomplete.d.ts} +0 -0
  28. package/dist/components/ui3n-badge/{ui3n-badge-simple.vue.d.ts → ui3n-badge-simple.d.ts} +0 -0
  29. package/dist/components/ui3n-badge/{ui3n-badge.vue.d.ts → ui3n-badge.d.ts} +0 -0
  30. package/dist/components/ui3n-breadcrumbs/{ui3n-breadcrumb.vue.d.ts → ui3n-breadcrumb.d.ts} +0 -0
  31. package/dist/components/ui3n-breadcrumbs/{ui3n-breadcrumbs.vue.d.ts → ui3n-breadcrumbs.d.ts} +0 -0
  32. package/dist/components/ui3n-button/{ui3n-button.vue.d.ts → ui3n-button.d.ts} +0 -0
  33. package/dist/components/ui3n-checkbox/{ui3n-checkbox.vue.d.ts → ui3n-checkbox.d.ts} +0 -0
  34. package/dist/components/ui3n-chip/{ui3n-chip.vue.d.ts → ui3n-chip.d.ts} +0 -0
  35. package/dist/components/ui3n-dialog/{ui3n-dialog-provider.vue.d.ts → ui3n-dialog-provider.d.ts} +0 -0
  36. package/dist/components/ui3n-dialog/{ui3n-dialog.vue.d.ts → ui3n-dialog.d.ts} +0 -0
  37. package/dist/components/ui3n-drop-files/{ui3n-drop-files.vue.d.ts → ui3n-drop-files.d.ts} +0 -0
  38. package/dist/components/ui3n-editable/{ui3n-editable.vue.d.ts → ui3n-editable.d.ts} +0 -0
  39. package/dist/components/ui3n-emoji/{ui3n-emoji.vue.d.ts → ui3n-emoji.d.ts} +0 -0
  40. package/dist/components/ui3n-icon/{ui3n-icon.vue.d.ts → ui3n-icon.d.ts} +0 -0
  41. package/dist/components/ui3n-input/{ui3n-input.vue.d.ts → ui3n-input.d.ts} +0 -0
  42. package/dist/components/ui3n-input-file/{ui3n-input-file.vue.d.ts → ui3n-input-file.d.ts} +0 -0
  43. package/dist/components/ui3n-list/{ui3n-list.vue.d.ts → ui3n-list.d.ts} +0 -0
  44. package/dist/components/ui3n-menu/{ui3n-menu.vue.d.ts → ui3n-menu.d.ts} +0 -0
  45. package/dist/components/ui3n-mobile-menu/{ui3n-mobile-menu.vue.d.ts → ui3n-mobile-menu.d.ts} +0 -0
  46. package/dist/components/ui3n-mobile-menu-item/{ui3n-mobile-menu-item.vue.d.ts → ui3n-mobile-menu-item.d.ts} +0 -0
  47. package/dist/components/ui3n-notification/{ui3n-notification.vue.d.ts → ui3n-notification.d.ts} +0 -0
  48. package/dist/components/ui3n-progress/{ui3n-progress-circular.vue.d.ts → ui3n-progress-circular.d.ts} +0 -0
  49. package/dist/components/ui3n-progress/{ui3n-progress-linear.vue.d.ts → ui3n-progress-linear.d.ts} +0 -0
  50. package/dist/components/ui3n-radio-group/{ui3n-radio-group.vue.d.ts → ui3n-radio-group.d.ts} +0 -0
  51. package/dist/components/ui3n-radio-group/{ui3n-radio.vue.d.ts → ui3n-radio.d.ts} +0 -0
  52. package/dist/components/ui3n-selector/{ui3n-selector.vue.d.ts → ui3n-selector.d.ts} +0 -0
  53. package/dist/components/ui3n-slider/{ui3n-slider.vue.d.ts → ui3n-slider.d.ts} +2 -2
  54. /package/dist/components/ui3n-step-line-bar/{ui3n-step-line-bar.vue.d.ts → ui3n-step-line-bar.d.ts} +0 -0
  55. /package/dist/components/ui3n-switch/{ui3n-switch.vue.d.ts → ui3n-switch.d.ts} +0 -0
  56. /package/dist/components/ui3n-table/{ui3n-table-sort-icon.vue.d.ts → ui3n-table-sort-icon.d.ts} +0 -0
  57. /package/dist/components/ui3n-table/{ui3n-table.vue.d.ts → ui3n-table.d.ts} +0 -0
  58. /package/dist/components/ui3n-tabs/{ui3n-tabs.vue.d.ts → ui3n-tabs.d.ts} +0 -0
  59. /package/dist/components/ui3n-text/{ui3n-text.vue.d.ts → ui3n-text.d.ts} +0 -0
  60. /package/dist/components/ui3n-tooltip/{ui3n-tooltip.vue.d.ts → ui3n-tooltip.d.ts} +0 -0
  61. /package/dist/components/ui3n-virtual-scroll/{ui3n-virtual-scroll.vue.d.ts → ui3n-virtual-scroll.d.ts} +0 -0
@@ -949,11 +949,11 @@ div {
949
949
  }
950
950
 
951
951
  ::-webkit-scrollbar-track {
952
- background-color: var(--s-default-outline-focused);
952
+ background-color: transparent;
953
953
  }
954
954
 
955
955
  ::-webkit-scrollbar-thumb {
956
- border-radius: 2px;
956
+ border-radius: 4px;
957
957
  height: 50px;
958
958
  background-color: var(--default-fill-pressed);
959
959
  }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@v1nt1248/3nclient-lib",
3
3
  "license": "AGPL-3.0-or-later",
4
4
  "author": "v1nt1248",
5
- "version": "0.3.25",
5
+ "version": "0.3.28",
6
6
  "description": "Library for 3NWeb clients",
7
7
  "type": "module",
8
8
  "files": [
@@ -25,25 +25,17 @@
25
25
  "types": "./dist/ui3n-utils.d.ts"
26
26
  },
27
27
  "./style.css": "./dist/style.css",
28
- "./variables.css": "./dist/variables.css"
28
+ "./variables.css": "./dist/variables.css",
29
+ "./mixins.scss": "./dist/mixins.scss"
29
30
  },
30
31
  "scripts": {
31
- "dev": "LIB_NAME=all vite",
32
- "generate:types": "vue-tsc --declaration --emitDeclarationOnly --outdir ./dist",
33
- "copy:dts": "cp ./src/types.d.ts ./dist",
34
- "copy:css": "cp ./src/assets/styles/variables.css ./dist",
35
- "copy:icons:css": "cp ./src/assets/styles/icons.css ./dist",
32
+ "dev": "vite",
36
33
  "clean:dist": "rm -rf dist/",
37
- "build:components": "LIB_NAME=lib vite build",
38
- "build:plugins": "LIB_NAME=plugins vite build",
39
- "build:utils": "LIB_NAME=utils vite build",
40
- "build": "pnpm clean:dist && vue-tsc --noEmit && pnpm build:plugins && pnpm build:utils && pnpm build:components && pnpm copy:css",
34
+ "build": "pnpm clean:dist && vite build",
41
35
  "pack": "pnpm build && npm pack && cp *.tgz ./dist && rm *.tgz",
42
36
  "preview": "vite preview",
43
37
  "stylelint": "stylelint --config .stylelint.config.cjs 'src/**/*.{vue,scss,css}'",
44
38
  "stylelint:fix": "stylelint --config .stylelint.config.cjs --fix 'src/**/*.{vue,scss,css}'",
45
- "linter": "eslint -c eslint.config.js --ext .js,.vue,.ts, src",
46
- "linter:fix": "eslint -c eslint.config.js --fix --ext .js,.vue,.ts, src",
47
39
  "lint": "pnpm linter && pnpm stylelint",
48
40
  "lint:fix": "pnpm linter:fix && pnpm stylelint:fix",
49
41
  "docs:dev": "vitepress dev docs",
@@ -103,6 +95,7 @@
103
95
  "vite-plugin-css-injected-by-js": "4.0.1",
104
96
  "vite-plugin-dts": "4.5.4",
105
97
  "vite-plugin-node-polyfills": "^0.28.0",
98
+ "vite-plugin-static-copy": "^4.1.1",
106
99
  "vite-plugin-vue-devtools": "8.1.2",
107
100
  "vitepress": "1.6.4",
108
101
  "vue": "3.5.35",
@@ -120,6 +120,20 @@ import type {
120
120
  Ui3nMobileMenuItemProps,
121
121
  Ui3nMobileMenuItemEmits,
122
122
  } from './ui3n-mobile-menu-item/types';
123
+ import Ui3nScrollbarVertical from './ui3n-scrollbar-vertical/ui3n-scrollbar-vertical.vue';
124
+ import type {
125
+ Ui3nScrollbarVerticalProps,
126
+ Ui3nScrollbarVerticalEmits,
127
+ Ui3nScrollbarVerticalSlots,
128
+ Ui3nScrollbarVerticalExpose,
129
+ } from './ui3n-scrollbar-vertical/types';
130
+ import Ui3nScrollbarHorizontal from './ui3n-scrollbar-horizontal/ui3n-scroolbar-horizontal.vue';
131
+ import type {
132
+ Ui3nScrollbarHorizontalProps,
133
+ Ui3nScrollbarHorizontalEmits,
134
+ Ui3nScrollbarHorizontalSlots,
135
+ Ui3nScrollbarHorizontalExpose,
136
+ } from './ui3n-scrollbar-horizontal/types';
123
137
 
124
138
  export {
125
139
  Ui3nIcon,
@@ -251,4 +265,14 @@ export {
251
265
  Ui3nMobileMenuItemBase,
252
266
  Ui3nMobileMenuItemProps,
253
267
  Ui3nMobileMenuItemEmits,
268
+ Ui3nScrollbarVertical,
269
+ Ui3nScrollbarVerticalProps,
270
+ Ui3nScrollbarVerticalEmits,
271
+ Ui3nScrollbarVerticalSlots,
272
+ Ui3nScrollbarVerticalExpose,
273
+ Ui3nScrollbarHorizontal,
274
+ Ui3nScrollbarHorizontalProps,
275
+ Ui3nScrollbarHorizontalEmits,
276
+ Ui3nScrollbarHorizontalSlots,
277
+ Ui3nScrollbarHorizontalExpose,
254
278
  };
@@ -1,4 +1,4 @@
1
- import { VNode } from 'vue';
1
+ import type { VNode } from 'vue';
2
2
 
3
3
  /**
4
4
  * List component properties
@@ -32,7 +32,7 @@
32
32
  <div
33
33
  v-for="(item, index) in items"
34
34
  :key="item[keyField as keyof T] as PropertyKey"
35
- :class="$style.ui3nListItem "
35
+ :class="$style.ui3nListItem"
36
36
  >
37
37
  <slot
38
38
  name="item"
@@ -40,10 +40,7 @@
40
40
  :index="index"
41
41
  >
42
42
  <div
43
- :class="[
44
- $style.ui3nListItemContent,
45
- disabled && $style.ui3nListItemContentDisabled,
46
- ]"
43
+ :class="[$style.ui3nListItemContent, disabled && $style.ui3nListItemContentDisabled]"
47
44
  @click.stop="emits('select', { value: item, index })"
48
45
  >
49
46
  {{ item }}
@@ -63,16 +60,12 @@
63
60
  width: 100%;
64
61
  height: 100%;
65
62
  background-color: var(--ui3n-list-bg-color);
66
- display: flex;
67
- flex-direction: column;
68
- justify-content: flex-start;
69
- align-items: stretch;
70
63
  }
71
64
 
72
65
  .ui3nListTitle {
73
66
  position: relative;
74
67
  top: 0;
75
- z-index: 1;
68
+ z-index: 2;
76
69
  }
77
70
 
78
71
  .ui3nListTitleSticky {
@@ -81,7 +74,6 @@
81
74
 
82
75
  .ui3nListContent {
83
76
  position: relative;
84
- flex-grow: 1;
85
77
  }
86
78
 
87
79
  .ui3nListTitleContent,
@@ -106,6 +98,7 @@
106
98
  font-size: 14px;
107
99
  font-weight: 400;
108
100
  cursor: pointer;
101
+ width: 100%;
109
102
  }
110
103
 
111
104
  .ui3nListItemContentDisabled {
@@ -0,0 +1,26 @@
1
+ import type { VNode } from 'vue';
2
+
3
+ export interface Ui3nScrollbarHorizontalProps {
4
+ thumbMinWidth?: number | string;
5
+ thumbWidth?: number | string | 'auto';
6
+ thumbRadius?: number | string;
7
+ thumbColor?: string;
8
+ thumbHoverColor?: string;
9
+ thumbActiveColor?: string;
10
+ trackHeight?: number | string;
11
+ trackRadius?: number | string;
12
+ trackColor?: string;
13
+ }
14
+
15
+ export interface Ui3nScrollbarHorizontalEmits {
16
+ (ev: 'scroll', value: Event): void;
17
+ }
18
+
19
+ export interface Ui3nScrollbarHorizontalSlots {
20
+ default: () => VNode;
21
+ }
22
+
23
+ export interface Ui3nScrollbarHorizontalExpose {
24
+ scrollTo(options: ScrollToOptions): void;
25
+ getContainer(): HTMLDivElement;
26
+ }
@@ -0,0 +1,337 @@
1
+ <script lang="ts" setup>
2
+ import { ref, computed, onMounted, onBeforeUnmount } from 'vue';
3
+ import type {
4
+ Ui3nScrollbarHorizontalProps,
5
+ Ui3nScrollbarHorizontalEmits,
6
+ Ui3nScrollbarHorizontalSlots,
7
+ Ui3nScrollbarHorizontalExpose,
8
+ } from './types';
9
+
10
+ const MIN_WIDTH = 32;
11
+
12
+ const props = withDefaults(defineProps<Ui3nScrollbarHorizontalProps>(), {
13
+ thumbMinWidth: MIN_WIDTH,
14
+ thumbWidth: 'auto',
15
+ thumbRadius: 4,
16
+ thumbColor: 'var(--color-bg-control-accent-default)',
17
+ thumbHoverColor: 'var(--color-bg-control-accent-hover)',
18
+ thumbActiveColor: 'var(--color-bg-control-accent-focused)',
19
+ trackHeight: 6,
20
+ trackRadius: 4,
21
+ trackColor: 'transparent',
22
+ });
23
+
24
+ const emits = defineEmits<Ui3nScrollbarHorizontalEmits>();
25
+ defineSlots<Ui3nScrollbarHorizontalSlots>();
26
+
27
+ const containerRef = ref<HTMLDivElement | null>(null);
28
+ const trackRef = ref<HTMLDivElement | null>(null);
29
+ const thumbRef = ref<HTMLDivElement | null>(null);
30
+
31
+ const scrollWidth = ref(0);
32
+ const clientWidth = ref(0);
33
+ const scrollLeft = ref(0);
34
+
35
+ const isDragging = ref(false);
36
+ const isHovered = ref(false);
37
+ const isScrollingNow = ref(false);
38
+
39
+ let resizeObserver: ResizeObserver | null = null;
40
+ let scrollTimeout: number | undefined;
41
+ let startX = 0;
42
+ let startScrollLeft = 0;
43
+
44
+ const isScrollable = computed(() => scrollWidth.value > clientWidth.value);
45
+
46
+ const isBarVisible = computed(() => {
47
+ if (isDragging.value) {
48
+ return true;
49
+ }
50
+
51
+ return isScrollable.value && (isHovered.value || isScrollingNow.value);
52
+ });
53
+
54
+ const minWidth = computed(() => {
55
+ const num = Number(props.thumbMinWidth);
56
+ return isNaN(num) ? MIN_WIDTH : num;
57
+ });
58
+
59
+ const thumbWidth = computed(() => {
60
+ if (!scrollWidth.value) {
61
+ return 0;
62
+ }
63
+
64
+ if (props.thumbWidth !== 'auto') {
65
+ const fixedNum = Number(props.thumbWidth);
66
+ return isNaN(fixedNum) ? minWidth.value : fixedNum;
67
+ }
68
+
69
+ const ratio = clientWidth.value / scrollWidth.value;
70
+ const calculated = clientWidth.value * ratio;
71
+ return Math.max(minWidth.value, calculated);
72
+ });
73
+
74
+ const thumbLeft = computed(() => {
75
+ if (!scrollWidth.value || scrollWidth.value === clientWidth.value) {
76
+ return 0;
77
+ }
78
+
79
+ const maxScrollLeft = scrollWidth.value - clientWidth.value;
80
+ const maxThumbLeft = clientWidth.value - thumbWidth.value;
81
+ return (scrollLeft.value / maxScrollLeft) * maxThumbLeft;
82
+ });
83
+
84
+ const thumbRadiusCss = computed(() => {
85
+ const num = Number(props.thumbRadius);
86
+ return isNaN(num) ? String(props.thumbRadius) : `${num}px`;
87
+ });
88
+ const thumbColorCss = computed(() => props.thumbColor);
89
+ const thumbHoverColorCss = computed(() => props.thumbHoverColor);
90
+ const thumbActiveColorCss = computed(() => props.thumbActiveColor);
91
+ const trackHeightCss = computed(() => {
92
+ const num = Number(props.trackHeight);
93
+ return isNaN(num) ? String(props.trackHeight) : `${num}px`;
94
+ });
95
+ const trackRadiusCss = computed(() => {
96
+ const num = Number(props.trackRadius);
97
+ return isNaN(num) ? String(props.trackRadius) : `${num}px`;
98
+ });
99
+ const trackColorCss = computed(() => props.trackColor);
100
+
101
+ function updateMetrics() {
102
+ if (!containerRef.value) {
103
+ return;
104
+ }
105
+
106
+ scrollWidth.value = containerRef.value.scrollWidth;
107
+ clientWidth.value = containerRef.value.clientWidth;
108
+ scrollLeft.value = containerRef.value.scrollLeft;
109
+ }
110
+
111
+ function onScroll(event: Event) {
112
+ if (!isDragging.value) {
113
+ scrollLeft.value = (event.target as HTMLDivElement).scrollLeft;
114
+ }
115
+
116
+ isScrollingNow.value = true;
117
+ window.clearTimeout(scrollTimeout);
118
+
119
+ scrollTimeout = window.setTimeout(() => {
120
+ isScrollingNow.value = false;
121
+ }, 1500);
122
+
123
+ emits('scroll', event);
124
+ }
125
+
126
+ function onTrackClick(e: MouseEvent) {
127
+ if (e.target !== trackRef.value || !containerRef.value || !trackRef.value) {
128
+ return;
129
+ }
130
+
131
+ const trackRect = trackRef.value.getBoundingClientRect();
132
+ const clickX = e.clientX - trackRect.left;
133
+ const targetThumbLeft = clickX - thumbWidth.value / 2;
134
+ const maxScrollLeft = scrollWidth.value - clientWidth.value;
135
+ const maxThumbLeft = clientWidth.value - thumbWidth.value;
136
+
137
+ let targetScrollLeft = (targetThumbLeft / maxThumbLeft) * maxScrollLeft;
138
+ targetScrollLeft = Math.max(0, Math.min(maxScrollLeft, targetScrollLeft));
139
+
140
+ containerRef.value.scrollTo({
141
+ left: targetScrollLeft,
142
+ behavior: 'smooth',
143
+ });
144
+ }
145
+
146
+ function onThumbPointerDown(e: PointerEvent) {
147
+ if (!thumbRef.value || !containerRef.value) {
148
+ return;
149
+ }
150
+
151
+ e.preventDefault();
152
+ e.stopPropagation();
153
+
154
+ thumbRef.value.setPointerCapture(e.pointerId);
155
+
156
+ isDragging.value = true;
157
+ startX = e.clientX;
158
+ startScrollLeft = scrollLeft.value;
159
+
160
+ document.body.style.userSelect = 'none';
161
+
162
+ thumbRef.value.addEventListener('pointermove', onThumbPointerMove);
163
+ thumbRef.value.addEventListener('pointerup', onThumbPointerUp);
164
+ thumbRef.value.addEventListener('pointercancel', onThumbPointerUp);
165
+ }
166
+
167
+ function onThumbPointerMove(e: PointerEvent) {
168
+ if (!isDragging.value || !containerRef.value) {
169
+ return;
170
+ }
171
+
172
+ const deltaX = e.clientX - startX;
173
+ const maxScrollLeft = scrollWidth.value - clientWidth.value;
174
+ const maxThumbLeft = clientWidth.value - thumbWidth.value;
175
+
176
+ const scrollDelta = (deltaX / maxThumbLeft) * maxScrollLeft;
177
+ containerRef.value.scrollLeft = startScrollLeft + scrollDelta;
178
+ scrollLeft.value = containerRef.value.scrollLeft;
179
+ }
180
+
181
+ function onThumbPointerUp(e: PointerEvent) {
182
+ if (!isDragging.value) {
183
+ return;
184
+ }
185
+
186
+ isDragging.value = false;
187
+ document.body.style.userSelect = '';
188
+
189
+ if (thumbRef.value) {
190
+ try {
191
+ thumbRef.value.releasePointerCapture(e.pointerId);
192
+ } catch (err) {}
193
+ thumbRef.value.removeEventListener('pointermove', onThumbPointerMove);
194
+ thumbRef.value.removeEventListener('pointerup', onThumbPointerUp);
195
+ thumbRef.value.removeEventListener('pointercancel', onThumbPointerUp);
196
+ }
197
+ }
198
+
199
+ onMounted(() => {
200
+ updateMetrics();
201
+ if (containerRef.value) {
202
+ resizeObserver = new ResizeObserver(updateMetrics);
203
+ resizeObserver.observe(containerRef.value);
204
+
205
+ if (containerRef.value.firstElementChild) {
206
+ resizeObserver.observe(containerRef.value.firstElementChild);
207
+ }
208
+ }
209
+ });
210
+
211
+ onBeforeUnmount(() => {
212
+ resizeObserver?.disconnect();
213
+ window.clearTimeout(scrollTimeout);
214
+
215
+ if (thumbRef.value) {
216
+ thumbRef.value.removeEventListener('pointermove', onThumbPointerMove);
217
+ thumbRef.value.removeEventListener('pointerup', onThumbPointerUp);
218
+ thumbRef.value.removeEventListener('pointercancel', onThumbPointerUp);
219
+ }
220
+ document.body.style.userSelect = '';
221
+ });
222
+
223
+ defineExpose<Ui3nScrollbarHorizontalExpose>({
224
+ scrollTo: (options: ScrollToOptions) => {
225
+ containerRef.value?.scrollTo(options);
226
+ },
227
+ getContainer: () => containerRef.value!,
228
+ });
229
+ </script>
230
+
231
+ <template>
232
+ <div
233
+ :class="$style.ui3nScrollbarHorizontal"
234
+ :style="{
235
+ '--ui3n-scrollbar-horizontal-thumb-radius': thumbRadiusCss,
236
+ '--ui3n-scrollbar-horizontal-thumb-color': thumbColorCss,
237
+ '--ui3n-scrollbar-horizontal-thumb-hover-color': thumbHoverColorCss,
238
+ '--ui3n-scrollbar-horizontal-thumb-active-color': thumbActiveColorCss,
239
+ '--ui3n-scrollbar-horizontal-track-height': trackHeightCss,
240
+ '--ui3n-scrollbar-horizontal-track-radius': trackRadiusCss,
241
+ '--ui3n-scrollbar-horizontal-track-color': trackColorCss,
242
+ }"
243
+ @mouseenter="isHovered = true"
244
+ @mouseleave="isHovered = false"
245
+ >
246
+ <div
247
+ ref="containerRef"
248
+ :class="$style.scrollbarContainer"
249
+ @scroll="onScroll"
250
+ >
251
+ <slot />
252
+ </div>
253
+
254
+ <div
255
+ ref="trackRef"
256
+ :class="[$style.track, { [$style.trackVisible]: isBarVisible }]"
257
+ @mousedown="onTrackClick"
258
+ >
259
+ <div
260
+ ref="thumbRef"
261
+ :class="[$style.thumb, { [$style.active]: isDragging }]"
262
+ :style="{
263
+ width: `${thumbWidth}px`,
264
+ transform: `translateX(${thumbLeft}px)`,
265
+ }"
266
+ @pointerdown="onThumbPointerDown"
267
+ />
268
+ </div>
269
+ </div>
270
+ </template>
271
+
272
+ <style lang="scss" module>
273
+ .ui3nScrollbarHorizontal {
274
+ position: relative;
275
+ width: 100%;
276
+ height: 100%;
277
+ overflow: hidden;
278
+ }
279
+
280
+ .scrollbarContainer {
281
+ position: relative;
282
+ width: 100%;
283
+ height: 100%;
284
+ overflow-x: auto;
285
+ overflow-y: hidden;
286
+ scrollbar-width: none;
287
+
288
+ &::-webkit-scrollbar {
289
+ display: none !important;
290
+ width: 0 !important;
291
+ height: 0 !important;
292
+ }
293
+ }
294
+
295
+ .track {
296
+ position: absolute;
297
+ left: 0;
298
+ right: 0;
299
+ bottom: 2px;
300
+ height: var(--ui3n-scrollbar-horizontal-track-height);
301
+ background: var(--ui3n-scrollbar-horizontal-track-color);
302
+ border-radius: var(--ui3n-scrollbar-horizontal-track-radius);
303
+ z-index: 10;
304
+ visibility: hidden;
305
+ opacity: 0;
306
+ pointer-events: none;
307
+ transition:
308
+ opacity 0.3s ease,
309
+ visibility 0.3s ease;
310
+ }
311
+
312
+ .trackVisible {
313
+ visibility: visible;
314
+ opacity: 1;
315
+ pointer-events: auto;
316
+ }
317
+
318
+ .thumb {
319
+ position: absolute;
320
+ top: 0;
321
+ height: 100%;
322
+ border-radius: var(--ui3n-scrollbar-horizontal-thumb-radius);
323
+ background-color: var(--ui3n-scrollbar-horizontal-thumb-color);
324
+ cursor: pointer;
325
+ transition: background-color 0.15s ease;
326
+ touch-action: none;
327
+
328
+ &:hover {
329
+ background-color: var(--ui3n-scrollbar-horizontal-thumb-hover-color);
330
+ }
331
+
332
+ &:active,
333
+ &.active {
334
+ background-color: var(--ui3n-scrollbar-horizontal-thumb-active-color);
335
+ }
336
+ }
337
+ </style>
@@ -0,0 +1,38 @@
1
+ import type { VNode } from 'vue';
2
+
3
+ /**
4
+ * ScrollbarVertical component properties
5
+ */
6
+ export interface Ui3nScrollbarVerticalProps {
7
+ thumbMinHeight?: number | string;
8
+ thumbHeight?: number | string | 'auto';
9
+ thumbRadius?: number | string;
10
+ thumbColor?: string;
11
+ thumbHoverColor?: string;
12
+ thumbActiveColor?: string;
13
+ trackWidth?: number;
14
+ trackRadius?: number | string;
15
+ trackColor?: string;
16
+ }
17
+
18
+ /**
19
+ * ScrollbarVertical component emits
20
+ */
21
+ export interface Ui3nScrollbarVerticalEmits {
22
+ (ev: 'scroll', value: Event): void;
23
+ }
24
+
25
+ /**
26
+ * ScrollbarVertical component slots
27
+ */
28
+ export interface Ui3nScrollbarVerticalSlots {
29
+ /**
30
+ * Default slot
31
+ */
32
+ default: () => VNode;
33
+ }
34
+
35
+ export interface Ui3nScrollbarVerticalExpose {
36
+ scrollTo(options: ScrollToOptions): void;
37
+ getContainer(): HTMLDivElement;
38
+ }