UNPKG

cyclejs-modal

Version:

An easy way to open custom modals in a cyclejs app

221 lines 10 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; Object.defineProperty(exports, "__esModule", { value: true }); var xstream_1 = require("xstream"); var dom_1 = require("@cycle/dom"); var adapt_1 = require("@cycle/run/lib/adapt"); var cyclejs_utils_1 = require("cyclejs-utils"); var ModalSource = /** @class */ (function () { function ModalSource(_namespace, _sinks$$) { if (_sinks$$ === void 0) { _sinks$$ = xstream_1.default.create(); } this._namespace = _namespace; this._sinks$$ = _sinks$$; } ModalSource.prototype.select = function (id) { return new ModalSource(this._namespace, this._sinks$$.filter(function (o) { return o.id !== undefined && o.id === id; })); }; ModalSource.prototype.sinks = function (driverNames) { if (driverNames) { return cyclejs_utils_1.extractSinks(this.sinks(), driverNames); } return this._sinks$$.map(function (o) { return o.sinks$; }).flatten(); }; ModalSource.prototype.isolateSource = function (source, scope) { return new ModalSource(source._namespace.concat(scope), source._sinks$$ .filter(function (o) { return o.namespace[0] === scope; }) .map(function (o) { return (__assign({}, o, { namespace: o.namespace.slice(1) })); })); }; ModalSource.prototype.isolateSink = function (modal$, scope) { var _this = this; return modal$.map(function (action) { return (__assign({}, action, { namespace: action.namespace ? action.namespace : _this._namespace.concat(scope) })); }); }; return ModalSource; }()); exports.ModalSource = ModalSource; function modalify(main, _a) { var _b = _a === void 0 ? {} : _a, _c = _b.name, name = _c === void 0 ? 'modal' : _c, _d = _b.DOMDriverKey, DOMDriverKey = _d === void 0 ? 'DOM' : _d, _e = _b.center, center = _e === void 0 ? true : _e, _f = _b.wrapperClass, wrapperClass = _f === void 0 ? null : _f, _g = _b.modalContainerClass, modalContainerClass = _g === void 0 ? null : _g, _h = _b.background, background = _h === void 0 ? 'rgba(0,0,0,0.8)' : _h, _j = _b.zIndex, zIndex = _j === void 0 ? 500 : _j; return function (sources) { var _a, _b; var modalSource = new ModalSource([]); var parentSinks = main(__assign({}, sources, (_a = {}, _a[name] = modalSource, _a))); var sinks = Object.keys(parentSinks) .map(function (k) { var _a; return (_a = {}, _a[k] = xstream_1.default.fromObservable(parentSinks[k]), _a); }) .reduce(function (prev, curr) { return Object.assign(prev, curr); }, {}); if (sinks[name]) { var modalProxy$ = xstream_1.default.create(); var modalStack$ = xstream_1.default .merge(sinks[name], modalProxy$) .fold(function (acc, curr) { if (curr.type === 'close') { var count = curr.count || 1; for (var i = 0; i < Math.min(acc.length, count); i++) { var _a = acc[acc.length - i - 1], id = _a[0], namespace = _a[1], _ = _a[2]; modalSource._sinks$$.shamefullySendNext({ id: id, namespace: namespace, sinks$: xstream_1.default.never() }); } return acc.slice(0, Math.max(acc.length - count, 0)); } else if (curr.type === 'open') { var _sources = curr.sources !== undefined ? curr.sources : sources; var overlayClose$ = xstream_1.default.never(); if (curr.backgroundOverlayClose !== false) { overlayClose$ = xstream_1.default .fromObservable(sources[DOMDriverKey].select('div.cyclejs-modal').events('click')) .map(function (ev) { ev.stopPropagation(); return ev; }) .filter(function (e) { return e.target === (e.currentTarget || e.ownerTarget); }) .mapTo({ type: 'close' }); } var componentSinks_1 = curr.component(_sources); var xsComponentSinks = Object.keys(componentSinks_1) .map(function (k) { var _a; return (_a = {}, _a[k] = xstream_1.default.fromObservable(componentSinks_1[k]), _a); }) .reduce(function (prev, curr) { return Object.assign(prev, curr); }, {}); var domlessSinks = __assign({}, componentSinks_1); delete domlessSinks[DOMDriverKey]; modalSource._sinks$$.shamefullySendNext({ id: curr.id, namespace: curr.namespace || [], sinks$: xstream_1.default.never().startWith(domlessSinks) }); return acc.concat([ [ curr.id, curr.namespace || [], __assign({}, xsComponentSinks, { modal: xstream_1.default.merge(xsComponentSinks[name] || xstream_1.default.never(), overlayClose$) }) ] ]); } return acc; }, []); var modalVDom$ = modalStack$ .map(function (arr) { return arr.map(function (s) { return s[2][DOMDriverKey]; }); }) .map(function (arr) { return xstream_1.default.combine.apply(xstream_1.default, arr); }) .flatten(); var mergedVDom$ = xstream_1.default .combine(sinks[DOMDriverKey], modalVDom$) .map(function (_a) { var vdom = _a[0], modals = _a[1]; return dom_1.h('div', { attrs: { class: wrapperClass || '' } }, [ vdom, center && modals.length > 0 ? displayModals(wrapModals(modals, modalContainerClass), background, zIndex) : dom_1.h('div', { attrs: { class: modalContainerClass || '' } }, modals) ]); }); var extractedSinks = cyclejs_utils_1.extractSinks(modalStack$ .map(function (arr) { return arr.filter(function (s) { return s[0] === undefined; }).map(function (s) { return s[2]; }); }) .map(cyclejs_utils_1.mergeSinks), Object.keys(sinks)); modalProxy$.imitate(extractedSinks[name]); var newSinks_1 = __assign({}, cyclejs_utils_1.mergeSinks([extractedSinks, sinks]), (_b = {}, _b[DOMDriverKey] = mergedVDom$, _b)); return Object.keys(newSinks_1) .map(function (k) { var _a; return (_a = {}, _a[k] = adapt_1.adapt(newSinks_1[k]), _a); }) .reduce(function (prev, curr) { return Object.assign(prev, curr); }, {}); } return sinks; }; } exports.modalify = modalify; function centerHTML(children) { return dom_1.h('div', { style: { width: '100%', height: '100%', position: 'relative', 'pointer-events': 'none' } }, children.map(function (child) { return dom_1.h('div', { style: { position: 'absolute', top: '50%', left: '50%', '-ms-transform': 'translate(-50%, -50%)', '-webkit-transform': 'translate(-50%, -50%)', transform: 'translate(-50%, -50%)', 'pointer-events': 'auto' } }, [child]); })); } exports.centerHTML = centerHTML; function displayModals(modals, background, zIndex) { if (background === void 0) { background = 'rgba(0,0,0,0.8)'; } if (zIndex === void 0) { zIndex = 500; } var processedModals = modals.map(function (m, i) { return addStyles({ 'z-index': i * 5 + 10 + zIndex }, m); }); return addStyles({ background: background, 'z-index': zIndex, top: '0px', left: '0px', position: 'fixed', width: '100%', height: '100%' }, dom_1.h('div.cyclejs-modal', {}, [centerHTML(processedModals)])); } function wrapModals(modals, containerClass) { if (containerClass === void 0) { containerClass = null; } var wrapper = function (child) { return dom_1.h('div', containerClass ? { attrs: { class: containerClass } } : { style: { display: 'block', padding: '10px', background: 'white', width: 'auto', height: 'auto', 'border-radius': '5px' } }, [child]); }; return modals.map(wrapper); } function addStyles(styles, vnode) { return __assign({}, vnode, { data: __assign({}, (vnode.data || {}), { style: __assign({}, (vnode.data.style || {}), styles) }) }); } //# sourceMappingURL=modalify.js.map