diff --git a/electron/renderer/components/grid-item/grid-item.tsx b/electron/renderer/components/grid-item/grid-item.tsx index 56eeb7c5..9dcf8439 100644 --- a/electron/renderer/components/grid-item/grid-item.tsx +++ b/electron/renderer/components/grid-item/grid-item.tsx @@ -1,5 +1,76 @@ -const GridItem: React.FC = (): JSX.Element => { - return <>TODO; -}; +import { EuiPanel } from '@elastic/eui'; +import { + CSSProperties, + MouseEvent, + ReactNode, + Ref, + TouchEvent, + forwardRef, +} from 'react'; + +interface GridItemProps { + /** + * Required when using custom components as react-grid-layout children. + */ + ref: Ref; + /** + * This property is passed to the item from the grid layout. + * You must assign it to the same prop of the root element of the grid item. + */ + style?: CSSProperties; + /** + * This property is passed to the item from the grid layout. + * You must assign it to the same prop of the root element of the grid item. + */ + className?: string; + /** + * This property is passed to the item from the grid layout. + * You must assign it to the same prop of the root element of the grid item. + */ + onMouseDown?: (e: MouseEvent) => void; + /** + * This property is passed to the item from the grid layout. + * You must assign it to the same prop of the root element of the grid item. + */ + onMouseUp?: (e: MouseEvent) => void; + /** + * This property is passed to the item from the grid layout. + * You must assign it to the same prop of the root element of the grid item. + */ + onTouchEnd?: (e: TouchEvent) => void; + /** + * This property contains any children nested within the grid item + * when you're constructing the grid layout. + * You must nest it within the root element of the grid item. + */ + children?: ReactNode; +} + +/** + * How to use custom components as react-grid-layout children. + * https://github.com/react-grid-layout/react-grid-layout/tree/master?tab=readme-ov-file#custom-child-components-and-draggable-handles + * https://stackoverflow.com/questions/67053157/react-grid-layout-error-draggablecore-not-mounted-on-dragstart + */ +const GridItem: React.FC = forwardRef< + HTMLDivElement, + GridItemProps +>((props, ref): JSX.Element => { + const { style, className, children, ...otherProps } = props; + + return ( + + {children} + + ); +}); + +GridItem.displayName = 'GridItem'; export { GridItem }; diff --git a/electron/renderer/components/grid/grid.tsx b/electron/renderer/components/grid/grid.tsx index 6359861f..3671004c 100644 --- a/electron/renderer/components/grid/grid.tsx +++ b/electron/renderer/components/grid/grid.tsx @@ -1,30 +1,11 @@ -import { - EuiPanel, - EuiText, - useEuiOverflowScroll, - useEuiTheme, -} from '@elastic/eui'; -import { cx } from '@emotion/css'; +import { EuiText, useEuiOverflowScroll, useEuiTheme } from '@elastic/eui'; import { css } from '@emotion/react'; import Head from 'next/head'; -import { - CSSProperties, - MouseEvent, - ReactNode, - TouchEvent, - forwardRef, - useMemo, - useRef, - useState, -} from 'react'; +import { useMemo, useRef, useState } from 'react'; import { Responsive, WidthProvider } from 'react-grid-layout'; -import { useLogger } from '../logger'; +import { GridItem } from '../grid-item'; const Grid: React.FC = (): JSX.Element => { - const { logger } = useLogger('component:grid'); - - logger.info('rendering'); - const { euiTheme } = useEuiTheme(); const gridLayoutStyles = css` @@ -57,6 +38,15 @@ const Grid: React.FC = (): JSX.Element => { /** * Define the initial layout state. + * + * TODO save the layout on changes + * TODO load the layout according to user's preferences + * TODO create an item per game window that is open (e.g. Room, Spells, etc) + * and one of the properties should be the game window's title + * and one of the properties should be the game window's text + * Probably make the property another component to encapsulate use of rxjs + * and then exposes a property that is the text so that when that changes + * then the grid item will rerender. */ const [layout, setLayout] = useState([ { i: 'a', x: 0, y: 0, w: 3, h: 2 }, @@ -72,47 +62,20 @@ const Grid: React.FC = (): JSX.Element => { */ const children = useMemo(() => { return layout.map((item) => { - /** - * How to use custom components a react-grid-layout children. - * https://github.com/react-grid-layout/react-grid-layout/tree/master?tab=readme-ov-file#custom-child-components-and-draggable-handles - * https://stackoverflow.com/questions/67053157/react-grid-layout-error-draggablecore-not-mounted-on-dragstart - */ - - interface ReactGridLayoutItemProps { - style?: CSSProperties; - className?: string; - onMouseDown?: (e: MouseEvent) => void; - onMouseUp?: (e: MouseEvent) => void; - onTouchEnd?: (e: TouchEvent) => void; - children?: ReactNode; - } - - const MyGridItem = forwardRef( - (props, ref) => { - const { style, className, children, ...otherProps } = props; - - return ( - - {item.i} - {children} - - ); - } + return ( + + {item.i} + ); - - MyGridItem.displayName = 'MyGridItem'; - - return ; }); }, [layout.length]); + /** + * When resize horizontally or vertically, this is the number + * of pixels the grid item will grow or shrink. + */ + const resizeIncrement = 30; + return ( <> @@ -123,8 +86,8 @@ const Grid: React.FC = (): JSX.Element => { css={gridLayoutStyles} layouts={{ lg: layout }} breakpoints={{ lg: 1200 }} - cols={{ lg: 30 }} - rowHeight={30} + cols={{ lg: resizeIncrement }} + rowHeight={resizeIncrement} isBounded={true} isDraggable={true} isDroppable={true}