Canvas components

Cell content is described with render instructions. The following components are supported (fully drawn on canvas); others are stubs (placeholder) for future use.

Supported components

ComponentDescriptionMain props
TextSingle-line textvalue, style?, color?, fontWeight?, fontSize?
BadgePill/chip with backgroundvalue, style?, color?, backgroundColor?, borderRadius?
FlexTaffy-compatible flex container; lays out and draws childrenchildren, style?, flexDirection?, gap?, alignItems?, justifyContent?
BoxContainer: padding, margin, border; children in content rect (vertical stack)children?, style?, padding?, margin?, borderWidth?, backgroundColor?
StackRow or column layout with gapchildren?, direction? ("row" | "column"), gap?, style?
SparklineInline mini line chart from data (number[])data, style?, color?, strokeWidth?, variant? ("line" | "area")
ColorCentered square color swatchvalue (hex), borderRadius?, borderWidth?, borderColor?
TagOutlined text (stroke border + text)value, color?, borderColor?, borderRadius?, fontSize?
RatingFilled ★ and empty ☆ starsvalue, max?, color?, emptyColor?, size?
ChipFilled pill with optional close buttonvalue, color?, backgroundColor?, borderRadius?, closable?
LinkText with link color, optional underline; opens URL on clickvalue, href?, color?, underline?, fontSize?

All support an optional style object; individual props override style when both are set.

Text and Badge

import React from "react";
import { 
import Text
Text
,
import Badge
Badge
} from "@ohah/react-wasm-table";
// In a column render or as children of Flex/Box: export const
const Example: () => React.JSX.Element
Example
= () => (
<> <
import Text
Text
value: string
value
="Hello"
style: {
    color: string;
    fontWeight: string;
}
style
={{
color: string
color
: "#333",
fontWeight: string
fontWeight
: "bold" }} />
<
import Badge
Badge
value: string
value
="active"
style: {
    backgroundColor: string;
    color: string;
}
style
={{
backgroundColor: string
backgroundColor
: "#d1fae5",
color: string
color
: "#065f46" }} />
</> );

Flex (Taffy layout)

Flex accepts the same style surface as the layout engine: flexDirection, gap, alignItems, justifyContent, padding, margin, borderWidth, boxSizing, etc.

import React from "react";
import { 
import Flex
Flex
,
import Text
Text
,
import Badge
Badge
} from "@ohah/react-wasm-table";
export const
const Example: () => React.JSX.Element
Example
= () => (
<
import Flex
Flex
flexDirection: string
flexDirection
="row"
gap: number
gap
={8}
alignItems: string
alignItems
="center">
<
import Text
Text
value: string
value
="Name" />
<
import Badge
Badge
value: string
value
="New" />
</
import Flex
Flex
>
);

Individual props override style:

import React from "react";
import { 
import Flex
Flex
,
import Text
Text
} from "@ohah/react-wasm-table";
export const
const Example: () => React.JSX.Element
Example
= () => (
<
import Flex
Flex
style: {
    flexDirection: string;
    gap: number;
}
style
={{
flexDirection: string
flexDirection
: "column",
gap: number
gap
: 8 }}
flexDirection: string
flexDirection
="row"
gap: number
gap
={4}>
<
import Text
Text
value: string
value
="Result: flexDirection = 'row', gap = 4" />
</
import Flex
Flex
>
);

Box and Stack

  • Box: Padding, margin, border; children stacked vertically in the content rect.
  • Stack: Row or column with gap; no padding from layout buffer.
import React from "react";
import { 
import Box
Box
,
import Stack
Stack
,
import Text
Text
} from "@ohah/react-wasm-table";
export const
const Example: () => React.JSX.Element
Example
= () => (
<> <
import Box
Box
padding: number
padding
={8}
borderWidth: number
borderWidth
={1}
borderColor: string
borderColor
="#eee">
<
import Text
Text
value: string
value
="Inside box" />
</
import Box
Box
>
<
import Stack
Stack
direction: string
direction
="row"
gap: number
gap
={8}>
<
import Text
Text
value: string
value
="A" />
<
import Text
Text
value: string
value
="B" />
</
import Stack
Stack
>
</> );

Sparkline

Inline mini chart from a numeric array. Drawn on canvas.

