# Daily Rings

A goal tracker of concentric rings: open one and it grows to the centre with quick logging, a week of bars and a streak; add, edit and delete goals in place.

- Page and source: https://uibrik.com/components/daily-rings
- Install (Pro, needs a license key, see https://uibrik.com/docs/pro): `npx shadcn@latest add @uibrik-pro/daily-rings`
- Packages: none beyond React
- Import: `import { DailyRings } from "@/components/uibrik/daily-rings/daily-rings"`

Where to use the Daily Rings React component:

- **Habit and wellness apps**: Rings fill as entries are logged, so a day's progress reads at a glance and each tap visibly counts. Pairs with [Streak Calendar](https://uibrik.com/components/streak-calendar).
- **Fitness dashboards**: The week strip refills the rings for any day, which makes comparing days quicker than reading numbers.
- **Goal tracking**: Opening a goal keeps the others in view as small rings, so switching between them is one tap. Pairs with [Progress](https://uibrik.com/components/progress).

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| ringWidth | `number` | `16` | Thickness of the rings in the overview. |
| ringGap | `number` | `4` | Space between rings in the overview. |
| palette | `string[]` | `["#f2555a","#8b7cf6","#3aa8e8","#22b07d","#f59e0b","#ec4899"]` | Colours offered when adding or editing a goal. The demo also paints its first rings with them. |
| maxHabits | `number` | `4` | Most goals, and so rings. Four fit comfortably. |
| editable | `boolean` | `true` | Let goals be added, edited and deleted. |
| weekStrip | `boolean` | `true` | Show the week above the rings to switch days. |
| showOverflow | `boolean` | `true` | Keep counting past a goal in the numbers. Rings always stop full. |
| centerLabel | `string` | `"of goals"` | Line under the percentage in the overview. |
| logLabel | `string` | `"Log"` | Word on the log button, before the step amount. |
| listMaxHeight | `number` | `160` | Tallest the entries list grows before it scrolls. |
| locale | `string` | `"en-US"` | Locale for numbers and weekday names. |
| defaultHabits | `{ id: string; label: string; goal: number; step: number; unit: string; color: string; icon?: HabitIconName \| ReactNode }[]` | `SAMPLE_HABITS` | Goals on mount, outermost ring first. `step` is what one tap of the log button adds; `icon` is a built-in name (flame, bolt, droplet, moon, sun, book, heart, leaf, barbell, bike, apple, salad, pill, bed, star) or your own node. |
| habits | `Habit[]` |  | Goals (controlled). Pair with `onHabitsChange`. |
| onHabitsChange | `(habits: Habit[]) => void` |  | Called after a goal is added, edited, deleted or restored with Undo. |
| days | `{ date: string; logs: { id: string; habit: string; amount: number; time: string }[] }[]` |  | Days in the week strip (controlled). A ring's value is the sum of its logs for the day. |
| defaultDays | `HabitDay[]` | `SAMPLE_WEEK` | Days on mount (uncontrolled). |
| onDaysChange | `(days: HabitDay[]) => void` |  | Called with every day after an entry is added or removed. |
| onLog | `(habit: Habit, log: HabitLog, date: string) => void` |  | Called after an entry is logged, from the log button, the double-step chip or a custom amount. |
| onOpenChange | `(habitId: string \| null) => void` |  | Called when a goal is opened, or with null when going back to all. |
| defaultDay | `number` |  | Index of the day selected on mount. Defaults to the last day with entries. |
| className | `string` |  | Classes for the card. |
