# P composer 9

> Rounded adaptive composer with circular actions

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

- Page, with a live preview: https://shadcn.exchange/r/coss/p-composer-9
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/coss/p-composer-9-light-83b794519170c4e7.png
- Registry item: https://coss.com/ui/r/p-composer-9.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-9.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-9.tsx`

```tsx
"use client";

import { ArrowUpIcon, PlusIcon } from "lucide-react";
import { useState } from "react";
import { Button } from "@/registry/default/ui/button";
import {
  Composer,
  ComposerActionGroup,
  ComposerActions,
  ComposerInput,
  ComposerSubmit,
  type ComposerValue,
  getComposerText,
} from "@/registry/default/ui/composer";

export default function Particle() {
  const [value, setValue] = useState<ComposerValue>([]);
  const [notice, setNotice] = useState("");

  return (
    <div className="flex w-full max-w-xl flex-col gap-2">
      <Composer
        className="rounded-[calc(--spacing(6.5)+1px)] before:rounded-[--spacing(6.5)] sm:rounded-[calc(--spacing(6)+1px)] sm:before:rounded-[--spacing(6)]"
        layout="adaptive"
        value={value}
        onValueChange={setValue}
        onSubmit={(draft) => {
          setNotice(`Sent: ${getComposerText(draft)}`);
          setValue([]);
        }}
      >
        <ComposerInput aria-label="Message" placeholder="Write a message…" />
        <ComposerActions>
          <ComposerActionGroup>
            <Button
              aria-label="Add an attachment"
              className="rounded-full"
              size="icon"
              type="button"
              variant="ghost"
              onClick={() => setNotice("Add an attachment")}
            >
              <PlusIcon aria-hidden="true" />
            </Button>
          </ComposerActionGroup>
          <ComposerActionGroup align="end">
            <ComposerSubmit
              render={
                <Button
                  aria-label="Send message"
                  className="rounded-full"
                  size="icon"
                >
                  <ArrowUpIcon aria-hidden="true" />
                </Button>
              }
            />
          </ComposerActionGroup>
        </ComposerActions>
      </Composer>
      <p className="min-h-5 text-muted-foreground text-sm" role="status">
        {notice}
      </p>
    </div>
  );
}
```
