# Bar Chart Range

A weather forecast where each horizontal pill spans the day's low and high on a shared gradient scale.

Bar Chart Range 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-range

**React**

**Example**

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

import * as React from "react"
import { Bar, BarChart, XAxis, YAxis } from "recharts"

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

const chartData = [
  { day: "Today", low: 14, high: 22 },
  { day: "Wed", low: 13, high: 21 },
  { day: "Thu", low: 15, high: 24 },
  { day: "Fri", low: 16, high: 25 },
  { day: "Sat", low: 14, high: 20 },
  { day: "Sun", low: 11, high: 17 },
  { day: "Mon", low: 10, high: 16 },
  { day: "Tue", low: 12, high: 19 },
].map((item) => ({ ...item, range: [item.low, item.high] }))

const chartConfig = {
  range: { label: "Temperature" },
} satisfies ChartConfig

export function BarChartRange() {
  const id = React.useId()

  return (
    <Card variant="filled" size="sm">
      <CardHeader>
        <CardTitle>8-day forecast</CardTitle>
        <CardDescription>Each bar spans the low and high</CardDescription>
      </CardHeader>
      <CardContent>
        <ChartContainer
          config={chartConfig}
          className="aspect-auto h-60 w-full"
        >
          <BarChart
            accessibilityLayer
            data={chartData}
            layout="vertical"
            barCategoryGap={7}
            margin={{ top: 0, right: 0, left: 0, bottom: 0 }}
          >
            <defs>
              <linearGradient id={id} x1="0" y1="0" x2="1" y2="0">
                <stop offset="0%" stopColor="var(--color-teal-500)" />
                <stop offset="55%" stopColor="var(--color-yellow-500)" />
                <stop offset="100%" stopColor="var(--color-orange-500)" />
              </linearGradient>
            </defs>
            <YAxis
              dataKey="day"
              type="category"
              tickLine={false}
              axisLine={false}
              width="auto"
              tick={{ className: "fill-foreground font-semibold" }}
            />
            <YAxis
              yAxisId="high"
              dataKey="high"
              type="category"
              orientation="right"
              tickLine={false}
              axisLine={false}
              width="auto"
              tick={{ className: "fill-foreground font-semibold" }}
              tickFormatter={(value: number) => `${value}°`}
            />
            <XAxis type="number" hide domain={[8, 27]} />
            <ChartTooltip
              cursor={false}
              content={
                <ChartTooltipContent
                  hideIndicator
                  formatter={(value) => (
                    <span className="font-semibold tabular-nums">
                      {Array.isArray(value)
                        ? `${value[0]}° to ${value[1]}°`
                        : value}
                    </span>
                  )}
                />
              }
            />
            <Bar
              dataKey="range"
              fill={`url(#${id})`}
              radius={99}
              background={{ fill: "var(--secondary)", radius: 99 }}
            />
          </BarChart>
        </ChartContainer>
      </CardContent>
    </Card>
  )
}
```

A weather-app forecast where each horizontal pill spans a day's low to high temperature against a shared scale, with a colored gradient fill and the high on the right. Use floating range bars like these whenever each item has a minimum and a maximum.

## Installation

### CLI

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

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-range
```

### 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-range.tsx`:

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

import * as React from "react"
import { Bar, BarChart, XAxis, YAxis } from "recharts"

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

const chartData = [
  { day: "Today", low: 14, high: 22 },
  { day: "Wed", low: 13, high: 21 },
  { day: "Thu", low: 15, high: 24 },
  { day: "Fri", low: 16, high: 25 },
  { day: "Sat", low: 14, high: 20 },
  { day: "Sun", low: 11, high: 17 },
  { day: "Mon", low: 10, high: 16 },
  { day: "Tue", low: 12, high: 19 },
].map((item) => ({ ...item, range: [item.low, item.high] }))

const chartConfig = {
  range: { label: "Temperature" },
} satisfies ChartConfig

