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:
@ -0,0 +1,6 @@
|
||||
import { SerializableParam } from 'recoil';
|
||||
|
||||
export type ComponentFamilyStateKey<FamilyKey extends SerializableParam> = {
|
||||
scopeId: string;
|
||||
familyKey: FamilyKey;
|
||||
};
|
||||
@ -0,0 +1,3 @@
|
||||
export type ComponentStateKey = {
|
||||
scopeId: string;
|
||||
};
|
||||
@ -0,0 +1,24 @@
|
||||
import { selectorFamily, SerializableParam } from 'recoil';
|
||||
|
||||
import { ComponentFamilyStateKey } from '@/ui/utilities/state/component-state/types/ComponentFamilyStateKey';
|
||||
import { SelectorGetter } from '@/ui/utilities/state/types/SelectorGetter';
|
||||
import { SelectorSetter } from '@/ui/utilities/state/types/SelectorSetter';
|
||||
|
||||
export const createComponentFamilySelector = <
|
||||
ValueType,
|
||||
FamilyKey extends SerializableParam,
|
||||
>({
|
||||
key,
|
||||
get,
|
||||
set,
|
||||
}: {
|
||||
key: string;
|
||||
get: SelectorGetter<ValueType, ComponentFamilyStateKey<FamilyKey>>;
|
||||
set: SelectorSetter<ValueType, ComponentFamilyStateKey<FamilyKey>>;
|
||||
}) => {
|
||||
return selectorFamily<ValueType, ComponentFamilyStateKey<FamilyKey>>({
|
||||
key,
|
||||
get,
|
||||
set,
|
||||
});
|
||||
};
|
||||
@ -0,0 +1,19 @@
|
||||
import { atomFamily, SerializableParam } from 'recoil';
|
||||
|
||||
import { ComponentFamilyStateKey } from '@/ui/utilities/state/component-state/types/ComponentFamilyStateKey';
|
||||
|
||||
export const createComponentFamilyState = <
|
||||
ValueType,
|
||||
FamilyKey extends SerializableParam,
|
||||
>({
|
||||
key,
|
||||
defaultValue,
|
||||
}: {
|
||||
key: string;
|
||||
defaultValue: ValueType;
|
||||
}) => {
|
||||
return atomFamily<ValueType, ComponentFamilyStateKey<FamilyKey>>({
|
||||
key,
|
||||
default: defaultValue,
|
||||
});
|
||||
};
|
||||
@ -0,0 +1,17 @@
|
||||
import { selectorFamily } from 'recoil';
|
||||
|
||||
import { ComponentStateKey } from '@/ui/utilities/state/component-state/types/ComponentStateKey';
|
||||
import { SelectorGetter } from '@/ui/utilities/state/types/SelectorGetter';
|
||||
|
||||
export const createComponentReadOnlySelector = <ValueType>({
|
||||
key,
|
||||
get,
|
||||
}: {
|
||||
key: string;
|
||||
get: SelectorGetter<ValueType, ComponentStateKey>;
|
||||
}) => {
|
||||
return selectorFamily<ValueType, ComponentStateKey>({
|
||||
key,
|
||||
get,
|
||||
});
|
||||
};
|
||||
@ -0,0 +1,21 @@
|
||||
import { selectorFamily } from 'recoil';
|
||||
|
||||
import { ComponentStateKey } from '@/ui/utilities/state/component-state/types/ComponentStateKey';
|
||||
import { SelectorGetter } from '@/ui/utilities/state/types/SelectorGetter';
|
||||
import { SelectorSetter } from '@/ui/utilities/state/types/SelectorSetter';
|
||||
|
||||
export const createComponentSelector = <ValueType>({
|
||||
key,
|
||||
get,
|
||||
set,
|
||||
}: {
|
||||
key: string;
|
||||
get: SelectorGetter<ValueType, ComponentStateKey>;
|
||||
set: SelectorSetter<ValueType, ComponentStateKey>;
|
||||
}) => {
|
||||
return selectorFamily<ValueType, ComponentStateKey>({
|
||||
key,
|
||||
get,
|
||||
set,
|
||||
});
|
||||
};
|
||||
@ -0,0 +1,16 @@
|
||||
import { atomFamily } from 'recoil';
|
||||
|
||||
import { ComponentStateKey } from '@/ui/utilities/state/component-state/types/ComponentStateKey';
|
||||
|
||||
export const createComponentState = <ValueType>({
|
||||
key,
|
||||
defaultValue,
|
||||
}: {
|
||||
key: string;
|
||||
defaultValue: ValueType;
|
||||
}) => {
|
||||
return atomFamily<ValueType, ComponentStateKey>({
|
||||
key,
|
||||
default: defaultValue,
|
||||
});
|
||||
};
|
||||
@ -0,0 +1,19 @@
|
||||
import { RecoilState, SerializableParam } from 'recoil';
|
||||
|
||||
import { ComponentFamilyStateKey } from '@/ui/utilities/state/component-state/types/ComponentFamilyStateKey';
|
||||
|
||||
export const extractComponentFamilyState = <
|
||||
StateType,
|
||||
FamilyKey extends SerializableParam,
|
||||
>(
|
||||
componentfamilyState: (
|
||||
componentFamilyStateKey: ComponentFamilyStateKey<FamilyKey>,
|
||||
) => RecoilState<StateType>,
|
||||
scopeId: string,
|
||||
) => {
|
||||
return (familyKey: FamilyKey) =>
|
||||
componentfamilyState({
|
||||
scopeId,
|
||||
familyKey: familyKey || ('' as FamilyKey),
|
||||
});
|
||||
};
|
||||
@ -0,0 +1,12 @@
|
||||
import { RecoilValueReadOnly } from 'recoil';
|
||||
|
||||
import { ComponentStateKey } from '@/ui/utilities/state/component-state/types/ComponentStateKey';
|
||||
|
||||
export const extractComponentReadOnlySelector = <StateType>(
|
||||
componentSelector: (
|
||||
componentStateKey: ComponentStateKey,
|
||||
) => RecoilValueReadOnly<StateType>,
|
||||
scopeId: string,
|
||||
) => {
|
||||
return () => componentSelector({ scopeId });
|
||||
};
|
||||
@ -0,0 +1,12 @@
|
||||
import { RecoilState } from 'recoil';
|
||||
|
||||
import { ComponentStateKey } from '@/ui/utilities/state/component-state/types/ComponentStateKey';
|
||||
|
||||
export const extractComponentSelector = <StateType>(
|
||||
componentSelector: (
|
||||
componentStateKey: ComponentStateKey,
|
||||
) => RecoilState<StateType>,
|
||||
scopeId: string,
|
||||
) => {
|
||||
return () => componentSelector({ scopeId });
|
||||
};
|
||||
@ -0,0 +1,12 @@
|
||||
import { RecoilState } from 'recoil';
|
||||
|
||||
import { ComponentStateKey } from '@/ui/utilities/state/component-state/types/ComponentStateKey';
|
||||
|
||||
export const extractComponentState = <StateType>(
|
||||
componentState: (
|
||||
componentStateKey: ComponentStateKey,
|
||||
) => RecoilState<StateType>,
|
||||
scopeId: string,
|
||||
) => {
|
||||
return () => componentState({ scopeId });
|
||||
};
|
||||
@ -0,0 +1,14 @@
|
||||
import {
|
||||
GetCallback,
|
||||
GetRecoilValue,
|
||||
Loadable,
|
||||
RecoilValue,
|
||||
WrappedValue,
|
||||
} from 'recoil';
|
||||
|
||||
export type SelectorGetter<T, P> = (
|
||||
param: P,
|
||||
) => (opts: {
|
||||
get: GetRecoilValue;
|
||||
getCallback: GetCallback;
|
||||
}) => Promise<T> | RecoilValue<T> | Loadable<T> | WrappedValue<T> | T;
|
||||
@ -0,0 +1,13 @@
|
||||
import {
|
||||
DefaultValue,
|
||||
GetRecoilValue,
|
||||
ResetRecoilState,
|
||||
SetRecoilState,
|
||||
} from 'recoil';
|
||||
|
||||
export type SelectorSetter<T, P> = (
|
||||
param: P,
|
||||
) => (
|
||||
opts: { set: SetRecoilState; get: GetRecoilValue; reset: ResetRecoilState },
|
||||
newValue: T | DefaultValue,
|
||||
) => void;
|
||||
@ -0,0 +1,17 @@
|
||||
import { atomFamily, SerializableParam } from 'recoil';
|
||||
|
||||
export const createFamilyState = <
|
||||
ValueType,
|
||||
FamilyKey extends SerializableParam,
|
||||
>({
|
||||
key,
|
||||
defaultValue,
|
||||
}: {
|
||||
key: string;
|
||||
defaultValue: ValueType;
|
||||
}) => {
|
||||
return atomFamily<ValueType, FamilyKey>({
|
||||
key,
|
||||
default: defaultValue,
|
||||
});
|
||||
};
|
||||
@ -0,0 +1,18 @@
|
||||
import { atom, AtomEffect } from 'recoil';
|
||||
|
||||
export const createState = <ValueType>({
|
||||
key,
|
||||
defaultValue,
|
||||
effects,
|
||||
}: {
|
||||
key: string;
|
||||
defaultValue: ValueType;
|
||||
effects?: ReadonlyArray<AtomEffect<ValueType>>;
|
||||
}) => {
|
||||
const recoilState = atom<ValueType>({
|
||||
key,
|
||||
default: defaultValue,
|
||||
effects,
|
||||
});
|
||||
return () => recoilState;
|
||||
};
|
||||
@ -0,0 +1,8 @@
|
||||
import { RecoilState, RecoilValueReadOnly, Snapshot } from 'recoil';
|
||||
|
||||
export const getSnapshotValue = <StateType>(
|
||||
snapshot: Snapshot,
|
||||
state: RecoilState<StateType> | RecoilValueReadOnly<StateType>,
|
||||
) => {
|
||||
return snapshot.getLoadable(state).getValue();
|
||||
};
|
||||
@ -0,0 +1,8 @@
|
||||
import { DefaultValue } from 'recoil';
|
||||
|
||||
export const guardRecoilDefaultValue = (
|
||||
candidate: any,
|
||||
): candidate is DefaultValue => {
|
||||
if (candidate instanceof DefaultValue) return true;
|
||||
return false;
|
||||
};
|
||||
Reference in New Issue
Block a user