Skip to content

Commit

Permalink
feat: functional component for xstate-router-navigo
Browse files Browse the repository at this point in the history
  • Loading branch information
mikaelkaron committed Jun 18, 2019
1 parent a699f4a commit de34af9
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 57 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { EventObject, StateMachine, StateSchema } from 'xstate';
import {
ComponentRenderer,
RouteEvent,
RouterInterpreterOptions,
StateRenderer
} from '../xstate-router/types';

export type RouterNavigoProps<
TContext,
TSchema extends StateSchema,
TEvent extends EventObject
> = {
machine: StateMachine<TContext, TSchema, TEvent>;
options?: RouterInterpreterOptions;
stateRenderer?: StateRenderer<any, any, RouteEvent>;
componentRenderer?: ComponentRenderer<any, any, EventObject>;
capture?: boolean;
root?: string;
useHash?: boolean;
hash?: string;
};

/**
* Functional component wrapper around XstateRouterNavigo
* @param props Component props
* @param children Component children
*/
export const RouterNavigo: <
TContext,
TSchema extends StateSchema,
TEvent extends EventObject
>(
props: RouterNavigoProps<TContext, TSchema, TEvent>,
children?: JSX.Element[]
) => JSX.Element = (props, children) => (
<xstate-router-navigo {...props}>{children}</xstate-router-navigo>
);
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import { EventObject, StateSchema } from 'xstate';
import {
ComponentRenderer,
RouteConditionPredicate,
RouteEvent,
RouterProps
} from './types';
import { RouterProps } from './types';

export * from './types';
export * from './utils';

/**
* Functional component wrapper for XstateRouter
Expand All @@ -20,56 +16,8 @@ export const Router: <
>(
props: RouterProps<TContext, TSchema, TEvent>,
children?: JSX.Element[]
) => JSX.Element = (
{ machine, options, route, navigate, stateRenderer, componentRenderer },
children
) => (
<xstate-router
machine={machine}
options={options}
route={route}
navigate={navigate}
stateRenderer={stateRenderer}
componentRenderer={componentRenderer}
>
{children}
</xstate-router>
) => JSX.Element = (props, children) => (
<xstate-router {...props}>{children}</xstate-router>
);

/**
* Merges meta objects
* @param source XState.State meta object
* @param target Target object
*/
export const mergeMeta: <T extends Record<string, any>>(
source: T,
target?: T | {}
) => T = (source, target = {}) =>
Object.keys(source).reduce(
(result, key) => Object.assign(result, source[key]),
target
);

/**
* Renders a component
* @param Component Component tag
* @param props Component props
*/
export const renderComponent: ComponentRenderer<any, any, EventObject> = (
Component,
props
) => <Component {...props} />;

/**
* Guards a route
* @param context Context
* @param event Event
* @param meta Meta
*/
export const routeGuard: RouteConditionPredicate<any, RouteEvent> = (
_,
event,
{ cond }
) => event.path === cond.path;

export default Router;
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { EventObject } from 'xstate';
import {
ComponentRenderer,
RouteConditionPredicate,
RouteEvent
} from './types';

/**
* Merges meta objects
* @param source XState.State meta object
* @param target Target object
*/
export const mergeMeta: <T extends Record<string, any>>(
source: T,
target?: T | {}
) => T = (source, target = {}) =>
Object.keys(source).reduce(
(result, key) => Object.assign(result, source[key]),
target
);

/**
* Renders a component
* @param Component Component tag
* @param props Component props
*/
export const renderComponent: ComponentRenderer<any, any, EventObject> = (
Component,
props
) => <Component {...props} />;

/**
* Guards a route
* @param context Context
* @param event Event
* @param meta Meta
*/
export const routeGuard: RouteConditionPredicate<any, RouteEvent> = (
_,
event,
{ cond }
) => event.path === cond.path;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, ComponentInterface, Prop, State } from '@stencil/core';
import { EventObject, interpret, Interpreter, StateMachine } from 'xstate';
import { mergeMeta, renderComponent, routeGuard } from '.';
import { mergeMeta, renderComponent, routeGuard } from './utils';
import {
ComponentRenderer,
NavigationEvent,
Expand Down

0 comments on commit de34af9

Please sign in to comment.