# Composer scope picker

Where the next message's work lands, as a pill that opens a picker, for Composer's `tools` slot (leave Composer's own `scope` out). A scope can be an environment, a client, a project or the person's own ("Just me"), each with its icon and words; production is a warning in words, not only colour. The picker groups the scopes by kind in the order each kind first appears, ticks the current one and starts focus on it; Up, Down, Home and End move without choosing, and a press chooses. Nothing is chosen for the person: the pill shows the scope the app says is current.

- Registry name: `composer-scope-picker` (`@candor/composer-scope-picker`)
- Tier: Pro. Installing it needs a Pro, Premium or Team licence key: the person runs `npx candor-ui key <key>` themselves; never ask for the key in chat or write it to a file.
- Docs: https://candor.themethodic.com/docs/composer-scope-picker

## Install

```bash
npx candor-ui add composer-scope-picker
```

Run `npx candor-ui@latest init` once first (https://candor.themethodic.com/get-started.md). Without the CLI: `npx shadcn@latest add @candor/composer-scope-picker`.
It brings in: bidi, chat, locale, popover, tokens, utils.
npm packages: lucide-react@^1.67.0.

## Example

```tsx
"use client"

import * as React from "react"
import { Composer } from "@/components/candor/composer"
import { ComposerScopePicker, type ComposerScopeChoice } from "@/components/candor/composer-scope-picker"

// The places a message's work can land, by kind: the pill opens a picker of them, the current one ticked.
const scopes: ComposerScopeChoice[] = [
  { id: "client", kind: "client", environment: "Harbour Trading", production: false },
  { id: "project", kind: "project", environment: "Spring release", production: false },
  { id: "staging", environment: "Shop", detail: "staging", production: false },
  { id: "prod", environment: "Shop", production: true },
  { id: "me", kind: "personal", environment: "", production: false },
]

export default function Example() {
  const [value, setValue] = React.useState("")
  const [scope, setScope] = React.useState(scopes[2]!)
  // Composer's own `scope` is left out: the picker in `tools` shows it.
  return (
    <Composer
      className="max-w-2xl"
      value={value}
      onValueChange={setValue}
      onSubmit={() => setValue("")}
      tools={<ComposerScopePicker scope={scope} scopes={scopes} onScopeChange={setScope} />}
    />
  )
}
```

## <ComposerScopePicker>

Props:

- `scope: ComposerScopeChoice`: Where the next message's work lands now, from your app. Production turns the pill to a warning.
- `scopes: ComposerScopeChoice[]`: The scopes the person can choose: environments, clients, projects and their own ("Just me").
- `onScopeChange: (scope: ComposerScopeChoice) => void`: Called with the scope the person chooses; set `scope` to it.
- `className?: string | undefined`: Classes, merged with Candor's.

## Strings (`composerScopePicker`)

The fixed words, English by default. Override any of them under `composerScopePicker` in `<LocaleProvider strings={{ composerScopePicker: { … } }}>`; the table is exported as `composerScopePickerStrings`.

- `production`: Production
- `nonProduction`: Non-production
- `personal`: Just me
- `scopeKind`: ({kind})
- `kindEnvironment`: {environment}
- `kindClient`: client
- `kindProject`: project
- `kindPersonal`: personal
- `groupEnvironment`: {Environments}
- `groupClient`: Clients
- `groupProject`: Projects
- `groupPersonal`: Personal
- `scopeMenu`: Where this message’s work lands

## Types

### ComposerScopeKind

What kind of place a scope is.

```ts
"environment" | "client" | "project" | "personal"
```

### ComposerScopeChoice

A place the next message's work can land: Composer's `ComposerScope`, with a kind and an id. Without `kind` it is an environment, as Composer draws it. With a `kind`, `environment` is that scope's name (a client's or a project's), and `production` still turns it to a warning.

```ts
ComposerScope & {
  /**
   * What kind of place it is: "environment" (the default), "client", "project", or "personal" (the person's own, not
   * tied to a client or project), each drawn with its icon and words. A personal scope reads "Just me".
   */
  kind?: ComposerScopeKind | undefined;
  /** Tells scopes apart; without it, kind, account, name and detail do. */
  id?: string | undefined;
}
```

## Types from other items

The props above take these. Each is defined by another item; import it from the path shown.

### ComposerScope

Import: `import type { ComposerScope } from "@/lib/candor/chat"` (item `chat`, https://candor.themethodic.com/docs/chat.md)

Where the next message's work lands.

```ts
{ account?: string | undefined; environment: string; detail?: string | undefined; production: boolean }
```

## Motion

- **tint** (tint): The pill's and each option's background changes when the pointer is over it.

Set with `--cd-motion-composer-scope-picker-<moment>-*` in your brand file; the families are in the design reference.

## Rules for using Candor UI

- Components take plain typed data. Never pass model output as HTML or render it as a link; messages are typed blocks.
- A control that can't be used says why: wrap it in `<Locked reason="…">`, don't just disable it.
- Don't show a value you don't have: leave it out (it renders as —) rather than guess. An estimate is labelled as one.
- Nothing is pre-selected in a decision a person makes, and the agent is named from your app's data, never from model output.
- Your app's words go in `LocaleProvider`: its fixed strings in `strings`, its nouns in `nouns`; entity kinds and agent roles in `EntityKindsProvider` and `AgentRolesProvider`.
