Metadata-Version: 2.3
Name: encinitas
Version: 1.0.0
Summary: Add your description here
Author: Bret Beatty
Author-email: Bret Beatty <bbeatty14@gmail.com>
Requires-Dist: dash>=4.1.0
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# encinitas

Reusable Dash components for dashboards.

## KPI cards

```python
from dash import Dash, html
from encinitas import (
    assets_path,
    bullet_chart,
    bullet_chart_stack,
    kpi_card,
    sparkline,
    sparkline_stack,
)

app = Dash(__name__, assets_folder=assets_path())

app.layout = html.Div(
    [
        kpi_card(
            "Revenue",
            "$42k",
            delta=3.2,
            delta_text="3.2% vs last week",
            subtitle="Trailing 7 days",
            tooltip="Recognized revenue across closed-won accounts.",
            tooltip_placement="bottom",
            tooltip_max_width=240,
            id="revenue-card",
        ),
        kpi_card(
            "Churn",
            "1.8%",
            delta=-0.4,
            delta_text="0.4 pts better",
            tone="positive",
            delta_tone="positive",
            tooltip="A decrease in churn is favorable.",
        ),
        kpi_card(
            "Open tickets",
            "118",
            delta=0,
            delta_text="No change",
        ),
    ],
    style={
        "display": "grid",
        "gap": "16px",
        "gridTemplateColumns": "repeat(auto-fit, minmax(220px, 1fr))",
    },
)
```

`kpi_card` derives tone from `delta` by default:

- positive values use the positive color
- negative values use the negative color
- zero or missing values use the neutral color

Pass `tone="positive"`, `tone="negative"`, `tone="neutral"`, or
`tone="warning"` to override that behavior. The colored left border is off by
default; pass `show_border_tone=True` to show it. Use `colors={...}` and the
`*_style` keyword arguments to customize the card without replacing the
component. KPI cards default to a fixed, responsive width; pass `width=320` or
`width="18rem"` to adjust it.

For lower-is-better metrics, keep the real direction and color the outcome:

```python
kpi_card(
    "Churn",
    "1.8%",
    delta=-0.4,
    delta_text="0.4 pts better",
    tone="positive",
    delta_tone="positive",
)
```

Use `tooltip="..."` for card-level hover and focus content. Tooltips are
rendered as Dash components inside the card, so strings and richer `html.*`
content both work. Use `tooltip_placement="top"`, `"right"`, `"bottom"`, or
`"left"` to adjust placement. Use `tooltip_max_width=240` or
`tooltip_max_width="18rem"` to control wrapping.

## Bullet charts

`bullet_chart` renders a standalone horizontal chart with no x-axis, y-axis,
or tick marks. It includes a wide grey background bar, a narrower actual bar,
and a target marker.

```python
bullet_chart(
    actual=72,
    target=80,
    maximum=100,
    background=95,
)
```

Actual bar color is based on performance against target by default. For
lower-is-better metrics, set `favorable_direction="lower"`:

```python
bullet_chart(
    actual=42,
    target=50,
    maximum=80,
    favorable_direction="lower",
)
```

For a normal chart-like set of rows, use `bullet_chart_stack`. The stack uses
a shared scale by default, so categories line up cleanly.

```python
bullet_chart_stack(
    [
        {
            "label": "California",
            "actual": 72,
            "prior_year": 68,
            "target": 80,
            "background": 95,
        },
        {
            "label": "Texas",
            "actual": 64,
            "prior_year": 61,
            "target": 70,
            "background": 88,
        },
        {
            "label": "Florida",
            "actual": 81,
            "prior_year": 74,
            "target": 76,
            "background": 92,
        },
    ],
    headers=("State", "Sales"),
    maximum=100,
    value_formatter=lambda value: f"${value:.0f}M",
    tooltip_placement="bottom",
    tooltip_max_width=260,
    aria_label="State sales against target",
)
```

Headers are optional and off by default. Row tooltips are also optional; add
`"tooltip": ...` to any row to show card-style hover and focus content for that
row. The trailing actual/target value column is off by default; pass
`show_values=True` to display it.

