Skip to content

Instantly share code, notes, and snippets.

@diegohaz
Created April 22, 2020 05:05
Show Gist options
  • Save diegohaz/9a422d2e126ae9231b017a273cd734a7 to your computer and use it in GitHub Desktop.
Save diegohaz/9a422d2e126ae9231b017a273cd734a7 to your computer and use it in GitHub Desktop.
import * as React from "react";
import { FixedSizeList as List, areEqual } from "react-window";
import chunk from "lodash/chunk";
import {
usePopoverState,
PopoverDisclosure,
Button,
PopoverDisclosureHTMLProps,
} from "reakit";
import {
useGridState,
Grid,
GridRow,
GridCell,
ComboboxGrid,
Combobox,
} from "../future";
import EmojiColorPopover from "./EmojiColorPopover";
import data from "../data/emoji.json";
type Props = { combobox?: boolean };
const emojis = data.slice(0, 500);
const emojiGrid = chunk(data, 8);
// const id = `row-${emojiGrid[index].reduce(
// (acc, curr) => `${acc}${curr.hexcode}`,
// ""
// )}`;
// return (
// <EmojiRow {...grid} style={style} row={index} key={id} id={id} />
// );
function EmojiGrid({ combobox }: Props) {
const grid = useGridState({
virtual: combobox,
currentId: combobox ? null : undefined,
wrap: "horizontal",
});
const GridComponent = combobox ? ComboboxGrid : Grid;
const memoizedGrid = React.useMemo(() => grid, [grid]);
return (
<>
{combobox && <Combobox {...grid} />}
<GridComponent {...grid} aria-label="Emojis">
<List
height={150}
itemCount={emojiGrid.length}
itemSize={32}
width={352}
itemData={memoizedGrid}
useIsScrolling
itemKey={(index) =>
`row-${emojiGrid[index].reduce(
(acc, curr) => `${acc}${curr.hexcode}`,
""
)}`
}
>
{Lol}
</List>
</GridComponent>
</>
);
}
const Lol = React.memo(
// @ts-ignore
({ data, index, style, isScrolling }) => {
const id = `row-${emojiGrid[index].reduce(
(acc, curr) => `${acc}${curr.hexcode}`,
""
)}`;
return (
<EmojiRow
{...data}
simple={isScrolling}
key={id}
id={id}
row={index}
style={style}
/>
);
},
areEqual
);
type EmojiRowProps = EmojiCellProps &
React.ComponentProps<typeof GridRow> & { row: number; simple?: boolean };
const EmojiRow = React.memo(
React.forwardRef<HTMLButtonElement, EmojiRowProps>(
({ row, style, simple, ...props }, ref) => {
return (
<GridRow {...props} key={props.id} style={style} ref={ref}>
{emojiGrid[row].map((emoji) => (
<EmojiCell
{...props}
simple={simple}
key={emoji.hexcode}
id={`emoji-${emoji.hexcode}`}
>
{`${emoji.emoji}`}
</EmojiCell>
))}
</GridRow>
);
}
),
GridRow.unstable_propsAreEqual
);
type EmojiCellProps = React.ComponentProps<typeof GridCell> & {
simple?: boolean;
};
const EmojiCell = React.memo(
React.forwardRef<HTMLButtonElement, EmojiCellProps>(
({ simple, ...props }, ref) => {
const popover = usePopoverState({ placement: "top", modal: true });
return (
<>
<GridCell {...props} key={props.id} ref={ref}>
{({ role, ...cellProps }) => (
<span role={role}>
{simple ? (
<Button {...cellProps} className="components-button">
{props.children}
</Button>
) : (
// @ts-ignore
<Pop {...cellProps} className="components-button">
{props.children}
</Pop>
)}
</span>
)}
</GridCell>
<EmojiColorPopover {...popover} />
</>
);
}
),
GridCell.unstable_propsAreEqual
);
const Pop = React.forwardRef<HTMLButtonElement, PopoverDisclosureHTMLProps>(
(props, ref) => {
const popover = usePopoverState({ placement: "top", modal: true });
return (
<>
<PopoverDisclosure {...popover} {...props} ref={ref}>
{props.children}
</PopoverDisclosure>
<EmojiColorPopover {...popover} />
</>
);
}
);
export default EmojiGrid;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment