Skip to content

Instantly share code, notes, and snippets.

@rosskevin rosskevin/found.js
Last active Jun 1, 2017

Embed
What would you like to do?
flow libdef for found
// @flow
// WARNING: WORK IN PROGRESS and will likely submit to flow-typed when workable.
declare module 'found' {
declare type Map = { [key: string]: any }
/**
* Location descriptor string:
* store.dispatch(FarceActions.push('/foo?bar=baz#qux'));
*
* Equivalent location descriptor object:
* store.dispatch(FarceActions.push({
* pathname: '/foo',
* search: '?bar=baz',
* hash: '#qux',
* }));
*
* https://github.com/4Catalyzer/farce#locations-and-location-descriptors
*/
declare export type Location = {
/**
* 'PUSH' or 'REPLACE' if the location was reached via FarceActions.push or FarceActions.replace respectively;
* 'POP' on the initial location, or if the location was reached via the browser back or forward buttons or
* via FarceActions.go
*/
action: 'PUSH' | 'REPLACE' | 'POP',
/**
* the difference between the current index and the index of the previous location
*/
delta: number,
/**
* the location hash; as on window.location e.g. '#qux'
*/
hash: string,
/**
* the current index of the history entry, starting at 0 for the initial entry; this increments
* on FarceActions.push but not on FarceActions.replace
*/
index: number,
/**
* if present, a unique key identifying the current history entry
*/
key?: string,
/**
* the path name; as on window.location e.g. '/foo'
*/
pathname: string,
/**
* map version of search string
*/
query: Map,
/**
* the search string; as on window.location e.g. '?bar=baz'
*/
search: string,
/**
* additional location state that is not part of the URL
*/
state: any
}
/**
* The shape might be different with a custom matcher or history enhancer, but the default matcher
* assumes and provides this shape. As such, this validator is purely for user convenience and
* should not be used internally.
*/
declare export type Match = {
location: Location,
params: Map,
}
/**
* An object implementing the matching algorithm.
*
* User code generally shouldn't need this, but it doesn't hurt to export here, since we use it
* for routerShape below.
*/
declare export class Matcher {
match: Function,
getRoutes: Function,
isActive: Function,
/**
* Returns the path string for a pattern of the same format as a route path and a object of the
* corresponding path parameters
*/
format: (pattern: any, params: Map) => any,
}
/**
* Lenient arg version of location using in #push and #replace.
*/
declare export type LocationArg = {
pathname: string,
search?: string,
hash?: string,
state?: any,
query?: Map
}
/**
* The transition hook function receives the location to which the user is attempting to navigate.
*
* This function may return:
* - true to allow the transition
* - false to block the transition
* - A string to prompt the user with that string as the message
* - A nully value to call the next transition hook and use its return value, if present, or
* else to allow the transition
* - A promise that resolves to any of the above values, to allow or block the transition
* once the promise resolves
*
* @see https://github.com/4Catalyzer/farce#transition-hooks
*/
declare export type TransitionHook = (location: Location) =>
?(boolean | string | Promise<?(boolean | string)>)
declare export class Router {
/**
* Navigates to a new location
* @see farce
*/
push: (location: string | LocationArg) => void;
/**
* Replace the current history entry
* @see farce
*/
replace: (location: string | LocationArg) => void;
/**
* Moves delta steps in the history stack
* @see farce
*/
go: (delta: number) => void;
createHref: Function;
createLocation: Function;
/**
* for match as above, returns whether match corresponds to location or a subpath of location;
* if exact is set, returns whether match corresponds exactly to location
*/
isActive: (match: Match, location: Location, options: { exact?: boolean }) => boolean;
matcher: Matcher;
/**
* Adds a transition hook that can block navigation.
*
* This method takes a transition hook function and returns a function to remove the transition hook.
*/
addTransitionHook: (hook: TransitionHook) => (() => void);
}
declare export class Route {
// NOTE: need semi-colons in class def - otherwise it breaks with FlowFixMe libdef bug.
Component?: Function;
children?: Array<Route>;
getComponent?: (props: RoutingState) => Promise<Function>;
path?: string;
render?: (args: RenderArgs) => Function;
prepareParams?: (params: Map, match: Match) => Map;
queries?: {
[key: string]: Function
};
// Provide indexer allowing for random properties
[key: string]: any;
}
declare export type RoutingState = {
/**
* The current location
*/
location: Location,
/**
* An object with location and params as properties
*/
match: Match,
/**
* The union of path parameters for *all* matched routes
*/
params: Map,
/**
* The route object corresponding to this component
*/
route: Route,
/**
* The path parameters for route
*/
routeParams: Map,
/**
* An object with static router properties
*/
router: Router,
/**
* An array of all matched route objects
*/
routes: Array<Route>
}
/**
* @see https://github.com/4Catalyzer/found/blob/master/README.md#route-configuration
* A bit lower for the list, no anchor there
*/
declare export type RenderArgs = {
match: Match,
/**
* The component for the route, if any; null if the component has not yet been loaded
*/
Component?: Function,
/**
* The data for the route, as above; null if the data have not yet been loaded
*/
data?: any,
/**
* The default props for the route component, specifically match with data as an additional property;
* null if data have not yet been loaded
*/
props?: RoutingState
}
/**
* Helper type to ease use of withRouter
*/
declare export type WithRouter = {
match: Match,
router: Router
}
declare type FunctionComponent<P> = (props: P) => ?React$Element<any>;
declare type ClassComponent<D, P, S> = Class<React$Component<D, P, S>>;
declare export function withRouter<P, S> (Component: ClassComponent<void, P, S> | FunctionComponent<P>): ClassComponent<void, $Diff<P, WithRouter>, S>;
declare export class Link extends React$Component {
props: {
Component?: React$Element,
to: string | LocationArg,
// match: Match, provided by withRouter
activeClassName?: string,
activeStyle?: Object,
activePropName?: string,
// router: Router, provided by withRouter
exact?: boolean,
target?: string,
onClick?: Function,
childProps?: Object
};
onClick: SyntheticEventHandler
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.