Skip to content

Commit

Permalink
feat(apiref): apiRef object for access VisibilityContext from outside…
Browse files Browse the repository at this point in the history
… of Menu component
  • Loading branch information
asmyshlyaev177 committed Oct 6, 2021
1 parent 9a42375 commit ef9a281
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 3 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

[Dynamically add items when last is visible](https://codesandbox.io/s/react-horizontal-scrolling-menu-v2-dynamically-add-items-38ted?file=/src/index.tsx)

[apiRef - controling component outside](https://codesandbox.io/s/react-horizontal-scrolling-menu-v2-apiref-vdr0d?file=/src/index.tsx)


### Previous version [V1](https://github.com/asmyshlyaev177/react-horizontal-scrolling-menu/tree/v1)

Expand Down Expand Up @@ -169,6 +171,7 @@ RightArrow | React component for right arrow
onWheel | (VisibilityContext, event) => void
onScroll | (VisibilityContext, event) => void
onInit | (VisibilityContext) => void
apiRef | React.RefObject
onUpdate | (VisibilityContext) => void
onMouseDown |(VisibilityContext) => (React.MouseEventHandler) => void
onMouseUp | (VisibilityContext) => (React.MouseEventHandler) => void
Expand Down Expand Up @@ -222,7 +225,10 @@ scrollToItem(getItemById(centerItem, 'smooth', 'center'))
```
Check out [examples](#examples)


### apiRef
Can pass Ref object to Menu, current value will assigned as VisibilityContext. But `visibleItems` and some other values can be staled, so better use it only for firing functions like `scrollToItem`.
See [`apiRef` example](#examples)

## Browser support
* Browser must support **IntersectionObserver API**, [**Element.scrollIntoView for Safari**](https://github.com/magic-akari/seamless-scroll-polyfill) and **requestAnimationFrame** or use polyfills.
* Only modern browsers, no IE or smart toasters
Expand Down
1 change: 1 addition & 0 deletions src/ItemsMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class ItemsMap extends Map<string, IOItem> {
}
return this;
}

public first(): IOItem | undefined {
return this.toArr()[0]?.[1];
}
Expand Down
6 changes: 6 additions & 0 deletions src/createApi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ describe('createApi', () => {
jest.clearAllMocks();
});

test('visibleItems', () => {
const { items, visibleItems } = setup([0.3, 1, 0.7]);

expect(createApi(items, visibleItems).visibleItems).toEqual(visibleItems);
});

test('visibleItemsWithoutSeparators', () => {
const { items, visibleItems } = setup([0.3, 1, 0.7]);
const expected = items
Expand Down
1 change: 1 addition & 0 deletions src/createApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export default function createApi(
scrollNext,
scrollPrev,
scrollToItem,
visibleItems,
visibleItemsWithoutSeparators,
};
}
Expand Down
20 changes: 20 additions & 0 deletions src/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ describe('ScrollMenu', () => {
jest.resetAllMocks();
});

// eslint-disable-next-line radar/no-duplicate-string
test('should fire with publicApi', () => {
(useIntersectionObserver as jest.Mock).mockReturnValue({
visibleItems: defaultItemsWithSeparators,
Expand Down Expand Up @@ -148,6 +149,25 @@ describe('ScrollMenu', () => {
});
});

describe('apiRef', () => {
beforeEach(() => {
jest.resetAllMocks();
});

test('should fire with publicApi', () => {
(useIntersectionObserver as jest.Mock).mockReturnValue({
visibleItems: defaultItemsWithSeparators,
});
const apiRef = { current: {} } as React.MutableRefObject<publicApiType>;

const { container } = setup({ apiRef });

expect(container.firstChild).toBeTruthy();

comparePublicApi(apiRef.current);
});
});

describe('onUpdate', () => {
beforeEach(() => {
jest.resetAllMocks();
Expand Down
7 changes: 5 additions & 2 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export interface Props {
separatorClassName?: string;
scrollContainerClassName?: string;
wrapperClassName?: string;
apiRef?: React.MutableRefObject<publicApiType>;
}

function ScrollMenu({
Expand All @@ -58,6 +59,7 @@ function ScrollMenu({
itemClassName = '',
separatorClassName = '',
wrapperClassName = '',
apiRef = { current: {} as publicApiType },
}: Props): JSX.Element {
const LeftArrow = getElementOrConstructor(_LeftArrow);
const RightArrow = getElementOrConstructor(_RightArrow);
Expand Down Expand Up @@ -113,11 +115,12 @@ function ScrollMenu({
initComplete: mounted,
items,
scrollContainer: scrollContainerRef,
visibleItems,
}),
[api, mounted, items, visibleItems]
[api, mounted, items]
);

apiRef.current = publicApi.current;

const scrollHandler = React.useCallback(
(event: React.UIEvent) => onScroll(publicApi.current, event),
[onScroll, publicApi]
Expand Down

0 comments on commit ef9a281

Please sign in to comment.