-
Notifications
You must be signed in to change notification settings - Fork 0
State
The state offers a way to create reactive values that can be used with tags to build dynamic and responsive web apps. This documentation will guide you through the usage of the state and listState function and its features.
When you create a state , it creates a Observable. Observables can then used across Cardboard for different things, take a look at the Observables guide to get a better understanding on how they work.
There are a couple of utilities that can help with manipulating list states.
Add item to array Observable.
const myList = state([]);
stateAdd(myList, 4); // Adds 4 to myListAdd item at index in array Observable.
const myList = state([]);
stateAddAr(myList, 4, 2); // Adds 4 to myList at index 2Remove item from array Observable.
const myList = state([1]);
stateRemove(myList, 1); // Removes item 1 from myListRemove item from array Observable.
const myList = state([1]);
stateRemove(myList, (item) => item == 1); // Removes item 1 from myListHere are some examples of how to use the state function and work with reactive state:
The simplest way of using the state is to make individual value states:
import { state } from 'cardboard-js/dist/cardboard.js';
const count = state(0);
// Listen to changes in the entire state
count.changed((count) => {
console.log('Count changed:', count);
});
// Modify the state and trigger change events
count.value++; // Increment the count
count.value = 3; // Set the count to 3
count.dispatch(3); // Set the count to 3You can create states with any value you like. For examples you can create a state with an object instead of a primitive.
import { state } from 'cardboard-js/dist/cardboard.js';
const { value, changed } = state({ count: 0 });
changed(({ count }) => { /* something in the object changed */ });
value.count++;
div('There are no items').hideIf(value.count); // Will be hidden when the list contains itemsAs mentioned above, you can also create array states:
const st = state([]);
st.value = [...st.value, 'new item'];
const hasItems = notEmpty(st);
div('There are no items').hideIf(hasItems); // Will be hidden when the list contains items
notEmptyis a built-in compute helper, this means it returns a new Observable that updates it's value when the statestchanges. It will tell you if the list is empty or not.
Take a look at "Computing" for a more detailed explanation.
You can also use each to render lists dinamically.
const colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'];
div(
each(colors, (color) =>
button(color).addStyle('color', color)
)
);You can conditionally/reactively change properties and do certain actions with tags. Like hiding an element, adding classes, etc... Take a look at Conditional Element Manipulation for more detailed explanations.
import { state } from 'cardboard-js/dist/cardboard.js';
const isLoading = state(true);
// Hide an element if isLoading is true
div().hideIf(isLoading);
// Disable an element if isLoading is true
div().disableIf(isLoading);
// Add class "loading" when isLoading is true, and add class "idle" when isLoading is false
div()
.classIf(isLoading, ['loading'])
.classIfNot(isLoading, ['idle'])
isLoading.value = false;You can also use state to reactively update text. Take a look at Managing Text for more detailed explanations.
import { state } from 'cardboard-js/dist/cardboard.js';
const st = state({ count: 0 });
// Create a div with a text that displays the count
div(text('Count is: $count', st));
div().text('Count is: $count', st);
div('Count is: ', st.count);For handling lists you can create a listState, which gives some extra utilities, like adding/removing items, getting the count (as a consumable), etc... It also makes items into Observables, this way you can interact with items in more complex ways.
List state returns a custom object instead of a Observable. It contains a list with the data, the length (as a Observable), and methods to modify the data. You can then use the list as explained here, and you can also add and remove items from the list.
import { listState } from './state.js';
const numbers = listState([1, 2]);
div(
each(numbers.list, (n) => p(`item ${n}`))
);
numbers.add(3);
numbers.remove(2);
numbers.addAt(4, 3);Any time the numbers change,
eachwill update the content accordingly.
Once you have created a reactive list using listState, you can use the following methods and properties to manage and access the list:
-
add(item: T): Adds an item to the end of the list.
-
item(T): The item to add to the list.
-
addAt(item: T, index: number): Adds an item at a specific index in the list.
-
item(T): The item to add to the list. -
index(number): The index at which to insert the item.
-
remove(item: T): Removes an item from the list based on the value.
-
item(T): The item to remove from the list.
-
removeWhere(cb: (item: T) => boolean): Removes items from the list based on a provided condition.
-
cb(Function): A callback function that returnstruefor items to be removed andfalsefor items to be retained.
-
list(Property): The underlying Observable. You can use this property to access the list directly. -
listValue(Property): A property that returns the current values of the reactive list as a regular array. -
length(Property): A Observable representing the current length of the list.
This Wiki is a work in progress, and your help is greatly appreciated!
If you have some free time and are interested in contributing to the wiki or the project in general, please don't hesitate to reach out. All contributions are welcome!