Skip to content

Commit

Permalink
fix(useToolbar): add typesafe keys (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
carlosthe19916 authored May 24, 2022
1 parent 2fb0145 commit 4be16a5
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 26 deletions.
46 changes: 32 additions & 14 deletions src/hooks/useToolbar/useToolbar.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,23 @@ import { useToolbar } from './useToolbar';

describe('useToolbar', () => {
it('initialValue', () => {
const initialValue = new Map([['key1', ['value1', 'value2']]]);
const { result } = renderHook(() => useToolbar<string>(initialValue));
type KeyType = 'key1' | 'key2';

const initialValue = new Map<KeyType, string[]>([['key1', ['value1', 'value2']]]);
const { result } = renderHook(() => useToolbar<KeyType, string>(initialValue));

expect(result.current.isPresent).toBe(true);
expect(result.current.filters.get('key1')).toEqual(['value1', 'value2']);
});

it('clearAllFilters', () => {
const initialValue = new Map([
type KeyType = 'key1' | 'key2';

const initialValue = new Map<KeyType, string[]>([
['key1', ['value1', 'value2']],
['key2', ['value3', 'value4']],
]);
const { result } = renderHook(() => useToolbar<string>(initialValue));
const { result } = renderHook(() => useToolbar<KeyType, string>(initialValue));

const { clearAllFilters } = result.current;
act(() => clearAllFilters());
Expand All @@ -27,7 +31,9 @@ describe('useToolbar', () => {
});

it("addFilter: 'string'", () => {
const { result } = renderHook(() => useToolbar<string>());
type KeyType = 'key1' | 'key2';

const { result } = renderHook(() => useToolbar<KeyType, string>());

const { addFilter } = result.current;
expect(result.current.isPresent).toBe(false);
Expand All @@ -39,7 +45,9 @@ describe('useToolbar', () => {
});

it("addFilter: 'ToolbarChip'", () => {
const { result } = renderHook(() => useToolbar<ToolbarChip>());
type KeyType = 'key1' | 'key2';

const { result } = renderHook(() => useToolbar<KeyType, ToolbarChip>());

const { addFilter } = result.current;
expect(result.current.isPresent).toBe(false);
Expand All @@ -52,7 +60,9 @@ describe('useToolbar', () => {
});

it("setFilter: 'string'", () => {
const { result } = renderHook(() => useToolbar<string>());
type KeyType = 'key1' | 'key2';

const { result } = renderHook(() => useToolbar<KeyType, string>());

const { setFilter } = result.current;
expect(result.current.isPresent).toBe(false);
Expand All @@ -64,7 +74,9 @@ describe('useToolbar', () => {
});

it("setFilter: 'ToolbarChip'", () => {
const { result } = renderHook(() => useToolbar<ToolbarChip>());
type KeyType = 'key1' | 'key2';

const { result } = renderHook(() => useToolbar<KeyType, ToolbarChip>());

const { setFilter } = result.current;
expect(result.current.isPresent).toBe(false);
Expand All @@ -78,11 +90,13 @@ describe('useToolbar', () => {
});

it('removeFilter: single value', () => {
const initialValue = new Map([
type KeyType = 'key1' | 'key2';

const initialValue = new Map<KeyType, string[]>([
['key1', ['value1', 'value11']],
['key2', ['value2', 'value22']],
]);
const { result } = renderHook(() => useToolbar<string>(initialValue));
const { result } = renderHook(() => useToolbar<KeyType, string>(initialValue));

const { removeFilter } = result.current;
act(() => removeFilter('key1', 'value11'));
Expand All @@ -92,7 +106,9 @@ describe('useToolbar', () => {
});

it('removeFilter: single value', () => {
const initialValue = new Map([
type KeyType = 'key1' | 'key2';

const initialValue = new Map<KeyType, ToolbarChip[]>([
[
'key1',
[
Expand All @@ -108,7 +124,7 @@ describe('useToolbar', () => {
],
],
]);
const { result } = renderHook(() => useToolbar<ToolbarChip>(initialValue));
const { result } = renderHook(() => useToolbar<KeyType, ToolbarChip>(initialValue));

const { removeFilter } = result.current;
act(() => removeFilter('key1', { key: 'value11', node: 'VALUE11' }));
Expand All @@ -117,11 +133,13 @@ describe('useToolbar', () => {
});

it('removeFilter: array', () => {
const initialValue = new Map([
type KeyType = 'key1' | 'key2';

const initialValue = new Map<KeyType, string[]>([
['key1', ['value1', 'value11', 'value111']],
['key2', ['value2', 'value22', 'value222']],
]);
const { result } = renderHook(() => useToolbar<string>(initialValue));
const { result } = renderHook(() => useToolbar<KeyType, string>(initialValue));

const { removeFilter } = result.current;
act(() => removeFilter('key1', ['value1', 'value111']));
Expand Down
24 changes: 12 additions & 12 deletions src/hooks/useToolbar/useToolbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,36 @@ const getToolbarChipKey = (value: string | ToolbarChip) => {

type FilterType = string | ToolbarChip;

interface HookState<T> {
filters: Map<string, T[]>;
interface HookState<K, T> {
filters: Map<K, T[]>;
isPresent: boolean;
addFilter: (key: string, value: T) => void;
setFilter: (key: string, value: T[]) => void;
removeFilter: (key: string, value: FilterType | FilterType[]) => void;
addFilter: (key: K, value: T) => void;
setFilter: (key: K, value: T[]) => void;
removeFilter: (key: K, value: FilterType | FilterType[]) => void;
clearAllFilters: () => void;
}

export const useToolbar = <T extends FilterType>(
initialValue: Map<string, T[]> | (() => Map<string, T[]>) = new Map()
): HookState<T> => {
const [filters, setFilters] = useState<Map<string, T[]>>(initialValue);
export const useToolbar = <K, T extends FilterType>(
initialValue: Map<K, T[]> | (() => Map<K, T[]>) = new Map()
): HookState<K, T> => {
const [filters, setFilters] = useState<Map<K, T[]>>(initialValue);

const isPresent =
Array.from(filters.values()).reduce((previous, current) => [...previous, ...current], [])
.length > 0;

const addFilter = (key: string, value: T) => {
const addFilter = (key: K, value: T) => {
setFilters((current) => {
const currentChips = current.get(key) || [];
return new Map(current).set(key, [...currentChips, value]);
});
};

const setFilter = (key: string, value: T[]) => {
const setFilter = (key: K, value: T[]) => {
setFilters((current) => new Map(current).set(key, value));
};

const removeFilter = (key: string, value: FilterType | FilterType[]) => {
const removeFilter = (key: K, value: FilterType | FilterType[]) => {
setFilters((current) => {
let elementsToBeRemoved: FilterType[];
if (Array.isArray(value)) {
Expand Down

0 comments on commit 4be16a5

Please sign in to comment.