Point and ask
Click a spot on an image or a page to pin a question to it, so the model answers about that exact place.
Loading preview…
Install
- 1
Run this command in your Tailwind CSS project. It adds
components/ai/point-and-ask-image.tsxand installs its dependencies.$ npx shadcn@latest add https://gradientdeck.com/ai-components/r/point-and-ask-image.json
Usage & API
Example
import { PinnedImage } from "@/components/ai/point-and-ask-image"
<PinnedImage
children={children}
pins={[]}
openId={null}
onOpenChange={() => {}}
onAsk={() => {}}
onRemove={() => {}}
nextNumber={1}
/>Props PinnedImage
| Prop | Type & description | Required |
|---|---|---|
children | ReactNodeThe image itself. It is stretched to fill the frame. | Required |
pins | ImagePin[] | Required |
openId | string | nullPin whose answer card is open. | Required |
onOpenChange | (id: string | null) => void | Required |
hoverId | string | nullPin highlighted from elsewhere, e.g. a list row under the pointer. | Optional |
onHoverChange | (id: string | null) => void | Optional |
onAsk | (x: number, y: number, question: string) => void | Required |
onRemove | (id: string) => void | Required |
nextNumber | numberNumber the next pin will get. | Required |
aspect | stringCSS aspect ratio of the frame, e.g. "4 / 3". | Optional |
placeholderFor | (x: number, y: number) => stringPlaceholder for the composer, given the spot in percent. | Optional |
label | string | Optional |
Dependencies
- React
- Tailwind CSS
- motion
- lucide-react
Implementation notes
The image variant frames a picture, here a Lisbon guide cover, with a crosshair. Clicking opens a composer labeled with the next pin number, a placeholder that names the region under the pointer, and an ask button that stays disabled until there is text. Seeded pins 1 and 2 already have answers about the tram and the bridge. Opening one shows the answer card. The list on the right is titled Pinned questions, counts the pins, and offers an empty state that says to click a spot. A removed pin can be undone from a status strip. Enter on the frame itself pins the centre.
Example
import { PinnedPage } from "@/components/ai/point-and-ask-page"
<PinnedPage
children={children}
pins={[]}
activeId={null}
onActiveChange={() => {}}
hoverId={null}
onHoverChange={() => {}}
onAsk={() => {}}
nextNumber={1}
/>Props PinnedPage
| Prop | Type & description | Required |
|---|---|---|
children | ReactNodeThe page being reviewed. Elements with `data-target="Name"` become pin anchors and give pins a readable label. | Required |
pins | ReviewPin[] | Required |
activeId | string | null | Required |
onActiveChange | (id: string | null) => void | Required |
hoverId | string | null | Required |
onHoverChange | (id: string | null) => void | Required |
onAsk | (pin: { x: number; y: number; target: string }, question: string) => void | Required |
nextNumber | number | Required |
showResolved | boolean | Optional |
Dependencies
- React
- Tailwind CSS
- motion
- lucide-react
Implementation notes
The page variant reviews a marketing page inside a fake browser, with a header that names the draft, an In review chip, a desktop or phone width toggle, and a count of open pins. Pins stick to named targets such as the hero button or a plan card, and resolved ones turn into a check and can be hidden. The side column has Open and Resolved tabs with counts, a resolve or reopen control, a reply field, and an AI line while it looks at the page. Resolving raises an undo toast. Escape closes the active thread unless the composer is focused.
Choosing a layout
Use it in a design review, a generated cover, or a screenshot walkthrough, where "the button" is ambiguous and the person would otherwise crop, arrow, or describe coordinates. The image layout fits one picture plus a list of questions. The page layout fits a scrolling mock inside a browser chrome, with open and resolved threads in a side column.
Skip it when the question is about the whole file, or when the person is editing pixels rather than asking. A full research write-up belongs in report output, and a quoted passage from a PDF belongs in the source viewer. Those siblings cite a document. This one cites a coordinate.
Does a pin remember where it was after the picture or the page changes size?
Yes. An image pin stores x and y as a percent of the frame. A page pin stores a percent of the element named in its target, or of the whole page when the click missed every named target, then the layout is measured again on resize.
Can someone ask a follow-up on the same spot?
On the page variant, yes. An open thread has a reply field, and the model answer is appended as another message. The image variant is one question and one answer per pin. A new question is a new pin.