### Basic Usage of Sprae Directives in HTML
Source: https://github.com/dy/sprae/blob/main/readme.md
Demonstrates a simple counter example using Sprae's reactive directives for text content and click events. It requires including the Sprae library via a script tag and uses the 'start' attribute for auto-initialization.
```html
```
--------------------------------
### Sprae Framework Basic Usage Example
Source: https://github.com/dy/sprae/blob/main/docs/index.html
This snippet demonstrates the basic usage of the Sprae framework, including initialization, event handling, and text binding. It requires including the Sprae library via a script tag.
```html
Count:
```
--------------------------------
### Automatic Sprae Initialization with `data-start`
Source: https://github.com/dy/sprae/blob/main/readme.md
The `start` attribute or `data-start` attribute on a script tag automatically initializes Sprae on the document. You can specify a selector in `data-start` to target a specific container for initialization. This simplifies setup for simple applications or for integrating Sprae into existing HTML.
```html
```
--------------------------------
### Initialize Sprae with JavaScript
Source: https://context7.com/dy/sprae/llms.txt
This JavaScript snippet demonstrates how to initialize Sprae.js and its features. It imports the necessary functions like 'sprae' or 'start' and defines the initial state for the application.
```javascript
import sprae from 'sprae'
const state = sprae(document.getElementById('app'), {
items: ['Apple', 'Banana', 'Cherry'],
user: { name: 'Alice', role: 'Admin', email: 'alice@example.com' }
})
state.items.push('Date') // Adds new item
state.items[0] = 'Apricot' // Updates existing
state.items.length = 2 // Removes items
```
```javascript
import { start } from 'sprae'
start()
```
```javascript
import { start } from 'sprae'
start()
```
```javascript
import { start } from 'sprae'
start()
```
```javascript
import { start } from 'sprae'
start()
```
--------------------------------
### Sprae Todo List Example
Source: https://github.com/dy/sprae/blob/main/r&d.md
A basic todo list implementation using Sprae directives. It employs `:state` to manage input values and the todo list array, `:value` for input binding, `:onclick` to add new tasks, and `:each` to render the list of tasks. This example showcases Sprae's declarative approach to UI management.
```html
My Example Task
```
--------------------------------
### Sprae TodoMVC Implementation with JavaScript
Source: https://github.com/dy/sprae/blob/main/examples/todomvc.html
This JavaScript code implements the TodoMVC application using the Sprae framework. It manages the application state, including the list of todos and the current hash for routing, and persists the todos to local storage. It also handles hash change events to update the application state.
```javascript
// import sprae from '../sprae.js'
import sprae from 'sprae'
import plur from 'plur'
let state = sprae(document.body, {
plur,
console,
todos: JSON.parse(localStorage.getItem('todomvc.items') || '[]'),
hash: window.location.hash || '#/',
save: items => localStorage.setItem('todomvc.items', JSON.stringify(items))
})
// hash source
window.addEventListener('hashchange', e => state.hash = window.location.hash)
```
--------------------------------
### Initialize Sprae with Data
Source: https://github.com/dy/sprae/blob/main/examples/js-framework-benchmark.html
This snippet demonstrates the initial setup of Sprae by binding it to an HTML element and providing an initial dataset for 'rows'. It also defines functions for data manipulation like 'remove', 'select', 'run', 'add', 'update', 'runLots', 'clear', and 'swap'. The 'buildData' function generates sample data with random labels.
```javascript
import sprae from '../sprae.js' // import sprae from 'https://unpkg.com/sprae@10.13.0/dist/sprae.js' // import sprae from '../dist/sprae.js' const adjectives = [
'pretty',
'large',
'big',
'small',
'tall',
'short',
'long',
'handsome',
'plain',
'quaint',
'clean',
'elegant',
'easy',
'angry',
'crazy',
'helpful',
'mushy',
'odd',
'unsightly',
'adorable',
'important',
'inexpensive',
'cheap',
'expensive',
'fancy'
]
const colours = [
'red',
'yellow',
'blue',
'green',
'pink',
'brown',
'purple',
'brown',
'white',
'black',
'orange'
]
const nouns = [
'table',
'chair',
'house',
'bbq',
'desk',
'car',
'pony',
'cookie',
'sandwich',
'burger',
'pizza',
'mouse',
'keyboard'
]
let nextId = 1
function buildData(count) {
const data = []
for (let i = 0; i < count; i++) {
data.push({
id: nextId++,
label: `${adjectives[_random(adjectives.length)]} ${colours[_random(colours.length)]} ${nouns[_random(nouns.length)]}`,
})
}
return data
}
function _random(max) {
return Math.round(Math.random() * 1000) % max
}
sprae(document.getElementById('main'), {
rows: buildData(3),
selected: null,
remove(item) {
const index = this.rows.findIndex(x => (x.id == item.id))
this.rows.splice(index, 1)
},
select(item) {
console.time('select', item)
this.selected = item
console.timeEnd('select')
},
run() {
this.rows = buildData(1000)
this.selected = null
},
add() {
this.rows.push(...buildData(1000))
// this.rows = [...this.rows, ...buildData(1000)]
this.selected = null
},
update() {
for (let i = 0; i < this.rows.length; i += 10) {
this.rows[i].label += ' !!!'
}
this.selected = null
},
runLots() {
console.time('10k')
this.rows = buildData(10000)
this.selected = null
console.timeEnd('10k')
},
clear() {
this.rows = []
this.selected = null
},
swap() {
if (this.rows.length > 998) {
let rows = this.rows;
[rows[1], rows[998]] = [rows[998], rows[1]]
}
}
})
```
--------------------------------
### Sprae auto-initialization using data-start attribute
Source: https://github.com/dy/sprae/blob/main/r&d.md
Configuration for Sprae's auto-initialization mechanism. This approach uses a `data-start` attribute (or simply `start`) on an element to trigger Sprae initialization. It is designed to be compatible with UMD builds and aims to avoid redundancy with existing auto-initialization patterns.
```html
```
--------------------------------
### Manual Sprae Initialization
Source: https://github.com/dy/sprae/blob/main/readme.md
For more control, Sprae can be initialized manually. You can remove the `start` attribute from the script tag and then call `sprae.start(document.body, scope)` to initialize Sprae on a specific element and scope, or call `sprae(element, scope)` to initialize individual elements without automatic watching.
```javascript
import sprae from './sprae.js'
// init
const state = sprae(document.getElementById('counter'), { count: 0 })
// update state
state.count++
```
--------------------------------
### Sprae Day/Night Switch Example
Source: https://github.com/dy/sprae/blob/main/r&d.md
Demonstrates a simple day/night toggle using Sprae directives. It utilizes `:scope` for state management, `:onclick` for event handling, and `:text` and `:class` for dynamic content and styling. No external dependencies beyond the Sprae library are required.
```html
Welcome to Spræ!
```
--------------------------------
### Example of :with for Situational Variables
Source: https://github.com/dy/sprae/blob/main/r&d.md
Demonstrates using the :with directive to define situational variables for props precalculation, acting as a reactive watch within local component state.
```html
```
--------------------------------
### Django's 'with' Tag for Alias and Complex Calculations
Source: https://github.com/dy/sprae/blob/main/r&d.md
An example from Django's documentation illustrating the 'with' tag, which performs aliasing or complex access but does not synchronize global state.
```django
{% assign myVar = false %}
```
```django
{% with total = price|add:tax %}
```
--------------------------------
### Get Element References with :ref in HTML
Source: https://context7.com/dy/sprae/llms.txt
The :ref directive in Sprae.js provides a way to get direct references to DOM elements. These references can be stored in the scope or passed to a callback function. It also supports lifecycle hooks for mount and unmount events.
```html
```
--------------------------------
### Sprae async effects example
Source: https://github.com/dy/sprae/blob/main/r&d.md
Illustrates a proposed approach for handling asynchronous effects within Sprae. This method allows referring to newly created state from within methods and supports potential batch updates and awaiting effects, although it might introduce a 'first blank frame' delay.
```javascript
// Example concept for async effects in Sprae
// This is a conceptual representation and not actual runnable code
// sprae.effect(async () => {
// const newState = await someAsyncOperation();
// sprae.update(store, 'someKey', newState);
// });
```
--------------------------------
### Conditional Rendering with :if and :else Directives
Source: https://context7.com/dy/sprae/llms.txt
Sprae.js's :if and :else directives enable conditional rendering of HTML elements, ensuring proper cleanup of elements when they are removed from the DOM. They support complex conditions, fragment rendering using template tags, and a function form for dynamic visibility. Requires Sprae.js and its start() function.
```html
Home View
About View
Not Found
Count is high
Visible
```
--------------------------------
### Sprae DOM Writer Signals Example
Source: https://github.com/dy/sprae/blob/main/r&d.md
Demonstrates the usage of Sprae's DOM writer signals for manipulating text, classes, and HTML content of elements. These signals act as simple writers, updating the target DOM property directly.
```javascript
const elText = text(el, 'init');
elText.value = 123;
const elClass = cl(el, 'init');
// Example of class manipulation would follow here
const elContent = html(el, 'init');
// Example of HTML manipulation would follow here
```
--------------------------------
### Exposing Element References with :ref in HTML
Source: https://github.com/dy/sprae/blob/main/readme.md
The :ref attribute allows you to expose an element in scope or get a direct reference to it. It can be used for direct DOM manipulation, setting innerHTML, or for local references within loops and conditional rendering.
```html
```
--------------------------------
### Sprae initialization with data-sprae-init and data-sprae-prefix
Source: https://github.com/dy/sprae/blob/main/r&d.md
An alternative method for Sprae auto-initialization using standard attributes. `data-sprae-init` marks elements for initialization, while `data-sprae-prefix` allows for custom prefixes, offering a more verbose but flexible approach.
```html
```
--------------------------------
### Create Reactive Signals with Sprae
Source: https://context7.com/dy/sprae/llms.txt
Demonstrates how to create basic signals, computed signals, effects with cleanup, batch updates, and untracked reads using Sprae's core reactive primitives. This approach allows for fine-grained control over reactivity.
```javascript
import { signal, computed, effect, batch, untracked } from 'sprae'
// Basic signal
const count = signal(0)
console.log(count.value) // 0
count.value = 1 // Triggers effects
console.log(count.peek()) // 1 (no subscription)
// Computed signal
const double = computed(() => count.value * 2)
console.log(double.value) // 2
count.value = 5
console.log(double.value) // 10
// Effect with cleanup
const dispose = effect(() => {
console.log('Count:', count.value)
const timer = setTimeout(() => console.log('Delayed'), 1000)
return () => clearTimeout(timer) // Cleanup on rerun
})
count.value++ // Logs "Count: 6" and schedules delayed log
// Stop effect
dispose()
// Batch updates (single effect run)
batch(() => {
count.value = 10
count.value = 20
count.value = 30
}) // Effect runs once with value 30
// Untracked reads (no subscription)
effect(() => {
console.log('Count:', count.value) // Subscribes
const other = signal(5)
console.log('Other:', untracked(() => other.value)) // Doesn't subscribe
})
```
--------------------------------
### Auto-start Sprae with Mutation Observer
Source: https://context7.com/dy/sprae/llms.txt
Automatically initializes Sprae on the entire document or a specific container using a MutationObserver. This allows for live detection and initialization of new elements with Sprae directives as they are added to the DOM.
```javascript
import { start } from 'sprae'
// Watch entire document
const state = start(document.body, { count: 0, user: 'Alice' })
// Or target specific container
const state = start(document.getElementById('app'), { items: [] })
// Dynamically added elements with : attributes are auto-initialized
document.body.innerHTML += '' // Works immediately
```
--------------------------------
### Custom Sprae Build with Preact Signals and Custom Directives (JavaScript)
Source: https://github.com/dy/sprae/blob/main/readme.md
This JavaScript snippet demonstrates how to create a custom build of Sprae. It includes importing core Sprae functionality, integrating with Preact signals for state management, and using a custom compiler. It also shows how to register standard directives and define a custom ':id' directive.
```javascript
// sprae.custom.js
import sprae, { directive, use } from 'sprae/core'
import * as signals from '@preact/signals'
import compile from 'subscript/justin'
import _default from 'sprae/directive/default.js'
import _if from 'sprae/directive/if.js'
import _text from 'sprae/directive/text.js'
use({
// custom prefix, defaults to ':'
prefix: 'data-sprae-',
// use preact signals
...signals,
// use safer compiler
compile
})
// standard directives
directive.if = _if;
directive.text = _text;
directive.default = _default;
// custom directive :id="expression"
directive.id = (el, state, expr) => {
// ...init
return newValue => {
// ...update
let nextValue = el.id = newValue
return nextValue
}
}
export default sprae;
```
--------------------------------
### Sprae Configuration Options for Signals
Source: https://github.com/dy/sprae/blob/main/r&d.md
Presents various methods for configuring or setting signal implementations within Sprae, including global configuration, direct assignment, and a 'use' method, discussing their pros and cons.
```javascript
// Option 1: Universal config
sprae.config({ signals });
sprae.setup({ signals });
// Option 2: Direct assignment
sprae.signals(signals);
// Option 3: Plugin-like usage
sprae.set({ signals });
sprae.use(signals);
// Option 4: Direct property assignment
sprae.signals = signals;
```
--------------------------------
### Use Preact Signals with Sprae
Source: https://context7.com/dy/sprae/llms.txt
Shows how to replace Sprae's default signals with industry-standard implementations, specifically using `@preact/signals-core`. This integration allows Sprae to leverage Preact's optimized signal handling.
```javascript
import sprae from 'sprae'
import * as preactSignals from '@preact/signals-core'
// Switch to preact signals
sprae.use(preactSignals)
// Now sprae uses preact's optimized signals internally
const state = sprae(document.body, { count: 0 })
```
--------------------------------
### Content Rendering with :render and :with Directives
Source: https://github.com/dy/sprae/blob/main/r&d.md
Presents the ':render' directive for specifying a template and ':with' for providing scope. This syntax is noted as being compatible with liquid 5.0 and aims to simplify content inclusion by focusing on the rendering logic rather than fetching mechanisms.
```html
```
--------------------------------
### Template Directives for Property and Attribute Assignment
Source: https://github.com/dy/sprae/blob/main/r&d.md
Demonstrates different syntaxes for assigning properties and attributes to HTML elements within a template. It highlights the differences and potential conflicts between various directive prefixes like ':', '.', '_', and ':_'. The primary goal is to manage API friction and maintain clear conventions.
```html
```
--------------------------------
### Replacing :with with := for Initialization
Source: https://github.com/dy/sprae/blob/main/r&d.md
Illustrates how the ':=' syntax can be used as a replacement for the :with directive, simplifying variable initialization within the template.
```html
:='x=123'
```
--------------------------------
### Sprae Control Flow with :if and :else Directives
Source: https://github.com/dy/sprae/blob/main/readme.md
Demonstrates Sprae's conditional rendering capabilities using the :if and :else directives. It shows how to chain conditions and use fragments for conditional rendering of multiple elements.
```html
foobarbaz
foo bar baz
```
--------------------------------
### Sprae Signal and Effect Imports
Source: https://github.com/dy/sprae/blob/main/r&d.md
Demonstrates different import strategies for Sprae's signal and effect functionalities, evaluating clarity, size implications, and required usage patterns.
```javascript
// Option 1: All from main entry
import sprae, { signal, effect } from 'sprae';
// Option 2: Separate signal entry
import sprae from 'sprae';
import { signal, effect } from 'sprae/signal';
// Option 3: External signal library assignment
import sprae from 'sprae';
import * as ulive from 'ulive';
Object.assign(sprae, ulive);
const { signal } = ulive;
```
--------------------------------
### Declaring Local Variables with :let
Source: https://github.com/dy/sprae/blob/main/r&d.md
Shows the proposed :let syntax for cleanly declaring local variables without polluting the scope, indicating only local initialization rather than subscription.
```html
:let="x, y=2"
```
--------------------------------
### Create Reactive Store with Sprae
Source: https://context7.com/dy/sprae/llms.txt
Creates a reactive store from plain objects and arrays, enabling automatic dependency tracking for state changes. It supports reactive properties, arrays, methods, computed properties, and external signals, while allowing for sandboxing of global objects.
```javascript
import { store, signal, computed } from 'sprae'
const state = store({
count: 0, // Reactive property
items: [1, 2, 3], // Reactive array
inc() { this.count++ }, // Method
get double() { return this.count * 2 }, // Computed property
_private: 'data', // Untracked (underscore prefix)
external: signal('value'), // External signal
}, { Math, console }) // Parent scope/sandbox
state.count++ // Triggers reactivity
state.items.push(4) // Triggers list updates
state._private = 'new' // No reactivity
state.Math.random() // Access sandboxed globals
state.window // undefined (not in sandbox)
```
--------------------------------
### Extending State with :fx for Local Updates
Source: https://github.com/dy/sprae/blob/main/r&d.md
Demonstrates using the ':fx' directive to extend state with local updates, such as defining and modifying variables within a sandboxed environment.
```html
:fx="x=1, y=2"
```
```html
:fx="x=1, y=2, get=()=>x++"
```
--------------------------------
### Simplifying Directive Structure with Flat Files
Source: https://github.com/dy/sprae/blob/main/r&d.md
Advocates for a flat `directives.js` file structure instead of a `directives/` directory. This simplification aims to reduce project weight, improve maintainability, and facilitate custom bundle creation through copy-pasting.
```javascript
// Example: directives.js content
export const text = (el, binding) => {
// ... implementation ...
};
export const ref = (el, binding) => {
// ... implementation ...
};
// ... other directives
```
--------------------------------
### Sprae :ref Attribute for Functional Initialization
Source: https://github.com/dy/sprae/blob/main/r&d.md
Illustrates the use of the :ref attribute in Sprae for initializing elements, analogous to React's ref. It shows how to directly manipulate element styles or assign elements to state variables.
```sprae
:ref="el=>el.style='abc'"
:ref="(el, state) => state[name] = el"
x=el}>
x=el}>
```
--------------------------------
### Sprae :style Directive for Inline Style Management
Source: https://github.com/dy/sprae/blob/main/readme.md
Demonstrates how to use the :style directive in Sprae to apply inline styles to HTML elements. It supports binding to a string, extending static styles, using objects for multiple styles, and functions for dynamic style generation.
```html
```
--------------------------------
### Using Preact Signals with Sprae
Source: https://github.com/dy/sprae/blob/main/readme.md
Sprae allows integration with `@preact/signals-core` for enhanced reactivity. By using `sprae.use(signals)`, you can leverage the high performance and advanced features of Preact's signals library within your Sprae application. This is beneficial for complex state management scenarios.
```javascript
import sprae from 'sprae';
import { signal, computed, effect, batch, untracked } from 'sprae/signal';
import * as signals from '@preact/signals-core';
sprae.use(signals);
```
--------------------------------
### Initialize Element with Sprae
Source: https://context7.com/dy/sprae/llms.txt
Initializes an element with Sprae, applying directives and establishing reactive state binding. It returns a state object that can be mutated to trigger DOM updates. The initialization can be disposed of when no longer needed.
```javascript
import sprae from 'sprae'
// Basic initialization
const el = document.querySelector('#counter')
const state = sprae(el, { count: 0 })
// State mutations trigger updates
state.count++ // Updates DOM automatically
// Dispose when done
el[Symbol.dispose]()
```
--------------------------------
### Sprae :value and :ref for Bidirectional Data Binding
Source: https://github.com/dy/sprae/blob/main/r&d.md
Explains how the :value and :ref attributes can be combined in Sprae to achieve bidirectional data binding, where :value updates a prop path and :ref can work in reverse.
```sprae
This combines :value and :ref. :value can take simple prop path and will save value there. Same time :ref can take path and work in reverse.
```
--------------------------------
### Event Chaining in Sprae: Sequential vs. Parallel Execution
Source: https://github.com/dy/sprae/blob/main/r&d.md
Demonstrates how event chaining can be managed sequentially in Sprae. It highlights the default behavior and how to limit parallel event execution using numerical modifiers.
```sprae
:onclick..onclick="play"
:onclick.1..onclick :onclick.second..onclick
```
--------------------------------
### Sprae Attribute Binding with :attr and Spread
Source: https://github.com/dy/sprae/blob/main/readme.md
Covers Sprae's generic attribute binding using the :attr directive and its spread syntax. This allows setting any HTML attribute dynamically, including multiple attributes at once or passing an object of properties.
```html
```
--------------------------------
### Sprae Conditional and List Rendering Signals
Source: https://github.com/dy/sprae/blob/main/r&d.md
Illustrates how Sprae handles conditional rendering with ':if' and list rendering with ':each'. These directives manage context and child element creation based on the provided logic.
```javascript
const items = each(el, (items) => children);
const cond = if(el, cond);
const cur = select([el1, el2, el3], 0);
```
--------------------------------
### Sprae :fx Directive for Side Effects and Cleanup
Source: https://github.com/dy/sprae/blob/main/readme.md
Illustrates the :fx directive in Sprae for running side effects or executing cleanup functions. It supports inline expressions and functions that can return a cleanup function for managing subscriptions or intervals.
```html
```
--------------------------------
### Configure Sprae Behavior
Source: https://context7.com/dy/sprae/llms.txt
Customizes Sprae's core behavior, including the directive prefix, the signals implementation, and the expression compiler. It also demonstrates how to define custom directives and modifiers for extending Sprae's functionality.
```javascript
import { use, directive, modifier } from 'sprae/core'
import * as preactSignals from '@preact/signals-core'
import justin from 'subscript/justin' // CSP-safe evaluator
use({
prefix: 'data-app-', // Change directive prefix
...preactSignals, // Use preact signals
compile: justin // Use safe evaluator (no eval/Function)
})
// Custom directive: :id="expression"
directive.id = (el, state, expr) => {
// Init phase - runs once
console.log('Setting up id directive')
// Return update function
return (newValue) => {
el.id = newValue
return newValue // Optional: return for function chaining
}
}
// Custom modifier: :onclick.custom="handler"
modifier.custom = (fn) => (event) => {
console.log('Custom modifier wrapping handler')
return fn(event)
}
```
--------------------------------
### Sprae :each Directive for List Rendering
Source: https://github.com/dy/sprae/blob/main/readme.md
Explains Sprae's :each directive for iterating over data and rendering lists of elements. It supports arrays, objects, numbers, and functions, and allows accessing item and index.
```html
```
--------------------------------
### Sprae :text Directive for Content Updates
Source: https://github.com/dy/sprae/blob/main/readme.md
Shows how to use the :text directive in Sprae to dynamically set the text content of HTML elements. It covers simple text binding, template fragments, and using functions for dynamic text generation.
```html
Welcome, Guest.
Welcome, .
```
--------------------------------
### Wildcard Directives for Event Handling
Source: https://github.com/dy/sprae/blob/main/r&d.md
Proposes using `on*` and `*` wildcards for directives instead of a generic `:*`. This allows for special argument handling (like event names) and better separation of concerns, particularly for the events directive.
```html
```
--------------------------------
### Sprae Scoped Data Management with ':with' and 'sprae'
Source: https://github.com/dy/sprae/blob/main/r&d.md
Compares Sprae's ':with' directive for component-like scope management with the primary 'sprae' function. It shows how 'sprae(el, data)' can achieve similar signal-based updates to ':with(el, data)'.
```javascript
// Using :with for component scope
// with(el, data)
// Equivalent using sprae for signal updates
// sprae(el, data)
// Using :render for explicit scope and content replacement
const template = render(el, data, template?);
```
--------------------------------
### Mount/Unmount and Visibility Event Handlers in HTML
Source: https://github.com/dy/sprae/blob/main/readme.md
Sprae provides special event handlers for element lifecycle events. :onmount..onunmount triggers when an element is connected or disconnected from the DOM, and :onvisible..oninvisible triggers when an element enters or leaves the viewport.
```html
```
--------------------------------
### Unified Event Handling with @ Prefix
Source: https://github.com/dy/sprae/blob/main/r&d.md
Proposal to use the '@' prefix for events, differentiating them from property binding directives (':'). This aims to provide a unified and cleaner approach to handling events, potentially allowing subscriptions to property changes as well.
```html