@code-coaching/vuetiful 0.22.0 → 0.23.0

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 (105) hide show
  1. package/README.md +1 -1
  2. package/dist/style.css +2 -2
  3. package/dist/types/components/VBootstrap.vue.d.ts +15 -0
  4. package/dist/types/components/atoms/VAvatar.vue.d.ts +37 -10
  5. package/dist/types/components/atoms/VBadge.vue.d.ts +22 -1
  6. package/dist/types/components/atoms/VButton.vue.d.ts +27 -0
  7. package/dist/types/components/atoms/VChip.vue.d.ts +22 -1
  8. package/dist/types/components/atoms/VRadio/VRadioGroup.vue.d.ts +10 -1
  9. package/dist/types/components/atoms/VRadio/VRadioItem.vue.d.ts +2 -2
  10. package/dist/types/components/atoms/VSwitch/VSwitch.vue.d.ts +24 -15
  11. package/dist/types/components/atoms/index.d.ts +1 -2
  12. package/dist/types/components/molecules/VAccordion/VAccordion.vue.d.ts +15 -6
  13. package/dist/types/components/molecules/VAccordion/VAccordionItem.vue.d.ts +11 -1
  14. package/dist/types/components/molecules/VAlert.vue.d.ts +39 -3
  15. package/dist/types/components/molecules/VCard/VCard.vue.d.ts +5 -5
  16. package/dist/types/components/molecules/VCard/VCardBody.vue.d.ts +13 -1
  17. package/dist/types/components/molecules/VCard/VCardFooter.vue.d.ts +22 -1
  18. package/dist/types/components/molecules/VCard/VCardHeader.vue.d.ts +22 -1
  19. package/dist/types/components/{atoms → molecules}/VCodeBlock.vue.d.ts +36 -9
  20. package/dist/types/components/molecules/VListbox/VListbox.vue.d.ts +51 -14
  21. package/dist/types/components/molecules/VListbox/VListboxItem.vue.d.ts +13 -3
  22. package/dist/types/components/molecules/VListbox/VListboxItems.vue.d.ts +9 -0
  23. package/dist/types/components/molecules/VTabs/VTab.vue.d.ts +9 -0
  24. package/dist/types/components/molecules/VTabs/VTabs.vue.d.ts +18 -0
  25. package/dist/types/components/molecules/index.d.ts +4 -3
  26. package/dist/types/props/index.d.ts +1 -0
  27. package/dist/types/props/props.d.ts +14 -0
  28. package/dist/types/services/index.d.ts +5 -3
  29. package/dist/types/services/settings.service.d.ts +132 -0
  30. package/dist/types/services/settings.service.test.d.ts +1 -0
  31. package/dist/types/types/index.d.ts +53 -0
  32. package/dist/vuetiful.es.mjs +920 -557
  33. package/dist/vuetiful.umd.js +23 -10
  34. package/package.json +1 -1
  35. package/src/components/VBootstrap.vue +62 -0
  36. package/src/components/atoms/VAvatar.test.ts +98 -28
  37. package/src/components/atoms/VAvatar.vue +46 -13
  38. package/src/components/atoms/VBadge.test.ts +10 -0
  39. package/src/components/atoms/VBadge.vue +13 -1
  40. package/src/components/atoms/VButton.test.ts +58 -0
  41. package/src/components/atoms/VButton.vue +31 -2
  42. package/src/components/atoms/VChip.test.ts +26 -11
  43. package/src/components/atoms/VChip.vue +13 -1
  44. package/src/components/atoms/VRadio/VRadioDescription.vue +1 -1
  45. package/src/components/atoms/VRadio/VRadioGroup.test.ts +7 -7
  46. package/src/components/atoms/VRadio/VRadioGroup.vue +16 -5
  47. package/src/components/atoms/VRadio/VRadioItem.vue +12 -8
  48. package/src/components/atoms/VRadio/VRadioLabel.vue +1 -1
  49. package/src/components/atoms/VSwitch/VSwitch.test.ts +20 -18
  50. package/src/components/atoms/VSwitch/VSwitch.vue +29 -17
  51. package/src/components/atoms/VSwitch/VSwitchDescription.vue +1 -1
  52. package/src/components/atoms/VSwitch/VSwitchGroup.vue +2 -2
  53. package/src/components/atoms/VSwitch/VSwitchLabel.vue +1 -1
  54. package/src/components/atoms/index.ts +0 -2
  55. package/src/components/molecules/VAccordion/VAccordion.test.ts +11 -0
  56. package/src/components/molecules/VAccordion/VAccordion.vue +16 -7
  57. package/src/components/molecules/VAccordion/VAccordionItem.test.ts +65 -16
  58. package/src/components/molecules/VAccordion/VAccordionItem.vue +53 -32
  59. package/src/components/molecules/VAlert.test.ts +11 -1
  60. package/src/components/molecules/VAlert.vue +33 -7
  61. package/src/components/molecules/VCard/VCard.test.ts +1 -1
  62. package/src/components/molecules/VCard/VCard.vue +12 -7
  63. package/src/components/molecules/VCard/VCardBody.test.ts +18 -0
  64. package/src/components/molecules/VCard/VCardBody.vue +16 -1
  65. package/src/components/molecules/VCard/VCardFooter.test.ts +18 -0
  66. package/src/components/molecules/VCard/VCardFooter.vue +21 -3
  67. package/src/components/molecules/VCard/VCardHeader.test.ts +18 -0
  68. package/src/components/molecules/VCard/VCardHeader.vue +26 -5
  69. package/src/components/molecules/VCodeBlock.test.ts +133 -0
  70. package/src/components/molecules/VCodeBlock.vue +120 -0
  71. package/src/components/molecules/VListbox/VListbox.test.ts +42 -15
  72. package/src/components/molecules/VListbox/VListbox.vue +44 -15
  73. package/src/components/molecules/VListbox/VListboxButton.test.ts +15 -6
  74. package/src/components/molecules/VListbox/VListboxButton.vue +10 -1
  75. package/src/components/molecules/VListbox/VListboxItem.test.ts +2 -2
  76. package/src/components/molecules/VListbox/VListboxItem.vue +18 -7
  77. package/src/components/molecules/VListbox/VListboxItems.test.ts +2 -2
  78. package/src/components/molecules/VListbox/VListboxItems.vue +18 -5
  79. package/src/components/molecules/VListbox/VListboxLabel.test.ts +1 -2
  80. package/src/components/molecules/VListbox/VListboxLabel.vue +1 -1
  81. package/src/components/molecules/VPreview.vue +9 -5
  82. package/src/components/molecules/{VRail.test.ts → VRail/VRail.test.ts} +1 -1
  83. package/src/components/molecules/{VRail.vue → VRail/VRail.vue} +6 -6
  84. package/src/components/molecules/VRail/VRailTile.test.ts +99 -0
  85. package/src/components/molecules/{VRailTile.vue → VRail/VRailTile.vue} +4 -6
  86. package/src/components/molecules/VTabs/VTab.test.ts +7 -3
  87. package/src/components/molecules/VTabs/VTab.vue +20 -5
  88. package/src/components/molecules/VTabs/VTabPanel.vue +2 -2
  89. package/src/components/molecules/VTabs/VTabs.test.ts +4 -2
  90. package/src/components/molecules/VTabs/VTabs.vue +32 -8
  91. package/src/components/molecules/index.ts +5 -2
  92. package/src/props/index.ts +1 -0
  93. package/src/props/props.ts +62 -0
  94. package/src/services/index.ts +5 -3
  95. package/src/services/settings.service.test.ts +17 -0
  96. package/src/services/settings.service.ts +136 -0
  97. package/src/types/index.ts +58 -0
  98. package/src/components/atoms/VCodeBlock.test.ts +0 -14
  99. package/src/components/atoms/VCodeBlock.vue +0 -92
  100. package/src/components/molecules/VRailTile.test.ts +0 -14
  101. /package/dist/types/components/{atoms → molecules}/VCodeBlock.test.d.ts +0 -0
  102. /package/dist/types/components/molecules/{VRail.test.d.ts → VRail/VRail.test.d.ts} +0 -0
  103. /package/dist/types/components/molecules/{VRail.vue.d.ts → VRail/VRail.vue.d.ts} +0 -0
  104. /package/dist/types/components/molecules/{VRailTile.test.d.ts → VRail/VRailTile.test.d.ts} +0 -0
  105. /package/dist/types/components/molecules/{VRailTile.vue.d.ts → VRail/VRailTile.vue.d.ts} +0 -0
