-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(accordion): ♻️ separate single & multi accordion (#203)
Co-authored-by: anuraghazra <[email protected]>
- Loading branch information
1 parent
4b96280
commit 747d50c
Showing
23 changed files
with
1,219 additions
and
928 deletions.
There are no files selected for viewing
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,50 +0,0 @@ | ||
/* eslint-disable react-hooks/rules-of-hooks */ | ||
import React from "react"; | ||
import { expectError, expectType } from "tsd"; | ||
import { | ||
MultiOverloadReturn, | ||
SingleOverloadReturn, | ||
} from "../src/accordion/types"; | ||
import { useAccordionState } from "../src/accordion/AccordionState"; | ||
|
||
const multi = useAccordionState({ allowMultiple: true }); | ||
expectType<(string | null)[] | undefined>(multi.selectedIds); | ||
expectType<React.Dispatch<React.SetStateAction<(string | null)[]>>>( | ||
multi.setSelectedIds, | ||
); | ||
expectType<MultiOverloadReturn>(multi); | ||
|
||
const single = useAccordionState({ allowMultiple: false }); | ||
expectType<string | null | undefined>(single.selectedId); | ||
expectType<React.Dispatch<React.SetStateAction<string | null>>>( | ||
single.setSelectedId, | ||
); | ||
expectType<SingleOverloadReturn>(single); | ||
|
||
expectType<MultiOverloadReturn>( | ||
useAccordionState({ | ||
allowMultiple: true, | ||
defaultSelectedIds: [], | ||
}), | ||
); | ||
|
||
expectError( | ||
useAccordionState({ | ||
allowMultiple: true, | ||
defaultSelectedId: "", | ||
}), | ||
); | ||
|
||
expectError( | ||
useAccordionState({ | ||
allowMultiple: false, | ||
defaultSelectedIds: [], | ||
}), | ||
); | ||
|
||
expectType<SingleOverloadReturn>( | ||
useAccordionState({ | ||
allowMultiple: false, | ||
defaultSelectedId: "", | ||
}), | ||
); | ||
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { | ||
CompositeState, | ||
CompositeActions, | ||
useCompositeState, | ||
CompositeInitialState, | ||
} from "reakit"; | ||
|
||
export function useAccordionBaseState( | ||
props: AccordionBaseInitialState = {}, | ||
): AccordionBaseStateReturn { | ||
const composite = useCompositeState({ | ||
orientation: "vertical", | ||
...props, | ||
}); | ||
|
||
const panels = useCompositeState(); | ||
|
||
return { | ||
panels: panels.items, | ||
registerPanel: panels.registerItem, | ||
unregisterPanel: panels.unregisterItem, | ||
...composite, | ||
}; | ||
} | ||
|
||
export type AccordionBaseState = CompositeState & { | ||
/** | ||
* Lists all the panels. | ||
*/ | ||
panels: CompositeState["items"]; | ||
}; | ||
|
||
export type AccordionBaseActions = CompositeActions & { | ||
/** | ||
* Registers a accordion panel. | ||
*/ | ||
registerPanel: CompositeActions["registerItem"]; | ||
|
||
/** | ||
* Unregisters a accordion panel. | ||
*/ | ||
unregisterPanel: CompositeActions["unregisterItem"]; | ||
}; | ||
|
||
export type AccordionBaseInitialState = CompositeInitialState; | ||
|
||
export type AccordionBaseStateReturn = AccordionBaseState & | ||
AccordionBaseActions; |
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,112 @@ | ||
import * as React from "react"; | ||
import { Dispatch, SetStateAction } from "react"; | ||
import { useControllableState } from "@chakra-ui/hooks"; | ||
|
||
import { | ||
AccordionBaseState, | ||
AccordionBaseActions, | ||
useAccordionBaseState, | ||
AccordionBaseInitialState, | ||
} from "./AccordionBaseState"; | ||
|
||
export function useAccordionMultiState( | ||
props: AccordionMultiInitialState = {}, | ||
): AccordionMultiStateReturn { | ||
const { manual = true } = props; | ||
|
||
const { move, ...baseState } = useAccordionBaseState(props); | ||
|
||
const [selectedIds, setSelectedIds] = useControllableState({ | ||
defaultValue: props?.defaultSelectedIds || [], | ||
value: props?.selectedIds, | ||
onChange: props?.onSelectedIdsChange, | ||
}); | ||
|
||
const select = React.useCallback( | ||
(id: string) => { | ||
move(id); | ||
|
||
if (selectedIds.includes(id)) { | ||
setSelectedIds(prevIds => prevIds?.filter(pId => pId !== id)); | ||
|
||
return; | ||
} | ||
|
||
setSelectedIds(prevIds => [...prevIds, id]); | ||
}, | ||
|
||
[move, selectedIds, setSelectedIds], | ||
); | ||
|
||
return { | ||
selectedIds, | ||
setSelectedIds, | ||
select, | ||
manual, | ||
allowToggle: true, | ||
allowMultiple: true, | ||
move, | ||
...baseState, | ||
}; | ||
} | ||
|
||
export type AccordionMultiState = AccordionBaseState & { | ||
/** | ||
* The current selected accordion's `id`. | ||
*/ | ||
selectedIds: string[]; | ||
|
||
/** | ||
* Allow to toggle accordion items | ||
* @default false | ||
*/ | ||
allowToggle: boolean; | ||
|
||
/** | ||
* Allow to open multiple accordion items | ||
*/ | ||
allowMultiple: boolean; | ||
|
||
/** | ||
* Whether the accodion selection should be manual. | ||
* @default true | ||
*/ | ||
manual: boolean; | ||
}; | ||
|
||
export type AccordionMultiActions = AccordionBaseActions & { | ||
/** | ||
* Sets the value. | ||
*/ | ||
setSelectedIds: Dispatch<SetStateAction<string[]>>; | ||
|
||
/** | ||
* Moves into and selects an accordion by its `id`. | ||
*/ | ||
select: (id: string) => void; | ||
}; | ||
|
||
export type AccordionMultiInitialState = Pick< | ||
Partial<AccordionMultiState>, | ||
"manual" | "selectedIds" | ||
> & | ||
AccordionBaseInitialState & { | ||
/** | ||
* The initial value to be used, in uncontrolled mode | ||
* @default [] | ||
*/ | ||
defaultSelectedIds?: string[] | (() => string[]); | ||
|
||
/** | ||
* The callback fired when the value changes | ||
*/ | ||
onSelectedIdsChange?: (value: string[]) => void; | ||
|
||
/** | ||
* The function that determines if the state should be updated | ||
*/ | ||
shouldUpdate?: (prev: string[], next: string[]) => boolean; | ||
}; | ||
|
||
export type AccordionMultiStateReturn = AccordionMultiState & | ||
AccordionMultiActions; |
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
Oops, something went wrong.
747d50c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs: