← All proposals

Send Button

A square, filled icon button (primary Button colors, IconButton shape and sizes) with three states:

Net-new componentOpen in Storybook

proposals/SendButton/decisions.md14 lines · View on GitHub

Decisions

  • New component, IconButton's structure. Same sizes (xs, s, m), tooltip behavior, icon sizes and focus ring as IconButton; none of its variants, hasBorder, pressed state or icon swap. Not a variant of IconButton because the three states and filled look are specific to chat input.
  • state prop: 'send' | 'working' | 'stop', default send. It is a state, not a variant (these change during one interaction and change behavior and the label), and not state, which in PDS means a semantic color (StatusDot, StatusType).
  • One ariaLabel, changed by the consumer per state (for example "Send message" / "Stop generating"), the same pattern as IconButton's pressed story. No text is hardcoded in the component. It is also the tooltip text.
  • Fill: primary Button tokens (--pds-color-button-primary-*), so it is dark in light mode and light in dark mode. Hover and active follow primary.
  • working is disabled: the real disabled attribute is set while state is working, so it looks like the empty-prompt disabled button (40% opacity, not-allowed cursor) with the spinner inside, and the tooltip is off. Trade-off: a disabled button can't hold focus, so keyboard focus drops when it flips from send to working; the consumer should keep focus in the input. aria-busy is still set.
  • Spinner color is configurable: spinnerColor (default currentColor; accepts any CSS color or token, or 'agentic'). Offered in Storybook as currentColor, agentic and discovery, under a Spinner group in the controls. Size is not exposed: it stays matched to the button (xs: s, s: m, m: l). Uses the local ../Spinner/Spinner proposal so 'agentic' works, so that proposal must land with this one.
  • Stop icon is not in PDS. The set has no filled-square icon (stop is only an alias on another icon). Erika's stop-solid-full.svg is Font Awesome Free's solid stop, so it is drawn inline in SendButton.tsx with that exact path (full FA canvas, viewBox 0 0 640 640, so it has the same built-in padding as the other icons). The port adds it to the registry as an FA icon (faStop, style solid, name stop) and uses <Icon>; no custom path needed, and Free-licensed.
  • Send icon is paperPlane (the regular outline, matching the design).
  • Open: should this get isAgentic like Button and IconButton?
  • Storybook: Proposals/Buttons/Send Button.
  • Marked as a net-new pattern with the new-pattern Storybook tag (sidebar "New" pill + "New pattern" badge on each story + a line in the component description). The tag is reusable: any proposal can opt in with one line in its meta.