export function BarChartRange() {
  const id = React.useId()

  return (
    <Card variant="filled" size="sm">
      <CardHeader>
        <CardTitle>8-day forecast</CardTitle>
        <CardDescription>Each bar spans the low and high</CardDescription>
      </CardHeader>
      <CardContent>
        <ChartContainer
          config={chartConfig}
          className="aspect-auto h-60 w-full"
        >
          <BarChart
            accessibilityLayer
            data={chartData}
            layout="vertical"
            barCategoryGap={7}
            margin={{ top: 0, right: 0, left: 0, bottom: 0 }}
          >
            <defs>
              <linearGradient id={id} x1="0" y1="0" x2="1" y2="0">
                <stop offset="0%" stopColor="var(--color-teal-500)" />
                <stop offset="55%" stopColor="var(--color-yellow-500)" />
                <stop offset="100%" stopColor="var(--color-orange-500)" />
              </linearGradient>
            </defs>
            <YAxis
              dataKey="day"
              type="category"
              tickLine={false}
              axisLine={false}
              width="auto"
              tick={{ className: "fill-foreground font-semibold" }}
            />
            <YAxis
              yAxisId="high"
              dataKey="high"
              type="category"
              orientation="right"
              tickLine={false}
              axisLine={false}
              width="auto"
              tick={{ className: "fill-foreground font-semibold" }}
              tickFormatter={(value: number) => `${value}°`}
            />
            <XAxis type="number" hide domain={[8, 27]} />
            <ChartTooltip
              cursor={false}
              content={
                <ChartTooltipContent
                  hideIndicator
                  formatter={(value) => (
                    <span className="font-semibold tabular-nums">
                      {Array.isArray(value)
                        ? `${value[0]}° to ${value[1]}°`
                        : value}
                    </span>
                  )}
                />
              }
            />
            <Bar
              dataKey="range"
              fill={`url(#${id})`}
              radius={99}
              background={{ fill: "var(--secondary)", radius: 99 }}
            />
          </BarChart>
        </ChartContainer>
      </CardContent>
    </Card>
  )
}
```

4. Update the import paths to match your project.

## Usage

```tsx
import { BarChartRange } from "@/components/charts/bar-chart-range"
```

```tsx
<BarChartRange />
```

Give each record a label, a `low` and a `high`; the chart derives the two-value `range` from them. Set the hidden value axis `domain` to cover your full range so pills line up across rows. Edit the gradient stops in the `defs` block to change the colors.

## Notes

The gradient runs across each pill rather than across the whole scale, so every pill shows the full color ramp regardless of its temperatures. Only the high is printed beside the bars; the low is available in the tooltip.

**React Native, SwiftUI, Jetpack Compose**

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

```tsx title="uniwind/components/charts/bar-chart-range.tsx"
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
import {
  Bar,
  BarChart,
  type ChartConfig,
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
  XAxis,
  YAxis,
} from "@/components/ui/chart"
import { Text } from "@/components/ui/text"

const chartData = [
  { day: "Today", low: 14, high: 22 },
  { day: "Wed", low: 13, high: 21 },
  { day: "Thu", low: 15, high: 24 },
  { day: "Fri", low: 16, high: 25 },
  { day: "Sat", low: 14, high: 20 },
  { day: "Sun", low: 11, high: 17 },
  { day: "Mon", low: 10, high: 16 },
  { day: "Tue", low: 12, high: 19 },
].map((item) => ({ ...item, range: [item.low, item.high] }))

const chartConfig = {
  range: { label: "Temperature" },
} satisfies ChartConfig