When a row includes `prior_year`, a detail tooltip is generated automatically.
It shows actual, prior year, target, percent vs prior year, and percent vs
target. Set `"tooltip": False` on a row to suppress the generated tooltip, or
set `"tooltip": html.Div(...)` to replace it with custom content.

Use `value_formatter` and `percent_formatter` to format generated tooltip
values:

```python
bullet_chart_stack(
    rows,
    value_formatter=lambda value: f"${value:.0f}M",
    percent_formatter=lambda value: f"{value:+.1f}%",
)
```

## Sparklines

`sparkline` renders a compact time-series trend line with no axes or tick
marks.

```python
sparkline(
    [42, 44, 43, 49, 47, 52, 56, 54, 59],
    display_width=128,
    line_color="#0f766e",
    aria_label="Sales trend from 42 to 59",
    tooltip_placement="bottom",
    value_formatter=lambda value: f"${value:.0f}M",
)
```

The line color is derived from the first and last values by default. Use
`tone="positive"`, `tone="negative"`, or `tone="neutral"` to override the tone,
or pass `line_color="#0f766e"` to set the stroke directly. Use
`display_width=128` or `display_width="8rem"` to control rendered width without
changing the time-series scaling.
Sparkline tooltips are generated by default and show start, end, min, max, and
percent change. Set `tooltip=False` to hide the tooltip or `tooltip=...` to
provide custom content. Sparklines do not show an endpoint marker by default;
pass `show_endpoint=True` if you want one.

Use `sparkline_stack` for grouped time-series rows, such as states:

```python
sparkline_stack(
    [
        {"label": "California", "values": [42, 44, 43, 49, 47, 52, 56]},
        {"label": "Texas", "values": [38, 39, 41, 40, 43, 45, 46]},
        {
            "label": "Florida",
            "values": [35, 37, 36, 39, 42, 44, 48],
            "line_color": "#0f766e",
        },
    ],
    headers=("State", "Sales trend"),
    display_width=128,
    value_formatter=lambda value: f"${value:.0f}M",
)
```

Stacked sparklines use a shared vertical scale by default so rows are
comparable. Pass `shared_scale=False` to scale each row independently.
The delta/change is available in the generated tooltip. If you explicitly want
a visible delta column, pass `show_delta=True`.

## API reference

### `assets_path()`

Returns the packaged Dash assets directory. Use it when creating the app:

```python
app = Dash(__name__, assets_folder=assets_path())
```

### `kpi_card(title, value, **kwargs)`

Builds a rounded KPI card with optional tone-colored left border, optional
delta row, subtitle, custom children, and card-level tooltip.

Common arguments:

- `delta`: Numeric change used for default tone and direction.
- `delta_text`: Text displayed beside the delta icon.
- `delta_tone`: Override delta row color independently from direction.
- `delta_direction`: Force `"up"`, `"down"`, or `"flat"`.
- `subtitle`: Secondary text below the KPI.
- `tone`: Override card tone: `"positive"`, `"negative"`, `"neutral"`, or `"warning"`.
- `tone_thresholds`: `(negative, positive)` thresholds for deriving tone from `delta`.
- `show_border_tone`: Show the tone-colored left border. Defaults to `False`.
- `width`: Card width as a number of pixels or CSS size string.
- `tooltip`: Card-level hover/focus content. Accepts strings or Dash components.
- `tooltip_placement`: `"top"`, `"right"`, `"bottom"`, or `"left"`.
- `tooltip_max_width`: Number of pixels or CSS size string.
- `colors`: Override tone colors.
- `children`: Extra Dash components appended inside the card.
- `*_style`: Style overrides for card parts.

### `delta_indicator(value=None, **kwargs)`

Builds a small delta row with an up, down, or flat icon.

Common arguments:

- `value`: Numeric value used for default direction and text.
- `text`: Override displayed text.
- `direction`: Force `"up"`, `"down"`, or `"flat"`.
- `tone`: Override color tone.
- `colors`: Override tone colors.

### `bullet_chart(actual, target, **kwargs)`

Builds a standalone horizontal bullet chart with no axes or tick marks.

Common arguments:

