feat: tabs component

This commit is contained in:
Alexandr
2022-07-05 19:55:18 +03:00
parent 3c342e4473
commit 702088f165
7 changed files with 212 additions and 19 deletions

View File

@@ -1,24 +1,23 @@
<template>
<div class="vp-raw">
<tabs v-model="activeTab">
<tab name="first" title="Проверка">
Проверка
<tabs v-model="activeTab" class="p-5">
<tab name="first" title="First">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Explicabo, id, nisi? Enim excepturi id minus molestias quaerat qui rem repudiandae sed tempore ullam voluptate, voluptatum. Consequuntur illum possimus tempora totam.
</tab>
<tab name="second" title="Проверка1">
Проверка 2
<tab name="second" title="Second">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Assumenda consectetur expedita explicabo facere facilis fugit illo laboriosam minus molestias nulla placeat porro quaerat, quo repellat sapiente similique temporibus voluptate. Nemo!
</tab>
<tab name="third" title="Проверка2">
Проверка 3
<tab name="third" title="Third">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus alias assumenda consequatur, dicta eius eos excepturi hic magnam maxime molestias nisi perferendis provident quia. Aliquam consequatur esse ex sit velit.
</tab>
<tab name="fourth" title="Проверка3" :disabled="true">
Проверка 4
<tab name="fourth" title="Fourth" :disabled="true">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi deleniti dolores ea eligendi quis, ratione repellat temporibus veniam veritatis voluptates. Distinctio enim eos illo incidunt ipsam provident, quaerat quia vel!
</tab>
</tabs>
current tab: {{ activeTab }}
</div>
</template>
<script setup>
import { ref } from 'vue'
import { Tabs, Tab } from '../../../../src/index'
const activeTab = ref('')
const activeTab = ref('first')
</script>

View File

@@ -0,0 +1,23 @@
<template>
<div class="vp-raw">
<tabs variant="pills" v-model="activeTab" class="p-5">
<tab name="first" title="First">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab aspernatur debitis iste libero molestiae mollitia, optio sunt? A, consectetur distinctio, eaque harum iusto laudantium, molestiae nam odio officia pariatur vitae?
</tab>
<tab name="second" title="Second">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aperiam asperiores autem cupiditate, deleniti eligendi exercitationem magnam maiores, minus pariatur provident quasi qui quidem recusandae rem reprehenderit sapiente sequi sint soluta.
</tab>
<tab name="third" title="Third">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam animi aperiam assumenda consectetur, dolorem, dolores, ea eos ipsum itaque iure laudantium nostrum nulla numquam perspiciatis provident qui quod totam voluptatem.
</tab>
<tab name="fourth" title="Fourth" :disabled="true">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Architecto blanditiis cupiditate ea error eveniet hic impedit in labore maxime, minima mollitia nam sapiente sint tempora tempore vel velit veniam, voluptatem.
</tab>
</tabs>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { Tabs, Tab } from '../../../../src/index'
const activeTab = ref('first')
</script>

View File

@@ -0,0 +1,23 @@
<template>
<div class="vp-raw">
<tabs variant="underline" v-model="activeTab" class="p-5">
<tab name="first" title="First">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab aspernatur debitis iste libero molestiae mollitia, optio sunt? A, consectetur distinctio, eaque harum iusto laudantium, molestiae nam odio officia pariatur vitae?
</tab>
<tab name="second" title="Second">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aperiam asperiores autem cupiditate, deleniti eligendi exercitationem magnam maiores, minus pariatur provident quasi qui quidem recusandae rem reprehenderit sapiente sequi sint soluta.
</tab>
<tab name="third" title="Third">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam animi aperiam assumenda consectetur, dolorem, dolores, ea eos ipsum itaque iure laudantium nostrum nulla numquam perspiciatis provident qui quod totam voluptatem.
</tab>
<tab name="fourth" title="Fourth" :disabled="true">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Architecto blanditiis cupiditate ea error eveniet hic impedit in labore maxime, minima mollitia nam sapiente sint tempora tempore vel velit veniam, voluptatem.
</tab>
</tabs>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { Tabs, Tab } from '../../../../src/index'
const activeTab = ref('first')
</script>

View File

