> ## Documentation Index
> Fetch the complete documentation index at: https://docs.datazone.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Components

> Detailed reference for components in Datazone Intelligent Apps

## Common Properties

All chart types share these properties:

| Property | Type | Description |
| - | - | - |
| `type` | string | Chart type: `number`, `line`, `bar`, `pie`, `radial`, `table`, `data_table`, `item_list`, `composed`, `heatmap`, or `scatter` |
| `name` | string | Unique identifier for the chart |
| `title` | string | Display title |
| `description` | string | Optional description |
| `query` | string | SQL query that provides chart data |
| `chart_config` | object | (Optional) Chart configuration options |

### Chart Configuration

The `chart_config` object allows you to customize chart appearance and behavior:

| Property | Type | Description |
| - | - | - |
| `show_legend` | boolean | (Optional) Whether to show the chart legend (default: false) |
| `show_labels` | boolean | (Optional) Whether to show labels on the chart (default: false) |
| `fill_donut` | boolean | (Optional, pie charts only) Whether to fill the donut chart (default: false) |
| `is_stacked` | boolean | (Optional, bar/pie charts) Whether to stack elements (default: false) |
| `line_type` | string | (Optional, line/composed charts) Line style: `linear`, `monotone`, `step`, `natural` |
| `fill_area` | boolean | (Optional, line charts only) Whether to fill the area under the line |
| `custom_chart_type` | string | (Optional, custom charts only) Custom chart type identifier |
| `sub_expression` | string | (Optional, number/radial charts) Sub-expression for metric calculation |
| `page_size` | integer | (Optional, data\_table charts) Number of rows per page |
| `layout` | string | (Optional, bar charts) Layout orientation: `horizontal` or `vertical` |
| `hide_expression` | string | (Optional, all chart types) JavaScript expression to conditionally hide the chart based on data (e.g., `"(data) => {return data.length < 5}"`) |

### Metric Properties

Each entry in a chart's `metrics` list supports the following properties:

| Property | Type | Description |
| - | - | - |
| `name` | string | Column name from the query result that holds the metric value |
| `label` | string | Display label for the metric |
| `format` | string | (Optional) Number format string for the value |
| `icon` | string | (Optional, number/radial charts only) Lucide icon name |
| `icon_variant` | string | (Optional, number/radial charts only) One of: `default`, `neutral`, `success`, `warning`, `error` |
| `axis_name` | string | (Optional, line/bar/composed charts) Axis to assign this metric to |
| `composed_type` | string | (Optional, composed charts) Series type: `bar` or `line` |
| `submetric_name` | string | (Optional, number/radial charts only) Name of the submetric to display |
| `submetric_type` | string | (Optional, number/radial charts only) Submetric display: `plain`, `change`, `delta` |
| `color` | string | (Optional) Custom color for this metric's series, overriding the theme palette (e.g., a hex code like `#2563eb` or a chart color variable) |
| `show_label` | boolean | (Optional) Whether to show the data label for this specific metric, overriding the chart-level `show_labels` setting |

<Note>`show_label` is a per-metric override that controls labels for a single series, whereas `chart_config.show_labels` toggles labels for the whole chart. Use `color` to give an individual series a distinct color instead of the default theme palette.</Note>

## Number Charts

Number charts display a single metric value, often used for KPIs.

<Frame>
  <img src="https://mintcdn.com/datazone/YFojkVY1avf3O4H9/images/light/number-chart-example.png?fit=max&auto=format&n=YFojkVY1avf3O4H9&q=85&s=fffcba2c06ed6c34d0e52429a114f69a" alt="Intelligent App Example" width="493" height="143" data-path="images/light/number-chart-example.png" />
</Frame>

