Skip to content

Commit ee9377a

Browse files
committed
fix(context): Introduce InternalContext
1 parent d48464f commit ee9377a

File tree

3 files changed

+125
-0
lines changed

3 files changed

+125
-0
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import React from 'react';
2+
import { render, fireEvent } from '@testing-library/react';
3+
import '@testing-library/jest-dom';
4+
import { InternalContextProvider, useInternalContext, DataViewSelection } from './InternalContext';
5+
6+
describe('InternalContext', () => {
7+
const mockSelection: DataViewSelection = {
8+
onSelect: jest.fn(),
9+
isSelected: jest.fn(),
10+
isSelectDisabled: jest.fn(),
11+
};
12+
13+
test('should provide context value and allow consuming it', () => {
14+
const TestComponent = () => {
15+
const { selection } = useInternalContext();
16+
17+
return (
18+
<div>
19+
<button onClick={() => selection?.onSelect(true, [ 'item1' ])}>Select item</button>
20+
<span>{selection?.isSelected('item1') ? 'Selected' : 'Not selected'}</span>
21+
</div>
22+
);
23+
};
24+
25+
const { getByText } = render(
26+
<InternalContextProvider selection={mockSelection}>
27+
<TestComponent />
28+
</InternalContextProvider>
29+
);
30+
31+
fireEvent.click(getByText('Select item'));
32+
expect(mockSelection.onSelect).toHaveBeenCalledWith(true, [ 'item1' ]);
33+
});
34+
35+
test('should handle selection state correctly', () => {
36+
const mockSelectionState = {
37+
...mockSelection,
38+
isSelected: jest.fn((item) => item === 'item1'),
39+
};
40+
41+
const TestComponent = () => {
42+
const { selection } = useInternalContext();
43+
44+
return (
45+
<div>
46+
<span>{selection?.isSelected('item1') ? 'Item 1 is selected' : 'Item 1 is not selected'}</span>
47+
<span>{selection?.isSelected('item2') ? 'Item 2 is selected' : 'Item 2 is not selected'}</span>
48+
</div>
49+
);
50+
};
51+
52+
const { getByText } = render(
53+
<InternalContextProvider selection={mockSelectionState}>
54+
<TestComponent />
55+
</InternalContextProvider>
56+
);
57+
58+
expect(getByText('Item 1 is selected')).toBeInTheDocument();
59+
expect(getByText('Item 2 is not selected')).toBeInTheDocument();
60+
});
61+
62+
test('should handle selection disabled correctly', () => {
63+
const mockSelectionWithDisabled = {
64+
...mockSelection,
65+
isSelectDisabled: jest.fn((item) => item === 'item3'),
66+
};
67+
68+
const TestComponent = () => {
69+
const { selection } = useInternalContext();
70+
71+
return (
72+
<div>
73+
<span>{selection?.isSelectDisabled?.('item3') ? 'Item 3 is disabled' : 'Item 3 is enabled'}</span>
74+
<span>{selection?.isSelectDisabled?.('item1') ? 'Item 1 is disabled' : 'Item 1 is enabled'}</span>
75+
</div>
76+
);
77+
};
78+
79+
const { getByText } = render(
80+
<InternalContextProvider selection={mockSelectionWithDisabled}>
81+
<TestComponent />
82+
</InternalContextProvider>
83+
);
84+
85+
expect(getByText('Item 3 is disabled')).toBeInTheDocument();
86+
expect(getByText('Item 1 is enabled')).toBeInTheDocument();
87+
});
88+
});
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React, { createContext, PropsWithChildren, useContext } from 'react';
2+
3+
export interface DataViewSelection {
4+
/** Called when the selection of items changes */
5+
onSelect: (isSelecting: boolean, items?: any[] | any) => void; // eslint-disable-line @typescript-eslint/no-explicit-any
6+
/** Checks if a specific item is currently selected */
7+
isSelected: (item: any) => boolean; // eslint-disable-line @typescript-eslint/no-explicit-any
8+
/** Determines if selection is disabled for a given item */
9+
isSelectDisabled?: (item: any) => boolean; // eslint-disable-line @typescript-eslint/no-explicit-any
10+
}
11+
12+
export interface InternalContextValue {
13+
selection?: DataViewSelection;
14+
}
15+
16+
export const InternalContext = createContext<InternalContextValue>({
17+
selection: undefined
18+
});
19+
20+
export type InternalProviderProps = PropsWithChildren<InternalContextValue>
21+
22+
export const InternalContextProvider: React.FC<InternalProviderProps> = ({
23+
children,
24+
selection
25+
}) => (
26+
<InternalContext.Provider
27+
value={{ selection }}
28+
>
29+
{children}
30+
</InternalContext.Provider>
31+
);
32+
33+
export const useInternalContext = () => useContext(InternalContext);
34+
35+
export default InternalContext;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { default } from './InternalContext';
2+
export * from './InternalContext';

0 commit comments

Comments
 (0)