tmp/webapp-docs/src/components/Field.js

import { jsxDEV as _jsxDEV } from "react/jsx-dev-runtime";
/**
 * Small labeled, controlled form controls (Text, Num, Toggle, Select, TextArea,
 * Group). Each takes `value` + `onChange(newValue)` so the parent owns state.
 * @module web-app/components/Field
 */
// Small labeled form controls. Each takes a value + onChange(newValue) so the
// parent owns state. Keeps the Settings / Builder forms uncluttered.

/**
 * Labeled text input.
 * @param {object} props `{ label, value, onChange, ...rest }`.
 * @returns {JSX.Element}
 */
export function Text({
  label,
  value,
  onChange,
  ...rest
}) {
  return /*#__PURE__*/_jsxDEV("label", {
    className: "field",
    children: [label && /*#__PURE__*/_jsxDEV("span", {
      children: label
    }, void 0, false), /*#__PURE__*/_jsxDEV("input", {
      type: "text",
      value: value ?? "",
      onChange: e => onChange(e.target.value),
      ...rest
    }, void 0, false)]
  }, void 0, true);
}

/**
 * Labeled number input (emits a Number, or "" when cleared).
 * @param {object} props `{ label, value, onChange, step, min, max }`.
 * @returns {JSX.Element}
 */
export function Num({
  label,
  value,
  onChange,
  step,
  min,
  max
}) {
  return /*#__PURE__*/_jsxDEV("label", {
    className: "field",
    children: [label && /*#__PURE__*/_jsxDEV("span", {
      children: label
    }, void 0, false), /*#__PURE__*/_jsxDEV("input", {
      type: "number",
      value: value ?? 0,
      step: step,
      min: min,
      max: max,
      onChange: e => onChange(e.target.value === "" ? "" : Number(e.target.value))
    }, void 0, false)]
  }, void 0, true);
}

/**
 * Labeled checkbox.
 * @param {object} props `{ label, value, onChange }`.
 * @returns {JSX.Element}
 */
export function Toggle({
  label,
  value,
  onChange
}) {
  return /*#__PURE__*/_jsxDEV("label", {
    className: "field field-toggle",
    children: [/*#__PURE__*/_jsxDEV("input", {
      type: "checkbox",
      checked: !!value,
      onChange: e => onChange(e.target.checked)
    }, void 0, false), /*#__PURE__*/_jsxDEV("span", {
      children: label
    }, void 0, false)]
  }, void 0, true);
}

/**
 * Labeled select. `options` are strings or `{ value, label }`.
 * @param {object} props `{ label, value, onChange, options }`.
 * @returns {JSX.Element}
 */
export function Select({
  label,
  value,
  onChange,
  options
}) {
  return /*#__PURE__*/_jsxDEV("label", {
    className: "field",
    children: [label && /*#__PURE__*/_jsxDEV("span", {
      children: label
    }, void 0, false), /*#__PURE__*/_jsxDEV("select", {
      value: value,
      onChange: e => onChange(e.target.value),
      children: options.map(o => {
        const opt = typeof o === "string" ? {
          value: o,
          label: o
        } : o;
        return /*#__PURE__*/_jsxDEV("option", {
          value: opt.value,
          children: opt.label
        }, opt.value, false);
      })
    }, void 0, false)]
  }, void 0, true);
}

/**
 * Labeled textarea.
 * @param {object} props `{ label, value, onChange, rows, ...rest }`.
 * @returns {JSX.Element}
 */
export function TextArea({
  label,
  value,
  onChange,
  rows = 3,
  ...rest
}) {
  return /*#__PURE__*/_jsxDEV("label", {
    className: "field",
    children: [label && /*#__PURE__*/_jsxDEV("span", {
      children: label
    }, void 0, false), /*#__PURE__*/_jsxDEV("textarea", {
      value: value ?? "",
      rows: rows,
      onChange: e => onChange(e.target.value),
      ...rest
    }, void 0, false)]
  }, void 0, true);
}

/**
 * Titled section wrapper.
 * @param {object} props `{ title, children }`.
 * @returns {JSX.Element}
 */
export function Group({
  title,
  children
}) {
  return /*#__PURE__*/_jsxDEV("section", {
    className: "group",
    children: [title && /*#__PURE__*/_jsxDEV("h2", {
      children: title
    }, void 0, false), /*#__PURE__*/_jsxDEV("div", {
      className: "group-body",
      children: children
    }, void 0, false)]
  }, void 0, true);
}