feat(layout): clsPrefix

This commit is contained in:
07akioni 2021-04-17 16:37:47 +08:00
parent 73e530085e
commit 28d040bc84
9 changed files with 125 additions and 84 deletions

View File

@ -21,7 +21,7 @@ import NLayoutHeader from '../../../layout/src/LayoutHeader'
import type { LayoutHeaderProps } from '../../../layout/src/LayoutHeader'
import { createItems } from './utils'
import type { Item } from './interface'
import { LayoutRef } from '../../../layout'
import { LayoutInst } from '../../../layout'
export default defineComponent({
name: 'ServiceLayout',
@ -33,14 +33,10 @@ export default defineComponent({
},
name: String,
headerProps: Object as PropType<
Partial<LayoutHeaderProps & { style: CSSProperties }>
>,
contentProps: Object as PropType<
Partial<LayoutProps & { style: CSSProperties }>
>,
siderProps: Object as PropType<
Partial<LayoutSiderProps & { style: CSSProperties }>
LayoutHeaderProps & { style: CSSProperties }
>,
contentProps: Object as PropType<LayoutProps & { style: CSSProperties }>,
siderProps: Object as PropType<LayoutSiderProps & { style: CSSProperties }>,
value: String,
'onUpdate:value': Function as PropType<(value: string) => void>,
// deprecated
@ -55,7 +51,7 @@ export default defineComponent({
setup (props) {
const router = useRouter()
const route = useRoute()
const bodyLayoutInstRef = ref<LayoutRef | null>(null)
const bodyLayoutInstRef = ref<LayoutInst | null>(null)
const uncontrolledValueRef = ref<string | null>(null)
const controlledValueRef = toRef(props, 'value')
const mergedValueRef = useMergedState(
@ -94,7 +90,7 @@ export default defineComponent({
}
doUpdateValue(value)
}
const scrollTo: LayoutRef['scrollTo'] = (...args: any[]): void => {
const scrollTo: LayoutInst['scrollTo'] = (...args: any[]): void => {
;(bodyLayoutInstRef.value?.scrollTo as Function)(...args)
}
function syncPath (path?: string, items?: Item[]): void {

View File

@ -1,7 +1,13 @@
/* 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'
export type { LayoutRef } from './src/interface'
export type {
LayoutProps,
LayoutProps as LayoutContentProps
} from './src/Layout'
export type { LayoutHeaderProps } from './src/LayoutHeader'
export type { LayoutFooterProps } from './src/LayoutFooter'
export type { LayoutSiderProps } from './src/LayoutSider'
export type { LayoutInst, LayoutSiderInst } from './src/interface'

View File

@ -5,18 +5,19 @@ import {
PropType,
CSSProperties,
ref,
ExtractPropTypes,
InjectionKey,
provide
provide,
ExtractPropTypes
} from 'vue'
import { NScrollbar } from '../../scrollbar'
import type { ScrollbarProps, ScrollbarInst } from '../../scrollbar'
import { useTheme } from '../../_mixins'
import { useConfig, useTheme } from '../../_mixins'
import type { ThemeProps } from '../../_mixins'
import { layoutLight } from '../styles'
import type { LayoutTheme } from '../styles'
import style from './styles/layout.cssr'
import { LayoutRef, positionProp } from './interface'
import { LayoutInst, positionProp } from './interface'
import type { ExtractPublicPropTypes } from '../../_utils'
const layoutProps = {
position: positionProp,
@ -28,11 +29,11 @@ const layoutProps = {
hasSider: Boolean
} as const
export type LayoutProps = ExtractPropTypes<typeof layoutProps>
export type LayoutProps = ExtractPublicPropTypes<typeof layoutProps>
export const layoutInjectionKey: InjectionKey<LayoutProps> = Symbol(
'layoutInjectionKey'
)
export const layoutInjectionKey: InjectionKey<
ExtractPropTypes<LayoutProps>
> = Symbol('layout')
export default defineComponent({
name: 'Layout',
@ -44,8 +45,16 @@ export default defineComponent({
setup (props) {
const selfRef = ref<HTMLElement | null>(null)
const scrollbarRef = ref<ScrollbarInst | null>(null)
const themeRef = useTheme('Layout', 'Layout', style, layoutLight, props)
const scrollTo: LayoutRef['scrollTo'] = (
const { mergedClsPrefix } = useConfig(props)
const themeRef = useTheme(
'Layout',
'Layout',
style,
layoutLight,
props,
mergedClsPrefix
)
const scrollTo: LayoutInst['scrollTo'] = (
options: ScrollToOptions | number,
y?: number
): void => {
@ -57,6 +66,7 @@ export default defineComponent({
}
if (__DEV__) provide(layoutInjectionKey, props)
return {
cPrefix: mergedClsPrefix,
selfRef,
scrollbarRef,
scrollTo,
@ -75,13 +85,14 @@ export default defineComponent({
}
},
render () {
const { cPrefix } = this
return (
<div
ref="selfRef"
class={[
'n-layout',
`n-layout--${this.position}-positioned`,
this.hasSider && 'n-layout--has-sider'
`${cPrefix}-layout`,
`${cPrefix}-layout--${this.position}-positioned`,
this.hasSider && `${cPrefix}-layout--has-sider`
]}
style={this.cssVars as CSSProperties}
>

View File

@ -1,30 +1,38 @@
import { h, computed, defineComponent, CSSProperties } from 'vue'
import { useTheme } from '../../_mixins'
import { useConfig, 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'
import type { ExtractPublicPropTypes } from '../../_utils'
const layoutFooterProps = {
...(useTheme.props as ThemeProps<LayoutTheme>),
position: positionProp,
bordered: {
type: Boolean,
default: false
}
}
export type LayoutFooterProps = ExtractPublicPropTypes<typeof layoutFooterProps>
export default defineComponent({
name: 'LayoutFooter',
props: {
...(useTheme.props as ThemeProps<LayoutTheme>),
position: positionProp,
bordered: {
type: Boolean,
default: false
}
},
props: layoutFooterProps,
setup (props) {
const { mergedClsPrefix } = useConfig(props)
const themeRef = useTheme(
'Layout',
'LayoutFooter',
style,
layoutLight,
props
props,
mergedClsPrefix
)
return {
cPrefix: mergedClsPrefix,
cssVars: computed(() => {
const {
common: { cubicBezierEaseInOut },
@ -38,13 +46,15 @@ export default defineComponent({
}
},
render () {
const { cPrefix } = this
return (
<div
class={[
'n-layout-footer',
`${cPrefix}-layout-footer`,
{
[`n-layout-footer--${this.position}-positioned`]: this.position,
'n-layout-footer--bordered': this.bordered
[`${cPrefix}-layout-footer--${this.position}-positioned`]: this
.position,
[`${cPrefix}-layout-footer--bordered`]: this.bordered
}
]}
style={this.cssVars as CSSProperties}

View File

@ -1,16 +1,11 @@
import {
h,
defineComponent,
computed,
CSSProperties,
ExtractPropTypes
} from 'vue'
import { useTheme } from '../../_mixins'
import { h, defineComponent, computed, CSSProperties } from 'vue'
import { useConfig, 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-header.cssr'
import { ExtractPublicPropTypes } from '../../_utils'
const headerProps = {
position: positionProp,
@ -20,7 +15,7 @@ const headerProps = {
}
} as const
export type LayoutHeaderProps = ExtractPropTypes<typeof headerProps>
export type LayoutHeaderProps = ExtractPublicPropTypes<typeof headerProps>
export default defineComponent({
name: 'LayoutHeader',
@ -29,14 +24,17 @@ export default defineComponent({
...headerProps
},
setup (props) {
const { mergedClsPrefix } = useConfig(props)
const themeRef = useTheme(
'Layout',
'LayoutHeader',
style,
layoutLight,
props
props,
mergedClsPrefix
)
return {
cPrefix: mergedClsPrefix,
cssVars: computed(() => {
const {
common: { cubicBezierEaseInOut },
@ -51,14 +49,14 @@ export default defineComponent({
}
},
render () {
const { cPrefix } = this
return (
<div
class={[
'n-layout-header',
this.position && `n-layout-header--${this.position}-positioned`,
{
'n-layout-header--bordered': this.bordered
}
`${cPrefix}-layout-header`,
this.position &&
`${cPrefix}-layout-header--${this.position}-positioned`,
this.bordered && `${cPrefix}-layout-header--bordered`
]}
style={this.cssVars as CSSProperties}
>

View File

@ -6,13 +6,12 @@ import {
ref,
CSSProperties,
toRef,
ExtractPropTypes,
inject
} from 'vue'
import { useTheme } from '../../_mixins'
import { useConfig, useTheme } from '../../_mixins'
import type { ThemeProps } from '../../_mixins'
import { formatLength, MaybeArray, call, warn } from '../../_utils'
import { formatLength, call, warn } from '../../_utils'
import type { MaybeArray, ExtractPublicPropTypes } from '../../_utils'
import { NScrollbar } from '../../scrollbar'
import type { ScrollbarProps, ScrollbarInst } from '../../scrollbar'
import { layoutLight } from '../styles'
@ -82,7 +81,7 @@ const layoutSiderProps = {
onCollapse: [Function, Array] as PropType<MaybeArray<() => void>>
} as const
export type LayoutSiderProps = ExtractPropTypes<typeof layoutSiderProps>
export type LayoutSiderProps = ExtractPublicPropTypes<typeof layoutSiderProps>
export default defineComponent({
name: 'LayoutSider',
@ -160,16 +159,19 @@ export default defineComponent({
if (onCollapse) call(onCollapse)
}
}
const { mergedClsPrefix } = useConfig(props)
const themeRef = useTheme(
'Layout',
'LayoutSider',
style,
layoutLight,
props
props,
mergedClsPrefix
)
return {
selfRef,
scrollbarRef,
cPrefix: mergedClsPrefix,
mergedTheme: themeRef,
styleMaxWidth: styleMaxWidthRef,
mergedCollapsed: mergedCollapsedRef,
@ -199,32 +201,31 @@ export default defineComponent({
}
},
render () {
const { cPrefix } = this
return (
<aside
ref="selfRef"
class={[
'n-layout-sider',
this.position && [`n-layout-sider--${this.position}-positioned`],
`${cPrefix}-layout-sider`,
`${cPrefix}-layout-sider--${this.position}-positioned`,
{
'n-layout-sider--bordered': this.bordered,
'n-layout-sider--collapsed': this.mergedCollapsed,
'n-layout-sider--show-content': this.showContent
[`${cPrefix}-layout-sider--bordered`]: this.bordered,
[`${cPrefix}-layout-sider--collapsed`]: this.mergedCollapsed,
[`${cPrefix}-layout-sider--show-content`]: this.showContent
}
]}
style={[
this.cssVars as any,
{
maxWidth: this.styleMaxWidth,
width: formatLength(this.width)
}
]}
style={
[
this.cssVars,
{
maxWidth: this.styleMaxWidth,
width: formatLength(this.width)
}
] as any
}
>
{!this.nativeScrollbar ? (
<NScrollbar
ref="scrollbarRef"
class="n-layout-sider__content"
class={`${cPrefix}-layout-sider__content`}
style={this.contentStyle}
{...this.scrollbarProps}
theme={this.mergedTheme.peers.Scrollbar}
@ -233,19 +234,26 @@ export default defineComponent({
{this.$slots}
</NScrollbar>
) : (
<div class="n-layout-sider__content" style={this.contentStyle}>
<div
class={`${cPrefix}-layout-sider__content`}
style={this.contentStyle}
>
{this.$slots}
</div>
)}
{this.bordered ? <div class="n-layout-sider__border" /> : null}
{this.bordered ? (
<div class={`${cPrefix}-layout-sider__border`} />
) : null}
{this.showTrigger ? (
this.showTrigger === 'arrow-circle' ? (
<ToggleButton
clsPrefix={cPrefix}
style={this.triggerStyle}
onClick={this.handleTriggerClick}
/>
) : (
<ToggleBar
clsPrefix={cPrefix}
collapsed={this.mergedCollapsed}
style={this.triggerStyle}
onClick={this.handleTriggerClick}

View File

@ -2,6 +2,10 @@ import { h, defineComponent, PropType } from 'vue'
export default defineComponent({
props: {
clsPrefix: {
type: String,
required: true
},
onClick: Function as PropType<(e: MouseEvent) => void>,
collapsed: {
type: Boolean,
@ -9,18 +13,17 @@ export default defineComponent({
}
},
render () {
const { clsPrefix } = this
return (
<div
onClick={this.onClick}
class={[
'n-layout-toggle-bar',
{
'n-layout-toggle-bar--collapsed': this.collapsed
}
`${clsPrefix}-layout-toggle-bar`,
this.collapsed && `${clsPrefix}-layout-toggle-bar--collapsed`
]}
>
<div class="n-layout-toggle-bar__top" />
<div class="n-layout-toggle-bar__bottom" />
<div class={`${clsPrefix}-layout-toggle-bar__top`} />
<div class={`${clsPrefix}-layout-toggle-bar__bottom`} />
</div>
)
}

View File

@ -3,11 +3,18 @@ import { h, defineComponent, PropType } from 'vue'
export default defineComponent({
name: 'LayoutToggleButton',
props: {
clsPrefix: {
type: String,
required: true
},
onClick: Function as PropType<(e: MouseEvent) => void>
},
render () {
return (
<div class="n-layout-toggle-button" onClick={this.onClick}>
<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"

View File

@ -5,7 +5,9 @@ export const positionProp = {
default: 'static'
} as const
export interface LayoutRef {
export interface LayoutInst {
scrollTo: ((options: ScrollToOptions) => void) &
((x: number, y: number) => void)
}
export type LayoutSiderInst = LayoutInst