From 6c2904f6c591973f37a7ef47b8e16cd97eb998b8 Mon Sep 17 00:00:00 2001 From: Reece Carolan Date: Sat, 27 Aug 2022 00:42:10 -0700 Subject: [PATCH 1/3] docs: add react-virtuoso examples --- package.json | 1 + pnpm-lock.yaml | 29 ++ stories/examples/45-virtual.stories.tsx | 19 +- stories/src/primatives/quote-item.tsx | 20 +- .../src/virtual/react-virtualized/board.tsx | 32 +- .../src/virtual/react-virtualized/list.tsx | 92 +++--- .../virtual/react-virtualized/window-list.tsx | 108 +++---- stories/src/virtual/react-virtuoso/board.tsx | 287 ++++++++++++++++++ stories/src/virtual/react-virtuoso/list.tsx | 136 +++++++++ 9 files changed, 598 insertions(+), 126 deletions(-) create mode 100644 stories/src/virtual/react-virtuoso/board.tsx create mode 100644 stories/src/virtual/react-virtuoso/list.tsx diff --git a/package.json b/package.json index ea70234ff..30a344fb9 100644 --- a/package.json +++ b/package.json @@ -79,6 +79,7 @@ "memoize-one": "^6.0.0", "raf-schd": "^4.0.3", "react-redux": "^8.0.2", + "react-virtuoso": "^2.17.2", "redux": "^4.2.0", "use-memo-one": "^1.1.2" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c9bc79122..bea5eea89 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -109,6 +109,7 @@ specifiers: react-dom-17: npm:react-dom@17.0.2 react-redux: ^8.0.2 react-virtualized: 9.22.3 + react-virtuoso: ^2.17.2 react-window: 1.8.7 redux: ^4.2.0 release-it: 15.3.0 @@ -138,6 +139,7 @@ dependencies: memoize-one: 6.0.0 raf-schd: 4.0.3 react-redux: 8.0.2_ps4ywwwjjeajezffxxirqk36qa + react-virtuoso: 2.17.2_biqbaboplfbrettd7655fr4n2y redux: 4.2.0 use-memo-one: 1.1.2_react@18.2.0 @@ -5067,6 +5069,20 @@ packages: eslint-visitor-keys: 3.3.0 dev: true + /@virtuoso.dev/react-urx/0.2.13_react@18.2.0: + resolution: {integrity: sha512-MY0ugBDjFb5Xt8v2HY7MKcRGqw/3gTpMlLXId2EwQvYJoC8sP7nnXjAxcBtTB50KTZhO0SbzsFimaZ7pSdApwA==} + engines: {node: '>=10'} + peerDependencies: + react: '>=16' + dependencies: + '@virtuoso.dev/urx': 0.2.13 + react: 18.2.0 + dev: false + + /@virtuoso.dev/urx/0.2.13: + resolution: {integrity: sha512-iirJNv92A1ZWxoOHHDYW/1KPoi83939o83iUBQHIim0i3tMeSKEh+bxhJdTHQ86Mr4uXx9xGUTq69cp52ZP8Xw==} + dev: false + /@webassemblyjs/ast/1.11.1: resolution: {integrity: sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==} dependencies: @@ -14434,6 +14450,19 @@ packages: react-lifecycles-compat: 3.0.4 dev: true + /react-virtuoso/2.17.2_biqbaboplfbrettd7655fr4n2y: + resolution: {integrity: sha512-5xl0mCCVEANzY0SbVbUjQgRrc2it3vdGCn72kUQo0wy4s3QGVR8S3QcLZj3lBrHocGIf/ONEJ3g/uqs0KEl9eA==} + engines: {node: '>=10'} + peerDependencies: + react: '>=16 || >=17 || >= 18' + react-dom: '>=16 || >=17 || >= 18' + dependencies: + '@virtuoso.dev/react-urx': 0.2.13_react@18.2.0 + '@virtuoso.dev/urx': 0.2.13 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + dev: false + /react-window/1.8.7_biqbaboplfbrettd7655fr4n2y: resolution: {integrity: sha512-JHEZbPXBpKMmoNO1bNhoXOOLg/ujhL/BU4IqVU9r8eQPcy5KQnGHIHDRkJ0ns9IM5+Aq5LNwt3j8t3tIrePQzA==} engines: {node: '>8.0.0'} diff --git a/stories/examples/45-virtual.stories.tsx b/stories/examples/45-virtual.stories.tsx index 94f7fcaaa..1d3d15abe 100644 --- a/stories/examples/45-virtual.stories.tsx +++ b/stories/examples/45-virtual.stories.tsx @@ -1,20 +1,23 @@ -import React from 'react'; import { storiesOf } from '@storybook/react'; -import ReactWindowList from '../src/virtual/react-window/list'; -import ReactVirtualizedList from '../src/virtual/react-virtualized/list'; +import React from 'react'; import { getQuotes } from '../src/data'; -import ReactWindowBoard from '../src/virtual/react-window/board'; import ReactVirtualizedBoard from '../src/virtual/react-virtualized/board'; +import ReactVirtualizedList from '../src/virtual/react-virtualized/list'; import ReactVirtualizedWindowList from '../src/virtual/react-virtualized/window-list'; +import ReactVirtuosoBoard from '../src/virtual/react-virtuoso/board'; +import ReactVirtuosoList from '../src/virtual/react-virtuoso/list'; +import ReactWindowBoard from '../src/virtual/react-window/board'; +import ReactWindowList from '../src/virtual/react-window/list'; + +storiesOf('Examples/Virtual: react-virtuoso', module) + .add('list', () => ) + .add('board', () => ); storiesOf('Examples/Virtual: react-window', module) .add('list', () => ) .add('board', () => ); -storiesOf( - 'Examples/Virtual: react-virtualized (this library does not official support for react 18)', - module, -) +storiesOf('Examples/Virtual: react-virtualized', module) .add('list', () => ) .add('board', () => ) .add( diff --git a/stories/src/primatives/quote-item.tsx b/stories/src/primatives/quote-item.tsx index ad9c82c1d..3eefad1bb 100644 --- a/stories/src/primatives/quote-item.tsx +++ b/stories/src/primatives/quote-item.tsx @@ -1,14 +1,14 @@ -import React, { CSSProperties } from 'react'; -import styled from '@emotion/styled'; import { colors } from '@atlaskit/theme'; +import styled from '@emotion/styled'; import type { DraggableProvided } from '@hello-pangea/dnd'; +import React, { CSSProperties } from 'react'; import { borderRadius, grid } from '../constants'; -import type { Quote, AuthorColors } from '../types'; +import type { AuthorColors, Quote } from '../types'; interface Props { quote: Quote; isDragging: boolean; - provided: DraggableProvided; + provided?: DraggableProvided; isClone?: boolean; isGroupedOver?: boolean; style?: CSSProperties; @@ -158,13 +158,13 @@ const QuoteId = styled.small` text-align: right; `; -function getStyle(provided: DraggableProvided, style?: CSSProperties | null) { +function getStyle(provided?: DraggableProvided, style?: CSSProperties | null) { if (!style) { - return provided.draggableProps.style; + return provided?.draggableProps.style ?? {}; } return { - ...provided.draggableProps.style, + ...provided?.draggableProps.style, ...style, }; } @@ -186,9 +186,9 @@ function QuoteItem(props: Props) { isDragging={isDragging} isGroupedOver={Boolean(isGroupedOver)} colors={quote.author.colors} - ref={provided.innerRef} - {...provided.draggableProps} - {...provided.dragHandleProps} + ref={provided?.innerRef} + {...provided?.draggableProps} + {...provided?.dragHandleProps} style={getStyle(provided, style)} data-is-dragging={isDragging} data-testid={quote.id} diff --git a/stories/src/virtual/react-virtualized/board.tsx b/stories/src/virtual/react-virtualized/board.tsx index 66e8a5b0d..3a4afde29 100644 --- a/stories/src/virtual/react-virtualized/board.tsx +++ b/stories/src/virtual/react-virtualized/board.tsx @@ -1,28 +1,28 @@ -import React, { CSSProperties, ReactElement, useReducer } from 'react'; -import ReactDOM from 'react-dom'; -import 'react-virtualized/styles.css'; -import { List } from 'react-virtualized'; -import styled from '@emotion/styled'; -import { Global, css } from '@emotion/react'; import { colors } from '@atlaskit/theme'; +import { css, Global } from '@emotion/react'; +import styled from '@emotion/styled'; import type { - DropResult, DraggableLocation, DraggableProvided, + DraggableRubric, DraggableStateSnapshot, DroppableProvided, DroppableStateSnapshot, - DraggableRubric, + DropResult, } from '@hello-pangea/dnd'; -import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd'; -import type { QuoteMap, Quote } from '../../types'; -import Title from '../../primatives/title'; -import { reorderQuoteMap } from '../../reorder'; +import { DragDropContext, Draggable, Droppable } from '@hello-pangea/dnd'; +import React, { CSSProperties, ReactElement, useReducer } from 'react'; +import ReactDOM from 'react-dom'; +import { List } from 'react-virtualized'; +import 'react-virtualized/styles.css'; +import { borderRadius, grid } from '../../constants'; +import { generateQuoteMap } from '../../data'; import QuoteItem from '../../primatives/quote-item'; -import { grid, borderRadius } from '../../constants'; import { getBackgroundColor } from '../../primatives/quote-list'; +import Title from '../../primatives/title'; +import { reorderQuoteMap } from '../../reorder'; +import type { Quote, QuoteMap } from '../../types'; import QuoteCountSlider from '../quote-count-chooser'; -import { generateQuoteMap } from '../../data'; const Container = styled.div` display: flex; @@ -229,6 +229,10 @@ function Board(): ReactElement { return ( <> +

+ React virtualized is no longer maintained and does not support React 18. + Try react-virtuoso or react-window instead. +

{state.columnKeys.map((key: string) => { diff --git a/stories/src/virtual/react-virtualized/list.tsx b/stories/src/virtual/react-virtualized/list.tsx index 9036c6872..60b0c7a32 100644 --- a/stories/src/virtual/react-virtualized/list.tsx +++ b/stories/src/virtual/react-virtualized/list.tsx @@ -1,14 +1,14 @@ +import { DragDropContext, Draggable, Droppable } from '@hello-pangea/dnd'; import React, { CSSProperties, ReactElement, useState } from 'react'; import ReactDOM from 'react-dom'; -import 'react-virtualized/styles.css'; import { List } from 'react-virtualized'; -import { Droppable, Draggable, DragDropContext } from '@hello-pangea/dnd'; +import 'react-virtualized/styles.css'; import type { - DroppableProvided, DraggableProvided, - DraggableStateSnapshot, DraggableRubric, + DraggableStateSnapshot, + DroppableProvided, DropResult, } from '@hello-pangea/dnd'; import type { Quote } from '../../types'; @@ -67,46 +67,52 @@ function App(props: Props): ReactElement { } return ( - - ( - - )} - > - {(droppableProvided: DroppableProvided) => ( - { - // react-virtualized has no way to get the list's ref that I can so - // So we use the `ReactDOM.findDOMNode(ref)` escape hatch to get the ref - if (ref) { - // eslint-disable-next-line react/no-find-dom-node - const whatHasMyLifeComeTo = ReactDOM.findDOMNode(ref); - if (whatHasMyLifeComeTo instanceof HTMLElement) { - droppableProvided.innerRef(whatHasMyLifeComeTo); + <> +

+ React virtualized is no longer maintained and does not support React 18. + Try react-virtuoso or react-window instead. +

+ + ( + + )} + > + {(droppableProvided: DroppableProvided) => ( + { + // react-virtualized has no way to get the list's ref that I can so + // So we use the `ReactDOM.findDOMNode(ref)` escape hatch to get the ref + if (ref) { + // eslint-disable-next-line react/no-find-dom-node + const whatHasMyLifeComeTo = ReactDOM.findDOMNode(ref); + if (whatHasMyLifeComeTo instanceof HTMLElement) { + droppableProvided.innerRef(whatHasMyLifeComeTo); + } } - } - }} - rowRenderer={getRowRender(quotes)} - /> - )} - - + }} + rowRenderer={getRowRender(quotes)} + /> + )} +
+
+ ); } diff --git a/stories/src/virtual/react-virtualized/window-list.tsx b/stories/src/virtual/react-virtualized/window-list.tsx index 7e6102fd3..c889c96ce 100644 --- a/stories/src/virtual/react-virtualized/window-list.tsx +++ b/stories/src/virtual/react-virtualized/window-list.tsx @@ -1,14 +1,14 @@ +import { DragDropContext, Draggable, Droppable } from '@hello-pangea/dnd'; import React, { CSSProperties, ReactElement, useState } from 'react'; import ReactDOM from 'react-dom'; +import { List, WindowScroller } from 'react-virtualized'; import 'react-virtualized/styles.css'; -import { WindowScroller, List } from 'react-virtualized'; -import { Droppable, Draggable, DragDropContext } from '@hello-pangea/dnd'; import type { - DroppableProvided, DraggableProvided, - DraggableStateSnapshot, DraggableRubric, + DraggableStateSnapshot, + DroppableProvided, DropResult, } from '@hello-pangea/dnd'; import type { Quote } from '../../types'; @@ -67,54 +67,60 @@ function App(props: Props): ReactElement { } return ( - - ( - - )} - > - {(droppableProvided: DroppableProvided) => ( - - {({ height, isScrolling, onChildScroll, scrollTop }: any) => ( - { - // react-virtualized has no way to get the list's ref that I can so - // So we use the `ReactDOM.findDOMNode(ref)` escape hatch to get the ref - if (ref) { - // eslint-disable-next-line react/no-find-dom-node - const whatHasMyLifeComeTo = ReactDOM.findDOMNode(ref); - if (whatHasMyLifeComeTo instanceof HTMLElement) { - droppableProvided.innerRef(whatHasMyLifeComeTo); + <> +

+ React virtualized is no longer maintained and does not support React 18. + Try react-virtuoso or react-window instead. +

+ + ( + + )} + > + {(droppableProvided: DroppableProvided) => ( + + {({ height, isScrolling, onChildScroll, scrollTop }: any) => ( + { + // react-virtualized has no way to get the list's ref that I can so + // So we use the `ReactDOM.findDOMNode(ref)` escape hatch to get the ref + if (ref) { + // eslint-disable-next-line react/no-find-dom-node + const whatHasMyLifeComeTo = ReactDOM.findDOMNode(ref); + if (whatHasMyLifeComeTo instanceof HTMLElement) { + droppableProvided.innerRef(whatHasMyLifeComeTo); + } } - } - }} - rowRenderer={getRowRender(quotes)} - /> - )} - - )} - - + }} + rowRenderer={getRowRender(quotes)} + /> + )} +
+ )} +
+
+ ); } diff --git a/stories/src/virtual/react-virtuoso/board.tsx b/stories/src/virtual/react-virtuoso/board.tsx new file mode 100644 index 000000000..e324f054d --- /dev/null +++ b/stories/src/virtual/react-virtuoso/board.tsx @@ -0,0 +1,287 @@ +import { colors } from '@atlaskit/theme'; +import { css, Global } from '@emotion/react'; +import styled from '@emotion/styled'; +import { + DragDropContext, + Draggable, + DraggableLocation, + DraggableProvided, + DraggableRubric, + DraggableStateSnapshot, + Droppable, + DropResult, +} from '@hello-pangea/dnd'; +import React, { ReactElement, useEffect, useReducer, useState } from 'react'; +import { Virtuoso } from 'react-virtuoso'; +import { borderRadius, grid } from '../../constants'; +import { generateQuoteMap } from '../../data'; +import QuoteItem from '../../primatives/quote-item'; +import { getBackgroundColor } from '../../primatives/quote-list'; +import Title from '../../primatives/title'; +import { reorderQuoteMap } from '../../reorder'; +import type { Quote, QuoteMap } from '../../types'; +import QuoteCountSlider from '../quote-count-chooser'; + +const Container = styled.div` + display: flex; +`; + +interface RowProps { + quote: Quote; + provided: DraggableProvided; + isDragging: boolean; +} + +// Memoizing row items for even better performance! +const Row = React.memo(({ quote, provided, isDragging }: RowProps) => { + return ( +
+
+ +
+
+ ); +}); + +const HeightPreservingItem = ({ children, ...props }: any) => { + const [size, setSize] = useState(0); + const knownSize = props['data-known-size']; + useEffect(() => { + setSize((prevSize) => { + return knownSize === 0 ? prevSize : knownSize; + }); + }, [knownSize]); + + return ( +
+ {children} +
+ ); +}; + +interface ColumnProps { + columnId: string; + quotes: Quote[]; +} + +const ColumnContainer = styled.div` + border-top-left-radius: ${borderRadius}px; + border-top-right-radius: ${borderRadius}px; + background-color: ${colors.N30}; + flex-shrink: 0; + margin: ${grid}px; + display: flex; + flex-direction: column; +`; + +const Column = React.memo(function Column(props: ColumnProps) { + const { columnId, quotes } = props; + + return ( + + {columnId} + ( + + )} + > + {(droppableProvided, snapshot) => { + // Add an extra item to our list to make space for a dragging item + // Usually the DroppableProvided.placeholder does this, but that won't + // work in a virtual list + const itemCount: number = snapshot.isUsingPlaceholder + ? quotes.length + 1 + : quotes.length; + + return ( + { + // We are rendering an extra item for the placeholder + // Do do this we increased our data set size to include one 'fake' item + if (!quote) { + return null; + } + + return ( + + {(provided) => ( + + )} + + ); + }} + /> + ); + }} + + + ); +}); + +interface State { + itemCount: number; + quoteMap: QuoteMap; + columnKeys: string[]; +} + +function getColumnKeys(quoteMap: QuoteMap): string[] { + return Object.keys(quoteMap).sort(); +} + +function getInitialState() { + const itemCount = 10000; + const quoteMap: QuoteMap = generateQuoteMap(itemCount); + const columnKeys: string[] = getColumnKeys(quoteMap); + return { + itemCount, + quoteMap, + columnKeys, + }; +} + +type Action = + | { + type: 'CHANGE_COUNT'; + payload: number; + } + | { + type: 'REORDER'; + payload: QuoteMap; + }; + +function reducer(state: State, action: Action) { + if (action.type === 'CHANGE_COUNT') { + const quoteMap: QuoteMap = generateQuoteMap(action.payload); + return { + itemCount: action.payload, + quoteMap, + columnKeys: getColumnKeys(quoteMap), + }; + } + if (action.type === 'REORDER') { + return { + itemCount: state.itemCount, + quoteMap: action.payload, + columnKeys: getColumnKeys(action.payload), + }; + } + + return state; +} + +function Board(): ReactElement { + const [state, dispatch] = useReducer(reducer, undefined, getInitialState); + + function onDragEnd(result: DropResult) { + if (!result.destination) { + return; + } + const source: DraggableLocation = result.source; + const destination: DraggableLocation = result.destination; + + // did not move anywhere - can bail early + if ( + source.droppableId === destination.droppableId && + source.index === destination.index + ) { + return; + } + + const updated = reorderQuoteMap({ + quoteMap: state.quoteMap, + source, + destination, + }); + + dispatch({ type: 'REORDER', payload: updated.quoteMap }); + } + + return ( + <> + + + + {state.columnKeys.map((key: string) => { + const quotes: Quote[] = state.quoteMap[key]; + + return ; + })} + + + dispatch({ type: 'CHANGE_COUNT', payload: count }) + } + /> + + + + ); +} + +export default Board; diff --git a/stories/src/virtual/react-virtuoso/list.tsx b/stories/src/virtual/react-virtuoso/list.tsx new file mode 100644 index 000000000..14461ea9c --- /dev/null +++ b/stories/src/virtual/react-virtuoso/list.tsx @@ -0,0 +1,136 @@ +import { DragDropContext, Draggable, Droppable } from '@hello-pangea/dnd'; +import React, { ReactElement, useEffect, useState } from 'react'; +import { Virtuoso } from 'react-virtuoso'; + +import type { + DraggableProvided, + DraggableRubric, + DraggableStateSnapshot, + DropResult, +} from '@hello-pangea/dnd'; +import type { Quote } from '../../types'; + +import QuoteItem from '../../primatives/quote-item'; +import reorder from '../../reorder'; + +interface Props { + initial: Quote[]; +} + +interface RowProps { + quote: Quote; + index: number; + provided: DraggableProvided; + isDragging: boolean; +} + +const Row = React.memo(({ quote, index, provided, isDragging }: RowProps) => { + return ( + + ); +}); + +const HeightPreservingItem = ({ children, ...props }: any) => { + const [size, setSize] = useState(0); + const knownSize = props['data-known-size']; + useEffect(() => { + setSize((prevSize) => { + return knownSize === 0 ? prevSize : knownSize; + }); + }, [knownSize]); + return ( +
+ {children} +
+ ); +}; + +function App(props: Props): ReactElement { + const [quotes, setQuotes] = useState(() => props.initial); + + function onDragEnd(result: DropResult) { + if (!result.destination) { + return; + } + if (result.source.index === result.destination.index) { + return; + } + + const newQuotes: Quote[] = reorder( + quotes, + result.source.index, + result.destination.index, + ); + setQuotes(newQuotes); + } + + return ( + + + ( + + )} + > + {(droppableProvided) => ( + ( + + {(provided) => ( + + )} + + )} + /> + )} + + + ); +} + +export default App; From 2909dc4975d48bbf75736da8fec0d1562935fad4 Mon Sep 17 00:00:00 2001 From: Reece Carolan Date: Sat, 27 Aug 2022 00:51:15 -0700 Subject: [PATCH 2/3] chore: move react-virtuoso to devDependencies --- package.json | 2 +- pnpm-lock.yaml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 30a344fb9..8066c98cc 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,6 @@ "memoize-one": "^6.0.0", "raf-schd": "^4.0.3", "react-redux": "^8.0.2", - "react-virtuoso": "^2.17.2", "redux": "^4.2.0", "use-memo-one": "^1.1.2" }, @@ -187,6 +186,7 @@ "react-dom-16": "npm:react-dom@16.14.0", "react-dom-17": "npm:react-dom@17.0.2", "react-virtualized": "9.22.3", + "react-virtuoso": "^2.17.2", "react-window": "1.8.7", "release-it": "15.3.0", "require-from-string": "2.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bea5eea89..855ba090f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -139,7 +139,6 @@ dependencies: memoize-one: 6.0.0 raf-schd: 4.0.3 react-redux: 8.0.2_ps4ywwwjjeajezffxxirqk36qa - react-virtuoso: 2.17.2_biqbaboplfbrettd7655fr4n2y redux: 4.2.0 use-memo-one: 1.1.2_react@18.2.0 @@ -247,6 +246,7 @@ devDependencies: react-dom-16: /react-dom/16.14.0_react@18.2.0 react-dom-17: /react-dom/17.0.2_react@18.2.0 react-virtualized: 9.22.3_biqbaboplfbrettd7655fr4n2y + react-virtuoso: 2.17.2_biqbaboplfbrettd7655fr4n2y react-window: 1.8.7_biqbaboplfbrettd7655fr4n2y release-it: 15.3.0 require-from-string: 2.0.2 @@ -5077,11 +5077,11 @@ packages: dependencies: '@virtuoso.dev/urx': 0.2.13 react: 18.2.0 - dev: false + dev: true /@virtuoso.dev/urx/0.2.13: resolution: {integrity: sha512-iirJNv92A1ZWxoOHHDYW/1KPoi83939o83iUBQHIim0i3tMeSKEh+bxhJdTHQ86Mr4uXx9xGUTq69cp52ZP8Xw==} - dev: false + dev: true /@webassemblyjs/ast/1.11.1: resolution: {integrity: sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==} @@ -14461,7 +14461,7 @@ packages: '@virtuoso.dev/urx': 0.2.13 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 - dev: false + dev: true /react-window/1.8.7_biqbaboplfbrettd7655fr4n2y: resolution: {integrity: sha512-JHEZbPXBpKMmoNO1bNhoXOOLg/ujhL/BU4IqVU9r8eQPcy5KQnGHIHDRkJ0ns9IM5+Aq5LNwt3j8t3tIrePQzA==} From 2a54f3fa706263b1ee4e8006fc2a6d70b2b5c68e Mon Sep 17 00:00:00 2001 From: Reece Carolan Date: Sat, 27 Aug 2022 00:54:00 -0700 Subject: [PATCH 3/3] fix: add optional className to QuoteItem --- stories/src/primatives/quote-item.tsx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/stories/src/primatives/quote-item.tsx b/stories/src/primatives/quote-item.tsx index 3eefad1bb..d8e685cc2 100644 --- a/stories/src/primatives/quote-item.tsx +++ b/stories/src/primatives/quote-item.tsx @@ -13,6 +13,7 @@ interface Props { isGroupedOver?: boolean; style?: CSSProperties; index?: number; + className?: string; } const getBackgroundColor = ( @@ -177,8 +178,16 @@ function getStyle(provided?: DraggableProvided, style?: CSSProperties | null) { // things we should be doing in the selector as we do not know if consumers // will be using PureComponent function QuoteItem(props: Props) { - const { quote, isDragging, isGroupedOver, provided, style, isClone, index } = - props; + const { + quote, + isDragging, + isGroupedOver, + provided, + style, + isClone, + index, + className, + } = props; return ( {isClone ? Clone : null}