@ixfx/ui 0.50.2 → 0.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,18 @@
1
+ //#region rolldown:runtime
2
+ var __defProp = Object.defineProperty;
3
+ var __exportAll = (all, symbols) => {
4
+ let target = {};
5
+ for (var name in all) {
6
+ __defProp(target, name, {
7
+ get: all[name],
8
+ enumerable: true
9
+ });
10
+ }
11
+ if (symbols) {
12
+ __defProp(target, Symbol.toStringTag, { value: "Module" });
13
+ }
14
+ return target;
15
+ };
16
+
17
+ //#endregion
18
+ export { __exportAll as t };
@@ -0,0 +1,558 @@
1
+ import { EventSourceOptions } from "@ixfx/rx/from";
2
+ import * as Rx from "@ixfx/rx";
3
+ import { Reactive, ReactiveInitial, ReactiveNonInitial, ReactiveWritable } from "@ixfx/rx";
4
+ import { Colour } from "@ixfx/visual";
5
+ import { Interval, Pathed, RecursivePartial } from "@ixfx/core";
6
+ import { HslScalar } from "@ixfx/visual/colour";
7
+
8
+ //#region src/rx/browser-resize.d.ts
9
+
10
+ /**
11
+ * Observe when element resizes. Specify `interval` to debounce, uses 100ms by default.
12
+ *
13
+ * ```
14
+ * const o = resizeObservable(myEl, 500);
15
+ * o.subscribe(() => {
16
+ * // called 500ms after last resize
17
+ * });
18
+ * ```
19
+ * @param elem
20
+ * @param interval Tiemout before event gets triggered
21
+ * @returns
22
+ */
23
+ declare const browserResizeObservable: (elem: Readonly<Element>, interval?: Interval) => any;
24
+ /**
25
+ * Returns an Reactive for window resize. Default 100ms debounce.
26
+ * @param elapsed
27
+ * @returns
28
+ */
29
+ declare const windowResize: (elapsed?: Interval) => any;
30
+ //#endregion
31
+ //#region src/rx/browser-theme-change.d.ts
32
+ /**
33
+ * Observe when a class changes on a target element, by default the document.
34
+ * Useful for tracking theme changes.
35
+ *
36
+ * ```js
37
+ * const c = cssClassChange();
38
+ * c.on(msg => {
39
+ * // some class has changed on the document
40
+ * });
41
+ * ```
42
+ */
43
+ declare const cssClassChange: (target?: HTMLElement) => Reactive<MutationRecord[]>;
44
+ //#endregion
45
+ //#region src/rx/colour.d.ts
46
+ type ReactiveColour = ReactiveWritable<HslScalar> & {
47
+ setHsl: (hsl: HslScalar) => void;
48
+ };
49
+ declare function colour(initialValue: HslScalar): ReactiveColour & ReactiveInitial<HslScalar>;
50
+ declare function colour(): ReactiveColour & ReactiveNonInitial<HslScalar>;
51
+ //#endregion
52
+ //#region src/rx/dom-types.d.ts
53
+ type DomBindValueTarget = {
54
+ /**
55
+ * If _true_ `innerHTML` is set (a shortcut for elField:`innerHTML`)
56
+ */
57
+ htmlContent?: boolean;
58
+ /**
59
+ * If _true_, 'textContent' is set (a shortcut for elField:'textContext')
60
+ */
61
+ textContent?: boolean;
62
+ /**
63
+ * If set, this DOM element field is set. Eg 'textContent'
64
+ */
65
+ elField?: string;
66
+ /**
67
+ * If set, this DOM attribute is set, Eg 'width'
68
+ */
69
+ attribName?: string;
70
+ /**
71
+ * If set, this CSS variable is set, Eg 'hue' (sets '--hue')
72
+ */
73
+ cssVariable?: string;
74
+ /**
75
+ * If set, this CSS property is set, Eg 'background-color'
76
+ */
77
+ cssProperty?: string;
78
+ };
79
+ type ElementBind = {
80
+ /**
81
+ * Tag name for this binding.
82
+ * Overrides `defaultTag`
83
+ */
84
+ tagName?: string;
85
+ /**
86
+ * If _true_, sub-paths are appended to element, rather than `container`
87
+ */
88
+ nestChildren?: boolean;
89
+ transform?: (value: any) => string;
90
+ };
91
+ type ElementsOptions = {
92
+ container: HTMLElement | string;
93
+ defaultTag: string;
94
+ binds: Record<string, DomBindValueTarget & ElementBind>;
95
+ };
96
+ type DomBindTargetNode = {
97
+ query?: string;
98
+ element?: HTMLElement;
99
+ };
100
+ type DomBindTargetNodeResolved = {
101
+ element: HTMLElement;
102
+ };
103
+ type DomBindUnresolvedSource<TSource, TDestination> = DomBindTargetNode & DomBindSourceValue<TSource, TDestination> & DomBindValueTarget;
104
+ type DomBindResolvedSource<TSource, TDestination> = DomBindTargetNodeResolved & DomBindSourceValue<TSource, TDestination> & DomBindValueTarget;
105
+ type DomBindSourceValue<TSource, TDestination> = {
106
+ twoway?: boolean;
107
+ /**
108
+ * Field from source value to pluck and use.
109
+ * This will also be the value passed to the transform
110
+ */
111
+ sourceField?: keyof TSource;
112
+ transform?: (input: TSource) => TDestination;
113
+ transformValue?: (input: any) => TDestination;
114
+ };
115
+ type DomBindInputOptions<TSource, TDestination> = DomBindSourceValue<TSource, TDestination> & {
116
+ transformFromInput: (input: TDestination) => TSource;
117
+ };
118
+ type BindUpdateOpts<V> = {
119
+ initial: (v: V, el: HTMLElement) => void;
120
+ binds: Record<string, DomBindValueTarget & {
121
+ transform?: (value: any) => string;
122
+ }>;
123
+ };
124
+ type DomCreateOptions = {
125
+ tagName: string;
126
+ parentEl: string | HTMLElement;
127
+ };
128
+ type PipeDomBinding = {
129
+ /**
130
+ * Remove binding and optionally delete element(s) (false by default)
131
+ */
132
+ remove(deleteElements: boolean): void;
133
+ };
134
+ type DomValueOptions = EventSourceOptions & {
135
+ /**
136
+ * If true, the current value will be emitted even though it wasn't
137
+ * triggered by an event.
138
+ * Default: false
139
+ */
140
+ emitInitialValue: boolean;
141
+ attributeName: string;
142
+ fieldName: string;
143
+ /**
144
+ * Respond to when value has changed or when value is changing
145
+ * Default: `changed`
146
+ */
147
+ when: `changed` | `changing`;
148
+ fallbackValue: string;
149
+ upstreamSource?: Reactive<unknown>;
150
+ upstreamFilter?: (value: unknown) => string;
151
+ };
152
+ type DomFormOptions<T extends Record<string, unknown>> = EventSourceOptions & {
153
+ /**
154
+ * If true, the current value will be emitted even though it wasn't
155
+ * triggered by an event.
156
+ * Default: false
157
+ */
158
+ emitInitialValue: boolean;
159
+ /**
160
+ * Respond to when value has changed or when value is changing
161
+ * Default: `changed`
162
+ */
163
+ when: `changed` | `changing`;
164
+ upstreamSource?: Reactive<T>;
165
+ upstreamFilter?: (name: string, value: unknown) => string;
166
+ };
167
+ type DomNumberInputValueOptions = DomValueOptions & {
168
+ /**
169
+ * If true, sets up INPUT element to operate with relative values
170
+ */
171
+ relative?: boolean;
172
+ /**
173
+ * If true, when setting up, sets max to be on left side
174
+ */
175
+ inverted?: boolean;
176
+ upstreamSource?: Reactive<number>;
177
+ };
178
+ //#endregion
179
+ //#region src/rx/dom-source.d.ts
180
+ /**
181
+ * Reactive getting/setting of values to a HTML INPUT element.
182
+ *
183
+ * Options:
184
+ * - relative: if _true_, values are 0..1 (default: false)
185
+ * - inverted: if _true_, values are 1..0 (default: false)
186
+ *
187
+ * If element is missing a 'type' attribute, this will be set to 'range'.
188
+ * @param targetOrQuery
189
+ * @param options
190
+ * @returns
191
+ */
192
+ declare function domNumberInputValue(targetOrQuery: HTMLInputElement | string, options?: Partial<DomNumberInputValueOptions>): ReactiveInitial<number> & ReactiveWritable<number>;
193
+ declare function domHslInputValue(targetOrQuery: HTMLInputElement | string, options?: Partial<DomValueOptions>): ReactiveInitial<Colour.HslScalar> & Reactive<Colour.HslScalar> & ReactiveWritable<Colour.HslScalar>;
194
+ /**
195
+ * A stream of values when the a HTMLInputElement changes. Eg a <input type="range">
196
+ * ```js
197
+ * const r = Rx.From.domInputValue(`#myEl`);
198
+ * r.onValue(value => {
199
+ * // value will be string
200
+ * });
201
+ * ```
202
+ *
203
+ * Options:
204
+ * * emitInitialValue: If _true_ emits the HTML value of element (default: false)
205
+ * * attributeName: If set, this is the HTML attribute value is set to when writing to stream (default: 'value')
206
+ * * fieldName: If set, this is the DOM object field set when writing to stream (default: 'value')
207
+ * * when: 'changed'|'changing' when values are emitted. (default: 'changed')
208
+ * * fallbackValue: Fallback value to use if field/attribute cannot be read (default: '')
209
+ * @param targetOrQuery
210
+ * @param options
211
+ * @returns
212
+ */
213
+ declare function domInputValue(targetOrQuery: HTMLInputElement | string, options?: Partial<DomValueOptions>): {
214
+ el: HTMLInputElement;
215
+ } & ReactiveInitial<string> & ReactiveWritable<string>;
216
+ /**
217
+ * Listens for data changes from elements within a HTML form element.
218
+ * Input elements must have a 'name' attribute.
219
+ *
220
+ * Simple usage:
221
+ * ```js
222
+ * const rx = Rx.From.domForm(`#my-form`);
223
+ * rx.onValue(value => {
224
+ * // Object containing values from form
225
+ * });
226
+ *
227
+ * rx.last(); // Read current values of form
228
+ * ```
229
+ *
230
+ * UI can be updated
231
+ * ```js
232
+ * // Set using an object of key-value pairs
233
+ * rx.set({
234
+ * size: 'large'
235
+ * });
236
+ *
237
+ * // Or set a single name-value pair
238
+ * rx.setNamedValue(`size`, `large`);
239
+ * ```
240
+ *
241
+ * If an 'upstream' reactive is provided, this is used to set initial values of the UI, overriding
242
+ * whatever may be in the HTML. Upstream changes modify UI elements, but UI changes do not modify the upstream
243
+ * source.
244
+ *
245
+ * ```js
246
+ * // Create a reactive object
247
+ * const obj = Rx.From.object({
248
+ * when: `2024-10-03`,
249
+ * size: 12,
250
+ * checked: true
251
+ * });
252
+ *
253
+ * // Use this as initial values for a HTML form
254
+ * // (assuming appropriate INPUT/SELECT elements exist)
255
+ * const rx = Rx.From.domForm(`form`, {
256
+ * upstreamSource: obj
257
+ * });
258
+ *
259
+ * // Listen for changes in the UI
260
+ * rx.onValue(value => {
261
+ *
262
+ * });
263
+ * ```
264
+ * @param formElOrQuery
265
+ * @param options
266
+ * @returns
267
+ */
268
+ declare function domForm<T extends Record<string, any>>(formElOrQuery: HTMLFormElement | string, options?: Partial<DomFormOptions<T>>): {
269
+ setNamedValue: (name: string, value: any) => void;
270
+ el: HTMLFormElement;
271
+ } & ReactiveInitial<T> & ReactiveWritable<T>;
272
+ //#endregion
273
+ //#region src/rx/dom.d.ts
274
+ /**
275
+ * Reactive stream of array of elements that match `query`.
276
+ * @param query
277
+ * @returns
278
+ */
279
+ declare function fromDomQuery(query: string): Rx.Reactive<HTMLElement[]> & {
280
+ set(value: HTMLElement[]): void;
281
+ } & {
282
+ onField(fieldName: string, handler: (result: Rx.ObjectFieldHandler) => void): () => void;
283
+ onDiff(changes: (changes: Pathed.PathDataChange<any>[]) => void): () => void;
284
+ update(changedPart: (RecursivePartial<HTMLElement> | undefined)[]): HTMLElement[];
285
+ updateField(field: string, value: any): void;
286
+ } & {
287
+ last(): HTMLElement[];
288
+ };
289
+ /**
290
+ * Updates an element's `textContent` when the source value changes.
291
+ * ```js
292
+ * bindText(source, `#blah`);
293
+ * ```
294
+ * @param elOrQuery
295
+ * @param source
296
+ * @param bindOpts
297
+ */
298
+ declare const bindText: <TSource>(source: Rx.Reactive<TSource>, elOrQuery: string | HTMLElement | null, bindOpts?: Partial<DomBindSourceValue<TSource, string>>) => PipeDomBinding;
299
+ /**
300
+ * Updates an element's `value` (as well as the 'value' attribute) when the source value changes.s
301
+ * @param source
302
+ * @param elOrQuery
303
+ * @param bindOpts
304
+ * @returns
305
+ */
306
+ declare const bindValueText: <TSource>(source: Rx.Reactive<TSource>, elOrQuery: string | HTMLInputElement | null, bindOpts?: Partial<DomBindSourceValue<TSource, string>>) => PipeDomBinding;
307
+ /**
308
+ * Updates an element's `innerHTML` when the source value changes
309
+ * ```js
310
+ * bindHtml(source, `#blah`);
311
+ * ```
312
+ *
313
+ * Uses {@link bindElement}, with `{elField:'innerHTML'}` as the options.
314
+ * @param elOrQuery
315
+ * @param source
316
+ * @param bindOpts
317
+ * @returns
318
+ */
319
+ declare const bindHtml: <TSource>(source: Rx.Reactive<TSource>, elOrQuery: string | HTMLElement | null, bindOpts?: DomBindSourceValue<TSource, string>) => PipeDomBinding;
320
+ /**
321
+ * Shortcut to bind to an elements attribute
322
+ * @param elOrQuery
323
+ * @param source
324
+ * @param attribute
325
+ * @param bindOpts
326
+ * @returns
327
+ */
328
+ /**
329
+ * Shortcut to bind to a CSS variable
330
+ * @param elOrQuery
331
+ * @param source
332
+ * @param cssVariable
333
+ * @param bindOpts
334
+ * @returns
335
+ */
336
+ /**
337
+ * Creates a new HTML element, calling {@link bind} on it to update when `source` emits new values.
338
+ *
339
+ *
340
+ * ```js
341
+ * // Set textContent of a SPAN with values from `source`
342
+ * create(source, { tagName: `span`, parentEl: document.body })
343
+ * ```
344
+ *
345
+ * If `parentEl` is not given in the options, the created element needs to be manually added
346
+ * ```js
347
+ * const b = create(source);
348
+ * someEl.append(b.el); // Append manually
349
+ * ```
350
+ *
351
+ * ```
352
+ * // Set 'title' attribute based on values from `source`
353
+ * create(source, { parentEl: document.body, attribName: `title` })
354
+ * ```
355
+ * @param source
356
+ * @param options
357
+ * @returns
358
+ */
359
+ /**
360
+ * Update a DOM element's field, attribute or CSS variable when `source` produces a value.
361
+ *
362
+ * ```js
363
+ * // Access via DOM query. Binds to 'textContent' by default
364
+ * bind(readableSource, `#someEl`);
365
+ *
366
+ * // Set innerHTML instead
367
+ * bind(readableSource, someEl, { elField: `innerHTML` });
368
+ *
369
+ * // An attribute
370
+ * bind(readableSource, someEl, { attribName: `width` });
371
+ *
372
+ * // A css variable ('--' optiona)
373
+ * bind(readableSource, someEl, { cssVariable: `hue` });
374
+ *
375
+ * // Pluck a particular field from source data.
376
+ * // Ie someEl.textContent = value.colour
377
+ * bind(readableSource, someEl, { sourceField: `colour` });
378
+ *
379
+ * // Transform value before setting it to field
380
+ * bind(readableSource, someEl, {
381
+ * field: `innerHTML`,
382
+ * transform: (v) => `Colour: ${v.colour}`
383
+ * })
384
+ * ```
385
+ *
386
+ * If `source` has an initial value, this is used when first bound.
387
+ *
388
+ * Returns {@link PipeDomBinding} to control binding:
389
+ * ```js
390
+ * const bind = bind(source, `#someEl`);
391
+ * bind.remove(); // Unbind
392
+ * bind.remove(true); // Unbind and remove HTML element
393
+ * ```
394
+ *
395
+ * If several fields need to be updated based on a new value, consider using {@link bindUpdate} instead.
396
+ * @param elOrQuery Element to update to, or query string such as '#someid'
397
+ * @param source Source of data
398
+ * @param binds Bindings
399
+ */
400
+ declare const bindElement: <TSource, TDestination>(source: Rx.Reactive<TSource>, elOrQuery: string | HTMLElement | null, ...binds: (DomBindSourceValue<TSource, TDestination> & DomBindValueTarget)[]) => PipeDomBinding;
401
+ /**
402
+ * Binds `source` to one or more element(s). One or more bindings for the same source
403
+ * can be provided.
404
+ *
405
+ * ```js
406
+ * bind(source,
407
+ * // Binds .name field of source values to textContent of #some-element
408
+ * { query: `#some-element`, sourceField: `name` },
409
+ * { query: `section`, }
410
+ * );
411
+ * ```
412
+ *
413
+ * Can update
414
+ * * CSS variables
415
+ * * CSS styles
416
+ * * textContent / innerHTML
417
+ * * HTML DOM attributes and object fields
418
+ *
419
+ * Can use a particular field on source values, or use the whole value. These can
420
+ * pass through `transformValue` or `transform` respectively.
421
+ *
422
+ * Returns a function to unbind from source and optionally remove HTML element
423
+ * ```js
424
+ * const unbind = bind( . . . );
425
+ * unbind(); // Unbind
426
+ * unbind(true); // Unbind and remove HTML element(s)
427
+ * ```
428
+ * @param source
429
+ * @param bindsUnresolvedElements
430
+ * @returns
431
+ */
432
+ declare const bind: <TSource, TDestination>(source: Rx.Reactive<TSource>, ...bindsUnresolvedElements: DomBindUnresolvedSource<TSource, TDestination>[]) => PipeDomBinding;
433
+ /**
434
+ * Calls `updater` whenever `source` produces a value. Useful when several fields from a value
435
+ * are needed to update an element.
436
+ * ```js
437
+ * bindUpdate(source, `#someEl`, (v, el) => {
438
+ * el.setAttribute(`width`, v.width);
439
+ * el.setAttribute(`height`, v.height);
440
+ * });
441
+ * ```
442
+ *
443
+ * Returns a {@link PipeDomBinding} to manage binding
444
+ * ```js
445
+ * const b = bindUpdate(...);
446
+ * b.remove(); // Disconnect binding
447
+ * b.remove(true); // Disconnect binding and remove element
448
+ * b.el; // HTML element
449
+ * ```
450
+ * @param elOrQuery
451
+ * @param source
452
+ * @param updater
453
+ * @returns
454
+ */
455
+ declare const bindUpdate: <V>(source: Rx.Reactive<V>, elOrQuery: string | HTMLElement, updater: (v: V, el: HTMLElement) => void) => PipeDomBinding;
456
+ /**
457
+ * Updates a HTML element based on diffs on an object.
458
+ * ```js
459
+ * // Wrap an object
460
+ * const o = Rx.object({ name: `Jane`, ticks: 0 });
461
+ * const b = bindDiffUpdate(`#test`, o, (diffs, el) => {
462
+ * // el = reference to #test
463
+ * // diff = Array of Changes,
464
+ * // eg [ { path: `ticks`, value: 797, previous: 0 } ]
465
+ * for (const diff of diffs) {
466
+ * if (diff.path === `ticks`) el.textContent = `${diff.previous} -> ${diff.value}`
467
+ * }
468
+ * })
469
+ *
470
+ * // Eg. update field
471
+ * o.updateField(`ticks`, Math.floor(Math.random()*1000));
472
+ * ```
473
+ *
474
+ * 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
475
+ * update happens.
476
+ * ```js
477
+ * bindDiffUpdate(el, source, updater, {
478
+ * initial: (v, el) => {
479
+ * el.innerHTML = v.name;
480
+ * }
481
+ * })
482
+ * ```
483
+ * @param elOrQuery
484
+ * @param source
485
+ * @param updater
486
+ * @param opts
487
+ * @returns
488
+ */
489
+ declare const bindDiffUpdate: <V>(source: Rx.ReactiveDiff<V>, elOrQuery: string | HTMLElement | null, updater: (diffs: Pathed.PathDataChange<any>[], el: HTMLElement) => void, opts?: Partial<BindUpdateOpts<V>>) => PipeDomBinding & {
490
+ refresh: () => void;
491
+ };
492
+ /**
493
+ * Creates a new HTML element and calls `bindUpdate` so values from `source` can be used
494
+ * to update it.
495
+ *
496
+ *
497
+ * ```js
498
+ * // Creates a span, adding it to <body>
499
+ * const b = createUpdate(dataSource, (value, el) => {
500
+ * el.width = value.width;
501
+ * el.height = value.height;
502
+ * }, {
503
+ * tagName: `SPAN`,
504
+ * parentEl: document.body
505
+ * })
506
+ * ```
507
+ * @param source
508
+ * @param updater
509
+ * @param options
510
+ * @returns
511
+ */
512
+ /**
513
+ * Creates, updates & deletes elements based on pathed values from a reactive.
514
+ *
515
+ * This means that elements are only manipulated if its associated data changes,
516
+ * and elements are not modified if there's no need to.
517
+ * @param source
518
+ * @param options
519
+ */
520
+ declare const elements: <T>(source: Rx.ReactiveDiff<T> | (Rx.ReactiveDiff<T> & Rx.ReactiveInitial<T>), options: Partial<ElementsOptions>) => void;
521
+ declare function win(): {
522
+ dispose: (reason?: string) => void;
523
+ size: Rx.Reactive<{
524
+ lazy: string;
525
+ transform: () => {
526
+ width: number;
527
+ height: number;
528
+ };
529
+ }> & {
530
+ last(): {
531
+ lazy: string;
532
+ transform: () => {
533
+ width: number;
534
+ height: number;
535
+ };
536
+ };
537
+ };
538
+ pointer: Rx.Reactive<{
539
+ lazy: string;
540
+ transform: (args: Event | undefined) => {
541
+ x: number;
542
+ y: number;
543
+ };
544
+ }> & {
545
+ last(): {
546
+ lazy: string;
547
+ transform: (args: Event | undefined) => {
548
+ x: number;
549
+ y: number;
550
+ };
551
+ };
552
+ };
553
+ };
554
+ declare namespace index_d_exports {
555
+ export { BindUpdateOpts, DomBindInputOptions, DomBindResolvedSource, DomBindSourceValue, DomBindTargetNode, DomBindTargetNodeResolved, DomBindUnresolvedSource, DomBindValueTarget, DomCreateOptions, DomFormOptions, DomNumberInputValueOptions, DomValueOptions, ElementBind, ElementsOptions, PipeDomBinding, ReactiveColour, bind, bindDiffUpdate, bindElement, bindHtml, bindText, bindUpdate, bindValueText, browserResizeObservable, colour, cssClassChange, domForm, domHslInputValue, domInputValue, domNumberInputValue, elements, fromDomQuery, win, windowResize };
556
+ }
557
+ //#endregion
558
+ export { index_d_exports as RxUi };