{
  "type": "dropdown",
  "description": "Select dropdown with 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 dropdown",
        "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 dropdown.",
        "type": "string"
      },
      "sql": {
        "description": "DuckDB SQL query with {{udf_name}} and $param_name placeholders. Must return 'value' and 'label' 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 non-empty value and label.",
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "value": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {}
                }
              ]
            },
            "label": {
              "type": "string"
            }
          },
          "required": [
            "value"
          ],
          "description": "A single dropdown option with value (string or object) and label (displayed). String options with empty value are filtered out."
        }
      },
      "placeholder": {
        "default": "Select an option...",
        "description": "Placeholder text shown when nothing is selected",
        "type": "string"
      },
      "defaultValue": {
        "default": "",
        "description": "Initial value when no canvas/form value exists. Can be a constant string, UDF query (e.g., {{my_udf.default_city[0]}}), or a JSON object matching an option value.",
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {}
          }
        ]
      },
      "disabled": {
        "default": false,
        "type": "boolean"
      },
      "style": {
        "description": "Inline CSS styles as a plain CSS string (e.g., \"color: red; font-size: 16px\")",
        "type": "string"
      },
      "centered": {
        "default": false,
        "description": "If true, centers the dropdown within the node.",
        "type": "boolean"
      },
      "nullable": {
        "default": false,
        "description": "If true, the dropdown does not auto-select the first option when no defaultValue is provided. The param starts cleared/null.",
        "type": "boolean"
      },
      "allowInvalidValue": {
        "default": false,
        "description": "If true, preserves param values that are not present in the current options. If false, clears invalid param values.",
        "type": "boolean"
      },
      "searchable": {
        "default": false,
        "description": "If true, shows a search input inside the dropdown panel.",
        "type": "boolean"
      }
    },
    "description": "A dropdown that syncs with canvas parameters. Prefer sql (DuckDB query with {{udf_name}} placeholders returning 'value' and 'label' columns) for dynamic options from UDF DataFrames. Fall back to options array for static choices."
  }
}
