edvoyui-component-library-test-flight 0.0.105 → 0.0.107

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.
@@ -1,5 +1,5 @@
1
1
  export * from "/Volumes/work/repos/edvoy-ui-v2/src/components/modal/EUIModal.vue?vue&type=script&lang.ts";
2
- import "/Volumes/work/repos/edvoy-ui-v2/src/components/modal/EUIModal.vue?vue&type=style&index=0&scoped=03103d67&lang.scss";
2
+ import "/Volumes/work/repos/edvoy-ui-v2/src/components/modal/EUIModal.vue?vue&type=style&index=0&scoped=0a1278e7&lang.scss";
3
3
  declare const _default: any;
4
4
  export default _default;
5
5
  //# sourceMappingURL=EUIModal.vue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EUIModal.vue.d.ts","sourceRoot":"","sources":["../../src/components/modal/EUIModal.vue"],"names":[],"mappings":"AACA,cAAc,2FAA2F,CAAC;AA0F1G,OAAO,oHAAoH,CAAC;;AAE5H,wBAAmH"}
1
+ {"version":3,"file":"EUIModal.vue.d.ts","sourceRoot":"","sources":["../../src/components/modal/EUIModal.vue"],"names":[],"mappings":"AACA,cAAc,2FAA2F,CAAC;AA6F1G,OAAO,oHAAoH,CAAC;;AAE5H,wBAAmH"}
@@ -1,5 +1,5 @@
1
1
  export * from "/Volumes/work/repos/edvoy-ui-v2/src/components/tabs/EUITabs.vue?vue&type=script&setup=true&lang.ts";
2
- import "/Volumes/work/repos/edvoy-ui-v2/src/components/tabs/EUITabs.vue?vue&type=style&index=0&scoped=9b4681af&lang.css";
2
+ import "/Volumes/work/repos/edvoy-ui-v2/src/components/tabs/EUITabs.vue?vue&type=style&index=0&scoped=8ce36c62&lang.css";
3
3
  declare const _default: any;
4
4
  export default _default;
5
5
  //# sourceMappingURL=EUITabs.vue.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "edvoyui-component-library-test-flight",
3
3
  "private": false,
4
- "version": "0.0.105",
4
+ "version": "0.0.107",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist/",
@@ -0,0 +1,75 @@
1
+ // EUIBreadcrumb.stories.ts
2
+ import { Meta, StoryObj } from "@storybook/vue3";
3
+ import EUIBreadcrumb from "./EUIBreadcrumb.vue";
4
+ import {
5
+ BookOpenIcon,
6
+ HomeIcon,
7
+ TableCellsIcon,
8
+ } from "@heroicons/vue/24/outline";
9
+
10
+ const meta = {
11
+ title: "Components/Breadcrumb",
12
+ component: EUIBreadcrumb,
13
+ tags: ["autodocs"],
14
+ argTypes: {
15
+ pages: {
16
+ description: `An array of objects representing the breadcrumb pages.
17
+ Each object can include:
18
+ - \`name\` (string): The display name of the breadcrumb item.
19
+ - \`href\` (string, optional): The URL the breadcrumb item points to.
20
+ - \`current\` (boolean, optional): Indicates if the breadcrumb item is the current page.
21
+ - \`showIcon\` (Vue component, optional): An icon component to display alongside the name.`,
22
+ control: "object",
23
+ },
24
+ },
25
+ } satisfies Meta<typeof EUIBreadcrumb>;
26
+
27
+ export default meta;
28
+ type Story = StoryObj<typeof meta>;
29
+
30
+ // Default story with minimum props
31
+ export const Default: Story = {
32
+ args: {
33
+ pages: [
34
+ {
35
+ name: "Home",
36
+ href: "/",
37
+ current: true,
38
+ },
39
+ {
40
+ name: "Library",
41
+ href: "/library",
42
+ current: false,
43
+ },
44
+ {
45
+ name: "Data",
46
+ current: false,
47
+ },
48
+ ],
49
+ },
50
+ };
51
+
52
+ // Default story with minimum props
53
+ export const IconsUsed: Story = {
54
+ args: {
55
+ pages: [
56
+ {
57
+ name: "Home",
58
+ href: "/",
59
+ current: true,
60
+ showIcon: HomeIcon,
61
+ },
62
+ {
63
+ name: "Library",
64
+ href: "/library",
65
+ current: false,
66
+ showIcon: BookOpenIcon,
67
+ },
68
+ {
69
+ name: "Data",
70
+ current: false,
71
+ showIcon: TableCellsIcon,
72
+ },
73
+ ],
74
+ },
75
+ };
@@ -0,0 +1,59 @@
1
+ <template>
2
+ <nav aria-label="breadcrumb" class="my-2">
3
+ <ol
4
+ role="list"
5
+ class="flex items-center justify-start max-w-full space-x-1"
6
+ >
7
+ <li
8
+ v-for="(page, index) in pages"
9
+ :key="page.name"
10
+ class="flex flex-row items-center justify-start space-x-1"
11
+ >
12
+ <a
13
+ :href="page.href"
14
+ class="inline-flex items-center gap-2 text-sm font-medium font-inter"
15
+ :class="
16
+ pages.length - 1 !== index
17
+ ? 'text-gray-600 hover:text-gray-700'
18
+ : 'text-gray-500'
19
+ "
20
+ :aria-current="page.current ? 'page' : undefined"
21
+ >
22
+ <component
23
+ v-if="page?.showIcon"
24
+ :is="page?.showIcon"
25
+ class="text-current size-4"
26
+ />
27
+ {{ page.name }}</a
28
+ >
29
+ <ChevronDownStroke
30
+ v-if="pages.length - 1 !== index"
31
+ class="flex-shrink-0 w-5 h-5 text-gray-400 transform -rotate-90"
32
+ aria-hidden="true"
33
+ />
34
+ </li>
35
+ </ol>
36
+ </nav>
37
+ </template>
38
+
39
+ <script setup lang="ts">
40
+ import { toRefs, type PropType } from "vue";
41
+ import ChevronDownStroke from "../../assets/svg/ChevronDownStroke.vue";
42
+
43
+ interface BreadcrumbPage {
44
+ name: string;
45
+ href?: string;
46
+ current?: boolean;
47
+ showIcon?: {};
48
+ }
49
+
50
+ const props = defineProps({
51
+ pages: {
52
+ type: Array as PropType<BreadcrumbPage[]>,
53
+ default: [],
54
+ },
55
+ });
56
+ const { pages } = toRefs(props);
57
+ </script>
58
+
59
+ <style scoped></style>
@@ -4,20 +4,32 @@
4
4
  <button
