Skip to content

Commit

Permalink
feat(ui/tabs): support props.scrollable and props.indicatorPosition (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
tiny-dust authored Mar 22, 2023
1 parent 81cdcef commit 33ea0d8
Show file tree
Hide file tree
Showing 10 changed files with 117 additions and 9 deletions.
17 changes: 11 additions & 6 deletions packages/varlet-ui/src/tabs/Tabs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@
:class="
classes(
n('tab-wrap'),
[scrollable, n(`--layout-${layoutDirection}-scrollable`)],
[localScrollable, n(`--layout-${layoutDirection}-scrollable`)],
n(`--layout-${layoutDirection}`)
)
"
>
<slot />

<div
:class="classes(n('indicator'), n(`--layout-${layoutDirection}-indicator`))"
:class="classes(n('indicator'), n(`--layout-${layoutDirection}${indicatorPosition}-indicator`))"
:style="{
width: layoutDirection === 'horizontal' ? indicatorWidth : toSizeUnit(indicatorSize),
height: layoutDirection === 'horizontal' ? toSizeUnit(indicatorSize) : indicatorHeight,
Expand Down Expand Up @@ -71,9 +71,12 @@ export default defineComponent({
const indicatorHeight: Ref<string> = ref('0px')
const indicatorX: Ref<string> = ref('0px')
const indicatorY: Ref<string> = ref('0px')
const scrollable: Ref<boolean> = ref(false)
const localScrollable: Ref<boolean> = ref(false)
const scrollerEl: Ref<HTMLElement | null> = ref(null)
const active: ComputedRef<number | string> = computed(() => props.active)
const indicatorPosition: ComputedRef<string> = computed(() =>
props.indicatorPosition === 'reverse' ? '-reverse' : ''
)
const activeColor: ComputedRef<string | undefined> = computed(() => props.activeColor)
const inactiveColor: ComputedRef<string | undefined> = computed(() => props.inactiveColor)
const disabledColor: ComputedRef<string | undefined> = computed(() => props.disabledColor)
Expand Down Expand Up @@ -113,7 +116,7 @@ export default defineComponent({
}
const watchScrollable = () => {
scrollable.value = tabList.length >= 5
localScrollable.value = props.scrollable === 'always' || tabList.length >= 5
}
const moveIndicator = ({ element }: TabProvider) => {
Expand All @@ -131,7 +134,7 @@ export default defineComponent({
}
const scrollToCenter = ({ element }: TabProvider) => {
if (!scrollable.value) {
if (!localScrollable.value) {
return
}
Expand Down Expand Up @@ -193,6 +196,7 @@ export default defineComponent({
)
watch(() => props.active, resize)
watch(() => props.scrollable, resize)
useEventListener(window, 'resize', resize)
return {
Expand All @@ -201,7 +205,8 @@ export default defineComponent({
indicatorHeight,
indicatorX,
indicatorY,
scrollable,
indicatorPosition,
localScrollable,
scrollerEl,
Transition,
toSizeUnit,
Expand Down
29 changes: 29 additions & 0 deletions packages/varlet-ui/src/tabs/__tests__/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ const Wrapper = {
'indicatorSize',
'elevation',
'safeArea',
'scrollable',
'indicatorPosition',
],
data: () => ({
active: 2,
Expand Down Expand Up @@ -219,6 +221,33 @@ describe('test tabs component props', () => {
expect(wrapper.find('.var-tabs--safe-area').exists()).toBe(false)
wrapper.unmount()
})

test('test tabs scrollable', async () => {
const wrapper = mount(Wrapper, {
props: {
scrollable: 'auto',
},
})
await delay(100)
expect(wrapper.find('.var-tabs--layout-horizontal-scrollable').exists()).toBe(false)
wrapper.setProps({ scrollable: 'always' })
await delay(100)
expect(wrapper.find('.var-tabs--layout-horizontal-scrollable').exists()).toBe(true)
wrapper.unmount()
})

test('test tabs indicator-position', async () => {
const wrapper = mount(Wrapper, {
props: {
indicatorPosition: 'reverse',
},
})

expect(wrapper.find('.var-tabs--layout-horizontal-reverse-indicator').exists()).toBe(true)
await wrapper.setProps({ indicatorPosition: 'normal' })
expect(wrapper.find('.var-tabs--layout-horizontal-indicator').exists()).toBe(true)
wrapper.unmount()
})
})

test('test tabs items getSwipe method', async () => {
Expand Down
3 changes: 2 additions & 1 deletion packages/varlet-ui/src/tabs/docs/en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,8 @@ const active = ref(0)
| `sticky-z-index` | Sticky layouts z-index | _number_ | `10` |
| `safe-area` | Whether to enable bottom safe area adaptation | _boolean_ | `false` |
| `offset-top` | Distance offset top | _string \| number_ | `0` |

| `scrollable` | Whether to enable scrollable, optional value of `auto` `always` | _string_ | `auto` |
| `indicator-position` | The position of the indicator, optional value of `normal` `reverse` | _string_ | `normal` |
#### Tab Props

| Prop | Description | Type | Default |
Expand Down
3 changes: 2 additions & 1 deletion packages/varlet-ui/src/tabs/docs/zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,8 @@ const active = ref(0)
| `sticky-z-index` | 粘性布局的层级 | _number_ | `10` |
| `safe-area` | 是否开启底部安全区适配 | _boolean_ | `false` |
| `offset-top` | 吸顶距离 | _string \| number_ | `0` |

| `scrollable` | 是否开启滚动,可选值为 `auto` `always` | _string_ | `auto` |
| `indicator-position` | 选项卡激活指示器的位置,可选值为 `normal` `reverse` | _string_ | `normal` |
#### Tab Props

| 参数 | 说明 | 类型 | 默认值 |
Expand Down
34 changes: 33 additions & 1 deletion packages/varlet-ui/src/tabs/example/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ const actives = reactive({
active5: 0,
active6: 0,
active7: 0,
active8: 0,
activeRelation: 0,
})
const { active, active2, active3, active4, active5, active6, active7, activeRelation } = toRefs(actives)
const { active, active2, active3, active4, active5, active6, active7, active8, activeRelation } = toRefs(actives)
const theme = ref('lightTheme')
const tabItemStyle = computed(() => ({
Expand Down Expand Up @@ -164,6 +165,37 @@ watchDarkMode(dark, (mode) => {
<var-tab>{{ pack.option }}3</var-tab>
</var-tabs>

<app-type>{{ pack.indicatorPosition }}</app-type>
<var-tabs
elevation
indicator-position="reverse"
color="var(--color-primary)"
active-color="#fff"
inactive-color="hsla(0, 0%, 100%, .6)"
v-model:active="active8"
>
<var-tab>{{ pack.option }}1</var-tab>
<var-tab>{{ pack.option }}2</var-tab>
<var-tab>{{ pack.option }}3</var-tab>
</var-tabs>

<app-type></app-type>

<var-tabs
elevation
class="vertical-tabs"
indicator-position="reverse"
layout-direction="vertical"
color="var(--color-primary)"
active-color="#fff"
inactive-color="hsla(0, 0%, 100%, .6)"
v-model:active="active8"
>
<var-tab>{{ pack.option }}1</var-tab>
<var-tab>{{ pack.option }}2</var-tab>
<var-tab>{{ pack.option }}3</var-tab>
</var-tabs>

<div style="height: 120vh"></div>
</template>

Expand Down
1 change: 1 addition & 0 deletions packages/varlet-ui/src/tabs/example/locale/en-US.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export default {
viewRelation: 'View Relation',
option: 'Option',
stickyLayout: 'Sticky Layout',
indicatorPosition: 'Indicator Position',
text:
'The way she came into the place.\n' +
'I knew right then and there.\n' +
Expand Down
1 change: 1 addition & 0 deletions packages/varlet-ui/src/tabs/example/locale/zh-CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export default {
viewRelation: '视图联动',
option: '选项',
stickyLayout: '开启粘性布局',
indicatorPosition: '指示器位置',
text:
'呜啦啦啦火车笛,随着奔腾的马蹄。\n' +
'小妹妹吹着口琴,夕阳下美了剪影。\n' +
Expand Down
18 changes: 18 additions & 0 deletions packages/varlet-ui/src/tabs/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ function directionValidator(direction: string) {
return ['horizontal', 'vertical'].includes(direction)
}

function scrollableValidator(scrollable: string) {
return ['auto', 'always'].includes(scrollable)
}

function positionValidator(pos: string) {
return ['normal', 'reverse'].includes(pos)
}

export const props = {
active: {
type: [String, Number],
Expand Down Expand Up @@ -58,6 +66,16 @@ export const props = {
type: Boolean,
default: false,
},
scrollable: {
type: String as PropType<'auto' | 'always'>,
default: 'auto',
validator: scrollableValidator,
},
indicatorPosition: {
type: String as PropType<'normal' | 'reverse'>,
default: 'normal',
validator: positionValidator,
},
onClick: defineListenerProp<(active: string | number) => void>(),
onChange: defineListenerProp<(active: string | number) => void>(),
'onUpdate:active': defineListenerProp<(active: string | number) => void>(),
Expand Down
14 changes: 14 additions & 0 deletions packages/varlet-ui/src/tabs/tabs.less
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@
height: var(--tabs-indicator-size);
background: var(--tabs-indicator-background);
}

&-reverse-indicator {
left: 0;
top: 0;
height: var(--tabs-indicator-size);
background: var(--tabs-indicator-background);
}
}

&--layout-vertical {
Expand All @@ -73,6 +80,13 @@
width: var(--tabs-indicator-size);
background: var(--tabs-indicator-background);
}

&-reverse-indicator {
right: 0;
top: 0;
width: var(--tabs-indicator-size);
background: var(--tabs-indicator-background);
}
}

&--item-horizontal {
Expand Down
6 changes: 6 additions & 0 deletions packages/varlet-ui/types/tabs.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { VNode } from 'vue'

export declare const tabsProps: Record<string, any>

export type TabsScrollable = 'auto' | 'always'

export type TabsIndicatorPosition = 'normal' | 'reverse'

export { TabsDirection }

export interface TabsProps extends BasicAttributes {
Expand All @@ -22,6 +26,8 @@ export interface TabsProps extends BasicAttributes {
stickyZIndex?: number
offsetTop?: string | number
safeArea?: boolean
scrollable?: TabsScrollable
indicatorPosition?: TabsIndicatorPosition
onClick?: ListenerProp<(active: string | number) => void>
onChange?: ListenerProp<(active: string | number) => void>
'onUpdate:active'?: ListenerProp<(active: string | number) => void>
Expand Down

0 comments on commit 33ea0d8

Please sign in to comment.