You can add an icon next to the number using any [Lucide icon](https://lucide.dev/icons/), and control its color with `icon_variant`.
Required properties for number metrics:

| Property | Type | Description |
| - | - | - |
| `icon` | string | (Optional) Lucide icon name (e.g., `check`, `star`) |
| `icon_variant` | string | (Optional) One of: `default`, `neutral`, `success`, `warning`, `error` |

For detailed information, check the [YAML reference](./yaml-reference#charts).

<Note>Datazone currently uses Lucide version 0.515.0. If you try to use an icon introduced in a newer version, it may cause an error or not display correctly. See the [Lucide icon gallery](https://lucide.dev/icons/) for available icons in 0.515.0.</Note>

```yaml theme={null}
- type: number
  name: completed_tasks
  title: "Completed Tasks"
  query: "SELECT count(*) as completed FROM tasks WHERE status = 'done'"
  metrics:
    - name: completed
      label: Completed Tasks
      icon: check
      icon_variant: success
      format: "0"
```

## Composed Charts

Composed charts allow you to combine line and bar series in a single chart, each mapped to a specific axis. Use the `axis` property to define axes, and set `axis_name` and `composed_type` for each metric.

<Frame>
  <img src="https://mintcdn.com/datazone/YFojkVY1avf3O4H9/images/light/composed-chart-example.png?fit=max&auto=format&n=YFojkVY1avf3O4H9&q=85&s=d1c5fd7c35fef9e24e072f8dc93674e3" alt="Intelligent App Example" width="2056" height="1180" data-path="images/light/composed-chart-example.png" />
</Frame>

```yaml theme={null}
- type: composed
  name: top_products_composed
  title: Top Performing Products
  description: Top 10 products by revenue
  query: |
    SELECT 
      ProductName as product,
      SUM(OrderLineTotalAmount) as revenue,
      AVG(OrderLineTotalAmount) as avg_revenue
    FROM consolidated_sales_df_299ceb 
    WHERE 1=1
    {% if region_filter is defined %}
    AND CustomerRegion = '{{ region_filter }}'
    {% endif %}
    {% if product_group_filter is defined %}
    AND ProductGroup = '{{ product_group_filter }}'
    {% endif %}
    GROUP BY ProductName
    ORDER BY revenue DESC
    LIMIT 10;
  axis:
    - name: left
    - name: right
      position: right
  dimensions:
    - name: product
      label: Product
  metrics:
    - name: revenue
      label: Revenue
      axis_name: "left"
      composed_type: "bar"
      format: "$0,0.00"
    - name: avg_revenue
      label: "Average Revenue"
      axis_name: "right"
      composed_type: "line"
      format: "0,0[.]00 $"
```

## Line Charts

Line charts visualize trends over time or continuous data. You can use the `axis` property to define multiple axes and assign metrics to them using `axis_name`. Use `fill_area` to control whether the area under the line is filled.

```yaml theme={null}
- type: line
  name: sales_trend
  title: "Sales Trend"
  query: "SELECT date, sum(amount) as total, avg(amount) as avg FROM sales GROUP BY date ORDER BY date"
  chart_config:
    fill_area: true
  axis:
    - name: left
    - name: right
      position: right
  dimensions:
    - name: date
      label: Date
  metrics:
    - name: total
      label: Daily Sales
      axis_name: left
    - name: avg
      label: Average Sales
      axis_name: right
```

### Line Chart Configuration

| Property | Type | Description |
| - | - | - |
| `fill_area` | boolean | (Optional) Whether to fill the area under the line (default: true) |

## Bar Charts

Bar charts compare values across categories. You can use the `affected_filter` attribute under a dimension to allow users to update a filter by clicking a bar.

### Standard Bar Charts

```yaml theme={null}
- type: bar
  name: sales_by_country
  title: Sales by Country
  query: SELECT country, sum(amount) as total FROM sales GROUP BY country
  dimensions:
    - name: country
      label: Country
      affected_filter: country_filter
  metrics:
    - name: total
      label: Total Sales
```

### Dynamic Charts with Chart Inputs

You can add **interactive controls** directly to charts using `chart_inputs`. This allows users to modify queries dynamically using **dropdown menus** without leaving the chart view.

<Frame>
  <img src="https://mintcdn.com/datazone/4SIOmB9951t8k5Yg/images/dynamic-chart-input.png?fit=max&auto=format&n=4SIOmB9951t8k5Yg&q=85&s=3a464e7471ca015f6fe2425147bef678" alt="Dynamic Chart Input Example" width="1858" height="1042" data-path="images/dynamic-chart-input.png" />
</Frame>

Chart inputs work seamlessly with **Jinja templating** in your queries, enabling dynamic GROUP BY clauses, WHERE conditions, and more:

```yaml theme={null}
- type: bar
  name: top_by_revenue
  title: Top 10 by Revenue
  chart_inputs:
    - type: dropdown
      name: group_by_column
      label: Group By
      default: Product
      options:
        - Product
        - Customer
  query: |
    SELECT 
      {% if group_by_column == 'Product' %}
      ProductName as group,
      {% else %}
      CustomerName as group,
      {% endif %}
      SUM(OrderLineTotalAmount) as revenue
    FROM consolidated_sales_df
    WHERE 1=1
    {% if date_from is defined %}
    AND OrderDate >= '{{ date_from }}'
    {% endif %}
    {% if group_by_column == 'Product' %}
    GROUP BY ProductName 
    {% else %}
    GROUP BY CustomerName
    {% endif %}
    ORDER BY revenue DESC 
    LIMIT 10
  dimensions:
    - name: group
      label: Group
  metrics:
    - name: revenue
      label: Revenue
      format: "$0,0.00"
```

#### Chart Input Properties

| Property | Type | Description |
| - | - | - |
| `type` | string | Input type (currently supports `dropdown`) |
| `name` | string | Variable name accessible in the query via Jinja |
| `label` | string | Display label shown in the UI |
| `default` | string | Default selected value |
| `options` | array | (Optional) List of static options for the dropdown |
| `options_query` | string | (Optional) SQL query to fetch dynamic options (cannot be used with `options`) |

<Tip>
  Chart inputs are perfect for allowing users to **switch dimensions** (e.g., by Product vs. by Customer) or **change grouping levels** (e.g., daily vs. monthly) without creating multiple separate charts.
</Tip>

#### Dynamic Chart Input Options

Chart inputs can fetch their dropdown options dynamically from database queries, enabling data-driven dropdowns and cascading input scenarios. This is particularly useful when:

* **Filter-Dependent Options**: You want the available options to change based on active tab-level filters
* **Cascading Inputs**: One input's value should affect another input's available options
* **Data-Driven Dropdowns**: Options need to come from your database rather than being hard-coded

**Example: Cascading Inputs**

```yaml theme={null}
chart_inputs:
  - type: dropdown
    name: country
    label: Select Country
    default: USA
    options:
      - USA
      - Canada
      - UK
  
  - type: dropdown
    name: region
    label: Select Region
    options_query: "SELECT DISTINCT region FROM sales_data WHERE country = '{{ country }}' ORDER BY region"
```

In this example:

1. User selects a country from the first dropdown (static options)
2. The second dropdown automatically fetches regions for the selected country
3. The `options_query` has access to the `country` variable from the first input

**Example: Filter-Dependent Options**

```yaml theme={null}
chart_inputs:
  - type: dropdown
    name: product_category
    label: Select Category
    options_query: "SELECT DISTINCT category FROM products WHERE date >= '{{ start_date }}' ORDER BY category"
```

Here, the available categories change based on the tab-level `start_date` filter value.

<Note>
  You cannot define both `options` and `options_query` for the same chart input. The `options_query` can reference both tab-level filter variables and other chart input values using Jinja template syntax.
</Note>

### Stacked Bar Charts

Stacked bar charts allow you to show multiple metrics stacked on top of each other for each category. Use the `chart_config.stacked` property to enable stacking:

```yaml theme={null}
- type: bar
  name: monthly_order_performance
  title: Monthly Order Performance
  query: |
    SELECT 
      month,
      sum(orders) as orders,
      sum(customers) as customers
    FROM sales_data
    GROUP BY month
    ORDER BY month
  chart_config:
    is_stacked: true
    show_legend: true
  dimensions:
    - name: month
      label: Month
  metrics:
    - name: orders
      label: Orders
    - name: customers
      label: Customers
```

<Frame>
  <img src="https://mintcdn.com/datazone/YFojkVY1avf3O4H9/images/light/stacked-example.png?fit=max&auto=format&n=YFojkVY1avf3O4H9&q=85&s=6e0ce746f9658daee4f25b577024fb71" alt="Stacked Bar Chart Example" width="1354" height="664" data-path="images/light/stacked-example.png" />
</Frame>

### Chart Configuration for Bar Charts

| Property | Type | Description |
| - | - | - |
| `is_stacked` | boolean | (Optional) Whether to stack bars on top of each other |
| `show_legend` | boolean | (Optional) Whether to show the legend for multi-series charts |
| `show_labels` | boolean | (Optional) Whether to show labels on the bars |

### Vertical Layout Bar Charts

You can create vertical layout bar charts by setting `layout: vertical` in the chart configuration:

```yaml theme={null}
- type: bar
  name: monthly_order_performance
  title: Monthly Order Performance
  query: |
    SELECT 
      month,
      sum(orders) as orders,
      sum(customers) as customers
    FROM sales_data
    GROUP BY month
    ORDER BY month
  axis:
    - name: top_axis
      position: top
    - name: bottom_axis
      position: bottom
  chart_config:
    layout: vertical
    show_legend: true
  dimensions:
    - name: month
      label: Month
  metrics:
    - name: orders
      label: Orders
      axis_name: top_axis
    - name: customers
      label: Customers
      axis_name: bottom_axis
```

## Pie Charts

Pie charts show part-to-whole relationships. You can use the `affected_filter` attribute under a dimension to allow users to update a filter by clicking a pie slice.

```yaml theme={null}
- type: pie
  name: sales_distribution
  title: Sales Distribution
  query: SELECT category, sum(amount) as total FROM sales GROUP BY category
  dimensions:
    - name: category
      label: Category
      affected_filter: category_filter
  metrics:
    - name: total
      label: Total Sales
```

### Donut Charts

You can create donut charts by setting `fill_donut: false` in the chart configuration:

```yaml theme={null}
- type: pie
  name: revenue_by_region
  title: Revenue by Region
  query: SELECT region, sum(revenue) as total_revenue FROM sales GROUP BY region
  chart_config:
    fill_donut: false
    show_labels: true
    show_legend: false
  dimensions:
    - name: region
      label: Region
  metrics:
    - name: total_revenue
      label: Total Revenue
      format: "$0,0.00"
```

## Radial Charts

Radial charts display progress or completion metrics in a circular format. They require exactly two metrics: the first metric represents the current value (displayed with a label), and the second metric represents the total or maximum value.

<Frame>
  <img src="https://mintcdn.com/datazone/YFojkVY1avf3O4H9/images/light/radial-chart-example.png?fit=max&auto=format&n=YFojkVY1avf3O4H9&q=85&s=48e58eaca774e9782ef4d36d53c26228" alt="Radial Chart Example" width="568" height="481" data-path="images/light/radial-chart-example.png" />
</Frame>

```yaml theme={null}
- type: radial
  name: task_completion
  title: "Task Completion"
  description: "Current progress on project tasks"
  query: "SELECT sum(case when status = 'completed' then 1 else 0 end) as completed_tasks, count(*) as total_tasks FROM tasks"
  metrics:
    - name: completed_tasks
      label: "Completed Tasks"
      format: "0,0"
    - name: total_tasks
      label: "Total Tasks"
      format: "0,0"
```

## Table Charts

Table charts display raw data in tabular format.

<Frame>
  <img src="https://mintcdn.com/datazone/YFojkVY1avf3O4H9/images/light/table-chart-example.png?fit=max&auto=format&n=YFojkVY1avf3O4H9&q=85&s=ec726919fb839723bbc012ef2d78a74c" alt="Intelligent App Example" width="733" height="469" data-path="images/light/table-chart-example.png" />
</Frame>

```yaml theme={null}
- type: table
  name: recent_orders
  title: "Recent Orders"
  description: "Last 100 orders placed"
  query: "SELECT * FROM orders ORDER BY date DESC LIMIT 100"
```

## Data Table Charts

Data Table charts provide advanced tabular display with custom formatting and alignment for each column.

* **Sorting**: Users can click on column headers to sort the table by any dimension or metric, ascending or descending.
* **Pagination**: Large result sets are automatically split into pages, allowing users to navigate through data efficiently.

This makes `data_table` ideal for exploring large datasets interactively within your Intelligent App.

<Frame>
  <img src="https://mintcdn.com/datazone/YFojkVY1avf3O4H9/images/light/data-table-chart-example.png?fit=max&auto=format&n=YFojkVY1avf3O4H9&q=85&s=46adbcda5e17290c8032d1f0fa7b3928" alt="Intelligent App Example" width="1308" height="509" data-path="images/light/data-table-chart-example.png" />
</Frame>

```yaml theme={null}
- type: data_table
  name: detailed_orders
  title: "Detailed Orders"
  description: "All order details with formatting"
  query: "SELECT order_id, amount, status FROM orders ORDER BY date DESC LIMIT 100"
  dimensions:
    - name: order_id
      label: Order ID
      table_align: left
    - name: amount
      label: Amount
      number_format: "$0,0.00"
      table_align: right
    - name: status
      label: Status
      table_align: left
```

### Chart Config

Chart configuration options allow you to customize the appearance and behavior of your charts. Common properties include:

* `page_size`: (For `data_table`) Number of rows per page

```yaml theme={null}
chart_config:
  page_size: 20
```

### Formatting

Use the `format` attribute under each metric to control how numbers are displayed:

| Format | Example | Result |
| - | - | - |
| `"0,0"` | 1234 | "1,234" |
| `"$0,0.00"` | 1234.5 | "\$1,234.50" |
| `"0.0%"` | 0.123 | "12.3%" |
| `"0.00a"` | 1234 | "1.23k" |

### Dimensions

| Property | Type | Description |
| - | - | - |
| `name` | string | Unique identifier for the dimension |
| `label` | string | Display label for the dimension |
| `number_format` | string | (Optional) Number format for this dimension |
| `table_align` | string | (Optional) Table alignment: `left` or `right` |

## Heatmap Charts

Heatmap charts visualize data where individual values are represented as colors. They require exactly two dimensions and one metric. Heatmaps are ideal for showing relationships between two categorical dimensions with a numeric value determining the color intensity.

<Frame>
  <img src="https://mintcdn.com/datazone/5aX7TF5X6Kr7I81Q/images/light/heatmap-chart-example.png?fit=max&auto=format&n=5aX7TF5X6Kr7I81Q&q=85&s=7a1ae8c3550496d4cedbd41637e9c4e7" alt="Heatmap Chart Example" width="1503" height="540" data-path="images/light/heatmap-chart-example.png" />
</Frame>

```yaml theme={null}
- type: heatmap
  name: sales_by_region_product
  title: "Sales by Region and Product"
  description: "Sales distribution across regions and products"
  query: |
    SELECT 
      region,
      product_category,
      SUM(sales_amount) as total_sales
    FROM sales_data
    GROUP BY region, product_category
    ORDER BY region, product_category
  chart_config:
    show_legend: true
  dimensions:
    - name: region
      label: Region
    - name: product_category
      label: Product Category
  metrics:
    - name: total_sales
      label: Total Sales
      format: "$0,0.00"
```

## Scatter Plot Charts

Scatter plot charts visualize the relationship between two numerical variables. Each point represents a data record, positioned according to the values of two metrics on the x and y axes. Scatter plots are ideal for identifying correlations, patterns, or outliers in your data.

<Frame>
  <img src="https://mintcdn.com/datazone/96e4fGEtSfybTDnt/images/light/scatter-chart-example.png?fit=max&auto=format&n=96e4fGEtSfybTDnt&q=85&s=a265022abf66ce67a699ee1d7a7ef427" alt="Scatter Chart Example" width="1563" height="477" data-path="images/light/scatter-chart-example.png" />
</Frame>

```yaml theme={null}
- type: scatter
  name: example_scatter_chart
  title: Sales Profiles by Countries
  query: |
    SELECT 
      CustomerCountry,
      ROUND(AVG(UnitPrice), 2) as avg_unit_price,
      ROUND(SUM(InvoiceTotalAmount), 2) as total_invoice_count
    FROM consolidated_sales_df_9cb4a3
    GROUP BY CustomerCountry
    ORDER BY total_invoice_count DESC
    LIMIT 20;
  dimensions:
    - name: CustomerCountry
      label: "Country"
  metrics:
    - name: avg_unit_price
      label: Average Unit Price
    - name: total_invoice_count
      label: Total Invoice Count
  chart_config:
    show_labels: true
```

<Note>Scatter plots require exactly one dimension and two to three metrics. The first metric is plotted on the x-axis, the second metric on the y-axis, and an optional third metric can be used for additional visualization properties.</Note>

## Advanced Features

### Multi-Series Charts

For line and bar charts, you can include multiple metrics:

```yaml theme={null}
- type: line
  name: revenue_vs_cost
  title: "Revenue vs Cost"
  query: "SELECT date, sum(revenue) as rev, sum(cost) as cost FROM financials GROUP BY date"
  dimensions:
    - name: date
      label: Date
  metrics:
    - name: rev
      label: Revenue
    - name: cost
      label: Cost
```

## Text (Markdown)

Render rich text using Markdown in your Intelligent App.

<Frame>
  <img src="https://mintcdn.com/datazone/5aX7TF5X6Kr7I81Q/images/light/markdown-example.png?fit=max&auto=format&n=5aX7TF5X6Kr7I81Q&q=85&s=2c06eb4b273d33db49d145da0f231a7e" alt="Markdown component example" width="1500" height="891" data-path="images/light/markdown-example.png" />
</Frame>

````yaml theme={null}
components:
  texts:
    - name: features_md
      title: Features
      content: |
        ## Key Features

        ### Data Analysis
        - Real-time data processing
        - Advanced analytics
        - Custom visualizations

        ### User Experience
        - Intuitive interface
        - Responsive design
        - Mobile-friendly

        ```sql
        SELECT 
          id,
          name,
          created_at
        FROM users 
        WHERE active = true;
        ```

layout:
  tabs:
    - name: features
      title: Features
      items:
        - type: text
          name: features_md
          span: 12
````

For full attributes, see the [YAML Reference: Texts](/reference/intelligent-apps/yaml-reference#texts).

## Item List

List-style chart for items (orders, activity): icon, title, description, optional timestamp and badge; opens detail modal on click.

<Frame>
  <img src="https://mintcdn.com/datazone/_w_UGz6h1rqewXYG/images/light/item-list-component.png?fit=max&auto=format&n=_w_UGz6h1rqewXYG&q=85&s=284b8c13fe6c383ed75c97a4155d9541" alt="Item List component example" width="758" height="570" data-path="images/light/item-list-component.png" />
</Frame>

```yaml theme={null}
components:
  charts:
    - type: item_list
      name: recent_orders_list
      title: "Recent Orders"
      query: |
        SELECT
          'ShoppingCart' AS icon,
          'text-indigo-600' AS icon_color,
          concat('Order #', order_id) AS title,
          concat(customer_name, ' | ', product_name, ' (Qty: ', quantity, ')') AS description,
          formatDate(order_date, 'MMM dd, yyyy') AS timestamp,
          payment_status AS badge_text,
          CASE
            WHEN payment_status = 'Paid' THEN 'success'
            WHEN payment_status = 'Unpaid' THEN 'warning'
            ELSE 'neutral'
          END AS badge_variant
        FROM orders
        ORDER BY order_date DESC
        LIMIT 20;

layout:
  tabs:
    - name: overview
      title: Overview
      items:
        - type: chart
          name: recent_orders_list
          span: 12
```

For full attributes and layout usage, see the [YAML Reference: Item Lists](/reference/intelligent-apps/yaml-reference#item-lists).

## Widgets

When none of the chart types above fit, render **your own React component** in the app grid with a widget. Widgets are TSX components that Datazone compiles in the browser at runtime, placed in the layout with `type: widget`. Attach a SQL query and its rows arrive as the component's `data` prop.

```yaml theme={null}
components:
  widgets:
    - name: top_customers_widget
      title: Top Customers
      source_type: file
      file: widgets/TopCustomers.tsx
      query: |
        SELECT CustomerName as customer, SUM(OrderLineTotalAmount) as revenue
        FROM consolidated_sales_df
        GROUP BY CustomerName
        ORDER BY revenue DESC
        LIMIT 5

layout:
  tabs:
    - name: overview
      title: Overview
      items:
        - type: widget
          name: top_customers_widget
          span: 6
          height: 320
```

The container gives your widget a bordered, padded surface and scrolls it when `height` is set. Widgets can also be nested inside a `chart-group`, next to charts.

<Note>`title` and `description` are metadata on the definition — no header is rendered for you. Your component owns its entire visual output, so render the heading yourself.</Note>

### Source Types

With `source_type: inline` (the default) the component code lives in the app YAML under `source`. With `source_type: file` it lives in a `.tsx` file in your project repository, referenced by a path relative to the repository root and read when the app is loaded.

```yaml theme={null}
widgets:
  # Inline: must define `source`, must not define `file`
  - name: status_banner
    title: Status Banner
    source_type: inline
    source: |
      import React from 'react'

      export default function StatusBanner({ appContext }) {
        return <div>Active theme: {appContext.theme}</div>
      }

  # File: must define `file`, must not define inline `source`
  - name: revenue_breakdown
    title: Revenue Breakdown
    source_type: file
    file: widgets/RevenueBreakdown.tsx
```

<Tip>Prefer `file` widgets for anything non-trivial: you get editor support, syntax highlighting, and reviewable diffs, and the same component can be reused across apps.</Tip>

### Component Contract

Your source must **`export default`** a React component. Datazone passes it two props:

| Prop | Type | Description |
| - | - | - |
| `data` | array | Rows returned by the widget's `query`, keyed by column alias. Empty array when no `query` is defined |
| `appContext` | object | `filters` (current filter values by filter name), `setFilter(name, value)`, and `theme` |

`setFilter` makes widgets **interactive participants** in the app rather than display surfaces: a click inside your component can drive every chart and filter, the same way `affected_filter` does for bar and pie charts.

```tsx theme={null}
import React from "react"
import { Card, CardContent } from "@datazone/widget-sdk"

export default function RegionPicker({ data, appContext }) {
  return (
    <Card>
      <CardContent>
        {data.map((row) => (
          <button key={row.region} onClick={() => appContext.setFilter("region_filter", row.region)}>
            {row.region}
          </button>
        ))}
      </CardContent>
    </Card>
  )
}
```

### Available Imports

The widget runtime resolves a fixed set of imports — anything else fails to compile.

| Module | Contents |
| - | - |
| `react` | The full React API — hooks, `Fragment`, and the default export |
| `@datazone/widget-sdk` | `Card`, `CardHeader`, `CardTitle`, `CardDescription`, `CardContent` |

<Warning>Third-party packages cannot be installed or imported inside a widget — no chart libraries, data-fetching clients, or utility libraries. Build with React and the widget SDK, and let the widget's `query` do the data work.</Warning>

### Styling

SDK components inherit the active theme automatically, so `Card` and friends match the rest of the dashboard, including [custom themes](/reference/intelligent-apps/yaml-reference#style-configuration). For your own styling, prefer inline `style` objects: utility classes are resolved from the platform's precompiled stylesheet, so a class the platform itself never uses may not exist at runtime.

Theme CSS variables come in two shapes, and mixing them up produces an invalid color:

| Variables | Value | Use as |
| - | - | - |
| `--chart-1` … `--chart-5` | Complete color | `var(--chart-1)` |
| `--foreground`, `--muted`, `--muted-foreground`, `--border`, `--accent`, `--success`, `--warning`, `--error` | HSL components | `hsl(var(--error))` |

```tsx theme={null}
<div style={{ backgroundColor: "var(--chart-3)", color: "hsl(var(--muted-foreground))" }} />
```

<Note>`--primary` and `--ring` are redefined by the color themes, so their shape depends on the active theme. Use `--chart-1` … `--chart-5` for a theme-following accent, and the semantic variables above for text, borders, and status colors.</Note>

### Widget Queries

A widget's `query` behaves like a chart query: **Jinja templating** with the app's current filter variables (use the same `{% if ... is defined %}` guards), **cached** per the app's `cache` and `cache_ttl` config, re-run whenever a filter changes, and restricted to `SELECT` statements executed with the permissions of the user viewing the app.

```yaml theme={null}
widgets:
  - name: filtered_orders
    title: Filtered Orders
    source_type: file
    file: widgets/FilteredOrders.tsx
    query: |
      SELECT OrderDate as order_date, CustomerName as customer, OrderLineTotalAmount as amount
      FROM consolidated_sales_df
      WHERE 1=1
      {% if order_date is defined %}
      AND OrderDate >= '{{ order_date }}'
      {% endif %}
      ORDER BY OrderDate DESC
      LIMIT 50
```

A widget without a `query` never hits the database — use that for purely presentational widgets, or ones that only react to `appContext`.

<Note>Widget queries read **tab-level filter variables** only. [Chart inputs](#dynamic-charts-with-chart-inputs) are a chart-level feature and are not available to widgets — render your own controls with React state instead.</Note>

### Validation and Errors

At **load time**, the app definition is rejected — with an error naming the widget — when a layout item references a widget that is not defined in `components.widgets`, when the `source` / `file` rules above are broken, or when a `file` widget points at a path that does not exist in the repository.

At **render time**, compile and runtime errors appear as an inline message in the widget's slot. A broken widget only breaks itself; the surrounding tab, charts, and filters keep working.

<Tip>Widget code is not validated when the app is saved — it is compiled in the viewer's browser. Open the app after deploying a new widget to confirm it renders. Widgets work in [embedded apps](/reference/intelligent-apps/embedding) too.</Tip>

For full attributes and layout usage, see the [YAML Reference: Widgets](/reference/intelligent-apps/yaml-reference#widgets).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.