# Line Chart Goal

Daily step counts plotted against a labeled dashed goal line at 10,000 steps.

Line Chart Goal 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/line-chart-goal

**React**

**Example**

```tsx title="components/charts/line-chart-goal.tsx"
"use client"

import {
  CartesianGrid,
  Line,
  LineChart,
  ReferenceLine,
  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 GOAL = 10000

const chartData = [
  { day: "Mon", steps: 8412 },
  { day: "Tue", steps: 10230 },
  { day: "Wed", steps: 6120 },
  { day: "Thu", steps: 12480 },
  { day: "Fri", steps: 9050 },
  { day: "Sat", steps: 14320 },
  { day: "Sun", steps: 4870 },
]

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

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

export function LineChartGoal() {
  return (
    <Card variant="filled" size="sm">
      <CardHeader>
        <CardTitle>Goal line</CardTitle>
        <CardDescription>A daily goal of 10,000 steps</CardDescription>
      </CardHeader>
      <CardContent>
        <ChartContainer
          config={chartConfig}
          className="aspect-auto h-48 w-full"
        >
          <LineChart
            accessibilityLayer
            data={chartData}
            margin={{ top: 10, right: 4, left: 12, bottom: 0 }}
          >
            <CartesianGrid vertical={false} strokeDasharray="2 4" />
            <XAxis
              dataKey="day"
              tickLine={false}
              axisLine={false}
              tickMargin={8}
              interval={0}
            />
            <YAxis
              orientation="right"
              tickLine={false}
              axisLine={false}
              tickMargin={6}
              width="auto"
              tickFormatter={(value: number) => `${value / 1000}k`}
            />
            <ReferenceLine
              y={GOAL}
              stroke="var(--color-green-500)"
              strokeDasharray="4 4"
              label={{
                value: "Goal",
                position: "insideTopLeft",
                className: "fill-muted-foreground text-xs font-semibold",
              }}
            />
            <ChartTooltip
              content={
                <ChartTooltipContent
                  hideIndicator
                  formatter={(value) => (
                    <span className="font-semibold tabular-nums">
                      {stepsFormat.format(Number(value))} steps
                    </span>
                  )}
                />
              }
            />
            <Line
              dataKey="steps"
              type="monotone"
              stroke="var(--color-steps)"
              strokeWidth={2.5}
              dot={{ r: 3.5, fill: "var(--color-steps)", strokeWidth: 0 }}
            />
          </LineChart>
        </ChartContainer>
      </CardContent>
    </Card>
  )
}
```

Daily steps as a line with dots, plotted against a labeled dashed goal line. Use it when a single target gives the values their meaning, such as quotas, budgets or fitness goals.

## Installation

### CLI

```bash title="Terminal"
npx shadcn@latest add @esuiss/line-chart-goal
```

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 line-chart-goal
```

### 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/line-chart-goal.tsx`:

```tsx title="components/charts/line-chart-goal.tsx"
"use client"

import {
  CartesianGrid,
  Line,
  LineChart,
  ReferenceLine,
  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 GOAL = 10000

const chartData = [
  { day: "Mon", steps: 8412 },
  { day: "Tue", steps: 10230 },
  { day: "Wed", steps: 6120 },
  { day: "Thu", steps: 12480 },
  { day: "Fri", steps: 9050 },
  { day: "Sat", steps: 14320 },
  { day: "Sun", steps: 4870 },
]

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

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

export function LineChartGoal() {
  return (
    <Card variant="filled" size="sm">
      <CardHeader>
        <CardTitle>Goal line</CardTitle>
        <CardDescription>A daily goal of 10,000 steps</CardDescription>
      </CardHeader>
      <CardContent>
        <ChartContainer
          config={chartConfig}
          className="aspect-auto h-48 w-full"
        >
          <LineChart
            accessibilityLayer
            data={chartData}
            margin={{ top: 10, right: 4, left: 12, bottom: 0 }}
          >
            <CartesianGrid vertical={false} strokeDasharray="2 4" />
            <XAxis
              dataKey="day"
              tickLine={false}
              axisLine={false}
              tickMargin={8}
              interval={0}
            />
            <YAxis
              orientation="right"
              tickLine={false}
              axisLine={false}
              tickMargin={6}
              width="auto"
              tickFormatter={(value: number) => `${value / 1000}k`}
            />
            <ReferenceLine
              y={GOAL}
              stroke="var(--color-green-500)"
              strokeDasharray="4 4"
              label={{
                value: "Goal",
                position: "insideTopLeft",
                className: "fill-muted-foreground text-xs font-semibold",
              }}
            />
            <ChartTooltip
              content={
                <ChartTooltipContent
                  hideIndicator
                  formatter={(value) => (
                    <span className="font-semibold tabular-nums">
                      {stepsFormat.format(Number(value))} steps
                    </span>
                  )}
                />
              }
            />
            <Line
              dataKey="steps"
              type="monotone"
              stroke="var(--color-steps)"
              strokeWidth={2.5}
              dot={{ r: 3.5, fill: "var(--color-steps)", strokeWidth: 0 }}
            />
          </LineChart>
        </ChartContainer>
      </CardContent>
    </Card>
  )
}
```