export function BarChartRange() {
  return (
    <Card variant="filled" size="sm">
      <CardHeader>
        <CardTitle>8-day forecast</CardTitle>
        <CardDescription>Each bar spans the low and high</CardDescription>
      </CardHeader>
      <CardContent>
        <ChartContainer
          config={chartConfig}
          accessibilityLabel="8-day forecast"
          className="h-60 w-full"
        >
          <BarChart
            data={chartData}
            layout="vertical"
            barCategoryGap={7}
            margin={{ top: 0, right: 0, left: 0, bottom: 0 }}
          >
            <YAxis
              dataKey="day"
              type="category"
              width="auto"
              tickClassName="text-foreground font-semibold"
            />
            <YAxis
              dataKey="high"
              type="category"
              orientation="right"
              width="auto"
              tickClassName="text-foreground font-semibold"
              tickFormatter={(value) => `${value}°`}
            />
            <XAxis type="number" hide domain={[8, 27]} />
            <ChartTooltip
              cursor={false}
              content={
                <ChartTooltipContent
                  hideIndicator
                  formatter={(value) => (
                    <Text className="font-semibold tabular-nums">
                      {typeof value === "number"
                        ? String(value)
                        : `${value[0]}° to ${value[1]}°`}
                    </Text>
                  )}
                />
              }
            />
            <Bar
              dataKey="range"
              fill={{
                direction: "horizontal",
                stops: [
                  { offset: 0, color: "chart-2" },
                  { offset: 0.55, color: "yellow-500" },
                  { offset: 1, color: "chart-4" },
                ],
              }}
              radius={99}
              background={{ fill: "secondary", radius: 99 }}
            />
          </BarChart>
        </ChartContainer>
      </CardContent>
    </Card>
  )
}
```

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

private let chartData: [(day: String, low: Double, high: Double)] = [
  ("Today", 14, 22), ("Wed", 13, 21), ("Thu", 15, 24), ("Fri", 16, 25),
  ("Sat", 14, 20), ("Sun", 11, 17), ("Mon", 10, 16), ("Tue", 12, 19),
]

private let chartConfig: ChartConfig = [
  "range": .init("Temperature"),
]

private func high(_ day: String) -> String {
  chartData.first { $0.day == day }.map { "\(Int($0.high))°" } ?? ""
}

public struct BarChartRange: View {
  @State private var selection: Int?

  public init() {}

  public var body: some View {
    Card(.filled, size: .sm) {
      CardHeader("8-day forecast", description: "Each bar spans the low and high")
      CardContent {
        ChartContainer(config: chartConfig) {
          ChartAnimator(animationDuration: 400) { progress in
            Chart {
              ForEach(chartData.indices, id: \.self) { index in
                BarMark(xStart: .value("Low", 8), xEnd: .value("High", 27), y: .value("Day", chartData[index].day), height: .ratio(0.76))
                  .clipShape(Capsule())
                  .foregroundStyle(EsuissColor.secondary)
                BarMark(xStart: .value("Low", chartData[index].low), xEnd: .value("High", chartData[index].low + (chartData[index].high - chartData[index].low) * progress), y: .value("Day", chartData[index].day), height: .ratio(0.76))
                  .clipShape(Capsule())
                  .foregroundStyle(LinearGradient(colors: [Palette.teal500, Palette.yellow500, Palette.orange500], startPoint: .leading, endPoint: .trailing))
              }
            }
            .chartXScale(domain: 8...27)
            .chartXAxis(.hidden)
            .chartYAxis {
              ChartAxis.y(values: chartData.map(\.day), edge: .leading, grid: false, emphasized: true) { $0 }
              ChartAxis.y(values: chartData.map(\.day), edge: .trailing, grid: false, emphasized: true) { high($0) }
            }
            .chartTooltip(
              y: chartData.map(\.day),
              selection: $selection,
              accessibilityLabel: "8-day forecast",
              items: { [ChartTooltipItem("range", value: chartData[$0].high)] }
            ) { payload in
              ChartTooltipContent(payload, hideIndicator: true) { (_: ChartTooltipItem) in
                Text(verbatim: "\(Int(chartData[payload.index].low))° to \(Int(chartData[payload.index].high))°")
                  .scaledFont(TextStyle.xs, weight: .semibold)
                  .monospacedDigit()
              }
            }
          }
        }
        .frame(height: 240)
      }
    }
  }
}
```

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

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.ui.Modifier
import androidx.compose.ui.text.TextStyle
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.CardHeader
import com.esuiss.ui.components.CardSize
import com.esuiss.ui.components.CardVariant
import com.esuiss.ui.components.ChartAxisOrientation
import com.esuiss.ui.components.ChartConfig
import com.esuiss.ui.components.ChartConfigItem
import com.esuiss.ui.components.ChartContainer
import com.esuiss.ui.components.ChartFill
import com.esuiss.ui.components.ChartLayout
import com.esuiss.ui.components.ChartMargin
import com.esuiss.ui.components.ChartRadius
import com.esuiss.ui.components.ChartTooltipContent
import com.esuiss.ui.theme.EsuissTheme
import com.esuiss.ui.theme.Palette
import com.esuiss.ui.theme.Typography

private class ForecastDay(val day: String, val low: Int, val high: Int)

