{% props field: Field, options: Vec<(String, String)>, label: String = "", placeholder: String = "Select…", heading: String = "", disabled: Vec<String> = Vec::new(), size: String = "" %}
{# heading: an optional label over the options; disabled: values shown but not choosable #}
{%- let label = if label.is_empty() { field.label.clone() } else { label } %}
{%- let chosen = options.iter().find(|(value, _)| *value == field.value).map(|(_, text)| text.clone()) %}
<div class="ui-field">
<label class="ui-label" id="{{ field.id }}-label">{{ label }}</label>
<div data-ui="select">
<input type="hidden" name="{{ field.name }}" value="{{ field.value }}">
<button class="ui-select-trigger"{% if !size.is_empty() %} data-size="{{ size }}"{% end %} type="button" id="{{ field.id }}" data-ui-part="trigger" popovertarget="{{ field.id }}-listbox" aria-haspopup="listbox" aria-expanded="false" aria-labelledby="{{ field.id }}-label {{ field.id }}"{% if chosen.is_none() %} data-placeholder{% end %}{% if field.has_errors() %} aria-invalid="true" aria-describedby="{{ field.id }}-error"{% end %}>
<span class="ui-select-value">{% if let Some(text) = &chosen %}{{ text }}{% else %}{{ placeholder }}{% end %}</span>
<svg class="ui-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div class="ui-menu" id="{{ field.id }}-listbox" role="listbox" aria-labelledby="{{ field.id }}-label" popover data-ui-part="content">
{%- if !heading.is_empty() %}
<div class="ui-menu-label">{{ heading }}</div>
{%- end %}
{%- for (value, text) in options.iter() %}
<div class="ui-menu-item" role="option" data-value="{{ value }}"{% if *value == field.value %} aria-selected="true"{% end %}{% if disabled.contains(value) %} aria-disabled="true"{% end %}>{{ text }}{% if *value == field.value %}<svg class="ui-icon ui-menu-check" viewBox="0 0 24 24" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>{% end %}</div>
{%- end %}
</div>
</div>
{%- if field.has_errors() %}
<p class="ui-field-error" id="{{ field.id }}-error">{%- for message in field.errors.iter() %}{{ label }} {{ message }}. {% end %}</p>
{%- end %}
</div>