Skip to content

Commit

Permalink
feat: match tab-slider component to related plugin (#41)
Browse files Browse the repository at this point in the history
  • Loading branch information
bpsmartdesign committed Aug 7, 2023
1 parent cde177c commit 3b1205c
Showing 1 changed file with 44 additions and 49 deletions.
93 changes: 44 additions & 49 deletions components/base/BaseTabSlider.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@ const props = withDefaults(
/**
* Controls the number of tabs displayed in a row. Can be 2 or 3.
*/
size?: 2 | 3
length?: 2 | 3
/**
* The size of the tabs.
*/
size?: 'sm' | 'md'
/**
* Controls the shape of the tabs. Can be 'rounded' or 'full'.
*/
shape?: 'straight' | 'rounded' | 'curved' | 'full'
shape?: 'straight' | 'rounded' | 'smooth' | 'curved' | 'full'
/**
* Controls the size of the tabs. Can be condensed or default.
*/
Expand All @@ -34,7 +38,8 @@ const props = withDefaults(
{
selected: undefined,
justify: undefined,
size: 2,
size: 'sm',
length: 2,
shape: undefined,
}
)
Expand All @@ -46,6 +51,27 @@ const shape = computed(
() => props.shape ?? appConfig.nui.defaultShapes?.tabSlider
)
const justifyStyle = {
start: '',
center: 'nui-tabs-centered',
end: 'nui-tabs-end',
}
const sizeStyle = {
sm: 'nui-tabs-sm',
md: 'nui-tabs-md',
}
const shapeStyle = {
straight: '',
rounded: 'nui-tabs-rounded',
smooth: 'nui-tabs-smooth',
curved: 'nui-tabs-curved',
full: 'nui-tabs-full',
}
const lengthStyle = computed(() =>
props.length == 2 ? 'nui-tabs-two-slots' : 'nui-tabs-three-slots'
)
const activeValue = ref<string | undefined>(
props.selected ?? props.tabs[0]?.value
)
Expand All @@ -60,70 +86,39 @@ watch(
activeValue.value = value
}
)
watch(activeValue, (value) => {
emit('update:selected', value)
})
</script>

<template>
<div class="relative">
<div
class="font-alt mb-6 flex"
:class="[
props.justify === 'center' && 'justify-center',
props.justify === 'end' && 'justify-end',
]"
>
<div
class="bg-muted-100 dark:bg-muted-700 relative flex w-full items-center font-sans"
:class="[
shape === 'rounded' && 'rounded-md',
shape === 'curved' && 'rounded-xl',
shape === 'full' && 'rounded-full',
props.condensed ? 'h-8 text-xs' : 'h-10 text-sm',
props.size === 2 && !props.condensed
? 'max-w-[250px]'
: 'max-w-[320px]',
props.size === 2 && props.condensed
? 'max-w-[140px]'
: 'max-w-[210px]',
]"
>
<div
class="nui-tab-slider"
:class="[
props.justify && justifyStyle[props.justify],
shape && shapeStyle[shape],
sizeStyle[props.size],
lengthStyle,
]"
>
<div class="nui-tab-slider-inner">
<div class="nui-tab-slider-track">
<button
v-for="(tab, index) in tabs.slice(0, props.size)"
:key="index"
type="button"
class="relative z-20 flex h-full flex-1 items-center justify-center p-6"
:class="[
activeValue === tab.value ? 'text-white' : 'text-muted-400',
props.size === 2 ? 'w-1/2' : 'w-1/3',
]"
class="nui-tab-slider-item"
:class="[activeValue === tab.value && 'nui-active']"
@keydown.space="toggle(tab?.value)"
@click="toggle(tab?.value)"
>
<span>{{ tab?.label ?? tab?.value }}</span>
</button>
<div
v-show="activeValue"
class="bg-primary-600 absolute start-0 top-0 z-10 h-full transition-all duration-300"
:class="[
activeValue === tabs?.[0]?.value && 'ms-0',
activeValue === tabs?.[1]?.value && props.size === 2 && 'ms-[50%]',
activeValue === tabs?.[1]?.value &&
props.size === 3 &&
'ms-[33.3%]',
activeValue === tabs?.[2]?.value && 'ms-[66.6%]',
props.size === 2 ? 'w-1/2' : 'w-1/3',
shape === 'rounded' && 'rounded-md',
shape === 'curved' && 'rounded-xl',
shape === 'full' && 'rounded-full',
]"
></div>
<div v-show="activeValue" class="nui-tab-slider-naver"></div>
</div>
</div>
<div class="relative block">
<div class="nui-tab-content">
<slot name="tab" :active-value="activeValue"></slot>
</div>
</div>
Expand Down

0 comments on commit 3b1205c

Please sign in to comment.