@veritree/ui 0.27.0 → 0.28.0-1

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 (116) hide show
  1. package/.claude/settings.local.json +10 -0
  2. package/index.js +105 -75
  3. package/mixins/floating-ui-content.js +17 -4
  4. package/mixins/floating-ui-item.js +31 -15
  5. package/mixins/floating-ui.js +142 -24
  6. package/mixins/form-control-icon.js +3 -3
  7. package/mixins/form-control.js +45 -20
  8. package/nuxt.js +38 -26
  9. package/package.json +17 -6
  10. package/src/components/Alert/VTAlert.vue +55 -14
  11. package/src/components/Avatar/VTAvatarImage.vue +6 -26
  12. package/src/components/Badge/VTBadge.vue +60 -0
  13. package/src/components/Badge/VTBadgeNew.vue +60 -0
  14. package/src/components/Breadcrumb/VTBreadcrumbItem.vue +11 -0
  15. package/src/components/Breadcrumb/VTBreadcrumbLink.vue +40 -0
  16. package/src/components/Breadcrumb/VTBreadcrumbList.vue +11 -0
  17. package/src/components/Breadcrumb/VTBreadcrumbRoot.vue +11 -0
  18. package/src/components/Breadcrumb/VTBreadcrumbSeparator.vue +19 -0
  19. package/src/components/Button/VTButton.vue +104 -56
  20. package/src/components/Carousel/VTCarousel.vue +69 -0
  21. package/src/components/Carousel/VTCarouselBackward.vue +36 -0
  22. package/src/components/Carousel/VTCarouselForward.vue +38 -0
  23. package/src/components/Carousel/VTCarouselTracker.vue +80 -0
  24. package/src/components/Checkbox/VTCheckbox.vue +134 -0
  25. package/src/components/Checkbox/VTCheckboxLabel.vue +3 -0
  26. package/src/components/Checkbox/VTCheckboxText.vue +20 -0
  27. package/src/components/Chip/VTChip.vue +29 -0
  28. package/src/components/Dialog/VTDialog.vue +59 -25
  29. package/src/components/Dialog/VTDialogClose.vue +3 -2
  30. package/src/components/Dialog/VTDialogContent.vue +29 -7
  31. package/src/components/Dialog/VTDialogFooter.vue +17 -2
  32. package/src/components/Dialog/VTDialogHeader.vue +2 -1
  33. package/src/components/Dialog/VTDialogMain.vue +5 -1
  34. package/src/components/Dialog/VTDialogOverlay.vue +5 -1
  35. package/src/components/Dialog/VTDialogTitle.vue +1 -1
  36. package/src/components/Disclosure/VTDisclosure.vue +2 -11
  37. package/src/components/Disclosure/VTDisclosureContent.vue +26 -52
  38. package/src/components/Disclosure/VTDisclosureDetails.vue +27 -2
  39. package/src/components/Disclosure/VTDisclosureHeader.vue +56 -89
  40. package/src/components/Disclosure/VTDisclosureIcon.vue +42 -31
  41. package/src/components/Divider/VTDivider.vue +9 -0
  42. package/src/components/Drawer/VTDrawer.vue +6 -15
  43. package/src/components/Drawer/VTDrawerClose.vue +5 -5
  44. package/src/components/Drawer/VTDrawerContent.vue +10 -10
  45. package/src/components/Drawer/VTDrawerFooter.vue +4 -4
  46. package/src/components/Drawer/VTDrawerHeader.vue +4 -4
  47. package/src/components/Drawer/VTDrawerMain.vue +5 -5
  48. package/src/components/Drawer/VTDrawerOverlay.vue +6 -6
  49. package/src/components/Drawer/VTDrawerTitle.vue +5 -5
  50. package/src/components/DropdownMenu/VTDropdownMenu.vue +0 -6
  51. package/src/components/DropdownMenu/VTDropdownMenuContent.vue +10 -1
  52. package/src/components/DropdownMenu/VTDropdownMenuDivider.vue +7 -16
  53. package/src/components/DropdownMenu/VTDropdownMenuItem.vue +5 -1
  54. package/src/components/DropdownMenu/VTDropdownMenuLabel.vue +1 -10
  55. package/src/components/DropdownMenu/VTDropdownMenuTrigger.vue +2 -4
  56. package/src/components/Form/VTFieldset.vue +5 -0
  57. package/src/components/Form/VTForm.vue +11 -0
  58. package/src/components/Form/VTFormCol.vue +20 -0
  59. package/src/components/Form/VTFormFeedback.vue +7 -1
  60. package/src/components/Form/VTFormGroup.vue +5 -7
  61. package/src/components/Form/VTFormLabel.vue +22 -0
  62. package/src/components/Form/VTFormLabelHelper.vue +22 -0
  63. package/src/components/Form/VTFormRow.vue +5 -0
  64. package/src/components/Form/VTInput.vue +2 -5
  65. package/src/components/Form/VTInputDate.vue +602 -0
  66. package/src/components/Form/VTInputIcon.vue +3 -9
  67. package/src/components/Form/VTInputNumber.vue +198 -0
  68. package/src/components/Form/VTInputPassword.vue +14 -5
  69. package/src/components/Form/VTInputRange.vue +92 -0
  70. package/src/components/Form/VTLegend.vue +24 -0
  71. package/src/components/Form/VTTextarea.vue +2 -2
  72. package/src/components/Image/VTImage.vue +10 -10
  73. package/src/components/Listbox/VTListbox.vue +128 -9
  74. package/src/components/Listbox/VTListboxContent.vue +14 -1
  75. package/src/components/Listbox/VTListboxDivider.vue +21 -0
  76. package/src/components/Listbox/VTListboxGroup.vue +9 -0
  77. package/src/components/Listbox/VTListboxItem.vue +57 -15
  78. package/src/components/Listbox/VTListboxLabel.vue +5 -4
  79. package/src/components/Listbox/VTListboxList.vue +1 -6
  80. package/src/components/Listbox/VTListboxPlaceholder.vue +25 -0
  81. package/src/components/Listbox/VTListboxSearch.vue +12 -8
  82. package/src/components/Listbox/VTListboxTrigger.vue +87 -6
  83. package/src/components/Listbox/VTListboxTriggerHighlight.vue +204 -0
  84. package/src/components/Listbox/VTListboxViewport.vue +33 -0
  85. package/src/components/Popover/VTPopoverContent.vue +3 -3
  86. package/src/components/Popover/VTPopoverDivider.vue +1 -1
  87. package/src/components/Popover/VTPopoverItem.vue +6 -2
  88. package/src/components/ProgressBar/VTProgressBar.vue +35 -10
  89. package/src/components/ProgressBar/VTProgressBarIndicator.vue +53 -0
  90. package/src/components/ScrollShadows/VTScrollShadows.vue +76 -0
  91. package/src/components/Separator/VTSeparator.vue +13 -0
  92. package/src/components/Switch/VTSwitch.vue +61 -0
  93. package/src/components/Tabs/VTTab.vue +6 -5
  94. package/src/components/Tabs/VTTabGroup.vue +88 -9
  95. package/src/components/Tabs/VTTabPanel.vue +4 -5
  96. package/src/components/Toast/README.md +263 -0
  97. package/src/components/Toast/VTToast.vue +145 -0
  98. package/src/components/Toast/VTToastAction.vue +25 -0
  99. package/src/components/Toast/VTToastClose.vue +52 -0
  100. package/src/components/Toast/VTToastContent.vue +25 -0
  101. package/src/components/Toast/VTToastDescription.vue +36 -0
  102. package/src/components/Toast/VTToastIcon.vue +72 -0
  103. package/src/components/Toast/VTToastItem.vue +180 -0
  104. package/src/components/Toast/VTToastTitle.vue +34 -0
  105. package/src/components/Tooltip/VTTooltipTrigger.vue +3 -5
  106. package/src/components/Transitions/FadeInOut.vue +2 -2
  107. package/src/components/Utils/FloatingUi.vue +31 -13
  108. package/src/helpers/currency.js +21 -0
  109. package/src/utils/components.js +18 -0
  110. package/src/utils/images.js +31 -12
  111. package/src/components/Input/VTInput.vue +0 -82
  112. package/src/components/Input/VTInputDate.vue +0 -36
  113. package/src/components/Input/VTInputFile.vue +0 -60
  114. package/src/components/Input/VTInputUpload.vue +0 -54
  115. package/src/components/Modal/VTModal.vue +0 -69
  116. package/src/utils/genId.js +0 -13