@@ -1,12 +1,16 @@
1
1
  <script setup lang="ts">
2
+ import { CssClasses, useSettings } from "@/index";
2
3
  import { Listbox } from "@headlessui/vue";
3
4
  import { computed, provide, ref, watch } from "vue";
4
5
  import VListboxButton from "./VListboxButton.vue";
5
6
  import VListboxItems from "./VListboxItems.vue";
6
7
  import VListboxLabel from "./VListboxLabel.vue";
8
+ import { unstyledProp } from "@/props";
7
9
 
8
10
  const emit = defineEmits(["update:modelValue"]);
9
11
  const props = defineProps({
12
+ modelValue: Listbox.props["modelValue"],
13
+
10
14
  by: {
11
15
  type: String,
12
16
  },
@@ -14,20 +18,32 @@ const props = defineProps({
14
18
  type: String,
15
19
  },
16
20
 
17
- labelText: {
21
+ textLabel: {
18
22
  type: String,
19
23
  },
20
- labelClasses: {
21
- type: Boolean,
22
- default: false,
24
+ classLabel: {
25
+ type: String as () => CssClasses,
26
+ default: "",
23
27
  },
24
28
 
25
- buttonText: {
29
+ textButton: {
26
30
  type: String,
27
31
  default: "Select an option",
28
32
  },
33
+ classButton: {
34
+ type: String as () => CssClasses,
35
+ default: "",
36
+ },
37
+
38
+ classItem: {
39
+ type: String as () => CssClasses,
40
+ default: "",
41
+ },
42
+ classItems: {
43
+ type: String as () => CssClasses,
44
+ default: "",
45
+ },
29
46
 
30
- modelValue: Listbox.props["modelValue"],
31
47
  horizontal: {
32
48
  type: Boolean,
33
49
  default: false,
@@ -43,7 +59,7 @@ const props = defineProps({
43
59
  },
44
60
  hover: {
45
61
  type: String,
46
- default: "variant-ghost",
62
+ default: "hover:variant-ghost",
47
63
  },
48
64
 
49
65
  background: {
@@ -54,6 +70,8 @@ const props = defineProps({
54
70
  type: String,
55
71
  default: "text-surface-900 dark:text-surface-50",
56
72
  },
73
+
74
+ unstyled: unstyledProp,
57
75
  });
58
76
 
59
77
  const parentModelValue = ref(props.modelValue);
@@ -75,33 +93,40 @@ provide("hover", props.hover);
75
93
  provide("background", props.background);
76
94
  provide("text", props.text);
77
95
  provide("horizontal", props.horizontal);
96
+ provide("unstyled", props.unstyled);
97
+ provide("classItem", props.classItem);
98
+ provide("classItems", props.classItems);
78
99
 
79
100
  const showText = computed(() => {
80
101
  if (props.display && parentModelValue.value) return parentModelValue.value[props.display];
81
102
 
82
103
  const length = parentModelValue.value?.length;
83
- if (props.multiple && length === 0) return props.buttonText;
104
+ if (props.multiple && length === 0) return props.textButton;
84
105
  if (props.multiple && length === 1) return parentModelValue.value[0];
85
106
  if (props.multiple && length > 1) return `${length} options selected`; // TODO: i18n
86
107
 
87
108
  if (parentModelValue.value) return parentModelValue.value;
88
109
 
89
- return props.buttonText;
110
+ return props.textButton;
90
111
  });
112
+
113
+ const { settings } = useSettings();
114
+ const isUnstyled =
115
+ settings.global.unstyled || settings.components.listbox.unstyled || props.unstyled;
91
116
  </script>
92
117
 
93
118
  <template>
94
- <!-- There is some odd behavior with test coverge, v-model must be the last property in this component -->
119
+ <!-- There is some odd behavior with test coverage, v-model must be the last property in this component -->
95
120
  <Listbox
96
- data-test="v-listbox"
121
+ data-test="listbox"
97
122
  as="div"
98
123
  :by="by"
99
124
  :multiple="multiple"
100
- class="vuetiful-listbox relative rounded-container-token"
125
+ :class="`vuetiful-listbox ${isUnstyled ? '' : 'relative rounded-container-token'}`"
101
126
  v-model="parentModelValue"
102
127
  >
103
- <v-listbox-label v-if="labelText" :class="labelClasses">{{ labelText }}</v-listbox-label>
104
- <v-listbox-button data-test="v-listbox-button" :class="`${background} ${text}`">
128
+ <v-listbox-label v-if="textLabel" :class="classLabel">{{ textLabel }}</v-listbox-label>
129
+ <v-listbox-button data-test="listbox-button" :class="`${background} ${text} ${classButton}`">
105
130
  {{ showText }}
106
131
  </v-listbox-button>
107
132
  <!-- TODO: Add configurable transition -->
@@ -113,7 +138,11 @@ const showText = computed(() => {
113
138
  leave-from-class="opacity-100"
114
139
  leave-to-class="opacity-0"
115
140
  >
116
- <v-listbox-items class="absolute mt-1 min-w-full">
141
+ <v-listbox-items
142
+ data-test="listbox-items"
143
+ :unstyled="unstyled"
144
+ :class="`${isUnstyled ? '' : 'absolute mt-1 min-w-full'}`"
145
+ >
117
146
  <slot />
118
147
  </v-listbox-items>
119
148
  </transition>
@@ -6,9 +6,12 @@ import VListboxButton from "./VListboxButton.vue";
6
6
  describe("VListboxButton props", () => {
7
7
  test("defaults", () => {
8
8
  const wrapper = mount({
9
+ provide: {
10
+ unstyled: false,
11
+ },
9
12
  template: /* html */ `
10
13
  <Listbox>
11
- <v-listbox-button data-test="v-listbox-button">John Duck</v-listbox-button>
14
+ <v-listbox-button data-test="listbox-button">John Duck</v-listbox-button>
12
15
  </Listbox>
13
16
  `,
14
17
  components: {
@@ -17,15 +20,18 @@ describe("VListboxButton props", () => {
17
20
  },
18
21
  });
19
22
 
20
- const listboxButton = wrapper.find("[data-test='v-listbox-button']");
23
+ const listboxButton = wrapper.find("[data-test='listbox-button']");
21
24
  expect(listboxButton.element.tagName).toBe("BUTTON");
22
25
  });
23
26
 
24
27
  test("custom 'as' prop", () => {
25
28
  const wrapper = mount({
29
+ provide: {
30
+ unstyled: false,
31
+ },
26
32
  template: /* html */ `
27
33
  <Listbox>
28
- <v-listbox-button as="div" data-test="v-listbox-button">John Duck</v-listbox-button>
34
+ <v-listbox-button as="div" data-test="listbox-button">John Duck</v-listbox-button>
29
35
  </Listbox>
30
36
  `,
31
37
  components: {
@@ -34,15 +40,18 @@ describe("VListboxButton props", () => {
34
40
  },
35
41
  });
36
42
 
37
- const listboxButton = wrapper.find("[data-test='v-listbox-button']");
43
+ const listboxButton = wrapper.find("[data-test='listbox-button']");
38
44
  expect(listboxButton.element.tagName).toBe("DIV");
39
45
  });
40
46
 
41
47
  test("should hide icon", () => {
42
48
  const wrapper = mount({
49
+ provide: {
50
+ unstyled: false,
51
+ },
43
52
  template: /* html */ `
44
53
  <Listbox>
45
- <v-listbox-button hide-icon data-test="v-listbox-button">John Duck</v-listbox-button>
54
+ <v-listbox-button hide-icon data-test="listbox-button">John Duck</v-listbox-button>
46
55
  </Listbox>
47
56
  `,
48
57
  components: {
@@ -51,7 +60,7 @@ describe("VListboxButton props", () => {
51
60
  },
52
61
  });
53
62
 
54
- const listboxButton = wrapper.find("[data-test='v-listbox-button']");
63
+ const listboxButton = wrapper.find("[data-test='listbox-button']");
55
64
  expect(listboxButton.find("svg").exists()).toBe(false);
56
65
  });
57
66
  });
@@ -1,5 +1,7 @@
1
1
  <script setup lang="ts">
2
+ import { useSettings } from "@/index";
2
3
  import { ListboxButton } from "@headlessui/vue";
4
+ import { inject } from "vue";
3
5
 
4
6
  defineProps({
5
7
  as: {
@@ -11,13 +13,20 @@ defineProps({
11
13
  default: false,
12
14
  },
13
15
  });
16
+
17
+ const unstyled = inject("unstyled") as boolean;
18
+
19
+ const { settings } = useSettings();
20
+ const isUnstyled = settings.global.unstyled || settings.components.listbox.unstyled || unstyled;
14
21
  </script>
15
22
 
16
23
  <template>
17
24
  <ListboxButton
18
25
  v-slot="{ open }"
19
26
  :as="as"
20
- class="variant-filled btn flex w-full justify-between active:scale-[100%]"
27
+ :class="`vuetiful-listbox-button ${
28
+ isUnstyled ? 'flex' : 'variant-filled btn flex w-full justify-between active:scale-[100%]'
29
+ }`"
21
30
  >
22
31
  <slot />
23
32
  <span v-if="!hideIcon">
@@ -23,10 +23,10 @@ describe("VListboxItem props", () => {
23
23
  },
24
24
  });
25
25
 
26
- const listbox = wrapper.find("[data-test='v-listbox']");
26
+ const listbox = wrapper.find("[data-test='listbox']");
27
27
  await listbox.find("button").trigger("click");
28
28
 
29
- const listboxItems = listbox.findAll("[data-test='v-listbox-item']");
29
+ const listboxItems = listbox.findAll("[data-test='listbox-item']");
30
30
  const selectedItem = listboxItems[0];
31
31
  const normalItem = listboxItems[1];
32
32
  expect(selectedItem.classes()).toEqual([
@@ -1,27 +1,38 @@
1
1
  <script setup lang="ts">
2
+ import { useSettings } from "@/services";
2
3
  import { ListboxOption } from "@headlessui/vue";
3
4
  import { inject } from "vue";
4
5
 
5
- defineProps({
6
+ const props = defineProps({
6
7
  value: {
7
8
  type: [String, Number, Boolean, Object],
8
9
  required: true,
9
10
  },
11
+
12
+ unstyled: {
13
+ type: Boolean,
14
+ default: false,
15
+ },
10
16
  });
11
17
 
12
18
  const activeClass = inject("active") as string;
13
19
  const hoverClass = inject("hover") as string;
20
+ const classItem = inject("classItem") as string;
21
+
22
+ const { settings } = useSettings();
23
+ const isUnstyled =
24
+ settings.global.unstyled || settings.components.listboxItem.unstyled || props.unstyled;
14
25
  </script>
15
26
 
16
27
  <template>
17
28
  <ListboxOption v-slot="{ selected, disabled, active }" :value="value">
18
29
  <div
19
- data-test="v-listbox-item"
20
- :class="`vuetiful-listbox-item px-4 py-1 text-base rounded-token ${
21
- selected ? activeClass : `hover:${hoverClass}`
22
- } ${disabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer'} ${
23
- active && !selected ? hoverClass : ''
24
- }`"
30
+ data-test="listbox-item"
31
+ :class="`vuetiful-listbox-item ${isUnstyled ? '' : 'px-4 py-1 text-base rounded-token'}
32
+ ${selected ? activeClass : hoverClass}
33
+ ${disabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer'}
34
+ ${active && !selected ? hoverClass : ''}
35
+ ${classItem}`"
25
36
  >
26
37
  <slot />
27
38
  </div>
@@ -16,7 +16,7 @@ test("VListboxItems defaults", async () => {
16
16
  },
17
17
  });
18
18
 
19
- const listbox = wrapper.find("[data-test='v-listbox']");
19
+ const listbox = wrapper.find("[data-test='listbox']");
20
20
  await listbox.find("button").trigger("click");
21
21
 
22
22
  const listboxItems = listbox.find("[data-test='listbox-items']");
@@ -36,7 +36,7 @@ test("VListboxItems horizontal", async () => {
36
36
  },
37
37
  });
38
38
 
39
- const listbox = wrapper.find("[data-test='v-listbox']");
39
+ const listbox = wrapper.find("[data-test='listbox']");
40
40
  await listbox.find("button").trigger("click");
41
41
 
42
42
  const listboxItems = listbox.find("[data-test='listbox-items']");
@@ -1,8 +1,9 @@
1
1
  <script setup lang="ts">
2
+ import { useSettings } from "@/index";
2
3
  import { ListboxOptions } from "@headlessui/vue";
3
4
  import { inject } from "vue";
4
5
 
5
- defineProps({
6
+ const props = defineProps({
6
7
  as: {
7
8
  type: String,
8
9
  default: "ul",
@@ -11,21 +12,33 @@ defineProps({
11
12
  type: Boolean,
12
13
  default: false,
13
14
  },
15
+
16
+ unstyled: {
17
+ type: Boolean,
18
+ default: false,
19
+ },
14
20
  });
15
21
 
16
22
  const background = inject("background") as string;
17
23
  const text = inject("text") as string;
18
24
  const horizontal = inject("horizontal") as boolean;
25
+ const classItems = inject("classItems") as string;
26
+
27
+ const { settings } = useSettings();
28
+ const isUnstyled = settings.global.unstyled || settings.components.listbox.unstyled || props.unstyled;
19
29
  </script>
20
30
 
21
31
  <template>
22
32
  <ListboxOptions
23
33
  :as="as"
24
34
  :static="static"
25
- :class="`p-4 border-token border-surface-400-500-token rounded-container-token ${background} ${text}`"
35
+ :class="`z-10 ${
36
+ isUnstyled
37
+ ? ''
38
+ : `rounded-container-token' gap-1 p-4 border-token border-surface-400-500-token`
39
+ } ${background} ${text} ${horizontal ? 'flex' : 'flex-col'} ${classItems}`"
40
+ data-test="listbox-items"
26
41
  >
27
- <div data-test="listbox-items" :class="`flex ${horizontal ? 'flex' : 'flex-col'} gap-1`">
28
- <slot />
29
- </div>
42
+ <slot />
30
43
  </ListboxOptions>
31
44
  </template>
@@ -1,6 +1,5 @@
1
1
  import { mount } from "@vue/test-utils";
2
2
  import { expect, test } from "vitest";
3
- import { ref } from "vue";
4
3
  import VListbox from "./VListbox.vue";
5
4
 
6
5
  test("VListboxLabel using slot", () => {
@@ -19,7 +18,7 @@ test("VListboxLabel using slot", () => {
19
18
  test("VListboxLabel custom label", () => {
20
19
  const wrapper = mount({
21
20
  template: `
22
- <v-listbox label-text="John Duck"></v-listbox>
21
+ <v-listbox text-label="John Duck"></v-listbox>
23
22
  `,
24
23
  components: {
25
24
  "v-listbox": VListbox,
@@ -10,5 +10,5 @@ defineProps({
10
10
  </script>
11
11
 
12
12
  <template>
13
- <ListboxLabel :as="as"><slot /></ListboxLabel>
13
+ <ListboxLabel class="vuetiful-listbox-label" :as="as"><slot /></ListboxLabel>
14
14
  </template>
@@ -135,9 +135,13 @@ const toggleSwatches = () => (swatches.value = !swatches.value);
135
135
  <v-button
136
136
  v-if="!hideSwatches"
137
137
  data-test="swatch-button"
138
- :class="`${
139
- swatches ? 'variant-filled' : 'variant-ghost'
140
- } px-4 py-1 border-token border-surface-400-500-token`"
138
+ :variant="swatches ? 'filled' : ''"
139
+ class="px-4 py-1 border-token border-surface-400-500-token"
140
+ :class="
141
+ swatches
142
+ ? ''
143
+ : 'text-center text-base rounded-token hover:variant-ghost hover:text-surface-900 dark:hover:text-surface-50'
144
+ "
141
145
  @click="toggleSwatches"
142
146
  title="Backgrounds"
143
147
  >
@@ -152,7 +156,7 @@ const toggleSwatches = () => (swatches.value = !swatches.value);
152
156
  </v-button>
153
157
  </header>
154
158
 
155
- <!-- There is some odd behavior with test coverge, v-model must be the last property in this component -->
159
+ <!-- There is some odd behavior with test coverage, v-model must be the last property in this component -->
156
160
  <v-radio-group
157
161
  v-if="swatches"
158
162
  data-test="swatches"
@@ -216,7 +220,7 @@ const toggleSwatches = () => (swatches.value = !swatches.value);
216
220
  <template v-if="tabView === 'code'">
217
221
  <div
218
222
  data-test="previewer-source"
219
- :class="`vuetiful-previewer-source p-4 ${backgrounds['neutral']} ${regionSource}`"
223
+ :class="`vuetiful-previewer-source p-4 md:p-10 ${backgrounds['neutral']} ${regionSource}`"
220
224
  >
221
225
  <slot name="source">(source)</slot>
222
226
  </div>
@@ -1,6 +1,6 @@
1
+ import { VRail } from "@/index";
1
2
  import { mount } from "@vue/test-utils";
2
3
  import { expect, test } from "vitest";
3
- import { VRail } from ".";
4
4
 
5
5
  test("VRail", () => {
6
6
  expect(VRail).toBeTruthy();
@@ -16,17 +16,17 @@ const props = defineProps({
16
16
  },
17
17
  });
18
18
 
19
- provide("active", props.active);
20
- provide("hover", props.hover);
19
+ provide("activeRail", props.active);
20
+ provide("hoverRail", props.hover);
21
21
  </script>
22
22
 
23
23
  <template>
24
24
  <v-radio-group
25
- unstyled
26
- :active="active"
27
- :hover="hover"
28
25
  v-model="selectedRailTile"
29
- class="vuetiful-rail flex h-full w-[70px] flex-col overflow-y-auto sm:w-20"
26
+ unstyled
27
+ hover=""
28
+ active=""
29
+ class="flex h-full w-[70px] flex-col overflow-y-auto"
30
30
  >
31
31
  <slot />
32
32
  </v-radio-group>
@@ -0,0 +1,99 @@
1
+ import { mount } from "@vue/test-utils";
2
+ import { expect, test, describe } from "vitest";
3
+ import { VRadioGroup, VRail, VRailTile, useRail } from "@/index";
4
+
5
+
6
+ describe("VRailTile", () => {
7
+ // TODO: add tests
8
+ test("default slot", () => {
9
+ const wrapper = mount({
10
+ provide: {
11
+ activeRail: null,
12
+ hoverRail: null,
13
+ },
14
+ template: /*html*/`
15
+ <v-radio-group>
16
+ <v-rail-tile>John Duck</v-rail-tile>
17
+ </v-radio-group>
18
+ `,
19
+ components: {
20
+ "v-rail-tile": VRailTile,
21
+ "v-radio-group": VRadioGroup,
22
+ },
23
+ });
24
+
25
+ expect(wrapper).toBeTruthy();
26
+ });
27
+
28
+ test("label prop", () => {
29
+ const wrapper = mount({
30
+ provide: {
31
+ activeRail: null,
32
+ hoverRail: null,
33
+ },
34
+ template: /*html*/`
35
+ <v-radio-group>
36
+ <v-rail-tile label="John Duck label">
37
+ John Duck
38
+ </v-rail-tile>
39
+ </v-radio-group>
40
+ `,
41
+ components: {
42
+ "v-rail-tile": VRailTile,
43
+ "v-radio-group": VRadioGroup,
44
+ },
45
+ });
46
+
47
+ const label = wrapper.find('.vuetiful-rail-tile-label');
48
+ expect(label.text()).toContain('John Duck label');
49
+ })
50
+
51
+ test("no default slot", () => {
52
+ const wrapper = mount({
53
+ provide: {
54
+ activeRail: null,
55
+ hoverRail: null,
56
+ },
57
+ template: /*html*/`
58
+ <v-radio-group>
59
+ <v-rail-tile label="John Duck label">
60
+ </v-rail-tile>
61
+ </v-radio-group>
62
+ `,
63
+ components: {
64
+ "v-rail-tile": VRailTile,
65
+ "v-radio-group": VRadioGroup,
66
+ },
67
+ });
68
+
69
+ const icon = wrapper.find('.vuetiful-rail-tile-icon');
70
+ expect(icon.exists()).toBeFalsy();
71
+ })
72
+
73
+ test("selected rail tile", async () => {
74
+ const wrapper = mount({
75
+ provide: {
76
+ activeRail: 'fake-active-class',
77
+ hoverRail: null,
78
+ },
79
+ template: /*html*/`
80
+ <v-rail data-test="rail">
81
+ <v-rail-tile data-test='rail-tile' label="John Duck label" value="John Duck">
82
+ John Duck
83
+ </v-rail-tile>
84
+ </v-rail>
85
+ `,
86
+ components: {
87
+ "v-rail-tile": VRailTile,
88
+ "v-rail": VRail,
89
+ },
90
+ });
91
+
92
+ const { selectedRailTile } = useRail();
93
+ expect(selectedRailTile.value).toBe("");
94
+ const railTile = wrapper.find('.vuetiful-rail-tile');
95
+ await railTile.trigger('click');
96
+ expect(selectedRailTile.value).toBe('John Duck');
97
+ })
98
+ })
99
+
@@ -25,17 +25,15 @@ defineProps({
25
25
  });
26
26
 
27
27
  const { selectedRailTile } = useRail();
28
- const active = inject("active");
29
- const hover = inject("hover");
28
+ const activeRail = inject("activeRail");
29
+ const hoverRail = inject("hoverRail");
30
30
  </script>
31
31
 
32
32
  <template>
33
33
  <v-radio-item
34
- :value="value"
35
34
  unstyled
36
- :class="`vuetiful-rail-tile grid aspect-square w-full cursor-pointer place-content-center place-items-center space-y-1.5 ${hover} ${
37
- selectedRailTile === value ? `${active}` : ''
38
- }`"
35
+ :value="value"
36
+ :class="`vuetiful-rail-tile grid aspect-square w-full cursor-pointer place-content-center place-items-center ${ selectedRailTile === value ? `${activeRail}` : `${hoverRail}` }`"
39
37
  >
40
38
  <template v-if="$slots.default">
41
39
  <div :class="`vuetiful-rail-tile-icon ${regionIcon}`"><slot /></div>
@@ -20,8 +20,9 @@ describe("VTab", () => {
20
20
 
21
21
  const vuetiful = wrapper.find("[data-test='vuetiful']");
22
22
  const slotContainer = vuetiful.find("[data-test='slot-container']");
23
- expect(vuetiful.classes()).toEqual(["flex", "flex-col"]);
23
+ expect(vuetiful.classes()).toEqual(["vuetiful-tab", "flex", "flex-col"]);
24
24
  expect(slotContainer.classes()).toEqual([
25
+ "vuetiful-tab-content",
25
26
  "text-base",
26
27
  "rounded-token",
27
28
  "w-full",
@@ -46,7 +47,7 @@ describe("VTab", () => {
46
47
  });
47
48
 
48
49
  const vuetiful = wrapper.find("[data-test='vuetiful']");
49
- expect(vuetiful.classes()).toEqual(["flex", "flex-row", "justify-between"]);
50
+ expect(vuetiful.classes()).toEqual(["vuetiful-tab", "flex", "flex-row", "justify-between"]);
50
51
  });
51
52
 
52
53
  test("class-tab", async () => {
@@ -66,7 +67,7 @@ describe("VTab", () => {
66
67
 
67
68
  const vuetiful = wrapper.find("[data-test='vuetiful']");
68
69
  const slotContainer = vuetiful.find("[data-test='slot-container']");
69
- expect(slotContainer.classes()).toEqual(["text-base", "rounded-token", "my-custom-class"]);
70
+ expect(slotContainer.classes()).toEqual(["vuetiful-tab-content", "text-base", "rounded-token", "my-custom-class"]);
70
71
  });
71
72
 
72
73
  test("hover/active", async () => {
@@ -95,6 +96,7 @@ describe("VTab", () => {
95
96
  .find("[data-test='slot-container']");
96
97
 
97
98
  expect(vuetifulSlotContainer.classes()).toEqual([
99
+ "vuetiful-tab-content",
98
100
  "text-base",
99
101
  "rounded-token",
100
102
  "my-custom-active-class",
@@ -103,6 +105,7 @@ describe("VTab", () => {
103
105
  "py-2",
104
106
  ]);
105
107
  expect(isSlotContainer.classes()).toEqual([
108
+ "vuetiful-tab-content",
106
109
  "text-base",
107
110
  "rounded-token",
108
111
  "hover:variant-ghost",
@@ -111,6 +114,7 @@ describe("VTab", () => {
111
114
  "py-2",
112
115
  ]);
113
116
  expect(beautifulSlotContainer.classes()).toEqual([
117
+ "vuetiful-tab-content",
114
118
  "text-base",
115
119
  "rounded-token",
116
120
  "hover:variant-ghost",