# Bar Chart Active

A week of step counts where clicking a bar selects it, dims the others and updates the header.

Bar Chart Active is an open-source chart from suiss/ui for React, React Native, SwiftUI and Jetpack Compose. The @esuiss/ui CLI copies its source into your project, so you own the code.

Source: https://ui.suiss.app/docs/charts/bar-chart-active

**React**

**Example**

```tsx title="components/charts/bar-chart-active.tsx"
"use client"

import * as React from "react"
import {
  Bar,
  BarChart,
  CartesianGrid,
  Cell,
  useActiveTooltipDataPoints,
  XAxis,
} from "recharts"

import { Card, CardContent, CardHeader } from "@/components/ui/card"
import { type ChartConfig, ChartContainer } from "@/components/ui/chart"

const chartData = [
  { day: "Monday", steps: 8412 },
  { day: "Tuesday", steps: 10230 },
  { day: "Wednesday", steps: 6120 },
  { day: "Thursday", steps: 12480 },
  { day: "Friday", steps: 9050 },
  { day: "Saturday", steps: 14320 },
  { day: "Sunday", steps: 4870 },
].map((item, index) => ({ ...item, index }))

const chartConfig = {
  steps: { label: "Steps", color: "var(--chart-4)" },
} satisfies ChartConfig

const stepsFormat = new Intl.NumberFormat("en-US")

function KeyboardPoint({
  onChange,
}: {
  onChange: (index: number | null) => void
}) {
  const points = useActiveTooltipDataPoints<(typeof chartData)[number]>()
  const index = points?.[0]?.index ?? null

  React.useEffect(() => onChange(index), [index, onChange])

  return null
}

export function BarChartActive() {
  const [selected, setSelected] = React.useState(5)
  const [highlighted, setHighlighted] = React.useState<number | null>(null)
  const day = chartData[selected]
  if (!day) return null
  const opacity = (index: number) => {
    if (index === selected) return 1
    if (index === highlighted) return 0.6
    return 0.3
  }

  return (
    <Card variant="filled" size="sm">
      <CardHeader className="gap-0.5">
        <p className="text-sm font-semibold text-[color-mix(in_oklab,var(--color-orange-500),var(--foreground)_45%)] dark:text-orange-500">
          Steps
        </p>
        <p className="flex items-baseline gap-1" aria-live="polite">
          <span className="text-3xl font-semibold tracking-tight tabular-nums">
            {stepsFormat.format(day.steps)}
          </span>
          <span className="text-base font-semibold text-muted-foreground">
            steps
          </span>
        </p>
        <p className="text-sm text-muted-foreground">
          {day.day} · select a bar
        </p>
      </CardHeader>
      <CardContent>
        <ChartContainer
          config={chartConfig}
          className="aspect-auto h-40 w-full [&_.recharts-bar-rectangle]:cursor-pointer"
          onKeyDown={(event) => {
            if (
              (event.key === "Enter" || event.key === " ") &&
              highlighted !== null
            ) {
              event.preventDefault()
              setSelected(highlighted)
            }
          }}
        >
          <BarChart
            accessibilityLayer
            data={chartData}
            margin={{ top: 10, right: 4, left: 4, bottom: 0 }}
          >
            <CartesianGrid vertical={false} strokeDasharray="2 4" />
            <XAxis
              dataKey="day"
              tickLine={false}
              axisLine={false}
              tickMargin={8}
              interval={0}
              tickFormatter={(value: string) => value.slice(0, 3)}
            />
            <Bar
              dataKey="steps"
              radius={5}
              maxBarSize={28}
              onClick={(_, index) => setSelected(index)}
            >
              {chartData.map((item) => (
                <Cell
                  key={item.day}
                  fill="var(--color-steps)"
                  fillOpacity={opacity(item.index)}
                  className="transition-[fill-opacity] duration-200"
                />
              ))}
            </Bar>
            <KeyboardPoint onChange={setHighlighted} />
          </BarChart>
        </ChartContainer>
      </CardContent>
    </Card>
  )
}
```

A week of step counts where one bar is selected at a time: the chosen day stays solid, the rest dim, and the header shows its value. Use it when a bar chart doubles as a picker for the detail shown above it.

## Installation

### CLI

```bash title="Terminal"
npx shadcn@latest add @esuiss/bar-chart-active
```