@@ -3,22 +3,21 @@
3
3
  :class="[
4
4
  headless
5
5
  ? 'progress-bar'
6
- : 'relative min-h-[10px] w-full overflow-hidden rounded-full bg-gray-200',
6
+ : 'relative min-h-[12px] w-full flex items-stretch overflow-hidden rounded bg-gray-200',
7
7
  ]"
8
8
  role="progressbar"
9
9
  aria-valuemin="0"
10
- aria-valuemax="100"
10
+ :aria-valuemax="max"
11
11
  :aria-valuenow="value"
12
12
  :aria-label="label"
13
13
  >
14
- <div
15
- :class="[
16
- headless
17
- ? 'progress-bar__indicator'
18
- : 'absolute left-0 h-full bg-secondary-300 transition-all',
19
- ]"
20
- :style="{ width: `${value}%` }"
21
- ></div>
14
+ <slot>
15
+ <VTProgressBarIndicator
16
+ :headless="headless"
17
+ :percentage="percentageComputed"
18
+ :variant="variant"
19
+ />
20
+ </slot>
22
21
  </div>
23
22
  </template>
24
23
 
@@ -37,6 +36,32 @@ export default {
37
36
  type: [String, Number],
38
37
  default: 0,
39
38
  },
39
+ max: {
40
+ type: [String, Number],
41
+ default: 100,
42
+ },
43
+ percentage: {
44
+ type: [String, Number],
45
+ default: null,
46
+ },
47
+ rounded: {
48
+ type: String,
49
+ default: 'rounded-full',
50
+ },
51
+ variant: {
52
+ type: String,
53
+ default: 'default',
54
+ },
55
+ },
56
+
57
+ computed: {
58
+ percentageComputed() {
59
+ if (typeof this.percentage !== 'undefined' && this.percentage !== null) {
60
+ return this.percentage;
61
+ }
62
+
63
+ return (this.value / this.max) * 100;
64
+ },
40
65
  },
