` which doesn't work (parent has no explicit height). The component already sets `display: flex; flex-direction: column;` internally.
```tsx
// ❌ DOESN'T WORK - content appears blank
{/* Content in DOM but invisible */}
// ✅ WORKS - full available width and height
{/* Scrollable content */}
```
---
## ct-image-input
```tsx
📷 Add Photo
```
The component compresses images to fit within `maxSizeBytes`.
---
## ct-code-editor
Rich text editor with wiki-link mentions. **Uses `[[` for completions, not `@`.**
```tsx
```
**To trigger completions:** Type `[[` (double brackets), not `@`.
---
## ct-map
Interactive map component using Leaflet with OpenStreetMap tiles. No API key required.
### Properties
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `value` / `$value` | `MapValue \| Writable
` | `{}` | Map data with markers, circles, polylines |
| `center` / `$center` | `LatLng \| Writable` | San Francisco | Map center coordinates (bidirectional) |
| `zoom` / `$zoom` | `number \| Writable` | `13` | Zoom level 0-18 (bidirectional) |
| `bounds` / `$bounds` | `Bounds \| Writable` | - | Visible map bounds (bidirectional) |
| `fitToBounds` | `boolean` | `false` | Auto-fit to show all features |
| `interactive` | `boolean` | `true` | Enable pan/zoom |
### Types
```tsx
interface LatLng { lat: number; lng: number; }
interface Bounds { north: number; south: number; east: number; west: number; }
interface MapValue {
markers?: MapMarker[];
circles?: MapCircle[];
polylines?: MapPolyline[];
}
interface MapMarker {
position: LatLng;
title?: string;
description?: string;
icon?: string; // Emoji or icon name
popup?: OpaqueRef; // Advanced: pattern reference for rich popup
draggable?: boolean;
}
interface MapCircle {
center: LatLng;
radius: number; // meters
color?: string;
fillOpacity?: number;
strokeWidth?: number;
title?: string;
description?: string;
popup?: OpaqueRef;
}
interface MapPolyline {
points: LatLng[];
color?: string;
strokeWidth?: number;
dashArray?: string; // e.g., "5, 10" for dashed
}
```
### Events
| Event | Detail | Description |
|-------|--------|-------------|
| `ct-click` | `{ lat, lng }` | Map background clicked |
| `ct-bounds-change` | `{ bounds, center, zoom }` | Viewport changed |
| `ct-marker-click` | `{ marker, index, lat, lng }` | Marker clicked |
| `ct-marker-drag-end` | `{ marker, index, position, oldPosition }` | Marker drag completed |
| `ct-circle-click` | `{ circle, index, lat, lng }` | Circle clicked |
**Note:** Polylines do not emit click events. For clickable segments, use circles as waypoints.
### Usage
```tsx
// Simple: Display locations
const mapData = {
markers: stores.map(store => ({
position: { lat: store.lat, lng: store.lng },
title: store.name,
icon: "📍"
}))
};
// Interactive: Click to add marker
{
markers.push({
position: { lat: e.detail.lat, lng: e.detail.lng },
title: "New Location",
draggable: true
});
}}
/>
// Draggable markers
{
markers.key(e.detail.index).key("position").set(e.detail.position);
}}
/>
// Coverage areas with circles
const mapData = {
circles: areas.map(area => ({
center: { lat: area.lat, lng: area.lng },
radius: area.radiusMeters,
color: area.available ? "#22c55e" : "#ef4444",
fillOpacity: 0.2,
title: area.name
}))
};
// Route visualization
const mapData = {
polylines: [{
points: route.waypoints,
color: "#3b82f6",
strokeWidth: 4
}],
markers: [
{ position: route.start, icon: "🚀" },
{ position: route.end, icon: "🏁" }
]
};
```
### Notes
- **Bundle size:** Leaflet adds ~40KB gzipped
- **Zoom range:** 0 (world) to 18 (street level)
- **Default center:** San Francisco (37.7749, -122.4194)
- **Emoji markers:** Use any emoji as the `icon` property
- **Rich popups:** Pass a pattern reference via `popup` for interactive popup content
---
## Style Syntax
| Element | Syntax | Example |
|---------|--------|---------|
| HTML (`div`, `span`) | Object, camelCase | `style={{ backgroundColor: "#fff" }}` |
| Custom (`ct-*`) | String, kebab-case | `style="background-color: #fff;"` |
```tsx
// Mixed usage
Label
```
---
## ct-chart
SVG charting components. Compose mark elements inside a `ct-chart` container.
### Elements
- **`ct-chart`** - Container that discovers child marks, computes scales, renders SVG
- **`ct-line-mark`** - Line series
- **`ct-area-mark`** - Filled area
- **`ct-bar-mark`** - Bar/column chart
- **`ct-dot-mark`** - Scatter/dot plot
### ct-chart Properties
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `height` | `number` | `200` | Chart height in px. Width fills container. |
| `marks` / `$marks` | `MarkConfig[]` | `[]` | Programmatic marks (rendered below children) |
| `xAxis` | `boolean` | `false` | Show x-axis |
| `yAxis` | `boolean` | `false` | Show y-axis |
| `xType` | `"linear"\|"time"\|"band"` | auto | Scale type (auto-detected from data) |
| `yType` | `"linear"\|"log"` | auto | Y scale type |
| `xDomain` | `[min, max]` | auto | Override x domain |
| `yDomain` | `[min, max]` | auto | Override y domain |
| `crosshair` | `boolean` | `true` | Show crosshair on hover |
### Mark Properties (shared)
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `data` / `$data` | `number[]\|object[]` | required | Data array |
| `x` | `string` | index | Key for x accessor |
| `y` | `string` | value | Key for y accessor |
| `color` | `string` | `"#6366f1"` | Stroke/fill color |
| `label` | `string` | - | Label for tooltip |
**ct-line-mark** adds: `strokeWidth` (default 2), `curve` (`"linear"`, `"step"`, `"monotone"`, `"natural"`)
**ct-area-mark** adds: `opacity` (default 0.2), `curve`, `y2` (baseline)
**ct-bar-mark** adds: `opacity` (default 1), `barPadding` (0-1, default 0.2)
**ct-dot-mark** adds: `radius` (default 3)
### Events
| Event | Detail | Description |
|-------|--------|-------------|
| `ct-hover` | `{ x, y, dataX, dataY, nearest }` | Mouse over chart |
| `ct-click` | `{ x, y, dataX, dataY, nearest }` | Chart clicked |
| `ct-leave` | `{}` | Mouse left chart |
### Usage
```tsx
// Sparkline (inline, no axes)
// Line chart with axes
// Layered area + line
// Bar chart
// Multi-series
// Simple number array (auto-indexed x)
```
### Notes
- **Data auto-detection:** Number arrays auto-index. String x-values use band scale. Date/ISO strings use time scale.
- **Responsive width:** Chart fills its container width. Use CSS to control.
- **Crosshair:** Enabled by default. Shows nearest data point on hover.
---
## Limitations
### SVG Not Supported
SVG elements (`