Works in any project with a `components.json`. See [Installation](https://ui.suiss.app/docs/installation#add-components) for the one-line registry setup. Or use the suiss/ui CLI:

```bash title="Terminal"
npx @esuiss/ui@latest add charts bar-chart-active
```

### Manual

1. Install the dependencies:

```bash title="Terminal"
npm install recharts
```

2. Add the pieces it builds on: [Card](https://ui.suiss.app/docs/components/card), [Chart](https://ui.suiss.app/docs/components/chart).

3. Copy the source into `components/charts/bar-chart-active.tsx`:

```tsx title="components/charts/bar-chart-active.tsx"
"use client"

import * as React from "react"
import {
  Bar,
  BarChart,
  CartesianGrid,
  Cell,
  useActiveTooltipDataPoints,
  XAxis,
} from "recharts"

import { Card, CardContent, CardHeader } from "@/components/ui/card"
import { type ChartConfig, ChartContainer } from "@/components/ui/chart"

const chartData = [
  { day: "Monday", steps: 8412 },
  { day: "Tuesday", steps: 10230 },
  { day: "Wednesday", steps: 6120 },
  { day: "Thursday", steps: 12480 },
  { day: "Friday", steps: 9050 },
  { day: "Saturday", steps: 14320 },
  { day: "Sunday", steps: 4870 },
].map((item, index) => ({ ...item, index }))

const chartConfig = {
  steps: { label: "Steps", color: "var(--chart-4)" },
} satisfies ChartConfig

const stepsFormat = new Intl.NumberFormat("en-US")

function KeyboardPoint({
  onChange,
}: {
  onChange: (index: number | null) => void
}) {
  const points = useActiveTooltipDataPoints<(typeof chartData)[number]>()
  const index = points?.[0]?.index ?? null

  React.useEffect(() => onChange(index), [index, onChange])

  return null
}

export function BarChartActive() {
  const [selected, setSelected] = React.useState(5)
  const [highlighted, setHighlighted] = React.useState<number | null>(null)
  const day = chartData[selected]
  if (!day) return null
  const opacity = (index: number) => {
    if (index === selected) return 1
    if (index === highlighted) return 0.6
    return 0.3
  }

  return (
    <Card variant="filled" size="sm">
      <CardHeader className="gap-0.5">
        <p className="text-sm font-semibold text-[color-mix(in_oklab,var(--color-orange-500),var(--foreground)_45%)] dark:text-orange-500">
          Steps
        </p>
        <p className="flex items-baseline gap-1" aria-live="polite">
          <span className="text-3xl font-semibold tracking-tight tabular-nums">
            {stepsFormat.format(day.steps)}
          </span>
          <span className="text-base font-semibold text-muted-foreground">
            steps
          </span>
        </p>
        <p className="text-sm text-muted-foreground">
          {day.day} · select a bar
        </p>
      </CardHeader>
      <CardContent>
        <ChartContainer
          config={chartConfig}
          className="aspect-auto h-40 w-full [&_.recharts-bar-rectangle]:cursor-pointer"
          onKeyDown={(event) => {
            if (
              (event.key === "Enter" || event.key === " ") &&
              highlighted !== null
            ) {
              event.preventDefault()
              setSelected(highlighted)
            }
          }}
        >
          <BarChart
            accessibilityLayer
            data={chartData}
            margin={{ top: 10, right: 4, left: 4, bottom: 0 }}
          >
            <CartesianGrid vertical={false} strokeDasharray="2 4" />
            <XAxis
              dataKey="day"
              tickLine={false}
              axisLine={false}
              tickMargin={8}
              interval={0}
              tickFormatter={(value: string) => value.slice(0, 3)}
            />
            <Bar
              dataKey="steps"
              radius={5}
              maxBarSize={28}
              onClick={(_, index) => setSelected(index)}
            >
              {chartData.map((item) => (
                <Cell
                  key={item.day}
                  fill="var(--color-steps)"
                  fillOpacity={opacity(item.index)}
                  className="transition-[fill-opacity] duration-200"
                />
              ))}
            </Bar>
            <KeyboardPoint onChange={setHighlighted} />
          </BarChart>
        </ChartContainer>
      </CardContent>
    </Card>
  )
}
```

4. Update the import paths to match your project.

## Usage

```tsx
import { BarChartActive } from "@/components/charts/bar-chart-active"
```

```tsx
<BarChartActive />
```

Replace `chartData` with your own days and values, and rename `steps` in the data, the `Bar` and `chartConfig`. Set the initially selected bar through the `selected` state, and change the unit text and number format in the header. Lower or raise the opacity of the dimmed bars to tune the contrast.

## Notes

Keyboard users move between bars with the arrow keys and select with Return or Space, and the header value is announced through a live region. There is no tooltip; the header is the only readout.

**React Native, SwiftUI, Jetpack Compose**

![Preview](https://ui.suiss.app/previews/charts-bar--active.light.webp)

```tsx title="uniwind/components/charts/bar-chart-active.tsx"
import * as React from "react"
import { View } from "react-native"
import { Card, CardContent, CardHeader } from "@/components/ui/card"
import {
  Bar,
  BarChart,
  CartesianGrid,
  Cell,
  type ChartConfig,
  ChartContainer,
  XAxis,
} from "@/components/ui/chart"
import { Text } from "@/components/ui/text"

const chartData = [
  { day: "Monday", steps: 8412 },
  { day: "Tuesday", steps: 10230 },
  { day: "Wednesday", steps: 6120 },
  { day: "Thursday", steps: 12480 },
  { day: "Friday", steps: 9050 },
  { day: "Saturday", steps: 14320 },
  { day: "Sunday", steps: 4870 },
].map((item, index) => ({ ...item, index }))

const chartConfig = {
  steps: { label: "Steps", color: "chart-4" },
} satisfies ChartConfig

function formatSteps(value: number) {
  try {
    return new Intl.NumberFormat("en-US").format(value)
  } catch {
    return String(value).replace(/\B(?=(\d{3})+(?!\d))/g, ",")
  }
}

export function BarChartActive() {
  const [selected, setSelected] = React.useState(5)
  const day = chartData[selected]
  if (!day) return null

  return (
    <Card variant="filled" size="sm">
      <CardHeader className="gap-0.5">
        <Text className="text-sm font-semibold text-orange-500">Steps</Text>
        <View
          className="flex-row items-baseline gap-1"
          accessibilityLiveRegion="polite"
        >
          <Text className="text-3xl font-semibold tracking-tight tabular-nums">
            {formatSteps(day.steps)}
          </Text>
          <Text className="text-base font-semibold text-muted-foreground">
            steps
          </Text>
        </View>
        <Text className="text-sm text-muted-foreground">
          {`${day.day} · select a bar`}
        </Text>
      </CardHeader>
      <CardContent>
        <ChartContainer
          config={chartConfig}
          accessibilityLabel="Steps"
          className="h-40 w-full"
        >
          <BarChart
            data={chartData}
            margin={{ top: 10, right: 4, left: 4, bottom: 0 }}
            onActiveIndexChange={(index) => {
              if (index !== null) setSelected(index)
            }}
          >
            <CartesianGrid vertical={false} strokeDasharray="2 4" />
            <XAxis
              dataKey="day"
              tickMargin={8}
              interval={0}
              tickFormatter={(value: string) => value.slice(0, 3)}
            />
            <Bar
              dataKey="steps"
              radius={5}
              maxBarSize={28}
              isAnimationActive={false}
            >
              {chartData.map((item) => (
                <Cell
                  key={item.day}
                  fillOpacity={item.index === selected ? 1 : 0.3}
                />
              ))}
            </Bar>
          </BarChart>
        </ChartContainer>
      </CardContent>
    </Card>
  )
}
```

```swift title="swift/Charts/BarChartActive.swift"
import Charts
import SwiftUI

private let chartData: [(day: String, steps: Double)] = [
  ("Monday", 8412), ("Tuesday", 10230), ("Wednesday", 6120), ("Thursday", 12480),
  ("Friday", 9050), ("Saturday", 14320), ("Sunday", 4870),
]

private let chartConfig: ChartConfig = [
  "steps": .init("Steps", color: EsuissColor.chart4),
]

public struct BarChartActive: View {
  @State private var selected = 5
  @Environment(\.accessibilityReduceMotion) private var reduceMotion

  public init() {}

  private var selection: Binding<Int?> {
    Binding(get: { selected }, set: { if let value = $0 { selected = value } })
  }

  public var body: some View {
    let day = chartData[selected]
    Card(.filled, size: .sm) {
      VStack(alignment: .leading, spacing: 2) {
        Text("Steps")
          .textStyle(.sm, weight: .semibold)
          .foregroundStyle(chartConfig.color("steps"))
        HStack(alignment: .firstTextBaseline, spacing: 4) {
          Text(day.steps, format: .number)
            .textStyle(.xl3, weight: .semibold)
            .monospacedDigit()
          Text("steps")
            .textStyle(.base, weight: .semibold)
            .foregroundStyle(EsuissColor.mutedForeground)
        }
        Text("\(day.day) · select a bar")
          .textStyle(.sm)
          .foregroundStyle(EsuissColor.mutedForeground)
      }
      .padding(.horizontal, 16)
      CardContent {
        ChartContainer(config: chartConfig) {
          Chart {
            ForEach(chartData.indices, id: \.self) { index in
              BarMark(x: .value("Day", chartData[index].day), y: .value("Steps", chartData[index].steps), width: .fixed(28))
                .clipShape(RoundedRectangle(cornerRadius: 5, style: .continuous))
                .foregroundStyle(chartConfig.color("steps").opacity(index == selected ? 1 : 0.3))
            }
          }
          .chartXAxis { ChartAxis.x(values: chartData.map(\.day)) { String($0.prefix(3)) } }
          .chartYAxis { ChartAxis.grid() }
          .animation(reduceMotion ? nil : .easeOut(duration: 0.2), value: selected)
          .chartTooltip(
            x: chartData.map(\.day),
            selection: selection,
            cursor: false,
            accessibilityLabel: "Steps",
            items: { [ChartTooltipItem("steps", value: chartData[$0].steps)] }
          ) { _ in
            EmptyView()
          }
        }
        .frame(height: 160)
      }
    }
  }
}
```

```kt title="kotlin/charts/BarChartActive.kt"
package com.esuiss.ui.charts

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.text.BasicText
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.lerp
import androidx.compose.ui.semantics.LiveRegionMode
import androidx.compose.ui.semantics.liveRegion
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.esuiss.ui.components.BarChart
import com.esuiss.ui.components.Card
import com.esuiss.ui.components.CardContent
import com.esuiss.ui.components.CardSize
import com.esuiss.ui.components.CardVariant
import com.esuiss.ui.components.ChartCell
import com.esuiss.ui.components.ChartConfig
import com.esuiss.ui.components.ChartConfigItem
import com.esuiss.ui.components.ChartContainer
import com.esuiss.ui.components.ChartMargin
import com.esuiss.ui.components.ChartRadius
import com.esuiss.ui.theme.EsuissTheme
import com.esuiss.ui.theme.Typography
import java.text.NumberFormat
import java.util.Locale

private class StepsDay(val day: String, val steps: Double)

private val chartData = listOf(
    StepsDay("Monday", 8412.0),
    StepsDay("Tuesday", 10230.0),
    StepsDay("Wednesday", 6120.0),
    StepsDay("Thursday", 12480.0),
    StepsDay("Friday", 9050.0),
    StepsDay("Saturday", 14320.0),
    StepsDay("Sunday", 4870.0),
)

private val chartConfig = ChartConfig(
    "steps" to ChartConfigItem("Steps") { chart4 },
)

@Composable
fun BarChartActive(modifier: Modifier = Modifier) {
    val colors = EsuissTheme.colors
    var selected by remember { mutableIntStateOf(5) }
    val day = chartData[selected]
    val stepsFormat = remember { NumberFormat.getNumberInstance(Locale.US) }
    Card(modifier, variant = CardVariant.Filled, size = CardSize.Sm) {
        CardContent {
            Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
                BasicText(
                    "Steps",
                    style = Typography.sm.copy(
                        color = if (colors.isDark) colors.chart4 else lerp(colors.chart4, colors.foreground, 0.45f),
                        fontWeight = FontWeight.SemiBold,
                    ),
                )
                Row(
                    Modifier.semantics { liveRegion = LiveRegionMode.Polite },
                    horizontalArrangement = Arrangement.spacedBy(4.dp),
                ) {
                    BasicText(
                        stepsFormat.format(day.steps),
                        Modifier.alignByBaseline(),
                        style = Typography.xl3.copy(color = colors.foreground, fontWeight = FontWeight.SemiBold, fontFeatureSettings = "tnum"),
                    )
                    BasicText(
                        "steps",
                        Modifier.alignByBaseline(),
                        style = Typography.base.copy(color = colors.mutedForeground, fontWeight = FontWeight.SemiBold),
                    )
                }
                BasicText("${day.day} · select a bar", style = Typography.sm.copy(color = colors.mutedForeground))
            }
        }
        CardContent {
            ChartContainer(
                chartConfig,
                Modifier
                    .fillMaxWidth()
                    .height(160.dp),
            ) {
                BarChart(
                    chartData,
                    margin = ChartMargin(top = 10.dp, right = 4.dp, bottom = 0.dp, left = 4.dp),
                    accessibilityLabel = "Steps",
                    selectedIndex = selected,
                    onSelectedIndexChange = { index -> if (index != null) selected = index },
                ) {
                    CartesianGrid(strokeDasharray = listOf(2f, 4f))
                    XAxis(label = { it.day }, tickMargin = 8.dp, interval = 0, tickFormatter = { it.take(3) })
                    Bar(
                        "steps",
                        value = { it.steps },
                        radius = ChartRadius(5.dp),
                        maxBarSize = 28.dp,
                        cells = { index -> ChartCell(alpha = if (index == selected) 1f else 0.3f) },
                        isAnimationActive = false,
                    )
                }
            }
        }
    }
}
```

Seven bars, one per day, with the selected bar at full opacity and the others dimmed. The `BarChart` reports the touched bar through `onActiveIndexChange`, which updates local state and the header. The header is a live region, so screen readers announce the new step count. The bars set `isAnimationActive={false}` and draw without the enter animation.

## Installation

**React Native**

```bash title="Terminal"
npx shadcn@latest add @esuiss-rn/bar-chart-active
```

See [Installation](https://ui.suiss.app/docs/installation) for the `components.json` setup. Or use the suiss/ui CLI:

```bash title="Terminal"
npx @esuiss/ui@latest add bar-chart-active
```

**SwiftUI**

```bash title="Terminal"
npx @esuiss/ui@latest add bar-chart-active --platform swift
```

**Jetpack Compose**

```bash title="Terminal"
npx @esuiss/ui@latest add bar-chart-active --platform kotlin
```

The CLI also adds what it builds on: [Card](https://ui.suiss.app/docs/components/card), [Chart](https://ui.suiss.app/docs/components/chart), [Text](https://ui.suiss.app/docs/components/text).

### Manual

**React Native**

**Uniwind**

1. Add the pieces it builds on: [Card](https://ui.suiss.app/docs/components/card), [Chart](https://ui.suiss.app/docs/components/chart), [Text](https://ui.suiss.app/docs/components/text).

2. Copy the source into `components/charts/bar-chart-active.tsx`:

- `uniwind/components/charts/bar-chart-active.tsx`: shown above

3. Update the import paths to match your project.

**NativeWind**

1. Add the pieces it builds on: [Card](https://ui.suiss.app/docs/components/card), [Chart](https://ui.suiss.app/docs/components/chart), [Text](https://ui.suiss.app/docs/components/text).

2. Copy the source into `components/charts/bar-chart-active.tsx`:

```tsx title="nativewind/components/charts/bar-chart-active.tsx"
import * as React from "react"
import { View } from "react-native"
import { Card, CardContent, CardHeader } from "@/components/ui/card"
import {
  Bar,
  BarChart,
  CartesianGrid,
  Cell,
  type ChartConfig,
  ChartContainer,
  XAxis,
} from "@/components/ui/chart"
import { Text } from "@/components/ui/text"

const chartData = [
  { day: "Monday", steps: 8412 },
  { day: "Tuesday", steps: 10230 },
  { day: "Wednesday", steps: 6120 },
  { day: "Thursday", steps: 12480 },
  { day: "Friday", steps: 9050 },
  { day: "Saturday", steps: 14320 },
  { day: "Sunday", steps: 4870 },
].map((item, index) => ({ ...item, index }))

const chartConfig = {
  steps: { label: "Steps", color: "chart-4" },
} satisfies ChartConfig

function formatSteps(value: number) {
  try {
    return new Intl.NumberFormat("en-US").format(value)
  } catch {
    return String(value).replace(/\B(?=(\d{3})+(?!\d))/g, ",")
  }
}

export function BarChartActive() {
  const [selected, setSelected] = React.useState(5)
  const day = chartData[selected]
  if (!day) return null

  return (
    <Card variant="filled" size="sm">
      <CardHeader className="gap-0.5">
        <Text className="text-sm font-semibold text-orange-500">Steps</Text>
        <View
          className="flex-row items-baseline gap-1"
          accessibilityLiveRegion="polite"
        >
          <Text className="text-3xl font-semibold tracking-tight tabular-nums">
            {formatSteps(day.steps)}
          </Text>
          <Text className="text-base font-semibold text-muted-foreground">
            steps
          </Text>
        </View>
        <Text className="text-sm text-muted-foreground">
          {`${day.day} · select a bar`}
        </Text>
      </CardHeader>
      <CardContent>
        <ChartContainer
          config={chartConfig}
          accessibilityLabel="Steps"
          className="h-40 w-full"
        >
          <BarChart
            data={chartData}
            margin={{ top: 10, right: 4, left: 4, bottom: 0 }}
            onActiveIndexChange={(index) => {
              if (index !== null) setSelected(index)
            }}
          >
            <CartesianGrid vertical={false} strokeDasharray="2 4" />
            <XAxis
              dataKey="day"
              tickMargin={8}
              interval={0}
              tickFormatter={(value: string) => value.slice(0, 3)}
            />
            <Bar
              dataKey="steps"
              radius={5}
              maxBarSize={28}
              isAnimationActive={false}
            >
              {chartData.map((item) => (
                <Cell
                  key={item.day}
                  fillOpacity={item.index === selected ? 1 : 0.3}
                />
              ))}
            </Bar>
          </BarChart>
        </ChartContainer>
      </CardContent>
    </Card>
  )
}
```

3. Update the import paths to match your project.

**StyleSheet**

1. Add the pieces it builds on: [Card](https://ui.suiss.app/docs/components/card), [Chart](https://ui.suiss.app/docs/components/chart), [Text](https://ui.suiss.app/docs/components/text).

2. Copy the source into `components/charts/bar-chart-active.tsx`:

```tsx title="stylesheet/components/charts/bar-chart-active.tsx"
import * as React from "react"
import { StyleSheet, View } from "react-native"
import { Card, CardContent, CardHeader } from "@/components/ui/card"
import {
  Bar,
  BarChart,
  CartesianGrid,
  Cell,
  type ChartConfig,
  ChartContainer,
  XAxis,
} from "@/components/ui/chart"
import { Text } from "@/components/ui/text"
import { fontSize, useTheme } from "@/components/ui/theme"

const chartData = [
  { day: "Monday", steps: 8412 },
  { day: "Tuesday", steps: 10230 },
  { day: "Wednesday", steps: 6120 },
  { day: "Thursday", steps: 12480 },
  { day: "Friday", steps: 9050 },
  { day: "Saturday", steps: 14320 },
  { day: "Sunday", steps: 4870 },
].map((item, index) => ({ ...item, index }))

const chartConfig = {
  steps: { label: "Steps", color: "chart-4" },
} satisfies ChartConfig

function formatSteps(value: number) {
  try {
    return new Intl.NumberFormat("en-US").format(value)
  } catch {
    return String(value).replace(/\B(?=(\d{3})+(?!\d))/g, ",")
  }
}

const styles = StyleSheet.create({
  header: { gap: 2 },
  eyebrow: { ...fontSize.sm, fontWeight: "600" },
  reading: { flexDirection: "row", alignItems: "baseline", gap: 4 },
  value: {
    ...fontSize["3xl"],
    fontWeight: "600",
    letterSpacing: -0.75,
    fontVariant: ["tabular-nums"],
  },
  unit: { ...fontSize.base, fontWeight: "600" },
  caption: { ...fontSize.sm },
  chart: { height: 160 },
})

export function BarChartActive() {
  const { colors } = useTheme()
  const [selected, setSelected] = React.useState(5)
  const day = chartData[selected]
  if (!day) return null

  return (
    <Card variant="filled" size="sm">
      <CardHeader style={styles.header}>
        <Text style={[styles.eyebrow, { color: colors.chart4 }]}>Steps</Text>
        <View style={styles.reading} accessibilityLiveRegion="polite">
          <Text style={styles.value}>{formatSteps(day.steps)}</Text>
          <Text style={[styles.unit, { color: colors.mutedForeground }]}>
            steps
          </Text>
        </View>
        <Text style={[styles.caption, { color: colors.mutedForeground }]}>
          {`${day.day} · select a bar`}
        </Text>
      </CardHeader>
      <CardContent>
        <ChartContainer
          config={chartConfig}
          accessibilityLabel="Steps"
          style={styles.chart}
        >
          <BarChart
            data={chartData}
            margin={{ top: 10, right: 4, left: 4, bottom: 0 }}
            onActiveIndexChange={(index) => {
              if (index !== null) setSelected(index)
            }}
          >
            <CartesianGrid vertical={false} strokeDasharray="2 4" />
            <XAxis
              dataKey="day"
              tickMargin={8}
              interval={0}
              tickFormatter={(value: string) => value.slice(0, 3)}
            />
            <Bar
              dataKey="steps"
              radius={5}
              maxBarSize={28}
              isAnimationActive={false}
            >
              {chartData.map((item) => (
                <Cell
                  key={item.day}
                  fillOpacity={item.index === selected ? 1 : 0.3}
                />
              ))}
            </Bar>
          </BarChart>
        </ChartContainer>
      </CardContent>
    </Card>
  )
}
```

3. Update the import paths to match your project.

**SwiftUI**

1. Target iOS 17 or later.

2. Copy the theme files every view uses:

- `swift/Theme/Theme.swift`: [source](https://github.com/e-suiss/ui/blob/main/packages/mobile/swiftui/Sources/EsuissUI/Theme/Theme.swift)

- `swift/Theme/Tokens.swift`: [source](https://github.com/e-suiss/ui/blob/main/packages/mobile/swiftui/Sources/EsuissUI/Theme/Tokens.swift)

3. Copy the source and every file it uses:

- `swift/Charts/BarChartActive.swift`: shown above

- `swift/Components/Card.swift`: see [Card](https://ui.suiss.app/docs/components/card.md)

- `swift/Components/Chart.swift`: see [Chart](https://ui.suiss.app/docs/components/chart.md)

- `swift/Components/Haptics.swift`: see [Haptics](https://ui.suiss.app/docs/components/haptics.md)

- `swift/Components/Item.swift`: see [Item](https://ui.suiss.app/docs/components/item.md)

- `swift/Components/Separator.swift`: see [Separator](https://ui.suiss.app/docs/components/separator.md)

- `swift/Components/TextVariant.swift`: [source](https://github.com/e-suiss/ui/blob/main/packages/mobile/swiftui/Sources/EsuissUI/Components/TextVariant.swift)

4. Add the files to your app target.

**Jetpack Compose**

1. Set `minSdk` to 24 or higher and add the dependencies:

```kotlin title="build.gradle.kts"
implementation(platform("androidx.compose:compose-bom:2026.09.00"))
implementation("androidx.compose.foundation:foundation")
implementation("androidx.compose.ui:ui")
```

2. Copy the theme files every view uses:

- `kotlin/theme/Theme.kt`: [source](https://github.com/e-suiss/ui/blob/main/packages/mobile/kotlin/ui/src/main/kotlin/com/esuiss/ui/theme/Theme.kt)

- `kotlin/theme/Tokens.kt`: [source](https://github.com/e-suiss/ui/blob/main/packages/mobile/kotlin/ui/src/main/kotlin/com/esuiss/ui/theme/Tokens.kt)

3. Copy the source and every file it uses:

- `kotlin/charts/BarChartActive.kt`: shown above

- `kotlin/components/Card.kt`: see [Card](https://ui.suiss.app/docs/components/card.md)

- `kotlin/components/Chart.kt`: see [Chart](https://ui.suiss.app/docs/components/chart.md)

- `kotlin/components/Content.kt`: [source](https://github.com/e-suiss/ui/blob/main/packages/mobile/kotlin/ui/src/main/kotlin/com/esuiss/ui/components/Content.kt)

- `kotlin/components/FormSupport.kt`: [source](https://github.com/e-suiss/ui/blob/main/packages/mobile/kotlin/ui/src/main/kotlin/com/esuiss/ui/components/FormSupport.kt)

- `kotlin/components/Haptics.kt`: see [Haptics](https://ui.suiss.app/docs/components/haptics.md)

- `kotlin/components/Icon.kt`: see [Icon](https://ui.suiss.app/docs/components/icon.md)

4. Update the `com.esuiss.ui` package names to match your project.

## Usage

```tsx
import { BarChartActive } from "@/components/charts/bar-chart-active"
```

```tsx
<BarChartActive />
```

Replace `chartData` with your daily values and update the `day` and `steps` keys to match. The initial selection is set by the `useState` default. The component takes no props.

