@vscode/observables-react 0.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/LICENSE +21 -0
- package/README.md +349 -0
- package/dist/IPropertyTransformer.d.ts +37 -0
- package/dist/IPropertyTransformer.d.ts.map +1 -0
- package/dist/IPropertyTransformer.js +64 -0
- package/dist/IPropertyTransformer.js.map +1 -0
- package/dist/ManualChangesHandler.d.ts +14 -0
- package/dist/ManualChangesHandler.d.ts.map +1 -0
- package/dist/ManualChangesHandler.js +45 -0
- package/dist/ManualChangesHandler.js.map +1 -0
- package/dist/ProvideViewModel.d.ts +41 -0
- package/dist/ProvideViewModel.d.ts.map +1 -0
- package/dist/ProvideViewModel.js +41 -0
- package/dist/ProvideViewModel.js.map +1 -0
- package/dist/Value.d.ts +16 -0
- package/dist/Value.d.ts.map +1 -0
- package/dist/Value.js +26 -0
- package/dist/Value.js.map +1 -0
- package/dist/di.d.ts +31 -0
- package/dist/di.d.ts.map +1 -0
- package/dist/di.js +86 -0
- package/dist/di.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/index.min.js +6 -0
- package/dist/index.min.js.map +1 -0
- package/dist/internal.d.ts +2 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +6 -0
- package/dist/internal.js.map +1 -0
- package/dist/obsView.d.ts +14 -0
- package/dist/obsView.d.ts.map +1 -0
- package/dist/obsView.js +109 -0
- package/dist/obsView.js.map +1 -0
- package/dist/router/Navigator.d.ts +18 -0
- package/dist/router/Navigator.d.ts.map +1 -0
- package/dist/router/Navigator.js +35 -0
- package/dist/router/Navigator.js.map +1 -0
- package/dist/router/Path.d.ts +23 -0
- package/dist/router/Path.d.ts.map +1 -0
- package/dist/router/Path.js +63 -0
- package/dist/router/Path.js.map +1 -0
- package/dist/router/PathPattern.d.ts +15 -0
- package/dist/router/PathPattern.d.ts.map +1 -0
- package/dist/router/PathPattern.js +88 -0
- package/dist/router/PathPattern.js.map +1 -0
- package/dist/router/Route.d.ts +35 -0
- package/dist/router/Route.d.ts.map +1 -0
- package/dist/router/Route.js +63 -0
- package/dist/router/Route.js.map +1 -0
- package/dist/router/Router.d.ts +16 -0
- package/dist/router/Router.d.ts.map +1 -0
- package/dist/router/Router.js +37 -0
- package/dist/router/Router.js.map +1 -0
- package/dist/router/index.d.ts +10 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/utils.d.ts +8 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +14 -0
- package/dist/utils.js.map +1 -0
- package/dist/view.d.ts +9 -0
- package/dist/view.d.ts.map +1 -0
- package/dist/view.js +27 -0
- package/dist/view.js.map +1 -0
- package/dist/viewModel.d.ts +33 -0
- package/dist/viewModel.d.ts.map +1 -0
- package/dist/viewModel.js +36 -0
- package/dist/viewModel.js.map +1 -0
- package/dist/viewWithModel.d.ts +30 -0
- package/dist/viewWithModel.d.ts.map +1 -0
- package/dist/viewWithModel.js +50 -0
- package/dist/viewWithModel.js.map +1 -0
- package/package.json +72 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Microsoft Corporation.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
# @vscode/observables-react
|
|
2
|
+
|
|
3
|
+
React bindings for `@vscode/observables`. Provides patterns for building reactive React components with observable state.
|
|
4
|
+
|
|
5
|
+
> **Note:** React Strict Mode is not supported.
|
|
6
|
+
|
|
7
|
+
<!-- @codeblock-config
|
|
8
|
+
outDir: readme-codeblock-examples/out
|
|
9
|
+
-->
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @vscode/observables @vscode/observables-react
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Core Patterns
|
|
18
|
+
|
|
19
|
+
### viewWithModel - The ViewModel Pattern
|
|
20
|
+
|
|
21
|
+
The recommended way to build components with observable state:
|
|
22
|
+
|
|
23
|
+
<!-- @codeblock
|
|
24
|
+
file: counter.tsx
|
|
25
|
+
postfix: |
|
|
26
|
+
export { Counter, CounterModel };
|
|
27
|
+
additionalFiles:
|
|
28
|
+
- suffix: .playwright-spec.tsx
|
|
29
|
+
content: |
|
|
30
|
+
import { test, expect } from '@playwright/experimental-ct-react';
|
|
31
|
+
import { Counter } from './counter';
|
|
32
|
+
|
|
33
|
+
test('counter increments and shows doubled value', async ({ mount }) => {
|
|
34
|
+
const component = await mount(<Counter initialCount={5} label="Score" />);
|
|
35
|
+
await expect(component).toContainText('Score: 5');
|
|
36
|
+
await expect(component).toContainText('Doubled: 10');
|
|
37
|
+
await component.getByRole('button', { name: '+' }).click();
|
|
38
|
+
await expect(component).toContainText('Score: 6');
|
|
39
|
+
await expect(component).toContainText('Doubled: 12');
|
|
40
|
+
});
|
|
41
|
+
-->
|
|
42
|
+
```tsx
|
|
43
|
+
import { observableValue, derived, IReader } from '@vscode/observables';
|
|
44
|
+
import { ViewModel, viewWithModel, prop } from '@vscode/observables-react';
|
|
45
|
+
|
|
46
|
+
class CounterModel extends ViewModel({ initialCount: prop.const<number>() }) {
|
|
47
|
+
public readonly count = observableValue(this, this.props.initialCount);
|
|
48
|
+
public readonly doubled = derived(this, reader => this.count.read(reader) * 2);
|
|
49
|
+
|
|
50
|
+
increment = () => this.count.set(this.count.get() + 1, undefined);
|
|
51
|
+
|
|
52
|
+
override dispose(): void {
|
|
53
|
+
// cleanup
|
|
54
|
+
super.dispose();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const Counter = viewWithModel(CounterModel, { label: prop<string>() }, (reader, model, props) => (
|
|
59
|
+
<div>
|
|
60
|
+
<span>{props.label.read(reader)}: {model.count.read(reader)}</span>
|
|
61
|
+
<span>Doubled: {model.doubled.read(reader)}</span>
|
|
62
|
+
<button onClick={model.increment}>+</button>
|
|
63
|
+
</div>
|
|
64
|
+
)
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
// Usage - both ViewModel props (initialCount) and view props (label) are merged
|
|
68
|
+
const example = <Counter initialCount={10} label="Score" />;
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### view - Observable Props
|
|
72
|
+
|
|
73
|
+
Create components with typed observable props:
|
|
74
|
+
|
|
75
|
+
<!-- @codeblock display.tsx -->
|
|
76
|
+
```tsx
|
|
77
|
+
import { view, prop } from '@vscode/observables-react';
|
|
78
|
+
|
|
79
|
+
const Display = view(
|
|
80
|
+
{
|
|
81
|
+
label: prop<string>(),
|
|
82
|
+
count: prop<number>(),
|
|
83
|
+
},
|
|
84
|
+
(reader, props) => (
|
|
85
|
+
<div>
|
|
86
|
+
<span>{props.label.read(reader)}</span>
|
|
87
|
+
<span>{props.count.read(reader)}</span>
|
|
88
|
+
</div>
|
|
89
|
+
)
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
// Usage
|
|
93
|
+
const example = <Display label="Total" count={42} />;
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### ObsView - Inline Observable Rendering
|
|
97
|
+
|
|
98
|
+
For embedding observable values in existing components:
|
|
99
|
+
|
|
100
|
+
<!-- @codeblock obsview.tsx -->
|
|
101
|
+
```tsx
|
|
102
|
+
import { observableValue } from '@vscode/observables';
|
|
103
|
+
import { ObsView } from '@vscode/observables-react';
|
|
104
|
+
|
|
105
|
+
const count = observableValue('count', 0);
|
|
106
|
+
|
|
107
|
+
function App() {
|
|
108
|
+
return (
|
|
109
|
+
<div>
|
|
110
|
+
<ObsView>{reader => <span>{count.read(reader)}</span>}</ObsView>
|
|
111
|
+
<button onClick={() => count.set(count.get() + 1, undefined)}>+</button>
|
|
112
|
+
</div>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### val - Observable to JSX Helper
|
|
118
|
+
|
|
119
|
+
Render an observable value inline:
|
|
120
|
+
|
|
121
|
+
<!-- @codeblock val.tsx -->
|
|
122
|
+
```tsx
|
|
123
|
+
import { observableValue } from '@vscode/observables';
|
|
124
|
+
import { val } from '@vscode/observables-react';
|
|
125
|
+
|
|
126
|
+
const message = observableValue('msg', 'Hello');
|
|
127
|
+
|
|
128
|
+
function App() {
|
|
129
|
+
return <div>{val(message)}</div>;
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Property Transformers
|
|
134
|
+
|
|
135
|
+
Property transformers control how props are passed to `view`, `viewWithModel`, and `ViewModel`. They define both the input type (what React receives) and the output type (what your render function or ViewModel sees).
|
|
136
|
+
|
|
137
|
+
### For `view` and `viewWithModel` props
|
|
138
|
+
|
|
139
|
+
<!-- @codeblock property-transformers.tsx -->
|
|
140
|
+
```tsx
|
|
141
|
+
import { view, prop } from '@vscode/observables-react';
|
|
142
|
+
|
|
143
|
+
const MyComponent = view(
|
|
144
|
+
{
|
|
145
|
+
// prop<T>() - input: T, output: IObservable<T>
|
|
146
|
+
// No re-render when value changes, read via observable
|
|
147
|
+
name: prop<string>(),
|
|
148
|
+
|
|
149
|
+
// prop.const<T>() - input: T, output: T
|
|
150
|
+
// Re-renders when value changes, available directly
|
|
151
|
+
label: prop.const<string>(),
|
|
152
|
+
|
|
153
|
+
// prop.obs<T>() - input: T | IObservable<T>, output: IObservable<T>
|
|
154
|
+
// Accepts either, normalizes to observable (slightly more expensive)
|
|
155
|
+
value: prop.obs<number>(),
|
|
156
|
+
},
|
|
157
|
+
(reader, props) => (
|
|
158
|
+
<div>
|
|
159
|
+
<span>{props.name.read(reader)}</span>
|
|
160
|
+
<span>{props.label}</span>
|
|
161
|
+
<span>{props.value.read(reader)}</span>
|
|
162
|
+
</div>
|
|
163
|
+
)
|
|
164
|
+
);
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### For `ViewModel` constructor props
|
|
168
|
+
|
|
169
|
+
The same transformers work in `ViewModel()`, making them available via `this.props`:
|
|
170
|
+
|
|
171
|
+
- `prop.const<T>()` - When the value changes, the **ViewModel is disposed and recreated**. Use for identity/key-like props. Has a slight performance advantage when the value is not expected to change (no observable wrapper).
|
|
172
|
+
- `prop<T>()` - Changes update the observable without recreating the ViewModel. Use for values that change during the ViewModel's lifetime.
|
|
173
|
+
|
|
174
|
+
<!-- @codeblock
|
|
175
|
+
file: viewmodel-props.tsx
|
|
176
|
+
prefix: |
|
|
177
|
+
import { observableValue, IObservable } from '@vscode/observables';
|
|
178
|
+
import { ViewModel, prop } from '@vscode/observables-react';
|
|
179
|
+
-->
|
|
180
|
+
```tsx
|
|
181
|
+
class MyModel extends ViewModel({
|
|
182
|
+
initialValue: prop.const<number>(), // if this changes, MyModel is recreated
|
|
183
|
+
config: prop<string>(), // changes update this.props.config observable
|
|
184
|
+
}) {
|
|
185
|
+
readonly value = observableValue(this, this.props.initialValue);
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### `inject` - DI transformer for ViewModels
|
|
190
|
+
|
|
191
|
+
`inject(key)` is a special transformer that resolves a service from the DI container:
|
|
192
|
+
|
|
193
|
+
<!-- @codeblock
|
|
194
|
+
file: inject-snippet.tsx
|
|
195
|
+
prefix: |
|
|
196
|
+
import { observableValue } from '@vscode/observables';
|
|
197
|
+
import { ViewModel, inject, createServiceKey } from '@vscode/observables-react';
|
|
198
|
+
class AppModel {
|
|
199
|
+
userName = observableValue(this, '');
|
|
200
|
+
login = (_userName: string) => {};
|
|
201
|
+
}
|
|
202
|
+
-->
|
|
203
|
+
```tsx
|
|
204
|
+
const $AppModel = createServiceKey(AppModel);
|
|
205
|
+
|
|
206
|
+
class LoginViewModel extends ViewModel({
|
|
207
|
+
appModel: inject($AppModel), // resolved from DIContainer, available as this.props.appModel
|
|
208
|
+
}) {
|
|
209
|
+
public readonly userName = observableValue(this, '');
|
|
210
|
+
login = () => this.props.appModel.login(this.userName.get());
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
- Input: optional (can be passed explicitly for testing)
|
|
215
|
+
- Output: the service instance
|
|
216
|
+
- Requires a `DIProvider` ancestor in the component tree
|
|
217
|
+
|
|
218
|
+
## Dependency Injection
|
|
219
|
+
|
|
220
|
+
Built-in DI support for ViewModels:
|
|
221
|
+
|
|
222
|
+
<!-- @codeblock di.tsx -->
|
|
223
|
+
```tsx
|
|
224
|
+
import { observableValue } from '@vscode/observables';
|
|
225
|
+
import {
|
|
226
|
+
createServiceKey, DIContainer, DIProvider, inject,
|
|
227
|
+
ViewModel, viewWithModel
|
|
228
|
+
} from '@vscode/observables-react';
|
|
229
|
+
|
|
230
|
+
// The AppModel, for simple apps the central piece for the business logic
|
|
231
|
+
class AppModel {
|
|
232
|
+
public readonly currentUser = observableValue<string | undefined>(this, undefined);
|
|
233
|
+
login = (userName: string) => this.currentUser.set(userName, undefined);
|
|
234
|
+
dispose() {} // Required for DisposableStore
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const $AppModel = createServiceKey(AppModel);
|
|
238
|
+
|
|
239
|
+
// RootViewModel - sets up DI and provides services.
|
|
240
|
+
class RootViewModel extends ViewModel() {
|
|
241
|
+
private readonly _appModel = this._store.add(new AppModel());
|
|
242
|
+
public readonly container = new DIContainer()
|
|
243
|
+
.register($AppModel, this._appModel);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// use `inject` to get the instance. It's private to the view model.
|
|
247
|
+
// The view model acts as an isolating bridge between the app model and the view.
|
|
248
|
+
class LoginViewModel extends ViewModel({ appModel: inject($AppModel) }) {
|
|
249
|
+
public readonly userName = observableValue(this, '');
|
|
250
|
+
login = () => this.props.appModel.login(this.userName.get());
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Root component provides DI context
|
|
254
|
+
const Root = viewWithModel(RootViewModel, (_reader, model) => (
|
|
255
|
+
<DIProvider container={model.container}>
|
|
256
|
+
<LoginPage />
|
|
257
|
+
</DIProvider>
|
|
258
|
+
));
|
|
259
|
+
|
|
260
|
+
const LoginPage = viewWithModel(LoginViewModel, (reader, model) => (
|
|
261
|
+
<div>
|
|
262
|
+
<input
|
|
263
|
+
value={model.userName.read(reader)}
|
|
264
|
+
onChange={e => model.userName.set(e.target.value, undefined)}
|
|
265
|
+
/>
|
|
266
|
+
<button onClick={model.login}>Login</button>
|
|
267
|
+
</div>
|
|
268
|
+
));
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Testing with Mock ViewModels
|
|
272
|
+
|
|
273
|
+
Override ViewModel instances for testing:
|
|
274
|
+
|
|
275
|
+
<!-- @codeblock
|
|
276
|
+
file: testing.tsx
|
|
277
|
+
prefix: |
|
|
278
|
+
import { observableValue, derived } from '@vscode/observables';
|
|
279
|
+
import { ViewModel, viewWithModel, prop, ProvideMockViewModels, mockViewModel } from '@vscode/observables-react';
|
|
280
|
+
|
|
281
|
+
class CounterModel extends ViewModel({ initialCount: prop.const<number>() }) {
|
|
282
|
+
public readonly count = observableValue(this, this.props.initialCount);
|
|
283
|
+
increment = () => this.count.set(this.count.get() + 1, undefined);
|
|
284
|
+
}
|
|
285
|
+
const Counter = viewWithModel(CounterModel, (reader, model) => (
|
|
286
|
+
<div><span>{model.count.read(reader)}</span></div>
|
|
287
|
+
));
|
|
288
|
+
-->
|
|
289
|
+
```tsx
|
|
290
|
+
const mockModel = new CounterModel({ initialCount: 0 });
|
|
291
|
+
mockModel.count.set(42, undefined);
|
|
292
|
+
|
|
293
|
+
const example = (
|
|
294
|
+
<ProvideMockViewModels mocks={[mockViewModel(CounterModel, mockModel)]}>
|
|
295
|
+
<Counter initialCount={0} />
|
|
296
|
+
</ProvideMockViewModels>
|
|
297
|
+
);
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Router (Experimental)
|
|
301
|
+
|
|
302
|
+
Type-safe routing utilities:
|
|
303
|
+
|
|
304
|
+
<!-- @codeblock router.tsx -->
|
|
305
|
+
```tsx
|
|
306
|
+
import { Route, Router } from '@vscode/observables-react';
|
|
307
|
+
|
|
308
|
+
const homeRoute = Route.create('/');
|
|
309
|
+
const userRoute = Route.create('/users/:id', { id: 'string' });
|
|
310
|
+
|
|
311
|
+
const router = Router.create<string>()
|
|
312
|
+
.with(homeRoute, () => 'home')
|
|
313
|
+
.with(userRoute, (args) => `user-${args.id}`);
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
## API Reference
|
|
317
|
+
|
|
318
|
+
### Components & Views
|
|
319
|
+
|
|
320
|
+
- `viewWithModel(ModelClass, props, render)` - Create component with ViewModel
|
|
321
|
+
- `view(props, render)` - Create component with observable props
|
|
322
|
+
- `ObsView` - Inline observable rendering component
|
|
323
|
+
- `Value` - Render observable as component
|
|
324
|
+
- `val(observable)` - Render observable inline
|
|
325
|
+
|
|
326
|
+
### ViewModel
|
|
327
|
+
|
|
328
|
+
- `ViewModel(props)` - Base class factory for ViewModels
|
|
329
|
+
- `BaseViewModel` - Base class with disposable store
|
|
330
|
+
- `ProvideMockViewModels` - Override multiple ViewModels for testing
|
|
331
|
+
- `mockViewModel(Class, instance)` - Create mock binding for ProvideMockViewModels
|
|
332
|
+
- `ProvideViewModel` - Override single ViewModel for testing (low-level)
|
|
333
|
+
|
|
334
|
+
### Property Transformers
|
|
335
|
+
|
|
336
|
+
- `prop<T>()` - Transform to `IObservable<T>`
|
|
337
|
+
- `prop.const<T>()` - Pass through as `T`
|
|
338
|
+
- `prop.obs<T>()` - Normalize to `IObservable<T>`
|
|
339
|
+
|
|
340
|
+
### Dependency Injection
|
|
341
|
+
|
|
342
|
+
- `createServiceKey<T>(name)` or `createServiceKey(Class)` - Create typed service identifier
|
|
343
|
+
- `DIContainer` - Service container
|
|
344
|
+
- `DIProvider` - React context provider
|
|
345
|
+
- `inject(key)` - Property transformer for injection
|
|
346
|
+
|
|
347
|
+
## License
|
|
348
|
+
|
|
349
|
+
MIT
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { IObservable, IReader } from "@vscode/observables";
|
|
2
|
+
import { Context } from "react";
|
|
3
|
+
export type Readable<T> = (reader: IReader) => T;
|
|
4
|
+
export interface IReadableObj<T> {
|
|
5
|
+
/**
|
|
6
|
+
* The reader of the component.
|
|
7
|
+
*/
|
|
8
|
+
read(reader: IReader): T;
|
|
9
|
+
}
|
|
10
|
+
export interface IPropertyTransformerFactory<TIn, TOut> {
|
|
11
|
+
/** If set, this context's value is passed to create() */
|
|
12
|
+
readonly _requiredContext?: Context<unknown>;
|
|
13
|
+
/** @param contextValue - value of _requiredContext if declared, otherwise undefined */
|
|
14
|
+
create(readable: Readable<TIn>, contextValue: unknown): IReadableObj<TOut>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Takes a value of type `T` and makes it available as `IObservable<T>`.
|
|
18
|
+
* When it changes, the component will not re-render.
|
|
19
|
+
*/
|
|
20
|
+
export declare function prop<T>(): IPropertyTransformerFactory<T, IObservable<T>>;
|
|
21
|
+
export declare namespace prop {
|
|
22
|
+
var _a: typeof propConst;
|
|
23
|
+
export var obs: typeof propObs;
|
|
24
|
+
export { _a as const };
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Takes a value of type `T` and makes it available as `T`.
|
|
28
|
+
* When it changes, the component will re-render.
|
|
29
|
+
*/
|
|
30
|
+
declare function propConst<T>(): IPropertyTransformerFactory<T, T>;
|
|
31
|
+
/**
|
|
32
|
+
* Takes a value of type `T` or `IObservable<T>` and makes it available as `IObservable<T>`.
|
|
33
|
+
* When it changes, the component will not re-render.
|
|
34
|
+
*/
|
|
35
|
+
declare function propObs<T>(): IPropertyTransformerFactory<T | IObservable<T>, IObservable<T>>;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=IPropertyTransformer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IPropertyTransformer.d.ts","sourceRoot":"","sources":["../src/IPropertyTransformer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,WAAW,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEhC,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,KAAK,CAAC,CAAC;AAEjD,MAAM,WAAW,YAAY,CAAC,CAAC;IAC3B;;MAEE;IACF,IAAI,CAAC,MAAM,EAAE,OAAO,GAAG,CAAC,CAAC;CAC5B;AAED,MAAM,WAAW,2BAA2B,CAAC,GAAG,EAAE,IAAI;IAClD,yDAAyD;IACzD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,uFAAuF;IACvF,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,YAAY,EAAE,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;CAC9E;AAED;;;GAGG;AACH,wBAAgB,IAAI,CAAC,CAAC,KAAK,2BAA2B,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAExE;yBAFe,IAAI;;;;;AAIpB;;;GAGG;AACH,iBAAS,SAAS,CAAC,CAAC,KAAK,2BAA2B,CAAC,CAAC,EAAE,CAAC,CAAC,CAEzD;AAED;;;GAGG;AACH,iBAAS,OAAO,CAAC,CAAC,KAAK,2BAA2B,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAErF"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { derived } from '@vscode/observables';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Takes a value of type `T` and makes it available as `IObservable<T>`.
|
|
9
|
+
* When it changes, the component will not re-render.
|
|
10
|
+
*/
|
|
11
|
+
function prop() {
|
|
12
|
+
return PropertyTransformerFactory.instance;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Takes a value of type `T` and makes it available as `T`.
|
|
16
|
+
* When it changes, the component will re-render.
|
|
17
|
+
*/
|
|
18
|
+
function propConst() {
|
|
19
|
+
return PropertyConstTransformerFactory.instance;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Takes a value of type `T` or `IObservable<T>` and makes it available as `IObservable<T>`.
|
|
23
|
+
* When it changes, the component will not re-render.
|
|
24
|
+
*/
|
|
25
|
+
function propObs() {
|
|
26
|
+
return PropertyObsTransformerFactory.instance;
|
|
27
|
+
}
|
|
28
|
+
prop.const = propConst;
|
|
29
|
+
prop.obs = propObs;
|
|
30
|
+
class PropertyTransformerFactory {
|
|
31
|
+
create(readableProp) {
|
|
32
|
+
const d = derived(reader => readableProp(reader));
|
|
33
|
+
return { read: (_reader) => d };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
PropertyTransformerFactory.instance = new PropertyTransformerFactory();
|
|
37
|
+
class PropertyConstTransformerFactory {
|
|
38
|
+
create(readableProp) {
|
|
39
|
+
const d = derived(reader => readableProp(reader));
|
|
40
|
+
return { read: (reader) => d.read(reader) };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
PropertyConstTransformerFactory.instance = new PropertyConstTransformerFactory();
|
|
44
|
+
class PropertyObsTransformerFactory {
|
|
45
|
+
create(readableProp) {
|
|
46
|
+
const d = derived(reader => {
|
|
47
|
+
const v = readableProp(reader);
|
|
48
|
+
if (isObservable(v)) {
|
|
49
|
+
return v.read(reader);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
return v;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
return { read: (_reader) => d };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
PropertyObsTransformerFactory.instance = new PropertyObsTransformerFactory();
|
|
59
|
+
function isObservable(obs) {
|
|
60
|
+
return typeof obs === "object" && obs !== null && "read" in obs;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export { prop };
|
|
64
|
+
//# sourceMappingURL=IPropertyTransformer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IPropertyTransformer.js","sources":["../src/IPropertyTransformer.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;AAmBA;;;AAGG;SACa,IAAI,GAAA;IAChB,OAAO,0BAA0B,CAAC,QAAQ,CAAC;AAC/C,CAAC;AAED;;;AAGG;AACH,SAAS,SAAS,GAAA;IACd,OAAO,+BAA+B,CAAC,QAAQ,CAAC;AACpD,CAAC;AAED;;;AAGG;AACH,SAAS,OAAO,GAAA;IACZ,OAAO,6BAA6B,CAAC,QAAQ,CAAC;AAClD,CAAC;AAED,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;AACvB,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC;AAEnB,MAAM,0BAA0B,CAAA;AAG5B,IAAA,MAAM,CAAC,YAAyB,EAAA;AAC5B,QAAA,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;QAClD,OAAO,EAAE,IAAI,EAAE,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;KACnC;;AALsB,0BAAA,CAAA,QAAQ,GAAG,IAAI,0BAA0B,EAAO,CAAC;AAQ5E,MAAM,+BAA+B,CAAA;AAGjC,IAAA,MAAM,CAAC,YAAyB,EAAA;AAC5B,QAAA,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;AAClD,QAAA,OAAO,EAAE,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;KAC/C;;AALsB,+BAAA,CAAA,QAAQ,GAAG,IAAI,+BAA+B,EAAO,CAAC;AAQjF,MAAM,6BAA6B,CAAA;AAG/B,IAAA,MAAM,CAAC,YAA0C,EAAA;AAC7C,QAAA,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,IAAG;AACvB,YAAA,MAAM,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;AAC/B,YAAA,IAAI,YAAY,CAAC,CAAC,CAAC,EAAE;AACjB,gBAAA,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;aACzB;iBAAM;AACH,gBAAA,OAAO,CAAC,CAAC;aACZ;AACL,SAAC,CAAC,CAAC;QACH,OAAO,EAAE,IAAI,EAAE,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;KACnC;;AAZsB,6BAAA,CAAA,QAAQ,GAAG,IAAI,6BAA6B,EAAO,CAAC;AAe/E,SAAS,YAAY,CAAC,GAAQ,EAAA;AAC1B,IAAA,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,MAAM,IAAI,GAAG,CAAC;AACpE;;;;"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IObservable, IObservableWithChange, IObserver, IDisposable } from "@vscode/observables";
|
|
2
|
+
export declare class ManualChangesHandler<TData> implements IObserver {
|
|
3
|
+
readonly _run: (changes: TData[]) => void;
|
|
4
|
+
private _changes;
|
|
5
|
+
private readonly _map;
|
|
6
|
+
constructor(_run: (changes: TData[]) => void);
|
|
7
|
+
addDependency(observable: IObservable<any>, data: TData): IDisposable;
|
|
8
|
+
private _updateCounter;
|
|
9
|
+
beginUpdate<T>(observable: IObservableWithChange<T, unknown>): void;
|
|
10
|
+
endUpdate<T>(_observable: IObservableWithChange<T, unknown>): void;
|
|
11
|
+
handlePossibleChange<T>(observable: IObservableWithChange<T, unknown>): void;
|
|
12
|
+
handleChange<T, TChange>(_observable: IObservableWithChange<T, TChange>, _change: TChange): void;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=ManualChangesHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ManualChangesHandler.d.ts","sourceRoot":"","sources":["../src/ManualChangesHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEjG,qBAAa,oBAAoB,CAAC,KAAK,CAAE,YAAW,SAAS;aAK3C,IAAI,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,IAAI;IAJjD,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAsC;gBAG1C,IAAI,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,IAAI;IAGjD,aAAa,CAAC,UAAU,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,GAAG,WAAW;IAUrE,OAAO,CAAC,cAAc,CAAK;IAE3B,WAAW,CAAC,CAAC,EAAE,UAAU,EAAE,qBAAqB,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,IAAI;IAKnE,SAAS,CAAC,CAAC,EAAE,WAAW,EAAE,qBAAqB,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,IAAI;IAWlE,oBAAoB,CAAC,CAAC,EAAE,UAAU,EAAE,qBAAqB,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,IAAI;IAI5E,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,qBAAqB,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;CAGhG"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
class ManualChangesHandler {
|
|
6
|
+
constructor(_run) {
|
|
7
|
+
this._run = _run;
|
|
8
|
+
this._changes = [];
|
|
9
|
+
this._map = new Map();
|
|
10
|
+
this._updateCounter = 0;
|
|
11
|
+
}
|
|
12
|
+
addDependency(observable, data) {
|
|
13
|
+
this._map.set(observable, data);
|
|
14
|
+
observable.addObserver(this);
|
|
15
|
+
return {
|
|
16
|
+
dispose: () => {
|
|
17
|
+
this._map.delete(observable);
|
|
18
|
+
observable.removeObserver(this);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
beginUpdate(observable) {
|
|
23
|
+
this._updateCounter++;
|
|
24
|
+
this._changes.push(this._map.get(observable));
|
|
25
|
+
}
|
|
26
|
+
endUpdate(_observable) {
|
|
27
|
+
this._updateCounter--;
|
|
28
|
+
if (this._updateCounter === 0) {
|
|
29
|
+
if (this._changes.length > 0) {
|
|
30
|
+
const c = this._changes;
|
|
31
|
+
this._changes = [];
|
|
32
|
+
this._run(c);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
handlePossibleChange(observable) {
|
|
37
|
+
this._changes.push(this._map.get(observable));
|
|
38
|
+
}
|
|
39
|
+
handleChange(_observable, _change) {
|
|
40
|
+
//this._changes.push(this._map.get(observable)!);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export { ManualChangesHandler };
|
|
45
|
+
//# sourceMappingURL=ManualChangesHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ManualChangesHandler.js","sources":["../src/ManualChangesHandler.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;MAEa,oBAAoB,CAAA;AAIhC,IAAA,WAAA,CACiB,IAAgC,EAAA;QAAhC,IAAI,CAAA,IAAA,GAAJ,IAAI,CAA4B;QAJzC,IAAQ,CAAA,QAAA,GAAY,EAAE,CAAC;AACd,QAAA,IAAA,CAAA,IAAI,GAAG,IAAI,GAAG,EAA2B,CAAC;QAgBnD,IAAc,CAAA,cAAA,GAAG,CAAC,CAAC;KAZtB;IAEL,aAAa,CAAC,UAA4B,EAAE,IAAW,EAAA;QACtD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AAChC,QAAA,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC7B,OAAO;YACN,OAAO,EAAE,MAAK;AACb,gBAAA,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;AAC7B,gBAAA,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;aAChC;SACD,CAAC;KACF;AAGD,IAAA,WAAW,CAAI,UAA6C,EAAA;QAC3D,IAAI,CAAC,cAAc,EAAE,CAAC;AACtB,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAE,CAAC,CAAC;KAC/C;AAED,IAAA,SAAS,CAAI,WAA8C,EAAA;QAC1D,IAAI,CAAC,cAAc,EAAE,CAAC;AACtB,QAAA,IAAI,IAAI,CAAC,cAAc,KAAK,CAAC,EAAE;YAC9B,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;AAC7B,gBAAA,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;AACxB,gBAAA,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;AACnB,gBAAA,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aACb;SACD;KACD;AAED,IAAA,oBAAoB,CAAI,UAA6C,EAAA;AACpE,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAE,CAAC,CAAC;KAC/C;IAED,YAAY,CAAa,WAA8C,EAAE,OAAgB,EAAA;;KAExF;AACD;;;;"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Context, ReactNode } from "react";
|
|
2
|
+
import { ViewModelContextSymbol } from "./viewModel";
|
|
3
|
+
/**
|
|
4
|
+
* Provider component to override a ViewModel instance.
|
|
5
|
+
* Useful for testing - allows injecting a mock ViewModel.
|
|
6
|
+
*/
|
|
7
|
+
export declare function ProvideViewModel<T>({ viewModel: ViewModelClass, value, children }: {
|
|
8
|
+
viewModel: {
|
|
9
|
+
[ViewModelContextSymbol]?: Context<T | undefined>;
|
|
10
|
+
};
|
|
11
|
+
value: T;
|
|
12
|
+
children: ReactNode;
|
|
13
|
+
}): ReactNode;
|
|
14
|
+
/**
|
|
15
|
+
* Represents a mock binding of a ViewModel class to an instance.
|
|
16
|
+
*/
|
|
17
|
+
export interface ViewModelMock {
|
|
18
|
+
readonly _provide: (children: ReactNode) => ReactNode;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Creates a mock binding for use with ProvideMockViewModels.
|
|
22
|
+
*/
|
|
23
|
+
export declare function mockViewModel<T>(viewModelClass: {
|
|
24
|
+
[ViewModelContextSymbol]?: Context<T | undefined>;
|
|
25
|
+
}, instance: T): ViewModelMock;
|
|
26
|
+
/**
|
|
27
|
+
* Provider component to override multiple ViewModel instances at once.
|
|
28
|
+
* Useful for testing - allows injecting multiple mock ViewModels.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```tsx
|
|
32
|
+
* <ProvideMockViewModels mocks={[mockViewModel(AppPageViewModel, fakeViewModel)]}>
|
|
33
|
+
* <AppPage theme="light" />
|
|
34
|
+
* </ProvideMockViewModels>
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function ProvideMockViewModels({ mocks, children }: {
|
|
38
|
+
mocks: ViewModelMock[];
|
|
39
|
+
children: ReactNode;
|
|
40
|
+
}): ReactNode;
|
|
41
|
+
//# sourceMappingURL=ProvideViewModel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProvideViewModel.d.ts","sourceRoot":"","sources":["../src/ProvideViewModel.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,EAAE,sBAAsB,EAA+B,MAAM,aAAa,CAAC;AAElF;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,EAChC,SAAS,EAAE,cAAc,EACzB,KAAK,EACL,QAAQ,EACX,EAAE;IACC,SAAS,EAAE;QAAE,CAAC,sBAAsB,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAA;KAAE,CAAC;IACjE,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,EAAE,SAAS,CAAC;CACvB,GAAG,SAAS,CAGZ;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,SAAS,KAAK,SAAS,CAAC;CACzD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAC3B,cAAc,EAAE;IAAE,CAAC,sBAAsB,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAA;CAAE,EACrE,QAAQ,EAAE,CAAC,GACZ,aAAa,CAKf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,EAClC,KAAK,EACL,QAAQ,EACX,EAAE;IACC,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,QAAQ,EAAE,SAAS,CAAC;CACvB,GAAG,SAAS,CAKZ"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { jsx } from 'react/jsx-runtime';
|
|
6
|
+
import { getOrCreateViewModelContext } from './viewModel.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Provider component to override a ViewModel instance.
|
|
10
|
+
* Useful for testing - allows injecting a mock ViewModel.
|
|
11
|
+
*/
|
|
12
|
+
function ProvideViewModel({ viewModel: ViewModelClass, value, children }) {
|
|
13
|
+
const ContextType = getOrCreateViewModelContext(ViewModelClass);
|
|
14
|
+
return jsx(ContextType.Provider, { value: value, children: children });
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Creates a mock binding for use with ProvideMockViewModels.
|
|
18
|
+
*/
|
|
19
|
+
function mockViewModel(viewModelClass, instance) {
|
|
20
|
+
const ContextType = getOrCreateViewModelContext(viewModelClass);
|
|
21
|
+
return {
|
|
22
|
+
_provide: children => jsx(ContextType.Provider, { value: instance, children: children }),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Provider component to override multiple ViewModel instances at once.
|
|
27
|
+
* Useful for testing - allows injecting multiple mock ViewModels.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```tsx
|
|
31
|
+
* <ProvideMockViewModels mocks={[mockViewModel(AppPageViewModel, fakeViewModel)]}>
|
|
32
|
+
* <AppPage theme="light" />
|
|
33
|
+
* </ProvideMockViewModels>
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
function ProvideMockViewModels({ mocks, children }) {
|
|
37
|
+
return mocks.reduceRight((acc, mock) => mock._provide(acc), children);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { ProvideMockViewModels, ProvideViewModel, mockViewModel };
|
|
41
|
+
//# sourceMappingURL=ProvideViewModel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProvideViewModel.js","sources":["../src/ProvideViewModel.tsx"],"sourcesContent":[null],"names":["_jsx"],"mappings":";;;;;;;AAGA;;;AAGG;AACG,SAAU,gBAAgB,CAAI,EAChC,SAAS,EAAE,cAAc,EACzB,KAAK,EACL,QAAQ,EAKX,EAAA;AACG,IAAA,MAAM,WAAW,GAAG,2BAA2B,CAAI,cAAc,CAAC,CAAC;IACnE,OAAOA,GAAA,CAAC,WAAW,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,KAAK,EAAA,QAAA,EAAG,QAAQ,EAAA,CAAwB,CAAC;AACjF,CAAC;AASD;;AAEG;AACa,SAAA,aAAa,CACzB,cAAqE,EACrE,QAAW,EAAA;AAEX,IAAA,MAAM,WAAW,GAAG,2BAA2B,CAAI,cAAc,CAAC,CAAC;IACnE,OAAO;AACH,QAAA,QAAQ,EAAE,QAAQ,IAAIA,GAAC,CAAA,WAAW,CAAC,QAAQ,IAAC,KAAK,EAAE,QAAQ,EAAA,QAAA,EAAG,QAAQ,EAAwB,CAAA;KACjG,CAAC;AACN,CAAC;AAED;;;;;;;;;;AAUG;SACa,qBAAqB,CAAC,EAClC,KAAK,EACL,QAAQ,EAIX,EAAA;IACG,OAAO,KAAK,CAAC,WAAW,CACpB,CAAC,GAAG,EAAE,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EACjC,QAAQ,CACX,CAAC;AACN;;;;"}
|
package/dist/Value.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { IObservable } from "@vscode/observables";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
/**
|
|
4
|
+
* A component that renders an observable ReactNode value.
|
|
5
|
+
* Re-renders when the observable changes.
|
|
6
|
+
* Usage: <Value value={myObservable} />
|
|
7
|
+
*/
|
|
8
|
+
export declare const Value: import("react").ComponentType<import("./viewModel").PropsIn<{
|
|
9
|
+
value: import("./IPropertyTransformer").IPropertyTransformerFactory<ReactNode | IObservable<ReactNode>, IObservable<ReactNode>>;
|
|
10
|
+
}>>;
|
|
11
|
+
/**
|
|
12
|
+
* Helper function to render an observable as inline JSX.
|
|
13
|
+
* Usage: {val(myObservable)}
|
|
14
|
+
*/
|
|
15
|
+
export declare function val(v: IObservable<ReactNode>): ReactNode;
|
|
16
|
+
//# sourceMappingURL=Value.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Value.d.ts","sourceRoot":"","sources":["../src/Value.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIlC;;;;GAIG;AACH,eAAO,MAAM,KAAK;;GAEhB,CAAC;AAEH;;;GAGG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,SAAS,CAAC,GAAG,SAAS,CAExD"}
|