Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/sebbekarlsson/plicit
Reactive UI framework
https://github.com/sebbekarlsson/plicit
frontend-framework jsx reactive ui ui-framework
Last synced: about 6 hours ago
JSON representation
Reactive UI framework
- Host: GitHub
- URL: https://github.com/sebbekarlsson/plicit
- Owner: sebbekarlsson
- Created: 2024-08-02T14:14:01.000Z (6 months ago)
- Default Branch: master
- Last Pushed: 2024-08-24T20:09:06.000Z (5 months ago)
- Last Synced: 2024-12-31T10:07:56.593Z (about 1 month ago)
- Topics: frontend-framework, jsx, reactive, ui, ui-framework
- Language: TypeScript
- Homepage:
- Size: 5.59 MB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
Plicit
A framework for building web user interfaces with explicitly defined reactivity---
#### Some unique features:
* You have full control over the reactivity.
> You decide if a singe property / attribute should be reactive, or if an entire component should be reactive.
* Reactivity is separated from the rendering.
> You can use reactivity "outside" of the component hierarchy.
* Asynchronous components and synchronous components are treated the same.
> You don't need to treat async components in some special way... ( No **\** needed! )---
## Reactivity
### Explicit Reactivity
While some implicit reactivity is supported, this framework aims to provide full control over
the reactivity by giving you the ability to be explicit about it.An example:
```tsx
const Counter = () => {
const count = signal(0)
return (
The counter is
{ computedSignal(() => {count.get()}) }
count.set(x => x + 1) }}>increment
)
}
```
> Here, we are explicitly saying the only one of the `` elements should react to changes.
> However, the dependencies are __automatically__ tracked.---
To summarize, we explicitly define an element to be reactive by wrapping it in a function.
Dependencies of a `signal` are automatically tracked.### Asynchronous Reactivity
Plicit has been developed with asynchronicity in mind.
Components can be async, as well as VDOM children.#### Async Components
```tsx
const HelloWorld = async () => {
await sleep(1000); // or do an API request or something :)
returnHello world!;
}const App = () => {
return
}
```
> Here, the `` component will begin rendering once the `sleep()` promise has been resolved.You can also define a "placeholder" to render while the component is loading:
```tsx
const App = () => {
return
Please wait...}/>
}
```
> Here's a good place to put a spinner or some other cool animation!#### Async VDOM children
```tsx
const App = () => {
return
{
asyncSignal(async () => {
await sleep(1000);
returnHello world!
}, { fallback: () => Please wait... })
}
}
```
> This will give you a similar result as the previous example,
> but instead of an async component, we're using an async signal.### Signals
As you might have noticed from the examples, signals are used for reactive states.
**If you're not familiar with signals**: a signal is basically a container for some data and it will automatically track other functions (or signals) who depends on it.#### Signals in Plicit
Signals in Plicit might differ a bit from other implementations, so let's go through some examples.##### Basic Counter
```typescript
const counter = signal(0);// This will be triggered everytime the counter is changed.
effect(() => console.log(counter.get()))counter.set((count) => count + 1)
```##### Computed
There is also something called __computed signals__ in Plicit, it's just a signal that transforms the value of another signal.
```typescript
const name = signal('John Doe');// will update everytime `name` is changed
const reversedName = computedSignal(() => Array.from(name.get()).reverse().join(''));// A computed signal can also be defined like this:
const reversedName = signal(() => name.get().reverse(), { isComputed: true });
```##### Async
An async signal works just like a regular signal, however it's able to be updated asynchronously.
```typescript
const products = asyncSignal(async () => {
const response = await fetch('https://somedomain.com/your/api/endpoint');
return await response.json();
});// You can check whether or not the signal has finished, either by inspecting it's state,
// or by having another signal react to it's changes.
// However, inspecting it's state is not reactive.// Reactive, will be triggered when the promise is resolved
const productNames = computedSignal(() => {
return (products.get() || []).map(product => product.name)
})// Not reactive
if (products.state === ESignalState.RESOLVED) { doSomething() }```
You can also provide a fallback value and the signal will return this value if it hasn't been resolved yet
```typescript
const products = asyncSignal(async () => {
const response = await fetch('https://somedomain.com/your/api/endpoint');
return await response.json();
}, { fallback: [] });
```---
## Getting Started
Simply run:
npx plicit-cli myapp && cd myapp && npm i && npm run dev
Now your app should be up and running!