4. Update the import paths to match your project.

## Usage

```tsx
import { LineChartGoal } from "@/components/charts/line-chart-goal"
```

```tsx
<LineChartGoal />
```

Replace `chartData` and set `GOAL` to your target. Change the label text on the `ReferenceLine` and the unit in the tooltip formatter and axis `tickFormatter` to match your metric.

## Notes

The value axis scales to the data only, so a goal far above or below every value may fall outside the plot; set a `domain` on the axis if that can happen. Focus the chart and use the arrow keys to step through the days.

**React Native, SwiftUI, Jetpack Compose**

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

```tsx title="uniwind/components/charts/line-chart-goal.tsx"
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
import {
  CartesianGrid,
  type ChartConfig,
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
  Line,
  LineChart,
  ReferenceLine,
  XAxis,
  YAxis,
} from "@/components/ui/chart"
import { Text } from "@/components/ui/text"

const GOAL = 10000

const chartData = [
  { day: "Mon", steps: 8412 },
  { day: "Tue", steps: 10230 },
  { day: "Wed", steps: 6120 },
  { day: "Thu", steps: 12480 },
  { day: "Fri", steps: 9050 },
  { day: "Sat", steps: 14320 },
  { day: "Sun", steps: 4870 },
]

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 LineChartGoal() {
  return (
    <Card variant="filled" size="sm">
      <CardHeader>
        <CardTitle>Goal line</CardTitle>
        <CardDescription>A daily goal of 10,000 steps</CardDescription>
      </CardHeader>
      <CardContent>
        <ChartContainer
          config={chartConfig}
          accessibilityLabel="Goal line"
          className="h-48 w-full"
        >
          <LineChart
            data={chartData}
            margin={{ top: 10, right: 4, left: 12, bottom: 0 }}
          >
            <CartesianGrid vertical={false} strokeDasharray="2 4" />
            <XAxis dataKey="day" tickMargin={8} interval={0} />
            <YAxis
              orientation="right"
              tickMargin={6}
              width="auto"
              tickFormatter={(value: number) => `${value / 1000}k`}
            />
            <ReferenceLine
              y={GOAL}
              stroke="green-500"
              strokeDasharray="4 4"
              label="Goal"
            />
            <ChartTooltip
              content={
                <ChartTooltipContent
                  hideIndicator
                  formatter={(value) => (
                    <Text className="font-semibold tabular-nums">
                      {formatSteps(Number(value))} steps
                    </Text>
                  )}
                />
              }
            />
            <Line
              dataKey="steps"
              type="monotone"
              strokeWidth={2.5}
              dot={{ r: 3.5 }}
            />
          </LineChart>
        </ChartContainer>
      </CardContent>
    </Card>
  )
}
```

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

private let goal = 10000.0

