Skip to content

Commit

Permalink
feat(components/picker): 优化 PickerCol 跟随选中
Browse files Browse the repository at this point in the history
  • Loading branch information
mengxinssfd committed Jan 13, 2024
1 parent 7dde9cb commit 5a2246b
Showing 1 changed file with 35 additions and 10 deletions.
45 changes: 35 additions & 10 deletions packages/components/src/picker/components/picker.Col.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { debounceTime, fromEvent, timer, race, take, tap } from 'rxjs';
import { OptionValueType, getClasses } from '@pkg/shared';
import { getClassNames } from '@tool-pack/basic';
import { getClassNames, emptyFn } from '@tool-pack/basic';
import type { PickerOption } from '~/picker';
import { useEffect, useRef } from 'react';
import { Option } from '~/option';
Expand All @@ -17,7 +18,7 @@ interface Props {
const cls = getClasses('picker-col', ['option', 'list', 'item'], ['picked']);

export const PickerCol: React.FC<Props> = ({
value: railValue,
value: colValue,
onPickOption,
options,
}) => {
Expand All @@ -27,17 +28,32 @@ export const PickerCol: React.FC<Props> = ({
// 跟随
useEffect(() => {
if (isFirstRef.current) return;
if (railValue === undefined) return;
ulRef.current?.scrollTo({ top: getScrollTop(), behavior: 'smooth' });
}, [options, railValue]);
if (colValue === undefined) return;

const clear = changeOverflow((ul) =>
ul.scrollTo({ top: getScrollTop(), behavior: 'smooth' }),
);

const sub = race(
fromEvent(ulRef.current!, 'scroll').pipe(debounceTime(50)),
timer(1000),
)
.pipe(tap(clear), take(1))
.subscribe();

return () => {
clear();
sub.unsubscribe();
};
}, [options, colValue]);

// 初始化
useEffect(() => {
if (!isFirstRef.current) return;
isFirstRef.current = false;

if (railValue === undefined) return;
const cb = () => (ulRef.current!.scrollTop = getScrollTop());
if (colValue === undefined) return;
const cb = () => changeOverflow((ul) => (ul.scrollTop = getScrollTop()))();
const timer = setTimeout(cb, 0);
return () => {
clearTimeout(timer);
Expand All @@ -64,7 +80,7 @@ export const PickerCol: React.FC<Props> = ({
onPickOption(opt, index, options);
},
className: getClassNames(attrs.className, cls.__.option, {
[cls['--'].picked]: value === railValue,
[cls['--'].picked]: value === colValue,
}),
}}
>
Expand All @@ -77,11 +93,20 @@ export const PickerCol: React.FC<Props> = ({
</div>
);

function changeOverflow(cb: (ul: HTMLUListElement) => void): () => void {
const ul = ulRef.current;
if (!ul) return emptyFn;

const overflow = ul.style.overflow;
ul.style.overflow = 'auto';
cb(ul);
return () => (ul.style.overflow = overflow);
}
function getScrollTop(): number {
const root = ulRef.current;
if (!root || railValue === undefined) return 0;
if (!root || colValue === undefined) return 0;

const index = options.findIndex((opt) => opt.value === railValue);
const index = options.findIndex((opt) => opt.value === colValue);
if (index === -1) return 0;

const item = root.children[index] as HTMLElement;
Expand Down

0 comments on commit 5a2246b

Please sign in to comment.