mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2024-12-09 04:31:35 +08:00
fix(layout): scrollTo
not working with native scrollbar
This commit is contained in:
parent
c5dd884df6
commit
e32b020a95
@ -2,6 +2,10 @@
|
||||
|
||||
## Pending
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- `n-layout-sider` removed `show-content` prop. Please use `show-collapsed-content` instead.
|
||||
|
||||
### Feats
|
||||
|
||||
- `n-data-table` support tree data.
|
||||
@ -25,6 +29,7 @@
|
||||
|
||||
### Fixes
|
||||
|
||||
- `n-layout` & `n-layout-sider`'s `scrollTo` not working with native scrollbar.
|
||||
- `n-layout-sider`'s `collapse-mode` not working.
|
||||
- Internal selection component's theme peers has wrong key for popover.
|
||||
|
||||
|
@ -2,6 +2,10 @@
|
||||
|
||||
## Pending
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- `n-layout-sider` 移除了 `show-content`,使用 `show-collapsed-content` 代替
|
||||
|
||||
### Feats
|
||||
|
||||
- `n-data-table` 支持树形数据
|
||||
@ -25,6 +29,7 @@
|
||||
|
||||
### Fixes
|
||||
|
||||
- `n-layout` & `n-layout-sider` 的 `scrollTo` 在使用原生滚动条时不生效
|
||||
- `n-layout-sider` 的 `collapse-mode` 属性不生效
|
||||
- 内部 selection 组件的主题 peers 中 popover 的 key 不正确
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
export { default as NLayout } from './src/Layout'
|
||||
export { default as NLayoutContent } from './src/Layout'
|
||||
export { default as NLayoutContent } from './src/LayoutContent'
|
||||
export { default as NLayoutHeader } from './src/LayoutHeader'
|
||||
export { default as NLayoutFooter } from './src/LayoutFooter'
|
||||
export { default as NLayoutSider } from './src/LayoutSider'
|
||||
|
@ -40,97 +40,102 @@ export const layoutInjectionKey: InjectionKey<
|
||||
ExtractPropTypes<LayoutProps>
|
||||
> = Symbol('layout')
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Layout',
|
||||
alias: ['LayoutContent'],
|
||||
props: {
|
||||
...(useTheme.props as ThemeProps<LayoutTheme>),
|
||||
...layoutProps
|
||||
},
|
||||
setup (props) {
|
||||
const selfRef = ref<HTMLElement | null>(null)
|
||||
const scrollbarRef = ref<ScrollbarInst | null>(null)
|
||||
const { mergedClsPrefixRef } = useConfig(props)
|
||||
const themeRef = useTheme(
|
||||
'Layout',
|
||||
'Layout',
|
||||
style,
|
||||
layoutLight,
|
||||
props,
|
||||
mergedClsPrefixRef
|
||||
)
|
||||
const scrollTo: LayoutInst['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)
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||
export function createLayoutComponent (isContent: boolean) {
|
||||
return defineComponent({
|
||||
name: isContent ? 'LayoutContent' : 'Layout',
|
||||
props: {
|
||||
...(useTheme.props as ThemeProps<LayoutTheme>),
|
||||
...layoutProps
|
||||
},
|
||||
setup (props) {
|
||||
const scrollableDivRef = ref<HTMLElement | null>(null)
|
||||
const scrollbarRef = ref<ScrollbarInst | null>(null)
|
||||
const { mergedClsPrefixRef } = useConfig(props)
|
||||
const themeRef = useTheme(
|
||||
'Layout',
|
||||
'Layout',
|
||||
style,
|
||||
layoutLight,
|
||||
props,
|
||||
mergedClsPrefixRef
|
||||
)
|
||||
const scrollTo: LayoutInst['scrollTo'] = (
|
||||
options: ScrollToOptions | number,
|
||||
y?: number
|
||||
): void => {
|
||||
if (scrollbarRef.value) {
|
||||
scrollbarRef.value.scrollTo(options as any, y as any)
|
||||
} else if (scrollableDivRef.value) {
|
||||
scrollableDivRef.value.scrollTo(options as any, y as any)
|
||||
}
|
||||
}
|
||||
}
|
||||
const scrollableDivStyleRef = computed(() => {
|
||||
return [
|
||||
props.contentStyle,
|
||||
{
|
||||
height: '100%',
|
||||
overflow: 'auto'
|
||||
}
|
||||
]
|
||||
})
|
||||
if (__DEV__) provide(layoutInjectionKey, props)
|
||||
return {
|
||||
mergedClsPrefix: mergedClsPrefixRef,
|
||||
selfRef,
|
||||
scrollbarRef,
|
||||
scrollableDivStyle: scrollableDivStyleRef,
|
||||
scrollTo,
|
||||
mergedTheme: themeRef,
|
||||
cssVars: computed(() => {
|
||||
const {
|
||||
common: { cubicBezierEaseInOut },
|
||||
self
|
||||
} = themeRef.value
|
||||
return {
|
||||
'--bezier': cubicBezierEaseInOut,
|
||||
'--color': props.embedded ? self.colorEmbedded : self.color,
|
||||
'--text-color': self.textColor
|
||||
}
|
||||
const scrollableDivStyleRef = computed(() => {
|
||||
return [
|
||||
props.contentStyle,
|
||||
{
|
||||
height: '100%',
|
||||
overflow: 'auto'
|
||||
}
|
||||
]
|
||||
})
|
||||
if (__DEV__) provide(layoutInjectionKey, props)
|
||||
return {
|
||||
mergedClsPrefix: mergedClsPrefixRef,
|
||||
scrollableDivRef,
|
||||
scrollbarRef,
|
||||
scrollableDivStyle: scrollableDivStyleRef,
|
||||
scrollTo,
|
||||
mergedTheme: themeRef,
|
||||
cssVars: computed(() => {
|
||||
const {
|
||||
common: { cubicBezierEaseInOut },
|
||||
self
|
||||
} = themeRef.value
|
||||
return {
|
||||
'--bezier': cubicBezierEaseInOut,
|
||||
'--color': props.embedded ? self.colorEmbedded : self.color,
|
||||
'--text-color': self.textColor
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
render () {
|
||||
const { mergedClsPrefix } = this
|
||||
return (
|
||||
<div
|
||||
class={[
|
||||
isContent && `${mergedClsPrefix}-layout-content`,
|
||||
`${mergedClsPrefix}-layout`,
|
||||
`${mergedClsPrefix}-layout--${this.position}-positioned`,
|
||||
this.hasSider && `${mergedClsPrefix}-layout--has-sider`
|
||||
]}
|
||||
style={this.cssVars as CSSProperties}
|
||||
>
|
||||
{!this.nativeScrollbar ? (
|
||||
<NScrollbar
|
||||
{...this.scrollbarProps}
|
||||
ref="scrollbarRef"
|
||||
theme={this.mergedTheme.peers.Scrollbar}
|
||||
themeOverrides={this.mergedTheme.peerOverrides.Scrollbar}
|
||||
contentClass={`${mergedClsPrefix}-layout__content`}
|
||||
contentStyle={this.contentStyle}
|
||||
>
|
||||
{this.$slots}
|
||||
</NScrollbar>
|
||||
) : (
|
||||
<div
|
||||
ref="scrollableDivRef"
|
||||
class={`${mergedClsPrefix}-layout__content`}
|
||||
style={this.scrollableDivStyle}
|
||||
>
|
||||
{this.$slots}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
render () {
|
||||
const { mergedClsPrefix } = this
|
||||
return (
|
||||
<div
|
||||
ref="selfRef"
|
||||
class={[
|
||||
`${mergedClsPrefix}-layout`,
|
||||
`${mergedClsPrefix}-layout--${this.position}-positioned`,
|
||||
this.hasSider && `${mergedClsPrefix}-layout--has-sider`
|
||||
]}
|
||||
style={this.cssVars as CSSProperties}
|
||||
>
|
||||
{!this.nativeScrollbar ? (
|
||||
<NScrollbar
|
||||
{...this.scrollbarProps}
|
||||
ref="scrollbarRef"
|
||||
theme={this.mergedTheme.peers.Scrollbar}
|
||||
themeOverrides={this.mergedTheme.peerOverrides.Scrollbar}
|
||||
contentClass={`${mergedClsPrefix}-layout__content`}
|
||||
contentStyle={this.contentStyle}
|
||||
>
|
||||
{this.$slots}
|
||||
</NScrollbar>
|
||||
) : (
|
||||
<div
|
||||
class={`${mergedClsPrefix}-layout__content`}
|
||||
style={this.scrollableDivStyle}
|
||||
>
|
||||
{this.$slots}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default createLayoutComponent(false)
|
||||
|
3
src/layout/src/LayoutContent.tsx
Normal file
3
src/layout/src/LayoutContent.tsx
Normal file
@ -0,0 +1,3 @@
|
||||
import { createLayoutComponent } from './Layout'
|
||||
|
||||
export default createLayoutComponent(true)
|
@ -48,7 +48,7 @@ const layoutSiderProps = {
|
||||
default: undefined
|
||||
},
|
||||
defaultCollapsed: Boolean,
|
||||
showContent: {
|
||||
showCollapsedContent: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
@ -106,7 +106,7 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
}
|
||||
const selfRef = ref<HTMLElement | null>(null)
|
||||
const scrollableDivRef = ref<HTMLElement | null>(null)
|
||||
const scrollbarRef = ref<ScrollbarInst | null>(null)
|
||||
const styleMaxWidthRef = computed(() => {
|
||||
return formatLength(
|
||||
@ -140,11 +140,11 @@ export default defineComponent({
|
||||
function scrollTo (options: ScrollToOptions | number, y?: number): void {
|
||||
if (scrollbarRef.value) {
|
||||
scrollbarRef.value.scrollTo(options as any, y as any)
|
||||
} else if (selfRef.value) {
|
||||
} else if (scrollableDivRef.value) {
|
||||
if (y === undefined) {
|
||||
selfRef.value.scrollTo(options as any)
|
||||
scrollableDivRef.value.scrollTo(options as any)
|
||||
} else {
|
||||
selfRef.value.scrollTo(options as any, y as any)
|
||||
scrollableDivRef.value.scrollTo(options as any, y as any)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -183,7 +183,7 @@ export default defineComponent({
|
||||
mergedClsPrefixRef
|
||||
)
|
||||
return {
|
||||
selfRef,
|
||||
scrollableDivRef,
|
||||
scrollbarRef,
|
||||
mergedClsPrefix: mergedClsPrefixRef,
|
||||
mergedTheme: themeRef,
|
||||
@ -227,13 +227,13 @@ export default defineComponent({
|
||||
const { mergedClsPrefix } = this
|
||||
return (
|
||||
<aside
|
||||
ref="selfRef"
|
||||
class={[
|
||||
`${mergedClsPrefix}-layout-sider`,
|
||||
`${mergedClsPrefix}-layout-sider--${this.position}-positioned`,
|
||||
this.bordered && `${mergedClsPrefix}-layout-sider--bordered`,
|
||||
this.mergedCollapsed && `${mergedClsPrefix}-layout-sider--collapsed`,
|
||||
this.showContent && `${mergedClsPrefix}-layout-sider--show-content`
|
||||
(!this.mergedCollapsed || this.showCollapsedContent) &&
|
||||
`${mergedClsPrefix}-layout-sider--show-content`
|
||||
]}
|
||||
style={[
|
||||
this.cssVars,
|
||||
@ -269,6 +269,7 @@ export default defineComponent({
|
||||
<div
|
||||
class={`${mergedClsPrefix}-layout-sider__content`}
|
||||
style={this.scrollableDivStyle}
|
||||
ref="scrollableDivRef"
|
||||
>
|
||||
{this.$slots}
|
||||
</div>
|
||||
|
@ -26,6 +26,7 @@ export default cB('layout', `
|
||||
`)
|
||||
])
|
||||
]),
|
||||
cE('content', 'box-sizing: border-box;'),
|
||||
cM('absolute-positioned', `
|
||||
position: absolute;
|
||||
left: 0;
|
||||
|
Loading…
Reference in New Issue
Block a user