private let chartData: [(day: String, steps: Double)] = [
  ("Mon", 8412), ("Tue", 10230), ("Wed", 6120), ("Thu", 12480), ("Fri", 9050), ("Sat", 14320), ("Sun", 4870),
]

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

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

  public init() {}

  public var body: some View {
    Card(.filled, size: .sm) {
      CardHeader("Goal line", description: "A daily goal of 10,000 steps")
      CardContent {
        ChartContainer(config: chartConfig) {
          ChartAnimator { progress in
            Chart {
              RuleMark(y: .value("Goal", goal))
                .lineStyle(StrokeStyle(lineWidth: 1, dash: [4, 4]))
                .foregroundStyle(Palette.green500)
                .annotation(position: .top, alignment: .leading, spacing: 4) {
                  Text("Goal")
                    .scaledFont(TextStyle.xs, weight: .semibold)
                    .foregroundStyle(EsuissColor.mutedForeground)
                }
              ForEach(chartData.indices, id: \.self) { index in
                LineMark(x: .value("Day", index), y: .value("Steps", chartData[index].steps))
                  .interpolationMethod(.monotone)
                  .lineStyle(StrokeStyle(lineWidth: 2.5, lineCap: .round, lineJoin: .round))
                  .foregroundStyle(chartConfig.color("steps"))
                PointMark(x: .value("Day", index), y: .value("Steps", chartData[index].steps))
                  .symbolSize(selection == index ? 64 : 49)
                  .foregroundStyle(chartConfig.color("steps"))
              }
              .chartReveal(progress, x: 0...(chartData.count - 1))
            }
            .chartXScale(domain: 0...(chartData.count - 1), range: .plotDimension(padding: 12))
            .chartXAxis { ChartAxis.x(values: Array(chartData.indices)) { chartData[$0].day } }
            .chartYAxis { ChartAxis.y(count: 5) { "\(($0 / 1000).formatted())k" } }
            .chartTooltip(
              x: Array(chartData.indices),
              labels: chartData.map(\.day),
              selection: $selection,
              accessibilityLabel: "Goal line",
              items: { [ChartTooltipItem("steps", value: chartData[$0].steps)] }
            ) { payload in
              ChartTooltipContent(payload, hideIndicator: true) { item in
                Text("\(item.value, format: .number) steps")
                  .scaledFont(TextStyle.xs, weight: .semibold)
                  .monospacedDigit()
              }
            }
          }
        }
        .frame(height: 192)
      }
    }
  }
}
```

```kt title="kotlin/charts/LineChartGoal.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.font.FontWeight
import androidx.compose.ui.unit.dp
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.ChartCurve
import com.esuiss.ui.components.ChartDot
import com.esuiss.ui.components.ChartMargin
import com.esuiss.ui.components.ChartTooltipContent
import com.esuiss.ui.components.LineChart
import com.esuiss.ui.theme.EsuissTheme
import com.esuiss.ui.theme.Palette
import com.esuiss.ui.theme.Typography
import java.text.NumberFormat
import java.util.Locale

private const val GOAL = 10000.0

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

private val chartData = listOf(
    LineGoalRow("Mon", 8412.0),
    LineGoalRow("Tue", 10230.0),
    LineGoalRow("Wed", 6120.0),
    LineGoalRow("Thu", 12480.0),
    LineGoalRow("Fri", 9050.0),
    LineGoalRow("Sat", 14320.0),
    LineGoalRow("Sun", 4870.0),
)

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

private fun thousands(value: Double): String {
    val k = value / 1000
    return if (k % 1.0 == 0.0) "${k.toLong()}k" else "${k}k"
}

@Composable
fun LineChartGoal(modifier: Modifier = Modifier) {
    val colors = EsuissTheme.colors
    val stepsFormat = NumberFormat.getNumberInstance(Locale.US)
    Card(modifier, variant = CardVariant.Filled, size = CardSize.Sm) {
        CardHeader("Goal line", description = "A daily goal of 10,000 steps")
        CardContent {
            ChartContainer(
                chartConfig,
                Modifier
                    .fillMaxWidth()
                    .height(192.dp),
            ) {
                LineChart(
                    chartData,
                    margin = ChartMargin(top = 10.dp, right = 4.dp, bottom = 0.dp, left = 12.dp),
                    accessibilityLabel = "Goal line",
                ) {
                    CartesianGrid(strokeDasharray = listOf(2f, 4f))
                    XAxis(label = { it.day }, tickMargin = 8.dp, interval = 0)
                    YAxis(orientation = ChartAxisOrientation.Right, tickMargin = 6.dp, tickFormatter = ::thousands)
                    ReferenceLine(GOAL, stroke = Palette.green500, strokeDasharray = listOf(4f, 4f), label = "Goal")
                    ChartTooltip {
                        ChartTooltipContent(
                            hideIndicator = true,
                            formatter = { item ->
                                BasicText(
                                    "${stepsFormat.format(item.value)} steps",
                                    style = Typography.xs.copy(color = colors.foreground, fontWeight = FontWeight.SemiBold, fontFeatureSettings = "tnum"),
                                )
                            },
                        )
                    }
                    Line(
                        "steps",
                        value = { it.steps },
                        curve = ChartCurve.Monotone,
                        strokeWidth = 2.5.dp,
                        dot = ChartDot(3.5.dp),
                    )
                }
            }
        }
    }
}
```

Seven days of steps drawn as a monotone line with dots, a value axis in thousands on the right and a labeled dashed `ReferenceLine` at `GOAL`. The tooltip formats the count with thousands separators.

## Installation

**React Native**

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

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 line-chart-goal
```

**SwiftUI**

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

**Jetpack Compose**

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

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

