@motorcycle/mostly-dom
Version:
Motorcycle.ts adapter for mostly-dom. Built on @motorcycle/dom.
52 lines • 2.23 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var prelude_1 = require("@typed/prelude");
var stream_1 = require("@motorcycle/stream");
/**
* Isolates a component by adding an isolation class name to the outermost
* DOM element emitted by the component’s view stream.
*
* The isolation class name is generated by appending the given isolation `key`
* to the prefix `$$isolation$$-`, e.g., given `foo` as `key` produces
* `$$isolation$$-foo`.
*
* Isolating components are useful especially when dealing with lists of a
* specific component, so that events can be differentiated between the siblings.
* However, isolated components are not isolated from access by an ancestor DOM
* element.
*
* Note that `isolate` is curried.
*
* @name isolate<Sources extends DomSources, Sinks extends DomSinks>(component: Component<Sources, Sinks>, key: string, sources: Sources): Sinks
*
* @example
* import { empty } from '@motorcycle/stream'
* import { createDomSource } from '@motorcycle/dom'
*
* const sources = createDomSource(empty())
* const sinks = isolate(MyComponent, `myIsolationKey`, sources)
*/
exports.isolate = prelude_1.curry3(function isolate(component, key, sources) {
var dom = sources.dom;
var isolatedDom = dom.query("." + KEY_PREFIX + key);
var sinks = component(Object.assign({}, sources, { dom: isolatedDom }));
var isolatedSinks = Object.assign({}, sinks, { view$: isolateView(sinks.view$, key) });
return isolatedSinks;
});
var KEY_PREFIX = "__isolation__";
function isolateView(view$, key) {
var prefixedKey = KEY_PREFIX + key;
return stream_1.tap(function (vNode) {
var _a = vNode.props.className, className = _a === void 0 ? EMPTY_CLASS_NAME : _a;
var needsIsolation = className.indexOf(prefixedKey) === -1;
if (needsIsolation)
vNode.props.className = removeSuperfluousSpaces(prelude_1.join(CLASS_NAME_SEPARATOR, [className, prefixedKey]));
}, view$);
}
var EMPTY_CLASS_NAME = "";
var CLASS_NAME_SEPARATOR = " ";
function removeSuperfluousSpaces(str) {
return str.replace(RE_TWO_OR_MORE_SPACES, CLASS_NAME_SEPARATOR);
}
var RE_TWO_OR_MORE_SPACES = /\s{2,}/g;
//# sourceMappingURL=isolate.js.map