Skip to content

feat: picker增加resistance属性,以支持通过鼠标滚轮进行选择时产生段落感 #6853

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/components/date-picker-view/date-picker-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export type RenderLabel = (type: Precision | 'now', data: number) => ReactNode

export type DatePickerViewProps = Pick<
PickerViewProps,
'style' | 'mouseWheel' | 'loading' | 'loadingContent'
'style' | 'mouseWheel' | 'wheelResistance' | 'loading' | 'loadingContent'
> & {
value?: PickerDate
defaultValue?: PickerDate
Expand Down Expand Up @@ -91,6 +91,7 @@ export const DatePickerView: FC<DatePickerViewProps> = p => {
loadingContent={props.loadingContent}
value={pickerValue}
mouseWheel={props.mouseWheel}
wheelResistance={props.wheelResistance}
onChange={onChange}
/>
)
Expand Down
2 changes: 2 additions & 0 deletions src/components/date-picker/date-picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export type DatePickerProps = Pick<
| 'stopPropagation'
| 'style'
| 'mouseWheel'
| 'wheelResistance'
| 'forceRender'
| 'destroyOnClose'
> & {
Expand Down Expand Up @@ -150,6 +151,7 @@ export const DatePicker = forwardRef<DatePickerRef, DatePickerProps>(
title={props.title}
stopPropagation={props.stopPropagation}
mouseWheel={props.mouseWheel}
wheelResistance={props.wheelResistance}
destroyOnClose={props.destroyOnClose}
forceRender={props.forceRender}
>
Expand Down
2 changes: 2 additions & 0 deletions src/components/picker-view/index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ PickerView is the content area of [Picker](/components/picker/#picker).
| columns | Options to configure each column | `PickerColumn[] \| ((value: PickerValue[]) => PickerColumn[])` | - |
| defaultValue | Default selected options | `PickerValue[]` | `[]` |
| mouseWheel | Whether to allow interact with mouse wheel | `boolean` | `false` |
| wheelResistance | Enable increased resistance to scrolling when selecting through mouse wheel | `boolean` | `true` |
| onChange | Triggered when the options are changed | `(value: PickerValue[], extend: PickerValueExtend) => void` | - |
| renderLabel | The function to custom rendering the label shown on a column | `(item: PickerColumnItem) => ReactNode` | `(item) => item.label` |
| value | Selected options | `PickerValue[]` | - |
Expand Down Expand Up @@ -82,6 +83,7 @@ type PickerDate = Date & {
| max | Max value | `PickerDate` | ten years later |
| min | Minimum value | `PickerDate` | ten years ago |
| mouseWheel | Whether to allow interact with mouse wheel | `boolean` | `false` |
| wheelResistance | Enable increased resistance to scrolling when selecting through mouse wheel | `boolean` | `true` |
| onChange | Triggered when the options are changed | `(value: PickerDate) => void` | - |
| precision | Precision | `'year' \| 'month' \| 'day' \| 'hour' \| 'minute' \| 'second' \| 'week' \| 'week-day' \| 'quarter'` | `'day'` |
| renderLabel | The function to custom rendering the label shown on a column. `type` means any value in `precision`, `data` means the default number | `(type: string, data: number) => ReactNode` | - |
Expand Down
2 changes: 2 additions & 0 deletions src/components/picker-view/index.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ PickerView 是 [Picker](/zh/components/picker/#picker) 的内容区域。
| columns | 配置每一列的选项 | `PickerColumn[] \| ((value: PickerValue[]) => PickerColumn[])` | - |
| defaultValue | 默认选中项 | `PickerValue[]` | `[]` |
| mouseWheel | 是否允许通过鼠标滚轮进行选择 | `boolean` | `false` |
| wheelResistance | 启用通过鼠标滚轮进行选择时,增强滚动的段落感 | `boolean` | `true` |
| onChange | 选项改变时触发 | `(value: PickerValue[], extend: PickerValueExtend) => void` | - |
| renderLabel | 自定义渲染每列展示的内容 | `(item: PickerColumnItem) => ReactNode` | `(item) => item.label` |
| value | 选中项 | `PickerValue[]` | - |
Expand Down Expand Up @@ -82,6 +83,7 @@ type PickerDate = Date & {
| max | 最大值 | `PickerDate` | 十年后 |
| min | 最小值 | `PickerDate` | 十年前 |
| mouseWheel | 是否允许通过鼠标滚轮进行选择 | `boolean` | `false` |
| wheelResistance | 启用通过鼠标滚轮进行选择时,增强滚动的段落感 | `boolean` | `true` |
| onChange | 选项改变时触发 | `(value: PickerDate) => void` | - |
| precision | 精度 | `'year' \| 'month' \| 'day' \| 'hour' \| 'minute' \| 'second' \| 'week' \| 'week-day' \| 'quarter'` | `'day'` |
| renderLabel | 自定义渲染每列展示的内容。其中 `type` 参数为 `precision` 中的任意值,`data` 参数为默认渲染的数字 | `(type: string, data: number) => ReactNode` | - |
Expand Down
3 changes: 3 additions & 0 deletions src/components/picker-view/picker-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export type PickerViewProps = {
value?: PickerValue[]
defaultValue?: PickerValue[]
mouseWheel?: boolean
wheelResistance?: boolean
loading?: boolean
loadingContent?: ReactNode
onChange?: (value: PickerValue[], extend: PickerValueExtend) => void
Expand All @@ -41,6 +42,7 @@ const defaultProps = {
defaultValue: [],
renderLabel: defaultRenderLabel,
mouseWheel: false,
wheelResistance: true,
loadingContent: (
<div className={`${classPrefix}-loading-content`}>
<SpinLoading />
Expand Down Expand Up @@ -114,6 +116,7 @@ export const PickerView = memo<PickerViewProps>(p => {
onSelect={handleSelect}
renderLabel={props.renderLabel}
mouseWheel={props.mouseWheel}
wheelResistance={props.wheelResistance}
/>
))}
<div className={`${classPrefix}-mask`}>
Expand Down
10 changes: 8 additions & 2 deletions src/components/picker-view/wheel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
onSelect: (value: PickerValue, index: number) => void
renderLabel: (item: PickerColumnItem) => ReactNode
mouseWheel: boolean
wheelResistance: boolean
}

export const Wheel = memo<Props>(
Expand Down Expand Up @@ -160,13 +161,17 @@
draggingRef.current = false

const speed = velocity * whellDir * 50
const position = scrollY + distance * whellDir + speed
const position =
scrollY +

Check warning on line 165 in src/components/picker-view/wheel.tsx

View check run for this annotation

Codecov / codecov/patch

src/components/picker-view/wheel.tsx#L165

Added line #L165 was not covered by tests
(distance / (props.wheelResistance ? 4 : 1)) * whellDir +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里为什么 4 就认为是有段落感的?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里为什么 4 就认为是有段落感的?

通过rubberbandIfOutOfBounds运算后,滚动差值会在itemHeight以内浮动,如果大于itemHeight,则无法一滚动一行,滚动差值过于小时,由于皮筋效应,会出现卡顿感,所以这个理想值被定在了4,也就是distance应该在25左右

speed
const boundNum = bound(position, min, max)
const targetIndex = -Math.round(boundNum / itemHeight.current)

scrollSelect(targetIndex)
} else {
const position = scrollY + distance * whellDir
const position =
scrollY + (distance / (props.wheelResistance ? 4 : 1)) * whellDir

api.start({
y: rubberbandIfOutOfBounds(
Expand Down Expand Up @@ -306,6 +311,7 @@
if (prev.onSelect !== next.onSelect) return false
if (prev.renderLabel !== next.renderLabel) return false
if (prev.mouseWheel !== next.mouseWheel) return false
if (prev.wheelResistance !== next.wheelResistance) return false
if (!isEqual(prev.column, next.column)) return false

return true
Expand Down
2 changes: 2 additions & 0 deletions src/components/picker/index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type PickerValueExtend = {
| destroyOnClose | Destroy `dom` when not visible | `boolean` | `false` |
| forceRender | Render content forcely | `boolean` | `false` |
| mouseWheel | Whether to allow interact with mouse wheel | `boolean` | `false` |
| wheelResistance | Enable increased resistance to scrolling when selecting through mouse wheel | `boolean` | `true` |
| onCancel | Triggered when cancelling | `() => void` | - |
| onClose | Triggered when confirming or cancelling | `() => void` | - |
| onConfirm | Triggered when confirming | `(value: PickerValue[], extend: PickerValueExtend) => void` | - |
Expand Down Expand Up @@ -160,6 +161,7 @@ type PickerDate = Date & {
| max | Max value | `PickerDate` | ten years later |
| min | Minimum value | `PickerDate` | ten years ago |
| mouseWheel | Whether to allow interact with mouse wheel | `boolean` | `false` |
| wheelResistance | Enable increased resistance to scrolling when selecting through mouse wheel | `boolean` | `true` |
| onConfirm | Triggered when confirming | `(value: PickerDate) => void` | - |
| onSelect | Triggered when the options are changed | `(value: PickerDate) => void` | - |
| precision | Precision | `'year' \| 'month' \| 'day' \| 'hour' \| 'minute' \| 'second' \| 'week' \| 'week-day' \| 'quarter'` | `'day'` |
Expand Down
2 changes: 2 additions & 0 deletions src/components/picker/index.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type PickerValueExtend = {
| destroyOnClose | 不可见时是否销毁 `DOM` 结构 | `boolean` | `false` |
| forceRender | 强制渲染内容 | `boolean` | `false` |
| mouseWheel | 是否允许通过鼠标滚轮进行选择 | `boolean` | `false` |
| wheelResistance | 启用通过鼠标滚轮进行选择时,增强滚动的段落感 | `boolean` | `true` |
| onCancel | 取消时触发 | `() => void` | - |
| onClose | 确认和取消时都会触发关闭事件 | `() => void` | - |
| onConfirm | 确认时触发 | `(value: PickerValue[], extend: PickerValueExtend) => void` | - |
Expand Down Expand Up @@ -162,6 +163,7 @@ type PickerDate = Date & {
| max | 最大值 | `PickerDate` | 十年后 |
| min | 最小值 | `PickerDate` | 十年前 |
| mouseWheel | 是否允许通过鼠标滚轮进行选择 | `boolean` | `false` |
| wheelResistance | 启用通过鼠标滚轮进行选择时,增强滚动的段落感 | `boolean` | `true` |
| onConfirm | 确认时触发 | `(value: PickerDate) => void` | - |
| onSelect | 选项改变时触发 | `(value: PickerDate) => void` | - |
| precision | 精度 | `'year' \| 'month' \| 'day' \| 'hour' \| 'minute' \| 'second' \| 'week' \| 'week-day' \| 'quarter'` | `'day'` |
Expand Down
2 changes: 2 additions & 0 deletions src/components/picker/picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export type PickerProps = {
) => ReactNode
renderLabel?: (item: PickerColumnItem) => ReactNode
mouseWheel?: boolean
wheelResistance?: boolean
popupClassName?: string
popupStyle?: CSSProperties
} & Pick<
Expand Down Expand Up @@ -188,6 +189,7 @@ export const Picker = memo(
renderLabel={props.renderLabel}
value={innerValue}
mouseWheel={props.mouseWheel}
wheelResistance={props.wheelResistance}
onChange={onChange}
/>
</div>
Expand Down
Loading