RHTML Experiments repo
npm install @rhtml/experimentsExperimental Components based on Monadic approach of building html blocks.
Declarative way of defining webcomponent via html itself.
In the future no javascript will present inside html only Functional components representing program behaviour
Monadic webcomponents are binded to following rules:
1. Monadadic webcomponents are like containers with scoped logic inside
2. Operators are empty pure components representing program settings
3. Monad container is creating composable logic based on operators provided inside his slot
4. Monad container will clean logic when composition is finished (removing operators from DOM Tree)
5. Rest of the program
#### Installation
``bash`
npm i @rhtml/experiments
#### Usage
`typescript`
import '@rhtml/experiments';
creation via html only`html
${s.pesho} | ${s.pesho2} | ${s.pesho3}
}>`
- - Monad container
- - Operator for r-component
- - Operator representing template for the webcomponent
- - Monadic container storing properties of the webcomponent
- - Monad working only inside r-props monad
- - Operator working only inside r-prop monad
- - Operator working only inside r-prop monad
We can represent this as a tree from top to bottom
1. r-component(Monad)(Stores logic for working with r-selector, r-template, r-props)r-selector
2. (Operator working with r-component monad)r-template
3. (Operator working with r-component monad)r-props
4. (Monad) (Stores logic for r-prop monad)r-prop
5. (Monad)(Stores logic for r-key and r-value composition)r-key
6. (Operator working inside r-prop monad)r-value
7. (Operator working inside r-prop monad)
`r-component
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ┌───────────────┐ │
│ │ │ │r-selector
│ │ ┌───────────┐ │ │
│ │ │ Monad │ │ - Stores logic for working with , r-template, r-props │ r-selector
│ │ └───────────┘ │ │
│ └───────────────┘ │
│ | │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ │ │ r-template │ │ r-props │ │r-component
│ │ ┌───────────┐ │ │ ┌───────────┐ │ │ ┌───────────┐ │ │
│ │ │ Operator │ │ │ │ Operator │ │ │ │ Monad │ │ - Components working with monad │r-props
│ │ └───────────┘ │ │ └───────────┘ │ │ └───────────┘ │ - Stores logic for r-prop monad │r-prop
│ └───────────────┘ └───────────────┘ └───────────────┘ │
│ | │
│ ┌───────────────┐ │
│ │ │ │r-props
│ │ ┌───────────┐ │ │
│ │ │ Monad │ │ - Monad working with monad │r-key
│ │ └───────────┘ │ │
│ └───────────────┘ │
│ | │
│ ┌───────────────┐ ┌───────────────┐ │
│ │ │ │ r-value │ │r-prop
│ │ ┌───────────┐ │ │ ┌───────────┐ │ │
│ │ │ Operator │ │ │ │ Operator │ │ -Operators working inside |`
│ │ └───────────┘ │ │ └───────────┘ │ │
│ └───────────────┘ └───────────────┘ │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────┘
1. r-render > state will be executed everytime when property is changedState
2. of the component can be changed with setState function exposed on second argumentsetState
3. function will trigger change detection only on properties defined inside r-props as r-prop with key and typeloading
4. There is a single predfined property called and it is set by default to true.
This property is important since it can be used to show loading information when long running job is executed
`html
Loading...
${value}
}>
`Can be used as follow:
`html
`
$3
Important aspect of usage is that components as a service are fire and forget what does that mean ?1. When component is initialized component will be
self destroyed with this.remove()
2. Once initialized inside the DOM Tree service component will fire run method and is no longer needed inside the dom tree
3. The run command is executed and our running job stay alive even after component is self removed
4. The idea to component be removed once initialized is in order to remove unused component from the DOM since we use it only for getting our data from backend(for example)User service
`ts
import { Component } from '@rxdi/lit-html';
import { LitServiceElement } from '@rhtml/experiments';import { of } from 'rxjs';
import { delay } from 'rxjs/operators';
@Component({
selector: 'user-service'
})
export class UserService extends LitServiceElement {
getUserById(id: number) {
return of({id, name: 'Kristyian Tachev'}).pipe(delay(2000)).toPromise()
}
}
`What is
LitServiceElement ? 1. A generic class defining 2 simple metods
run and OnUpdateFirst`ts
import { LitElement, property } from '@rxdi/lit-html';export class LitServiceElement extends LitElement {
@property({ type: Object })
run: (self: T) => void = () => null;
OnUpdateFirst() {
this.remove();
this.run.call(this);
}
}
`2. After that we can use our
webcomponent service like so:`ts
html
`Real world example
`ts
interface IUser {
id: number;
name: string;
}
interface IState {
userId: number;
user: IUser;
}
``html
void) => html User id: ${user.id}
User name: ${user.name}
}
>
`$3
`ts
import { Hydrate } from '@rhtml/experiments';
import { UserService } from './user.service'; / used only for typing purposes will not be included in bundle /const UserProfile = html
setState({
userId,
user: await this.getUserById(userId),
loading: false
});
}}
>
Loading...
User id: ${user.id}
User name: ${user.name}
}>;Hydrate(UserProfile);
export declare class UserProfileComponent extends LitElement {
userId: string;
}
declare global {
interface HTMLElementTagNameMap {
'user-profile': UserProfileComponent;
}
}
``html
``