private val chartData = listOf(
    ForecastDay("Today", 14, 22),
    ForecastDay("Wed", 13, 21),
    ForecastDay("Thu", 15, 24),
    ForecastDay("Fri", 16, 25),
    ForecastDay("Sat", 14, 20),
    ForecastDay("Sun", 11, 17),
    ForecastDay("Mon", 10, 16),
    ForecastDay("Tue", 12, 19),
)

private val chartConfig = ChartConfig(
    "range" to ChartConfigItem("Temperature"),
)

@Composable
fun BarChartRange(modifier: Modifier = Modifier) {
    val colors = EsuissTheme.colors
    val tick = TextStyle(color = colors.foreground, fontWeight = FontWeight.SemiBold)
    Card(modifier, variant = CardVariant.Filled, size = CardSize.Sm) {
        CardHeader("8-day forecast", description = "Each bar spans the low and high")
        CardContent {
            ChartContainer(
                chartConfig,
                Modifier
                    .fillMaxWidth()
                    .height(240.dp),
            ) {
                BarChart(
                    chartData,
                    layout = ChartLayout.Vertical,
                    barCategoryGap = 7.dp,
                    margin = ChartMargin(0.dp, 0.dp, 0.dp, 0.dp),
                    accessibilityLabel = "8-day forecast",
                ) {
                    YAxis(label = { it.day }, tickStyle = tick)
                    YAxis(label = { "${it.high}°" }, orientation = ChartAxisOrientation.Right, tickStyle = tick)
                    XAxis(domain = 8.0..27.0)
                    ChartTooltip(cursor = null) {
                        ChartTooltipContent(
                            hideIndicator = true,
                            formatter = { item ->
                                BasicText(
                                    "${item.base?.toInt()}° to ${item.value.toInt()}°",
                                    style = Typography.xs.copy(color = colors.foreground, fontWeight = FontWeight.SemiBold, fontFeatureSettings = "tnum"),
                                )
                            },
                        )
                    }
                    Bar(
                        "range",
                        value = { it.high.toDouble() },
                        base = { it.low.toDouble() },
                        fill = ChartFill.HorizontalGradient(listOf(0f to colors.chart2, 0.55f to Palette.yellow500, 1f to colors.chart4)),
                        radius = ChartRadius(99.dp),
                        background = colors.secondary,
                    )
                }
            }
        }
    }
}
```

A horizontal `BarChart` whose `range` values are `[low, high]` pairs, so each bar floats between the two temperatures. Bars use a teal-to-orange gradient over a full-width track, day names sit on the left and highs on the right. The tooltip shows the range in degrees.

## Installation

**React Native**

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

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-range
```

**SwiftUI**

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

**Jetpack Compose**

```bash title="Terminal"
npx @esuiss/ui@latest add bar-chart-range --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-range.tsx`:

- `uniwind/components/charts/bar-chart-range.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-range.tsx`:

```tsx title="nativewind/components/charts/bar-chart-range.tsx"
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
import {
  Bar,
  BarChart,
  type ChartConfig,
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
  XAxis,
  YAxis,
} from "@/components/ui/chart"
import { Text } from "@/components/ui/text"

const chartData = [
  { day: "Today", low: 14, high: 22 },
  { day: "Wed", low: 13, high: 21 },
  { day: "Thu", low: 15, high: 24 },
  { day: "Fri", low: 16, high: 25 },
  { day: "Sat", low: 14, high: 20 },
  { day: "Sun", low: 11, high: 17 },
  { day: "Mon", low: 10, high: 16 },
  { day: "Tue", low: 12, high: 19 },
].map((item) => ({ ...item, range: [item.low, item.high] }))

const chartConfig = {
  range: { label: "Temperature" },
} satisfies ChartConfig

export function BarChartRange() {
  return (
    <Card variant="filled" size="sm">
      <CardHeader>
        <CardTitle>8-day forecast</CardTitle>
        <CardDescription>Each bar spans the low and high</CardDescription>
      </CardHeader>
      <CardContent>
        <ChartContainer
          config={chartConfig}
          accessibilityLabel="8-day forecast"
          className="h-60 w-full"
        >
          <BarChart
            data={chartData}
            layout="vertical"
            barCategoryGap={7}
            margin={{ top: 0, right: 0, left: 0, bottom: 0 }}
          >
            <YAxis
              dataKey="day"
              type="category"
              width="auto"
              tickClassName="text-foreground font-semibold"
            />
            <YAxis
              dataKey="high"
              type="category"
              orientation="right"
              width="auto"
              tickClassName="text-foreground font-semibold"
              tickFormatter={(value) => `${value}°`}
            />
            <XAxis type="number" hide domain={[8, 27]} />
            <ChartTooltip
              cursor={false}
              content={
                <ChartTooltipContent
                  hideIndicator
                  formatter={(value) => (
                    <Text className="font-semibold tabular-nums">
                      {typeof value === "number"
                        ? String(value)
                        : `${value[0]}° to ${value[1]}°`}
                    </Text>
                  )}
                />
              }
            />
            <Bar
              dataKey="range"
              fill={{
                direction: "horizontal",
                stops: [
                  { offset: 0, color: "chart-2" },
                  { offset: 0.55, color: "yellow-500" },
                  { offset: 1, color: "chart-4" },
                ],
              }}
              radius={99}
              background={{ fill: "secondary", radius: 99 }}
            />
          </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-range.tsx`:

