# P composer 5

> Composer with a custom suggestion list

A shadcn/ui block from the [@coss](https://coss.com/ui) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/coss/p-composer-5).

- Page, with a live preview: https://shadcn.exchange/r/coss/p-composer-5
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/coss/p-composer-5-light-45ad0cf684074a5d.png
- Registry item: https://coss.com/ui/r/p-composer-5.json
- Categories: composer, text editor
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://coss.com/ui/r/p-composer-5.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- npm packages: `lucide-react`
- Registry items: `@coss/button`, `@coss/composer`

## Files

### `registry/default/particles/p-composer-5.tsx`

```tsx
"use client";

import { ArrowUpIcon } from "lucide-react";
import { useState } from "react";
import { Button } from "@/registry/default/ui/button";
import {
  Composer,
  ComposerActionGroup,
  ComposerActions,
  ComposerInput,
  ComposerItem,
  type ComposerItemValue,
  ComposerList,
  ComposerPopup,
  ComposerSubmit,
  type ComposerValue,
  useComposerFilter,
} from "@/registry/default/ui/composer";

const people = [
  { id: "alex", label: "Álex Morgan", description: "Design" },
  { id: "sam", label: "Sam Rivera", description: "Engineering" },
  { id: "taylor", label: "Taylor Kim", description: "Product" },
  { id: "jordan", label: "Jordan Lee", description: "Marketing" },
  { id: "casey", label: "Casey Chen", description: "Support" },
  { id: "morgan", label: "Morgan Davis", description: "Operations" },
  { id: "jamie", label: "Jamie Wilson", description: "Finance" },
  { id: "riley", label: "Riley Patel", description: "Research" },
];

export default function Particle() {
  const [value, setValue] = useState<ComposerValue>([]);
  const { startsWith } = useComposerFilter();

  return (
    <Composer
      className="w-full max-w-xl"
      value={value}
      onValueChange={setValue}
      onSubmit={() => setValue([])}
      triggers={[
        {
          character: "@",
          items: people,
          filter: (item, query) => startsWith(item.label, query),
        },
      ]}
    >
      <ComposerInput
        aria-label="Team message"
        placeholder="Mention a teammate…"
      />
      <ComposerPopup>
        <ComposerList>
          {(item: ComposerItemValue) => (
            <ComposerItem key={item.id} value={item}>
              <span className="flex min-w-0 flex-col">
                <span className="truncate">{item.label}</span>
                <span className="truncate text-muted-foreground text-xs">
                  {item.description}
                </span>
              </span>
            </ComposerItem>
          )}
        </ComposerList>
      </ComposerPopup>
      <ComposerActions>
        <ComposerActionGroup align="end">
          <ComposerSubmit
            render={
              <Button aria-label="Send message" size="icon">
                <ArrowUpIcon aria-hidden="true" />
              </Button>
            }
          />
        </ComposerActionGroup>
      </ComposerActions>
    </Composer>
  );
}
```
