-
Notifications
You must be signed in to change notification settings - Fork 73
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Eliminate the need to provide index in DragAndDrop (#11252)
- Loading branch information
Showing
14 changed files
with
539 additions
and
28 deletions.
There are no files selected for viewing
62 changes: 62 additions & 0 deletions
62
frontend/packages/shared/src/components/dragAndDrop/DragAndDropList/DragAndDropList.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import React, { ReactNode } from 'react'; | ||
import { DragAndDropList } from './'; | ||
import { | ||
DragAndDropListItemContext, | ||
DragAndDropListItemContextProps, | ||
} from '../DragAndDropListItem/DragAndDropListItemContext'; | ||
import { | ||
DragAndDropRootContext, | ||
DragAndDropRootContextProps, | ||
} from '../DragAndDropProvider/DragAndDropRootContext'; | ||
import { render as renderRtl } from '@testing-library/react'; | ||
import { DndProvider } from 'react-dnd'; | ||
import { HTML5Backend } from 'react-dnd-html5-backend'; | ||
import { domListClass, domListId } from 'app-shared/components/dragAndDrop/utils/domUtils'; | ||
|
||
// | ||
const itemId = 'id'; | ||
const rootId = 'rootId'; | ||
const uniqueDomId = ':r0:'; | ||
const onDrop = jest.fn(); | ||
const defaultlistItemContextProps: DragAndDropListItemContextProps = { | ||
isDisabled: false, | ||
itemId, | ||
}; | ||
const defaultRootContextProps: DragAndDropRootContextProps<string> = { | ||
onDrop, | ||
rootId, | ||
uniqueDomId, | ||
}; | ||
|
||
/* eslint-disable testing-library/no-node-access */ | ||
describe('DragAndDropList', () => { | ||
it('Renders with correct id and class name', () => { | ||
const { container } = render()(<div />); | ||
const expectedId = domListId(uniqueDomId, itemId); | ||
const expectedClass = domListClass(uniqueDomId); | ||
expect(container.firstChild).toHaveAttribute('id', expectedId); | ||
expect(container.firstChild).toHaveClass(expectedClass); | ||
}); | ||
}); | ||
|
||
interface RenderProps { | ||
listItemContextProps?: Partial<DragAndDropListItemContextProps>; | ||
rootContextProps?: Partial<DragAndDropRootContextProps<string>>; | ||
} | ||
|
||
function render({ listItemContextProps = {}, rootContextProps = {} }: RenderProps = {}) { | ||
return (children: ReactNode) => | ||
renderRtl( | ||
<DndProvider backend={HTML5Backend}> | ||
<DragAndDropRootContext.Provider | ||
value={{ ...rootContextProps, ...defaultRootContextProps }} | ||
> | ||
<DragAndDropListItemContext.Provider | ||
value={{ ...listItemContextProps, ...defaultlistItemContextProps }} | ||
> | ||
<DragAndDropList>{children}</DragAndDropList> | ||
</DragAndDropListItemContext.Provider> | ||
</DragAndDropRootContext.Provider> | ||
</DndProvider>, | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
...ckages/shared/src/components/dragAndDrop/DragAndDropListItem/DragAndDropListItem.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import React from 'react'; | ||
import { DragAndDropListItem, DragAndDropListItemProps } from './DragAndDropListItem'; | ||
import { | ||
DragAndDropListItemContext, | ||
DragAndDropListItemContextProps, | ||
} from './DragAndDropListItemContext'; | ||
import { | ||
DragAndDropRootContext, | ||
DragAndDropRootContextProps, | ||
} from '../DragAndDropProvider/DragAndDropRootContext'; | ||
import { render as renderRtl } from '@testing-library/react'; | ||
import { DndProvider } from 'react-dnd'; | ||
import { HTML5Backend } from 'react-dnd-html5-backend'; | ||
import { domItemClass, domItemId } from 'app-shared/components/dragAndDrop/utils/domUtils'; | ||
|
||
// | ||
const itemId = 'id'; | ||
const parentId = 'parentId'; | ||
const rootId = 'rootId'; | ||
const uniqueDomId = ':r0:'; | ||
const onDrop = jest.fn(); | ||
const renderItem = () => <div>test</div>; | ||
const defaultlistItemProps: DragAndDropListItemProps = { | ||
itemId, | ||
renderItem, | ||
}; | ||
const defaultlistItemContextProps: DragAndDropListItemContextProps = { | ||
isDisabled: false, | ||
itemId: parentId, | ||
}; | ||
const defaultRootContextProps: DragAndDropRootContextProps<string> = { | ||
onDrop, | ||
rootId, | ||
uniqueDomId, | ||
}; | ||
|
||
/* eslint-disable testing-library/no-node-access */ | ||
describe('DragAndDropListItem', () => { | ||
it('Renders with correct id and class name', () => { | ||
const { container } = render(); | ||
const expectedId = domItemId(uniqueDomId, itemId); | ||
const expectedClass = domItemClass(uniqueDomId); | ||
expect(container.firstChild).toHaveAttribute('id', expectedId); | ||
expect(container.firstChild).toHaveClass(expectedClass); | ||
}); | ||
}); | ||
|
||
interface RenderProps { | ||
listItemProps?: Partial<DragAndDropListItemProps>; | ||
listItemContextProps?: Partial<DragAndDropListItemContextProps>; | ||
rootContextProps?: Partial<DragAndDropRootContextProps<string>>; | ||
} | ||
|
||
function render({ | ||
listItemProps = {}, | ||
listItemContextProps = {}, | ||
rootContextProps = {}, | ||
}: RenderProps = {}) { | ||
return renderRtl( | ||
<DndProvider backend={HTML5Backend}> | ||
<DragAndDropRootContext.Provider value={{ ...rootContextProps, ...defaultRootContextProps }}> | ||
<DragAndDropListItemContext.Provider | ||
value={{ ...listItemContextProps, ...defaultlistItemContextProps }} | ||
> | ||
<DragAndDropListItem<string> {...listItemProps} {...defaultlistItemProps} /> | ||
</DragAndDropListItemContext.Provider> | ||
</DragAndDropRootContext.Provider> | ||
</DndProvider>, | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 2 additions & 2 deletions
4
...kages/shared/src/components/dragAndDrop/DragAndDropListItem/DragAndDropListItemContext.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,11 @@ | ||
import { createContext } from 'react'; | ||
|
||
export type DragDropListItemContextProps = { | ||
export type DragAndDropListItemContextProps = { | ||
isDisabled: boolean; | ||
itemId: string; | ||
}; | ||
|
||
export const DragAndDropListItemContext = createContext<DragDropListItemContextProps>({ | ||
export const DragAndDropListItemContext = createContext<DragAndDropListItemContextProps>({ | ||
isDisabled: false, | ||
itemId: null, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
frontend/packages/shared/src/components/dragAndDrop/hooks/useDomSelectors.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import React from 'react'; | ||
import { renderHook } from '@testing-library/react'; | ||
import { useDomSelectors } from 'app-shared/components/dragAndDrop/hooks/useDomSelectors'; | ||
import { DragAndDropRootContext } from 'app-shared/components/dragAndDrop/DragAndDropProvider'; | ||
import { | ||
extractIdFromDomItemId, | ||
extractIdFromDomListId, | ||
} from 'app-shared/components/dragAndDrop/utils/domUtils'; | ||
|
||
// Test data: | ||
const id = 'id'; | ||
const uniqueDomId = 'baseId'; | ||
|
||
describe('useDomSelectors', () => { | ||
afterEach(jest.clearAllMocks); | ||
|
||
it('Returns the base id and selector attributes for list and item components with the given id', () => { | ||
const { result } = renderHook(() => useDomSelectors(id), { | ||
wrapper: ({ children }) => ( | ||
<DragAndDropRootContext.Provider | ||
value={{ uniqueDomId, rootId: 'rootId', onDrop: jest.fn() }} | ||
> | ||
{children} | ||
</DragAndDropRootContext.Provider> | ||
), | ||
}); | ||
expect(result.current).toEqual({ | ||
baseId: uniqueDomId, | ||
list: { | ||
id: expect.any(String), | ||
className: expect.any(String), | ||
}, | ||
item: { | ||
id: expect.any(String), | ||
className: expect.any(String), | ||
}, | ||
}); | ||
const { list, item } = result.current; | ||
expect(extractIdFromDomListId(uniqueDomId, list.id)).toEqual(id); | ||
expect(extractIdFromDomItemId(uniqueDomId, item.id)).toEqual(id); | ||
}); | ||
|
||
it('Throws an error if not wrapped by a DragAndDropProvider', () => { | ||
jest.spyOn(console, 'error').mockImplementation(); | ||
const renderFn = () => renderHook(() => useDomSelectors(id)); | ||
expect(renderFn).toThrow( | ||
new Error('useDomSelectors must be used within a DragAndDropRootContext provider.'), | ||
); | ||
}); | ||
}); |
37 changes: 37 additions & 0 deletions
37
frontend/packages/shared/src/components/dragAndDrop/hooks/useDomSelectors.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { DragAndDropRootContext } from 'app-shared/components/dragAndDrop/DragAndDropProvider'; | ||
import { useContext } from 'react'; | ||
import { | ||
domItemClass, | ||
domItemId, | ||
domListClass, | ||
domListId, | ||
} from 'app-shared/components/dragAndDrop/utils/domUtils'; | ||
|
||
interface Attributes { | ||
id: string; | ||
className: string; | ||
} | ||
|
||
interface DomSelectors { | ||
baseId: string; | ||
item: Attributes; | ||
list: Attributes; | ||
} | ||
|
||
export function useDomSelectors(itemId: string): DomSelectors { | ||
const context = useContext(DragAndDropRootContext); | ||
if (!context) { | ||
throw new Error('useDomSelectors must be used within a DragAndDropRootContext provider.'); | ||
} | ||
return { | ||
baseId: context.uniqueDomId, | ||
item: { | ||
id: domItemId(context.uniqueDomId, itemId), | ||
className: domItemClass(context.uniqueDomId), | ||
}, | ||
list: { | ||
id: domListId(context.uniqueDomId, itemId), | ||
className: domListClass(context.uniqueDomId), | ||
}, | ||
}; | ||
} |
Oops, something went wrong.