import React from "react";
import { 
import Sparkline
Sparkline
} from "@ohah/react-wasm-table";
Cannot find module '@ohah/react-wasm-table' or its corresponding type declarations.
const
const series: number[]
series
= [10, 20, 15, 30, 25, 40];
export const
const Example: () => React.JSX.Element
Example
= () => (
<
import Sparkline
Sparkline
data: number[]
data
={
const series: number[]
series
}
variant: string
variant
="line"
color: string
color
="#2563eb"
strokeWidth: number
strokeWidth
={2} />
);
import React from "react";
import { 
import Color
Color
,
import Tag
Tag
,
import Rating
Rating
,
import Chip
Chip
,
import Link
Link
} from "@ohah/react-wasm-table";
export const
const Example: () => React.JSX.Element
Example
= () => (
<> <
import Color
Color
value: string
value
="#e53935"
borderRadius: number
borderRadius
={4} />
<
import Tag
Tag
value: string
value
="frontend"
color: string
color
="#1565c0"
borderColor: string
borderColor
="#1565c0" />
<
import Rating
Rating
value: number
value
={4}
max: number
max
={5}
color: string
color
="#f59e0b" />
<
import Chip
Chip
value: string
value
="React"
backgroundColor: string
backgroundColor
="#1976d2"
color: string
color
="#fff" />
<
import Link
Link
value: string
value
="Docs"
href: string
href
="https://example.com"
underline: true
underline
/>
</> );

Event handlers

All canvas components support HTMLElement-like event handlers via the CanvasEventHandlers interface. Events fire per-component with a GridCellEvent containing cell coordinates and the native MouseEvent.

HandlerFires when
onClickComponent cell is clicked
onDoubleClickComponent cell is double-clicked
onMouseDownMouse button pressed on component cell
onMouseUpMouse button released on component cell
onMouseEnterCursor enters a component cell
onMouseLeaveCursor leaves a component cell

Execution order

Event handlers follow DOM semantics with a 3-level execution order:

  1. Component-levelonClick on the component (element handler)
  2. Grid-levelonCellClick prop on the Grid (parent/bubbling)
  3. Renderer default action — e.g., Link opens URL

Calling e.preventDefault() at any level stops the levels below it.

Example

import React from "react";
import { 
import Link
Link
,
import Chip
Chip
, type
import GridCellEvent
GridCellEvent
} from "@ohah/react-wasm-table";
export const
const Example: () => React.JSX.Element
Example
= () => (
<> {/* preventDefault() blocks the Link renderer from opening the URL */} <
import Link
Link
value: string
value
="Click me"
href: string
href
="https://example.com"
onClick: (e: any) => void
onClick
={(
e: any
e
) => {
e: any
e
.preventDefault();
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
@seesource
console
.
Console.log(message?: any, ...optionalParams: any[]): void (+2 overloads)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0 .1.100
log
("clicked link at",
e: any
e
.cell);
}} /> {/* Hover events */} <
import Chip
Chip
value: string
value
="Hover me"
backgroundColor: string
backgroundColor
="#e3f2fd"
color: string
color
="#1565c0"
onMouseEnter: (e: any) => void
onMouseEnter
={(
e: any
e
) =>
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
@seesource
console
.
Console.log(message?: any, ...optionalParams: any[]): void (+2 overloads)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0 .1.100
log
("enter",
e: any
e
.cell)}
onMouseLeave: (e: any) => void
onMouseLeave
={(
e: any
e
) =>
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
@seesource
console
.
Console.log(message?: any, ...optionalParams: any[]): void (+2 overloads)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0 .1.100
log
("leave",
e: any
e
.cell)}
/> {/* Multiple events on one component */} <
import Chip
Chip
value: string
value
="All events"
backgroundColor: string
backgroundColor
="#e8f5e9"
color: string
color
="#2e7d32"
onClick: (e: any) => void
onClick
={(
e: any
e
) =>
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
@seesource
console
.
Console.log(message?: any, ...optionalParams: any[]): void (+2 overloads)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0 .1.100
log
("click",
e: any
e
.cell)}
onDoubleClick: (e: any) => void
onDoubleClick
={(
e: any
e
) =>
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
@seesource
console
.
Console.log(message?: any, ...optionalParams: any[]): void (+2 overloads)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0 .1.100
log
("dblclick",
e: any
e
.cell)}
onMouseDown: (e: any) => void
onMouseDown
={(
e: any
e
) =>
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
@seesource
console
.
Console.log(message?: any, ...optionalParams: any[]): void (+2 overloads)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0 .1.100
log
("mousedown",
e: any
e
.cell)}
onMouseUp: (e: any) => void
onMouseUp
={(
e: any
e
) =>
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
@seesource
console
.
Console.log(message?: any, ...optionalParams: any[]): void (+2 overloads)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0 .1.100
log
("mouseup",
e: any
e
.cell)}
/> </> );

Interactive components

The following components integrate with DOM overlays for user interaction:

ComponentDescriptionMain props
AvatarCircular avatar with image or initialsvalue, src?, size?, borderRadius?, color?
DatePickerDate input with DOM overlay pickervalue, onChange?, format?, style?
DropdownSelect input with DOM overlay dropdownvalue, options, onChange?, style?