@code-coaching/vuetiful 0.18.1 → 0.19.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-coaching/vuetiful",
3
- "version": "0.18.1",
3
+ "version": "0.19.0",
4
4
  "license": "MIT",
5
5
  "scripts": {
6
6
  "dev": "onchange 'src/**/*.vue' 'src/**/*.ts' 'src/**/*.css' -- npm run build",
@@ -0,0 +1,22 @@
1
+ import { mount } from "@vue/test-utils";
2
+ import { describe, expect, test } from "vitest";
3
+ import { VAccordion } from "..";
4
+
5
+ describe("VAccordion", () => {
6
+ test("defaults", async () => {
7
+ const wrapper = mount({
8
+ template: /*html*/ `<v-accordion></v-accordion>`,
9
+ components: {
10
+ "v-accordion": VAccordion,
11
+ },
12
+ });
13
+
14
+ expect(wrapper.classes()).toEqual([
15
+ "vuetiful-accordion",
16
+ "flex",
17
+ "w-full",
18
+ "flex-col",
19
+ "gap-1",
20
+ ]);
21
+ });
22
+ });
@@ -0,0 +1,23 @@
1
+ <script setup lang="ts">
2
+ import { provide } from 'vue';
3
+
4
+ const props = defineProps({
5
+ hover: {
6
+ type: String,
7
+ default: 'hover:variant-soft',
8
+ },
9
+ background: {
10
+ type: String,
11
+ default: 'bg-surface-200-700-token',
12
+ },
13
+ });
14
+
15
+ provide('hover', props.hover);
16
+ provide('background', props.background);
17
+ </script>
18
+
19
+ <template>
20
+ <div class="vuetiful-accordion flex w-full flex-col gap-1">
21
+ <slot></slot>
22
+ </div>
23
+ </template>
@@ -0,0 +1,85 @@
1
+ import { mount } from "@vue/test-utils";
2
+ import { describe, expect, test } from "vitest";
3
+ import { VAccordion, VAccordionItem } from "..";
4
+
5
+ describe("VAccordionItem", () => {
6
+ test("defaults", async () => {
7
+ const wrapper = mount({
8
+ template: /*html*/ `
9
+ <v-accordion>
10
+ <v-accordion-item title="Vuetiful">John Duck</v-accordion-item>
11
+ <v-accordion-item title="Is">Janine Duck</v-accordion-item>
12
+ </v-accordion>`,
13
+ components: {
14
+ "v-accordion": VAccordion,
15
+ "v-accordion-item": VAccordionItem,
16
+ },
17
+ });
18
+
19
+ const accordionItems = wrapper.findAllComponents(VAccordionItem);
20
+ accordionItems.forEach((accordionItem) => {
21
+ expect(accordionItem.classes()).toEqual(["vuetiful-accordion-item"]);
22
+
23
+ const accordionItemButton = accordionItem.find(".vuetiful-accordion-item-button");
24
+ expect(accordionItemButton.classes()).toEqual([
25
+ "bg-surface-200-700-token",
26
+ "hover:variant-soft",
27
+ "vuetiful-accordion-item-button",
28
+ "w-full",
29
+ "rounded-container-token",
30
+ ]);
31
+
32
+ const accordionItemTitle = accordionItem.find(".vuetiful-accordion-title");
33
+ expect(accordionItemTitle.text()).toEqual(accordionItem.props().title);
34
+ });
35
+ });
36
+
37
+ test("open", async () => {
38
+ const wrapper = mount({
39
+ template: /*html*/ `
40
+ <v-accordion>
41
+ <v-accordion-item title="Vuetiful" open>John Duck</v-accordion-item>
42
+ <v-accordion-item title="Is">Janine Duck</v-accordion-item>
43
+ </v-accordion>`,
44
+ components: {
45
+ "v-accordion": VAccordion,
46
+ "v-accordion-item": VAccordionItem,
47
+ },
48
+ });
49
+
50
+ const accordionItems = wrapper.findAllComponents(VAccordionItem);
51
+ const accordionItemButtonOne = accordionItems[0].find(".vuetiful-accordion-item-button");
52
+ const accordionItemButtonTwo = accordionItems[1].find(".vuetiful-accordion-item-button");
53
+
54
+ await accordionItemButtonOne.trigger("click");
55
+
56
+ expect(accordionItemButtonOne.classes()).toEqual([
57
+ "bg-surface-200-700-token",
58
+ "hover:variant-soft",
59
+ "!rounded-bl-none",
60
+ "!rounded-br-none",
61
+ "vuetiful-accordion-item-button",
62
+ "w-full",
63
+ "rounded-container-token",
64
+ ]);
65
+ expect(accordionItemButtonTwo.classes()).toEqual([
66
+ "bg-surface-200-700-token",
67
+ "hover:variant-soft",
68
+ "vuetiful-accordion-item-button",
69
+ "w-full",
70
+ "rounded-container-token",
71
+ ]);
72
+
73
+ const accordionItemPanelOne = accordionItems[0].find(".vuetiful-accordion-item-panel");
74
+
75
+ expect(accordionItemPanelOne.classes()).toEqual([
76
+ "vuetiful-accordion-item-panel",
77
+ "p-4",
78
+ "pt-0",
79
+ "rounded-container-token",
80
+ "bg-surface-200-700-token",
81
+ "!rounded-tl-none",
82
+ "!rounded-tr-none",
83
+ ]);
84
+ });
85
+ });
@@ -0,0 +1,60 @@
1
+ <script setup lang="ts">
2
+ import { Disclosure, DisclosureButton, DisclosurePanel } from "@headlessui/vue";
3
+ import { inject } from "vue";
4
+
5
+ defineProps({
6
+ title: {
7
+ type: String,
8
+ required: true,
9
+ },
10
+ });
11
+
12
+ const hover = inject("hover");
13
+ const background = inject("background");
14
+ </script>
15
+
16
+ <template>
17
+ <Disclosure class="vuetiful-accordion-item" as="div" v-slot="{ open }">
18
+ <DisclosureButton
19
+ :class="`${background} ${hover} ${open ? '!rounded-bl-none !rounded-br-none' : ''}`"
20
+ class="vuetiful-accordion-item-button w-full rounded-container-token"
21
+ >
22
+ <div
23
+ class="flex items-center justify-between p-4 rounded-container-token hover:cursor-pointer"
24
+ :class="`${background} ${hover} ${open ? '!rounded-bl-none !rounded-br-none' : ''}`"
25
+ >
26
+ <span class="vuetiful-accordion-title">{{ title }}</span>
27
+ <slot v-if="!open" name="open-item">
28
+ <!-- https://fontawesome.com/icons/plus?f=classic&s=solid -->
29
+ <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
30
+ <!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
31
+ <path
32
+ d="M256 80c0-17.7-14.3-32-32-32s-32 14.3-32 32V224H48c-17.7 0-32 14.3-32 32s14.3 32 32 32H192V432c0 17.7 14.3 32 32 32s32-14.3 32-32V288H400c17.7 0 32-14.3 32-32s-14.3-32-32-32H256V80z"
33
+ />
34
+ </svg>
35
+ </slot>
36
+ <slot v-if="open" name="close-item">
37
+ <!-- https://fontawesome.com/icons/minus?f=classic&s=solid -->
38
+ <svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
39
+ <!--! Font Awesome Free 6.4.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. -->
40
+ <path
41
+ d="M432 256c0 17.7-14.3 32-32 32L48 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l352 0c17.7 0 32 14.3 32 32z"
42
+ />
43
+ </svg>
44
+ </slot>
45
+ </div>
46
+ </DisclosureButton>
47
+ <DisclosurePanel
48
+ class="vuetiful-accordion-item-panel p-4 pt-0 rounded-container-token"
49
+ :class="`${open ? `${background} !rounded-tl-none !rounded-tr-none` : ''}`"
50
+ >
51
+ <slot></slot>
52
+ </DisclosurePanel>
53
+ </Disclosure>
54
+ </template>
55
+
56
+ <style scoped>
57
+ .icon {
58
+ @apply my-1 h-4 w-4 fill-current;
59
+ }
60
+ </style>
@@ -101,9 +101,7 @@ const showText = computed(() => {
101
101
  v-model="parentModelValue"
102
102
  >
103
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}`">
105
- {{ showText }}
106
- </v-listbox-button>
104
+ <v-listbox-button data-test="v-listbox-button">{{ showText }}</v-listbox-button>
107
105
  <!-- TODO: Add configurable transition -->
108
106
  <transition
109
107
  enter-active-class="transition duration-150 ease-in-out"
@@ -14,7 +14,12 @@ import VTab from "./VTabs/VTab.vue";
14
14
  import VTabPanel from "./VTabs/VTabPanel.vue";
15
15
  import VTabs from "./VTabs/VTabs.vue";
16
16
 
17
+ import VAccordion from "./VAccordion/VAccordion.vue";
18
+ import VAccordionItem from "./VAccordion/VAccordionItem.vue";
19
+
17
20
  export {
21
+ VAccordion,
22
+ VAccordionItem,
18
23
  VDrawer,
19
24
  VListbox,
20
25
  VListboxButton,