refactor(layout-sider): new arrow-circle trigger

This commit is contained in:
07akioni 2021-09-16 01:08:17 +08:00
parent 4f29c12e76
commit c1d6f4ec46
8 changed files with 72 additions and 35 deletions

View File

@ -11,9 +11,10 @@
:native-scrollbar="false"
:collapsed-width="0"
collapse-mode="transform"
trigger-style="top: 240px;"
collapsed-trigger-style="top: 240px; right: -20px;"
bordered
show-trigger="bar"
trigger-style="top: calc(50% - var(--header-height));"
show-trigger="arrow-circle"
v-if="showSider"
>
<n-menu

View File

@ -60,6 +60,7 @@ scroll-to
| bordered | `boolean` | `false` | Whether to show the border. |
| collapse-mode | `'transform' \| 'width'` | `'transform'` | If set to `'width'`, the sider's content width will be actually collapsed. If set to `'transform'`, the sider will only move it's position and won't change its content width. |
| collapsed | `boolean` | `undefined` | Whether the sider is collapsed. It only works for when `position` is `'static'`. |
| collapsed-trigger-style | `string \| Object` | `undefined` | Trigger style when collapsed. |
| collapsed-width | `number` | `48` | Folded width. |
| content-style | `string \| Object` | `undefined` | Style of scrollable content node. |
| default-collapsed | `boolean` | `false` | Default collapsed state in uncontrolled mode. |

View File

@ -60,6 +60,7 @@ scroll-to
| bordered | `boolean` | `false` | 是否显示边框 |
| collapse-mode | `'transform' \| 'width'` | `'transform'` | 如果设定为 `'width'`Sider 的内容宽度将会被实际改变;如果设定为 `'transform'`,边栏将只会移动它的位置而不会改变宽度 |
| collapsed | `boolean` | `undefined` | 边栏是否折叠。只在 `position``'static'` 时生效 |
| collapsed-trigger-style | `string \| Object` | `undefined` | 折叠时触发器样式 |
| collapsed-width | `number` | `48` | 折叠宽度 |
| content-style | `string \| Object` | `undefined` | 可滚动内容节点的样式 |
| default-collapsed | `boolean` | `false` | 非受控模式下的默认折叠状态 |
@ -68,7 +69,7 @@ scroll-to
| position | `'static' \| 'absolute'` | `'static'` | `static` 模式将会把 CSS `position` 设为 `static` `absolute` 模式将会把 CSS `position` 设为 `absolute`,还将 `left`、`top`、`bottom` 设为 `0`。`absolute` 模式在你想将内容在一个固定容器或者将这个页面的布局设为固定位置的时候很有用。你可能需要修改一些 style 来确保它按照你预想的方式展示 |
| show-collapsed-content | `boolean` | `true` | 是否在 `sider` 折叠后展示内部内容 |
| show-trigger | `boolean \| 'bar' \| 'arrow-circle'` | `false` | 内置的触发按钮是否展示 |
| trigger-style | `string \| Object` | `undefined` | 触发样式 |
| trigger-style | `string \| Object` | `undefined` | 触发样式 |
| width | `number \| string` | `272` | 宽度的 CSS 值,为数字时会添加 px |
| on-update:collapsed | `(collapsed: boolean) => void` | `undefined` | 折叠状态发生改变时的回调函数 |

View File

