Skip to content

Commit db8b686

Browse files
committed
feat(tabs): add tabs component with context, examples, and styles
1 parent 695bf54 commit db8b686

29 files changed

+887
-0
lines changed

packages/vue/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
"@destyler/splitter": "catalog:prod",
7676
"@destyler/steps": "catalog:prod",
7777
"@destyler/switch": "catalog:prod",
78+
"@destyler/tabs": "catalog:prod",
7879
"@destyler/utils": "catalog:prod",
7980
"@destyler/vue": "catalog:prod",
8081
"@destyler/xstate": "catalog:prod"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { anatomy as tabsAnatomy } from '@destyler/tabs'
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<script lang="ts">
2+
import type { ContentProps } from '@destyler/tabs'
3+
import type { PolymorphicProps } from '~/factory'
4+
5+
export interface TabContentProps extends ContentProps, PolymorphicProps {}
6+
</script>
7+
8+
<script setup lang="ts">
9+
import { useForwardExpose } from '~/composables'
10+
import { useRenderStrategyProps } from '~/composables'
11+
import { useTabsContext } from '../composables/use-tabs-context'
12+
import { Presence } from '~/components/presence'
13+
14+
defineOptions({
15+
name: 'TabContent',
16+
})
17+
18+
const props = defineProps<TabContentProps>()
19+
const tabs = useTabsContext()
20+
const renderStrategy = useRenderStrategyProps()
21+
22+
useForwardExpose()
23+
</script>
24+
25+
<template>
26+
<Presence
27+
v-bind="tabs.getContentProps(props)"
28+
:present="tabs.value === props.value"
29+
:lazy-mount="renderStrategy.lazyMount"
30+
:unmount-on-exit="renderStrategy.unmountOnExit"
31+
:immediate="true"
32+
>
33+
<slot />
34+
</Presence>
35+
</template>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<script lang="ts">
2+
import type { SlotsType, UnwrapRef } from 'vue'
3+
import type { UseTabsContext } from '../composables/use-tabs-context'
4+
5+
export interface TabsContextProps
6+
extends SlotsType<{
7+
default: UnwrapRef<UseTabsContext>
8+
}> {}
9+
</script>
10+
11+
<script setup lang="ts">
12+
import { useTabsContext } from '../composables/use-tabs-context'
13+
14+
defineOptions({
15+
name: 'TabsContext',
16+
})
17+
18+
const tabs = useTabsContext()
19+
20+
defineSlots<{
21+
default(tabs: UnwrapRef<UseTabsContext>): unknown
22+
}>()
23+
</script>
24+
25+
<template>
26+
<slot v-bind="tabs"></slot>
27+
</template>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<script lang="ts">
2+
import type { PolymorphicProps } from '~/factory'
3+
4+
export interface TabIndicatorProps extends PolymorphicProps {}
5+
</script>
6+
7+
<script setup lang="ts">
8+
import { ui } from '~/factory'
9+
import { useTabsContext } from '../composables/use-tabs-context'
10+
import { useForwardExpose } from '~/composables'
11+
12+
defineOptions({
13+
name: 'TabIndicator',
14+
})
15+
16+
defineProps<TabIndicatorProps>()
17+
const tabs = useTabsContext()
18+
19+
useForwardExpose()
20+
</script>
21+
22+
<template>
23+
<ui.div v-bind="tabs.getIndicatorProps()" :as-child="asChild">
24+
<slot />
25+
</ui.div>
26+
</template>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<script lang="ts">
2+
import type { PolymorphicProps } from '~/factory'
3+
4+
export interface TabListProps extends PolymorphicProps {}
5+
</script>
6+
7+
<script setup lang="ts">
8+
import { ui } from '~/factory'
9+
import { useTabsContext } from '../composables/use-tabs-context'
10+
import { useForwardExpose } from '~/composables'
11+
12+
defineOptions({
13+
name: 'TabList',
14+
})
15+
16+
defineProps<TabListProps>()
17+
const tabs = useTabsContext()
18+
19+
useForwardExpose()
20+
</script>
21+
22+
<template>
23+
<ui.div v-bind="tabs.getListProps()" :as-child="asChild">
24+
<slot />
25+
</ui.div>
26+
</template>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<script lang="ts">
2+
import type { BooleanDefaults } from '~/types'
3+
import type { RenderStrategyProps } from '~/composables'
4+
import type { PolymorphicProps } from '~/factory'
5+
import type { RootEmits, RootProps } from '../types'
6+
7+
export interface TabsRootProps extends RootProps, RenderStrategyProps, PolymorphicProps {}
8+
export interface TabsRootEmits extends RootEmits {}
9+
</script>
10+
11+
<script setup lang="ts">
12+
import { computed } from 'vue'
13+
import { RenderStrategyPropsProvider, useForwardExpose } from '~/composables'
14+
import { ui } from '~/factory'
15+
import { useTabs } from '../composables/use-tabs'
16+
import { TabsProvider } from '../composables/use-tabs-context'
17+
18+
defineOptions({
19+
name: 'TabsRoot',
20+
})
21+
22+
const props = withDefaults(defineProps<TabsRootProps>(), {
23+
composite: undefined,
24+
deselectable: undefined,
25+
loopFocus: undefined,
26+
} satisfies BooleanDefaults<RootProps>)
27+
28+
const emits = defineEmits<TabsRootEmits>()
29+
30+
const tabs = useTabs(props, emits)
31+
32+
TabsProvider(tabs)
33+
RenderStrategyPropsProvider(computed(() => ({ lazyMount: props.lazyMount, unmountOnExit: props.unmountOnExit })))
34+
35+
useForwardExpose()
36+
</script>
37+
38+
<template>
39+
<ui.div v-bind="tabs.getRootProps()" :as-child="asChild">
40+
<slot />
41+
</ui.div>
42+
</template>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<script lang="ts">
2+
import type { UnwrapRef } from 'vue'
3+
import type { RenderStrategyProps } from '~/composables'
4+
import type { PolymorphicProps } from '~/factory'
5+
import type { UseTabsReturn } from '../composables/use-tabs'
6+
7+
interface RootProviderProps {
8+
value: UnwrapRef<UseTabsReturn>
9+
}
10+
11+
export interface TabsRootProviderProps extends RootProviderProps, RenderStrategyProps, PolymorphicProps {}
12+
</script>
13+
14+
<script setup lang="ts">
15+
import { computed } from 'vue'
16+
import { RenderStrategyPropsProvider, useForwardExpose } from '~/composables'
17+
import { ui } from '~/factory'
18+
import { TabsProvider } from '../composables/use-tabs-context'
19+
20+
defineOptions({
21+
name: 'TabsRootProvider',
22+
})
23+
24+
const props = defineProps<TabsRootProviderProps>()
25+
const tabs = computed(() => props.value)
26+
27+
TabsProvider(tabs)
28+
RenderStrategyPropsProvider(computed(() => ({ lazyMount: props.lazyMount, unmountOnExit: props.unmountOnExit })))
29+
30+
useForwardExpose()
31+
</script>
32+
33+
<template>
34+
<ui.div v-bind="tabs.getRootProps()" :as-child="asChild">
35+
<slot />
36+
</ui.div>
37+
</template>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<script lang="ts">
2+
import type { TriggerProps } from '@destyler/tabs'
3+
import type { PolymorphicProps } from '~/factory'
4+
5+
export interface TabTriggerProps extends TriggerProps, PolymorphicProps {}
6+
</script>
7+
8+
<script setup lang="ts">
9+
import { ui } from '~/factory'
10+
import { useTabsContext } from '../composables/use-tabs-context'
11+
import { useForwardExpose } from '~/composables'
12+
13+
defineOptions({
14+
name: 'TabTrigger',
15+
})
16+
17+
const props = defineProps<TabTriggerProps>()
18+
const tabs = useTabsContext()
19+
20+
useForwardExpose()
21+
</script>
22+
23+
<template>
24+
<ui.button v-bind="tabs.getTriggerProps(props)" :as-child="asChild">
25+
<slot />
26+
</ui.button>
27+
</template>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import type { UseTabsReturn } from './use-tabs'
2+
import { createContext } from '~/utils'
3+
4+
export interface UseTabsContext extends UseTabsReturn {}
5+
6+
export const [TabsProvider, useTabsContext] = createContext<UseTabsContext>('TabsContext')

0 commit comments

Comments
 (0)