@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
@@ -1,9 +1,4 @@
1
1
  export const formControlMixin = {
2
- model: {
3
- prop: 'value',
4
- event: 'input',
5
- },
6
-
7
2
  props: {
8
3
  disabled: {
9
4
  type: Boolean,
@@ -13,41 +8,61 @@ export const formControlMixin = {
13
8
  type: Boolean,
14
9
  default: false,
15
10
  },
16
- value: {
17
- type: [String, Number, Object, Array],
11
+ modelValue: {
12
+ type: [String, Number, Object, Array, Date],
18
13
  default: null,
19
14
  },
20
15
  variant: {
21
16
  type: [String, Object, Function],
22
17
  default: '',
23
18
  },
19
+
20
+ /**
21
+ * Specifies the size of the button
22
+ *
23
+ * @values
24
+ * - 'small': A smaller size for the button
25
+ * - 'large': A larger size for the button
26
+ */
27
+ size: {
28
+ type: String,
29
+ default: 'large',
30
+ },
31
+ min: {
32
+ type: [String, Number],
33
+ default: null,
34
+ },
24
35
  },
25
36
 
26
37
  computed: {
27
- listeners() {
38
+ attrsComputed() {
28
39
  // `Object.assign` merges objects together to form a new object
29
40
  return Object.assign(
30
41
  {},
31
42
  // We add all the listeners from the parent
32
- this.$listeners,
43
+ this.$attrs,
33
44
  // Then we can add custom listeners or override the
34
45
  // behavior of some listeners.
35
46
  {
36
47
  // This ensures that the component works with v-model
37
- input: (event) => {
48
+ onInput: (event) => {
38
49
  // if (this.lazy) return;
39
- this.$emit('input', event.target.value);
50
+ this.$emit('update:modelValue', event.target.value);
40
51
  },
41
- blur: (event) => {
52
+ onBlur: (event) => {
42
53
  this.$emit('blur', event);
43
54
  },
44
- }
55
+ },
45
56
  );
46
57
  },
47
58
 
48
59
  isError() {
49
60
  return this.variant === 'error';
50
61
  },
62
+
63
+ isSuccess() {
64
+ return this.variant === 'success';
65
+ },
51
66
  },
52
67
  };
53
68
 
@@ -56,20 +71,30 @@ export const formControlStyleMixin = {
56
71
  classComputed() {
57
72
  return [
58
73
  this.headless
59
- ? `${this.name}`
60
- : 'leading-0 flex w-full max-w-full appearance-none items-center justify-between rounded border border-solid px-3 py-2 font-inherit text-base text-inherit file:hidden focus:border-secondary-200',
74
+ ? `${this.name ? this.name : ''}`
75
+ : 'leading-0 bg-white has-[:disabled]:bg-gray-200 disabled:bg-gray-200 flex w-full max-w-full relative appearance-none placeholder:font-light placeholder:text-gray-500 items-center justify-between rounded border border-solid px-3 py-2 font-inherit text-inherit file:hidden focus-within:border-gray-600 focus:border-gray-600 focus-within:placeholder:text-gray-400 focus:placeholder:text-gray-400 has-[:disabled]:text-gray-500 disabled:text-gray-500',
61
76
  // variant styles
62
77
  this.headless
63
- ? `${this.name}--${this.variant}`
78
+ ? `${this.name ? this.name : ''}${this.variant ? '--' + this.variant : ''}`
64
79
  : this.isError
65
- ? 'border-error-300'
66
- : 'border-gray-300',
80
+ ? 'border-error-300'
81
+ : this.isSuccess
82
+ ? 'border-success-300'
83
+ : 'border-gray-300',
67
84
  // height styles
68
85
  this.headless
69
86
  ? null
70
87
  : this.name === 'textarea'
71
- ? 'min-h-10' // limit it because input type number height can be different from other input types
72
- : 'h-10',
88
+ ? 'min-h-10' // limit it because input type number height can be different from other input types
89
+ : this.size === 'small'
90
+ ? 'h-8 text-sm'
91
+ : 'h-10 text-base',
92
+ // disabled styles
93
+ this.disabled
94
+ ? this.headless
95
+ ? `${this.name}--disabled`
96
+ : null
97
+ : null,
73
98
  ];
74
99
  },
75
100
  },
package/nuxt.js CHANGED
@@ -1,29 +1,41 @@
1
- import { join } from 'path';
1
+ import { defineNuxtModule } from '@nuxt/kit';
2
+ import { fileURLToPath } from 'node:url';
2
3
 
3
4
  const components = [
4
- 'src/components/Alert',
5
- 'src/components/Avatar',
6
- 'src/components/Button',
7
- 'src/components/Drawer',
8
- 'src/components/Dialog',
9
- 'src/components/Disclosure',
10
- 'src/components/DropdownMenu',
11
- 'src/components/Form',
12
- 'src/components/Listbox',
13
- 'src/components/Image',
14
- 'src/components/Popover',
15
- 'src/components/ProgressBar',
16
- 'src/components/Skeleton',
17
- 'src/components/Spinner',
18
- 'src/components/Tabs',
19
- 'src/components/Tooltip',
20
- ]
5
+ './src/components/Alert',
6
+ './src/components/Avatar',
7
+ './src/components/Badge',
8
+ './src/components/Breadcrumb',
9
+ './src/components/Button',
10
+ './src/components/Carousel',
11
+ './src/components/Checkbox',
12
+ './src/components/Chip',
13
+ './src/components/Dialog',
14
+ './src/components/Disclosure',
15
+ './src/components/Divider',
16
+ './src/components/Drawer',
17
+ './src/components/DropdownMenu',
18
+ './src/components/Form',
19
+ './src/components/Image',
20
+ './src/components/Listbox',
21
+ './src/components/Popover',
22
+ './src/components/ProgressBar',
23
+ './src/components/ScrollShadows',
24
+ './src/components/Separator',
25
+ './src/components/Skeleton',
26
+ './src/components/Switch',
27
+ './src/components/Tabs',
28
+ './src/components/Tooltip',
29
+ ];
21
30
 
22
- export default function () {
23
- this.nuxt.hook('components:dirs', dirs => {
24
- // Add ./components dir to the list
25
- components.forEach((component) => {
26
- dirs.push(join(__dirname, component))
27
- });
28
- })
29
- }
31
+ export default defineNuxtModule({
32
+ hooks: {
33
+ 'components:dirs'(dirs) {
34
+ components.forEach((component) => {
35
+ dirs.push({
36
+ path: fileURLToPath(new URL(component, import.meta.url)),
37
+ });
38
+ });
39
+ },
40
+ },
41
+ });
package/package.json CHANGED
@@ -1,23 +1,34 @@
1
1
  {
2
2
  "name": "@veritree/ui",
3
- "version": "0.27.0",
3
+ "version": "0.28.0-1",
4
4
  "description": "veritree ui library",
5
5
  "type": "module",
6
6
  "main": "index.js",
7
7
  "repository": "https://github.com/tentree-org/veritree-ui.git",
8
- "author": "cyroveritree <cyro@veritree.com>",
8
+ "author": "jb",
9
9
  "license": "MIT",
10
10
  "publishConfig": {
11
- "access": "public"
11
+ "registry": "https://registry.npmjs.org"
12
+ },
13
+ "scripts": {
14
+ "release": "np --no-tests --no-2fa --branch=next",
15
+ "release-v2": "yarn publish && yarn push-tag",
16
+ "push-tag": "git push origin v$(node -p \"require('./package.json').version\")"
12
17
  },
13
18
  "dependencies": {
14
- "@floating-ui/dom": "^1.0.4",
15
- "@linusborg/vue-simple-portal": "^0.1.5",
16
- "@veritree/icons": "^0.39.0"
19
+ "@floating-ui/dom": "^1.4.5",
20
+ "@internationalized/date": "^3.12.0",
21
+ "reka-ui": "^2.9.2"
17
22
  },
18
23
  "devDependencies": {
24
+ "@nuxt/kit": "^4.4.2",
25
+ "np": "^8.0.4",
19
26
  "prettier": "^2.7.1",
20
27
  "prettier-plugin-tailwindcss": "^0.1.13",
21
28
  "tailwindcss": "^3.2.4"
29
+ },
30
+ "engines": {
31
+ "npm": ">=8.0.0",
32
+ "node": ">=18.0.0"
22
33
  }
23
34
  }
@@ -1,11 +1,9 @@
1
1
  <template>
2
2
  <div
3
- v-if="show"
3
+ v-if="isVisible"
4
4
  :class="[
5
5
  // default styles
6
- headless
7
- ? 'alert'
8
- : 'flex items-start gap-3 rounded border border-solid p-3',
6
+ headless ? 'alert' : 'flex items-start gap-3 rounded border border-solid',
9
7
  // variant styles
10
8
  headless
11
9
  ? `alert--${variant}`
@@ -16,6 +14,14 @@
16
14
  : isWarning
17
15
  ? 'border-warning-300 bg-warning-200 text-warning-700'
18
16
  : null,
17
+ // sizes styles
18
+ headless
19
+ ? `alert--${size}`
20
+ : isLarge
21
+ ? 'p-3'
22
+ : isSmall
23
+ ? 'py-1 px-2 text-sm'
24
+ : null,
19
25
  ]"
20
26
  role="alert"
21
27
  >
@@ -23,9 +29,15 @@
23
29
  <button
24
30
  v-if="dismissable"
25
31
  :class="[
26
- !headless
27
- ? 'ml-auto mt-1 h-4 w-4 shrink-0 text-current'
28
- : 'alert-close',
32
+ // default styles
33
+ headless ? 'alert-close' : 'ml-auto h-4 w-4 shrink-0 text-current',
34
+ headless
35
+ ? `alert-close--${variant}`
36
+ : isLarge
37
+ ? 'mt-1'
38
+ : isSmall
39
+ ? 'mt-0.5'
40
+ : null,
29
41
  ]"
30
42
  @click="hide"
31
43
  >
@@ -35,14 +47,30 @@
35
47
  </template>
36
48
 
37
49
  <script>
50
+ import IconClose from '@veritree/icons/src/components/IconClose.vue';
51
+
38
52
  export default {
39
53
  name: 'VTAlert',
40
54
 
55
+ components: {
56
+ IconClose,
57
+ },
58
+
59
+ data() {
60
+ return {
61
+ modelValueLocal: true,
62
+ };
63
+ },
64
+
41
65
  props: {
42
66
  variant: {
43
67
  type: String,
44
68
  default: 'success',
45
69
  },
70
+ size: {
71
+ type: String,
72
+ default: 'large',
73
+ },
46
74
  headless: {
47
75
  type: Boolean,
48
76
  default: false,
@@ -51,12 +79,10 @@ export default {
51
79
  type: Boolean,
52
80
  default: false,
53
81
  },
54
- },
55
-
56
- data() {
57
- return {
58
- show: true,
59
- };
82
+ modelValue: {
83
+ type: Boolean,
84
+ default: null,
85
+ },
60
86
  },
61
87
 
62
88
  computed: {
@@ -71,12 +97,27 @@ export default {
71
97
  isWarning() {
72
98
  return this.variant === 'warning';
73
99
  },
100
+
101
+ isLarge() {
102
+ return this.size === 'large';
103
+ },
104
+
105
+ isSmall() {
106
+ return this.size === 'small';
107
+ },
108
+
109
+ isVisible() {
110
+ return this.modelValue !== null ? this.modelValue : this.modelValueLocal;
111
+ },
74
112
  },
75
113
 
76
114
  methods: {
77
115
  hide() {
116
+ this.modelValue !== null
117
+ ? this.$emit('update:modelValue', false)
118
+ : (this.modelValueLocal = false);
119
+
78
120
  this.$emit('dismiss');
79
- this.show = false;
80
121
  },
81
122
  },
82
123
  };
@@ -1,25 +1,13 @@
1
1
  <template>
2
- <VTImage
3
- v-if="src"
4
- :src="src"
5
- v-bind="attrs"
6
- :width="width"
7
- :height="height"
8
- />
9
- <VTImage
10
- v-else-if="cdnSrc"
11
- :cdn-src="cdnSrc"
12
- v-bind="attrs"
13
- :width="width"
14
- :height="height"
15
- />
2
+ <VTImage v-if="src" :src="src" v-bind="attrs" width="40" />
3
+ <VTImage v-else-if="cdnSrc" :cdn-src="cdnSrc" v-bind="attrs" width="40" />
16
4
  </template>
17
5
 
18
6
  <script>
19
- import VTImage from '../Image/VTImage.vue';
7
+ import VTImage from "../Image/VTImage.vue";
20
8
 
21
9
  export default {
22
- name: 'VTAvatarImage',
10
+ name: "VTAvatarImage",
23
11
 
24
12
  components: { VTImage },
25
13
 
@@ -30,27 +18,19 @@ export default {
30
18
  },
31
19
  src: {
32
20
  type: String,
33
- default: '',
21
+ default: "",
34
22
  },
35
23
  cdnSrc: {
36
24
  type: [String, Object],
37
25
  default: null,
38
26
  },
39
- width: {
40
- type: String,
41
- default: '40',
42
- },
43
- height: {
44
- type: String || null,
45
- default: null,
46
- },
47
27
  },
48
28
 
49
29
  computed: {
50
30
  attrs() {
51
31
  return {
52
32
  alt: this.alt,
53
- class: 'h-auto w-full',
33
+ class: "h-auto w-full",
54
34
  };
55
35
  },
56
36
  },
@@ -0,0 +1,60 @@
1
+ <template>
2
+ <span
3
+ :class="[
4
+ // default styles
5
+ headless
6
+ ? 'badge'
7
+ : 'ml-auto flex min-w-5 place-content-center rounded-xl p-1 text-xs leading-none ',
8
+ // variant styles
9
+ headless
10
+ ? `badge--${variant}`
11
+ : isDefault
12
+ ? 'bg-gray-800 text-white'
13
+ : isSuccess
14
+ ? 'bg-success-200 text-success-700'
15
+ : isError
16
+ ? 'bg-error-200 text-error-700'
17
+ : isWarning
18
+ ? 'bg-warning-200 text-warning-700'
19
+ : null,
20
+ // sizes styles
21
+ ]"
22
+ >
23
+ <slot />
24
+ </span>
25
+ </template>
26
+
27
+ <script>
28
+ export default {
29
+ name: 'VTBadge',
30
+
31
+ props: {
32
+ headless: {
33
+ type: Boolean,
34
+ default: false,
35
+ },
36
+ variant: {
37
+ type: String,
38
+ default: 'default',
39
+ },
40
+ },
41
+
42
+ computed: {
43
+ isDefault() {
44
+ return this.variant === 'default';
45
+ },
46
+
47
+ isSuccess() {
48
+ return this.variant === 'success';
49
+ },
50
+
51
+ isError() {
52
+ return this.variant === 'error';
53
+ },
54
+
55
+ isWarning() {
56
+ return this.variant === 'warning';
57
+ },
58
+ },
59
+ };
60
+ </script>
@@ -0,0 +1,60 @@
1
+ <template>
2
+ <span
3
+ :class="[
4
+ // default styles
5
+ headless
6
+ ? 'badge'
7
+ : 'ml-auto flex min-w-5 place-content-center rounded-xl p-1 text-xs leading-none ',
8
+ // variant styles
9
+ headless
10
+ ? `badge--${variant}`
11
+ : isDefault
12
+ ? 'bg-gray-800 text-white'
13
+ : isSuccess
14
+ ? 'bg-success-200 text-success-700'
15
+ : isError
16
+ ? 'bg-error-200 text-error-700'
17
+ : isWarning
18
+ ? 'bg-warning-200 text-warning-700'
19
+ : null,
20
+ // sizes styles
21
+ ]"
22
+ >
23
+ <slot />
24
+ </span>
25
+ </template>
26
+
27
+ <script>
28
+ export default {
29
+ name: 'VTBadgeNew',
30
+
31
+ props: {
32
+ headless: {
33
+ type: Boolean,
34
+ default: false,
35
+ },
36
+ variant: {
37
+ type: String,
38
+ default: 'default',
39
+ },
40
+ },
41
+
42
+ computed: {
43
+ isDefault() {
44
+ return this.variant === 'default';
45
+ },
46
+
47
+ isSuccess() {
48
+ return this.variant === 'success';
49
+ },
50
+
51
+ isError() {
52
+ return this.variant === 'error';
53
+ },
54
+
55
+ isWarning() {
56
+ return this.variant === 'warning';
57
+ },
58
+ },
59
+ };
60
+ </script>
@@ -0,0 +1,11 @@
1
+ <template>
2
+ <li>
3
+ <slot />
4
+ </li>
5
+ </template>
6
+
7
+ <script>
8
+ export default {
9
+ name: 'VTBreadcrumbItem',
10
+ };
11
+ </script>
@@ -0,0 +1,40 @@
1
+ <template>
2
+ <component :is="as" v-bind="linkProps" class="link-base link-underlined">
3
+ <slot />
4
+ </component>
5
+ </template>
6
+
7
+ <script>
8
+ export default {
9
+ name: 'VTBreadcrumbLink',
10
+
11
+ props: {
12
+ href: {
13
+ type: String,
14
+ default: null,
15
+ },
16
+ to: {
17
+ type: String,
18
+ default: null,
19
+ },
20
+ },
21
+
22
+ computed: {
23
+ as() {
24
+ return this.href ? 'a' : this.to ? resolveComponent('NuxtLink') : 'button';
25
+ },
26
+
27
+ linkProps() {
28
+ if (this.href) {
29
+ return { href: this.href };
30
+ }
31
+
32
+ if (this.to) {
33
+ return { to: this.to };
34
+ }
35
+
36
+ return {};
37
+ },
38
+ },
39
+ };
40
+ </script>
@@ -0,0 +1,11 @@
1
+ <template>
2
+ <ol class="flex gap-x-0.5 gap-y-1 font-medium flex-wrap text-sm">
3
+ <slot />
4
+ </ol>
5
+ </template>
6
+
7
+ <script>
8
+ export default {
9
+ name: 'VTBreadcrumbList',
10
+ };
11
+ </script>
@@ -0,0 +1,11 @@
1
+ <template>
2
+ <nav aria-label="breadcrumb">
3
+ <slot />
4
+ </nav>
5
+ </template>
6
+
7
+ <script>
8
+ export default {
9
+ name: 'VTBreadcrumbRoot',
10
+ };
11
+ </script>
@@ -0,0 +1,19 @@
1
+ <template>
2
+ <li>
3
+ <slot>
4
+ <IconChevronRight />
5
+ </slot>
6
+ </li>
7
+ </template>
8
+
9
+ <script>
10
+ import { IconChevronRight } from '@veritree/icons';
11
+
12
+ export default {
13
+ name: 'VTBreadcrumbSeparator',
14
+
15
+ components: {
16
+ IconChevronRight,
17
+ },
18
+ };
19
+ </script>