@ -73,6 +73,7 @@ const layoutSiderProps = {
Partial<ScrollbarProps> & { style: CSSProperties }
>,
triggerStyle: [String, Object] as PropType<string | CSSProperties>,
collapsedTriggerStyle: [String, Object] as PropType<string | CSSProperties>,
'onUpdate:collapsed': [Function, Array] as PropType<
MaybeArray<(value: boolean) => void>
>,
@ -205,12 +206,14 @@ export default defineComponent({
} = themeRef.value
const {
siderToggleButtonColor,
siderToggleButtonBorder,
siderToggleBarColor,
siderToggleBarColorHover
} = self
const vars: any = {
'--bezier': cubicBezierEaseInOut,
'--toggle-button-color': siderToggleButtonColor,
'--toggle-button-border': siderToggleButtonBorder,
'--toggle-bar-color': siderToggleBarColor,
'--toggle-bar-color-hover': siderToggleBarColorHover
}
@ -287,16 +290,20 @@ export default defineComponent({
</div>
)}
{showTrigger ? (
showTrigger === 'arrow-circle' ? (
<ToggleButton
showTrigger === 'bar' ? (
<ToggleBar
clsPrefix={mergedClsPrefix}
style={this.triggerStyle}
style={
mergedCollapsed ? this.collapsedTriggerStyle : this.triggerStyle
}
onClick={this.handleTriggerClick}
/>
) : (
<ToggleBar
<ToggleButton
clsPrefix={mergedClsPrefix}
style={this.triggerStyle}
style={
mergedCollapsed ? this.collapsedTriggerStyle : this.triggerStyle
}
onClick={this.handleTriggerClick}
/>
)

View File

@ -1,4 +1,6 @@
import { h, defineComponent, PropType } from 'vue'
import { NBaseIcon } from '../../_internal'
import { ChevronRightIcon } from '../../_internal/icons'
export default defineComponent({
name: 'LayoutToggleButton',
@ -10,17 +12,14 @@ export default defineComponent({
onClick: Function as PropType<(e: MouseEvent) => void>
},
render () {
const { clsPrefix } = this
return (
<div
class={`${this.clsPrefix}-layout-toggle-button`}
onClick={this.onClick}
>
<svg viewBox="0 0 56.06 56.06">
<path
d="M50,22A28,28,0,1,0,78,50,28.06,28.06,0,0,0,50,22ZM65.09,52.16h-25l7.1,7.1a2.16,2.16,0,0,1-3.05,3.05L33.38,51.52a2.15,2.15,0,0,1,0-3L44.16,37.69a2.16,2.16,0,0,1,3.05,3.05l-7.1,7.1h25a2.16,2.16,0,0,1,0,4.32Z"
transform="translate(-21.97 -21.97)"
/>
</svg>
<div class={`${clsPrefix}-layout-toggle-button`} onClick={this.onClick}>
<NBaseIcon clsPrefix={clsPrefix}>
{{
default: () => <ChevronRightIcon />
}}
</NBaseIcon>
</div>
)
}

View File

@ -33,9 +33,11 @@ export default cB('layout-sider', `
border-left: 1px solid var(--border-color);
`),
cM('collapsed', [
cB('layout-toggle-button', `
transform: translateX(-50%) translateY(-50%) rotate(0);
`),
cB('layout-toggle-button', [
cB('base-icon', `
transform: rotate(180deg);
`)
]),
cB('layout-toggle-bar', [
c('&:hover', [
cE('top', {
@ -48,9 +50,13 @@ export default cB('layout-sider', `
])
]),
cB('layout-toggle-button', `
transform: translateX(-50%) translateY(-50%) rotate(180deg);
left: 0;
`),
transform: translateX(-50%) translateY(-50%);
`, [
cB('base-icon', `
transform: rotate(0);
`)
]),
cB('layout-toggle-bar', `
left: -28px;
transform: rotate(180deg);
@ -76,23 +82,41 @@ export default cB('layout-sider', `
})
])
]),
cB('layout-toggle-button', `
transform: translateX(50%) translateY(-50%) rotate(180deg);
`)
cB('layout-toggle-button', [
cB('base-icon', `
transform: rotate(0);
`)
])
]),
cB('layout-toggle-button', `
transition:
transform .3s var(--bezier),
fill .3s var(--bezier);
color .3s var(--bezier),
right .3s var(--bezier),
left .3s var(--bezier),
border-color .3s var(--bezier),
background-color .3s var(--bezier);
cursor: pointer;
width: 36px;
height: 36px;
width: 24px;
height: 24px;
position: absolute;
top: 50%;
right: 0;
fill: var(--toggle-button-color);
transform: translateX(50%) translateY(-50%) rotate(0);
`),
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
color: var(--text-color);
border: var(--toggle-button-border);
background-color: var(--toggle-button-color);
box-shadow: 0 2px 4px 0px rgba(0, 0, 0, .06);
transform: translateX(50%) translateY(-50%);
`, [
cB('base-icon', `
transition: transform .3s var(--bezier);
transform: rotate(180deg);
`)
]),
cB('layout-toggle-bar', `
cursor: pointer;
height: 72px;

View File

@ -13,6 +13,7 @@ const layoutDark: LayoutTheme = {
const {
textColor2,
bodyColor,
popoverColor,
cardColor,
dividerColor,
scrollbarColor,
@ -35,7 +36,8 @@ const layoutDark: LayoutTheme = {
siderBorderColorInverted: dividerColor,
siderColor: cardColor,
siderColorInverted: cardColor,
siderToggleButtonColor: 'rgba(255, 255, 255, .3)',
siderToggleButtonBorder: '1px solid transparent',
siderToggleButtonColor: popoverColor,
siderToggleBarColor: composite(bodyColor, scrollbarColor),
siderToggleBarColorHover: composite(bodyColor, scrollbarColorHover),
__invertScrollbar: 'false'

View File

@ -6,6 +6,7 @@ import { createTheme } from '../../_mixins'
export const self = (vars: ThemeCommonVars) => {
const {
baseColor,
textColor2,
bodyColor,
cardColor,
@ -32,7 +33,8 @@ export const self = (vars: ThemeCommonVars) => {
siderBorderColorInverted: invertedColor,
siderColor: cardColor,
siderColorInverted: invertedColor,
siderToggleButtonColor: 'rgba(0, 0, 0, .15)',
siderToggleButtonBorder: `1px solid ${dividerColor}`,
siderToggleButtonColor: baseColor,
siderToggleBarColor: composite(bodyColor, scrollbarColor),
siderToggleBarColorHover: composite(bodyColor, scrollbarColorHover),
// hack for inverted background