Skip to content

Commit 9f9ac60

Browse files
committed
docs, types
1 parent 38f5383 commit 9f9ac60

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

README.md

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ const ColorPicker = (initial = [0, 0, 0]) => {
139139
`;
140140
};
141141

142+
// Render to the DOM
142143
document.getElementById('root-node').innerHTML = ColorPicker([255, 128, 64])
143144
```
144145

@@ -179,6 +180,7 @@ All Rimmel does is binding your observable streams to the UI in a seamless integ
179180
If you need to render something based on a condition, plain-old standard JS can help you. No further abstractions or custom DSLs are required:
180181

181182
```javascript
183+
// Render to the DOM
182184
document.body.innerHTML = rml`
183185
<main>
184186
${
@@ -210,6 +212,7 @@ const conditionalStream = new BehaviorSubject(0).pipe(
210212
})
211213
);
212214

215+
// Render to the DOM
213216
document.body.innerHTML = rml`
214217
<div>Count: ${conditionalStream}</div>
215218
<button onclick="${conditionalStream}">click me</button>
@@ -218,6 +221,25 @@ document.body.innerHTML = rml`
218221
219222
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/edit/rimmel-dynamic-conditional-rendering)
220223
224+
## No Build Tools 🔧
225+
Build tools can do a number of interesting things, but they're optional here, not a requirement.
226+
227+
You can always import the pre-built `rml` tag and use it in any Vanilla JS or microfrontend context:
228+
229+
```js
230+
import { rml } from "https://cdn.skypack.dev/rimmel";
231+
232+
// Define your streams
233+
const apiData = fetch('/api/data').then(r=>r.text());
234+
235+
// Render to the DOM
236+
document.body.innerHTML = rml`
237+
<p>Your reactive content here: ${apiData}</p>
238+
`;
239+
240+
```
241+
242+
221243
## No Lifecycle Events 🕢
222244
Component lifecycle events such as `onmount`, `beforeunmount`, present in most other imperative frameworks quickly become useless, redudant and discouraged here.
223245
Streams and other listeners get connected and disconnected automatically for you when a component is mounted/unmounted. If you think about it, this is exactly what you would normally do in your init/onmount functions, so you no longer have to deal with these tiny details.
@@ -249,8 +271,10 @@ All Observers such as event listener functions, Subjects and BehaviorSubjects wi
249271
### Examples:
250272
251273
```ts
252-
// Observable Subjects
274+
// Define your Observable Subjects
253275
const stream = new Subject<MouseEvent>();
276+
277+
// Bind/Render to the DOM
254278
target.innerHTML = rml`<button onclick="${stream}></button>`;
255279

256280

@@ -310,10 +334,12 @@ const datasetValue = map((e: Event) => Number(e.target.dataset.value));
310334
const buttonClick = filter((e: Event) => e.target.tagName == 'BUTTON');
311335

312336
const Component = () => {
337+
// Define your streams first
313338
const total = new Subject<number>().pipe(
314339
scan((a, b) => a+b, 0)
315340
);
316341

342+
// Then Bind/Render to the DOM
317343
return rml`
318344
<div onclick="${source(buttonClick, datasetValue, total)}">
319345
@@ -347,8 +373,10 @@ import { rml, Cut } from 'rimmel';
347373
import { Subject } from 'rxjs';
348374

349375
const Component = () => {
376+
// Define your streams first
350377
const stream1 = new Subject<string>();
351378

379+
// Then Bind/Render to the DOM
352380
return rml`
353381
<input onchange="${Cut(stream1)}"> <br>
354382
@@ -488,7 +516,7 @@ target.innerHTML = rml`<div>${UpperCase(stream)}</div>`;
488516
Dynamic sinks, on the other hand, are optimised for size and designed for convenience. They can take anyhing as input and figure out how to update the DOM at runtime.
489517
490518
491-
## Attribute Mixins
519+
## Attribute Mixins (Directives)
492520
Mixins are an exciting by-product of dynamic sinks, which allow you to inject pretty much anything at any time (event listeners, classes, attributes, etc) into an element by means of emitting an `Attribuend Object`­—a plain-old object whose properties and methods represent DOM attributes and event listeners to be merged in.
493521
494522
<br>
@@ -682,7 +710,7 @@ There are several collections on Stackblitz that can get you started, give you i
682710
[The Collection](https://stackblitz.com/@dariomannu/collections/rimmel-js-experiments) 🧞 Stream-Oriented programming examples using Rimmel.
683711

684712
### Experiments
685-
Cutting-edge things you can do with Rimmel. Still being refined here and there, but will show you where things are moving and bring some inspiration.
713+
This is the cutting-edge of what you can do with Rimmel, still being refined here and there, but will show you where things are going and maybe give you some inspiration.
686714

687715
[Web Components](https://stackblitz.com/@dariomannu/collections/web-components) 🧩 Experimental support for custom elements and web components in stream-oriented style.
688716

src/types/internal.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@ export interface BindingConfiguration {
2323
};
2424

2525
/**
26-
* This tells Rimmel how to bind an EventTarget to an event handler.
26+
* An object that specifies how to bind an EventTarget to an event handler.
2727
*
28-
* Objects of this type are normally returned by Source functions
28+
* Objects of this type are normally created by Source functions or
29+
* by the Rimmel parser based on the context
2930
*/
3031
export interface SourceBindingConfiguration<T extends RMLEventName> {
3132
type: 'source';
32-
listener: EventListenerOrEventListenerObject<EventType<T>>;
33+
listener: EventListenerOrEventListenerObject<EventType<T>> | Observer<EventType<T>>;
3334
options?: AddEventListenerOptions;
3435
eventName: RMLEventName;
3536
// error?: EventListener;

0 commit comments

Comments
 (0)