UNPKG

ixfx

Version:

Bundle of ixfx libraries

953 lines (946 loc) 27.5 kB
import { n as __exportAll } from "./chunk-CaR5F9JI.js"; import { C as beforeMatch, D as stringSegmentsWholeToEnd, O as stringSegmentsWholeToFirst, S as afterMatch, nt as findBySomeKey, q as getPathsAndData } from "./src-BUqDa_u7.js"; import { v as QueueMutable } from "./src-DOorb7Rs.js"; import { W as resolveEl } from "./src-BoQVyMUt.js"; import "./src-DyTd46TV.js"; import { _ as fromCss, g as fromCss$1, h as toCssColour, m as toColour, v as toCssString } from "./src-CHw3eZpa.js"; import { $ as transform, X as object, _ as event, at as initStream, bt as messageIsSignal, h as observable, lt as hasLast, q as debounce, v as eventTrigger, vt as messageHasValue } from "./src-CLEFEwoM.js"; //#region ../packages/ui/src/rx/browser-resize.ts /** * Observe when element resizes. Specify `interval` to debounce, uses 100ms by default. * * ``` * const o = resizeObservable(myEl, 500); * o.subscribe(() => { * // called 500ms after last resize * }); * ``` * @param elem * @param interval Tiemout before event gets triggered * @returns */ const browserResizeObservable = (elem, interval) => { if (elem === null) throw new Error(`Param 'elem' is null. Expected element to observe`); if (elem === void 0) throw new Error(`Param 'elem' is undefined. Expected element to observe`); const m = observable((stream) => { const ro = new ResizeObserver((entries) => { stream.set(entries); }); ro.observe(elem); return () => { ro.unobserve(elem); }; }); return debounce({ elapsed: interval ?? 100 })(m); }; /** * Returns an Reactive for window resize. Default 100ms debounce. * @param elapsed * @returns */ const windowResize = (elapsed) => debounce({ elapsed: elapsed ?? 100 })(event(window, `resize`, { innerWidth: 0, innerHeight: 0 })); //#endregion //#region ../packages/ui/src/rx/browser-theme-change.ts /** * Observe when a class changes on a target element, by default the document. * Useful for tracking theme changes. * * ```js * const c = cssClassChange(); * c.on(msg => { * // some class has changed on the document * }); * ``` */ const cssClassChange = (target = document.documentElement) => { return observable((stream) => { const ro = new MutationObserver((entries) => { stream.set(entries); }); ro.observe(target, { attributeFilter: [`class`], attributes: true }); return () => { ro.disconnect(); }; }); }; //#endregion //#region ../packages/ui/src/rx/colour.ts function colour(initialValue) { let value = initialValue; const events = initStream(); const set = (v) => { value = v; events.set(v); }; return { dispose: events.dispose, isDisposed: events.isDisposed, last: () => value, on: events.on, onValue: events.onValue, set, setHsl: (hsl) => { set(hsl); } }; } //#endregion //#region ../packages/ui/src/rx/dom-source.ts /** * Reactive getting/setting of values to a HTML INPUT element. * * Options: * - relative: if _true_, values are 0..1 (default: false) * - inverted: if _true_, values are 1..0 (default: false) * * If element is missing a 'type' attribute, this will be set to 'range'. * @param targetOrQuery * @param options * @returns */ function domNumberInputValue(targetOrQuery, options = {}) { const input = domInputValue(targetOrQuery, options); const el = input.el; const relative = options.relative ?? false; const inverted = options.inverted ?? false; const rx = transform(input, (v) => { return Number.parseFloat(v); }); if (relative) { el.max = inverted ? "0" : "1"; el.min = inverted ? "1" : "0"; if (!el.hasAttribute(`step`)) el.step = "0.1"; } if (el.getAttribute(`type`) === null) el.type = `range`; const set = (value) => { input.set(value.toString()); }; return { ...rx, last() { return Number.parseFloat(input.last()); }, set }; } function domHslInputValue(targetOrQuery, options = {}) { const input = domInputValue(targetOrQuery, { ...options, upstreamFilter: (value) => { return typeof value === `object` ? toCssColour(value) : value; } }); return { ...transform(input, (v) => { return fromCss(v, { scalar: true, ensureSafe: true }); }), last() { return fromCss(input.last(), { scalar: true, ensureSafe: true }); }, set(value) { input.set(toCssString(value)); } }; } /** * A stream of values when the a HTMLInputElement changes. Eg a <input type="range"> * ```js * const r = Rx.From.domInputValue(`#myEl`); * r.onValue(value => { * // value will be string * }); * ``` * * Options: * * emitInitialValue: If _true_ emits the HTML value of element (default: false) * * attributeName: If set, this is the HTML attribute value is set to when writing to stream (default: 'value') * * fieldName: If set, this is the DOM object field set when writing to stream (default: 'value') * * when: 'changed'|'changing' when values are emitted. (default: 'changed') * * fallbackValue: Fallback value to use if field/attribute cannot be read (default: '') * @param targetOrQuery * @param options * @returns */ function domInputValue(targetOrQuery, options = {}) { const target = typeof targetOrQuery === `string` ? document.querySelector(targetOrQuery) : targetOrQuery; if (target === null && typeof targetOrQuery === `string`) throw new Error(`Element query could not be resolved '${targetOrQuery}'`); if (target === null) throw new Error(`targetOrQuery is null`); const el = resolveEl(targetOrQuery); const eventName = (options.when ?? `changed`) === `changed` ? `change` : `input`; const emitInitialValue = options.emitInitialValue ?? false; const fallbackValue = options.fallbackValue ?? ``; const upstreamSource = options.upstreamSource; let upstreamSourceUnsub = () => {}; let attribName = options.attributeName; let fieldName = options.fieldName; if (fieldName === void 0 && attribName === void 0) attribName = fieldName = `value`; const readValue = () => { let value; if (attribName) value = el.getAttribute(attribName); if (fieldName) value = el[fieldName]; if (value === void 0 || value === null) value = fallbackValue; return value; }; const setValue = (value) => { if (attribName) el.setAttribute(attribName, value); if (fieldName) el[fieldName] = value; }; const setUpstream = (v) => { v = options.upstreamFilter ? options.upstreamFilter(v) : v; setValue(v); }; if (upstreamSource) { upstreamSourceUnsub = upstreamSource.onValue(setUpstream); if (hasLast(upstreamSource)) setUpstream(upstreamSource.last()); } const rxEvents = eventTrigger(el, eventName, { fireInitial: emitInitialValue, debugFiring: options.debugFiring ?? false, debugLifecycle: options.debugLifecycle ?? false }); const rxValues = transform(rxEvents, (_trigger) => readValue()); return { ...rxValues, el, last() { return readValue(); }, set(value) { setValue(value); }, dispose(reason) { upstreamSourceUnsub(); rxValues.dispose(reason); rxEvents.dispose(reason); } }; } /** * Listens for data changes from elements within a HTML form element. * Input elements must have a 'name' attribute. * * Simple usage: * ```js * const rx = Rx.From.domForm(`#my-form`); * rx.onValue(value => { * // Object containing values from form * }); * * rx.last(); // Read current values of form * ``` * * UI can be updated * ```js * // Set using an object of key-value pairs * rx.set({ * size: 'large' * }); * * // Or set a single name-value pair * rx.setNamedValue(`size`, `large`); * ``` * * If an 'upstream' reactive is provided, this is used to set initial values of the UI, overriding * whatever may be in the HTML. Upstream changes modify UI elements, but UI changes do not modify the upstream * source. * * ```js * // Create a reactive object * const obj = Rx.From.object({ * when: `2024-10-03`, * size: 12, * checked: true * }); * * // Use this as initial values for a HTML form * // (assuming appropriate INPUT/SELECT elements exist) * const rx = Rx.From.domForm(`form`, { * upstreamSource: obj * }); * * // Listen for changes in the UI * rx.onValue(value => { * * }); * ``` * @param formElOrQuery * @param options * @returns */ function domForm(formElOrQuery, options = {}) { const formEl = resolveEl(formElOrQuery); const eventName = (options.when ?? `changed`) === `changed` ? `change` : `input`; const emitInitialValue = options.emitInitialValue ?? false; const upstreamSource = options.upstreamSource; const typeHints = /* @__PURE__ */ new Map(); let upstreamSourceUnsub = () => {}; const readValue = () => { const fd = new FormData(formEl); const entries = []; for (const [k, v] of fd.entries()) { const vString = v.toString(); let typeHint = typeHints.get(k); if (!typeHint) { const el = getFormElement(k, vString); if (el) { if (el.type === `range` || el.type === `number`) typeHint = `number`; else if (el.type === `color`) typeHint = `colour`; else if (el.type === `checkbox` && (v === `true` || v === `on`)) typeHint = `boolean`; else typeHint = `string`; typeHints.set(k, typeHint); } } if (typeHint === `number`) entries.push([k, Number.parseFloat(vString)]); else if (typeHint === `boolean`) { const vBool = vString === `true` ? true : false; entries.push([k, vBool]); } else if (typeHint === `colour`) { const vRgb = toCssColour(vString); entries.push([k, fromCss$1(vRgb, { scalar: false })]); } else entries.push([k, v.toString()]); } for (const el of formEl.querySelectorAll(`input[type="checkbox"]`)) if (!el.checked && el.value === `true`) entries.push([el.name, false]); return Object.fromEntries(entries); }; const getFormElement = (name, value) => { const el = formEl.querySelector(`[name="${name}"]`); if (!el) { console.warn(`Form does not contain an element with name="${name}"`); return; } if (el.type === `radio`) { const radioEl = formEl.querySelector(`[name="${name}"][value="${value}"]`); if (!radioEl) { console.warn(`Form does not contain radio option for name=${name} value=${value}`); return; } return radioEl; } return el; }; const setNamedValue = (name, value) => { const el = getFormElement(name, value); if (!el) return; if (el.nodeName === `INPUT` || el.nodeName === `SELECT`) { if (el.type === `color`) { if (typeof value === `object`) value = toCssColour(value); } else if (el.type === `checkbox`) if (typeof value === `boolean`) { el.checked = value; return; } else console.warn(`Rx.Sources.domForm: Trying to set non boolean type to a checkbox. Name: ${name} Value: ${value} (${typeof value})`); else if (el.type === `radio`) { el.checked = true; return; } el.value = value; } }; const setFromUpstream = (value) => { for (const [name, v] of Object.entries(value)) { let hint = typeHints.get(name); if (!hint) { hint = typeof v; if (hint === `object`) { toColour(v); hint = `colour`; } typeHints.set(name, hint); } setNamedValue(name, options.upstreamFilter ? options.upstreamFilter(name, v) : v); } }; if (upstreamSource) { upstreamSourceUnsub = upstreamSource.onValue(setFromUpstream); if (hasLast(upstreamSource)) setFromUpstream(upstreamSource.last()); } const rxEvents = eventTrigger(formEl, eventName, { fireInitial: emitInitialValue, debugFiring: options.debugFiring ?? false, debugLifecycle: options.debugLifecycle ?? false }); const rxValues = transform(rxEvents, (_trigger) => readValue()); return { ...rxValues, el: formEl, last() { return readValue(); }, set: setFromUpstream, setNamedValue, dispose(reason) { upstreamSourceUnsub(); rxValues.dispose(reason); rxEvents.dispose(reason); } }; } //#endregion //#region ../packages/ui/src/rx/dom.ts /** * Reactive stream of array of elements that match `query`. * @param query * @returns */ function fromDomQuery(query) { const elements = [...document.querySelectorAll(query)]; return object(elements); } /** * Updates an element's `textContent` when the source value changes. * ```js * bindText(source, `#blah`); * ``` * @param elOrQuery * @param source * @param bindOpts */ const bindText = (source, elOrQuery, bindOpts = {}) => { return bindElement(source, elOrQuery, { ...bindOpts, elField: `textContent` }); }; /** * Updates an element's `value` (as well as the 'value' attribute) when the source value changes.s * @param source * @param elOrQuery * @param bindOpts * @returns */ const bindValueText = (source, elOrQuery, bindOpts = {}) => { return bindElement(source, elOrQuery, { ...bindOpts, elField: `value`, attribName: `value` }); }; /** * Updates an element's `innerHTML` when the source value changes * ```js * bindHtml(source, `#blah`); * ``` * * Uses {@link bindElement}, with `{elField:'innerHTML'}` as the options. * @param elOrQuery * @param source * @param bindOpts * @returns */ const bindHtml = (source, elOrQuery, bindOpts = {}) => { return bindElement(source, elOrQuery, { ...bindOpts, elField: `innerHTML` }); }; /** * Shortcut to bind to an elements attribute * @param elOrQuery * @param source * @param attribute * @param bindOpts * @returns */ /** * Shortcut to bind to a CSS variable * @param elOrQuery * @param source * @param cssVariable * @param bindOpts * @returns */ /** * Creates a new HTML element, calling {@link bind} on it to update when `source` emits new values. * * * ```js * // Set textContent of a SPAN with values from `source` * create(source, { tagName: `span`, parentEl: document.body }) * ``` * * If `parentEl` is not given in the options, the created element needs to be manually added * ```js * const b = create(source); * someEl.append(b.el); // Append manually * ``` * * ``` * // Set 'title' attribute based on values from `source` * create(source, { parentEl: document.body, attribName: `title` }) * ``` * @param source * @param options * @returns */ /** * Update a DOM element's field, attribute or CSS variable when `source` produces a value. * * ```js * // Access via DOM query. Binds to 'textContent' by default * bind(readableSource, `#someEl`); * * // Set innerHTML instead * bind(readableSource, someEl, { elField: `innerHTML` }); * * // An attribute * bind(readableSource, someEl, { attribName: `width` }); * * // A css variable ('--' optiona) * bind(readableSource, someEl, { cssVariable: `hue` }); * * // Pluck a particular field from source data. * // Ie someEl.textContent = value.colour * bind(readableSource, someEl, { sourceField: `colour` }); * * // Transform value before setting it to field * bind(readableSource, someEl, { * field: `innerHTML`, * transform: (v) => `Colour: ${v.colour}` * }) * ``` * * If `source` has an initial value, this is used when first bound. * * Returns {@link PipeDomBinding} to control binding: * ```js * const bind = bind(source, `#someEl`); * bind.remove(); // Unbind * bind.remove(true); // Unbind and remove HTML element * ``` * * If several fields need to be updated based on a new value, consider using {@link bindUpdate} instead. * @param elOrQuery Element to update to, or query string such as '#someid' * @param source Source of data * @param binds Bindings */ const bindElement = (source, elOrQuery, ...binds) => { if (elOrQuery === null) throw new Error(`Param 'elOrQuery' is null`); if (elOrQuery === void 0) throw new Error(`Param 'elOrQuery' is undefined`); const el = resolveEl(elOrQuery); let b = []; if (binds.length === 0) b.push({ elField: `textContent` }); else b = [...binds]; return bind(source, ...b.map((bind) => { if (`element` in bind) return bind; return { ...bind, element: el }; })); }; const resolveBindUpdater = (bind, element) => { const b = resolveBindUpdaterBase(bind); return (value) => { b(value, element); }; }; const resolveBindUpdaterBase = (bind) => { if (bind.elField !== void 0 || bind.cssVariable === void 0 && bind.attribName === void 0 && bind.cssProperty === void 0 && bind.textContent === void 0 && bind.htmlContent === void 0) { const field = bind.elField ?? `textContent`; return (v, element) => { element[field] = v; }; } if (bind.attribName !== void 0) { const attrib = bind.attribName; return (v, element) => { element.setAttribute(attrib, v); }; } if (bind.textContent) return (v, element) => { element.textContent = v; }; if (bind.htmlContent) return (v, element) => { element.innerHTML = v; }; if (bind.cssVariable !== void 0) { let css = bind.cssVariable; if (!css.startsWith(`--`)) css = `--` + css; return (v, element) => { element.style.setProperty(css, v); }; } if (bind.cssProperty !== void 0) return (v, element) => { element.style[bind.cssProperty] = v; }; return (_, _element) => { /** no-op */ }; }; const resolveTransform = (bind) => { if (!bind.transform && !bind.transformValue) return; if (bind.transformValue) { if (bind.sourceField === void 0) throw new Error(`Expects 'sourceField' to be set when 'transformValue' is set`); return (value) => { const fieldValue = value[bind.sourceField]; return bind.transformValue(fieldValue); }; } else if (bind.transform) { if (bind.sourceField !== void 0) throw new Error(`If 'transform' is set, 'sourceField' is ignored`); return (value) => bind.transform(value); } }; /** * Binds `source` to one or more element(s). One or more bindings for the same source * can be provided. * * ```js * bind(source, * // Binds .name field of source values to textContent of #some-element * { query: `#some-element`, sourceField: `name` }, * { query: `section`, } * ); * ``` * * Can update * * CSS variables * * CSS styles * * textContent / innerHTML * * HTML DOM attributes and object fields * * Can use a particular field on source values, or use the whole value. These can * pass through `transformValue` or `transform` respectively. * * Returns a function to unbind from source and optionally remove HTML element * ```js * const unbind = bind( . . . ); * unbind(); // Unbind * unbind(true); // Unbind and remove HTML element(s) * ``` * @param source * @param bindsUnresolvedElements * @returns */ const bind = (source, ...bindsUnresolvedElements) => { const binds = bindsUnresolvedElements.map((bind) => { if (bind.element && bind.element !== void 0) return bind; if (bind.query) return { ...bind, element: resolveEl(bind.query) }; throw new Error(`Unable to resolve element. Missing 'element' or 'query' values on bind. ${JSON.stringify(bind)}`); }); const bindsResolved = binds.map((bind) => ({ update: resolveBindUpdater(bind, bind.element), transformer: resolveTransform(bind), sourceField: bind.sourceField })); const update = (value) => { for (const bind of bindsResolved) if (bind.transformer) bind.update(bind.transformer(value)); else { const v = bind.sourceField ? value[bind.sourceField] : value; if (typeof v === `object`) if (bind.sourceField) bind.update(JSON.stringify(v)); else bind.update(JSON.stringify(v)); else bind.update(v); } }; const unsub = source.on((message) => { if (messageHasValue(message)) update(message.value); else if (messageIsSignal(message)) console.warn(message); }); if (hasLast(source)) update(source.last()); return { remove: (removeElements) => { unsub(); if (removeElements) for (const bind of binds) bind.element.remove(); } }; }; /** * Calls `updater` whenever `source` produces a value. Useful when several fields from a value * are needed to update an element. * ```js * bindUpdate(source, `#someEl`, (v, el) => { * el.setAttribute(`width`, v.width); * el.setAttribute(`height`, v.height); * }); * ``` * * Returns a {@link PipeDomBinding} to manage binding * ```js * const b = bindUpdate(...); * b.remove(); // Disconnect binding * b.remove(true); // Disconnect binding and remove element * b.el; // HTML element * ``` * @param elOrQuery * @param source * @param updater * @returns */ const bindUpdate = (source, elOrQuery, updater) => { const el = resolveEl(elOrQuery); const update = (value) => { updater(value, el); }; const unsub = source.on((message) => { if (messageHasValue(message)) { console.log(message); update(message.value); } else console.warn(message); }); if (hasLast(source)) update(source.last()); return { remove: (removeElement) => { unsub(); if (removeElement) el.remove(); } }; }; /** * Updates a HTML element based on diffs on an object. * ```js * // Wrap an object * const o = Rx.object({ name: `Jane`, ticks: 0 }); * const b = bindDiffUpdate(`#test`, o, (diffs, el) => { * // el = reference to #test * // diff = Array of Changes, * // eg [ { path: `ticks`, value: 797, previous: 0 } ] * for (const diff of diffs) { * if (diff.path === `ticks`) el.textContent = `${diff.previous} -> ${diff.value}` * } * }) * * // Eg. update field * o.updateField(`ticks`, Math.floor(Math.random()*1000)); * ``` * * If `initial` is provided as an option, this will be called if `source` has an initial value. Without this, the DOM won't be updated until the first data * update happens. * ```js * bindDiffUpdate(el, source, updater, { * initial: (v, el) => { * el.innerHTML = v.name; * } * }) * ``` * @param elOrQuery * @param source * @param updater * @param opts * @returns */ const bindDiffUpdate = (source, elOrQuery, updater, opts = {}) => { if (elOrQuery === null) throw new Error(`Param 'elOrQuery' is null`); if (elOrQuery === void 0) throw new Error(`Param 'elOrQuery' is undefined`); const el = resolveEl(elOrQuery); const update = (value) => { updater(value, el); }; const unsub = source.onDiff((value) => { update(value); }); const init = () => { if (hasLast(source) && opts.initial) opts.initial(source.last(), el); }; init(); return { refresh: () => { init(); }, remove: (removeElement) => { unsub(); if (removeElement) el.remove(); } }; }; /** * Creates a new HTML element and calls `bindUpdate` so values from `source` can be used * to update it. * * * ```js * // Creates a span, adding it to <body> * const b = createUpdate(dataSource, (value, el) => { * el.width = value.width; * el.height = value.height; * }, { * tagName: `SPAN`, * parentEl: document.body * }) * ``` * @param source * @param updater * @param options * @returns */ /** * Creates, updates & deletes elements based on pathed values from a reactive. * * This means that elements are only manipulated if its associated data changes, * and elements are not modified if there's no need to. * @param source * @param options */ const elements = (source, options) => { const containerEl = options.container ? resolveEl(options.container) : document.body; const defaultTag = options.defaultTag ?? `div`; const elByField = /* @__PURE__ */ new Map(); const binds = /* @__PURE__ */ new Map(); for (const [key, value] of Object.entries(options.binds ?? {})) { const tagName = value.tagName ?? defaultTag; binds.set(key, { ...value, update: resolveBindUpdaterBase(value), transform: resolveTransform(value), tagName, path: key }); } const findBind = (path) => { const bind = findBySomeKey(binds, stringSegmentsWholeToEnd(path)); if (bind !== void 0) return bind; if (!path.includes(`.`)) return binds.get(`_root`); }; function* ancestorBinds(path) { for (const p of stringSegmentsWholeToFirst(path)) if (binds.has(p)) yield binds.get(p); if (binds.has(`_root`) && path.includes(`.`)) yield binds.get(`_root`); } const create = (path, value) => { const rootedPath = getRootedPath(path); console.log(`Rx.Dom.elements.create: ${path} rooted: ${rootedPath} value: ${JSON.stringify(value)}`); const bind = findBind(getRootedPath(path)); let tagName = defaultTag; if (bind?.tagName) tagName = bind.tagName; const el = document.createElement(tagName); el.setAttribute(`data-path`, path); update(path, el, value); let parentForEl; for (const b of ancestorBinds(rootedPath)) if (b?.nestChildren) { const absoluteRoot = beforeMatch(path, `.`); const findBy = b.path.replace(`_root`, absoluteRoot); parentForEl = elByField.get(findBy); if (parentForEl === void 0) {} else break; } (parentForEl ?? containerEl).append(el); elByField.set(path, el); console.log(`Added el: ${path}`); }; const update = (path, el, value) => { console.log(`Rx.dom.update path: ${path} value:`, value); const bind = findBind(getRootedPath(path)); if (bind === void 0) { if (typeof value === `object`) value = JSON.stringify(value); el.textContent = value; } else { if (bind.transform) value = bind.transform(value); bind.update(value, el); } }; const changes = (changes) => { const queue = new QueueMutable({}, changes); let d = queue.dequeue(); const seenPaths = /* @__PURE__ */ new Set(); while (d !== void 0) { const path = d.path; if (!(`previous` in d) || d.previous === void 0) { console.log(`Rx.Dom.elements.changes no previous. path: ${path}`); create(path, d.value); const subdata = [...getPathsAndData(d.value, false, Number.MAX_SAFE_INTEGER, path)]; console.log(subdata); for (const dd of subdata) if (!seenPaths.has(dd.path)) { queue.enqueue(dd); seenPaths.add(dd.path); } } else if (d.value === void 0) { const el = elByField.get(path); if (el === void 0) console.warn(`No element to delete? ${path} `); else { console.log(`Rx.Dom.elements.changes delete ${path}`); el.remove(); } } else { const el = elByField.get(path); if (el === void 0) { console.warn(`Rx.Dom.elements.changes No element to update ? ${path} `); create(path, d.value); } else update(path, el, d.value); } d = queue.dequeue(); } }; /** * Source has changed */ source.onDiff((value) => { changes(value); }); if (hasLast(source)) { const last = source.last(); changes([...getPathsAndData(last, false, 1)]); } }; /** * Replaces the root portion of `path` with the magic keyword `_root` * @param path * @returns */ const getRootedPath = (path) => { const after = afterMatch(path, `.`); return after === path ? `_root` : `_root.` + after; }; function win() { const generateRect = () => ({ width: window.innerWidth, height: window.innerHeight }); const size = event(window, `resize`, { lazy: `very`, transform: () => generateRect() }); const pointer = event(window, `pointermove`, { lazy: `very`, transform: (args) => { if (args === void 0) return { x: 0, y: 0 }; const pe = args; return { x: pe.x, y: pe.y }; } }); const dispose = (reason = `Reactive.win.dispose`) => { size.dispose(reason); pointer.dispose(reason); }; return { dispose, size, pointer }; } //#endregion //#region ../packages/ui/src/rx/index.ts var rx_exports = /* @__PURE__ */ __exportAll({ bind: () => bind, bindDiffUpdate: () => bindDiffUpdate, bindElement: () => bindElement, bindHtml: () => bindHtml, bindText: () => bindText, bindUpdate: () => bindUpdate, bindValueText: () => bindValueText, browserResizeObservable: () => browserResizeObservable, colour: () => colour, cssClassChange: () => cssClassChange, domForm: () => domForm, domHslInputValue: () => domHslInputValue, domInputValue: () => domInputValue, domNumberInputValue: () => domNumberInputValue, elements: () => elements, fromDomQuery: () => fromDomQuery, win: () => win, windowResize: () => windowResize }); //#endregion export { rx_exports as RxUi }; //# sourceMappingURL=ui.js.map