Skip to content

Commit

Permalink
Experimental hooks API
Browse files Browse the repository at this point in the history
  • Loading branch information
Vlad Balin committed Jul 16, 2019
1 parent 135dd3f commit 4b564fe
Show file tree
Hide file tree
Showing 24 changed files with 506 additions and 440 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ The series of 5-minute tutorials (with `React.Component`):
- [Form validation with ValueLinks](https://medium.com/@gaperton/react-forms-with-value-links-part-2-validation-9d1ba78f8e49#.nllbm4cr7)
- [Complex state with ValueLinks](https://medium.com/@gaperton/state-and-forms-in-react-part-3-handling-the-complex-state-acf369244d37#.x0fjcxljo)

### [API Reference](/valuelink/README.md)
### [API Reference](/valuelink/API.md)

### [Linked Controls Reference](/linked-controls/README.md)

Expand Down
12 changes: 6 additions & 6 deletions examples/autocomplete/bundles/app.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/autocomplete/bundles/app.js.map

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions examples/babel-starter/bundles/app.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/babel-starter/bundles/app.js.map

Large diffs are not rendered by default.

225 changes: 122 additions & 103 deletions examples/databinding/dist/main.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/databinding/dist/main.js.map

Large diffs are not rendered by default.

225 changes: 122 additions & 103 deletions examples/todomvc-hooks/bundles/app.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/todomvc-hooks/bundles/app.js.map

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions examples/userslist-classes/bundles/app.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/userslist-classes/bundles/app.js.map

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions examples/userslist-hooks/bundles/app.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/userslist-hooks/bundles/app.js.map

Large diffs are not rendered by default.

15 changes: 8 additions & 7 deletions valuelink/lib/hooks.d.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
/// <reference types="react" />
import { Link, LinksHash } from './link';
export declare class UseStateLink<T> extends Link<T> {
import { Link as StateRef, RefsHash } from './link';
export declare class UseStateRef<T> extends StateRef<T> {
set(x: T | ((x: T) => T)): void;
update(fun: (x: T, event?: Object) => T, event?: Object): void;
constructor(value: T, set: (x: T | ((x: T) => T)) => void);
}
/**
* Create the ref to the local state.
*/
export declare function useLink<S>(initialState: S | (() => S)): UseStateLink<S>;
export declare function useLink<S>(initialState: S | (() => S)): UseStateRef<S>;
export { useLink as useStateRef, useSafeLink as useSafeStateRef, useBoundLink as useBoundStateRef, useSafeBoundLink as useSafeBoundStateRef };
/**
* Create the link to the local state which is safe to set when component is unmounted.
* Use this for the state which is set when async I/O is completed.
*/
export declare function useSafeLink<S>(initialState: S | (() => S)): UseStateLink<S>;
export declare function useSafeLink<S>(initialState: S | (() => S)): UseStateRef<S>;
/**
* Returns the ref which is true when component it mounted.
*/
Expand All @@ -23,20 +23,20 @@ export declare function useIsMountedRef(): import("react").MutableRefObject<bool
* Create the link to the local state which is bound to another
* value or link in a single direction. When the source changes, the link changes too.
*/
export declare function useBoundLink<T>(source: T | Link<T>): Link<T>;
export declare function useBoundLink<T>(source: T | StateRef<T>): StateRef<T>;
/**
* Create the safe link to the local state which is synchronized with another
* value or link in a single direction.
* When the source change, the linked state changes too.
*/
export declare function useSafeBoundLink<T>(source: T): Link<T>;
export declare function useSafeBoundLink<T>(source: T | StateRef<T>): StateRef<T>;
/**
* Persists links in local storage under the given key.
* Links will be loaded on component's mount, and saved on unmount.
* @param key - string key for the localStorage entry.
* @param state - links to persist wrapped in an object `{ lnk1, lnk2, ... }`
*/
export declare function useLocalStorage(key: string, state: LinksHash): void;
export declare function useLocalStorage(key: string, state: RefsHash): void;
/**
* Wait for the promise (or async function) completion.
* Execute operation once when mounted, returning `null` while the operation is pending.
Expand All @@ -49,3 +49,4 @@ export declare function useLocalStorage(key: string, state: LinksHash): void;
* });
*/
export declare function useIO(fun: () => Promise<any>, condition?: any[]): boolean;
export declare function whenChanged(...objs: any[]): any[];
38 changes: 23 additions & 15 deletions valuelink/lib/hooks.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion valuelink/lib/hooks.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

79 changes: 40 additions & 39 deletions valuelink/lib/link.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,36 @@ export interface Validator<T> {
(value: T): boolean;
error?: any;
}
export { Link as StateRef };
export declare abstract class Link<T> {
export { StateRef as Link };
export declare abstract class StateRef<T> {
value: T;
static value<T>(value: T, set: (x: T) => void): Link<T>;
static value<T>(value: T, set: (x: T) => void): StateRef<T>;
/**
* Unwrap object with links, returning an object of a similar shape filled with link values.
*/
static getValues<K extends keyof L, L extends LinksHash>(links: L): {
static getValues<K extends keyof L, L extends RefsHash>(links: L): {
[name in K]: any;
};
current: T;
private readonly _changeToken;
/**
* Unwrap object with links, returning an object of a similar shape filled with link errors.
*/
static getErrors<K extends keyof L, L extends LinksHash>(links: L): {
static getErrors<K extends keyof L, L extends RefsHash>(links: L): {
[name in K]: L[name]["value"];
};
/**
* Return true if an object with links contains any errors.
*/
static hasErrors<L extends LinksHash>(links: L): boolean;
static hasErrors<L extends RefsHash>(links: L): boolean;
/**
* Assing links with values from the source object.
*/
static setValues(links: LinksHash, source: object): void;
static setValues(links: RefsHash, source: object): void;
constructor(value: T);
error: any;
abstract set(x: T): void;
onChange(handler: (x: T) => void): Link<T>;
onChange(handler: (x: T) => void): StateRef<T>;
readonly props: {
checked: (T & false) | (T & true);
onChange: (e: any) => void;
Expand All @@ -43,79 +44,79 @@ export declare abstract class Link<T> {
checked?: undefined;
};
update(transform: Transform<T>, e?: Object): void;
pipe(handler: Transform<T>): Link<T>;
pipe(handler: Transform<T>): StateRef<T>;
action(transform: Transform<T>): EventHandler;
equals(truthyValue: T): Link<boolean>;
enabled(defaultValue?: T): Link<boolean>;
contains<E>(this: Link<E[]>, element: E): Link<boolean>;
push<E>(this: Link<E[]>, ...args: E[]): void;
unshift<E>(this: Link<E[]>, ...args: E[]): void;
equals(truthyValue: T): StateRef<boolean>;
enabled(defaultValue?: T): StateRef<boolean>;
contains<E>(this: StateRef<E[]>, element: E): StateRef<boolean>;
push<E>(this: StateRef<E[]>, ...args: E[]): void;
unshift<E>(this: StateRef<E[]>, ...args: E[]): void;
splice(start: number, deleteCount?: number): any;
map<E, Z>(this: Link<E[]>, iterator: (link: LinkAt<E, number>, idx: number) => Z): Z[];
map<E, Z>(this: Link<{
map<E, Z>(this: StateRef<E[]>, iterator: (link: RefAt<E, number>, idx: number) => Z): Z[];
map<E, Z>(this: StateRef<{
[key: string]: E;
}>, iterator: (link: LinkAt<E, string>, idx: string) => Z): Z[];
removeAt<E>(this: Link<E[]>, key: number): void;
removeAt<E>(this: Link<{
}>, iterator: (link: RefAt<E, string>, idx: string) => Z): Z[];
removeAt<E>(this: StateRef<E[]>, key: number): void;
removeAt<E>(this: StateRef<{
[key: string]: E;
}>, key: string): void;
at<E>(this: Link<E[]>, key: number): LinkAt<E, number>;
at<K extends keyof T, E extends T[K]>(key: K): LinkAt<E, K>;
at<E>(this: StateRef<E[]>, key: number): RefAt<E, number>;
at<K extends keyof T, E extends T[K]>(key: K): RefAt<E, K>;
clone(): T;
/**
* Convert link to object to the object of links. Optionally filter by
*/
pick<K extends keyof T>(...keys: K[]): {
[P in K]: Link<T[P]>;
[P in K]: StateRef<T[P]>;
};
/**
* Convert link to object to the object of links with $-keys.
*/
$links(): {
[P in keyof T]: Link<T[P]>;
[P in keyof T]: StateRef<T[P]>;
};
/**
* Validate link with validness predicate and optional custom error object. Can be chained.
*/
check(whenValid: Validator<T>, error?: any): this;
}
export declare class CustomLink<T> extends Link<T> {
export declare class CustomStateRef<T> extends StateRef<T> {
set(x: any): void;
constructor(value: T, set: (x: T) => void);
}
export declare class CloneLink<T> extends Link<T> {
export declare class ClonedStateRef<T> extends StateRef<T> {
set(x: any): void;
constructor(parent: Link<T>, set: (x: T) => void);
constructor(parent: StateRef<T>, set: (x: T) => void);
}
export declare class EqualsLink extends Link<boolean> {
parent: Link<any>;
export declare class EqualsRef extends StateRef<boolean> {
parent: StateRef<any>;
truthyValue: any;
constructor(parent: Link<any>, truthyValue: any);
constructor(parent: StateRef<any>, truthyValue: any);
set(x: boolean): void;
}
export declare class EnabledLink extends Link<boolean> {
parent: Link<any>;
export declare class EnabledRef extends StateRef<boolean> {
parent: StateRef<any>;
defaultValue: any;
constructor(parent: Link<any>, defaultValue: any);
constructor(parent: StateRef<any>, defaultValue: any);
set(x: boolean): void;
}
export declare class ContainsLink extends Link<boolean> {
parent: Link<any>;
export declare class ContainsRef extends StateRef<boolean> {
parent: StateRef<any>;
element: any;
constructor(parent: Link<any>, element: any);
constructor(parent: StateRef<any>, element: any);
set(x: boolean): void;
}
/**
* Link to array or object element enclosed in parent link.
* Performs purely functional update of the parent, shallow copying its value on `set`.
*/
export declare class LinkAt<E, K> extends Link<E> {
export declare class RefAt<E, K> extends StateRef<E> {
private parent;
key: K;
constructor(parent: Link<any>, key: K);
constructor(parent: StateRef<any>, key: K);
remove(): void;
set(x: E): void;
}
export interface LinksHash {
[name: string]: Link<any>;
export interface RefsHash {
[name: string]: StateRef<any>;
}
Loading

0 comments on commit 4b564fe

Please sign in to comment.