Skip to content

Commit

Permalink
fix: [ScrollView] a11y
Browse files Browse the repository at this point in the history
  • Loading branch information
akai committed Jul 13, 2021
1 parent 6c7a2f8 commit 8adf043
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 17 deletions.
4 changes: 4 additions & 0 deletions src/components/LocaleProvider/locales/en_US.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,8 @@ export default {
releaseOrSwipe: 'Release to send, swipe up to cancel',
release2cancel: 'Release to cancel',
},
ScrollView: {
prev: 'Previous',
next: 'Next',
},
};
4 changes: 4 additions & 0 deletions src/components/LocaleProvider/locales/zh_CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,8 @@ export default {
releaseOrSwipe: '松开发送,上滑取消',
release2cancel: '松开手指,取消发送',
},
ScrollView: {
prev: '上一页',
next: '下一页',
},
};
15 changes: 8 additions & 7 deletions src/components/ScrollView/Item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@ export type ScrollViewEffect = 'slide';
export type ScrollViewItemProps = {
item: any;
effect?: ScrollViewEffect;
onIntersect?: (item: any, entry: IntersectionObserverEntry) => boolean;
onIntersect?: (item?: any, entry?: IntersectionObserverEntry) => boolean | void;
};

const observerOptions = {
threshold: [0, 0.1],
};

export const Item: React.FC<ScrollViewItemProps> = (props) => {
const { item, effect, children, onIntersect } = props;
const itemRef = useRef<HTMLDivElement>(null);
const options = {
threshold: [0, 0.1],
};

useEffect(() => {
if (!onIntersect) return () => {};
if (!onIntersect) return undefined;

const observer = new IntersectionObserver(([entry]) => {
if (entry.intersectionRatio > 0) {
Expand All @@ -26,15 +27,15 @@ export const Item: React.FC<ScrollViewItemProps> = (props) => {
observer.unobserve(entry.target);
}
}
}, options);
}, observerOptions);

if (itemRef.current) {
observer.observe(itemRef.current);
}
return () => {
observer.disconnect();
};
}, [children]);
}, [item, onIntersect]);

return (
<div
Expand Down
38 changes: 28 additions & 10 deletions src/components/ScrollView/ScrollView.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React, { useRef, useImperativeHandle } from 'react';
import React, { useRef, useImperativeHandle, useCallback } from 'react';
import clsx from 'clsx';
import { Item, ScrollViewItemProps } from './Item';
import { IconButton } from '../IconButton';
import { useLocale } from '../LocaleProvider';
import canUse from '../../utils/canUse';

export type ScrollViewProps<T> = Pick<ScrollViewItemProps, 'effect' | 'onIntersect'> & {
Expand Down Expand Up @@ -37,6 +38,10 @@ export const ScrollView = React.forwardRef<ScrollViewHandle, ScrollViewProps<any
} = props;

const scrollerRef = useRef<HTMLDivElement>(null!);
const { trans } = useLocale('ScrollView', {
prev: 'Previous',
next: 'Next',
});

function handlePrev() {
const el = scrollerRef.current;
Expand All @@ -48,13 +53,16 @@ export const ScrollView = React.forwardRef<ScrollViewHandle, ScrollViewProps<any
el.scrollLeft += el.offsetWidth;
}

function getItemKey(item: any, index: number) {
let key;
if (itemKey) {
key = typeof itemKey === 'function' ? itemKey(item, index) : item[itemKey];
}
return key || index;
}
const getItemKey = useCallback(
(item: any, index: number) => {
let key;
if (itemKey) {
key = typeof itemKey === 'function' ? itemKey(item, index) : item[itemKey];
}
return key || index;
},
[itemKey],
);

useImperativeHandle(ref, () => ({
scrollTo: ({ x, y }: { x?: number; y?: number }) => {
Expand Down Expand Up @@ -82,7 +90,12 @@ export const ScrollView = React.forwardRef<ScrollViewHandle, ScrollViewProps<any
{...other}
>
{hasControls && (
<IconButton className="ScrollView-control" icon="chevron-left" onClick={handlePrev} />
<IconButton
className="ScrollView-control"
icon="chevron-left"
aria-label={trans('prev')}
onClick={handlePrev}
/>
)}
<div className="ScrollView-scroller" ref={scrollerRef} onScroll={onScroll}>
<div className="ScrollView-inner">
Expand All @@ -99,7 +112,12 @@ export const ScrollView = React.forwardRef<ScrollViewHandle, ScrollViewProps<any
</div>
</div>
{hasControls && (
<IconButton className="ScrollView-control" icon="chevron-right" onClick={handleNext} />
<IconButton
className="ScrollView-control"
icon="chevron-right"
aria-label={trans('next')}
onClick={handleNext}
/>
)}
</div>
);
Expand Down

0 comments on commit 8adf043

Please sign in to comment.