{
  "type": "gallery-input",
  "description": "Image-card gallery input with horizontal, vertical, or grid layout and SQL or static options.",
  "hasChildren": false,
  "propsSchema": {
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
      "label": {
        "description": "Label text displayed above the gallery",
        "type": "string"
      },
      "param": {
        "description": "The canvas parameter name to sync with, or form field name if inside a Form component. If omitted, works as a regular gallery input.",
        "type": "string"
      },
      "sql": {
        "description": "DuckDB SQL query with {{udf_name}} and $param_name placeholders. Must return value, title, and image columns. Takes precedence over options. Requires at least one {{udf_name}} placeholder.",
        "type": "string"
      },
      "options": {
        "description": "Static array of options. Used when sql is not provided or when sql fails. Each option must have value, title, and image.",
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "value": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {}
                }
              ]
            },
            "title": {
              "type": "string",
              "description": "Title displayed under the image"
            },
            "image": {
              "type": "string",
              "description": "Image URL or base64 data URL"
            }
          },
          "required": [
            "value",
            "title",
            "image"
          ],
          "description": "A single gallery option with value, title, and image. String options with empty value are filtered out."
        }
      },
      "defaultValue": {
        "default": "",
        "description": "Initial value when no canvas/form value exists. Can be a constant string, UDF query (e.g., {{my_udf.default_id[0]}}), or a JSON object matching an option value.",
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {}
          }
        ]
      },
      "mode": {
        "default": "horizontal",
        "description": "Layout mode. Use horizontal for a horizontal scroll row, vertical for a vertical scroll column, or grid for a non-scrollable wrapping layout. Legacy values carousel and vertical-carousel are still supported.",
        "type": "string",
        "enum": [
          "horizontal",
          "vertical",
          "grid",
          "carousel",
          "vertical-carousel"
        ]
      },
      "nullable": {
        "default": false,
        "description": "If true, the gallery does not auto-select the first option when no defaultValue is provided. The param starts cleared/null.",
        "type": "boolean"
      },
      "cardHeight": {
        "default": 200,
        "description": "Card height in pixels.",
        "type": "number",
        "exclusiveMinimum": 0
      },
      "cardWidth": {
        "default": 280,
        "description": "Card width in pixels.",
        "type": "number",
        "exclusiveMinimum": 0
      },
      "disabled": {
        "default": false,
        "type": "boolean"
      },
      "style": {
        "description": "Inline CSS styles as a plain CSS string (e.g., \"padding: 8px; max-width: 640px\")",
        "type": "string"
      }
    },
    "description": "An image-card gallery input with horizontal, vertical, or grid layout that syncs with canvas parameters. Prefer sql (DuckDB query with {{udf_name}} placeholders returning value, title, and image columns) for dynamic options from UDF DataFrames. Fall back to options array for static choices."
  }
}