- `actual`: Actual value represented by the foreground bar.
- `target`: Target value represented by the vertical marker.
- `prior_year`: Enables generated detail tooltip.
- `maximum`: Scale maximum. If omitted, derived from data.
- `background`: Wider grey comparison bar. If omitted, fills the scale.
- `favorable_direction`: `"higher"` or `"lower"`.
- `tolerance`: Neutral band around target.
- `actual_tone`: Override actual bar tone.
- `tooltip`: Custom tooltip content, or `False` to disable generated tooltip.
- `value_formatter`: Formats actual/prior/target values in generated tooltip.
- `percent_formatter`: Formats percent change values in generated tooltip.
- `colors`: Override tone colors.
- `background_style`, `actual_style`, `target_style`: Segment style overrides.

### `bullet_chart_stack(rows, **kwargs)`

Builds labeled bullet chart rows on a shared scale.

Each row is a mapping with:

- `label`: Row label.
- `actual`: Actual value.
- `target`: Target value.
- `prior_year`: Optional value for generated tooltip.
- `background`: Optional grey comparison bar.
- `tooltip`: Custom tooltip content, or `False` to disable generated tooltip.
- `value`: Optional visible value text when `show_values=True`.
- Row overrides: `favorable_direction`, `actual_tone`, `tooltip_placement`, `tooltip_max_width`, `class_name`, `style`.

Stack arguments:

- `maximum`: Shared scale maximum.
- `background`: Default background value for rows.
- `headers`: Optional column headers.
- `show_values`: Show trailing value column. Defaults to `False`.
- `favorable_direction`, `tolerance`, `colors`: Defaults for all rows.
- `value_formatter`, `percent_formatter`: Defaults for generated tooltips.
- `tooltip_placement`, `tooltip_max_width`, `tooltip_style`: Defaults for row tooltips.

### `sparkline(values, **kwargs)`

Builds a compact time-series sparkline with no axes or tick marks.

Common arguments:

- `values`: Sequence of numeric time-series values.
- `width`, `height`: SVG coordinate dimensions.
- `display_width`: Rendered CSS width. Number becomes pixels; strings pass through.
- `padding`: Internal SVG padding to avoid clipped strokes.
- `y_min`, `y_max`: Optional explicit vertical scale.
- `tone`: Override derived tone.
- `line_color`: Direct stroke color override.
- `stroke_width`: SVG stroke width.
- `show_endpoint`: Show endpoint marker. Defaults to `False`.
- `tooltip`: Custom tooltip content, or `False` to disable generated tooltip.
- `value_formatter`, `percent_formatter`: Format generated tooltip values.

### `sparkline_stack(rows, **kwargs)`

Builds grouped time-series sparkline rows, such as one row per state.

Each row is a mapping with:

- `label`: Row label.
- `values`: Numeric time-series values.
- `line_color`: Optional direct stroke color.
- `tone`: Optional tone override.
- `tooltip`: Custom tooltip content, or `False` to disable generated tooltip.
- `display_width`, `width`, `height`, `y_min`, `y_max`: Row-level sizing/scaling overrides.
- `delta_text`, `delta_tone`: Used only when `show_delta=True`.

Stack arguments:

- `display_width`: Default rendered width for all rows.
- `shared_scale`: Use one y-scale across all rows. Defaults to `True`.
- `headers`: Optional column headers.
- `show_delta`: Show visible delta column. Defaults to `False`.
- `value_formatter`, `percent_formatter`: Defaults for generated tooltips.
- `tooltip_placement`, `tooltip_max_width`, `tooltip_style`: Defaults for row tooltips.

### Helper functions

- `tone_from_value(value, thresholds=(0, 0))`: Returns `"positive"`, `"negative"`, or `"neutral"`.
- `tone_from_actual_target(actual, target, favorable_direction="higher", tolerance=0)`: Returns tone from target performance.
- `direction_from_value(value)`: Returns `"up"`, `"down"`, or `"flat"`.

Run the example app with:

```bash
uv run python examples/kpi_cards.py
```

## Documentation website

Build the Sphinx documentation site with:

```bash
uv run --group docs sphinx-build -b html docs docs/_build/html
```

The generated static site is written to `docs/_build/html`.

Serve the docs locally with:

```bash
make -C docs serve
```

Then open `http://localhost:8000`. Use `PORT=8001` if port `8000` is busy.