```tsx title="nativewind/components/charts/line-chart-goal.tsx"
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
import {
  CartesianGrid,
  type ChartConfig,
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
  Line,
  LineChart,
  ReferenceLine,
  XAxis,
  YAxis,
} from "@/components/ui/chart"
import { Text } from "@/components/ui/text"

const GOAL = 10000

const chartData = [
  { day: "Mon", steps: 8412 },
  { day: "Tue", steps: 10230 },
  { day: "Wed", steps: 6120 },
  { day: "Thu", steps: 12480 },
  { day: "Fri", steps: 9050 },
  { day: "Sat", steps: 14320 },
  { day: "Sun", steps: 4870 },
]

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 LineChartGoal() {
  return (
    <Card variant="filled" size="sm">
      <CardHeader>
        <CardTitle>Goal line</CardTitle>
        <CardDescription>A daily goal of 10,000 steps</CardDescription>
      </CardHeader>
      <CardContent>
        <ChartContainer
          config={chartConfig}
          accessibilityLabel="Goal line"
          className="h-48 w-full"
        >
          <LineChart
            data={chartData}
            margin={{ top: 10, right: 4, left: 12, bottom: 0 }}
          >
            <CartesianGrid vertical={false} strokeDasharray="2 4" />
            <XAxis dataKey="day" tickMargin={8} interval={0} />
            <YAxis
              orientation="right"
              tickMargin={6}
              width="auto"
              tickFormatter={(value: number) => `${value / 1000}k`}
            />
            <ReferenceLine
              y={GOAL}
              stroke="green-500"
              strokeDasharray="4 4"
              label="Goal"
            />
            <ChartTooltip
              content={
                <ChartTooltipContent
                  hideIndicator
                  formatter={(value) => (
                    <Text className="font-semibold tabular-nums">
                      {formatSteps(Number(value))} steps
                    </Text>
                  )}
                />
              }
            />
            <Line
              dataKey="steps"
              type="monotone"
              strokeWidth={2.5}
              dot={{ r: 3.5 }}
            />
          </LineChart>
        </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/line-chart-goal.tsx`:

```tsx title="stylesheet/components/charts/line-chart-goal.tsx"
import { StyleSheet } from "react-native"
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
import {
  CartesianGrid,
  type ChartConfig,
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
  Line,
  LineChart,
  ReferenceLine,
  XAxis,
  YAxis,
} from "@/components/ui/chart"
import { Text } from "@/components/ui/text"

const GOAL = 10000

const chartData = [
  { day: "Mon", steps: 8412 },
  { day: "Tue", steps: 10230 },
  { day: "Wed", steps: 6120 },
  { day: "Thu", steps: 12480 },
  { day: "Fri", steps: 9050 },
  { day: "Sat", steps: 14320 },
  { day: "Sun", steps: 4870 },
]

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

const styles = StyleSheet.create({
  strong: { fontWeight: "600", fontVariant: ["tabular-nums"] },
})

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 LineChartGoal() {
  return (
    <Card variant="filled" size="sm">
      <CardHeader>
        <CardTitle>Goal line</CardTitle>
        <CardDescription>A daily goal of 10,000 steps</CardDescription>
      </CardHeader>
      <CardContent>
        <ChartContainer
          config={chartConfig}
          accessibilityLabel="Goal line"
          style={{ height: 192 }}
        >
          <LineChart
            data={chartData}
            margin={{ top: 10, right: 4, left: 12, bottom: 0 }}
          >
            <CartesianGrid vertical={false} strokeDasharray="2 4" />
            <XAxis dataKey="day" tickMargin={8} interval={0} />
            <YAxis
              orientation="right"
              tickMargin={6}
              width="auto"
              tickFormatter={(value: number) => `${value / 1000}k`}
            />
            <ReferenceLine
              y={GOAL}
              stroke="green-500"
              strokeDasharray="4 4"
              label="Goal"
            />
            <ChartTooltip
              content={
                <ChartTooltipContent
                  hideIndicator
                  formatter={(value) => (
                    <Text style={styles.strong}>
                      {formatSteps(Number(value))} steps
                    </Text>
                  )}
                />
              }
            />
            <Line
              dataKey="steps"
              type="monotone"
              strokeWidth={2.5}
              dot={{ r: 3.5 }}
            />
          </LineChart>
        </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/LineChartGoal.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/LineChartGoal.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 { LineChartGoal } from "@/components/charts/line-chart-goal"
```

```tsx
<LineChartGoal />
```

Replace `chartData` with your daily values and set `GOAL`. The component takes no props.

