grainjs 1.0.1 → 1.1.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.
- package/README.md +23 -26
- package/dist/cjs/index.js +28 -17
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/lib/PriorityQueue.d.ts +2 -2
- package/dist/cjs/lib/PriorityQueue.js +1 -0
- package/dist/cjs/lib/PriorityQueue.js.map +1 -1
- package/dist/cjs/lib/_computed_queue.js +4 -3
- package/dist/cjs/lib/_computed_queue.js.map +1 -1
- package/dist/cjs/lib/binding.d.ts +11 -4
- package/dist/cjs/lib/binding.js +6 -5
- package/dist/cjs/lib/binding.js.map +1 -1
- package/dist/cjs/lib/browserGlobals.d.ts +4 -1
- package/dist/cjs/lib/browserGlobals.js +2 -0
- package/dist/cjs/lib/browserGlobals.js.map +1 -1
- package/dist/cjs/lib/computed.d.ts +49 -28
- package/dist/cjs/lib/computed.js +38 -51
- package/dist/cjs/lib/computed.js.map +1 -1
- package/dist/cjs/lib/dispose.d.ts +109 -96
- package/dist/cjs/lib/dispose.js +106 -79
- package/dist/cjs/lib/dispose.js.map +1 -1
- package/dist/cjs/lib/dom.d.ts +40 -18
- package/dist/cjs/lib/dom.js +63 -29
- package/dist/cjs/lib/dom.js.map +1 -1
- package/dist/cjs/lib/domComponent.d.ts +56 -51
- package/dist/cjs/lib/domComponent.js +46 -44
- package/dist/cjs/lib/domComponent.js.map +1 -1
- package/dist/cjs/lib/domComputed.d.ts +50 -20
- package/dist/cjs/lib/domComputed.js +37 -7
- package/dist/cjs/lib/domComputed.js.map +1 -1
- package/dist/cjs/lib/domDispose.d.ts +27 -12
- package/dist/cjs/lib/domDispose.js +27 -11
- package/dist/cjs/lib/domDispose.js.map +1 -1
- package/dist/cjs/lib/domForEach.d.ts +5 -4
- package/dist/cjs/lib/domForEach.js +41 -41
- package/dist/cjs/lib/domForEach.js.map +1 -1
- package/dist/cjs/lib/domImpl.d.ts +33 -10
- package/dist/cjs/lib/domImpl.js +29 -9
- package/dist/cjs/lib/domImpl.js.map +1 -1
- package/dist/cjs/lib/domMethods.d.ts +93 -47
- package/dist/cjs/lib/domMethods.js +91 -47
- package/dist/cjs/lib/domMethods.js.map +1 -1
- package/dist/cjs/lib/domevent.d.ts +87 -62
- package/dist/cjs/lib/domevent.js +85 -59
- package/dist/cjs/lib/domevent.js.map +1 -1
- package/dist/cjs/lib/emit.d.ts +62 -32
- package/dist/cjs/lib/emit.js +68 -53
- package/dist/cjs/lib/emit.js.map +1 -1
- package/dist/cjs/lib/kowrap.d.ts +6 -3
- package/dist/cjs/lib/kowrap.js +7 -3
- package/dist/cjs/lib/kowrap.js.map +1 -1
- package/dist/cjs/lib/obsArray.d.ts +91 -53
- package/dist/cjs/lib/obsArray.js +87 -54
- package/dist/cjs/lib/obsArray.js.map +1 -1
- package/dist/cjs/lib/observable.d.ts +25 -15
- package/dist/cjs/lib/observable.js +31 -19
- package/dist/cjs/lib/observable.js.map +1 -1
- package/dist/cjs/lib/pureComputed.d.ts +12 -15
- package/dist/cjs/lib/pureComputed.js +16 -18
- package/dist/cjs/lib/pureComputed.js.map +1 -1
- package/dist/cjs/lib/styled.d.ts +78 -61
- package/dist/cjs/lib/styled.js +27 -79
- package/dist/cjs/lib/styled.js.map +1 -1
- package/dist/cjs/lib/subscribe.d.ts +41 -37
- package/dist/cjs/lib/subscribe.js +31 -39
- package/dist/cjs/lib/subscribe.js.map +1 -1
- package/dist/cjs/lib/util.js +2 -0
- package/dist/cjs/lib/util.js.map +1 -1
- package/dist/cjs/lib/widgets/input.d.ts +3 -1
- package/dist/cjs/lib/widgets/input.js +7 -4
- package/dist/cjs/lib/widgets/input.js.map +1 -1
- package/dist/cjs/lib/widgets/select.d.ts +4 -2
- package/dist/cjs/lib/widgets/select.js +8 -5
- package/dist/cjs/lib/widgets/select.js.map +1 -1
- package/dist/esm/lib/_computed_queue.js +3 -3
- package/dist/esm/lib/_computed_queue.js.map +1 -1
- package/dist/esm/lib/binding.js +2 -2
- package/dist/esm/lib/binding.js.map +1 -1
- package/dist/esm/lib/browserGlobals.js +1 -0
- package/dist/esm/lib/browserGlobals.js.map +1 -1
- package/dist/esm/lib/computed.js +36 -50
- package/dist/esm/lib/computed.js.map +1 -1
- package/dist/esm/lib/dispose.js +104 -78
- package/dist/esm/lib/dispose.js.map +1 -1
- package/dist/esm/lib/dom.js +40 -18
- package/dist/esm/lib/dom.js.map +1 -1
- package/dist/esm/lib/domComponent.js +45 -44
- package/dist/esm/lib/domComponent.js.map +1 -1
- package/dist/esm/lib/domComputed.js +32 -5
- package/dist/esm/lib/domComputed.js.map +1 -1
- package/dist/esm/lib/domDispose.js +26 -11
- package/dist/esm/lib/domDispose.js.map +1 -1
- package/dist/esm/lib/domForEach.js +40 -41
- package/dist/esm/lib/domForEach.js.map +1 -1
- package/dist/esm/lib/domImpl.js +26 -7
- package/dist/esm/lib/domImpl.js.map +1 -1
- package/dist/esm/lib/domMethods.js +77 -35
- package/dist/esm/lib/domMethods.js.map +1 -1
- package/dist/esm/lib/domevent.js +84 -59
- package/dist/esm/lib/domevent.js.map +1 -1
- package/dist/esm/lib/emit.js +67 -53
- package/dist/esm/lib/emit.js.map +1 -1
- package/dist/esm/lib/kowrap.js +5 -2
- package/dist/esm/lib/kowrap.js.map +1 -1
- package/dist/esm/lib/obsArray.js +82 -50
- package/dist/esm/lib/obsArray.js.map +1 -1
- package/dist/esm/lib/observable.js +26 -15
- package/dist/esm/lib/observable.js.map +1 -1
- package/dist/esm/lib/pureComputed.js +15 -18
- package/dist/esm/lib/pureComputed.js.map +1 -1
- package/dist/esm/lib/styled.js +24 -77
- package/dist/esm/lib/styled.js.map +1 -1
- package/dist/esm/lib/subscribe.js +27 -36
- package/dist/esm/lib/subscribe.js.map +1 -1
- package/dist/esm/lib/util.js +1 -0
- package/dist/esm/lib/util.js.map +1 -1
- package/dist/esm/lib/widgets/input.js +3 -1
- package/dist/esm/lib/widgets/input.js.map +1 -1
- package/dist/esm/lib/widgets/select.js +3 -1
- package/dist/esm/lib/widgets/select.js.map +1 -1
- package/dist/grain-full.debug.js +2138 -3052
- package/dist/grain-full.debug.js.map +7 -0
- package/dist/grain-full.min.js +6 -2
- package/dist/grain-full.min.js.map +7 -1
- package/lib/binding.ts +9 -2
- package/lib/browserGlobals.ts +3 -1
- package/lib/computed.ts +56 -56
- package/lib/dispose.ts +110 -85
- package/lib/dom.ts +41 -20
- package/lib/domComponent.ts +68 -70
- package/lib/domComputed.ts +66 -21
- package/lib/domDispose.ts +28 -11
- package/lib/domForEach.ts +13 -12
- package/lib/domImpl.ts +30 -7
- package/lib/domMethods.ts +101 -46
- package/lib/domevent.ts +86 -61
- package/lib/emit.ts +64 -50
- package/lib/kowrap.ts +5 -2
- package/lib/obsArray.ts +89 -54
- package/lib/observable.ts +26 -15
- package/lib/pureComputed.ts +16 -22
- package/lib/styled.ts +85 -71
- package/lib/subscribe.ts +41 -45
- package/lib/util.ts +1 -0
- package/lib/widgets/input.ts +3 -1
- package/lib/widgets/select.ts +3 -1
- package/package.json +48 -38
package/lib/styled.ts
CHANGED
|
@@ -1,87 +1,85 @@
|
|
|
1
|
+
// Use the browser globals in a way that allows replacing them with mocks in tests.
|
|
2
|
+
import {G} from './browserGlobals';
|
|
3
|
+
import {dom, IDomArgs, TagElem, TagName} from './domImpl';
|
|
4
|
+
import {cls, clsPrefix} from './domMethods';
|
|
5
|
+
|
|
6
|
+
// The value returned by styled() matches the input (first argument), and also implements IClsName
|
|
7
|
+
// interface.
|
|
8
|
+
export interface IClsName {
|
|
9
|
+
className: string; // Name of the generated class.
|
|
10
|
+
cls: typeof cls; // Helper like dom.cls(), but which prefixes classes by className.
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type DomCreateFunc<R, Args extends IDomArgs<R> = IDomArgs<R>> = (...args: Args) => R;
|
|
14
|
+
|
|
1
15
|
/**
|
|
2
16
|
* In-code styling for DOM components, inspired by Reacts Styled Components.
|
|
3
17
|
*
|
|
4
18
|
* Usage:
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* const cssTitle = styled('h1', `
|
|
21
|
+
* font-size: 1.5em;
|
|
22
|
+
* text-align: center;
|
|
23
|
+
* color: palevioletred;
|
|
24
|
+
* `);
|
|
25
|
+
*
|
|
26
|
+
* const cssWrapper = styled('section', `
|
|
27
|
+
* padding: 4em;
|
|
28
|
+
* background: papayawhip;
|
|
29
|
+
* `);
|
|
30
|
+
*
|
|
31
|
+
* cssWrapper(cssTitle('Hello world'))
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* This generates class names for `cssTitle` and `cssWrapper`, adds the styles to the document on
|
|
35
|
+
* first use, and the result is equivalent to:
|
|
36
|
+
* ```ts
|
|
37
|
+
* dom(`section.${cssWrapper.className}`, dom(`h1.${cssTitle.className}`, 'Hello world'));
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* What `styled(tag)` returns is a function that takes the same arguments `...args` as
|
|
41
|
+
* `dom(tag, ...args)`. In particular, you may call it with all the arguments that
|
|
42
|
+
* [`dom()`](#dom) takes: content, DOM methods, event handlers, etc.
|
|
43
|
+
*
|
|
44
|
+
* Calls to `styled()` should happen at the top level, at import time, in order to register all
|
|
24
45
|
* styles upfront. Actual work happens the first time a style is needed to create an element.
|
|
25
|
-
* Calling styled() elsewhere than at top level is wasteful and bad for performance.
|
|
26
|
-
*
|
|
27
|
-
* You may create a style that modifies an existing styled() or other component, e.g.
|
|
46
|
+
* Calling `styled()` elsewhere than at top level is wasteful and bad for performance.
|
|
28
47
|
*
|
|
29
|
-
*
|
|
48
|
+
* You may create a style that modifies an existing `styled()` or other component, e.g.
|
|
49
|
+
* ```ts
|
|
50
|
+
* const cssTitle2 = styled(cssTitle, `font-size: 1rem; color: red;`);
|
|
51
|
+
* ```
|
|
30
52
|
*
|
|
31
|
-
*
|
|
53
|
+
* Now calling `cssTitle2('Foo')` becomes equivalent to
|
|
54
|
+
* `dom('h1', {className: cssTitle.className + ' ' + cssTitle2.className})`.
|
|
32
55
|
*
|
|
33
56
|
* Styles may incorporate other related styles by nesting them under the main one as follows:
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* const myButton = styled('button', `
|
|
59
|
+
* border-radius: 0.5rem;
|
|
60
|
+
* border: 1px solid grey;
|
|
61
|
+
* font-size: 1rem;
|
|
62
|
+
*
|
|
63
|
+
* &:active {
|
|
64
|
+
* background: lightblue;
|
|
65
|
+
* }
|
|
66
|
+
* &-small {
|
|
67
|
+
* font-size: 0.6rem;
|
|
68
|
+
* }
|
|
69
|
+
* `);
|
|
70
|
+
* ```
|
|
47
71
|
*
|
|
48
72
|
* In nested styles, ampersand (&) gets replaced with the generated .className of the main element.
|
|
49
73
|
*
|
|
50
|
-
* The resulting styled component provides a
|
|
51
|
-
* behaves as dom.cls()
|
|
74
|
+
* The resulting styled component provides a `.cls()` helper to simplify using prefixed classes. It
|
|
75
|
+
* behaves as `dom.cls()`, but prefixes the class names with the generated className of the main
|
|
52
76
|
* element. E.g. for the example above,
|
|
77
|
+
* ```ts
|
|
78
|
+
* myButton(myButton.cls('-small'), 'Test')
|
|
79
|
+
* ```
|
|
53
80
|
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* creates a button with both the myButton style above, and the style specified under "&-small".
|
|
57
|
-
*
|
|
58
|
-
* Animations with @keyframes may be created with a unique name by using the keyframes() helper:
|
|
59
|
-
*
|
|
60
|
-
* const rotate360 = keyframes(`
|
|
61
|
-
* from { transform: rotate(0deg); }
|
|
62
|
-
* to { transform: rotate(360deg); }
|
|
63
|
-
* `);
|
|
64
|
-
*
|
|
65
|
-
* const Rotate = styled('div', `
|
|
66
|
-
* display: inline-block;
|
|
67
|
-
* animation: ${rotate360} 2s linear infinite;
|
|
68
|
-
* `);
|
|
81
|
+
* creates a button with both the `myButton` style above, and the style specified under "&-small".
|
|
69
82
|
*/
|
|
70
|
-
|
|
71
|
-
// Use the browser globals in a way that allows replacing them with mocks in tests.
|
|
72
|
-
import {G} from './browserGlobals';
|
|
73
|
-
import {dom, IDomArgs, TagElem, TagName} from './domImpl';
|
|
74
|
-
import {cls, clsPrefix} from './domMethods';
|
|
75
|
-
|
|
76
|
-
// The value returned by styled() matches the input (first argument), and also implements IClsName
|
|
77
|
-
// interface.
|
|
78
|
-
export interface IClsName {
|
|
79
|
-
className: string; // Name of the generated class.
|
|
80
|
-
cls: typeof cls; // Helper like dom.cls(), but which prefixes classes by className.
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export type DomCreateFunc<R, Args extends IDomArgs<R> = IDomArgs<R>> = (...args: Args) => R;
|
|
84
|
-
|
|
85
83
|
// See module documentation for details.
|
|
86
84
|
export function styled<Tag extends TagName>(tag: Tag, styles: string): DomCreateFunc<TagElem<Tag>> & IClsName;
|
|
87
85
|
export function styled<Args extends any[], R extends Element>(
|
|
@@ -102,8 +100,24 @@ export function styled(creator: any, styles: string): IClsName {
|
|
|
102
100
|
});
|
|
103
101
|
}
|
|
104
102
|
|
|
105
|
-
|
|
106
|
-
|
|
103
|
+
/**
|
|
104
|
+
* Animations with `@keyframes` may be created with a unique name by using the keyframes() helper:
|
|
105
|
+
* ```ts
|
|
106
|
+
* const rotate360 = keyframes(`
|
|
107
|
+
* from { transform: rotate(0deg); }
|
|
108
|
+
* to { transform: rotate(360deg); }
|
|
109
|
+
* `);
|
|
110
|
+
*
|
|
111
|
+
* const Rotate = styled('div', `
|
|
112
|
+
* display: inline-block;
|
|
113
|
+
* animation: ${rotate360} 2s linear infinite;
|
|
114
|
+
* `);
|
|
115
|
+
* ```
|
|
116
|
+
*
|
|
117
|
+
* This function returns simply a string with the generated name. Note that keyframes do not
|
|
118
|
+
* support nesting or ampersand (&) handling, like `styled()` does, since these would be difficult
|
|
119
|
+
* and are entirely unneeded.
|
|
120
|
+
*/
|
|
107
121
|
export function keyframes(styles: string): string {
|
|
108
122
|
return (new KeyframePiece(styles)).className;
|
|
109
123
|
}
|
package/lib/subscribe.ts
CHANGED
|
@@ -1,23 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* subscribe.js implements subscriptions to several observables at once.
|
|
3
|
-
*
|
|
4
|
-
* E.g. if we have some existing observables (which may be instances of `computed`),
|
|
5
|
-
* we can subscribe to them explicitly:
|
|
6
|
-
* let obs1 = observable(5), obs2 = observable(12);
|
|
7
|
-
* subscribe(obs1, obs2, (use, v1, v2) => console.log(v1, v2));
|
|
8
|
-
*
|
|
9
|
-
* or implicitly by using `use(obs)` function, which allows dynamic subscriptions:
|
|
10
|
-
* subscribe(use => console.log(use(obs1), use(obs2)));
|
|
11
|
-
*
|
|
12
|
-
* In either case, if obs1 or obs2 is changed, the callbacks will get called automatically.
|
|
13
|
-
*
|
|
14
|
-
* Creating a subscription allows any number of dependencies to be specified explicitly, and their
|
|
15
|
-
* values will be passed to the callback(). These may be combined with automatic dependencies
|
|
16
|
-
* detected using use(). Note that constructor dependencies have less overhead.
|
|
17
|
-
*
|
|
18
|
-
* subscribe(...deps, ((use, ...depValues) => READ_CALLBACK));
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
1
|
import {DepItem} from './_computed_queue';
|
|
22
2
|
import {IDisposableOwner} from './dispose';
|
|
23
3
|
import {Listener} from './emit';
|
|
@@ -25,6 +5,7 @@ import {fromKo, IKnockoutReadObservable} from './kowrap';
|
|
|
25
5
|
import {BaseObservable as Obs} from './observable';
|
|
26
6
|
|
|
27
7
|
export interface ISubscribableObs {
|
|
8
|
+
/** @internal */
|
|
28
9
|
_getDepItem(): DepItem|null;
|
|
29
10
|
addListener(callback: (val: any, prev: any) => void, optContext?: object): Listener;
|
|
30
11
|
get(): any;
|
|
@@ -52,6 +33,31 @@ interface IListenerWithInUse extends Listener {
|
|
|
52
33
|
// Constant empty array, which we use to avoid allocating new read-only empty arrays.
|
|
53
34
|
const emptyArray: ReadonlyArray<any> = [];
|
|
54
35
|
|
|
36
|
+
/**
|
|
37
|
+
* `Subscription` allows subscribing to several observables at once. It's the foundation for a
|
|
38
|
+
* `Computed`, but may also be used directly.
|
|
39
|
+
*
|
|
40
|
+
* E.g. if we have some existing observables (which may be instances of `Computed`),
|
|
41
|
+
* we can subscribe to them explicitly:
|
|
42
|
+
* ```ts
|
|
43
|
+
* const obs1 = observable(5), obs2 = observable(12);
|
|
44
|
+
* subscribe(obs1, obs2, (use, v1, v2) => console.log(v1, v2));
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* or implicitly by using `use(obs)` function, which allows dynamic subscriptions:
|
|
48
|
+
* ```ts
|
|
49
|
+
* subscribe(use => console.log(use(obs1), use(obs2)));
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* In either case, if `obs1` or `obs2` is changed, the callbacks will get called automatically.
|
|
53
|
+
*
|
|
54
|
+
* Creating a subscription allows any number of dependencies to be specified explicitly, and their
|
|
55
|
+
* values will be passed to the `callback`. These may be combined with automatic dependencies
|
|
56
|
+
* detected using `use()`. Note that constructor dependencies have less overhead.
|
|
57
|
+
* ```ts
|
|
58
|
+
* subscribe(...deps, ((use, ...depValues) => READ_CALLBACK));
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
55
61
|
export class Subscription {
|
|
56
62
|
private readonly _depItem: DepItem;
|
|
57
63
|
private readonly _dependencies: ReadonlyArray<ISubscribableObs>;
|
|
@@ -60,11 +66,9 @@ export class Subscription {
|
|
|
60
66
|
private _callback: (use: UseCB, ...args: any[]) => void;
|
|
61
67
|
private _useFunc: UseCB;
|
|
62
68
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
* of the 'use' function that gets passed to the callback.
|
|
67
|
-
*/
|
|
69
|
+
// Internal constructor for a Subscription. You should use subscribe() function instead.
|
|
70
|
+
// The last owner argument is used by computed() to make itself available as the .owner property
|
|
71
|
+
// of the 'use' function that gets passed to the callback.
|
|
68
72
|
constructor(callback: (use: UseCB, ...args: any[]) => void, dependencies: ReadonlyArray<ISubscribable>, owner?: any) {
|
|
69
73
|
this._depItem = new DepItem(this._evaluate, this);
|
|
70
74
|
this._dependencies = dependencies.length > 0 ? dependencies : emptyArray;
|
|
@@ -90,14 +94,14 @@ export class Subscription {
|
|
|
90
94
|
|
|
91
95
|
/**
|
|
92
96
|
* For use by computed(): returns this subscription's hook into the _computed_queue.
|
|
97
|
+
* @internal
|
|
93
98
|
*/
|
|
94
99
|
public _getDepItem(): DepItem { return this._depItem; }
|
|
95
100
|
|
|
96
101
|
/**
|
|
97
|
-
* @private
|
|
98
102
|
* Gets called when the callback calls `use(obs)` for an observable. It creates a
|
|
99
103
|
* subscription to `obs` if one doesn't yet exist.
|
|
100
|
-
* @param
|
|
104
|
+
* @param obs - The observable being used as a dependency.
|
|
101
105
|
*/
|
|
102
106
|
private _useDependency(_obs: ISubscribable) {
|
|
103
107
|
const obs = ('_getDepItem' in _obs) ? _obs : fromKo(_obs);
|
|
@@ -112,7 +116,6 @@ export class Subscription {
|
|
|
112
116
|
}
|
|
113
117
|
|
|
114
118
|
/**
|
|
115
|
-
* @private
|
|
116
119
|
* Calls the callback() with appropriate args, and updates subscriptions when it is done.
|
|
117
120
|
* I.e. adds dynamic subscriptions created via `use(obs)`, and disposes those no longer used.
|
|
118
121
|
*/
|
|
@@ -140,10 +143,9 @@ export class Subscription {
|
|
|
140
143
|
}
|
|
141
144
|
|
|
142
145
|
/**
|
|
143
|
-
* @private
|
|
144
146
|
* Subscribes this computed to another observable that it depends on.
|
|
145
|
-
* @param
|
|
146
|
-
* @returns
|
|
147
|
+
* @param obs - The observable to subscribe to.
|
|
148
|
+
* @returns Listener object.
|
|
147
149
|
*/
|
|
148
150
|
private _subscribeTo(_obs: ISubscribable) {
|
|
149
151
|
const obs = ('_getDepItem' in _obs) ? _obs : fromKo(_obs);
|
|
@@ -151,7 +153,6 @@ export class Subscription {
|
|
|
151
153
|
}
|
|
152
154
|
|
|
153
155
|
/**
|
|
154
|
-
* @private
|
|
155
156
|
* Adds this item to the recompute queue.
|
|
156
157
|
*/
|
|
157
158
|
private _enqueue() {
|
|
@@ -160,9 +161,14 @@ export class Subscription {
|
|
|
160
161
|
}
|
|
161
162
|
|
|
162
163
|
/**
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
164
|
+
* Creates a new Subscription.
|
|
165
|
+
* @param observables - The initial params, of which there may be zero or more, are
|
|
166
|
+
* observables on which this computed depends. When any of them change, the `callback`
|
|
167
|
+
* will be called with the values of these observables as arguments.
|
|
168
|
+
* @param callback - will be called with arguments `(use, ...values)`, i.e. the
|
|
169
|
+
* `use` function and values for all of the `...observables` that precede this argument.
|
|
170
|
+
* This callback is called immediately, and whenever any dependency changes.
|
|
171
|
+
* @returns The new `Subscription` which may be disposed to unsubscribe.
|
|
166
172
|
*/
|
|
167
173
|
export function subscribe(cb: (use: UseCB) => void): Subscription;
|
|
168
174
|
|
|
@@ -186,16 +192,6 @@ export function subscribe<A, B, C, D, E>(
|
|
|
186
192
|
a: Obs<A>, b: Obs<B>, c: Obs<C>, d: Obs<D>, e: Obs<E>,
|
|
187
193
|
cb: (use: UseCB, a: A, b: B, c: C, d: D, e: E) => void): Subscription;
|
|
188
194
|
|
|
189
|
-
/**
|
|
190
|
-
* Creates a new Subscription.
|
|
191
|
-
* @param {Observable} ...observables: The initial params, of which there may be zero or more, are
|
|
192
|
-
* observables on which this computed depends. When any of them change, the callback()
|
|
193
|
-
* will be called with the values of these observables as arguments.
|
|
194
|
-
* @param {Function} callback: will be called with arguments (use, ...values), i.e. the
|
|
195
|
-
* `use` function and values for all of the ...observables that precede this argument.
|
|
196
|
-
* This callback is called immediately, and whenever any dependency changes.
|
|
197
|
-
* @returns {Subscription} The new subscription which may be disposed to unsubscribe.
|
|
198
|
-
*/
|
|
199
195
|
export function subscribe(...args: any[]): Subscription {
|
|
200
196
|
const cb = args.pop();
|
|
201
197
|
// The cast helps ensure that Observable is compatible with ISubscribable abstraction that we use.
|
package/lib/util.ts
CHANGED
package/lib/widgets/input.ts
CHANGED
|
@@ -19,13 +19,15 @@ export interface IInputOptions {
|
|
|
19
19
|
* number, tel.
|
|
20
20
|
*
|
|
21
21
|
* Note that every change to the observable will affect the input element, but not every change to
|
|
22
|
-
* the input element will affect the observable. Specifically, unless {onInput: true} is set, the
|
|
22
|
+
* the input element will affect the observable. Specifically, unless `{onInput: true}` is set, the
|
|
23
23
|
* visible content may differ from the observable until the element loses focus or Enter is hit.
|
|
24
24
|
*
|
|
25
25
|
* Example usage:
|
|
26
|
+
* ```
|
|
26
27
|
* input(obs, {}, {type: 'text', placeholder: 'Your name...'});
|
|
27
28
|
* input(obs, {isValid: isValidObs}, {type: 'email', placeholder: 'Your email...'});
|
|
28
29
|
* input(obs, {onInput: true}, {type: 'text'});
|
|
30
|
+
* ```
|
|
29
31
|
*/
|
|
30
32
|
export function input(
|
|
31
33
|
obs: Observable<string>, options: IInputOptions, ...args: IDomArgs<HTMLInputElement>
|
package/lib/widgets/select.ts
CHANGED
|
@@ -24,7 +24,7 @@ function getOptionValue<T>(option: IOption<T>): T {
|
|
|
24
24
|
/**
|
|
25
25
|
* Creates a select dropdown widget. The observable `obs` reflects the value of the selected
|
|
26
26
|
* option, and `optionArray` is an array (regular or observable) of option values and labels.
|
|
27
|
-
* These may be either strings, or {label, value, disabled} objects.
|
|
27
|
+
* These may be either strings, or `{label, value, disabled}` objects.
|
|
28
28
|
*
|
|
29
29
|
* The type of value may be any type at all; it is opaque to this widget.
|
|
30
30
|
*
|
|
@@ -32,6 +32,7 @@ function getOptionValue<T>(option: IOption<T>): T {
|
|
|
32
32
|
* label that the select box will show, blank by default.
|
|
33
33
|
*
|
|
34
34
|
* Usage:
|
|
35
|
+
* ```
|
|
35
36
|
* const fruit = observable("apple");
|
|
36
37
|
* select(fruit, ["apple", "banana", "mango"]);
|
|
37
38
|
*
|
|
@@ -42,6 +43,7 @@ function getOptionValue<T>(option: IOption<T>): T {
|
|
|
42
43
|
* {value: 21, label: "Eve"},
|
|
43
44
|
* ]);
|
|
44
45
|
* select(employee, employees, {defLabel: "Select employee:"});
|
|
46
|
+
* ```
|
|
45
47
|
*/
|
|
46
48
|
export function select<T>(obs: Observable<T>, optionArray: MaybeObsArray<IOption<T>>,
|
|
47
49
|
options: {defLabel?: string} = {}) {
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "grainjs",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "JS library from Grist Labs",
|
|
5
5
|
"main": "dist/cjs/index",
|
|
6
6
|
"module": "dist/esm/index",
|
|
7
|
-
"types": "dist/cjs/index",
|
|
7
|
+
"types": "dist/cjs/index.d.ts",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"build": "bash build.sh",
|
|
10
10
|
"watch": "tsc -w",
|
|
@@ -16,8 +16,12 @@
|
|
|
16
16
|
"test-browser-headless": "MOCHA_WEBDRIVER_ARGS='--no-sandbox --disable-gpu' MOCHA_WEBDRIVER_HEADLESS=1 mocha 'test/browser/*.{js,ts}'",
|
|
17
17
|
"test-browser": "mocha 'test/browser/*.{js,ts}'",
|
|
18
18
|
"test-browser-debug": "mocha --bail --no-exit 'test/browser/*.{js,ts}'",
|
|
19
|
-
"test-types": "
|
|
20
|
-
"prepack": "npm run build && npm test"
|
|
19
|
+
"test-types": "tsd --files 'test/types/**/*.ts'",
|
|
20
|
+
"prepack": "npm run build && npm test",
|
|
21
|
+
"docs:dev": "vitepress dev docs",
|
|
22
|
+
"docs:build": "vitepress build docs",
|
|
23
|
+
"docs:build-api": "tsc -p tsconfig/tsconfig.es2015.cjs.json && api-extractor run --local --verbose && node scripts/generate-api-md.js",
|
|
24
|
+
"docs:preview": "vitepress preview docs"
|
|
21
25
|
},
|
|
22
26
|
"keywords": [
|
|
23
27
|
"grist",
|
|
@@ -44,6 +48,11 @@
|
|
|
44
48
|
},
|
|
45
49
|
"homepage": "https://github.com/gristlabs/grainjs#readme",
|
|
46
50
|
"nyc": {
|
|
51
|
+
"reporter": [
|
|
52
|
+
"html",
|
|
53
|
+
"text",
|
|
54
|
+
"lcov"
|
|
55
|
+
],
|
|
47
56
|
"extension": [
|
|
48
57
|
".ts"
|
|
49
58
|
],
|
|
@@ -55,41 +64,42 @@
|
|
|
55
64
|
"owner": "gristlabs",
|
|
56
65
|
"repo": "grainjs"
|
|
57
66
|
},
|
|
58
|
-
"dependencies": {},
|
|
59
67
|
"devDependencies": {
|
|
60
|
-
"@
|
|
61
|
-
"@types/chai
|
|
62
|
-
"@types/
|
|
63
|
-
"@types/
|
|
64
|
-
"@types/
|
|
65
|
-
"@types/
|
|
66
|
-
"@types/
|
|
67
|
-
"@types/
|
|
68
|
-
"@types/
|
|
69
|
-
"
|
|
70
|
-
"chai": "^
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
"
|
|
84
|
-
"
|
|
85
|
-
"
|
|
86
|
-
"
|
|
87
|
-
"
|
|
88
|
-
"typescript": "
|
|
89
|
-
"typescript-tslint-plugin": "^0.3.1",
|
|
68
|
+
"@microsoft/api-extractor": "^7.55.1",
|
|
69
|
+
"@types/chai": "^4.2.18",
|
|
70
|
+
"@types/chai-as-promised": "^7.1.4",
|
|
71
|
+
"@types/jsdom": "^16.2.11",
|
|
72
|
+
"@types/lodash": "^4.14.170",
|
|
73
|
+
"@types/mocha": "^8.2.2",
|
|
74
|
+
"@types/node": "^22",
|
|
75
|
+
"@types/selenium-webdriver": "^4.0.13",
|
|
76
|
+
"@types/sinon": "^21.0.0",
|
|
77
|
+
"chai": "^6.2.1",
|
|
78
|
+
"chai-as-promised": "^8.0.2",
|
|
79
|
+
"esbuild": "^0.27.2",
|
|
80
|
+
"eslint": "^9.39.2",
|
|
81
|
+
"fastpriorityqueue": "^0.7.5",
|
|
82
|
+
"jsdom": "27.3.0",
|
|
83
|
+
"knockout": "^3.5.1",
|
|
84
|
+
"lodash": "^4.17.21",
|
|
85
|
+
"markdown-it-multimd-table": "^4.2.3",
|
|
86
|
+
"mocha": "^11.7.5",
|
|
87
|
+
"mocha-webdriver": "^0.3.4",
|
|
88
|
+
"nyc": "^17.1.0",
|
|
89
|
+
"selenium-webdriver": "^4.38.0",
|
|
90
|
+
"sinon": "^21.0.0",
|
|
91
|
+
"ts-loader": "^9.2.3",
|
|
92
|
+
"ts-node": "^10.9.2",
|
|
93
|
+
"tsd": "^0.27.0",
|
|
94
|
+
"typescript": "^4",
|
|
95
|
+
"typescript-eslint": "^8.50.0",
|
|
96
|
+
"typescript-tslint-plugin": "^1.0.1",
|
|
90
97
|
"uglify-es": "^3.2.0",
|
|
91
|
-
"
|
|
92
|
-
"webpack
|
|
93
|
-
"webpack-dev-server": "^
|
|
98
|
+
"vitepress": "^1.6.4",
|
|
99
|
+
"webpack": "^5.104.0",
|
|
100
|
+
"webpack-dev-server": "^5.2.2"
|
|
101
|
+
},
|
|
102
|
+
"overrides": {
|
|
103
|
+
"esbuild": "^0.27.2"
|
|
94
104
|
}
|
|
95
105
|
}
|