@@ -1,5 +1,116 @@
<script setup>
import TabsDefaultExample from './examples/TabsDefaultExample.vue';
import TabsPillsExample from './examples/TabsPillsExample.vue';
import TabsUnderlineExample from './examples/TabsUnderlineExample.vue';
</script>
## Prop - variant (default)
```typescript
export type TabsVariant = 'default' | 'underline' | 'pills'
defineProps({
variant: {
type: String as PropType<TabsVariant>,
default: 'default',
},
})
```
<TabsDefaultExample />
```vue
<script setup>
import { ref } from 'vue'
import { Tabs, Tab } from 'flowbite-vue'
const activeTab = ref('first')
</script>
<template>
<tabs v-model="activeTab" class="p-5"> <!-- class appends to content DIV for all tabs -->
<tab name="first" title="First">
Lorem...
</tab>
<tab name="second" title="Second">
Lorem...
</tab>
<tab name="third" title="Third">
Lorem...
</tab>
<tab name="fourth" title="Fourth" :disabled="true">
Lorem...
</tab>
</tabs>
</template>
```
## Prop - variant (underline)
<TabsUnderlineExample />
```vue
<script setup>
import { ref } from 'vue'
import { Tabs, Tab } from 'flowbite-vue'
const activeTab = ref('first')
</script>
<template>
<tabs variant="underline" v-model="activeTab" class="p-5"> <!-- class appends to content DIV for all tabs -->
<tab name="first" title="First">
Lorem...
</tab>
<tab name="second" title="Second">
Lorem...
</tab>
<tab name="third" title="Third">
Lorem...
</tab>
<tab name="fourth" title="Fourth" :disabled="true">
Lorem...
</tab>
</tabs>
</template>
```
## Prop - variant (pills)
<TabsPillsExample />
```vue
<script setup>
import { ref } from 'vue'
import { Tabs, Tab } from 'flowbite-vue'
const activeTab = ref('first')
</script>
<template>
<tabs variant="pills" v-model="activeTab" class="p-5"> <!-- class appends to content DIV for all tabs -->
<tab name="first" title="First">
Lorem...
</tab>
<tab name="second" title="Second">
Lorem...
</tab>
<tab name="third" title="Third">
Lorem...
</tab>
<tab name="fourth" title="Fourth" :disabled="true">
Lorem...
</tab>
</tabs>
</template>
```
## Prop - directive
Use this props if you want to control which directive to use for rendering every tab content
```typescript
export type TabsVariant = 'default' | 'underline' | 'pills'
defineProps({
directive: {
type: String as PropType<'if' | 'show'>,
default: 'if',
},
})
```

View File

@@ -12,19 +12,24 @@
/>
</ul>
</div>
<slot/>
<div v-bind="$attrs">
<slot />
</div>
</div>
</template>
<script lang="ts" setup>
import { TAB_ACTIVATE_INJECTION_KEY, TAB_STYLE_INJECTION_KEY } from './config'
import {
TAB_ACTIVATE_INJECTION_KEY,
TAB_ACTIVE_NAME_INJECTION_KEY,
TAB_STYLE_INJECTION_KEY,
TAB_VISIBILITY_DIRECTIVE_INJECTION_KEY,
} from './config'
import { useTabsClasses } from './useTabsClasses'
import type { PropType } from 'vue'
import { computed, provide, useSlots } from 'vue'
import { computed, provide, toRef, useSlots } from 'vue'
import { flatten } from '../../utils/flatten'
import TabPane from './components/TabPane/TabPane.vue'
export type TabsVariant = 'default' | 'underline' | 'pills'
const props = defineProps({
variant: {
type: String as PropType<TabsVariant>,
@@ -34,9 +39,12 @@ const props = defineProps({
type: String,
default: '',
},
directive: {
type: String as PropType<'if' | 'show'>,
default: 'if',
},
})
const emit = defineEmits(['update:modelValue'])
const { ulClasses, divClasses } = useTabsClasses(props)
@@ -59,9 +67,21 @@ const modelValueRef = computed({
set: (value: string) => emit('update:modelValue', value),
})
provide(TAB_ACTIVE_NAME_INJECTION_KEY, modelValueRef)
provide(TAB_VISIBILITY_DIRECTIVE_INJECTION_KEY, toRef(props, 'directive'))
const onActivate = (value: string) => {
modelValueRef.value = value
}
provide(TAB_ACTIVATE_INJECTION_KEY, onActivate)
</script>
<script lang="ts">
export default {
inheritAttrs: false,
}
export type TabsVariant = 'default' | 'underline' | 'pills'
</script>

View File

@@ -1,9 +1,21 @@
<template>
<div>
<slot />
<template v-if="directive === 'if'">
<div v-if="activeTab === name">
<slot/>
</div>
</template>
<template v-else-if="directive === 'show'">
<div v-show="activeTab === name">
<slot/>
</div>
</template>
</div>
</template>
<script lang="ts" setup>
import { inject } from 'vue'
import { TAB_ACTIVE_NAME_INJECTION_KEY, TAB_VISIBILITY_DIRECTIVE_INJECTION_KEY } from '../../config'
defineProps({
name: {
type: String,
@@ -18,6 +30,9 @@ defineProps({
default: false,
},
})
const activeTab = inject(TAB_ACTIVE_NAME_INJECTION_KEY, '')
const directive = inject(TAB_VISIBILITY_DIRECTIVE_INJECTION_KEY, 'if')
</script>
<script lang="ts">

View File

@@ -1,2 +1,4 @@
export const TAB_STYLE_INJECTION_KEY = 'flowbite-tab-style-injection'
export const TAB_ACTIVE_NAME_INJECTION_KEY = 'flowbite-tab-active-name-injection'
export const TAB_VISIBILITY_DIRECTIVE_INJECTION_KEY = 'flowbite-tab-visibility-directive-injection'
export const TAB_ACTIVATE_INJECTION_KEY = 'flowbite-tab-activate-func-injection'