5
5
  type="button"
6
6
  ref="dropdownButton"
7
- :class="['inline-flex items-center text-sm font-semibold gap-x-2 capitalize outline-none focus:outline-none', className]"
7
+ :class="[
8
+ 'inline-flex items-center text-sm font-semibold gap-x-2 capitalize outline-none focus:outline-none',
9
+ className,
10
+ ]"
8
11
  :disabled="disabled"
9
12
  @click="toggleDropdown()"
10
13
  >
11
14
  <slot name="dropdownName" :open="isOpen">
12
- {{ title }}
13
- <ChevronDownStroke :class="isOpen ? 'text-gray-900 rotate-180' : 'text-gray-500'"
14
- class="transition duration-100 ease-in-out transform rotate-0 size-6 group-hover:text-opacity-80"
15
- aria-hidden="true"
15
+ {{ title }}
16
+ <ChevronDownStroke
17
+ :class="isOpen ? 'text-gray-900 rotate-180' : 'text-gray-500'"
18
+ class="transition duration-100 ease-in-out transform rotate-0 size-6 group-hover:text-opacity-80"
19
+ aria-hidden="true"
16
20
  />
17
21
  </slot>
18
22
  </button>
19
23
  <!-- Menu lists -->
20
- <div v-if="isOpen && menuItems.length" class="absolute left-0 z-0 p-2 mt-1 transition-all duration-300 ease-in-out bg-white border border-gray-200 border-solid rounded-lg shadow-2xl top-full shadow-gray-300 min-w-32 max-w-64 w-max" @click.stop>
24
+ <div
25
+ v-if="isOpen && menuItems.length"
26
+ :class="[
27
+ 'absolute left-0 z-0 p-2 mt-1 transition-all duration-300 ease-in-out bg-white border border-gray-200 border-solid rounded-lg shadow-2xl shadow-gray-300 min-w-32 max-w-64 w-max',
28
+ placement === 'top' ? 'bottom-full' : 'top-full',
29
+ dropdownClass,
30
+ ]"
31
+ @click.stop
32
+ >
21
33
  <div
22
34
  v-for="item in menuItems"
23
35
  :key="item.text"
@@ -26,36 +38,55 @@
26
38
  @mouseleave="clearActiveMenuItem"