41
66
  };
42
67
  </script>
@@ -0,0 +1,53 @@
1
+ <template>
2
+ <div
3
+ :class="[
4
+ headless
5
+ ? 'progress-bar__indicator'
6
+ : `${backgroundComputed} min-h-min transition-all duration-500`,
7
+ ]"
8
+ :style="{ width: `${percentage}%` }"
9
+ ></div>
10
+ </template>
11
+
12
+ <script>
13
+ export default {
14
+ name: 'VTProgressBarIndicator',
15
+
16
+ props: {
17
+ headless: {
18
+ type: Boolean,
19
+ default: false,
20
+ },
21
+ percentage: {
22
+ type: [String, Number],
23
+ default: null,
24
+ },
25
+ variant: {
26
+ type: String,
27
+ default: 'default',
28
+ },
29
+ },
30
+
31
+ computed: {
32
+ backgroundComputed() {
33
+ if (this.variant === 'default') {
34
+ return 'bg-secondary-300';
35
+ }
36
+
37
+ if (this.variant === 'error') {
38
+ return 'bg-error-500';
39
+ }
40
+
41
+ if (this.variant === 'warning') {
42
+ return 'bg-warning-500';
43
+ }
44
+
45
+ if (this.variant === 'dark') {
46
+ return 'bg-gray-800';
47
+ }
48
+
49
+ return 'bg-secondary-300';
50
+ },
51
+ },
52
+ };
53
+ </script>
@@ -0,0 +1,76 @@
1
+ <template>
2
+ <component :is="tag" :class="`scroll-shadows-${orientation}`">
3
+ <slot></slot>
4
+ </component>
5
+ </template>
6
+
7
+ <script>
8
+ export default {
9
+ name: 'VTScrollShadows',
10
+
11
+ props: {
12
+ tag: {
13
+ type: String,
14
+ default: 'div',
15
+ },
16
+ orientation: {
17
+ type: String,
18
+ default: 'vertical', // horizontal
19
+ },
20
+ },
21
+ };
22
+ </script>
23
+
24
+ <style scoped>
25
+ .scroll-shadows-vertical {
26
+ background:
27
+ /* Shadow Cover TOP */
28
+ linear-gradient(white 30%, rgba(255, 255, 255, 0)) center top,
29
+ /* Shadow Cover BOTTOM */ linear-gradient(rgba(255, 255, 255, 0), white 70%)
30
+ center bottom,
31
+ /* Shadow TOP */
32
+ radial-gradient(
33
+ farthest-side at 50% 0,
34
+ rgba(0, 0, 0, 0.1),
35
+ rgba(0, 0, 0, 0)
36
+ )
37
+ center top,
38
+ /* Shadow BOTTOM */
39
+ radial-gradient(
40
+ farthest-side at 50% 100%,
41
+ rgba(0, 0, 0, 0.1),
42
+ rgba(0, 0, 0, 0)
43
+ )
44
+ center bottom;
45
+
46
+ background-repeat: no-repeat;
47
+ background-size:
48
+ 100% 30px,
49
+ 100% 30px,
50
+ 100% 8px,
51
+ 100% 8px;
52
+ background-attachment: local, local, scroll, scroll;
53
+ }
54
+
55
+ .scroll-shadows-horizontal {
56
+ background:
57
+ linear-gradient(90deg, white 30%, rgba(255, 255, 255, 0)),
58
+ linear-gradient(90deg, rgba(255, 255, 255, 0), white 70%) 0 100%,
59
+ radial-gradient(farthest-side at 0% 50%, rgba(0, 0, 0, 0.2), white),
60
+ radial-gradient(farthest-side at 100% 50%, rgba(0, 0, 0, 0.2), white) 0 100%;
61
+
62
+ background-repeat: no-repeat;
63
+ background-color: white;
64
+ background-position:
65
+ top left,
66
+ top right,
67
+ top left,
68
+ top right;
69
+ background-size:
70
+ 10px 100%,
71
+ 10px 100%,
72
+ 5px 100%,
73
+ 5px 100%;
74
+ background-attachment: local, local, scroll, scroll;
75
+ }
76
+ </style>
@@ -0,0 +1,13 @@
1
+ <template>
2
+ <div
3
+ class="h-px bg-border bg-gray-200 shrink-0 w-full"
4
+ data-orientation="horizontal"
5
+ role="separator"
6
+ />
7
+ </template>
8
+
9
+ <script>
10
+ export default {
11
+ name: 'VTSeparator',
12
+ };
13
+ </script>
@@ -0,0 +1,61 @@
1
+ <template>
2
+ <div class="relative flex w-11 h-6 px-0.5 items-center">
3
+ <input
4
+ ref="input"
5
+ :id="id"
6
+ :checked="checkedComputed"
7
+ :disabled="disabled"
8
+ :value="valueComputed"
9
+ class="absolute inset-0 appearance-none peer rounded-full transition-colors bg-gray-400 checked:bg-secondary-300 disabled:bg-gray-200"
10
+ role="switch"
11
+ type="checkbox"
12
+ @change="onChange"
13
+ />
14
+ <span
15
+ class="size-5 rounded-full bg-white transition-transform translate-x-0 peer-checked:translate-x-full pointer-events-none peer-disabled:bg-gray-400"
16
+ />
17
+ </div>
18
+ </template>
19
+
20
+ <script>
21
+ export default {
22
+ name: 'VTSwitch',
23
+
24
+ props: {
25
+ id: {
26
+ type: String,
27
+ default: null,
28
+ },
29
+ disabled: {
30
+ type: Boolean,
31
+ default: null,
32
+ },
33
+ modelValue: {
34
+ type: [Array, Boolean, Number, String],
35
+ default: false,
36
+ },
37
+ },
38
+
39
+ computed: {
40
+ checkedComputed() {
41
+ return this.modelValue;
42
+ },
43
+
44
+ valueComputed: {
45
+ get() {
46
+ return this.modelValue;
47
+ },
48
+ set(newVal) {
49
+ this.$emit('update:modelValue', newVal);
50
+ },
51
+ },
52
+ },
53
+
54
+ methods: {
55
+ onChange(event) {
56
+ this.valueComputed = !Boolean(this.valueComputed);
57
+ this.$emit('change', event);
58
+ },
59
+ },
60
+ };
61
+ </script>
@@ -18,11 +18,11 @@
18
18
  ]"
