Needs you line
ProOne line at the top of a home page that says what waits on this person in this scope: "3 things need you" with a Review link, "Nothing needs you right now" only when the count is known and zero, and "Couldn't check what needs you" with the reason and Retry when it couldn't be read. Each state has its icon and tone beside its words.
Pass the same count you give the navigation's urgent badge (a NavItem's count with urgent, in AppSidebar or the rail), read from the same source and scoped the same way, so the line and the badge never disagree. Put the app's own words after it with after ("Here's what happened since yesterday").
When Retry is pressed and the count arrives, Retry leaves the page; if Retry still had focus, focus moves to the line, never to the page's body. If the person had moved on (to another control, or by clicking elsewhere), focus stays where they put it and the new sentence is announced instead.
Version 5.2.0· other versions
This page is for 5.2.0, the current release. An earlier release’s page is the Markdown that release published, so the docs match the version you have installed (candor-lock.json records it).
Not in the docs of 1.3.0, 1.4.0, 1.5.0, 1.5.1, 1.6.0, 1.7.0, 1.8.0, 1.8.1, 1.9.0, 1.9.1, 2.0.0, 2.1.0, 2.2.0, 2.3.0, 2.4.0, 2.5.0, 2.5.1, 2.6.0, 2.6.1, 2.6.2, 2.7.0, 2.8.0, 2.9.0, 2.10.0, 3.0.0, 4.0.0, 4.0.1, 4.0.2, 4.1.0, 4.2.0 and 4.3.0: the page came later, or had another name then.
Docs pages weren’t kept for 1.0.0, 1.0.1, 1.1.0, 1.1.1, 1.2.0 and 1.2.1: they are kept from 1.3.0 on, and before that only llms.txt was published.
Preview
Loading the preview
Install
First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/needs-you-line
Brings in: link, locale, motion, tokens, use-announcer, use-focus-within, utils · npm: lucide-react@^1.67.0
Usage
"use client"
import * as React from "react"
import { Badge } from "@/components/candor/ui/badge"
import { NeedsYouLine } from "@/components/candor/needs-you-line"
export default function Example() {
// One count, read once, scoped to the workspace on screen: the line says it and the navigation's urgent badge shows
// it (here a badge; in the app, the `count` of the Approvals place, with `urgent`).
const [waiting, setWaiting] = React.useState<number | null>(null)
return (
<div className="flex flex-col gap-4">
<div className="flex items-center gap-2 text-sm">
<span>Approvals</span>
{waiting !== null && waiting > 0 && <Badge>{waiting}</Badge>}
</div>
<NeedsYouLine
count={waiting}
href="#approvals"
reason="The approvals service didn’t answer."
onRetry={() => setWaiting(3)}
after="Here’s what happened since yesterday."
/>
<NeedsYouLine count={0} after="Here’s what happened since yesterday." />
</div>
)
}<NeedsYouLine>
| Prop | Type | Default | Description |
|---|---|---|---|
| countrequired | number | null | — | How many things wait on this person in this scope: the number the navigation's urgent badge shows. `null` when it couldn't be checked. |
| href | string | undefined | — | Where those things are: "Review" is a link there. |
| onOpen | (() => void) | undefined | — | Opens those things, when they aren't at an address: "Review" is a button. `href` wins when both are given. |
| reason | string | undefined | — | Why the count couldn't be checked, shown after the sentence when `count` is null. |
| onRetry | (() => void) | undefined | — | Tries the check again; shown as Retry when `count` is null. |
| after | string | undefined | — | The app's words after the sentence: "Here's what happened since yesterday". |
| className | string | undefined | — | Extra classes for the outer element. |
Strings
The fixed words, in English by default. Change any of them under needsYouLine in <LocaleProvider strings={{ … }}>; the table is exported as needsYouLineStrings.
| Key | English |
|---|---|
| nothing | Nothing needs you right now |
| some | { one: "{count} thing needs you", other: "{count} things need you" } |
| unknown | Couldn’t check what needs you |
| review | Review |
| retry | Retry |
Motion
| Moment | Family | What it does |
|---|---|---|
| count | value, fade | When the count changes while the line is on screen (a new count arrives, or a check that failed succeeds), the sentence crossfades to the new one. A line that mounts with its count draws it still, and the change isn't announced: the navigation's badge and the notifications carry news. |
Set with --cd-motion-needs-you-line-<moment>-* in your brand file; the families are in the design reference.