27
39
  @click.stop="$emit('menuItem', item)"
28
40
  >
29
- <div class="flex items-center justify-between w-full gap-2 text-sm font-medium text-gray-800 break-words hover:text-gray-900">
41
+ <div
42
+ class="flex items-center justify-between w-full gap-2 text-sm font-medium text-gray-800 break-words hover:text-gray-900"
43
+ >
30
44
  <slot name="menu" :menuitem="item">
31
- {{ item.text }}
32
- <ChevronDownStroke v-if="item.subMenu" :class="activeMenuItem === item.text ? 'text-gray-900 -rotate-90' : 'text-gray-500 rotate-0'"
33
- class="ml-auto transition duration-300 ease-in-out transform size-6 group-hover:text-opacity-80"
34
- aria-hidden="true" />
45
+ {{ item.text }}
46
+ <ChevronDownStroke
47
+ v-if="item.subMenu"
48
+ :class="
49
+ activeMenuItem === item.text
50
+ ? 'text-gray-900 -rotate-90'
51
+ : 'text-gray-500 rotate-0'
52
+ "
53
+ class="ml-auto transition duration-300 ease-in-out transform size-6 group-hover:text-opacity-80"
54
+ aria-hidden="true"
55
+ />
35
56
  </slot>
36
57
  </div>
37
58
 
38
59
  <!-- Sub-menu lists-->
39
- <div v-if="item.subMenu && activeMenuItem === item.text" class="absolute top-0 z-10 transition-all duration-300 ease-in-out left-full min-w-32 max-w-64 w-max">
40
- <div class="bg-white border border-gray-200 border-solid rounded-lg shadow-2xl ms-2 shadow-gray-300">
41
- <div v-if="item.enableAction" class="flex items-center justify-center w-full gap-1 px-6 py-3 text-sm font-medium text-gray-900 bg-purple-100 rounded-t-md" @click.prevent="$emit('actionItem', 'action')">
42
- <slot name="actionName">{{ '+ Action Name' }}</slot>
43
- </div>
44
- <div class="p-2 overflow-y-auto overscroll-auto max-h-[50svh] min-h-0 scrollbar--thin">
60
+ <div
61
+ v-if="item.subMenu && activeMenuItem === item.text"
62
+ class="absolute top-0 z-10 transition-all duration-300 ease-in-out left-full min-w-32 max-w-64 w-max"
63
+ >
64
+ <div
65
+ class="bg-white border border-gray-200 border-solid rounded-lg shadow-2xl ms-2 shadow-gray-300"
66
+ >
67
+ <div
68
+ v-if="item.enableAction"
69
+ class="flex items-center justify-center w-full gap-1 px-6 py-3 text-sm font-medium text-gray-900 bg-purple-100 rounded-t-md"
70
+ @click.prevent="$emit('actionItem', 'action')"
71
+ >
72
+ <slot name="actionName">{{ "+ Action Name" }}</slot>
73
+ </div>
74
+ <div
75
+ class="p-2 overflow-y-auto overscroll-auto max-h-[50svh] min-h-0 scrollbar--thin"
76
+ >
45
77
  <div
46
78
  v-for="subItem in item.subMenu"
47
79
  :key="subItem.text"
48
80
  class="flex items-center justify-between gap-2 px-3 py-2 text-sm font-medium text-gray-700 rounded-lg cursor-pointer hover:bg-gray-100 hover:text-gray-900"
49
81
  @click.stop="$emit('subMenuItem', subItem)"
50
82
  >
51
- <slot name="submenu" :subItem="subItem">
52
- {{ subItem.text }}
53
- </slot>
83
+ <slot name="submenu" :subItem="subItem">
84
+ {{ subItem.text }}
85
+ </slot>
54
86
  </div>
55
- </div>
87
+ </div>
56
88
  </div>
57
89
  </div>
58
-
59
90
  </div>
60
91
  </div>
61
92
  </div>
@@ -69,7 +100,7 @@ import ChevronDownStroke from "../../assets/svg/ChevronDownStroke.vue";
69
100
  interface MenuItem {
70
101
  text: string;
71
102
  subMenu?: MenuItem[];
72
- enableAction?:boolean;
103
+ enableAction?: boolean;
73
104
  }
74
105
 
