### Install Ripple using create-ripple CLI
Source: https://www.ripplejs.com/docs/quick-start
Installs Ripple.js using the experimental create-ripple command-line interface. This is a quick way to set up a new Ripple project.
```bash
npm create ripple
```
--------------------------------
### Clone Ripple Basic Template and Run
Source: https://www.ripplejs.com/docs/quick-start
Clones the Vite-based basic template for Ripple.js using npx and degit, installs dependencies, and starts the development server. This is useful for a quick project setup.
```bash
npx degit Ripple-TS/ripple/templates/basic ripple-app
cd ripple-app
npm i
npm run dev
```
--------------------------------
### Install Ripple Language Server
Source: https://www.ripplejs.com/docs/quick-start
Installs the Ripple.js language server globally using npm. This is a prerequisite for editor integration in IDEs like WebStorm/IntelliJ and Sublime Text.
```bash
npm install -g '@ripple-ts/language-server'
```
--------------------------------
### Configure Ripple Language Server in WebStorm/IntelliJ
Source: https://www.ripplejs.com/docs/quick-start
Configuration for setting up the Ripple.js language server in WebStorm/IntelliJ. It involves installing the server, the LSP4IJ plugin, and configuring language server settings and file mappings.
```json
{
"clients": {
"Ripple": {
"enabled": true,
"command": ["'@ripple-ts/language-server'", "--stdio"],
"selector": "source.ripple"
}
}
}
```
--------------------------------
### Ripple.js If Statement Example
Source: https://www.ripplejs.com/docs/guide/control-flow
Demonstrates the usage of if/else statements within Ripple.js templating for conditional rendering. This allows for cleaner and more readable control flow directly in your components.
```ripple
export component Truthy({ x }) {
if (x) {
{'x is truthy'}
} else {
{'x is falsy'}
}
}
```
--------------------------------
### Ripple.js Switch Statement Example (Reactive)
Source: https://www.ripplejs.com/docs/guide/control-flow
Illustrates using switch statements with reactive values in Ripple.js. This enables dynamic UI updates based on changes to tracked state variables.
```ripple
import { track } from 'ripple';
export component InteractiveStatus() {
let status = track('loading');
switch (@status) {
case 'loading':
{'Loading...'}
break;
case 'success':
{'Success!'}
break;
case 'error':
{'Error!'}
break;
default:
{'Unknown status'}
}
}
```
--------------------------------
### Ripple.js Async Suspense Boundary (Experimental)
Source: https://www.ripplejs.com/docs/guide/control-flow
Provides an example of an experimental Suspense boundary in Ripple.js for handling asynchronous operations. It allows for displaying fallback content while waiting for data.
```ripple
export component SuspenseBoundary() {
try {
} pending {
{'Loading...'}
// fallback
}
}
```
--------------------------------
### Invalid Raw HTML Rendering Example in Ripple.js
Source: https://www.ripplejs.com/docs/guide/syntax
Highlights an example of incorrect usage of the `html` directive in Ripple.js, where malformed HTML is passed. The directive expects complete and valid HTML structures; using it with incomplete tags like only a closing tag will result in rendering errors. Ensure all HTML elements are properly opened and closed.
```ripple
{html '
'}content{html '
'}
```
--------------------------------
### Customize Tracked Value Get/Set with Functions in RippleJS
Source: https://www.ripplejs.com/docs/guide/reactivity
Shows how to use optional 'get' and 'set' functions with the 'track' function in RippleJS to customize how a tracked value is read or written. The 'get' function processes the value on read, and the 'set' function processes it on write, allowing for logging, validation, or transformation. This example is within a RippleJS component.
```ripple
import { track } from 'ripple';
export component App() {
let count = track(0,
(current) => {
console.log(current);
return current;
},
(next, prev) => {
console.log(prev);
if (typeof next === 'string') {
next = Number(next);
}
return next;
}
);
}
```
--------------------------------
### Ripple.js Switch Statement Example (Static)
Source: https://www.ripplejs.com/docs/guide/control-flow
Shows how to use switch statements in Ripple.js to conditionally render content based on a static status value. This is useful for managing different UI states.
```ripple
export component StatusIndicator({ status }) {
switch (status) {
case 'loading':
{'Loading...'}
break;
case 'success':
{'Success!'}
break;
case 'error':
{'Error!'}
break;
default:
{'Unknown status'}
}
}
```
--------------------------------
### Ripple Card Component with Header, Footer, and Children Composition
Source: https://www.ripplejs.com/docs/guide/components
An example of a versatile Card component using child composition, allowing for optional Header, Footer, and main content children. This pattern is similar to slots or render props in other frameworks.
```ripple
component Card({ children, Header, Footer }) {
}
component CustomHeader() {
{'Card Title'}
}
export component App() {
// <- Header passed in as a prop
{'Card content here'}
component Footer() { // <- Footer passed in as a inline component
}
}
```
--------------------------------
### Capture Phase Event Handling with `capture: true`
Source: https://www.ripplejs.com/docs/guide/events
Shows how to handle events during the capture phase by setting the `capture` option to `true` within an event attribute object. This example demonstrates the order of event propagation when an inner button is clicked within a div.
```ripple
import { track } from 'ripple';
export component EventExample() {
let order = #[];
order.push('outer-capture'),
capture: true,
}}>
{order.join(' → ')}
}
// Clicking button outputs: outer-capture → inner-bubble
```
--------------------------------
### Using Effect for Side-Effects in RippleJS
Source: https://www.ripplejs.com/docs/guide/reactivity
Demonstrates how to use the `effect` primitive in RippleJS to create side-effects that trigger when reactive state updates. This example logs the current count to the console whenever it changes.
```ripple
import { track, effect } from 'ripple';
export component App() {
let count = track(0);
effect(() => {
console.log(@count);
});
}
```
--------------------------------
### Create and Update Tracked Primitive Variables in TypeScript
Source: https://www.ripplejs.com/docs/guide/reactivity
Demonstrates creating primitive reactive variables (string and number) using the 'track' function in TypeScript. Updates to these variables, accessed via the '@' operator, automatically trigger re-renders. Ensure 'ripple' is installed as a dependency.
```typescript
import { track } from 'ripple';
let name = track('World');
let count = track(0);
// Updates automatically trigger re-renders
@count++;
```
--------------------------------
### Passing Data Between Components Using Context (Ripple.js)
Source: https://www.ripplejs.com/docs/guide/state-management
Illustrates how to pass data between parent and child components using Ripple.js's Context API. The example shows setting a context value in the parent and accessing it in the child. It highlights the initial null value when reading context before it's set. Requires `Context` from 'ripple'.
```ripple
import { Context } from 'ripple';
const MyContext = new Context(null);
component Child() {
// Context is read in the Child component
const value = MyContext.get();
// value is "Hello from context!"
console.log(value);
}
export component Parent() {
const value = MyContext.get();
// Context is read in the Parent component, but hasn't yet
// been set, so we fallback to the initial context value.
// So the value is `null`
console.log(value);
// Context is set in the Parent component
MyContext.set("Hello from context!");
}
```
--------------------------------
### Mount Ripple App to DOM
Source: https://www.ripplejs.com/docs/guide/application
This snippet demonstrates how to mount the root Ripple component to a specified DOM element. It imports the 'mount' function and the root 'App' component, then uses 'document.getElementById' to find the target element for mounting. Ensure the target element exists in your HTML.
```javascript
import { mount } from 'ripple';
// @ts-expect-error: known issue, we're working on it
import { App } from './App.ripple';
mount(App, {
target: document.getElementById('app')!,
});
```
--------------------------------
### Get DOM Element Reference with Ripple.js bindNode
Source: https://www.ripplejs.com/docs/guide/bindings
Provides a convenient way to get a reference to a DOM element using the bindNode function. This allows direct manipulation or access to element properties and methods. It requires the 'track' and 'bindNode' functions from the 'ripple' library and a tracked variable to store the reference.
```ripple
import { track, bindNode } from 'ripple';
export component App() {
let divElement = track();
const handleFocus = () => {
if (@divElement) {
@divElement.focus();
@divElement.style.backgroundColor = 'lightblue';
}
};
{'Click the button to focus this div'}
}
```
--------------------------------
### Basic Ripple.js Component with Reactivity
Source: https://www.ripplejs.com/docs/introduction
This snippet demonstrates a basic Ripple.js component named 'App' that utilizes reactive primitives for a counter. It includes an h1 title, buttons to increment/decrement the count, and displays the current count. The component also includes scoped CSS for styling.
```ripple
import { track } from 'ripple'
export component App() {
{"Welcome to Ripple!"}
let count = track(0);
{@count}
}
```
--------------------------------
### Ripple Prop Shorthands
Source: https://www.ripplejs.com/docs/guide/components
Demonstrates shorthand syntax for spreading object properties and for props where the variable name matches the prop name.
```ripple
// Object spread
{"Content"}
// Shorthand props (when variable name matches prop name)
{"Content"}
// Equivalent to:
{"Content"}
```
--------------------------------
### Create and Manage Context with Reactive Data (Ripple.js)
Source: https://www.ripplejs.com/docs/guide/state-management
Demonstrates creating a context with an initial empty object and setting reactive properties within it. It shows how to access and update these reactive properties using `.get()` and `.set()` within a component. Dependencies include `track` and `Context` from 'ripple'.
```ripple
import { track, Context } from 'ripple'
// create context with an empty object
const context = new Context({});
const context2 = new Context();
export component App() {
// get reference to the object
const obj = context.get();
// set your reactive value
obj.count = track(0);
// create another tracked variable
const count2 = track(0);
// context2 now contains a tracked variable
context2.set(count2);
// context's reactive property count gets updated
{'Context: '}{context.get().@count}
{'Context2: '}{@count2}
}
```
--------------------------------
### RippleJS: Track Device Pixel Content Box Size (ResizeObserver)
Source: https://www.ripplejs.com/docs/guide/bindings
Tracks the content box size in device pixels using ResizeObserver, beneficial for high-DPI displays. This binding requires 'track' and 'bindDevicePixelContentBoxSize' from 'ripple'. Input is a trackable array; output is an array of objects specifying 'blockSize' and 'inlineSize' in device pixels.
```ripple
import { track, bindDevicePixelContentBoxSize } from 'ripple';
export component App() {
let size = track([]);
}
```
--------------------------------
### Untracking Reactivity in RippleJS
Source: https://www.ripplejs.com/docs/guide/reactivity
Illustrates how to use the `untrack` function in RippleJS to exclude dependencies from reactive effects. This example shows an effect that will no longer fire because its only dependency has been untracked.
```ripple
import { effect, track, untrack } from 'ripple';
export component App() {
let count = track(10);
let double = track(() => @count * 2);
let quadruple = track(() => @double * 2);
effect(() => {
// This effect will never fire again, as we've untracked the only dependency it has
console.log(untrack(() => @quadruple));
})
}
```
--------------------------------
### Ripple Component with Children
Source: https://www.ripplejs.com/docs/guide/components
Demonstrates how to create a Card component that accepts and renders child content. Children can be passed implicitly or explicitly as a component.
```ripple
import type { Component } from 'ripple';
component Card(props: { children: Component }) {
}
export component App() {
// Use implicitly...
{"Card content here"}
// or explicitly!
component children() {
{"Card content here"}
}
}
```
--------------------------------
### Ripple Portal Component for DOM Teleporting
Source: https://www.ripplejs.com/docs/guide/components
Shows how to use the `Portal` component to render content at a specified target in the DOM, outside the component's natural hierarchy. Useful for modals and tooltips.
```ripple
import { Portal } from 'ripple';
export component App() {
{'My App'}
{/* This will render inside document.body, not inside the .app div */}
{'I am rendered in document.body!'}
{'This content escapes the normal component tree.'}
}
```
--------------------------------
### Define a Ripple Component
Source: https://www.ripplejs.com/docs/guide/syntax
Demonstrates how to define a simple Ripple component using the 'component' keyword. Ripple's compiler transforms this into an optimized JavaScript function for DOM manipulation. Components must contain templates within their body.
```ripple
component Hello() {
{'Hello World!'}
}
```
--------------------------------
### Apply Ripple.js Ref to Composite Components
Source: https://www.ripplejs.com/docs/guide/dom-refs
This example demonstrates how to apply a Ripple.js ref to a composite component (`Image`). When used with composite components, refs receive a Symbol property, allowing them to be correctly passed down and applied to underlying HTML elements. This maintains consistency across different component types.
```ripple
console.log(node)} {...props} />
```
--------------------------------
### Inline DOM Element Reference Capture in Ripple.js
Source: https://www.ripplejs.com/docs/guide/dom-refs
This example shows how to define a ref function inline within the template in Ripple.js. This is a concise way to capture DOM elements when the logic is simple and doesn't require a separate named function. It achieves the same result as the named function approach but with less boilerplate.
```ripple
import { track } from 'ripple';
export component App() {
let div = track();
}
```
--------------------------------
### Attach Event Listeners with `on()` in RippleJS
Source: https://www.ripplejs.com/docs/guide/events
Illustrates how to use the `on()` function in RippleJS to attach event listeners to elements, ensuring proper execution order and optimized handling. It returns a function to remove the listener, crucial for preventing memory leaks on component unmount. The example shows attaching a 'resize' event listener to the window.
```javascript
import { effect, on } from 'ripple';
export component App() {
effect(() => {
// on component mount
const removeListener = on(window, 'resize', () => {
console.log('Window resized!');
});
// return the removeListener when the component unmounts
return removeListener;
});
}
```
--------------------------------
### Ripple.js Dynamic Element Rendering
Source: https://www.ripplejs.com/docs/guide/control-flow
Illustrates rendering HTML elements dynamically in Ripple.js using a tracked variable for the tag name. The `<@tagName>` syntax allows for flexible element switching based on state.
```ripple
export component App() {
let tag = track('div');
<@tag class="dynamic">{'Hello World'}@tag>
}
```
--------------------------------
### Capture DOM Element Reference with Ripple.js Ref Function
Source: https://www.ripplejs.com/docs/guide/dom-refs
This snippet demonstrates how to capture a DOM element reference using the `{ref fn}` syntax in Ripple.js. The `divRef` function receives the DOM node upon mounting and can return a cleanup function for unmounting. This is useful for direct DOM manipulation or event listener setup.
```ripple
import { track } from 'ripple';
export default component App() {
let div = track();
const divRef = (node) => {
@div = node;
console.log("mounted", node);
return () => {
@div = undefined;
console.log("unmounted", node);
};
};
{"Hello world"}
}
```
--------------------------------
### Create and Use TrackedObject in RippleJS
Source: https://www.ripplejs.com/docs/guide/reactivity
Shows how to create a TrackedObject using syntactic sugar or constructors and demonstrates its reactivity in a RippleJS component. TrackedObject extends JS Object, providing shallow reactivity for root-level properties. Unboxing is not required for properties.
```ripple
import { TrackedObject } from 'ripple';
// using syntactic sugar `#`
const obj = #{a: 1, b: 2, c: 3};
// using the new constructor
const obj = new TrackedObject({a: 1, b: 2, c: 3});
```
```ripple
export component App() {
const obj = #{a: 0}
obj.a = 0;
{'obj.a is: '}{obj.a}
{'obj.b is: '}{obj.b}
}
```
--------------------------------
### Handle Custom Events with `customName` in RippleJS
Source: https://www.ripplejs.com/docs/guide/events
Demonstrates how to use the `customName` option to specify a custom event name for an event listener. This allows overriding the default inferred event name, which is useful for custom DOM events or when a different naming convention is required. The example shows a component that listens for 'MyCustomEvent' instead of the standard 'mycustomevent'.
```javascript
import { track } from 'ripple';
export component EventExample() {
let count = track(0);
}
// The element listens for 'MyCustomEvent' instead of 'mycustomevent'
```
--------------------------------
### Displaying Text in Ripple Components
Source: https://www.ripplejs.com/docs/guide/syntax
Shows the correct syntax for displaying text within Ripple components. Text must be enclosed in curly braces '{}' as it's treated as an expression, differentiating it from standard JSX where plain text is often allowed directly.
```ripple
// ✅ Correct - Text is an expression
{'Hello World!'}
// ❌ Wrong - Compilation error
Hello World!
```
--------------------------------
### Component Transport Pattern in RippleJS
Source: https://www.ripplejs.com/docs/guide/reactivity
Explains the Component Transport Pattern in RippleJS, demonstrating how to pass reactive components as props. It showcases tracking component references and passing them to child components for rendering.
```ripple
import { track } from 'ripple';
export component App() {
const tracked_basic = track(() => basic);
const obj = {
tracked_basic,
};
const tracked_object = track(obj);
const Button = track(() => SomeButton);
const AnotherButton = track(() => SomeButton);
<@tracked_object.@tracked_basic />
{'Child Button'}{'Another Child Button'}
}
component Child({ Button, children }) {
<@Button>@Button>
}
component AnotherChild(props) {
}
component SomeButton({ children }) {
}
component basic() {
{'Basic Component'}
}
```
--------------------------------
### Combine Multiple Ripple.js Bindings on One Element
Source: https://www.ripplejs.com/docs/guide/bindings
Demonstrates how to apply multiple bindings, such as bindValue, bindClientWidth, and bindNode, to the same HTML element by using multiple '{ref}' attributes. This allows for simultaneous management of element value, dimensions, and direct node reference. It requires 'track' and the specific binding functions from the 'ripple' library.
```ripple
import { track, bindValue, bindClientWidth, bindNode } from 'ripple';
export component App() {
let text = track('');
let width = track(0);
let inputElement = track();
const logInfo = () => {
console.log('Input:', @inputElement);
console.log('Value:', @text);
console.log('Width:', @width);
};
{'Text: '}{@text}
{'Width: '}{@width}{'px'}
}
```
--------------------------------
### Ripple.js For Statement (Basic List Rendering)
Source: https://www.ripplejs.com/docs/guide/control-flow
Demonstrates rendering a list of items using a basic for...of loop in Ripple.js. This is suitable for displaying collections where element identity is stable.
```ripple
component ListView({ title, items }) {
{title}
for (const item of items) {
{item.text}
}
}
// usage
export default component App() {
}
```
--------------------------------
### Ripple Templates Must Be Within Components
Source: https://www.ripplejs.com/docs/guide/syntax
Illustrates the correct and incorrect ways to use templates in Ripple. Templates (JSX-like syntax) are only allowed within the body of a 'component'. Helper functions should return data, not templates. Violating this rule will result in compilation errors.
```ripple
// ❌ Wrong - Templates outside the component
const element =
// Compilation error
);
// ✅ Correct - Templates only inside components
component MyComponent() {
// Template syntax is valid here
{"Hello World"}
// You can have JavaScript code mixed with templates
const message = "Dynamic content";
console.log("This JavaScript works");
{message}
}
// ✅ Correct - Helper functions return data, not templates
function getMessage() {
return "Hello from function"; // Return data, not JSX
}
component App() {
{getMessage()}
// Use function result in template
}
```
--------------------------------
### Ripple.js Try Statement (Error Handling)
Source: https://www.ripplejs.com/docs/guide/control-flow
Shows how to use try/catch blocks in Ripple.js for error handling and implementing error boundaries. Errors within the try block are caught, allowing for fallback UI rendering.
```ripple
import { reportError } from 'some-library';
export component ErrorBoundary() {
try {
} catch (e) {
reportError(e);
{'An error occurred! ' + e.message}
}
}
```
--------------------------------
### RippleJS: Correctly Closing Void Elements
Source: https://www.ripplejs.com/docs/troubleshooting
Illustrates the proper self-closing syntax for void elements in RippleJS to avoid 'Unexpected token `}`' errors. This is crucial for elements like , , , and .
```ripple
export component Bracey() {
// ✔️ valid
// ❌ invalid
//
//
//
//
}
```
--------------------------------
### RippleJS: Track Element Border Box Size (ResizeObserver)
Source: https://www.ripplejs.com/docs/guide/bindings
Tracks the border box size of an element using ResizeObserver, including padding and borders. It depends on 'track' and 'bindBorderBoxSize' from 'ripple'. The input is a trackable array; the output is an array of objects detailing 'blockSize' and 'inlineSize' of the border box.
```ripple
import { track, bindBorderBoxSize } from 'ripple';
export component App() {
let size = track([]);
}
```
--------------------------------
### Initialize TrackedDate in RippleJS
Source: https://www.ripplejs.com/docs/guide/reactivity
Demonstrates how to import and initialize the TrackedDate class from the ripple library. TrackedDate extends the standard JS Date class, supporting all its methods and properties.
```ripple
import { TrackedDate } from 'ripple';
const date = new TrackedDate(2026, 0, 1); // January 1, 2026
```
--------------------------------
### Ripple.js For Statement (With Key)
Source: https://www.ripplejs.com/docs/guide/control-flow
Illustrates using a 'key' with a for...of loop in Ripple.js for efficient list updates and reconciliation. This is crucial when list items can be reordered, added, or removed.
```ripple
for (const item of items; index i; key item.id) {
{item.label}{' at index '}{i}
}
```
--------------------------------
### Create and Use TrackedArray in RippleJS
Source: https://www.ripplejs.com/docs/guide/reactivity
Demonstrates creating a TrackedArray using syntactic sugar or constructors and its usage within a RippleJS component. TrackedArray extends JS Array and makes its elements reactive to operations like push, pop, shift, etc. No unboxing is needed for elements.
```ripple
import { TrackedArray } from 'ripple';
// using syntactic sugar `#`
const arr = #[1, 2, 3];
// using the new constructor
const arr = new TrackedArray(1, 2, 3);
// using static from method
const arr = TrackedArray.from([1, 2, 3]);
// using static method
const arr = TrackedArray.of(1, 2, 3);
```
```ripple
export component App() {
const items = #[1, 2, 3];
{"Length: "}{items.length}
// Reactive length
for (const item of items) {
{item}
}
}
```
--------------------------------
### RippleJS: Track Element Content Box Size (ResizeObserver)
Source: https://www.ripplejs.com/docs/guide/bindings
Tracks the content box size of an element using ResizeObserver, excluding padding and borders. This binding requires 'track' and 'bindContentBoxSize' from 'ripple'. The input is a trackable array; the output is an array of objects, typically with 'blockSize' and 'inlineSize'.
```ripple
import { track, bindContentBoxSize } from 'ripple';
export component App() {
let size = track([]);
}
```
--------------------------------
### Create and Use TrackedMap in RippleJS
Source: https://www.ripplejs.com/docs/guide/reactivity
Demonstrates creating a TrackedMap and its reactive application in a RippleJS component. TrackedMap extends JS Map, supporting reactive methods directly or via reactive variables using `track`. Changes to map entries trigger UI updates.
```ripple
import { TrackedMap, track } from 'ripple';
const map = new TrackedMap([[1,1], [2,2], [3,3], [4,4]]);
```
```ripple
import { TrackedMap, track } from 'ripple';
export component App() {
const map = new TrackedMap([[1,1], [2,2], [3,3], [4,4]]);
// direct usage
{"Direct usage: map has an item with key 2: "}{map.has(2)}
// reactive assignment
let has = track(() => map.has(2));
{"Assigned usage: map has an item with key 2: "}{@has}
}
```
--------------------------------
### Text Interpolation in Ripple
Source: https://www.ripplejs.com/docs/guide/syntax
Demonstrates text interpolation in Ripple, a basic form of data-binding. Variables or expressions are placed within curly braces '{}' inside template elements to dynamically insert values into the DOM.
```ripple
{`Message: ${msg}`}{'Message: ' + msg}
```
--------------------------------
### RippleJS: Validating Text Nodes with Braces
Source: https://www.ripplejs.com/docs/troubleshooting
Demonstrates the correct usage of braces for DOM text nodes in RippleJS components to prevent 'unterminated regular expression' errors. This ensures proper rendering of dynamic text content.
```ripple
export component TextBrace() {
// ✔️ valid
{'Hello world!'}
// ❌ invalid
//
Hello world!
}
```
--------------------------------
### RippleJS: Track Element Content Rect (ResizeObserver)
Source: https://www.ripplejs.com/docs/guide/bindings
Utilizes the ResizeObserver API to track an element's content rectangle, including its dimensions and position relative to its layout. It requires 'track' and 'bindContentRect' from 'ripple'. The input is a trackable object for the rect; the output is an object containing width, height, top, and left.
```ripple
import { track, bindContentRect } from 'ripple';
export component App() {
let rect = track({ width: 0, height: 0, top: 0, left: 0 });
{'Resize me!'}
{JSON.stringify(@rect, null, 2)}
}
```
--------------------------------
### Using Plain HTML Attributes in Ripple.js
Source: https://www.ripplejs.com/docs/guide/syntax
Illustrates the use of standard, un-bound HTML attributes within Ripple.js components. These attributes function like in plain HTML, where values are provided as strings within quotes, without the need for JavaScript expressions or curly braces.
```ripple
```
--------------------------------
### Ripple.js For Statement (TrackedArray)
Source: https://www.ripplejs.com/docs/guide/control-flow
Demonstrates using Ripple.js's TrackedArray with a for...of loop to render and dynamically update a list. Changes to the array (like push) automatically trigger UI updates.
```ripple
import { TrackedArray } from 'ripple';
export component Numbers() {
const array = new TrackedArray(1, 2, 3);
for (const item of array; index i) {
{item}{' at index '}{i}
}
}
```
--------------------------------
### RippleJS: Track Element Client Dimensions (Width/Height)
Source: https://www.ripplejs.com/docs/guide/bindings
Binds to an element's clientWidth and clientHeight, tracking its inner dimensions excluding borders and scrollbars. It requires the 'track', 'bindClientWidth', and 'bindClientHeight' functions from the 'ripple' library. Inputs are trackable variables to store the dimensions; outputs are the updated width and height values.
```ripple
import { track, bindClientWidth, bindClientHeight } from 'ripple';
export component App() {
let width = track(0);
let height = track(0);
{'Resize me! (drag bottom-right corner)'}
{'Client Width: '}{@width}{'px'}
{'Client Height: '}{@height}{'px'}
}
```
--------------------------------
### RippleJS: Track Element Offset Dimensions (Width/Height)
Source: https://www.ripplejs.com/docs/guide/bindings
Binds to an element's offsetWidth and offsetHeight, tracking its full outer dimensions including borders. This binding requires 'track', 'bindOffsetWidth', and 'bindOffsetHeight' from the 'ripple' library. The inputs are trackable variables, and the outputs are the element's total width and height including borders.
```ripple
import { track, bindOffsetWidth, bindOffsetHeight } from 'ripple';
export component App() {
let width = track(0);
let height = track(0);
}
```
--------------------------------
### Programmatically Setting Files with DataTransfer in JavaScript
Source: https://www.ripplejs.com/docs/guide/bindings
This JavaScript snippet demonstrates how to programmatically set files for a file input using the `DataTransfer` object. It's essential for updating file inputs dynamically when direct modification of `FileList` is not possible. This method is crucial for `bindFiles` in Ripple JS.
```javascript
const dt = new DataTransfer();
dt.items.add(new File(['content'], 'filename.txt'));
// Assuming '@files' is a tracked variable in Ripple JS
// @files = dt.files;
```
--------------------------------
### Rendering Raw HTML Content Safely with Ripple.js `html` directive
Source: https://www.ripplejs.com/docs/guide/syntax
Shows how to render trusted HTML content directly into the DOM using Ripple.js's `html` directive. This directive bypasses the default text escaping mechanism, which is crucial for preventing script injection vulnerabilities when rendering user-generated or external HTML content. Ensure the HTML passed to the directive is valid and well-formed.
```ripple
export component App() {
let source = `
My Blog Post
Hi! I like JS and Ripple.
`
{html source}
}
```
--------------------------------
### Array Transport Pattern in RippleJS
Source: https://www.ripplejs.com/docs/guide/reactivity
Demonstrates the Array Transport Pattern in RippleJS, showing how to pass reactive state as an array to a function and return a reactive value. It involves tracking a count, creating a double of it, and updating the UI.
```ripple
import { effect, track } from 'ripple';
function createDouble([ count ]) {
const double = track(() => @count * 2);
effect(() => {
console.log('Count:', @count)
});
return [ double ];
}
export component App() {
let count = track(0);
const [ double ] = createDouble([ count ]);
{'Double: ' + @double}
}
```
--------------------------------
### Dynamic Inline Styles in Ripple
Source: https://www.ripplejs.com/docs/guide/styling
Shows how to apply dynamic inline styles to elements in Ripple components using the `style` attribute. Supports both string concatenation and object notation for styles. The object notation is generally recommended for better performance. CSS property names can be in camelCase or kebab-case.
```ripple
ripple```
let color = track('red');
const style = {
@color,
fontWeight: 'bold',
'background-color': 'gray',
};
// using object spread
// using object directly
```
```
--------------------------------
### Simple Reactive Array with RippleJS
Source: https://www.ripplejs.com/docs/guide/reactivity
Demonstrates how to create a simple reactive array in RippleJS by composing normal arrays with tracked values. It calculates the total sum of the array elements reactively.
```ripple
import { effect, track } from 'ripple';
export component App() {
let first = track(1);
let second = track(2);
const arr = [first, second];
const total = track(() => arr.reduce((a, b) => a + @b, 0));
effect(() => {
console.log(@total);
})
}
```
--------------------------------
### Dynamic Component Rendering in Ripple.js
Source: https://www.ripplejs.com/docs/guide/reactivity
Ripple.js supports dynamic components, enabling the rendering of different components based on reactive state. A component can be stored in a `Tracked` variable, allowing it to be updated at runtime. The `<@Component />` tag is used to render these dynamic components, automatically handling mounting and unmounting when the tracked state changes, thus simplifying state-driven UI development.
```javascript
import { track } from 'ripple';
export component App() {
let swapMe = track(() => Child1);
}
component Child({ swapMe }: {swapMe: Tracked}) {
<@swapMe />
}
component Child1(props) {
{'I am child 1'}
}
component Child2(props) {
{'I am child 2'}
}
```
--------------------------------
### Event Handling with `handleEvent` Object
Source: https://www.ripplejs.com/docs/guide/events
Illustrates using an object with a `handleEvent` function as an event handler for `onClick`. This provides an alternative to directly passing a function, offering more control over event processing.
```ripple
```
--------------------------------
### Templates as Lexical Scopes in Ripple
Source: https://www.ripplejs.com/docs/guide/syntax
Explains and exemplifies how Ripple templates act as lexical scopes. This allows for inline JavaScript, including variable declarations, function calls, conditional logic, and even 'debugger' statements, directly within the template structure.
```ripple
component TemplateScope() {
// Variable declarations inside templates
const message = "Hello from template scope";
let count = 42;
// Function calls and expressions
console.log("This runs during render");
// Conditional logic
const isEven = count % 2 === 0;
{message}
{"Count is: "}{count}
if (isEven) {
{"Count is even"}
}
// Nested scopes work too
const sectionData = "Nested scope variable";