19
19
  role="tab"
20
20
  type="button"
21
- @click.stop="onClick"
21
+ @click.prevent.stop="onClick"
22
22
  @keydown="onKeyDown"
23
23
  @blur="onBlur"
24
24
  >
25
- <slot></slot>
25
+ <slot :selected="selected"></slot>
26
26
  </button>
27
27
  </template>
28
28
 
@@ -32,7 +32,7 @@ import { keys } from '../../utils/keyboard';
32
32
  export default {
33
33
  name: 'VTTabItem',
34
34
 
35
- inject: ['api'],
35
+ inject: ['apiTabs'],
36
36
 
37
37
  props: {
38
38
  headless: {
@@ -43,7 +43,7 @@ export default {
43
43
 
44
44
  data() {
45
45
  return {
46
- api: this.api(),
46
+ api: this.apiTabs(),
47
47
  index: null,
48
48
  indexFocus: null,
49
49
  selected: false,
@@ -60,7 +60,7 @@ export default {
60
60
  this.api.registerTab(this);
61
61
  },
62
62
 
63
- beforeDestroy() {
63
+ beforeUnmount() {
64
64
  this.api.unregisterTab(this.index);
65
65
  },
66
66
 
@@ -106,6 +106,7 @@ export default {
106
106
  onClick() {
107
107
  this.api.selectTab(this.index);
108
108
  this.$emit('change');
109
+ this.$emit('click');
109
110
  },
110
111
 
111
112
  onKeyDown(event) {
@@ -5,10 +5,10 @@
5
5
  </template>
6
6
 
7
7
  <style scoped>
8
- .TabGroup.vertical{
8
+ .TabGroup.vertical {
9
9
  display: flex;
10
10
  }
11
- .TabGroup.vertical .TabList{
11
+ .TabGroup.vertical .TabList {
12
12
  display: flex;
13
13
  flex-direction: column;
14
14
  }
@@ -17,29 +17,87 @@
17
17
  <script>
18
18
  export default {
19
19
  name: 'VTTabGroup',
20
+
20
21
  props: {
21
- vertical: {
22
- type: Boolean,
23
- default: false
24
- }
22
+ activeIndex: {
23
+ type: Number,
24
+ default: null,
25
+ },
26
+ vertical: {
27
+ type: Boolean,
28
+ default: false,
29
+ },
25
30
  },
31
+
26
32
  provide() {
27
33
  return {
28
- api: () => {
34
+ apiTabs: () => {
35
+ /**
36
+ * Registers a tab.
37
+ * This function adds a tab to the list of tabs managed by the provider.
38
+ * If there is an active index set, it checks if the newly registered tab matches the active index,
39
+ * and if so, selects the tab.
40
+ * If no active index is set, it selects the tab if its index is 0.
41
+ * @param {VueComponent} tab - The tab to register.
42
+ * @returns {void}
43
+ */
29
44
  const registerTab = (tab) => {
30
45
  _register(this.tabs, tab);
31
- if (tab.index === 0) tab.select();
46
+
47
+ if (this.activeIndex) {
48
+ if (tab.index === this.activeIndex) {
49
+ tab.select();
50
+ }
51
+
52
+ return;
53
+ }
54
+
55
+ if (tab.index === 0) {
56
+ tab.select();
57
+ }
32
58
  };
33
59
 
60
+ /**
61
+ * Registers a tab panel.
62
+ * This function adds a tab panel to the list of tab panels managed by the provider.
63
+ * If there is an active index set, it checks if the newly registered tab panel matches the active index,
64
+ * and if so, shows the tab panel.
65
+ * If no active index is set, it shows the tab panel if its index is 0.
66
+ * @param {VueComponent} tabPanel - The tab panel to register.
67
+ * @returns {void}
68
+ */
34
69
  const registerTabPanel = (tabPanel) => {
35
70
  _register(this.tabPanels, tabPanel);
36
- if (tabPanel.index === 0) tabPanel.show();
71
+
72
+ if (this.activeIndex) {
73
+ if (tabPanel.index === this.activeIndex) {
74
+ tabPanel.show();
75
+ }
76
+
77
+ return;
78
+ }
79
+
80
+ if (tabPanel.index === 0) {
81
+ tabPanel.show();
82
+ }
37
83
  };
38
84
 
85
+ /**
86
+ * Unregisters a tab.
87
+ * This function removes a tab from the list of tabs managed by the provider.
88
+ * @param {string} id - The ID of the tab to unregister.
89
+ * @returns {void}
90
+ */
39
91
  const unregisterTab = (id) => {
40
92
  _unregister(this.tabs, id);
41
93
  };
42
94
 
95
+ /**
96
+ * Unregisters a tab panel.
97
+ * This function removes a tab panel from the list of tab panels managed by the provider.
98
+ * @param {string} id - The ID of the tab panel to unregister.
99
+ * @returns {void}
100
+ */
43
101
  const unregisterTabPanel = (id) => {
44
102
  _unregister(this.tabPanels, id);
45
103
  };
@@ -111,5 +169,26 @@ export default {
111
169
  return this.tabs.length;
112
170
  },
113
171
  },
172
+
173
+ watch: {
174
+ activeIndex(newVal, oldVal) {
175
+ const newTab = this.tabs.find((tab) => tab.index === newVal);
176
+ const newTabPanel = this.tabPanels.find(
177
+ (tabPanel) => tabPanel.index === newVal
178
+ );
179
+ const oldTab = this.tabs.find((tab) => tab.index === oldVal);
180
+ const oldTabPanel = this.tabPanels.find(
181
+ (tabPanel) => tabPanel.index === oldVal
182
+ );
183
+
184
+ if (newTab && newTabPanel && oldTab && oldTabPanel) {
185
+ oldTab.unselect();
186
+ oldTabPanel.hide();
187
+
188
+ newTab.select();
189
+ newTabPanel.show();
190
+ }
191
+ },
192
+ },
114
193
  };
115
194
  </script>
@@ -14,11 +14,10 @@
14
14
  export default {
15
15
  name: 'VTTabPanel',
16
16
 
17
- inject: ['api'],
17
+ inject: ['apiTabs'],
18
18
 
19
19
  data() {
20
20
  return {
21
- api: this.api(),
22
21
  index: null,
23
22
  visible: false,
24
23
  };
@@ -31,11 +30,11 @@ export default {
31
30
  },
32
31
 
33
32
  mounted() {
34
- this.api.registerTabPanel(this);
33
+ this.apiTabs().registerTabPanel(this);
35
34
  },
36
35
 
37
- beforeDestroy() {
38
- this.api.unregisterTabPanel(this.id);
36
+ beforeUnmount() {
37
+ this.apiTabs().unregisterTabPanel(this.id);
39
38
  },
40
39
 
41
40
  methods: {