75
106
  defineProps({
@@ -81,6 +112,10 @@ defineProps({
81
112
  type: String,
82
113
  required: false,
83
114
  },
115
+ dropdownClass: {
116
+ type: String,
117
+ required: false,
118
+ },
84
119
  menuItems: {
85
120
  type: Array as PropType<MenuItem[]>,
86
121
  default: () => [
@@ -93,44 +128,44 @@ defineProps({
93
128
  { text: "UKI Fair" },
94
129
  { text: "Germany Q4' 24" },
95
130
  { text: "Edvoy Express" },
96
- { text: "Q1 2025 Pipeline" }
97
- ]
131
+ { text: "Q1 2025 Pipeline" },
132
+ ],
98
133
  },
99
134
  {
100
135
  text: "Custom Filter",
101
- subMenu: [
102
- { text: "Application Intakes" },
103
- { text: "New Students" },
104
- ],
105
- enableAction: true
106
- }
107
- ]
136
+ subMenu: [{ text: "Application Intakes" }, { text: "New Students" }],
137
+ enableAction: true,
138
+ },
139
+ ],
108
140
  },
109
141
  disabled: Boolean,
142
+ placement: {
143
+ type: String as PropType<"top" | "bottom">,
144
+ default: "bottom",
145
+ },
110
146
  });
111
147
 
112
148
  const isOpen = ref(false);
113
149
  const activeMenuItem = ref<string | null>(null);
114
150
  const dropdownButton = ref<HTMLElement | null>(null);
115
151
 
116
- defineEmits(['subMenuItem', 'menuItem', 'actionItem'])
152
+ defineEmits(["subMenuItem", "menuItem", "actionItem"]);
117
153
 
118
154
  const toggleDropdown = () => {
119
155
  isOpen.value = !isOpen.value;
120
- }
156
+ };
121
157
 
122
- const setActiveMenuItem = (text:string) => {
158
+ const setActiveMenuItem = (text: string) => {
123
159
  activeMenuItem.value = text;
124
- }
160
+ };
125
161
 
126
162
  const clearActiveMenuItem = () => {
127
163
  activeMenuItem.value = null;
128
- }
164
+ };
129
165
 
130
166
  onClickOutside(dropdownButton, () => {
131
167
  isOpen.value = false;
132
168
  });
133
169
  </script>
134
170
 
135
- <style lang="scss" scoped>
136
- </style>
171
+ <style lang="scss" scoped></style>
@@ -48,3 +48,5 @@ export { default as EUITooltip } from "./tooltip/EUITooltip.vue";
48
48
  export { default as EUISearch } from "./searchInput/EUISearch.vue";
49
49
  export { default as EUISearchExpand } from "./searchexpand/EUISearchExpand.vue";
50
50
  export { default as EUISearchToggle } from "./searchexpand/EUISearchToggle.vue";
51
+
52
+ export { default as EUIBreadcrumb } from "./breadcrumb/EUIBreadcrumb.vue";
@@ -44,6 +44,17 @@ const meta: Meta<typeof EUIModal> = {
44
44
  "Prevents the modal from being closed by clicking on the backdrop or pressing the Escape key.",
45
45
  defaultValue: false,
46
46
  },
47
+ size: {
48
+ control: {
49
+ type: "select",
50
+ options: ["xs", "sm", "md", "lg", "xl", "full"],
51
+ },
52
+ description: "Size of the slideover.",
53
+ defaultValue: "sm",
54
+ table: {
55
+ defaultValue: { summary: "sm" },
56
+ },
57
+ },
47
58
  },
48
59
  },