```tsx title="stylesheet/components/charts/bar-chart-range.tsx"
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
import {
  Bar,
  BarChart,
  type ChartConfig,
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
  XAxis,
  YAxis,
} from "@/components/ui/chart"
import { Text } from "@/components/ui/text"
import { useTheme } from "@/components/ui/theme"

const chartData = [
  { day: "Today", low: 14, high: 22 },
  { day: "Wed", low: 13, high: 21 },
  { day: "Thu", low: 15, high: 24 },
  { day: "Fri", low: 16, high: 25 },
  { day: "Sat", low: 14, high: 20 },
  { day: "Sun", low: 11, high: 17 },
  { day: "Mon", low: 10, high: 16 },
  { day: "Tue", low: 12, high: 19 },
].map((item) => ({ ...item, range: [item.low, item.high] }))

const chartConfig = {
  range: { label: "Temperature" },
} satisfies ChartConfig

export function BarChartRange() {
  const { colors } = useTheme()
  const tickStyle = { color: colors.foreground, fontWeight: "600" } as const
  return (
    <Card variant="filled" size="sm">
      <CardHeader>
        <CardTitle>8-day forecast</CardTitle>
        <CardDescription>Each bar spans the low and high</CardDescription>
      </CardHeader>
      <CardContent>
        <ChartContainer
          config={chartConfig}
          accessibilityLabel="8-day forecast"
          style={{ height: 240 }}
        >
          <BarChart
            data={chartData}
            layout="vertical"
            barCategoryGap={7}
            margin={{ top: 0, right: 0, left: 0, bottom: 0 }}
          >
            <YAxis
              dataKey="day"
              type="category"
              width="auto"
              tickStyle={tickStyle}
            />
            <YAxis
              dataKey="high"
              type="category"
              orientation="right"
              width="auto"
              tickStyle={tickStyle}
              tickFormatter={(value) => `${value}°`}
            />
            <XAxis type="number" hide domain={[8, 27]} />
            <ChartTooltip
              cursor={false}
              content={
                <ChartTooltipContent
                  hideIndicator
                  formatter={(value) => (
                    <Text
                      style={{
                        fontWeight: "600",
                        fontVariant: ["tabular-nums"],
                      }}
                    >
                      {typeof value === "number"
                        ? String(value)
                        : `${value[0]}° to ${value[1]}°`}
                    </Text>
                  )}
                />
              }
            />
            <Bar
              dataKey="range"
              fill={{
                direction: "horizontal",
                stops: [
                  { offset: 0, color: "chart-2" },
                  { offset: 0.55, color: "yellow-500" },
                  { offset: 1, color: "chart-4" },
                ],
              }}
              radius={99}
              background={{ fill: "secondary", radius: 99 }}
            />
          </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/BarChartRange.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/BarChartRange.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 { BarChartRange } from "@/components/charts/bar-chart-range"
```

```tsx
<BarChartRange />
```

Replace `chartData` with your days and `low` and `high` values; the `range` pair is derived from them. Adjust the hidden `XAxis` `domain` to fit your temperature range. The component takes no props.

