Skip to content
Permalink
Browse files
feat(grid): added hook to access grid list size
This is much more useful than the children renderer function since
you'll be able to get the size at **any** child without any prop
drilling.
  • Loading branch information
mlaursen committed Aug 19, 2020
1 parent 3c61f3c commit a44881602de57447e9cb5ba720f5f2c031936863
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 20 deletions.
@@ -14,6 +14,7 @@ import bem from "../bem";
import useResizeObserver from "../sizing/useResizeObserver";
import GridListCell from "./GridListCell";
import getScrollbarSize from "./scrollbarSize";
import { GridListSizeProvider, GridListSize } from "./context";

/**
* This is the css variable that is used store the current size of each cell.
@@ -25,18 +26,6 @@ export const CELL_SIZE_VAR = "--rmd-cell-size";
*/
export const CELL_MARGIN_VAR = "--rmd-cell-margin";

export interface GridListSize {
/**
* The current number of columns in the `GridList`.
*/
columns: number;

/**
* The current width of each cell within the grid.
*/
cellWidth: number;
}

/**
* The children render function that will be provided the current grid list size
* object and should return renderable elements.
@@ -230,14 +219,16 @@ const GridList = forwardRef<HTMLDivElement, GridListProps>(function GridList(
}

return (
<div
{...props}
ref={refHandler}
style={mergedStyle}
className={cn(block(), className)}
>
{content}
</div>
<GridListSizeProvider value={gridSize}>
<div
{...props}
ref={refHandler}
style={mergedStyle}
className={cn(block(), className)}
>
{content}
</div>
</GridListSizeProvider>
);
});

@@ -2,6 +2,7 @@ import React from "react";
import { render } from "@testing-library/react";

import GridList from "../GridList";
import { useGridListSize } from "../context";

let getBoundingClientRect: jest.SpyInstance<DOMRect, []>;
beforeAll(() => {
@@ -112,4 +113,44 @@ describe("GridList", () => {
);
expect(container).toMatchSnapshot();
});

it("should allow for the current cellWidth to be accessed with the useGridListSize hook", () => {
const Child = () => {
const size = useGridListSize();

return <div data-testid="child">{JSON.stringify(size)}</div>;
};

const { getByTestId } = render(
<GridList>
<Child />
</GridList>
);
const child = getByTestId("child");
expect(child).toMatchInlineSnapshot(`
<div
data-testid="child"
>
{"cellWidth":140.57142857142858,"columns":7}
</div>
`);
});

it("should provide -1 if the useGridListSize hook is used without a parent GridList component", () => {
const Child = () => {
const size = useGridListSize();

return <div data-testid="child">{JSON.stringify(size)}</div>;
};

const { getByTestId } = render(<Child />);
const child = getByTestId("child");
expect(child).toMatchInlineSnapshot(`
<div
data-testid="child"
>
{"columns":-1,"cellWidth":-1}
</div>
`);
});
});
@@ -0,0 +1,28 @@
import { createContext, useContext } from "react";

export interface GridListSize {
/**
* The current number of columns in the `GridList`.
*/
columns: number;

/**
* The current width of each cell within the grid.
*/
cellWidth: number;
}

const context = createContext<GridListSize>({
columns: -1,
cellWidth: -1,
});

export const { Provider: GridListSizeProvider } = context;

/**
* Gets the current size of each cell within the `GridList` component. If this
* is used without a parent `GridList` component, `-1` is returned instead.
*/
export function useGridListSize(): GridListSize {
return useContext(context);
}
@@ -11,3 +11,5 @@ export { default as GridListCell } from "./GridListCell";
export * from "./GridListCell";

export { default as scrollbarSize } from "./scrollbarSize";

export { useGridListSize, GridListSize } from "./context";

0 comments on commit a448816

Please sign in to comment.