Skip to content

Instantly share code, notes, and snippets.

@christianalfoni
Created September 25, 2019 06:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christianalfoni/13c037b4c988d3298af576cb878bafeb to your computer and use it in GitHub Desktop.
Save christianalfoni/13c037b4c988d3298af576cb878bafeb to your computer and use it in GitHub Desktop.
export const createModals = <
T extends {
[name: string]: {
state?: IState;
result?: unknown;
};
}
>(
modals: T
): {
state?: {
current: keyof T;
} & {
[K in keyof T]: T[K]['state'] & { isCurrent: IDerive<any, any, boolean> }
};
actions?: {
[K in keyof T]: {
open: AsyncAction<
T[K]['state'] extends IState ? T[K]['state'] : void,
T[K]['result']
>;
close: AsyncAction<T[K]['result']>;
}
};
} => {
function createModal(name, modal) {
let resolver;
const open: AsyncAction<any, any> = async ({ state }, newState = {}) => {
state.modals.current = name;
Object.assign(state.modals[name], newState);
return new Promise(resolve => {
resolver = resolve;
});
};
const close: AsyncAction<T> = async ({ state }, payload) => {
state.modals.current = null;
resolver(payload || modal.result);
};
return {
state: {
...modal.state,
isCurrent(_, root) {
return root.modals.current === name;
},
},
actions: {
open,
close,
},
};
}
return Object.keys(modals).reduce(
(aggr, name) => {
const modal = createModal(name, modals[name]);
aggr.state[name] = modal.state;
aggr.actions[name] = modal.actions;
return aggr;
},
{
state: {
current: null,
},
actions: {},
}
) as any;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment