@shapesos/clay 0.14.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -47,7 +47,7 @@ import {
47
47
  PromptInputTools,
48
48
  Suggestion,
49
49
  Suggestions
50
- } from "./chunk-BR5S37SC.js";
50
+ } from "./chunk-4VE6ZXXW.js";
51
51
  import {
52
52
  TextArea
53
53
  } from "./chunk-7OYIDM42.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapesos/clay",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "main": "./dist/index.cjs",
5
5
  "module": "./dist/index.js",
6
6
  "devDependencies": {
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/ai-elements/prompt-input/prompt-input.tsx","../src/components/ai-elements/prompt-input/types.ts","../src/components/ai-elements/mouse-grid/mouse-grid.tsx","../src/components/ai-elements/suggestion/suggestion.tsx"],"sourcesContent":["import { forwardRef, useCallback } from \"react\";\nimport type { FormEventHandler, KeyboardEventHandler, MouseEventHandler } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/button/button\";\nimport { BUTTON_INTENT, BUTTON_SIZE } from \"@/components/button/constants\";\nimport { TextArea } from \"@/components/text-area/text-area\";\nimport { CHAT_STATUS } from \"./types\";\nimport type {\n PromptInputFooterProps,\n PromptInputProps,\n PromptInputSubmitProps,\n PromptInputTextareaProps,\n PromptInputToolsProps,\n} from \"./types\";\n\n/* ------------------------------------------------------------------------------------------------\n * Originally vendored from `@vercel/ai-elements`'s `prompt-input` registry entry. Slimmed hard to\n * the creation-surface essentials a consumer composes into a prompt-launcher hero: `PromptInput`\n * (form wrapper), `PromptInputTextarea`, `PromptInputFooter`, `PromptInputTools`, `PromptInputSubmit`.\n *\n * Everything else from the upstream entry is intentionally dropped: the action menu\n * (`PromptInputActionMenu*`), attachment / screenshot actions, the attachments strip, the\n * provider/controller contexts, and the `Select` / `HoverCard` / `Command` / `Tab` families. That\n * also sheds the upstream `nanoid` (id-per-attachment) dependency.\n *\n * Rewiring to clay's single-sourced primitives let this primitive ship with ZERO new runtime\n * dependencies — diverging from the original shared spec, which assumed the kept set would still\n * lean on `@base-ui/react`, `ai`, and `lucide-react`:\n * - upstream `InputGroupButton` (submit) → clay `Button` (filled, `type=\"button\"`, consumer label).\n * - upstream `InputGroupTextarea` → clay `TextArea` (auto-resize, transparent chrome).\n * - `lucide-react` icons → clay's already-bundled `@tabler/icons-react`.\n * - `ai`'s `ChatStatus` → a local ready/error status (see `./types`).\n *\n * Because clay's `Button` always renders `type=\"button\"`, native form submit isn't available;\n * both the Enter-key handler and the submit button trigger `form.requestSubmit()` explicitly. And\n * because clay's `TextArea` doesn't forward a `name` attribute, `PromptInput` reads the textarea's\n * value straight off the DOM at submit time rather than via `FormData` — keeping the form wrapper\n * decoupled from whoever controls the textarea's value.\n *\n * Types live in `./types`.\n * ------------------------------------------------------------------------------------------------ */\n\n/**\n * Form wrapper for a prompt composer. Renders a bordered, rounded surface; stacks its children\n * (textarea + footer) vertically. Reads the nested textarea's value on submit and forwards it to\n * `onSubmit`. Empty / whitespace-only submissions, and all submissions while `disabled`, are\n * ignored.\n */\nexport const PromptInput = ({ className, onSubmit, disabled, children, ...props }: PromptInputProps) => {\n const handleSubmit: FormEventHandler<HTMLFormElement> = useCallback(\n (event) => {\n event.preventDefault();\n if (disabled) {\n return;\n }\n const textarea = event.currentTarget.querySelector(\"textarea\");\n const text = textarea?.value ?? \"\";\n if (!text.trim()) {\n return;\n }\n onSubmit({ text }, event);\n },\n [disabled, onSubmit]\n );\n\n return (\n <form\n className={cn(\n \"flex w-full flex-col overflow-hidden rounded-xl border bg-background shadow-lg shadow-foreground/5\",\n className\n )}\n onSubmit={handleSubmit}\n {...props}\n >\n {children}\n </form>\n );\n};\n\n/**\n * Auto-resizing textarea for the prompt composer. Wraps clay's `TextArea` and adds Enter-to-submit\n * (Shift+Enter inserts a newline; submission is suppressed while an IME composition is active). The\n * consumer's `onKeyDown` runs first and can `preventDefault()` to opt out of the built-in Enter\n * handling.\n *\n * Horizontal padding lives on the textarea itself (not the wrapper) so its overflow scrollbar sits\n * flush against the wrapper's right edge; the wrapper only owns the vertical padding.\n */\nexport const PromptInputTextarea = forwardRef<HTMLTextAreaElement, PromptInputTextareaProps>(\n function PromptInputTextarea({ className, onKeyDown, placeholder = \"What would you like to know?\", ...props }, ref) {\n const handleKeyDown: KeyboardEventHandler<HTMLTextAreaElement> = useCallback(\n (event) => {\n onKeyDown?.(event);\n if (event.defaultPrevented) {\n return;\n }\n if (event.key === \"Enter\" && !event.shiftKey && !event.nativeEvent.isComposing) {\n event.preventDefault();\n event.currentTarget.form?.requestSubmit();\n }\n },\n [onKeyDown]\n );\n\n return (\n <div className={cn(\"py-3\", className)}>\n <TextArea ref={ref} className=\"px-4\" onKeyDown={handleKeyDown} placeholder={placeholder} {...props} />\n </div>\n );\n }\n);\n\n/**\n * Footer row beneath the textarea — left tools and the right-aligned submit button. Horizontal\n * padding matches {@link PromptInputTextarea}'s (`px-4`) so the tools/submit align with the\n * textarea's text edges.\n */\nexport const PromptInputFooter = ({ className, ...props }: PromptInputFooterProps) => (\n <div className={cn(\"flex items-center justify-between gap-1 px-4 pb-3\", className)} {...props} />\n);\n\n/** Left-aligned cluster inside {@link PromptInputFooter} (e.g. the submit hint). */\nexport const PromptInputTools = ({ className, ...props }: PromptInputToolsProps) => (\n <div className={cn(\"flex min-w-0 items-center gap-1\", className)} {...props} />\n);\n\n/**\n * Submit button for the prompt composer — a filled clay `Button` whose text is the consumer's\n * `label` (pass a localized string for i18n). Always submits the form via `form.requestSubmit()` on\n * click (clay buttons render `type=\"button\"`); the consumer disables it while a generation is in\n * flight. `status` drives the color: `error` renders the error (red) intent, otherwise primary.\n */\nexport const PromptInputSubmit = ({\n label = \"Submit\",\n status = CHAT_STATUS.READY,\n disabled,\n className,\n}: PromptInputSubmitProps) => {\n const handleClick = useCallback<MouseEventHandler<HTMLButtonElement>>((event) => {\n event.currentTarget.form?.requestSubmit();\n }, []);\n\n return (\n <Button\n intent={status === CHAT_STATUS.ERROR ? BUTTON_INTENT.ERROR : BUTTON_INTENT.PRIMARY}\n size={BUTTON_SIZE.XS}\n className={className}\n disabled={disabled}\n onClick={handleClick}\n >\n {label}\n </Button>\n );\n};\n","import type { FormEvent, HTMLAttributes } from \"react\";\n\nimport type { TextAreaProps } from \"@/components/text-area/types\";\n\n/**\n * Submission status the submit button reflects. The composer has no cancellation and no\n * intermediate \"generating\" state of its own — the consumer disables the button while busy — so\n * only the idle and error states are modeled here.\n */\nexport const CHAT_STATUS = {\n /** Idle / ready to submit. */\n READY: \"ready\",\n /** The last submission errored — the button shows a retry affordance. */\n ERROR: \"error\",\n} as const;\n\n/** Submission status the submit button reflects. */\nexport type ChatStatus = (typeof CHAT_STATUS)[keyof typeof CHAT_STATUS];\n\n/** Payload emitted by {@link PromptInput} on submit. v1 carries only text (attachments are cut). */\nexport interface PromptInputMessage {\n /** The current textarea value at submit time. */\n text: string;\n}\n\n/** Props for the {@link PromptInput} form wrapper. */\nexport type PromptInputProps = Omit<HTMLAttributes<HTMLFormElement>, \"onSubmit\"> & {\n /**\n * Fired when the form is submitted (Enter key or the submit button) with non-empty text.\n * Receives the captured message and the underlying form event.\n */\n onSubmit: (message: PromptInputMessage, event: FormEvent<HTMLFormElement>) => void;\n /**\n * Blocks submission across every trigger (Enter key, submit button, programmatic) when `true` —\n * e.g. while a generation is in flight. The single gate that keeps the Enter path in sync with a\n * disabled submit button. @default false\n */\n disabled?: boolean;\n};\n\n/** Props for {@link PromptInputTextarea} — clay `TextArea` props; `className` styles the wrapper. */\nexport type PromptInputTextareaProps = TextAreaProps;\n\n/** Props for {@link PromptInputFooter}. */\nexport type PromptInputFooterProps = HTMLAttributes<HTMLDivElement>;\n\n/** Props for {@link PromptInputTools}. */\nexport type PromptInputToolsProps = HTMLAttributes<HTMLDivElement>;\n\n/** Props for {@link PromptInputSubmit}. */\nexport interface PromptInputSubmitProps {\n /** Button label — pass a localized string (i18n) from the consumer. @default \"Submit\" */\n label?: string;\n /** Drives the button color: `error` renders the red error intent, otherwise primary. @default \"ready\" */\n status?: ChatStatus;\n /** Whether the button is non-interactive (e.g. empty input or a generation in flight). */\n disabled?: boolean;\n /** Additional CSS class name. */\n className?: string;\n}\n","import { useEffect, useRef, type CSSProperties } from \"react\";\n\nimport type { MouseGridProps } from \"./types\";\n\n/**\n * Absolutely-positioned grid backdrop, confined to its nearest positioned ancestor (give the\n * parent `position: relative` + `overflow: hidden` to clip it). The grid is revealed only near the\n * cursor via a radial mask whose center is driven by the `--vibe-mx` / `--vibe-my` CSS vars,\n * updated by a rAF-throttled `mousemove` listener. Renders behind all content (`z-0`) and never\n * blocks pointer events.\n *\n * Cursor coordinates are translated from viewport space (`clientX` / `clientY`) into layer-local\n * space (minus the layer's `getBoundingClientRect()` origin) and written onto the layer element\n * itself — not the document root — so the glow tracks correctly even though the layer no longer\n * fills the viewport. The rect read happens inside the rAF so it batches with paint.\n *\n * Pure `useEffect` + `requestAnimationFrame`, no animation library. The `.vibe-mouse-grid-layer` /\n * `.vibe-mouse-grid` / `.vibe-mouse-glow` styles ship in `@shapesos/clay/blocks/styles.css`.\n */\nexport function MouseGrid({ glowColor }: MouseGridProps = {}) {\n const layerRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n let raf = 0;\n let clientX = 0;\n let clientY = 0;\n function flush() {\n raf = 0;\n const layer = layerRef.current;\n if (!layer) {\n return;\n }\n const rect = layer.getBoundingClientRect();\n layer.style.setProperty(\"--vibe-mx\", `${clientX - rect.left}px`);\n layer.style.setProperty(\"--vibe-my\", `${clientY - rect.top}px`);\n }\n function onMove(event: MouseEvent) {\n clientX = event.clientX;\n clientY = event.clientY;\n if (raf) {\n return;\n }\n raf = requestAnimationFrame(flush);\n }\n window.addEventListener(\"mousemove\", onMove, { passive: true });\n return () => {\n window.removeEventListener(\"mousemove\", onMove);\n if (raf) {\n cancelAnimationFrame(raf);\n }\n };\n }, []);\n\n const glowStyle = glowColor ? ({ \"--vibe-glow-color\": glowColor } as CSSProperties) : undefined;\n\n return (\n <div ref={layerRef} aria-hidden=\"true\" className=\"vibe-mouse-grid-layer\">\n <div className=\"vibe-mouse-grid\" />\n <div className=\"vibe-mouse-glow\" style={glowStyle} />\n </div>\n );\n}\n","import { useCallback } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\nimport type { SuggestionProps, SuggestionsProps } from \"./types\";\n\n/* ------------------------------------------------------------------------------------------------\n * Vendored + slimmed from `@vercel/ai-elements`'s `suggestion` registry entry. Upstream wraps the\n * pills in a shadcn `ScrollArea` and renders each as a shadcn `Button variant=\"outline\"`; clay has\n * neither, so this ships a dependency-free row (`flex flex-wrap`) of Tailwind-styled pills using\n * clay's named color tokens. Engine note: this is vendored ai-elements chrome, so it's Tailwind —\n * clay's `Button` is styled-components with fixed radii and can't produce the rounded-full pill.\n * ------------------------------------------------------------------------------------------------ */\n\n/**\n * A centered, wrapping row of {@link Suggestion} pills — e.g. starter prompts beneath a composer.\n * Compose `Suggestion` children inside.\n */\nexport const Suggestions = ({ className, ...props }: SuggestionsProps) => (\n <div className={cn(\"flex flex-wrap items-center justify-center gap-3\", className)} {...props} />\n);\n\n/**\n * A single tappable suggestion pill. Renders `children` if provided, otherwise the `suggestion`\n * text, and calls `onClick(suggestion)` when clicked.\n */\nexport const Suggestion = ({ suggestion, onClick, className, children, ...props }: SuggestionProps) => {\n const handleClick = useCallback(() => onClick?.(suggestion), [onClick, suggestion]);\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n className={cn(\n \"cursor-pointer whitespace-nowrap rounded-full border border-brown-30 bg-white px-4 py-2 text-sm text-brown-100 transition-colors hover:bg-brown-10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brown-40\",\n className\n )}\n {...props}\n >\n {children ?? suggestion}\n </button>\n );\n};\n"],"mappings":"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","names":["PromptInputTextarea","jsx","useCallback","jsx","useCallback"]}