-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add component bottom-navigation
- Loading branch information
1 parent
00a799b
commit 13dd6bb
Showing
25 changed files
with
1,675 additions
and
0 deletions.
There are no files selected for viewing
116 changes: 116 additions & 0 deletions
116
packages/varlet-vue2-ui/src/bottom-navigation-item/BottomNavigationItem.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
<template> | ||
<button | ||
class="var-bottom-navigation-item" | ||
ref="bottomNavigationItem" | ||
v-ripple | ||
:style="{ | ||
color: computeColorStyle(), | ||
}" | ||
@click="handleClick" | ||
> | ||
<var-icon | ||
v-if="icon && !$slots.icon" | ||
:name="icon" | ||
:namespace="namespace" | ||
class="var-bottom-navigation-item__icon" | ||
/> | ||
<slot name="icon" :active="isActive"></slot> | ||
<var-badge v-if="badge" v-bind="badgeProps" class="var-bottom-navigation-item__badge" /> | ||
<span class="var-bottom-navigation-item__label"> | ||
<template v-if="!$slots.default"> | ||
{{ label }} | ||
</template> | ||
<slot></slot> | ||
</span> | ||
</button> | ||
</template> | ||
|
||
<script> | ||
import Ripple from '../ripple' | ||
import VarBadge from '../badge' | ||
import VarIcon from '../icon' | ||
import { defineComponent } from '../utils/create' | ||
import { props } from './props' | ||
import { createChildrenMixin } from '../utils/mixins/relation' | ||
const defaultBadgeProps = { | ||
type: 'danger', | ||
dot: true, | ||
} | ||
export default defineComponent({ | ||
name: 'VarBottomNavigationItem', | ||
components: { | ||
VarBadge, | ||
VarIcon, | ||
}, | ||
directives: { Ripple }, | ||
mixins: [ | ||
createChildrenMixin('bottomNavigation', { parentKey: 'bottomNavigation', childrenKey: 'bottomNavigationItems' }), | ||
], | ||
inheritAttrs: false, | ||
props, | ||
data: () => ({ | ||
isActive: false, | ||
badgeProps: {}, | ||
}), | ||
mounted() { | ||
this.isActive = this.name === this.bottomNavigation.active || this.index === this.bottomNavigation.active | ||
if (this.isActive) { | ||
this.$refs.bottomNavigationItem.classList.add('var-bottom-navigation-item--active') | ||
} | ||
}, | ||
watch: { | ||
badge: { | ||
handler(newValue) { | ||
this.badgeProps = newValue === true ? defaultBadgeProps : this.badge | ||
}, | ||
immediate: true, | ||
}, | ||
}, | ||
methods: { | ||
computeColorStyle() { | ||
const { activeColor, inactiveColor } = this.bottomNavigation | ||
return this.isActive ? activeColor : inactiveColor | ||
}, | ||
setCurrent(value) { | ||
const _isActive = value === this.index || value === this.name | ||
if (_isActive === this.isActive) { | ||
return | ||
} | ||
this.isActive = _isActive | ||
if (this.isActive) { | ||
this.$refs.bottomNavigationItem.classList.add('var-bottom-navigation-item--active') | ||
} else { | ||
this.$refs.bottomNavigationItem.classList.remove('var-bottom-navigation-item--active') | ||
} | ||
}, | ||
handleClick() { | ||
const { name, getListeners, index } = this | ||
const active = name ?? index | ||
getListeners().onClick?.(active) | ||
this.bottomNavigation.onToggle(active) | ||
}, | ||
}, | ||
}) | ||
</script> | ||
<style lang="less"> | ||
@import '../styles/common'; | ||
@import '../ripple/ripple'; | ||
@import '../badge/badge'; | ||
@import '../icon/icon'; | ||
@import './bottomNavigationItem'; | ||
</style> |
78 changes: 78 additions & 0 deletions
78
packages/varlet-vue2-ui/src/bottom-navigation-item/bottomNavigationItem.less
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
@bottom-navigation-item-font-size: var(--font-size-sm); | ||
@bottom-navigation-item-inactive-color: #646566; | ||
@bottom-navigation-item-active-color: var(--color-primary); | ||
@bottom-navigation-item-active-background-color: #fff; | ||
@bottom-navigation-item-line-height: 1; | ||
@bottom-navigation-item-icon-size: 22px; | ||
@bottom-navigation-item-icon-margin-bottom: 5px; | ||
|
||
:root { | ||
--bottom-navigation-item-font-size: @bottom-navigation-item-font-size; | ||
--bottom-navigation-item-inactive-color: @bottom-navigation-item-inactive-color; | ||
--bottom-navigation-item-active-color: @bottom-navigation-item-active-color; | ||
--bottom-navigation-item-active-background-color: @bottom-navigation-item-active-background-color; | ||
--bottom-navigation-item-line-height: @bottom-navigation-item-line-height; | ||
--bottom-navigation-item-icon-size: @bottom-navigation-item-icon-size; | ||
--bottom-navigation-item-icon-margin-bottom: @bottom-navigation-item-icon-margin-bottom; | ||
} | ||
|
||
.var-bottom-navigation-item { | ||
height: 100%; | ||
padding: 6px 12px 8px; | ||
position: relative; | ||
display: inline-flex; | ||
flex: 1 1 0%; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: center; | ||
line-height: var(--bottom-navigation-item-line-height); | ||
color: var(--bottom-navigation-item-inactive-color); | ||
cursor: pointer; | ||
user-select: none; | ||
vertical-align: middle; | ||
appearance: none; | ||
text-decoration: none; | ||
background-color: transparent; | ||
outline: 0; | ||
border: 0; | ||
transition: color 250ms, margin 250ms; | ||
|
||
&--active { | ||
color: var(--bottom-navigation-item-active-color); | ||
background-color: var(--bottom-navigation-item-active-background-color); | ||
transition: background-color 250ms; | ||
|
||
.var-bottom-navigation-item__label { | ||
font-size: calc(var(--bottom-navigation-item-font-size) * 1.16); | ||
} | ||
} | ||
|
||
&--right-half-space { | ||
margin-right: calc(var(--bottom-navigation-height) / 2); | ||
} | ||
|
||
&--left-half-space { | ||
margin-left: calc(var(--bottom-navigation-height) / 2); | ||
} | ||
|
||
&--right-space { | ||
margin-right: calc(var(--bottom-navigation-height) + var(--bottom-navigation-fab-offset)); | ||
} | ||
|
||
&__icon { | ||
font-size: var(--bottom-navigation-item-icon-size); | ||
} | ||
|
||
&__badge { | ||
position: absolute; | ||
left: 40px; | ||
transform: translateY(-16px); | ||
} | ||
|
||
&__label { | ||
margin-top: var(--bottom-navigation-item-icon-margin-bottom); | ||
font-size: var(--bottom-navigation-item-font-size); | ||
transition: font-size 0.2s ease 0.1s; | ||
white-space: nowrap; | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
packages/varlet-vue2-ui/src/bottom-navigation-item/docs/zh-CN.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
## API | ||
|
||
### 属性 | ||
|
||
|参数 | 说明 | 类型 | 默认值 | | ||
| ---- | ---- | ---- | ---- | | ||
| `name` | 标签名称,作为匹配的标识符 | _string_ | `-` | | ||
| `icon` | 图标名称,等同于 Icon 组件的 [name 属性](/#/zh-CN/icon) | _string_ | `-` | | ||
| `label` | 标签文字内容 | _string_ | - | | ||
| `namespace` | 图标的命名空间, 可扩展自定义图标库,等同于 Icon 组件的 [namespace 属性](/#/zh-CN/icon) | _string_ | `var-icon` | | ||
| `badge` | 图标右上角徽标 | _boolean \| BadgeProps_ | `false` | | ||
|
||
### 事件 | ||
|
||
|事件名 | 说明 | 回调参数 | | ||
| ---- | ---- | ---- | | ||
| `click` | 点击时触发 | `active: number \| string` | | ||
|
||
### 插槽 | ||
|
||
| 名称 | 说明 | 参数 | | ||
| ---- | ---- | ----| | ||
| `default` | 自定义标签文字内容,会覆盖 `label` 的内容 | `-` | | ||
| `icon` | 自定义图标 | `active: boolean` | |
10 changes: 10 additions & 0 deletions
10
packages/varlet-vue2-ui/src/bottom-navigation-item/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import type { VueConstructor } from 'vue' | ||
import BottomNavigationItem from './BottomNavigationItem.vue' | ||
|
||
BottomNavigationItem.install = function (app: VueConstructor) { | ||
app.component(BottomNavigationItem.name, BottomNavigationItem) | ||
} | ||
|
||
export const _BottomNavigationItemComponent = BottomNavigationItem | ||
|
||
export default BottomNavigationItem |
25 changes: 25 additions & 0 deletions
25
packages/varlet-vue2-ui/src/bottom-navigation-item/props.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import type { PropType } from 'vue' | ||
import type { BadgeProps } from '../../types' | ||
|
||
export const props = { | ||
name: { | ||
type: String, | ||
}, | ||
icon: { | ||
type: String, | ||
}, | ||
label: { | ||
type: String, | ||
}, | ||
namespace: { | ||
type: String, | ||
default: 'var-icon', | ||
}, | ||
badge: { | ||
type: [Boolean, Object] as PropType<boolean | Partial<BadgeProps>>, | ||
default: false, | ||
}, | ||
onClick: { | ||
type: Function as PropType<(active: number | string) => void>, | ||
}, | ||
} |
Oops, something went wrong.