Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation #5

Open
iamogbz opened this issue Dec 2, 2022 · 0 comments
Open

Documentation #5

iamogbz opened this issue Dec 2, 2022 · 0 comments

Comments

@iamogbz
Copy link
Owner

iamogbz commented Dec 2, 2022

Demo

The app has three components

  1. Parent input; simple useValue
  2. Child input that is updated when the parent changes and also sends updates to the parent useSyncedValue
  3. Child input that is updated when the parent changes only; use case useTrackedValue

const [value, setValue] = React.useState<string | undefined>(
"initial parent value",
);
return (
<div className="App">
<LabelledInput
id="parentValue"
label={{ text: " parent: ", style: labelStyle }}
onValueChange={setValue}
value={value}
/>
<hr />
<SourceTargetInput
id="childValue"
label={{ text: " child that updates parent: ", style: labelStyle }}
source={{ value, setValue }}
/>
<hr />
<SourceTargetInput
id="childValue"
label={{ text: " child that only receives: ", style: labelStyle }}
source={{ value }}
/>
</div>
);

export function SourceTargetInput({
id,
label,
source,
}: SourceTargetInputProps): JSX.Element {
const synced = useSyncedValue({ source });
return (
<LabelledInput
id={id}
label={label}
value={synced.value}
onValueChange={synced.setValue}
/>
);
}

useValue

/** Params for `useValue` which include the updateable initial value and time stamper */
interface UseValueOptions<T, U> {
initial?: Partial<UpdateableValue<T>>;
stamper?: U;
}
/** Results from `useValue` which includes the recent value, time stamp and updater */
interface UseValueResult<T, U> extends UpdateableValue<T> {
value: MaybeValue<T>;
stamp: Stamp<U>;
}
/**
* Keep track of set value changes and triggers change handler on difference.
* Uses {@link isEqual} to compare values when checking for a change.
*/
export function useValue<T, U>({
initial,
stamper,
}: UseValueOptions<T, U> = {}): UseValueResult<T, U> {

useTrackedValue

/**
* Params for `useTrackedValue` which include the source value, stamper and a predicate.
*/
interface UseTrackedValueOptions<T, U> {
source?: Partial<UseValueResult<T, U>>;
stamper?: U;
shouldUpdate: ShouldUpdateCallback<T, U>;
}
export type ShouldUpdateCallback<T, U> = (
source?: ShouldUpdateArg<T, U>,
target?: ShouldUpdateArg<T, U>,
) => boolean;
type ShouldUpdateArg<T, U> = Pick<
Partial<UseValueResult<T, U>>,
"stamp" | "value"
>;
/**
* This keeps track of the source value and updates the internal value using the
* given update predicate method. This compares the stamp of the incoming source
* and the internal value, updating the tracked internal value which is returned
* if there is a change from the incoming source.
*/
export function useTrackedValue<T, U>({
source,
stamper,
shouldUpdate,
}: UseTrackedValueOptions<T, U>): UseValueResult<T, U> {

useSyncedValue

type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
type UseSycedValueOptions<T, U> = Optional<
UseTrackedValueOptions<T, U>,
"shouldUpdate"
>;
/**
* Sync a parent with a dependent child value. The incoming parent source updates are
* always tracked, while the child value which is returned can be updated independently
* only being overwritten by the parent source if there is a more recent stamped value.
*/
export function useSyncedValue<T, U>({
shouldUpdate,
source: { setValue: setSourceValue, ...source } = {},
stamper,
}: UseSycedValueOptions<T, U>): UseValueResult<T, U> {

Repository owner locked and limited conversation to collaborators Dec 2, 2022
@iamogbz iamogbz pinned this issue Dec 2, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant