mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-01-30 12:52:43 +08:00
refactor(layout): ts
This commit is contained in:
parent
62242cf442
commit
ddda5c84be
@ -1,6 +0,0 @@
|
|||||||
/* istanbul ignore file */
|
|
||||||
export { default as NLayout } from './src/Layout.vue'
|
|
||||||
export { default as NLayoutContent } from './src/Layout.vue'
|
|
||||||
export { default as NLayoutHeader } from './src/LayoutHeader.vue'
|
|
||||||
export { default as NLayoutFooter } from './src/LayoutFooter.vue'
|
|
||||||
export { default as NLayoutSider } from './src/LayoutSider.vue'
|
|
6
src/layout/index.ts
Normal file
6
src/layout/index.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
/* istanbul ignore file */
|
||||||
|
export { default as NLayout } from './src/Layout'
|
||||||
|
export { default as NLayoutContent } from './src/Layout'
|
||||||
|
export { default as NLayoutHeader } from './src/LayoutHeader'
|
||||||
|
export { default as NLayoutFooter } from './src/LayoutFooter'
|
||||||
|
export { default as NLayoutSider } from './src/LayoutSider'
|
134
src/layout/src/Layout.tsx
Normal file
134
src/layout/src/Layout.tsx
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
import {
|
||||||
|
h,
|
||||||
|
defineComponent,
|
||||||
|
computed,
|
||||||
|
PropType,
|
||||||
|
reactive,
|
||||||
|
inject,
|
||||||
|
provide,
|
||||||
|
ref
|
||||||
|
} from 'vue'
|
||||||
|
import { NScrollbar } from '../../scrollbar'
|
||||||
|
import type { ScrollbarProps, ScrollbarRef } from '../../scrollbar'
|
||||||
|
import { useTheme } from '../../_mixins'
|
||||||
|
import type { ThemeProps } from '../../_mixins'
|
||||||
|
import { layoutLight } from '../styles'
|
||||||
|
import type { LayoutTheme } from '../styles'
|
||||||
|
import style from './styles/layout.cssr'
|
||||||
|
import { positionProp } from './interface'
|
||||||
|
|
||||||
|
export interface LayoutInjection {
|
||||||
|
hasSider: boolean
|
||||||
|
siderWidth: number | null
|
||||||
|
siderCollapsedWidth: number | null
|
||||||
|
siderCollapseMode: 'width' | 'transform' | null
|
||||||
|
siderPosition: 'absolute' | 'static' | null
|
||||||
|
siderCollapsed: boolean | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'Layout',
|
||||||
|
alias: ['LayoutContent'],
|
||||||
|
props: {
|
||||||
|
...(useTheme.props as ThemeProps<LayoutTheme>),
|
||||||
|
position: positionProp,
|
||||||
|
nativeScrollbar: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
scrollbarProps: Object as PropType<Partial<ScrollbarProps>>
|
||||||
|
},
|
||||||
|
setup (props) {
|
||||||
|
const selfRef = ref<HTMLElement | null>(null)
|
||||||
|
const scrollbarRef = ref<ScrollbarRef | null>(null)
|
||||||
|
const themeRef = useTheme('Layout', 'Layout', style, layoutLight, props)
|
||||||
|
const state = reactive<LayoutInjection>({
|
||||||
|
hasSider: false,
|
||||||
|
siderWidth: null,
|
||||||
|
siderCollapsedWidth: null,
|
||||||
|
siderCollapseMode: null,
|
||||||
|
siderPosition: null,
|
||||||
|
siderCollapsed: null
|
||||||
|
})
|
||||||
|
const NLayout = inject<LayoutInjection | null>('NLayout', null)
|
||||||
|
const styleMarginLeftRef = computed(() => {
|
||||||
|
if (NLayout?.hasSider) {
|
||||||
|
if (
|
||||||
|
NLayout.siderPosition === 'absolute' &&
|
||||||
|
props.position === 'absolute'
|
||||||
|
) {
|
||||||
|
if (NLayout.siderCollapsed) {
|
||||||
|
return `${NLayout.siderCollapsedWidth as number}px`
|
||||||
|
} else {
|
||||||
|
return `${NLayout.siderWidth as number}px`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
})
|
||||||
|
const mergedLayoutStyleRef = computed(() => {
|
||||||
|
return {
|
||||||
|
marginLeft: styleMarginLeftRef.value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
function scrollTo (options: ScrollToOptions): void
|
||||||
|
function scrollTo (x: number, y: number): void
|
||||||
|
function scrollTo (options: ScrollToOptions | number, y?: number): void {
|
||||||
|
if (scrollbarRef.value) {
|
||||||
|
scrollbarRef.value.scrollTo(options as any, y as any)
|
||||||
|
} else if (selfRef.value) {
|
||||||
|
selfRef.value.scrollTo(options as any, y as any)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
provide<LayoutInjection>('NLayout', state)
|
||||||
|
return {
|
||||||
|
selfRef,
|
||||||
|
scrollbarRef,
|
||||||
|
state,
|
||||||
|
mergedLayoutStyle: mergedLayoutStyleRef,
|
||||||
|
scrollTo,
|
||||||
|
mergedTheme: themeRef,
|
||||||
|
cssVars: computed(() => {
|
||||||
|
const {
|
||||||
|
common: { cubicBezierEaseInOut },
|
||||||
|
self: { color, textColor }
|
||||||
|
} = themeRef.value
|
||||||
|
return {
|
||||||
|
'--bezier': cubicBezierEaseInOut,
|
||||||
|
'--color': color,
|
||||||
|
'--text-color': textColor
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
ref="selfRef"
|
||||||
|
class={[
|
||||||
|
'n-layout',
|
||||||
|
`n-layout--${this.position}-positioned`,
|
||||||
|
this.state.siderCollapseMode &&
|
||||||
|
`n-layout--${this.state.siderCollapseMode}-collapse-mode`,
|
||||||
|
{
|
||||||
|
'n-layout--has-sider': this.state.hasSider
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
style={[this.mergedLayoutStyle, this.cssVars] as any}
|
||||||
|
>
|
||||||
|
{!this.nativeScrollbar ? (
|
||||||
|
<NScrollbar
|
||||||
|
{...this.scrollbarProps}
|
||||||
|
ref="scrollbarRef"
|
||||||
|
unstableTheme={this.mergedTheme.peers.Scrollbar}
|
||||||
|
unstableThemeOverrides={this.mergedTheme.overrides.Scrollbar}
|
||||||
|
>
|
||||||
|
{this.$slots}
|
||||||
|
</NScrollbar>
|
||||||
|
) : (
|
||||||
|
this.$slots
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
@ -1,134 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div
|
|
||||||
class="n-layout"
|
|
||||||
:class="{
|
|
||||||
[`n-layout--${position}-positioned`]: true,
|
|
||||||
'n-layout--has-sider': hasSider,
|
|
||||||
[`n-layout--${siderCollapseMode}-collapse-mode`]: siderCollapseMode
|
|
||||||
}"
|
|
||||||
:style="mergedLayoutStyle"
|
|
||||||
>
|
|
||||||
<n-scrollbar
|
|
||||||
v-if="!nativeScrollbar"
|
|
||||||
ref="scrollbar"
|
|
||||||
:unstable-theme="mergedTheme.peers.Scrollbar"
|
|
||||||
:unstable-theme-overrides="mergedTheme.overrides.Scrollbar"
|
|
||||||
v-bind="scrollbarProps"
|
|
||||||
>
|
|
||||||
<slot />
|
|
||||||
</n-scrollbar>
|
|
||||||
<slot v-else />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { nextTick, defineComponent, computed } from 'vue'
|
|
||||||
import { NScrollbar } from '../../scrollbar'
|
|
||||||
import { useTheme } from '../../_mixins'
|
|
||||||
import { layoutLight } from '../styles'
|
|
||||||
import layoutModeMixin from './layoutModeMixin'
|
|
||||||
import style from './styles/layout.cssr.js'
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'Layout',
|
|
||||||
alias: ['LayoutContent'],
|
|
||||||
components: {
|
|
||||||
NScrollbar
|
|
||||||
},
|
|
||||||
mixins: [layoutModeMixin],
|
|
||||||
provide () {
|
|
||||||
return {
|
|
||||||
NLayout: this
|
|
||||||
}
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
...useTheme.props,
|
|
||||||
nativeScrollbar: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
scrollbarProps: {
|
|
||||||
type: Object,
|
|
||||||
default: undefined
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setup (props) {
|
|
||||||
const themeRef = useTheme('Layout', 'Layout', style, layoutLight, props)
|
|
||||||
return {
|
|
||||||
mergedTheme: themeRef,
|
|
||||||
cssVars: computed(() => {
|
|
||||||
const {
|
|
||||||
common: { cubicBezierEaseInOut },
|
|
||||||
self: { color, textColor }
|
|
||||||
} = themeRef.value
|
|
||||||
return {
|
|
||||||
'--bezier': cubicBezierEaseInOut,
|
|
||||||
'--color': color,
|
|
||||||
'--text-color': textColor
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
hasSider: false,
|
|
||||||
siderWidth: null,
|
|
||||||
collapsedSiderWidth: null,
|
|
||||||
siderCollapseMode: null,
|
|
||||||
siderPosition: null,
|
|
||||||
siderCollapsed: null,
|
|
||||||
childLayoutTransitionDisabled: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
styleMarginLeft () {
|
|
||||||
const { NLayout } = this
|
|
||||||
if (NLayout && NLayout.hasSider) {
|
|
||||||
if (
|
|
||||||
NLayout.siderPosition === 'absolute' &&
|
|
||||||
this.position === 'absolute'
|
|
||||||
) {
|
|
||||||
if (NLayout.siderCollapsed) {
|
|
||||||
return `${NLayout.collapsedSiderWidth}px`
|
|
||||||
} else {
|
|
||||||
return `${NLayout.siderWidth}px`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
},
|
|
||||||
mergedLayoutStyle () {
|
|
||||||
return Object.assign(
|
|
||||||
{
|
|
||||||
marginLeft: this.styleMarginLeft,
|
|
||||||
transition: this.transitionDisabled ? 'none' : null
|
|
||||||
},
|
|
||||||
this.cssVars
|
|
||||||
)
|
|
||||||
},
|
|
||||||
transitionDisabled () {
|
|
||||||
const { NLayout } = this
|
|
||||||
if (NLayout && NLayout.childLayoutTransitionDisabled) {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
scrollTo (...args) {
|
|
||||||
if (this.$refs.scrollbar) {
|
|
||||||
this.$refs.scrollbar.scrollTo(...args)
|
|
||||||
} else {
|
|
||||||
this.$el.scrollTo(...args)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
blockChildLayoutTransitionOneTick () {
|
|
||||||
this.childLayoutTransitionDisabled = true
|
|
||||||
nextTick(() => {
|
|
||||||
this.childLayoutTransitionDisabled = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
56
src/layout/src/LayoutFooter.tsx
Normal file
56
src/layout/src/LayoutFooter.tsx
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import { h, computed, defineComponent, renderSlot, CSSProperties } from 'vue'
|
||||||
|
import { useTheme } from '../../_mixins'
|
||||||
|
import type { ThemeProps } from '../../_mixins'
|
||||||
|
import { layoutLight } from '../styles'
|
||||||
|
import type { LayoutTheme } from '../styles'
|
||||||
|
import { positionProp } from './interface'
|
||||||
|
import style from './styles/layout-footer.cssr'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'LayoutFooter',
|
||||||
|
props: {
|
||||||
|
...(useTheme.props as ThemeProps<LayoutTheme>),
|
||||||
|
position: positionProp,
|
||||||
|
bordered: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup (props) {
|
||||||
|
const themeRef = useTheme(
|
||||||
|
'Layout',
|
||||||
|
'LayoutFooter',
|
||||||
|
style,
|
||||||
|
layoutLight,
|
||||||
|
props
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
cssVars: computed(() => {
|
||||||
|
const {
|
||||||
|
common: { cubicBezierEaseInOut },
|
||||||
|
self: { footerBorderColor }
|
||||||
|
} = themeRef.value
|
||||||
|
return {
|
||||||
|
'--bezier': cubicBezierEaseInOut,
|
||||||
|
'--footer-border-color': footerBorderColor
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
class={[
|
||||||
|
'n-layout-footer',
|
||||||
|
{
|
||||||
|
[`n-layout-footer--${this.position}-positioned`]: this.position,
|
||||||
|
'n-layout-footer--bordered': this.bordered
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
style={this.cssVars as CSSProperties}
|
||||||
|
>
|
||||||
|
{renderSlot(this.$slots, 'default')}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
@ -1,53 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div
|
|
||||||
class="n-layout-footer"
|
|
||||||
:class="{
|
|
||||||
[`n-layout-footer--${position}-positioned`]: position,
|
|
||||||
[`n-layout-footer--bordered`]: bordered
|
|
||||||
}"
|
|
||||||
:style="cssVars"
|
|
||||||
>
|
|
||||||
<slot />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { computed, defineComponent } from 'vue'
|
|
||||||
import layoutModeMixin from './layoutModeMixin'
|
|
||||||
import { useTheme } from '../../_mixins'
|
|
||||||
import { layoutLight } from '../styles'
|
|
||||||
import style from './styles/layout-footer.cssr.js'
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'LayoutFooter',
|
|
||||||
mixins: [layoutModeMixin],
|
|
||||||
props: {
|
|
||||||
...useTheme.props,
|
|
||||||
bordered: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setup (props) {
|
|
||||||
const themeRef = useTheme(
|
|
||||||
'Layout',
|
|
||||||
'LayoutFooter',
|
|
||||||
style,
|
|
||||||
layoutLight,
|
|
||||||
props
|
|
||||||
)
|
|
||||||
return {
|
|
||||||
cssVars: computed(() => {
|
|
||||||
const {
|
|
||||||
common: { cubicBezierEaseInOut },
|
|
||||||
self: { footerBorderColor }
|
|
||||||
} = themeRef.value
|
|
||||||
return {
|
|
||||||
'--bezier': cubicBezierEaseInOut,
|
|
||||||
'--footer-border-color': footerBorderColor
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
@ -1,28 +1,16 @@
|
|||||||
<template>
|
import { h, defineComponent, computed, CSSProperties } from 'vue'
|
||||||
<div
|
|
||||||
class="n-layout-header"
|
|
||||||
:class="{
|
|
||||||
[`n-layout-header--${position}-positioned`]: position,
|
|
||||||
[`n-layout-header--bordered`]: bordered
|
|
||||||
}"
|
|
||||||
:style="cssVars"
|
|
||||||
>
|
|
||||||
<slot />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { defineComponent, computed } from 'vue'
|
|
||||||
import { useTheme } from '../../_mixins'
|
import { useTheme } from '../../_mixins'
|
||||||
import layoutModeMixin from './layoutModeMixin'
|
import type { ThemeProps } from '../../_mixins'
|
||||||
import { layoutLight } from '../styles'
|
import { layoutLight } from '../styles'
|
||||||
import style from './styles/layout-header.cssr.js'
|
import type { LayoutTheme } from '../styles'
|
||||||
|
import { positionProp } from './interface'
|
||||||
|
import style from './styles/layout-header.cssr'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'LayoutHeader',
|
name: 'LayoutHeader',
|
||||||
mixins: [layoutModeMixin],
|
|
||||||
props: {
|
props: {
|
||||||
...useTheme.props,
|
...(useTheme.props as ThemeProps<LayoutTheme>),
|
||||||
|
position: positionProp,
|
||||||
bordered: {
|
bordered: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
@ -49,6 +37,21 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
class={[
|
||||||
|
'n-layout-header',
|
||||||
|
this.position && `n-layout-header--${this.position}-positioned`,
|
||||||
|
{
|
||||||
|
'n-layout-header--bordered': this.bordered
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
style={this.cssVars as CSSProperties}
|
||||||
|
>
|
||||||
|
{this.$slots}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
|
296
src/layout/src/LayoutSider.tsx
Normal file
296
src/layout/src/LayoutSider.tsx
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
import {
|
||||||
|
h,
|
||||||
|
defineComponent,
|
||||||
|
computed,
|
||||||
|
nextTick,
|
||||||
|
PropType,
|
||||||
|
ref,
|
||||||
|
watch,
|
||||||
|
CSSProperties,
|
||||||
|
toRef,
|
||||||
|
inject,
|
||||||
|
onBeforeUnmount
|
||||||
|
} from 'vue'
|
||||||
|
import { useTheme } from '../../_mixins'
|
||||||
|
import type { ThemeProps } from '../../_mixins'
|
||||||
|
import type { MaybeArray } from '../../_utils'
|
||||||
|
import { call } from '../../_utils'
|
||||||
|
import { NScrollbar } from '../../scrollbar'
|
||||||
|
import type { ScrollbarProps, ScrollbarRef } from '../../scrollbar'
|
||||||
|
import { layoutLight } from '../styles'
|
||||||
|
import type { LayoutTheme } from '../styles'
|
||||||
|
import style from './styles/layout-sider.cssr'
|
||||||
|
import type { LayoutInjection } from './Layout'
|
||||||
|
import ToggleButton from './ToggleButton'
|
||||||
|
import ToggleBar from './ToggleBar'
|
||||||
|
import { positionProp } from './interface'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'LayoutSider',
|
||||||
|
props: {
|
||||||
|
...(useTheme.props as ThemeProps<LayoutTheme>),
|
||||||
|
position: positionProp,
|
||||||
|
bordered: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
collapsedWidth: {
|
||||||
|
type: Number,
|
||||||
|
default: 48
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
type: Number,
|
||||||
|
default: 272
|
||||||
|
},
|
||||||
|
collapseMode: {
|
||||||
|
type: String as PropType<'width' | 'transform'>,
|
||||||
|
default: 'transform'
|
||||||
|
},
|
||||||
|
collapsed: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
showContent: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
showTrigger: {
|
||||||
|
type: [Boolean, String],
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
nativeScrollbar: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
duration: {
|
||||||
|
type: Number,
|
||||||
|
default: 300
|
||||||
|
},
|
||||||
|
scrollbarProps: Object as PropType<Partial<ScrollbarProps>>,
|
||||||
|
triggerStyle: Object as PropType<CSSProperties>,
|
||||||
|
// eslint-disable-next-line vue/prop-name-casing
|
||||||
|
'onUpdate:collapsed': Function as PropType<
|
||||||
|
MaybeArray<(value: boolean) => void>
|
||||||
|
>,
|
||||||
|
// deprecated
|
||||||
|
onExpand: Function as PropType<MaybeArray<() => void>>,
|
||||||
|
onCollapse: Function as PropType<MaybeArray<() => void>>
|
||||||
|
},
|
||||||
|
setup (props) {
|
||||||
|
const selfRef = ref<HTMLElement | null>(null)
|
||||||
|
const scrollbarRef = ref<ScrollbarRef | null>(null)
|
||||||
|
let collapseTimerId: number | null = null
|
||||||
|
const styleWidthRef = ref<string | null>(null)
|
||||||
|
const styleMaxWidthRef = ref<string | null>(null)
|
||||||
|
const NLayout = inject<LayoutInjection | null>('NLayout', null)
|
||||||
|
const styleTransformRef = computed(() => {
|
||||||
|
if (props.collapseMode === 'transform') {
|
||||||
|
if (!props.collapsed) return 'translateX(0)'
|
||||||
|
else return `translateX(-${props.width - props.collapsedWidth}px)`
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
})
|
||||||
|
function scrollTo (options: ScrollToOptions): void
|
||||||
|
function scrollTo (x: number, y: number): void
|
||||||
|
function scrollTo (options: ScrollToOptions | number, y?: number): void {
|
||||||
|
if (scrollbarRef.value) {
|
||||||
|
scrollbarRef.value.scrollTo(options as any, y as any)
|
||||||
|
} else if (selfRef.value) {
|
||||||
|
if (y === undefined) {
|
||||||
|
selfRef.value.scrollTo(options as any)
|
||||||
|
} else {
|
||||||
|
selfRef.value.scrollTo(options as any, y as any)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function handleTriggerClick (): void {
|
||||||
|
const {
|
||||||
|
'onUpdate:collapsed': onUpdateCollapsed,
|
||||||
|
collapsed,
|
||||||
|
// deprecated
|
||||||
|
onExpand,
|
||||||
|
onCollapse
|
||||||
|
} = props
|
||||||
|
if (onUpdateCollapsed) {
|
||||||
|
call(onUpdateCollapsed, !collapsed)
|
||||||
|
}
|
||||||
|
if (collapsed) {
|
||||||
|
if (onExpand) call(onExpand)
|
||||||
|
} else {
|
||||||
|
if (onCollapse) call(onCollapse)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
watch(toRef(props, 'width'), (value) => {
|
||||||
|
if (NLayout) {
|
||||||
|
NLayout.siderWidth = value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
watch(toRef(props, 'collapsedWidth'), (value) => {
|
||||||
|
if (NLayout) {
|
||||||
|
NLayout.siderCollapsedWidth = value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
watch(toRef(props, 'collapseMode'), (value) => {
|
||||||
|
if (NLayout) {
|
||||||
|
NLayout.siderCollapseMode = value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
watch(toRef(props, 'position'), (value) => {
|
||||||
|
if (NLayout) {
|
||||||
|
NLayout.siderPosition = value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
watch(toRef(props, 'collapsed'), (value) => {
|
||||||
|
if (props.collapseMode === 'width') {
|
||||||
|
if (collapseTimerId) {
|
||||||
|
window.clearTimeout(collapseTimerId)
|
||||||
|
}
|
||||||
|
if (value) {
|
||||||
|
styleMaxWidthRef.value = `${props.width}px`
|
||||||
|
void nextTick(() => {
|
||||||
|
void selfRef.value?.offsetWidth
|
||||||
|
styleMaxWidthRef.value = `${props.collapsedWidth}px`
|
||||||
|
})
|
||||||
|
collapseTimerId = window.setTimeout(() => {
|
||||||
|
styleWidthRef.value = `${props.collapsedWidth}px`
|
||||||
|
styleMaxWidthRef.value = null
|
||||||
|
}, props.duration)
|
||||||
|
} else {
|
||||||
|
styleMaxWidthRef.value = `${props.collapsedWidth}px`
|
||||||
|
styleWidthRef.value = `${props.width}px`
|
||||||
|
void nextTick(() => {
|
||||||
|
void selfRef.value?.offsetWidth
|
||||||
|
styleMaxWidthRef.value = `${props.width}px`
|
||||||
|
})
|
||||||
|
collapseTimerId = window.setTimeout(() => {
|
||||||
|
styleMaxWidthRef.value = null
|
||||||
|
}, props.duration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (NLayout) {
|
||||||
|
NLayout.siderCollapsed = value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// onCreated, init
|
||||||
|
if (props.collapseMode === 'width') {
|
||||||
|
if (props.collapsed) {
|
||||||
|
styleWidthRef.value = `${props.collapsedWidth}px`
|
||||||
|
} else {
|
||||||
|
styleWidthRef.value = `${props.width}px`
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
styleWidthRef.value = `${props.width}px`
|
||||||
|
}
|
||||||
|
if (NLayout) {
|
||||||
|
NLayout.hasSider = true
|
||||||
|
NLayout.siderWidth = props.width
|
||||||
|
NLayout.siderCollapsedWidth = props.collapsedWidth
|
||||||
|
NLayout.siderCollapseMode = props.collapseMode
|
||||||
|
NLayout.siderPosition = props.position
|
||||||
|
NLayout.siderCollapsed = props.collapsed
|
||||||
|
}
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
if (NLayout) {
|
||||||
|
NLayout.hasSider = false
|
||||||
|
NLayout.siderWidth = null
|
||||||
|
NLayout.siderCollapsedWidth = null
|
||||||
|
NLayout.siderCollapseMode = null
|
||||||
|
NLayout.siderPosition = null
|
||||||
|
NLayout.siderCollapsed = null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const themeRef = useTheme(
|
||||||
|
'Layout',
|
||||||
|
'LayoutSider',
|
||||||
|
style,
|
||||||
|
layoutLight,
|
||||||
|
props
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
selfRef,
|
||||||
|
scrollbarRef,
|
||||||
|
mergedTheme: themeRef,
|
||||||
|
styleTransform: styleTransformRef,
|
||||||
|
styleMaxWidth: styleMaxWidthRef,
|
||||||
|
styleWidth: styleWidthRef,
|
||||||
|
scrollTo,
|
||||||
|
handleTriggerClick,
|
||||||
|
cssVars: computed(() => {
|
||||||
|
const {
|
||||||
|
common: { cubicBezierEaseInOut },
|
||||||
|
self: {
|
||||||
|
siderColor,
|
||||||
|
siderToggleButtonColor,
|
||||||
|
siderBorderColor,
|
||||||
|
siderToggleBarColor,
|
||||||
|
siderToggleBarColorHover
|
||||||
|
}
|
||||||
|
} = themeRef.value
|
||||||
|
return {
|
||||||
|
'--bezier': cubicBezierEaseInOut,
|
||||||
|
'--sider-color': siderColor,
|
||||||
|
'--sider-border-color': siderBorderColor,
|
||||||
|
'--sider-toggle-button-color': siderToggleButtonColor,
|
||||||
|
'--sider-toggle-bar-color': siderToggleBarColor,
|
||||||
|
'--sider-toggle-bar-color-hover': siderToggleBarColorHover
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<aside
|
||||||
|
ref="selfRef"
|
||||||
|
class={[
|
||||||
|
'n-layout-sider',
|
||||||
|
this.position && [`n-layout-sider--${this.position}-positioned`],
|
||||||
|
{
|
||||||
|
'n-layout-sider--bordered': this.bordered,
|
||||||
|
'n-layout-sider--collapsed': this.collapsed,
|
||||||
|
'n-layout-sider--show-content': this.showContent
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
style={
|
||||||
|
[
|
||||||
|
this.cssVars,
|
||||||
|
{
|
||||||
|
transform: this.styleTransform,
|
||||||
|
maxWidth: this.styleMaxWidth,
|
||||||
|
width: this.styleWidth
|
||||||
|
}
|
||||||
|
] as any
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{!this.nativeScrollbar ? (
|
||||||
|
<NScrollbar
|
||||||
|
ref="scrollbarRef"
|
||||||
|
class="n-layout-sider__content"
|
||||||
|
{...this.scrollbarProps}
|
||||||
|
unstableTheme={this.mergedTheme.peers.Scrollbar}
|
||||||
|
unstableThemeOverrides={this.mergedTheme.overrides.Scrollbar}
|
||||||
|
>
|
||||||
|
{this.$slots}
|
||||||
|
</NScrollbar>
|
||||||
|
) : (
|
||||||
|
<div class="n-layout-sider__content">{this.$slots}</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{this.bordered ? <div class="n-layout-sider__border" /> : null}
|
||||||
|
{this.showTrigger ? (
|
||||||
|
this.showTrigger === 'arrow-circle' ? (
|
||||||
|
<ToggleButton
|
||||||
|
style={this.triggerStyle}
|
||||||
|
onClick={this.handleTriggerClick}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<ToggleBar
|
||||||
|
collapsed={this.collapsed}
|
||||||
|
style={this.triggerStyle}
|
||||||
|
onClick={this.handleTriggerClick}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
) : null}
|
||||||
|
</aside>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
@ -1,284 +0,0 @@
|
|||||||
<template>
|
|
||||||
<aside
|
|
||||||
class="n-layout-sider"
|
|
||||||
:class="{
|
|
||||||
[`n-layout-sider--${position}-positioned`]: position,
|
|
||||||
[`n-layout-sider--bordered`]: bordered,
|
|
||||||
[`n-layout-sider--collapsed`]: collapsed,
|
|
||||||
[`n-layout-sider--show-content`]: showContent
|
|
||||||
}"
|
|
||||||
:style="{
|
|
||||||
...cssVars,
|
|
||||||
transform: styleTransform,
|
|
||||||
maxWidth: styleMaxWidth,
|
|
||||||
width: styleWidth
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<n-scrollbar
|
|
||||||
v-if="!nativeScrollbar"
|
|
||||||
ref="scrollbar"
|
|
||||||
class="n-layout-sider__content"
|
|
||||||
:unstable-theme="NLayout.mergedTheme.peers.Scrollbar"
|
|
||||||
:unstable-theme-overrides="NLayout.mergedTheme.overrides.Scrollbar"
|
|
||||||
v-bind="scrollbarProps"
|
|
||||||
>
|
|
||||||
<slot />
|
|
||||||
</n-scrollbar>
|
|
||||||
<div v-else class="n-layout-sider__content">
|
|
||||||
<slot />
|
|
||||||
</div>
|
|
||||||
<div v-if="bordered" class="n-layout-sider__border" />
|
|
||||||
<template v-if="showTrigger">
|
|
||||||
<toggle-button
|
|
||||||
v-if="showTrigger === 'arrow-circle'"
|
|
||||||
:style="triggerStyle"
|
|
||||||
@click="handleTriggerClick"
|
|
||||||
/>
|
|
||||||
<toggle-bar
|
|
||||||
v-else
|
|
||||||
:collapsed="collapsed"
|
|
||||||
:style="triggerStyle"
|
|
||||||
@click="handleTriggerClick"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</aside>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { defineComponent, computed, nextTick } from 'vue'
|
|
||||||
import { useTheme } from '../../_mixins'
|
|
||||||
import { NScrollbar } from '../../scrollbar'
|
|
||||||
import { layoutLight } from '../styles'
|
|
||||||
import style from './styles/layout-sider.cssr.js'
|
|
||||||
import layoutModeMixin from './layoutModeMixin'
|
|
||||||
import ToggleButton from './ToggleButton.vue'
|
|
||||||
import ToggleBar from './ToggleBar.vue'
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'LayoutSider',
|
|
||||||
components: {
|
|
||||||
ToggleButton,
|
|
||||||
ToggleBar,
|
|
||||||
NScrollbar
|
|
||||||
},
|
|
||||||
mixins: [layoutModeMixin],
|
|
||||||
props: {
|
|
||||||
...useTheme.props,
|
|
||||||
bordered: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
collapsedWidth: {
|
|
||||||
type: Number,
|
|
||||||
default: 48
|
|
||||||
},
|
|
||||||
width: {
|
|
||||||
type: Number,
|
|
||||||
default: 272
|
|
||||||
},
|
|
||||||
collapseMode: {
|
|
||||||
validator (value) {
|
|
||||||
return ['width', 'transform'].includes(value)
|
|
||||||
},
|
|
||||||
default: 'transform'
|
|
||||||
},
|
|
||||||
collapsed: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
showContent: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
showTrigger: {
|
|
||||||
type: [Boolean, String],
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
nativeScrollbar: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
duration: {
|
|
||||||
type: Number,
|
|
||||||
default: 300
|
|
||||||
},
|
|
||||||
scrollbarProps: {
|
|
||||||
type: Object,
|
|
||||||
default: undefined
|
|
||||||
},
|
|
||||||
triggerStyle: {
|
|
||||||
type: Object,
|
|
||||||
default: undefined
|
|
||||||
},
|
|
||||||
// eslint-disable-next-line vue/prop-name-casing
|
|
||||||
'onUpdate:collapsed': {
|
|
||||||
type: Function,
|
|
||||||
default: undefined
|
|
||||||
},
|
|
||||||
// deprecated
|
|
||||||
onExpand: {
|
|
||||||
type: Function,
|
|
||||||
default: undefined
|
|
||||||
},
|
|
||||||
onCollapse: {
|
|
||||||
type: Function,
|
|
||||||
default: undefined
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setup (props) {
|
|
||||||
const themeRef = useTheme(
|
|
||||||
'Layout',
|
|
||||||
'LayoutSider',
|
|
||||||
style,
|
|
||||||
layoutLight,
|
|
||||||
props
|
|
||||||
)
|
|
||||||
return {
|
|
||||||
cssVars: computed(() => {
|
|
||||||
const {
|
|
||||||
common: { cubicBezierEaseInOut },
|
|
||||||
self: {
|
|
||||||
siderColor,
|
|
||||||
siderToggleButtonColor,
|
|
||||||
siderBorderColor,
|
|
||||||
siderToggleBarColor,
|
|
||||||
siderToggleBarColorHover
|
|
||||||
}
|
|
||||||
} = themeRef.value
|
|
||||||
return {
|
|
||||||
'--bezier': cubicBezierEaseInOut,
|
|
||||||
'--sider-color': siderColor,
|
|
||||||
'--sider-border-color': siderBorderColor,
|
|
||||||
'--sider-toggle-button-color': siderToggleButtonColor,
|
|
||||||
'--sider-toggle-bar-color': siderToggleBarColor,
|
|
||||||
'--sider-toggle-bar-color-hover': siderToggleBarColorHover
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
collapseTimerId: null,
|
|
||||||
styleWidth: null,
|
|
||||||
styleMaxWidth: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
styleTransform () {
|
|
||||||
if (this.collapseMode === 'transform') {
|
|
||||||
if (!this.collapsed) return 'translateX(0)'
|
|
||||||
else return `translateX(-${this.width - this.collapsedWidth}px)`
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
width (value) {
|
|
||||||
if (this.NLayout) {
|
|
||||||
this.NLayout.siderWidth = value
|
|
||||||
}
|
|
||||||
},
|
|
||||||
collapsedWidth (value) {
|
|
||||||
if (this.NLayout) {
|
|
||||||
this.NLayout.collapsedWidth = value
|
|
||||||
}
|
|
||||||
},
|
|
||||||
collapseMode (value) {
|
|
||||||
if (this.NLayout) {
|
|
||||||
this.NLayout.siderCollapseMode = value
|
|
||||||
}
|
|
||||||
},
|
|
||||||
position (value) {
|
|
||||||
if (this.NLayout) {
|
|
||||||
this.NLayout.siderPosition = value
|
|
||||||
}
|
|
||||||
},
|
|
||||||
collapsed (value) {
|
|
||||||
if (this.collapseMode === 'width') {
|
|
||||||
if (this.collapseTimerId) {
|
|
||||||
window.clearTimeout(this.collapseTimerId)
|
|
||||||
}
|
|
||||||
if (value) {
|
|
||||||
this.styleMaxWidth = `${this.width}px`
|
|
||||||
nextTick(() => {
|
|
||||||
this.$el.getBoundingClientRect()
|
|
||||||
this.styleMaxWidth = `${this.collapsedWidth}px`
|
|
||||||
})
|
|
||||||
this.collapseTimerId = window.setTimeout(() => {
|
|
||||||
this.styleWidth = `${this.collapsedWidth}px`
|
|
||||||
this.styleMaxWidth = null
|
|
||||||
}, this.duration)
|
|
||||||
} else {
|
|
||||||
this.styleMaxWidth = `${this.collapsedWidth}px`
|
|
||||||
this.styleWidth = `${this.width}px`
|
|
||||||
nextTick(() => {
|
|
||||||
this.$el.getBoundingClientRect()
|
|
||||||
this.styleMaxWidth = `${this.width}px`
|
|
||||||
})
|
|
||||||
this.collapseTimerId = window.setTimeout(() => {
|
|
||||||
this.styleMaxWidth = null
|
|
||||||
}, this.duration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.NLayout) {
|
|
||||||
this.NLayout.siderCollapsed = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created () {
|
|
||||||
if (this.collapseMode === 'width') {
|
|
||||||
if (this.collapsed) {
|
|
||||||
this.styleWidth = `${this.collapsedWidth}px`
|
|
||||||
} else {
|
|
||||||
this.styleWidth = `${this.width}px`
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.styleWidth = `${this.width}px`
|
|
||||||
}
|
|
||||||
const NLayout = this.NLayout
|
|
||||||
if (NLayout) {
|
|
||||||
NLayout.hasSider = true
|
|
||||||
NLayout.siderWidth = this.width
|
|
||||||
NLayout.collapsedSiderWidth = this.collapsedWidth
|
|
||||||
NLayout.siderCollapseMode = this.collapseMode
|
|
||||||
NLayout.siderPosition = this.position
|
|
||||||
NLayout.siderCollapsed = this.collapsed
|
|
||||||
}
|
|
||||||
},
|
|
||||||
beforeUnmount () {
|
|
||||||
const NLayout = this.NLayout
|
|
||||||
if (NLayout) {
|
|
||||||
NLayout.hasSider = false
|
|
||||||
NLayout.siderWidth = null
|
|
||||||
NLayout.collapsedSiderWidth = null
|
|
||||||
NLayout.siderCollapseMode = null
|
|
||||||
NLayout.siderPosition = null
|
|
||||||
NLayout.siderCollapsed = null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
scrollTo (...args) {
|
|
||||||
if (this.$refs.scrollbar) {
|
|
||||||
this.$refs.scrollbar.scrollTo(...args)
|
|
||||||
} else {
|
|
||||||
this.$el.scrollTo(...args)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleTriggerClick () {
|
|
||||||
const {
|
|
||||||
'onUpdate:collapsed': onUpdateCollapsed,
|
|
||||||
collapsed,
|
|
||||||
// deprecated
|
|
||||||
onExpand,
|
|
||||||
onCollapse
|
|
||||||
} = this
|
|
||||||
if (onUpdateCollapsed) onUpdateCollapsed(!collapsed)
|
|
||||||
if (collapsed) {
|
|
||||||
if (onExpand) onExpand()
|
|
||||||
} else {
|
|
||||||
if (onCollapse) onCollapse()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
25
src/layout/src/ToggleBar.tsx
Normal file
25
src/layout/src/ToggleBar.tsx
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { h, defineComponent } from 'vue'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
props: {
|
||||||
|
collapsed: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
class={[
|
||||||
|
'n-layout-toggle-bar',
|
||||||
|
{
|
||||||
|
'n-layout-toggle-bar--collapsed': this.collapsed
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<div class="n-layout-toggle-bar__top" />
|
||||||
|
<div class="n-layout-toggle-bar__bottom" />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
@ -1,22 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div
|
|
||||||
class="n-layout-toggle-bar"
|
|
||||||
:class="{
|
|
||||||
'n-layout-toggle-bar--collapsed': collapsed
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<div class="n-layout-toggle-bar__top" />
|
|
||||||
<div class="n-layout-toggle-bar__bottom" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
collapsed: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
17
src/layout/src/ToggleButton.tsx
Normal file
17
src/layout/src/ToggleButton.tsx
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { h, defineComponent } from 'vue'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'LayoutToggleButton',
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div class="n-layout-toggle-button">
|
||||||
|
<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>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
@ -1,10 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="n-layout-toggle-button">
|
|
||||||
<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>
|
|
||||||
</template>
|
|
6
src/layout/src/interface.ts
Normal file
6
src/layout/src/interface.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { PropType } from 'vue'
|
||||||
|
|
||||||
|
export const positionProp = {
|
||||||
|
type: String as PropType<'static' | 'absolute'>,
|
||||||
|
default: 'static'
|
||||||
|
}
|
@ -1,15 +0,0 @@
|
|||||||
export default {
|
|
||||||
inject: {
|
|
||||||
NLayout: {
|
|
||||||
default: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
position: {
|
|
||||||
default: 'static',
|
|
||||||
validator (value) {
|
|
||||||
return ['static', 'absolute'].includes(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -108,15 +108,7 @@ export default cB('layout-sider', `
|
|||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
`, [
|
`),
|
||||||
cE('content', `
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
`)
|
|
||||||
]),
|
|
||||||
cM('bordered', [
|
cM('bordered', [
|
||||||
cE('border', {
|
cE('border', {
|
||||||
backgroundColor: 'var(--sider-border-color)'
|
backgroundColor: 'var(--sider-border-color)'
|
@ -1,8 +1,9 @@
|
|||||||
import { composite } from 'seemly'
|
import { composite } from 'seemly'
|
||||||
import { commonDark } from '../../_styles/new-common'
|
import { commonDark } from '../../_styles/new-common'
|
||||||
import { scrollbarDark } from '../../scrollbar/styles'
|
import { scrollbarDark } from '../../scrollbar/styles'
|
||||||
|
import type { LayoutTheme } from './light'
|
||||||
|
|
||||||
export default {
|
const layoutDark: LayoutTheme = {
|
||||||
name: 'Layout',
|
name: 'Layout',
|
||||||
common: commonDark,
|
common: commonDark,
|
||||||
peers: {
|
peers: {
|
||||||
@ -31,3 +32,5 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default layoutDark
|
@ -1,2 +0,0 @@
|
|||||||
export { default as layoutDark } from './dark.js'
|
|
||||||
export { default as layoutLight } from './light.js'
|
|
3
src/layout/styles/index.ts
Normal file
3
src/layout/styles/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export { default as layoutDark } from './dark'
|
||||||
|
export { default as layoutLight } from './light'
|
||||||
|
export type { LayoutTheme, LayoutThemeVars } from './light'
|
@ -1,33 +0,0 @@
|
|||||||
import { composite } from 'seemly'
|
|
||||||
import { commonLight } from '../../_styles/new-common'
|
|
||||||
import { scrollbarLight } from '../../scrollbar/styles'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'Layout',
|
|
||||||
common: commonLight,
|
|
||||||
peers: {
|
|
||||||
Scrollbar: scrollbarLight
|
|
||||||
},
|
|
||||||
self (vars) {
|
|
||||||
const {
|
|
||||||
textColor2,
|
|
||||||
bodyColor,
|
|
||||||
cardColor,
|
|
||||||
dividerColorOverlay,
|
|
||||||
scrollbarColorOverlay,
|
|
||||||
scrollbarColorHoverOverlay
|
|
||||||
} = vars
|
|
||||||
return {
|
|
||||||
textColor: textColor2,
|
|
||||||
color: bodyColor,
|
|
||||||
headerColor: cardColor,
|
|
||||||
headerBorderColor: dividerColorOverlay,
|
|
||||||
footerBorderColor: dividerColorOverlay,
|
|
||||||
siderBorderColor: dividerColorOverlay,
|
|
||||||
siderColor: cardColor,
|
|
||||||
siderToggleButtonColor: 'rgba(0, 0, 0, .15)',
|
|
||||||
siderToggleBarColor: composite(bodyColor, scrollbarColorOverlay),
|
|
||||||
siderToggleBarColorHover: composite(bodyColor, scrollbarColorHoverOverlay)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
42
src/layout/styles/light.ts
Normal file
42
src/layout/styles/light.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import { composite } from 'seemly'
|
||||||
|
import { commonLight } from '../../_styles/new-common'
|
||||||
|
import type { ThemeCommonVars } from '../../_styles/new-common'
|
||||||
|
import { scrollbarLight } from '../../scrollbar/styles'
|
||||||
|
import { createTheme } from '../../_mixins'
|
||||||
|
|
||||||
|
const self = (vars: ThemeCommonVars) => {
|
||||||
|
const {
|
||||||
|
textColor2,
|
||||||
|
bodyColor,
|
||||||
|
cardColor,
|
||||||
|
dividerColorOverlay,
|
||||||
|
scrollbarColorOverlay,
|
||||||
|
scrollbarColorHoverOverlay
|
||||||
|
} = vars
|
||||||
|
return {
|
||||||
|
textColor: textColor2,
|
||||||
|
color: bodyColor,
|
||||||
|
headerColor: cardColor,
|
||||||
|
headerBorderColor: dividerColorOverlay,
|
||||||
|
footerBorderColor: dividerColorOverlay,
|
||||||
|
siderBorderColor: dividerColorOverlay,
|
||||||
|
siderColor: cardColor,
|
||||||
|
siderToggleButtonColor: 'rgba(0, 0, 0, .15)',
|
||||||
|
siderToggleBarColor: composite(bodyColor, scrollbarColorOverlay),
|
||||||
|
siderToggleBarColorHover: composite(bodyColor, scrollbarColorHoverOverlay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type LayoutThemeVars = ReturnType<typeof self>
|
||||||
|
|
||||||
|
const layoutLight = createTheme({
|
||||||
|
name: 'Layout',
|
||||||
|
common: commonLight,
|
||||||
|
peers: {
|
||||||
|
Scrollbar: scrollbarLight
|
||||||
|
},
|
||||||
|
self
|
||||||
|
})
|
||||||
|
|
||||||
|
export default layoutLight
|
||||||
|
export type LayoutTheme = typeof layoutLight
|
Loading…
Reference in New Issue
Block a user