← Back to Registry

text_input

Prompt the user for free-text input with an optional label.

inputpushAndWait
Display stack
text-input.tsxtsx
import { z } from "zod";
import type { ToolConfig, SlotRenderProps } from "glove-react";
import { useState } from "react";

export const textInput: ToolConfig = {
  name: "text_input",
  description:
    "Prompt the user for free-text input with an optional label. " +
    "Blocks until they submit.",
  inputSchema: z.object({
    label: z.string().describe("The label / question to display"),
    placeholder: z
      .string()
      .optional()
      .describe("Placeholder text for the input field"),
  }),
  async do(input, display) {
    const value = await display.pushAndWait({ input });
    return `User entered: ${value}`;
  },
  render({ data, resolve }: SlotRenderProps) {
    const { label, placeholder } = data as {
      label: string;
      placeholder?: string;
    };
    const [value, setValue] = useState("");
    return (
      <div
        style={{
          padding: 16,
          borderRadius: 12,
          border: "1px dashed var(--accent, #9ED4B8)",
          background: "var(--surface, #141414)",
          fontFamily:
            '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
        }}
      >
        <label
          style={{
            display: "block",
            fontSize: 14,
            fontWeight: 500,
            marginBottom: 10,
            color: "var(--text, #ededed)",
          }}
        >
          {label}
        </label>
        <div style={{ display: "flex", gap: 8 }}>
          <input
            type="text"
            value={value}
            onChange={(e) => setValue(e.target.value)}
            placeholder={placeholder ?? ""}
            onKeyDown={(e) => {
              if (e.key === "Enter" && value.trim()) resolve(value.trim());
            }}
            style={{
              flex: 1,
              padding: "8px 12px",
              border: "1px solid var(--border, #262626)",
              borderRadius: 6,
              background: "var(--bg, #0a0a0a)",
              color: "var(--text, #ededed)",
              fontSize: 13,
              outline: "none",
            }}
          />
          <button
            onClick={() => {
              if (value.trim()) resolve(value.trim());
            }}
            style={{
              padding: "8px 16px",
              border: "none",
              borderRadius: 6,
              background: "var(--accent, #9ED4B8)",
              color: "#0a0a0a",
              fontSize: 13,
              fontWeight: 500,
              cursor: "pointer",
            }}
          >
            Submit
          </button>
        </div>
      </div>
    );
  },
};
tools.tstypescript
const tools: ToolConfig[] = [
  text_input,
  // ...other tools
];