49
60
  parameters: {
@@ -58,6 +69,15 @@ type Story = StoryObj<typeof meta>;
58
69
 
59
70
  // Default EUIModal story with basic content
60
71
  export const Default: Story = {
72
+ argTypes: {
73
+ size: {
74
+ control: "select",
75
+ options: ["xs", "sm", "md", "lg", "full"],
76
+ persistent: false,
77
+ slimHeader: false,
78
+ visibleClose: true,
79
+ },
80
+ },
61
81
  args: {
62
82
  isVisible: false,
63
83
  },
@@ -3,16 +3,18 @@
3
3
  <Transition name="modal" appear>
4
4
  <div
5
5
  v-if="isVisible"
6
- class="fixed inset-0 z-50 flex flex-col items-center justify-end sm:justify-center"
6
+ class="fixed z-50 flex flex-col items-center justify-end inset-2 sm:justify-center"
7
7
  @click.self="closeModal"
8
8
  >
9
9
  <div
10
10
  class="backdrop fixed inset-0 z-[-1] w-screen h-screen bg-black/50 pointer-events-none overflow-hidden"
11
11
  ></div>
12
12
  <div
13
- class="bg-white shadow-lg max-w-lg w-full max-h-[calc(100svh-3rem)] md:h-auto overflow-hidden relative"
14
13
  :class="[
14
+ 'bg-white shadow-lg w-full overflow-hidden relative flex flex-col justify-between',
15
+ slideClass,
15
16
  roundedClass !== '' ? roundedClass : 'rounded-t-3xl md:rounded-2xl',
17
+ size === 'full' ? 'h-full max-h-svh' : 'max-h-[calc(100svh-3rem)] md:h-auto'
16
18
  ]"
17
19
  >
18
20
  <template v-if="$slots.header">
@@ -55,14 +57,14 @@
55
57
  <template v-if="$slots.content">
56
58
  <slot name="content"></slot>
57
59
  </template>
58
- <div v-else class="p-4 border-t border-b border-gray-200">
60
+ <div v-else class="p-4 border-t border-b border-gray-200 max-h-[calc(100svh-3rem)] flex-1">
59
61
  <slot></slot>
60
62
  </div>
61
63
 
62
64
  <template v-if="$slots.footer">
63
65
  <slot name="footer"></slot>
64
66
  </template>
65
- <div v-else class="flex items-center justify-end p-4 space-x-2">
67
+ <div v-else class="sticky bottom-0 flex items-center justify-end float-none p-4 space-x-2">
66
68
  <button
67
69
  @click="closeModal"
68
70
  class="px-4 py-2 text-base font-semibold tracking-wide text-gray-600 transition-colors duration-75 bg-white rounded-md hover:bg-gray-100"
@@ -83,7 +85,14 @@
83
85
  </template>
84
86
 
85
87
  <script lang="ts">
86
- import { defineComponent, onMounted, onUnmounted, watch } from "vue";
88
+ import {
89
+ defineComponent,
90
+ onMounted,
91
+ onUnmounted,
92
+ watch,
93
+ computed,
94
+ type PropType,
95
+ } from "vue";
87
96
 
88
97
  export default defineComponent({
89
98
  name: "Modal",
@@ -112,9 +121,27 @@ export default defineComponent({
112
121
  type: Boolean,
113
122
  default: false,
114
123
  },
124
+ size: {
125
+ type: String as PropType<"xs" | "sm" | "md" | "lg" | "xl" | "full">,
126
+ default: "sm",
127
+ },
115
128
  },
116
129
  emits: ["update:isVisible", "confirm"],
117
130
  setup(props, { emit }) {
131
+ const slideClass = computed(() => {
132
+ const sizeClass = {
133
+ full: "max-w-screen",
134
+ xl: "max-w-screen-lg min-w-[100svw] sm:min-w-[1024px]",
135
+ lg: "max-w-2xl min-w-[100svw] sm:min-w-[42rem]",
136
+ md: "max-w-xl min-w-[100svw] sm:min-w-[36rem]",
137
+ sm: "max-w-lg min-w-[100svw] sm:min-w-[32rem]",
138
+ xs: "max-w-md min-w-[100svw] sm:min-w-[28rem]",
139
+ };
140
+
141
+ const slideWidth = sizeClass[props.size];
142
+ return slideWidth;
143
+ });
144
+
118
145
  // Methods
119
146
  const closeModal = () => {
120
147
  if (!props.persistent) {
@@ -143,9 +170,10 @@ export default defineComponent({
143
170
  window.removeEventListener("keydown", handleKeydown);
144
171
  });
145
172
  return {
146
- closeModal
173
+ closeModal,
174
+ slideClass,
147
175
  };
148
- }
176
+ },
149
177
  });
150
178
  </script>
151
179
 
@@ -160,7 +188,7 @@ export default defineComponent({
160
188
  }
161
189
  .modal-enter-to,
162
190
  .modal-leave-from {
163
- @apply opacity-100;
191
+ @apply opacity-100;
164
192
  }
165
193
 
166
194
  .backdrop {
@@ -23,7 +23,7 @@ const meta: Meta<typeof EUISlideover> = {
23
23
  },
24
24
  },
25
25
  size: {
26
- control: { type: "select", options: ["xs", "sm", "md", "lg"] },
26
+ control: { type: "select", options: ["xs", "sm", "md", "lg", "full"] },
27
27
  description: "Size of the slideover.",
28
28
  defaultValue: "xs",
29
29
  table: {
@@ -31,7 +31,7 @@
31
31
  : ' text-gray-500 hover:text-gray-600 rounded-lg bg-transparent z-0 transition-colors duration-300 ease-in origin-center',
32
32
  ]"
33
33
  >
34
- <slot name="title" :tab="tab">
34
+ <slot name="title" :tab="tab" :tabIndex="tabindex" :activeTab="activeTabIndex">
35
35
  {{ tab?.name }}
36
36
  </slot>
37
37
  </span>
@@ -51,6 +51,7 @@
51
51
  <button
52
52
  v-for="(tab, tabindex) in tabs"
53
53
  :key="tabindex"
54
+ type="button"
54
55
  role="tab"
55
56
  :id="`id-${tab.name}`"
56
57
  :class="[
@@ -64,11 +65,38 @@
64
65
  ]"
65
66
  @click="selectTab(tabindex)"
66
67
  >
67
- <slot name="title" :tab="tab">
68
+ <slot name="title" :tab="tab" :tabIndex="tabindex" :activeTab="activeTabIndex">
68
69
  {{ tab?.name }}
69
70
  </slot>
70
71
  </button>
71
72
  </div>
73
+ <div
74
+ v-else-if="tabStyle === 'shadow'"
75
+ class="justify-start relative z-0 inline-flex items-center gap-0 bg-white/50 rounded-t-lg shadow-[0px_1px_2px_0px_rgba(55,65,81,0.10)]"
76
+ >
77
+ <button
78
+ v-for="(tab, tabindex) in tabs"
79
+ :key="tabindex"
80
+ type="button"
81
+ role="tab"
82
+ :id="`id-${tab.name}`"
83
+ :class="[
84
+ 'px-3 py-1 leading-5 transition-all duration-150 ease-in-out hover:text-gray-800 h-12 rounded-t-lg',
85
+ tabSize === 'sm'
86
+ ? 'text-sm font-medium border-b-2'
87
+ : 'text-base font-semibold border-b-[3px]',
88
+ activeTabIndex === tabindex
89
+ ? 'border-purple-800 text-purple-800 bg-white z-10 rounded-t-lg shadow-[0px_2px_4px_0px_rgba(55,65,81,0.1)]'
90
+ : 'border-transparent text-gray-500 z-0',
91
+ ]"
92
+ @click="selectTab(tabindex)"
93
+ >
94
+ <slot name="title" :tab="tab" :tabIndex="tabindex" :activeTab="activeTabIndex">
95
+ {{ tab?.name }}
96
+ </slot>
97
+ </button>
98
+ </div>
99
+
72
100
  <div
73
101
  v-else
74
102
  class="flex items-center gap-1 p-2 transition-all duration-100"
@@ -76,6 +104,7 @@
76
104
  <button
77
105
  v-for="(tab, tabindex) in tabs"
78
106
  :key="tabindex"
107
+ type="button"
79
108
  role="tab"
80
109
  :id="`id-${tab.name}`"
81
110
  class="px-4 py-1 text-sm font-semibold transition-colors duration-150 ease-in-out border rounded-full"
@@ -86,12 +115,12 @@
86
115
  "
87
116
  @click="selectTab(tabindex)"
88
117
  >
89
- <slot name="title" :tab="tab">
118
+ <slot name="title" :tab="tab" :tabIndex="tabindex" :activeTab="activeTabIndex">
90
119
  {{ tab?.name }}
91
120
  </slot>
92
121
  </button>
93
122
  </div>
94
- <div :class="['py-2 text-base font-normal text-gray-700', contentClass]">
123
+ <div :class="['py-2 text-base font-normal text-gray-700 bg-white relative', contentClass, {'rounded-lg !rounded-tl-none shadow-[0px_-2px_24px_0px_rgba(0,0,0,0.075)] z-20':tabStyle === 'shadow'}]">
95
124
  <slot name="content" :active-tab="tabs[activeTabIndex]">
96
125
  {{ tabs[activeTabIndex]?.content }}
97
126
  </slot>
@@ -110,7 +139,7 @@ interface Tab {
110
139
  const props = defineProps<{
111
140
  tabs: Tab[];
112
141
  defaultActiveIndex?: number;
113
- tabStyle: "rounded" | "border" | "design";
142
+ tabStyle: "rounded" | "border" | "design" | "shadow";
114
143
  contentClass?: string[] | string;
115
144
  tabSize?: "sm" | "md";
116
145
  tabAlign?: "start" | "justify" | "end";