Introduce ComponentState (#4386)
* Proof of concept ComponentState * Migrate to createState and createFamilyState * Refactor * Fix * Fix tests * Fix lint * Fix tests * Re-enable coverage
This commit is contained in:
@ -8,7 +8,7 @@ type IconsProviderProps = {
|
||||
};
|
||||
|
||||
export const IconsProvider = ({ children }: IconsProviderProps) => {
|
||||
const setIcons = useSetRecoilState(iconsState);
|
||||
const setIcons = useSetRecoilState(iconsState());
|
||||
|
||||
useEffect(() => {
|
||||
import('../constants/index').then((lazyLoadedIcons) => {
|
||||
|
||||
@ -4,7 +4,7 @@ import { Icon123 } from '@/ui/display/icon';
|
||||
import { iconsState } from '@/ui/display/icon/states/iconsState';
|
||||
|
||||
export const useIcons = () => {
|
||||
const icons = useRecoilValue(iconsState);
|
||||
const icons = useRecoilValue(iconsState());
|
||||
const defaultIcon = Icon123;
|
||||
|
||||
const getIcons = () => {
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import { atom } from 'recoil';
|
||||
|
||||
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
|
||||
export const iconsState = atom<Record<string, IconComponent>>({
|
||||
export const iconsState = createState<Record<string, IconComponent>>({
|
||||
key: 'iconsState',
|
||||
default: {},
|
||||
defaultValue: {},
|
||||
});
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { StateScopeMapKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/StateScopeMapKey';
|
||||
import { createScopeInternalContext } from '@/ui/utilities/recoil-scope/scopes-internal/utils/createScopeInternalContext';
|
||||
import { ComponentStateKey } from '@/ui/utilities/state/component-state/types/ComponentStateKey';
|
||||
|
||||
type DialogManagerScopeInternalContextProps = StateScopeMapKey;
|
||||
type DialogManagerScopeInternalContextProps = ComponentStateKey;
|
||||
|
||||
export const DialogManagerScopeInternalContext =
|
||||
createScopeInternalContext<DialogManagerScopeInternalContextProps>();
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
|
||||
import { DialogOptions } from '../types/DialogOptions';
|
||||
|
||||
@ -7,7 +7,7 @@ type DialogState = {
|
||||
queue: DialogOptions[];
|
||||
};
|
||||
|
||||
export const dialogInternalScopedState = createStateScopeMap<DialogState>({
|
||||
export const dialogInternalScopedState = createComponentState<DialogState>({
|
||||
key: 'dialog/internal-state',
|
||||
defaultValue: {
|
||||
maxQueue: 2,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { StateScopeMapKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/StateScopeMapKey';
|
||||
import { createScopeInternalContext } from '@/ui/utilities/recoil-scope/scopes-internal/utils/createScopeInternalContext';
|
||||
import { ComponentStateKey } from '@/ui/utilities/state/component-state/types/ComponentStateKey';
|
||||
|
||||
type SnackBarManagerScopeInternalContextProps = StateScopeMapKey;
|
||||
type SnackBarManagerScopeInternalContextProps = ComponentStateKey;
|
||||
|
||||
export const SnackBarManagerScopeInternalContext =
|
||||
createScopeInternalContext<SnackBarManagerScopeInternalContextProps>();
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
|
||||
import { SnackBarProps } from '../components/SnackBar';
|
||||
|
||||
@ -11,7 +11,7 @@ export type SnackBarState = {
|
||||
queue: SnackBarOptions[];
|
||||
};
|
||||
|
||||
export const snackBarInternalScopedState = createStateScopeMap<SnackBarState>({
|
||||
export const snackBarInternalScopedState = createComponentState<SnackBarState>({
|
||||
key: 'snackBarState',
|
||||
defaultValue: {
|
||||
maxQueue: 3,
|
||||
|
||||
@ -3,7 +3,7 @@ import { useRecoilState } from 'recoil';
|
||||
import { iconPickerState } from '../states/iconPickerState';
|
||||
|
||||
export const useIconPicker = () => {
|
||||
const [iconPicker, setIconPicker] = useRecoilState(iconPickerState);
|
||||
const [iconPicker, setIconPicker] = useRecoilState(iconPickerState());
|
||||
|
||||
return {
|
||||
Icon: iconPicker.Icon,
|
||||
|
||||
@ -1,14 +1,13 @@
|
||||
import { atom } from 'recoil';
|
||||
|
||||
import { IconApps } from '@/ui/display/icon';
|
||||
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
|
||||
type IconPickerState = {
|
||||
Icon: IconComponent;
|
||||
iconKey: string;
|
||||
};
|
||||
|
||||
export const iconPickerState = atom<IconPickerState>({
|
||||
export const iconPickerState = createState<IconPickerState>({
|
||||
key: 'iconPickerState',
|
||||
default: { Icon: IconApps, iconKey: 'IconApps' },
|
||||
defaultValue: { Icon: IconApps, iconKey: 'IconApps' },
|
||||
});
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { DropdownScopeInternalContext } from '@/ui/layout/dropdown/scopes/scope-internal-context/DropdownScopeInternalContext';
|
||||
import { dropdownHotkeyStateScopeMap } from '@/ui/layout/dropdown/states/dropdownHotkeyStateScopeMap';
|
||||
import { dropdownWidthStateScopeMap } from '@/ui/layout/dropdown/states/dropdownWidthStateScopeMap';
|
||||
import { isDropdownOpenStateScopeMap } from '@/ui/layout/dropdown/states/isDropdownOpenStateScopeMap';
|
||||
import { dropdownHotkeyComponentState } from '@/ui/layout/dropdown/states/dropdownHotkeyComponentState';
|
||||
import { dropdownWidthComponentState } from '@/ui/layout/dropdown/states/dropdownWidthComponentState';
|
||||
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
|
||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||
import { getState } from '@/ui/utilities/recoil-scope/utils/getState';
|
||||
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
||||
|
||||
type UseDropdownStatesProps = {
|
||||
dropdownScopeId?: string;
|
||||
@ -19,8 +19,17 @@ export const useDropdownStates = ({
|
||||
|
||||
return {
|
||||
scopeId,
|
||||
dropdownHotkeyScopeState: getState(dropdownHotkeyStateScopeMap, scopeId),
|
||||
dropdownWidthState: getState(dropdownWidthStateScopeMap, scopeId),
|
||||
isDropdownOpenState: getState(isDropdownOpenStateScopeMap, scopeId),
|
||||
dropdownHotkeyScopeState: extractComponentState(
|
||||
dropdownHotkeyComponentState,
|
||||
scopeId,
|
||||
),
|
||||
dropdownWidthState: extractComponentState(
|
||||
dropdownWidthComponentState,
|
||||
scopeId,
|
||||
),
|
||||
isDropdownOpenState: extractComponentState(
|
||||
isDropdownOpenComponentState,
|
||||
scopeId,
|
||||
),
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { StateScopeMapKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/StateScopeMapKey';
|
||||
import { createScopeInternalContext } from '@/ui/utilities/recoil-scope/scopes-internal/utils/createScopeInternalContext';
|
||||
import { ComponentStateKey } from '@/ui/utilities/state/component-state/types/ComponentStateKey';
|
||||
|
||||
type DropdownScopeInternalContextProps = StateScopeMapKey;
|
||||
type DropdownScopeInternalContextProps = ComponentStateKey;
|
||||
|
||||
export const DropdownScopeInternalContext =
|
||||
createScopeInternalContext<DropdownScopeInternalContextProps>();
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
|
||||
export const dropdownHotkeyComponentState = createComponentState<
|
||||
HotkeyScope | null | undefined
|
||||
>({
|
||||
key: 'dropdownHotkeyComponentState',
|
||||
defaultValue: null,
|
||||
});
|
||||
@ -1,9 +0,0 @@
|
||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
|
||||
|
||||
export const dropdownHotkeyStateScopeMap = createStateScopeMap<
|
||||
HotkeyScope | null | undefined
|
||||
>({
|
||||
key: 'dropdownHotkeyStateScopeMap',
|
||||
defaultValue: null,
|
||||
});
|
||||
@ -0,0 +1,8 @@
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
|
||||
export const dropdownWidthComponentState = createComponentState<
|
||||
number | undefined
|
||||
>({
|
||||
key: 'dropdownWidthComponentState',
|
||||
defaultValue: 160,
|
||||
});
|
||||
@ -1,8 +0,0 @@
|
||||
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
|
||||
|
||||
export const dropdownWidthStateScopeMap = createStateScopeMap<
|
||||
number | undefined
|
||||
>({
|
||||
key: 'dropdownWidthStateScopeMap',
|
||||
defaultValue: 160,
|
||||
});
|
||||
@ -0,0 +1,6 @@
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
|
||||
export const isDropdownOpenComponentState = createComponentState<boolean>({
|
||||
key: 'isDropdownOpenComponentState',
|
||||
defaultValue: false,
|
||||
});
|
||||
@ -1,6 +0,0 @@
|
||||
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
|
||||
|
||||
export const isDropdownOpenStateScopeMap = createStateScopeMap<boolean>({
|
||||
key: 'isDropdownOpenStateScopeMap',
|
||||
defaultValue: false,
|
||||
});
|
||||
@ -2,7 +2,7 @@ import { useRef } from 'react';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { Key } from 'ts-key-enum';
|
||||
|
||||
import { RIGHT_DRAWER_CLICK_OUTSIDE_LISTENER_ID } from '@/ui/layout/right-drawer/constants/RightDrawerClickOutsideListener';
|
||||
@ -41,12 +41,12 @@ const StyledRightDrawer = styled.div`
|
||||
|
||||
export const RightDrawer = () => {
|
||||
const [isRightDrawerOpen, setIsRightDrawerOpen] = useRecoilState(
|
||||
isRightDrawerOpenState,
|
||||
isRightDrawerOpenState(),
|
||||
);
|
||||
|
||||
const [isRightDrawerExpanded] = useRecoilState(isRightDrawerExpandedState);
|
||||
const isRightDrawerExpanded = useRecoilValue(isRightDrawerExpandedState());
|
||||
|
||||
const [rightDrawerPage] = useRecoilState(rightDrawerPageState);
|
||||
const rightDrawerPage = useRecoilValue(rightDrawerPageState());
|
||||
|
||||
const { closeRightDrawer } = useRightDrawer();
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ const StyledRightDrawerBody = styled.div`
|
||||
`;
|
||||
|
||||
export const RightDrawerRouter = () => {
|
||||
const [rightDrawerPage] = useRecoilState(rightDrawerPageState);
|
||||
const [rightDrawerPage] = useRecoilState(rightDrawerPageState());
|
||||
|
||||
let page = <></>;
|
||||
let topBar = <></>;
|
||||
|
||||
@ -10,7 +10,7 @@ import { isRightDrawerExpandedState } from '../states/isRightDrawerExpandedState
|
||||
|
||||
export const RightDrawerTopBarExpandButton = () => {
|
||||
const [isRightDrawerExpanded, setIsRightDrawerExpanded] = useRecoilState(
|
||||
isRightDrawerExpandedState,
|
||||
isRightDrawerExpandedState(),
|
||||
);
|
||||
|
||||
const handleButtonClick = () => {
|
||||
|
||||
@ -12,10 +12,12 @@ describe('useRightDrawer', () => {
|
||||
it('Should test the default behavior of useRightDrawer and change the states as the function calls', async () => {
|
||||
const useCombinedHooks = () => {
|
||||
const { openRightDrawer, closeRightDrawer } = useRightDrawer();
|
||||
const isRightDrawerOpen = useRecoilValue(isRightDrawerOpenState);
|
||||
const isRightDrawerExpanded = useRecoilValue(isRightDrawerExpandedState);
|
||||
const isRightDrawerOpen = useRecoilValue(isRightDrawerOpenState());
|
||||
const isRightDrawerExpanded = useRecoilValue(
|
||||
isRightDrawerExpandedState(),
|
||||
);
|
||||
|
||||
const rightDrawerPage = useRecoilValue(rightDrawerPageState);
|
||||
const rightDrawerPage = useRecoilValue(rightDrawerPageState());
|
||||
|
||||
return {
|
||||
openRightDrawer,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { useRecoilState, useSetRecoilState } from 'recoil';
|
||||
|
||||
import { isRightDrawerExpandedState } from '../states/isRightDrawerExpandedState';
|
||||
import { isRightDrawerOpenState } from '../states/isRightDrawerOpenState';
|
||||
@ -7,14 +7,15 @@ import { RightDrawerPages } from '../types/RightDrawerPages';
|
||||
|
||||
export const useRightDrawer = () => {
|
||||
const [isRightDrawerOpen, setIsRightDrawerOpen] = useRecoilState(
|
||||
isRightDrawerOpenState,
|
||||
isRightDrawerOpenState(),
|
||||
);
|
||||
const [, setIsRightDrawerExpanded] = useRecoilState(
|
||||
isRightDrawerExpandedState,
|
||||
const setIsRightDrawerExpanded = useSetRecoilState(
|
||||
isRightDrawerExpandedState(),
|
||||
);
|
||||
|
||||
const [rightDrawerPage, setRightDrawerPage] =
|
||||
useRecoilState(rightDrawerPageState);
|
||||
const [rightDrawerPage, setRightDrawerPage] = useRecoilState(
|
||||
rightDrawerPageState(),
|
||||
);
|
||||
|
||||
const openRightDrawer = (rightDrawerPage: RightDrawerPages) => {
|
||||
setRightDrawerPage(rightDrawerPage);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { atom } from 'recoil';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
|
||||
export const isRightDrawerExpandedState = atom<boolean>({
|
||||
export const isRightDrawerExpandedState = createState<boolean>({
|
||||
key: 'isRightDrawerExpandedState',
|
||||
default: false,
|
||||
defaultValue: false,
|
||||
});
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { atom } from 'recoil';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
|
||||
export const isRightDrawerOpenState = atom<boolean>({
|
||||
export const isRightDrawerOpenState = createState<boolean>({
|
||||
key: 'ui/layout/is-right-drawer-open',
|
||||
default: false,
|
||||
defaultValue: false,
|
||||
});
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { atom } from 'recoil';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
|
||||
import { RightDrawerPages } from '../types/RightDrawerPages';
|
||||
|
||||
export const rightDrawerPageState = atom<RightDrawerPages | null>({
|
||||
export const rightDrawerPageState = createState<RightDrawerPages | null>({
|
||||
key: 'ui/layout/right-drawer-page',
|
||||
default: null,
|
||||
defaultValue: null,
|
||||
});
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import { SelectableListScopeInternalContext } from '@/ui/layout/selectable-list/scopes/scope-internal-context/SelectableListScopeInternalContext';
|
||||
import { selectableItemIdsStateScopeMap } from '@/ui/layout/selectable-list/states/selectableItemIdsStateScopeMap';
|
||||
import { selectableListOnEnterStateScopeMap } from '@/ui/layout/selectable-list/states/selectableListOnEnterStateScopeMap';
|
||||
import { selectedItemIdStateScopeMap } from '@/ui/layout/selectable-list/states/selectedItemIdStateScopeMap';
|
||||
import { isSelectedItemIdFamilySelectorScopeMap } from '@/ui/layout/selectable-list/states/selectors/isSelectedItemIdFamilySelectorScopeMap';
|
||||
import { selectableItemIdsComponentState } from '@/ui/layout/selectable-list/states/selectableItemIdsComponentState';
|
||||
import { selectableListOnEnterComponentState } from '@/ui/layout/selectable-list/states/selectableListOnEnterComponentState';
|
||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||
import { isSelectedItemIdFamilySelector } from '@/ui/layout/selectable-list/states/selectors/isSelectedItemIdFamilySelector';
|
||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||
import { getFamilyState } from '@/ui/utilities/recoil-scope/utils/getFamilyState';
|
||||
import { getState } from '@/ui/utilities/recoil-scope/utils/getState';
|
||||
import { extractComponentFamilyState } from '@/ui/utilities/state/component-state/utils/extractComponentFamilyState';
|
||||
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
||||
|
||||
type useSelectableListStatesProps = {
|
||||
selectableListScopeId?: string;
|
||||
@ -21,15 +21,21 @@ export const useSelectableListStates = ({
|
||||
|
||||
return {
|
||||
scopeId,
|
||||
isSelectedItemIdSelector: getFamilyState(
|
||||
isSelectedItemIdFamilySelectorScopeMap,
|
||||
isSelectedItemIdSelector: extractComponentFamilyState(
|
||||
isSelectedItemIdFamilySelector,
|
||||
scopeId,
|
||||
),
|
||||
selectableItemIdsState: getState(selectableItemIdsStateScopeMap, scopeId),
|
||||
selectableListOnEnterState: getState(
|
||||
selectableListOnEnterStateScopeMap,
|
||||
selectableItemIdsState: extractComponentState(
|
||||
selectableItemIdsComponentState,
|
||||
scopeId,
|
||||
),
|
||||
selectableListOnEnterState: extractComponentState(
|
||||
selectableListOnEnterComponentState,
|
||||
scopeId,
|
||||
),
|
||||
selectedItemIdState: extractComponentState(
|
||||
selectedItemIdComponentState,
|
||||
scopeId,
|
||||
),
|
||||
selectedItemIdState: getState(selectedItemIdStateScopeMap, scopeId),
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { StateScopeMapKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/StateScopeMapKey';
|
||||
import { createScopeInternalContext } from '@/ui/utilities/recoil-scope/scopes-internal/utils/createScopeInternalContext';
|
||||
import { ComponentStateKey } from '@/ui/utilities/state/component-state/types/ComponentStateKey';
|
||||
|
||||
type SelectableListScopeInternalContextProps = StateScopeMapKey;
|
||||
type SelectableListScopeInternalContextProps = ComponentStateKey;
|
||||
|
||||
export const SelectableListScopeInternalContext =
|
||||
createScopeInternalContext<SelectableListScopeInternalContextProps>();
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
import { createComponentFamilyState } from '@/ui/utilities/state/component-state/utils/createComponentFamilyState';
|
||||
|
||||
export const isSelectedItemIdComponentFamilyState = createComponentFamilyState<
|
||||
boolean,
|
||||
string
|
||||
>({
|
||||
key: 'isSelectedItemIdComponentFamilyState',
|
||||
defaultValue: false,
|
||||
});
|
||||
@ -1,9 +0,0 @@
|
||||
import { createFamilyStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createFamilyStateScopeMap';
|
||||
|
||||
export const isSelectedItemIdFamilyStateScopeMap = createFamilyStateScopeMap<
|
||||
boolean,
|
||||
string
|
||||
>({
|
||||
key: 'isSelectedItemIdMapScopedFamilyState',
|
||||
defaultValue: false,
|
||||
});
|
||||
@ -0,0 +1,8 @@
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
|
||||
export const selectableItemIdsComponentState = createComponentState<string[][]>(
|
||||
{
|
||||
key: 'selectableItemIdsComponentState',
|
||||
defaultValue: [[]],
|
||||
},
|
||||
);
|
||||
@ -1,6 +0,0 @@
|
||||
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
|
||||
|
||||
export const selectableItemIdsStateScopeMap = createStateScopeMap<string[][]>({
|
||||
key: 'selectableItemIdsScopedState',
|
||||
defaultValue: [[]],
|
||||
});
|
||||
@ -0,0 +1,8 @@
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
|
||||
export const selectableListOnEnterComponentState = createComponentState<
|
||||
((itemId: string) => void) | undefined
|
||||
>({
|
||||
key: 'selectableListOnEnterComponentState',
|
||||
defaultValue: undefined,
|
||||
});
|
||||
@ -1,8 +0,0 @@
|
||||
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
|
||||
|
||||
export const selectableListOnEnterStateScopeMap = createStateScopeMap<
|
||||
((itemId: string) => void) | undefined
|
||||
>({
|
||||
key: 'selectableListOnEnterScopedState',
|
||||
defaultValue: undefined,
|
||||
});
|
||||
@ -0,0 +1,8 @@
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
|
||||
export const selectedItemIdComponentState = createComponentState<string | null>(
|
||||
{
|
||||
key: 'selectedItemIdComponentState',
|
||||
defaultValue: null,
|
||||
},
|
||||
);
|
||||
@ -1,6 +0,0 @@
|
||||
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
|
||||
|
||||
export const selectedItemIdStateScopeMap = createStateScopeMap<string | null>({
|
||||
key: 'selectedItemIdScopedState',
|
||||
defaultValue: null,
|
||||
});
|
||||
@ -0,0 +1,28 @@
|
||||
import { isSelectedItemIdComponentFamilyState } from '@/ui/layout/selectable-list/states/isSelectedItemIdComponentFamilyState';
|
||||
import { createComponentFamilySelector } from '@/ui/utilities/state/component-state/utils/createComponentFamilySelector';
|
||||
|
||||
export const isSelectedItemIdFamilySelector = createComponentFamilySelector<
|
||||
boolean,
|
||||
string
|
||||
>({
|
||||
key: 'isSelectedItemIdFamilySelector',
|
||||
get:
|
||||
({ scopeId, familyKey }: { scopeId: string; familyKey: string }) =>
|
||||
({ get }) =>
|
||||
get(
|
||||
isSelectedItemIdComponentFamilyState({
|
||||
scopeId: scopeId,
|
||||
familyKey: familyKey,
|
||||
}),
|
||||
),
|
||||
set:
|
||||
({ scopeId, familyKey }: { scopeId: string; familyKey: string }) =>
|
||||
({ set }, newValue) =>
|
||||
set(
|
||||
isSelectedItemIdComponentFamilyState({
|
||||
scopeId: scopeId,
|
||||
familyKey: familyKey,
|
||||
}),
|
||||
newValue,
|
||||
),
|
||||
});
|
||||
@ -1,26 +0,0 @@
|
||||
import { isSelectedItemIdFamilyStateScopeMap } from '@/ui/layout/selectable-list/states/isSelectedItemIdFamilyStateScopeMap';
|
||||
import { createFamilySelectorScopeMap } from '@/ui/utilities/recoil-scope/utils/createFamilySelectorScopeMap';
|
||||
|
||||
export const isSelectedItemIdFamilySelectorScopeMap =
|
||||
createFamilySelectorScopeMap<boolean, string>({
|
||||
key: 'isSelectedItemIdScopedFamilySelector',
|
||||
get:
|
||||
({ scopeId, familyKey }: { scopeId: string; familyKey: string }) =>
|
||||
({ get }) =>
|
||||
get(
|
||||
isSelectedItemIdFamilyStateScopeMap({
|
||||
scopeId: scopeId,
|
||||
familyKey: familyKey,
|
||||
}),
|
||||
),
|
||||
set:
|
||||
({ scopeId, familyKey }: { scopeId: string; familyKey: string }) =>
|
||||
({ set }, newValue) =>
|
||||
set(
|
||||
isSelectedItemIdFamilyStateScopeMap({
|
||||
scopeId: scopeId,
|
||||
familyKey: familyKey,
|
||||
}),
|
||||
newValue,
|
||||
),
|
||||
});
|
||||
@ -26,7 +26,7 @@ export const ShowPageMoreButton = ({
|
||||
objectNameSingular: string;
|
||||
}) => {
|
||||
const { closeDropdown, toggleDropdown } = useDropdown('more-show-page');
|
||||
const navigationMemorizedUrl = useRecoilValue(navigationMemorizedUrlState);
|
||||
const navigationMemorizedUrl = useRecoilValue(navigationMemorizedUrlState());
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { deleteOneRecord } = useDeleteOneRecord({
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { TabListScopeInternalContext } from '@/ui/layout/tab/scopes/scope-internal-context/TabListScopeInternalContext';
|
||||
import { activeTabIdStateScopeMap } from '@/ui/layout/tab/states/activeTabIdStateScopeMap';
|
||||
import { activeTabIdComponentState } from '@/ui/layout/tab/states/activeTabIdComponentState';
|
||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||
import { getState } from '@/ui/utilities/recoil-scope/utils/getState';
|
||||
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
||||
|
||||
type useTabListStatesProps = {
|
||||
tabListScopeId?: string;
|
||||
@ -15,6 +15,9 @@ export const useTabListStates = ({ tabListScopeId }: useTabListStatesProps) => {
|
||||
|
||||
return {
|
||||
scopeId,
|
||||
getActiveTabIdState: getState(activeTabIdStateScopeMap, scopeId),
|
||||
getActiveTabIdState: extractComponentState(
|
||||
activeTabIdComponentState,
|
||||
scopeId,
|
||||
),
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { StateScopeMapKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/StateScopeMapKey';
|
||||
import { createScopeInternalContext } from '@/ui/utilities/recoil-scope/scopes-internal/utils/createScopeInternalContext';
|
||||
import { ComponentStateKey } from '@/ui/utilities/state/component-state/types/ComponentStateKey';
|
||||
|
||||
type TabListScopeInternalContextProps = StateScopeMapKey;
|
||||
type TabListScopeInternalContextProps = ComponentStateKey;
|
||||
|
||||
export const TabListScopeInternalContext =
|
||||
createScopeInternalContext<TabListScopeInternalContextProps>();
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
|
||||
export const activeTabIdComponentState = createComponentState<string | null>({
|
||||
key: 'activeTabIdComponentState',
|
||||
defaultValue: null,
|
||||
});
|
||||
@ -1,6 +0,0 @@
|
||||
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
|
||||
|
||||
export const activeTabIdStateScopeMap = createStateScopeMap<string | null>({
|
||||
key: 'activeTabIdStateScopeMap',
|
||||
defaultValue: null,
|
||||
});
|
||||
@ -28,8 +28,8 @@ const StyledContainerActionBar = styled.div`
|
||||
`;
|
||||
|
||||
export const ActionBar = () => {
|
||||
const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState);
|
||||
const actionBarEntries = useRecoilValue(actionBarEntriesState);
|
||||
const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState());
|
||||
const actionBarEntries = useRecoilValue(actionBarEntriesState());
|
||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
if (contextMenuIsOpen) {
|
||||
|
||||
@ -9,7 +9,7 @@ import { actionBarOpenState } from '../../states/actionBarIsOpenState';
|
||||
import { ActionBar } from '../ActionBar';
|
||||
|
||||
const FilledActionBar = () => {
|
||||
const setActionBarOpenState = useSetRecoilState(actionBarOpenState);
|
||||
const setActionBarOpenState = useSetRecoilState(actionBarOpenState());
|
||||
setActionBarOpenState(true);
|
||||
return <ActionBar />;
|
||||
};
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { atom } from 'recoil';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
|
||||
import { ActionBarEntry } from '../types/ActionBarEntry';
|
||||
|
||||
export const actionBarEntriesState = atom<ActionBarEntry[]>({
|
||||
export const actionBarEntriesState = createState<ActionBarEntry[]>({
|
||||
key: 'actionBarEntriesState',
|
||||
default: [],
|
||||
defaultValue: [],
|
||||
});
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { atom } from 'recoil';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
|
||||
export const actionBarOpenState = atom<boolean>({
|
||||
export const actionBarOpenState = createState<boolean>({
|
||||
key: 'actionBarOpenState',
|
||||
default: false,
|
||||
defaultValue: false,
|
||||
});
|
||||
|
||||
@ -37,10 +37,10 @@ const StyledContainerContextMenu = styled.div<StyledContainerProps>`
|
||||
`;
|
||||
|
||||
export const ContextMenu = () => {
|
||||
const contextMenuPosition = useRecoilValue(contextMenuPositionState);
|
||||
const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState);
|
||||
const contextMenuEntries = useRecoilValue(contextMenuEntriesState);
|
||||
const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState);
|
||||
const contextMenuPosition = useRecoilValue(contextMenuPositionState());
|
||||
const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState());
|
||||
const contextMenuEntries = useRecoilValue(contextMenuEntriesState());
|
||||
const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState());
|
||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useListenClickOutside({
|
||||
|
||||
@ -10,12 +10,12 @@ import { contextMenuPositionState } from '../../states/contextMenuPositionState'
|
||||
import { ContextMenu } from '../ContextMenu';
|
||||
|
||||
const FilledContextMenu = () => {
|
||||
const setContextMenuPosition = useSetRecoilState(contextMenuPositionState);
|
||||
const setContextMenuPosition = useSetRecoilState(contextMenuPositionState());
|
||||
setContextMenuPosition({
|
||||
x: 100,
|
||||
y: 10,
|
||||
});
|
||||
const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState);
|
||||
const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState());
|
||||
setContextMenuOpenState(true);
|
||||
return <ContextMenu />;
|
||||
};
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { atom } from 'recoil';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
|
||||
import { ContextMenuEntry } from '../types/ContextMenuEntry';
|
||||
|
||||
export const contextMenuEntriesState = atom<ContextMenuEntry[]>({
|
||||
export const contextMenuEntriesState = createState<ContextMenuEntry[]>({
|
||||
key: 'contextMenuEntriesState',
|
||||
default: [],
|
||||
defaultValue: [],
|
||||
});
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { atom } from 'recoil';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
|
||||
export const contextMenuIsOpenState = atom<boolean>({
|
||||
export const contextMenuIsOpenState = createState<boolean>({
|
||||
key: 'contextMenuIsOpenState',
|
||||
default: false,
|
||||
defaultValue: false,
|
||||
});
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
import { atom } from 'recoil';
|
||||
|
||||
import { PositionType } from '@/ui/navigation/context-menu/types/PositionType';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
|
||||
export const contextMenuPositionState = atom<PositionType>({
|
||||
export const contextMenuPositionState = createState<PositionType>({
|
||||
key: 'contextMenuPositionState',
|
||||
default: {
|
||||
defaultValue: {
|
||||
x: null,
|
||||
y: null,
|
||||
},
|
||||
|
||||
@ -37,7 +37,7 @@ export const NavigationDrawerBackButton = ({
|
||||
}: NavigationDrawerBackButtonProps) => {
|
||||
const theme = useTheme();
|
||||
const navigate = useNavigate();
|
||||
const navigationMemorizedUrl = useRecoilValue(navigationMemorizedUrlState);
|
||||
const navigationMemorizedUrl = useRecoilValue(navigationMemorizedUrlState());
|
||||
|
||||
return (
|
||||
<StyledContainer>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { atom } from 'recoil';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
|
||||
export const navigationMemorizedUrlState = atom<string>({
|
||||
export const navigationMemorizedUrlState = createState<string>({
|
||||
key: 'navigationMemorizedUrlState',
|
||||
default: '/',
|
||||
defaultValue: '/',
|
||||
});
|
||||
|
||||
@ -11,7 +11,7 @@ const renderHooks = (initialStep: number) => {
|
||||
const { nextStep, prevStep, reset, setStep } = useStepBar({
|
||||
initialStep,
|
||||
});
|
||||
const stepBarInternal = useRecoilValue(stepBarInternalState);
|
||||
const stepBarInternal = useRecoilValue(stepBarInternalState());
|
||||
|
||||
return {
|
||||
nextStep,
|
||||
|
||||
@ -8,8 +8,9 @@ export type StepsOptions = {
|
||||
};
|
||||
|
||||
export const useStepBar = ({ initialStep }: StepsOptions) => {
|
||||
const [stepBarInternal, setStepBarInternal] =
|
||||
useRecoilState(stepBarInternalState);
|
||||
const [stepBarInternal, setStepBarInternal] = useRecoilState(
|
||||
stepBarInternalState(),
|
||||
);
|
||||
|
||||
const nextStep = () => {
|
||||
setStepBarInternal((prevState) => ({
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
import { atom } from 'recoil';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
|
||||
export type StepsState = {
|
||||
activeStep: number;
|
||||
};
|
||||
|
||||
export const stepBarInternalState = atom<StepsState>({
|
||||
export const stepBarInternalState = createState<StepsState>({
|
||||
key: 'step-bar/internal-state',
|
||||
default: {
|
||||
defaultValue: {
|
||||
activeStep: -1,
|
||||
},
|
||||
});
|
||||
|
||||
@ -32,7 +32,7 @@ describe('useColorScheme', () => {
|
||||
const colorScheme = useColorScheme();
|
||||
|
||||
const setCurrentWorkspaceMember = useSetRecoilState(
|
||||
currentWorkspaceMemberState,
|
||||
currentWorkspaceMemberState(),
|
||||
);
|
||||
|
||||
setCurrentWorkspaceMember(workspaceMember);
|
||||
|
||||
@ -8,7 +8,7 @@ import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
|
||||
|
||||
export const useColorScheme = () => {
|
||||
const [currentWorkspaceMember, setCurrentWorkspaceMember] = useRecoilState(
|
||||
currentWorkspaceMemberState,
|
||||
currentWorkspaceMemberState(),
|
||||
);
|
||||
|
||||
const { updateOneRecord: updateOneWorkspaceMember } = useUpdateOneRecord({
|
||||
|
||||
@ -13,7 +13,7 @@ export const usePreviousHotkeyScope = () => {
|
||||
({ snapshot, set }) =>
|
||||
() => {
|
||||
const previousHotkeyScope = snapshot
|
||||
.getLoadable(previousHotkeyScopeState)
|
||||
.getLoadable(previousHotkeyScopeState())
|
||||
.getValue();
|
||||
|
||||
if (!previousHotkeyScope) {
|
||||
@ -25,7 +25,7 @@ export const usePreviousHotkeyScope = () => {
|
||||
previousHotkeyScope.customScopes,
|
||||
);
|
||||
|
||||
set(previousHotkeyScopeState, null);
|
||||
set(previousHotkeyScopeState(), null);
|
||||
},
|
||||
[setHotkeyScope],
|
||||
);
|
||||
@ -34,11 +34,11 @@ export const usePreviousHotkeyScope = () => {
|
||||
({ snapshot, set }) =>
|
||||
(scope: string, customScopes?: CustomHotkeyScopes) => {
|
||||
const currentHotkeyScope = snapshot
|
||||
.getLoadable(currentHotkeyScopeState)
|
||||
.getLoadable(currentHotkeyScopeState())
|
||||
.getValue();
|
||||
|
||||
setHotkeyScope(scope, customScopes);
|
||||
set(previousHotkeyScopeState, currentHotkeyScope);
|
||||
set(previousHotkeyScopeState(), currentHotkeyScope);
|
||||
},
|
||||
[setHotkeyScope],
|
||||
);
|
||||
|
||||
@ -24,7 +24,7 @@ export const useScopedHotkeyCallback = () =>
|
||||
preventDefault?: boolean;
|
||||
}) => {
|
||||
const currentHotkeyScopes = snapshot
|
||||
.getLoadable(internalHotkeysEnabledScopesState)
|
||||
.getLoadable(internalHotkeysEnabledScopesState())
|
||||
.getValue();
|
||||
|
||||
if (!currentHotkeyScopes.includes(scope)) {
|
||||
|
||||
@ -22,7 +22,8 @@ export const useScopedHotkeys = (
|
||||
preventDefault: true,
|
||||
},
|
||||
) => {
|
||||
const [pendingHotkey, setPendingHotkey] = useRecoilState(pendingHotkeyState);
|
||||
const [pendingHotkey, setPendingHotkey] =
|
||||
useRecoilState(pendingHotkeyState());
|
||||
|
||||
const callScopedHotkeyCallback = useScopedHotkeyCallback();
|
||||
|
||||
|
||||
@ -20,7 +20,8 @@ export const useSequenceHotkeys = (
|
||||
},
|
||||
deps: any[] = [],
|
||||
) => {
|
||||
const [pendingHotkey, setPendingHotkey] = useRecoilState(pendingHotkeyState);
|
||||
const [pendingHotkey, setPendingHotkey] =
|
||||
useRecoilState(pendingHotkeyState());
|
||||
|
||||
const callScopedHotkeyCallback = useScopedHotkeyCallback();
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ export const useSetHotkeyScope = () =>
|
||||
({ snapshot, set }) =>
|
||||
async (hotkeyScopeToSet: string, customScopes?: CustomHotkeyScopes) => {
|
||||
const currentHotkeyScope = snapshot
|
||||
.getLoadable(currentHotkeyScopeState)
|
||||
.getLoadable(currentHotkeyScopeState())
|
||||
.getValue();
|
||||
|
||||
if (currentHotkeyScope.scope === hotkeyScopeToSet) {
|
||||
@ -76,8 +76,8 @@ export const useSetHotkeyScope = () =>
|
||||
}
|
||||
|
||||
scopesToSet.push(newHotkeyScope.scope);
|
||||
set(internalHotkeysEnabledScopesState, scopesToSet);
|
||||
set(currentHotkeyScopeState, newHotkeyScope);
|
||||
set(internalHotkeysEnabledScopesState(), scopesToSet);
|
||||
set(currentHotkeyScopeState(), newHotkeyScope);
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { atom } from 'recoil';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
|
||||
import { INITIAL_HOTKEYS_SCOPE } from '../../constants/InitialHotkeysScope';
|
||||
import { HotkeyScope } from '../../types/HotkeyScope';
|
||||
|
||||
export const currentHotkeyScopeState = atom<HotkeyScope>({
|
||||
export const currentHotkeyScopeState = createState<HotkeyScope>({
|
||||
key: 'currentHotkeyScopeState',
|
||||
default: INITIAL_HOTKEYS_SCOPE,
|
||||
defaultValue: INITIAL_HOTKEYS_SCOPE,
|
||||
});
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { atom } from 'recoil';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
|
||||
export const internalHotkeysEnabledScopesState = atom<string[]>({
|
||||
export const internalHotkeysEnabledScopesState = createState<string[]>({
|
||||
key: 'internalHotkeysEnabledScopesState',
|
||||
default: [],
|
||||
defaultValue: [],
|
||||
});
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { Keys } from 'react-hotkeys-hook/dist/types';
|
||||
import { atom } from 'recoil';
|
||||
|
||||
export const pendingHotkeyState = atom<Keys | null>({
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
|
||||
export const pendingHotkeyState = createState<Keys | null>({
|
||||
key: 'pendingHotkeyState',
|
||||
default: null,
|
||||
defaultValue: null,
|
||||
});
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { atom } from 'recoil';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
|
||||
import { HotkeyScope } from '../../types/HotkeyScope';
|
||||
|
||||
export const previousHotkeyScopeState = atom<HotkeyScope | null>({
|
||||
export const previousHotkeyScopeState = createState<HotkeyScope | null>({
|
||||
key: 'previousHotkeyScopeState',
|
||||
default: null,
|
||||
defaultValue: null,
|
||||
});
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { atom } from 'recoil';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
|
||||
export const currentPageLocationState = atom<string>({
|
||||
export const currentPageLocationState = createState<string>({
|
||||
key: 'currentPageLocationState',
|
||||
default: '',
|
||||
defaultValue: '',
|
||||
});
|
||||
|
||||
@ -1,25 +1,25 @@
|
||||
import { clickOutsideListenerCallbacksStateScopeMap } from '@/ui/utilities/pointer-event/states/clickOutsideListenerCallbacksStateScopeMap';
|
||||
import { clickOutsideListenerIsActivatedStateScopeMap } from '@/ui/utilities/pointer-event/states/clickOutsideListenerIsActivatedStateScopeMap';
|
||||
import { clickOutsideListenerIsMouseDownInsideStateScopeMap } from '@/ui/utilities/pointer-event/states/clickOutsideListenerIsMouseDownInsideStateScopeMap';
|
||||
import { clickOutsideListenerCallbacksComponentState } from '@/ui/utilities/pointer-event/states/clickOutsideListenerCallbacksComponentState';
|
||||
import { clickOutsideListenerIsActivatedComponentState } from '@/ui/utilities/pointer-event/states/clickOutsideListenerIsActivatedComponentState';
|
||||
import { clickOutsideListenerIsMouseDownInsideComponentState } from '@/ui/utilities/pointer-event/states/clickOutsideListenerIsMouseDownInsideComponentState';
|
||||
import { lockedListenerIdState } from '@/ui/utilities/pointer-event/states/lockedListenerIdState';
|
||||
import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId';
|
||||
import { getState } from '@/ui/utilities/recoil-scope/utils/getState';
|
||||
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
||||
|
||||
export const useClickOustideListenerStates = (componentId: string) => {
|
||||
const scopeId = getScopeIdFromComponentId(componentId);
|
||||
|
||||
return {
|
||||
scopeId,
|
||||
getClickOutsideListenerCallbacksState: getState(
|
||||
clickOutsideListenerCallbacksStateScopeMap,
|
||||
getClickOutsideListenerCallbacksState: extractComponentState(
|
||||
clickOutsideListenerCallbacksComponentState,
|
||||
scopeId,
|
||||
),
|
||||
getClickOutsideListenerIsMouseDownInsideState: getState(
|
||||
clickOutsideListenerIsMouseDownInsideStateScopeMap,
|
||||
getClickOutsideListenerIsMouseDownInsideState: extractComponentState(
|
||||
clickOutsideListenerIsMouseDownInsideComponentState,
|
||||
scopeId,
|
||||
),
|
||||
getClickOutsideListenerIsActivatedState: getState(
|
||||
clickOutsideListenerIsActivatedStateScopeMap,
|
||||
getClickOutsideListenerIsActivatedState: extractComponentState(
|
||||
clickOutsideListenerIsActivatedComponentState,
|
||||
scopeId,
|
||||
),
|
||||
lockedListenerIdState,
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
import { ClickOutsideListenerCallback } from '@/ui/utilities/pointer-event/types/ClickOutsideListenerCallback';
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
|
||||
export const clickOutsideListenerCallbacksComponentState = createComponentState<
|
||||
ClickOutsideListenerCallback[]
|
||||
>({
|
||||
key: 'clickOutsideListenerCallbacksComponentState',
|
||||
defaultValue: [],
|
||||
});
|
||||
@ -1,9 +0,0 @@
|
||||
import { ClickOutsideListenerCallback } from '@/ui/utilities/pointer-event/types/ClickOutsideListenerCallback';
|
||||
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
|
||||
|
||||
export const clickOutsideListenerCallbacksStateScopeMap = createStateScopeMap<
|
||||
ClickOutsideListenerCallback[]
|
||||
>({
|
||||
key: 'clickOutsideListenerCallbacksStateScopeMap',
|
||||
defaultValue: [],
|
||||
});
|
||||
@ -0,0 +1,7 @@
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
|
||||
export const clickOutsideListenerIsActivatedComponentState =
|
||||
createComponentState<boolean>({
|
||||
key: 'clickOutsideListenerIsActivatedComponentState',
|
||||
defaultValue: true,
|
||||
});
|
||||
@ -1,7 +0,0 @@
|
||||
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
|
||||
|
||||
export const clickOutsideListenerIsActivatedStateScopeMap =
|
||||
createStateScopeMap<boolean>({
|
||||
key: 'clickOutsideListenerIsActivatedStateScopeMap',
|
||||
defaultValue: true,
|
||||
});
|
||||
@ -0,0 +1,7 @@
|
||||
import { createComponentState } from '@/ui/utilities/state/component-state/utils/createComponentState';
|
||||
|
||||
export const clickOutsideListenerIsMouseDownInsideComponentState =
|
||||
createComponentState<boolean>({
|
||||
key: 'clickOutsideListenerIsMouseDownInsideComponentState',
|
||||
defaultValue: false,
|
||||
});
|
||||
@ -1,7 +0,0 @@
|
||||
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
|
||||
|
||||
export const clickOutsideListenerIsMouseDownInsideStateScopeMap =
|
||||
createStateScopeMap<boolean>({
|
||||
key: 'clickOutsideListenerIsMouseDownInsideStateScopeMap',
|
||||
defaultValue: false,
|
||||
});
|
||||
@ -1,6 +1,6 @@
|
||||
import { atom } from 'recoil';
|
||||
import { createState } from '@/ui/utilities/state/utils/createState';
|
||||
|
||||
export const lockedListenerIdState = atom<string | null>({
|
||||
export const lockedListenerIdState = createState<string | null>({
|
||||
key: 'lockedListenerIdState',
|
||||
default: null,
|
||||
defaultValue: null,
|
||||
});
|
||||
|
||||
@ -1,64 +0,0 @@
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
import { RecoilRoot, RecoilState } from 'recoil';
|
||||
import { undefined } from 'zod';
|
||||
|
||||
import { useRecoilScopedFamilyState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedFamilyState';
|
||||
import { FamilyStateScopeMapKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/FamilyStateScopeMapKey';
|
||||
import { createFamilyStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createFamilyStateScopeMap';
|
||||
|
||||
const testState = createFamilyStateScopeMap({
|
||||
key: 'sampleKey',
|
||||
defaultValue: 'defaultValue',
|
||||
});
|
||||
|
||||
describe('useRecoilScopedFamilyState', () => {
|
||||
it('Should work as expected', async () => {
|
||||
const { result, rerender } = renderHook(
|
||||
({
|
||||
recoilState,
|
||||
scopeId,
|
||||
familyKey,
|
||||
}: {
|
||||
recoilState: (
|
||||
scopedFamilyKey: FamilyStateScopeMapKey<string>,
|
||||
) => RecoilState<string>;
|
||||
scopeId: string;
|
||||
familyKey?: string;
|
||||
}) => useRecoilScopedFamilyState(recoilState, scopeId, familyKey),
|
||||
{
|
||||
wrapper: RecoilRoot,
|
||||
initialProps: {
|
||||
recoilState: testState,
|
||||
scopeId: 'scopeId',
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current).toEqual([undefined, undefined]);
|
||||
|
||||
rerender({
|
||||
recoilState: testState,
|
||||
scopeId: 'scopeId',
|
||||
familyKey: 'familyKey',
|
||||
});
|
||||
|
||||
const [value, setValue] = result.current;
|
||||
|
||||
expect(value).toBe('defaultValue');
|
||||
expect(setValue).toBeInstanceOf(Function);
|
||||
|
||||
act(() => {
|
||||
setValue?.('newValue');
|
||||
});
|
||||
|
||||
expect(result.current[0]).toBe('newValue');
|
||||
|
||||
rerender({
|
||||
recoilState: testState,
|
||||
scopeId: 'scopeId1',
|
||||
familyKey: 'familyKey',
|
||||
});
|
||||
|
||||
expect(result.current[0]).toBe('defaultValue');
|
||||
});
|
||||
});
|
||||
@ -1,50 +0,0 @@
|
||||
import { createContext } from 'react';
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
import { atomFamily, RecoilRoot } from 'recoil';
|
||||
|
||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||
|
||||
const testScopedState = atomFamily<string | null, string>({
|
||||
key: 'testKey',
|
||||
default: null,
|
||||
});
|
||||
|
||||
const mockedContextValue = 'mocked-scope-id';
|
||||
const MockedContext = createContext<string | null>(mockedContextValue);
|
||||
const nullContext = createContext<string | null>(null);
|
||||
|
||||
const ERROR_MESSAGE =
|
||||
'Using a scoped atom without a RecoilScope : testKey__"", verify that you are using a RecoilScope with a specific context if you intended to do so.';
|
||||
|
||||
describe('useRecoilScopedState', () => {
|
||||
it('Should return the getter and setter for the state and context passed and work properly', async () => {
|
||||
const { result } = renderHook(
|
||||
() => useRecoilScopedState(testScopedState, MockedContext),
|
||||
{
|
||||
wrapper: ({ children }) => (
|
||||
<MockedContext.Provider value={mockedContextValue}>
|
||||
<RecoilRoot>{children}</RecoilRoot>
|
||||
</MockedContext.Provider>
|
||||
),
|
||||
},
|
||||
);
|
||||
|
||||
const [scopedState, setScopedState] = result.current;
|
||||
|
||||
expect(scopedState).toBeNull();
|
||||
|
||||
await act(async () => {
|
||||
setScopedState('testValue');
|
||||
});
|
||||
|
||||
const [scopedStateAfterSetter] = result.current;
|
||||
|
||||
expect(scopedStateAfterSetter).toEqual('testValue');
|
||||
});
|
||||
|
||||
it('Should throw an error when the recoilScopeId is not found by the context', () => {
|
||||
expect(() => {
|
||||
renderHook(() => useRecoilScopedState(testScopedState, nullContext));
|
||||
}).toThrow(ERROR_MESSAGE);
|
||||
});
|
||||
});
|
||||
@ -1,42 +0,0 @@
|
||||
import { createContext } from 'react';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { atomFamily, RecoilRoot } from 'recoil';
|
||||
|
||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||
|
||||
const testScopedState = atomFamily<string | null, string>({
|
||||
key: 'testKey',
|
||||
default: null,
|
||||
});
|
||||
|
||||
const mockedContextValue = 'mocked-scope-id';
|
||||
const MockedContext = createContext<string | null>(mockedContextValue);
|
||||
const nullContext = createContext<string | null>(null);
|
||||
|
||||
const ERROR_MESSAGE =
|
||||
'Using a scoped atom without a RecoilScope : testKey__"", verify that you are using a RecoilScope with a specific context if you intended to do so.';
|
||||
|
||||
describe('useRecoilScopedValue', () => {
|
||||
it('Should return the getter and setter for the state and context passed and work properly', async () => {
|
||||
const { result } = renderHook(
|
||||
() => useRecoilScopedValue(testScopedState, MockedContext),
|
||||
{
|
||||
wrapper: ({ children }) => (
|
||||
<MockedContext.Provider value={mockedContextValue}>
|
||||
<RecoilRoot>{children}</RecoilRoot>
|
||||
</MockedContext.Provider>
|
||||
),
|
||||
},
|
||||
);
|
||||
|
||||
const scopedState = result.current;
|
||||
|
||||
expect(scopedState).toBeNull();
|
||||
});
|
||||
|
||||
it('Should throw an error when the recoilScopeId is not found by the context', () => {
|
||||
expect(() => {
|
||||
renderHook(() => useRecoilScopedValue(testScopedState, nullContext));
|
||||
}).toThrow(ERROR_MESSAGE);
|
||||
});
|
||||
});
|
||||
@ -1,27 +0,0 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { atomFamily, RecoilRoot } from 'recoil';
|
||||
|
||||
import { useRecoilScopedValueV2 } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValueV2';
|
||||
import { StateScopeMapKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/StateScopeMapKey';
|
||||
|
||||
const scopedAtom = atomFamily<string, StateScopeMapKey>({
|
||||
key: 'scopedAtomKey',
|
||||
default: 'initialValue',
|
||||
});
|
||||
|
||||
describe('useRecoilScopedValueV2', () => {
|
||||
const mockedScopeId = 'mocked-scope-id';
|
||||
|
||||
it('Should return the scoped value using useRecoilScopedValueV2', () => {
|
||||
const { result } = renderHook(
|
||||
() => useRecoilScopedValueV2(scopedAtom, mockedScopeId),
|
||||
{
|
||||
wrapper: RecoilRoot,
|
||||
},
|
||||
);
|
||||
|
||||
const scopedValue = result.current;
|
||||
|
||||
expect(scopedValue).toBe('initialValue');
|
||||
});
|
||||
});
|
||||
@ -1,79 +0,0 @@
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
import { atomFamily, RecoilRoot } from 'recoil';
|
||||
|
||||
import { useRecoilScopedFamilyState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedFamilyState';
|
||||
import { useSetRecoilScopedFamilyState } from '@/ui/utilities/recoil-scope/hooks/useSetRecoilScopedFamilyState';
|
||||
import { FamilyStateScopeMapKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/FamilyStateScopeMapKey';
|
||||
|
||||
const mockedScopedFamilyState = atomFamily<
|
||||
string,
|
||||
FamilyStateScopeMapKey<string>
|
||||
>({
|
||||
key: 'scopedAtomKey',
|
||||
default: 'initialValue',
|
||||
});
|
||||
|
||||
describe('useSetRecoilScopedFamilyState', () => {
|
||||
const mockedScopeId = 'mocked-scope-id';
|
||||
const mockedFamilyKey = 'test-key-value';
|
||||
|
||||
it('Should return a setter that updates the state value and work properly', async () => {
|
||||
const useCombinedHooks = () => {
|
||||
const setRecoilScopedFamilyState = useSetRecoilScopedFamilyState(
|
||||
mockedScopedFamilyState,
|
||||
mockedScopeId,
|
||||
mockedFamilyKey,
|
||||
);
|
||||
|
||||
const [mocked] = useRecoilScopedFamilyState(
|
||||
mockedScopedFamilyState,
|
||||
mockedScopeId,
|
||||
mockedFamilyKey,
|
||||
);
|
||||
|
||||
return {
|
||||
setRecoilScopedFamilyState,
|
||||
scopedFamilyState: mocked,
|
||||
};
|
||||
};
|
||||
|
||||
const { result } = renderHook(() => useCombinedHooks(), {
|
||||
wrapper: RecoilRoot,
|
||||
});
|
||||
|
||||
expect(result.current.scopedFamilyState).toBe('initialValue');
|
||||
expect(result.current.setRecoilScopedFamilyState).toBeInstanceOf(Function);
|
||||
|
||||
await act(async () => {
|
||||
result.current.setRecoilScopedFamilyState?.('testValue');
|
||||
});
|
||||
|
||||
expect(result.current.scopedFamilyState).toBe('testValue');
|
||||
});
|
||||
|
||||
it('Should return undefined when familyKey is missing', async () => {
|
||||
const useCombinedHooks = () => {
|
||||
const setRecoilScopedFamilyState = useSetRecoilScopedFamilyState(
|
||||
mockedScopedFamilyState,
|
||||
mockedScopeId,
|
||||
);
|
||||
|
||||
const [mocked] = useRecoilScopedFamilyState(
|
||||
mockedScopedFamilyState,
|
||||
mockedScopeId,
|
||||
);
|
||||
|
||||
return {
|
||||
setRecoilScopedFamilyState,
|
||||
scopedFamilyState: mocked,
|
||||
};
|
||||
};
|
||||
|
||||
const { result } = renderHook(() => useCombinedHooks(), {
|
||||
wrapper: RecoilRoot,
|
||||
});
|
||||
|
||||
expect(result.current.scopedFamilyState).toBeUndefined();
|
||||
expect(result.current.setRecoilScopedFamilyState).toBeUndefined();
|
||||
});
|
||||
});
|
||||
@ -1,47 +0,0 @@
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
import { atomFamily, RecoilRoot } from 'recoil';
|
||||
|
||||
import { useRecoilScopedValueV2 } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValueV2';
|
||||
import { useSetRecoilScopedStateV2 } from '@/ui/utilities/recoil-scope/hooks/useSetRecoilScopedStateV2';
|
||||
import { StateScopeMapKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/StateScopeMapKey';
|
||||
|
||||
const scopedAtom = atomFamily<string, StateScopeMapKey>({
|
||||
key: 'scopedAtomKey',
|
||||
default: 'initialValue',
|
||||
});
|
||||
|
||||
describe('useSetRecoilScopedStateV2', () => {
|
||||
const mockedScopeId = 'mocked-scope-id';
|
||||
|
||||
it('Should return a setter that updates the state value', async () => {
|
||||
const useCombinedHooks = () => {
|
||||
const setRecoilScopedStateV2 = useSetRecoilScopedStateV2(
|
||||
scopedAtom,
|
||||
mockedScopeId,
|
||||
);
|
||||
|
||||
const recoilScopedStateValue = useRecoilScopedValueV2(
|
||||
scopedAtom,
|
||||
mockedScopeId,
|
||||
);
|
||||
|
||||
return {
|
||||
setRecoilScopedStateV2,
|
||||
recoilScopedStateValue,
|
||||
};
|
||||
};
|
||||
|
||||
const { result } = renderHook(() => useCombinedHooks(), {
|
||||
wrapper: RecoilRoot,
|
||||
});
|
||||
|
||||
expect(result.current.recoilScopedStateValue).toBe('initialValue');
|
||||
expect(result.current.setRecoilScopedStateV2).toBeInstanceOf(Function);
|
||||
|
||||
await act(async () => {
|
||||
result.current.setRecoilScopedStateV2('testValue');
|
||||
});
|
||||
|
||||
expect(result.current.recoilScopedStateValue).toBe('testValue');
|
||||
});
|
||||
});
|
||||
@ -1,27 +0,0 @@
|
||||
import { RecoilState, SerializableParam, useRecoilState } from 'recoil';
|
||||
|
||||
import { FamilyStateScopeMapKey } from '../scopes-internal/types/FamilyStateScopeMapKey';
|
||||
|
||||
export const useRecoilScopedFamilyState = <
|
||||
StateType,
|
||||
FamilyKey extends SerializableParam,
|
||||
>(
|
||||
recoilState: (
|
||||
scopedFamilyKey: FamilyStateScopeMapKey<FamilyKey>,
|
||||
) => RecoilState<StateType>,
|
||||
scopeId: string,
|
||||
familyKey?: FamilyKey,
|
||||
) => {
|
||||
const familyState = useRecoilState<StateType>(
|
||||
recoilState({
|
||||
scopeId,
|
||||
familyKey: familyKey || ('' as FamilyKey),
|
||||
}),
|
||||
);
|
||||
|
||||
if (!familyKey) {
|
||||
return [undefined, undefined];
|
||||
}
|
||||
|
||||
return familyState;
|
||||
};
|
||||
@ -1,22 +0,0 @@
|
||||
import { Context, useContext } from 'react';
|
||||
import { RecoilState, useRecoilState } from 'recoil';
|
||||
|
||||
import { RecoilScopeContext } from '../states/RecoilScopeContext';
|
||||
|
||||
export const useRecoilScopedState = <StateType>(
|
||||
recoilState: (param: string) => RecoilState<StateType>,
|
||||
CustomRecoilScopeContext?: Context<string | null>,
|
||||
) => {
|
||||
const recoilScopeId = useContext(
|
||||
CustomRecoilScopeContext ?? RecoilScopeContext,
|
||||
);
|
||||
|
||||
if (!recoilScopeId)
|
||||
throw new Error(
|
||||
`Using a scoped atom without a RecoilScope : ${
|
||||
recoilState('').key
|
||||
}, verify that you are using a RecoilScope with a specific context if you intended to do so.`,
|
||||
);
|
||||
|
||||
return useRecoilState<StateType>(recoilState(recoilScopeId));
|
||||
};
|
||||
@ -1,9 +1,9 @@
|
||||
import { RecoilState, useRecoilState } from 'recoil';
|
||||
|
||||
import { StateScopeMapKey } from '../scopes-internal/types/StateScopeMapKey';
|
||||
import { ComponentStateKey } from '@/ui/utilities/state/component-state/types/ComponentStateKey';
|
||||
|
||||
export const useRecoilScopedStateV2 = <StateType>(
|
||||
recoilState: (scopedKey: StateScopeMapKey) => RecoilState<StateType>,
|
||||
recoilState: (scopedKey: ComponentStateKey) => RecoilState<StateType>,
|
||||
scopeId: string,
|
||||
) => {
|
||||
return useRecoilState<StateType>(
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
import { Context, useContext } from 'react';
|
||||
import { RecoilState, RecoilValueReadOnly, useRecoilValue } from 'recoil';
|
||||
|
||||
import { RecoilScopeContext } from '../states/RecoilScopeContext';
|
||||
|
||||
/**
|
||||
* @deprecated use useRecoilScopedStateV2 instead
|
||||
*/
|
||||
export const useRecoilScopedValue = <T>(
|
||||
recoilState: (param: string) => RecoilState<T> | RecoilValueReadOnly<T>,
|
||||
CustomRecoilScopeContext?: Context<string | null>,
|
||||
) => {
|
||||
const recoilScopeId = useContext(
|
||||
CustomRecoilScopeContext ?? RecoilScopeContext,
|
||||
);
|
||||
|
||||
if (!recoilScopeId)
|
||||
throw new Error(
|
||||
`Using a scoped atom without a RecoilScope : ${
|
||||
recoilState('').key
|
||||
}, verify that you are using a RecoilScope with a specific context if you intended to do so.`,
|
||||
);
|
||||
|
||||
return useRecoilValue<T>(recoilState(recoilScopeId));
|
||||
};
|
||||
@ -1,14 +0,0 @@
|
||||
import { RecoilState, useRecoilValue } from 'recoil';
|
||||
|
||||
import { StateScopeMapKey } from '../scopes-internal/types/StateScopeMapKey';
|
||||
|
||||
export const useRecoilScopedValueV2 = <StateType>(
|
||||
recoilState: (scopedKey: StateScopeMapKey) => RecoilState<StateType>,
|
||||
scopeId: string,
|
||||
) => {
|
||||
return useRecoilValue<StateType>(
|
||||
recoilState({
|
||||
scopeId,
|
||||
}),
|
||||
);
|
||||
};
|
||||
@ -1,27 +0,0 @@
|
||||
import { RecoilState, SerializableParam, useSetRecoilState } from 'recoil';
|
||||
|
||||
import { FamilyStateScopeMapKey } from '../scopes-internal/types/FamilyStateScopeMapKey';
|
||||
|
||||
export const useSetRecoilScopedFamilyState = <
|
||||
StateType,
|
||||
FamilyKey extends SerializableParam,
|
||||
>(
|
||||
recoilState: (
|
||||
scopedFamilyKey: FamilyStateScopeMapKey<FamilyKey>,
|
||||
) => RecoilState<StateType>,
|
||||
scopeId: string,
|
||||
familyKey?: FamilyKey,
|
||||
) => {
|
||||
const familyState = useSetRecoilState<StateType>(
|
||||
recoilState({
|
||||
scopeId,
|
||||
familyKey: familyKey || ('' as FamilyKey),
|
||||
}),
|
||||
);
|
||||
|
||||
if (!familyKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
return familyState;
|
||||
};
|
||||
@ -1,14 +0,0 @@
|
||||
import { RecoilState, useSetRecoilState } from 'recoil';
|
||||
|
||||
import { StateScopeMapKey } from '../scopes-internal/types/StateScopeMapKey';
|
||||
|
||||
export const useSetRecoilScopedStateV2 = <StateType>(
|
||||
recoilState: (scopedKey: StateScopeMapKey) => RecoilState<StateType>,
|
||||
scopeId: string,
|
||||
) => {
|
||||
return useSetRecoilState<StateType>(
|
||||
recoilState({
|
||||
scopeId,
|
||||
}),
|
||||
);
|
||||
};
|
||||
@ -1,44 +0,0 @@
|
||||
import { createContext } from 'react';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
|
||||
import { useScopeInternalContextOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useScopeInternalContextOrThrow';
|
||||
import { ScopeInternalContext } from '@/ui/utilities/recoil-scope/scopes-internal/types/ScopeInternalContext';
|
||||
|
||||
const mockedContextValue = 'mocked-scope-id';
|
||||
const MockedContext = createContext<string | null>(mockedContextValue);
|
||||
const nullContext = createContext<string | null>(null);
|
||||
|
||||
const ERROR_MESSAGE =
|
||||
'Using a scope context without a ScopeInternalContext.Provider wrapper for context';
|
||||
|
||||
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
<MockedContext.Provider value={mockedContextValue}>
|
||||
{children}
|
||||
</MockedContext.Provider>
|
||||
);
|
||||
|
||||
describe('useScopeInternalContextOrThrow', () => {
|
||||
it('should work as expected', () => {
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useScopeInternalContextOrThrow(
|
||||
MockedContext as ScopeInternalContext<{ scopeId: string }>,
|
||||
),
|
||||
{
|
||||
wrapper: Wrapper,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current).toBe(mockedContextValue);
|
||||
});
|
||||
|
||||
it('should throw an error when used outside of the specified context', () => {
|
||||
expect(() => {
|
||||
renderHook(() =>
|
||||
useScopeInternalContextOrThrow(
|
||||
nullContext as ScopeInternalContext<{ scopeId: string }>,
|
||||
),
|
||||
);
|
||||
}).toThrow(ERROR_MESSAGE);
|
||||
});
|
||||
});
|
||||
@ -1,192 +0,0 @@
|
||||
import { expect } from '@storybook/test';
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
import {
|
||||
atomFamily,
|
||||
RecoilRoot,
|
||||
selector,
|
||||
useRecoilCallback,
|
||||
useRecoilState,
|
||||
useRecoilValue,
|
||||
} from 'recoil';
|
||||
|
||||
import { StateScopeMapKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/StateScopeMapKey';
|
||||
import { createFamilyStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createFamilyStateScopeMap';
|
||||
import { getFamilyScopeInjector } from '@/ui/utilities/recoil-scope/utils/getFamilyScopeInjector';
|
||||
import { getScopeInjector } from '@/ui/utilities/recoil-scope/utils/getScopeInjector';
|
||||
import { getSelectorScopeInjector } from '@/ui/utilities/recoil-scope/utils/getSelectorScopeInjector';
|
||||
|
||||
import { useScopedState } from '../useScopedState';
|
||||
|
||||
const scopeId = 'scopeId';
|
||||
|
||||
// scoped state
|
||||
const defaultScopedState = 'defaultString';
|
||||
const scopedState = atomFamily<string, StateScopeMapKey>({
|
||||
key: 'ScopedStateKey',
|
||||
default: defaultScopedState,
|
||||
});
|
||||
const scopedStateScopeInjector = getScopeInjector(scopedState);
|
||||
|
||||
// scoped selector
|
||||
const anotherScopedState = atomFamily<number[], StateScopeMapKey>({
|
||||
key: 'ScopedStateKey',
|
||||
default: [1, 2, 3, 4, 5],
|
||||
});
|
||||
const scopedSelector = ({ scopeId }: StateScopeMapKey) =>
|
||||
selector({
|
||||
key: 'FilteredState',
|
||||
get: ({ get }) => {
|
||||
const scopedStateValue = get(anotherScopedState({ scopeId }));
|
||||
return scopedStateValue.filter((value) => value % 2 === 0);
|
||||
},
|
||||
});
|
||||
const selectorScopeInjector = getSelectorScopeInjector(scopedSelector);
|
||||
|
||||
// family state
|
||||
const defaultValue = 'defaultString';
|
||||
const scopedFamilyState = createFamilyStateScopeMap<string, string>({
|
||||
key: 'FamilyStateKey',
|
||||
defaultValue,
|
||||
});
|
||||
const familyScopeInjector = getFamilyScopeInjector(scopedFamilyState);
|
||||
|
||||
describe('useScopedState', () => {
|
||||
it('should get scoped state', () => {
|
||||
const {
|
||||
result: {
|
||||
current: { getScopedState },
|
||||
},
|
||||
} = renderHook(() => useScopedState(scopeId));
|
||||
|
||||
const scopedState = getScopedState(scopedStateScopeInjector);
|
||||
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const [scoped, setScoped] = useRecoilState(scopedState);
|
||||
return { scoped, setScoped };
|
||||
},
|
||||
{
|
||||
wrapper: RecoilRoot,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.scoped).toBe(defaultScopedState);
|
||||
|
||||
const newValue = 'anotherValue';
|
||||
|
||||
act(() => {
|
||||
result.current.setScoped(newValue);
|
||||
});
|
||||
|
||||
expect(result.current.scoped).toBe(newValue);
|
||||
});
|
||||
|
||||
it('should get scoped snapshot value', () => {
|
||||
const {
|
||||
result: {
|
||||
current: { getScopedSnapshotValue },
|
||||
},
|
||||
} = renderHook(() => useScopedState(scopeId));
|
||||
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
() =>
|
||||
getScopedSnapshotValue(snapshot, scopedStateScopeInjector),
|
||||
)(),
|
||||
{ wrapper: RecoilRoot },
|
||||
);
|
||||
|
||||
expect(result.current).toBe(defaultScopedState);
|
||||
});
|
||||
|
||||
it('should get scoped selector', () => {
|
||||
const {
|
||||
result: {
|
||||
current: { getScopedSelector },
|
||||
},
|
||||
} = renderHook(() => useScopedState(scopeId));
|
||||
|
||||
const recoilValue = getScopedSelector(selectorScopeInjector);
|
||||
|
||||
const { result } = renderHook(() => useRecoilValue(recoilValue), {
|
||||
wrapper: RecoilRoot,
|
||||
});
|
||||
|
||||
expect(result.current).toEqual([2, 4]);
|
||||
});
|
||||
|
||||
it('should get scoped selector snapshot value', () => {
|
||||
const {
|
||||
result: {
|
||||
current: { getScopedSelectorSnapshotValue },
|
||||
},
|
||||
} = renderHook(() => useScopedState(scopeId));
|
||||
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
() =>
|
||||
getScopedSelectorSnapshotValue(snapshot, selectorScopeInjector),
|
||||
)(),
|
||||
{ wrapper: RecoilRoot },
|
||||
);
|
||||
|
||||
expect(result.current).toEqual([2, 4]);
|
||||
});
|
||||
|
||||
it('should get scoped family state', () => {
|
||||
const {
|
||||
result: {
|
||||
current: { getScopedFamilyState },
|
||||
},
|
||||
} = renderHook(() => useScopedState(scopeId));
|
||||
|
||||
const scopedFamilyState = getScopedFamilyState(familyScopeInjector);
|
||||
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const [familyState, setFamilyState] = useRecoilState(
|
||||
scopedFamilyState('familyKey'),
|
||||
);
|
||||
|
||||
return { familyState, setFamilyState };
|
||||
},
|
||||
{
|
||||
wrapper: RecoilRoot,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.familyState).toBe('defaultString');
|
||||
|
||||
const newValue = 'newValue';
|
||||
|
||||
act(() => {
|
||||
result.current.setFamilyState(newValue);
|
||||
});
|
||||
|
||||
expect(result.current.familyState).toBe(newValue);
|
||||
});
|
||||
|
||||
it('should get scoped family snapshot value', () => {
|
||||
const {
|
||||
result: {
|
||||
current: { getScopedFamilySnapshotValue },
|
||||
},
|
||||
} = renderHook(() => useScopedState(scopeId));
|
||||
|
||||
const { result } = renderHook(
|
||||
() =>
|
||||
useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
() =>
|
||||
getScopedFamilySnapshotValue(snapshot, familyScopeInjector),
|
||||
)(),
|
||||
{ wrapper: RecoilRoot },
|
||||
);
|
||||
|
||||
expect(result.current('sampleKey')).toBe('defaultString');
|
||||
});
|
||||
});
|
||||
@ -1,19 +0,0 @@
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { isNonNullable } from '~/utils/isNonNullable';
|
||||
|
||||
import { ScopeInternalContext } from '../types/ScopeInternalContext';
|
||||
|
||||
export const useScopeInternalContextOrThrow = <T extends { scopeId: string }>(
|
||||
Context: ScopeInternalContext<T>,
|
||||
) => {
|
||||
const context = useContext(Context);
|
||||
|
||||
if (!isNonNullable(context)) {
|
||||
throw new Error(
|
||||
`Using a scope context without a ScopeInternalContext.Provider wrapper for context : ${Context.displayName}.`,
|
||||
);
|
||||
}
|
||||
|
||||
return context;
|
||||
};
|
||||
@ -1,50 +0,0 @@
|
||||
import { SerializableParam, Snapshot } from 'recoil';
|
||||
|
||||
import { FamilyScopeInjector } from '@/ui/utilities/recoil-scope/utils/getFamilyScopeInjector';
|
||||
import { ScopeInjector } from '@/ui/utilities/recoil-scope/utils/getScopeInjector';
|
||||
import { SelectorScopeInjector } from '@/ui/utilities/recoil-scope/utils/getSelectorScopeInjector';
|
||||
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
|
||||
|
||||
export const useScopedState = (scopeId: string) => {
|
||||
const getScopedState = <StateType>(scopeInjector: ScopeInjector<StateType>) =>
|
||||
scopeInjector(scopeId);
|
||||
|
||||
const getScopedSelector = <StateType>(
|
||||
scopeInjector: SelectorScopeInjector<StateType>,
|
||||
) => scopeInjector(scopeId);
|
||||
|
||||
const getScopedFamilyState =
|
||||
<StateType, FamilyKey extends SerializableParam>(
|
||||
familyScopeInjector: FamilyScopeInjector<StateType, FamilyKey>,
|
||||
) =>
|
||||
(familyKey: FamilyKey) =>
|
||||
familyScopeInjector(scopeId, familyKey);
|
||||
|
||||
const getScopedSnapshotValue = <StateType>(
|
||||
snapshot: Snapshot,
|
||||
scopeInjector: ScopeInjector<StateType>,
|
||||
) => getSnapshotValue(snapshot, scopeInjector(scopeId));
|
||||
|
||||
const getScopedSelectorSnapshotValue = <StateType>(
|
||||
snapshot: Snapshot,
|
||||
scopeInjector: SelectorScopeInjector<StateType>,
|
||||
) => getSnapshotValue(snapshot, scopeInjector(scopeId));
|
||||
|
||||
const getScopedFamilySnapshotValue =
|
||||
<StateType, FamilyKey extends SerializableParam>(
|
||||
snapshot: Snapshot,
|
||||
familyScopeInjector: FamilyScopeInjector<StateType, FamilyKey>,
|
||||
) =>
|
||||
(familyKey: FamilyKey) =>
|
||||
getSnapshotValue(snapshot, familyScopeInjector(scopeId, familyKey));
|
||||
|
||||
return {
|
||||
scopeId,
|
||||
getScopedState,
|
||||
getScopedSelector,
|
||||
getScopedFamilyState,
|
||||
getScopedSnapshotValue,
|
||||
getScopedSelectorSnapshotValue,
|
||||
getScopedFamilySnapshotValue,
|
||||
};
|
||||
};
|
||||
@ -1,3 +0,0 @@
|
||||
export type StateScopeMapKey = {
|
||||
scopeId: string;
|
||||
};
|
||||
@ -1,10 +1,10 @@
|
||||
import { Context, createContext } from 'react';
|
||||
|
||||
import { StateScopeMapKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/StateScopeMapKey';
|
||||
import { ComponentStateKey } from '@/ui/utilities/state/component-state/types/ComponentStateKey';
|
||||
|
||||
type ScopeInternalContext<T extends StateScopeMapKey> = Context<T | null>;
|
||||
type ScopeInternalContext<T extends ComponentStateKey> = Context<T | null>;
|
||||
|
||||
export const createScopeInternalContext = <T extends StateScopeMapKey>(
|
||||
export const createScopeInternalContext = <T extends ComponentStateKey>(
|
||||
initialValue?: T,
|
||||
) => {
|
||||
return createContext<T | null>(
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { RecoilValueReadOnly } from 'recoil';
|
||||
|
||||
import { StateScopeMapKey } from '../scopes-internal/types/StateScopeMapKey';
|
||||
import { ComponentStateKey } from '@/ui/utilities/state/component-state/types/ComponentStateKey';
|
||||
|
||||
export type RecoilScopedSelector<StateType> = (
|
||||
scopedKey: StateScopeMapKey,
|
||||
scopedKey: ComponentStateKey,
|
||||
) => RecoilValueReadOnly<StateType>;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { RecoilState } from 'recoil';
|
||||
|
||||
import { StateScopeMapKey } from '../scopes-internal/types/StateScopeMapKey';
|
||||
import { ComponentStateKey } from '@/ui/utilities/state/component-state/types/ComponentStateKey';
|
||||
|
||||
export type RecoilScopedState<StateType> = (
|
||||
scopedKey: StateScopeMapKey,
|
||||
scopedKey: ComponentStateKey,
|
||||
) => RecoilState<StateType>;
|
||||
|
||||
@ -1,40 +0,0 @@
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
import { RecoilRoot, useRecoilState } from 'recoil';
|
||||
|
||||
import { createFamilyStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createFamilyStateScopeMap';
|
||||
|
||||
import { getFamilyScopeInjector } from '../getFamilyScopeInjector';
|
||||
|
||||
const defaultValue = 'defaultString';
|
||||
|
||||
const testState = createFamilyStateScopeMap<string, string>({
|
||||
key: 'familyStateKey',
|
||||
defaultValue,
|
||||
});
|
||||
|
||||
describe('getFamilyScopeInjector', () => {
|
||||
it('should return a scoped family state', () => {
|
||||
const familyScopeInjector = getFamilyScopeInjector(testState);
|
||||
const familyState = familyScopeInjector('scopeId', 'familyKey');
|
||||
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const [family, setFamily] = useRecoilState(familyState);
|
||||
return { family, setFamily };
|
||||
},
|
||||
{
|
||||
wrapper: RecoilRoot,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.family).toBe(defaultValue);
|
||||
|
||||
const newValue = 'anotherValue';
|
||||
|
||||
act(() => {
|
||||
result.current.setFamily(newValue);
|
||||
});
|
||||
|
||||
expect(result.current.family).toBe(newValue);
|
||||
});
|
||||
});
|
||||
@ -1,45 +0,0 @@
|
||||
import { act, renderHook } from '@testing-library/react';
|
||||
import { atomFamily, RecoilRoot, useRecoilState } from 'recoil';
|
||||
|
||||
import { getScopeInjector } from '../getScopeInjector';
|
||||
|
||||
const defaultValue = 'defaultString';
|
||||
|
||||
const scopedState = atomFamily<
|
||||
string,
|
||||
{
|
||||
scopeId: string;
|
||||
}
|
||||
>({
|
||||
key: 'myStateKey',
|
||||
default: defaultValue,
|
||||
});
|
||||
|
||||
describe('getScopeInjector', () => {
|
||||
it('should return the scoped state for the given scopeId', () => {
|
||||
const scopeInjector = getScopeInjector(scopedState);
|
||||
|
||||
const scopeId = 'scopeId';
|
||||
const recoilState = scopeInjector(scopeId);
|
||||
|
||||
const { result } = renderHook(
|
||||
() => {
|
||||
const [recoil, setRecoil] = useRecoilState(recoilState);
|
||||
return { recoil, setRecoil };
|
||||
},
|
||||
{
|
||||
wrapper: RecoilRoot,
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.current.recoil).toBe(defaultValue);
|
||||
|
||||
const newValue = 'anotherValue';
|
||||
|
||||
act(() => {
|
||||
result.current.setRecoil(newValue);
|
||||
});
|
||||
|
||||
expect(result.current.recoil).toBe(newValue);
|
||||
});
|
||||
});
|
||||
@ -1,38 +0,0 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { atomFamily, RecoilRoot, selector, useRecoilValue } from 'recoil';
|
||||
|
||||
import { StateScopeMapKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/StateScopeMapKey';
|
||||
|
||||
import { getSelectorScopeInjector } from '../getSelectorScopeInjector';
|
||||
|
||||
const scopedState = atomFamily<
|
||||
number[],
|
||||
{
|
||||
scopeId: string;
|
||||
}
|
||||
>({
|
||||
key: 'myStateKey',
|
||||
default: [1, 2, 3, 4, 5],
|
||||
});
|
||||
|
||||
const scopedSelector = ({ scopeId }: StateScopeMapKey) =>
|
||||
selector({
|
||||
key: 'FilteredState',
|
||||
get: ({ get }) => {
|
||||
const scopedStateValue = get(scopedState({ scopeId }));
|
||||
return scopedStateValue.filter((value) => value % 2 === 0);
|
||||
},
|
||||
});
|
||||
|
||||
describe('getSelectorScopeInjector', () => {
|
||||
it('should return a valid SelectorScopeInjector', () => {
|
||||
const selectorScopeInjector = getSelectorScopeInjector(scopedSelector);
|
||||
const recoilValue = selectorScopeInjector('scopeId');
|
||||
|
||||
const { result } = renderHook(() => useRecoilValue(recoilValue), {
|
||||
wrapper: RecoilRoot,
|
||||
});
|
||||
|
||||
expect(result.current).toEqual([2, 4]);
|
||||
});
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user