mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
wip
This commit is contained in:
@@ -39,9 +39,9 @@ scrollbar/manual-scroll
|
||||
|
||||
:::
|
||||
|
||||
## Infinite scroll ^(2.9.11)
|
||||
## Infinite scroll ^(2.9.12)
|
||||
|
||||
:::demo When the end of the scroll is reached `endReached` is called. It can be used for infinite scroll.
|
||||
:::demo When the end of the scroll is reached `bottom-reached` is called. It can be used for infinite scroll.
|
||||
|
||||
scrollbar/infinite-scroll
|
||||
|
||||
@@ -51,25 +51,26 @@ scrollbar/infinite-scroll
|
||||
|
||||
### Attributes
|
||||
|
||||
| Name | Description | Type | Default |
|
||||
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | ------- |
|
||||
| height | height of scrollbar | ^[string] / ^[number] | — |
|
||||
| max-height | max height of scrollbar | ^[string] / ^[number] | — |
|
||||
| native | whether to use the native scrollbar style | ^[boolean] | false |
|
||||
| wrap-style | style of wrap container | ^[string] / ^[object]`CSSProperties \| CSSProperties[] \| string[]` | — |
|
||||
| wrap-class | class of wrap container | ^[string] | — |
|
||||
| view-style | style of view | ^[string] / ^[object]`CSSProperties \| CSSProperties[] \| string[]` | — |
|
||||
| view-class | class of view | ^[string] | — |
|
||||
| noresize | do not respond to container size changes, if the container size does not change, it is better to set it to optimize performance | ^[boolean] | false |
|
||||
| tag | element tag of the view | ^[string] | div |
|
||||
| always | always show scrollbar | ^[boolean] | false |
|
||||
| min-size | minimum size of scrollbar | ^[number] | 20 |
|
||||
| id ^(2.4.0) | id of view | ^[string] | — |
|
||||
| role ^(2.4.0) ^(a11y) | role of view | ^[string] | — |
|
||||
| aria-label ^(2.4.0) ^(a11y) | aria-label of view | ^[string] | — |
|
||||
| aria-orientation ^(2.4.0) ^(a11y) | aria-orientation of view | ^[enum]`'horizontal' \| 'vertical'` | — |
|
||||
| tabindex ^(2.8.3) | tabindex of wrap container | ^[number] / ^[string] | — |
|
||||
| end-reached ^(2.9.11) | Invoked when the end of the scroll is reached. Useful for infinite scroll. | (options: [InfiniteLoadScrollOptions](#typings)) => Awaitable<void\> | — |
|
||||
| Name | Description | Type | Default |
|
||||
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | ------- |
|
||||
| height | height of scrollbar | ^[string] / ^[number] | — |
|
||||
| max-height | max height of scrollbar | ^[string] / ^[number] | — |
|
||||
| native | whether to use the native scrollbar style | ^[boolean] | false |
|
||||
| wrap-style | style of wrap container | ^[string] / ^[object]`CSSProperties \| CSSProperties[] \| string[]` | — |
|
||||
| wrap-class | class of wrap container | ^[string] | — |
|
||||
| view-style | style of view | ^[string] / ^[object]`CSSProperties \| CSSProperties[] \| string[]` | — |
|
||||
| view-class | class of view | ^[string] | — |
|
||||
| noresize | do not respond to container size changes, if the container size does not change, it is better to set it to optimize performance | ^[boolean] | false |
|
||||
| tag | element tag of the view | ^[string] | div |
|
||||
| always | always show scrollbar | ^[boolean] | false |
|
||||
| min-size | minimum size of scrollbar | ^[number] | 20 |
|
||||
| id ^(2.4.0) | id of view | ^[string] | — |
|
||||
| role ^(2.4.0) ^(a11y) | role of view | ^[string] | — |
|
||||
| aria-label ^(2.4.0) ^(a11y) | aria-label of view | ^[string] | — |
|
||||
| aria-orientation ^(2.4.0) ^(a11y) | aria-orientation of view | ^[enum]`'horizontal' \| 'vertical'` | — |
|
||||
| tabindex ^(2.8.3) | tabindex of wrap container | ^[number] / ^[string] | — |
|
||||
| bottom-reached ^(2.9.12) | invoked when the end of the scroll is reached. Useful for infinite scroll. | (options: [ScrollOptions](#typings)) => Awaitable<void\> | — |
|
||||
| direction ^(2.9.12) | direction to use the infinite scroll scroll. | ^[enum]`'top'\| 'bottom' \| 'left'\| 'right'` | bottom |
|
||||
|
||||
### Events
|
||||
|
||||
@@ -104,8 +105,7 @@ import { useScroll } from '@vueuse/core'
|
||||
import type { UnwrapNestedRefs } from 'vue'
|
||||
|
||||
type Awaitable<T> = Promise<T> | T
|
||||
|
||||
type InfiniteLoadScrollOptions = UnwrapNestedRefs<ReturnType<typeof useScroll>>
|
||||
type ScrollOptions = UnwrapNestedRefs<ReturnType<typeof useScroll>>
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-scrollbar height="400px" :end-reached="loadMore">
|
||||
<el-scrollbar height="400px" :bottom-reached="loadMore">
|
||||
<p v-for="item in num" :key="item" class="scrollbar-demo-item">
|
||||
{{ item }}
|
||||
</p>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import type { InjectionKey } from 'vue'
|
||||
import type { ScrollbarProps } from './scrollbar'
|
||||
|
||||
export interface ScrollbarContext {
|
||||
scrollbarElement: HTMLDivElement
|
||||
wrapElement: HTMLDivElement
|
||||
direction: ScrollbarProps['direction']
|
||||
}
|
||||
|
||||
export const scrollbarContextKey: InjectionKey<ScrollbarContext> = Symbol(
|
||||
|
||||
@@ -100,18 +100,22 @@ export const scrollbarProps = buildProps({
|
||||
/**
|
||||
* @description hook function when reach the end of scroll.
|
||||
*/
|
||||
endReached: {
|
||||
type: definePropType<
|
||||
(options: InfiniteLoadScrollOptions) => Awaitable<void>
|
||||
>(Function),
|
||||
bottomReached: {
|
||||
type: definePropType<(options: ScrollOptions) => Awaitable<void>>(Function),
|
||||
default: NOOP,
|
||||
},
|
||||
/**
|
||||
* @description direction to use the infinite scroll
|
||||
*/
|
||||
direction: {
|
||||
type: String,
|
||||
values: ['top', 'bottom', 'left', 'right'] as const,
|
||||
default: 'bottom',
|
||||
},
|
||||
...useAriaProps(['ariaLabel', 'ariaOrientation']),
|
||||
} as const)
|
||||
export type ScrollbarProps = ExtractPropTypes<typeof scrollbarProps>
|
||||
export type InfiniteLoadScrollOptions = UnwrapNestedRefs<
|
||||
ReturnType<typeof useScroll>
|
||||
>
|
||||
export type ScrollOptions = UnwrapNestedRefs<ReturnType<typeof useScroll>>
|
||||
|
||||
export const scrollbarEmits = {
|
||||
scroll: ({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div ref="scrollbarRef" :class="ns.b()">
|
||||
<div ref="scrollbarRef" :class="[ns.b(), ns.is(direction)]">
|
||||
<div ref="wrapRef" :class="wrapKls" :style="wrapStyle" :tabindex="tabindex">
|
||||
<component
|
||||
:is="tag"
|
||||
@@ -67,7 +67,10 @@ const resizeRef = ref<HTMLElement>()
|
||||
const barRef = ref<BarInstance>()
|
||||
|
||||
onMounted(() => {
|
||||
useInfiniteScroll(wrapRef, props.endReached, { onScroll: handleScroll })
|
||||
useInfiniteScroll(wrapRef, props.bottomReached, {
|
||||
onScroll: handleScroll,
|
||||
direction: props.direction,
|
||||
})
|
||||
})
|
||||
|
||||
const wrapStyle = computed<StyleValue>(() => {
|
||||
@@ -166,6 +169,7 @@ provide(
|
||||
reactive({
|
||||
scrollbarElement: scrollbarRef,
|
||||
wrapElement: wrapRef,
|
||||
direction: props.direction,
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
@@ -47,12 +47,16 @@ let originalOnSelectStart:
|
||||
| null = isClient ? document.onselectstart : null
|
||||
|
||||
const bar = computed(() => BAR_MAP[props.vertical ? 'vertical' : 'horizontal'])
|
||||
const reverseScroll = computed(() =>
|
||||
scrollbar.direction.includes(bar.value.direction)
|
||||
)
|
||||
|
||||
const thumbStyle = computed(() =>
|
||||
renderThumbStyle({
|
||||
size: props.size,
|
||||
move: props.move,
|
||||
bar: bar.value,
|
||||
reverse: reverseScroll.value,
|
||||
})
|
||||
)
|
||||
|
||||
@@ -94,11 +98,17 @@ const clickTrackHandler = (e: MouseEvent) => {
|
||||
((offset - thumbHalf) * 100 * offsetRatio.value) /
|
||||
instance.value[bar.value.offset]
|
||||
|
||||
scrollbar.wrapElement[bar.value.scroll] =
|
||||
let scrollOffset =
|
||||
(thumbPositionPercentage * scrollbar.wrapElement[bar.value.scrollSize]) /
|
||||
100
|
||||
if (reverseScroll.value) {
|
||||
const scrollSize =
|
||||
scrollbar.wrapElement[bar.value.scrollSize] -
|
||||
scrollbar.wrapElement[bar.value.offset]
|
||||
scrollOffset = -(scrollSize - scrollOffset)
|
||||
}
|
||||
scrollbar.wrapElement[bar.value.scroll] = scrollOffset
|
||||
}
|
||||
|
||||
const startDrag = (e: MouseEvent) => {
|
||||
e.stopImmediatePropagation()
|
||||
cursorDown = true
|
||||
@@ -123,9 +133,16 @@ const mouseMoveDocumentHandler = (e: MouseEvent) => {
|
||||
const thumbPositionPercentage =
|
||||
((offset - thumbClickPosition) * 100 * offsetRatio.value) /
|
||||
instance.value[bar.value.offset]
|
||||
scrollbar.wrapElement[bar.value.scroll] =
|
||||
let scrollOffset =
|
||||
(thumbPositionPercentage * scrollbar.wrapElement[bar.value.scrollSize]) /
|
||||
100
|
||||
if (reverseScroll.value) {
|
||||
const scrollSize =
|
||||
scrollbar.wrapElement[bar.value.scrollSize] -
|
||||
scrollbar.wrapElement[bar.value.offset]
|
||||
scrollOffset = -(scrollSize - scrollOffset)
|
||||
}
|
||||
scrollbar.wrapElement[bar.value.scroll] = scrollOffset
|
||||
}
|
||||
|
||||
const mouseUpDocumentHandler = () => {
|
||||
|
||||
@@ -30,9 +30,13 @@ export const renderThumbStyle = ({
|
||||
move,
|
||||
size,
|
||||
bar,
|
||||
reverse,
|
||||
}: Pick<ThumbProps, 'move' | 'size'> & {
|
||||
bar: typeof BAR_MAP[keyof typeof BAR_MAP]
|
||||
reverse: boolean
|
||||
}): CSSProperties => ({
|
||||
[bar.size]: size,
|
||||
transform: `translate${bar.axis}(${move}%)`,
|
||||
transform: `${reverse ? `scale${bar.axis}(-1) ` : ''}translate${
|
||||
bar.axis
|
||||
}(${move}%)`,
|
||||
})
|
||||
|
||||
@@ -13,6 +13,33 @@
|
||||
position: relative;
|
||||
height: 100%;
|
||||
|
||||
@include when(top) {
|
||||
@include e(wrap) {
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
@include e(bar) {
|
||||
transform: scaleY(-1);
|
||||
}
|
||||
}
|
||||
@include when(left) {
|
||||
@include e(wrap) {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
@include e(view) {
|
||||
display: inline-flex;
|
||||
}
|
||||
@include e(bar) {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
}
|
||||
|
||||
@include when(right) {
|
||||
@include e(view) {
|
||||
display: inline-flex;
|
||||
}
|
||||
}
|
||||
@include e(wrap) {
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
|
||||
Reference in New Issue
Block a user