frm/ui/fields/single_choice.templ
2025-02-21 18:06:01 -07:00

82 lines
2.7 KiB
Text

package fields
import (
"fmt"
"github.com/acaloiaro/frm/types"
)
// SingleChoice is a form input type allowing only a single choice (radio)
templ SingleChoice(field types.FormField) {
@LabeledField(field) {
<div class="w-full">
<div class="join w-full">
for _, option := range field.SortedOptions() {
<label class="join-item h-auto flex-grow shrink btn has-[:checked]:bg-sky-400 first:border-x-0 last:border-r-0 border-y-0 border-black bg-sky-50 py-3">
<!-- the input field is hidden with opacity, width, and height, but available for HTML validation when 'required' -->
<input
class="opacity-0 w-0 h-0"
type="radio"
id={ field.ID.String() }
name={ field.ID.String() }
aria-label={ option.Label }
value={ option.Value }
if field.Required {
required
}
_={ fmt.Sprintf("on change trigger field_change(field_id: '%s', value: my.value)", field.ID.String()) }
/>
{ option.Label }
</label>
}
</div>
if len(field.OptionLabels) > 0 {
<div class="flex flex-grow w-full text-center text-gray-400">
for _, label := range field.OptionLabels {
<div class="w-full first:text-left last:text-right">{ label }</div>
}
</div>
}
</div>
<div
id={ fmt.Sprintf("errors-%s", field.ID.String()) }
class="text-red-400"
></div>
}
}
// SingleChoiceSpaced is a form input type allowing only a single choice (radio), spaced out
templ SingleChoiceSpaced(field types.FormField) {
@LabeledField(field) {
<div class="w-full">
<div class="grid grid-cols-1 xl:grid-cols-2 gap-8">
for _, option := range field.SortedOptions() {
<label
class="flex gap-2 w-auto h-auto btn bg-sky-50 has-[:checked]:bg-sky-400 has-[:checked]:border-sky-500 py-3"
>
<span>{ option.Label }</span>
<span class="grow"></span>
<input
type="radio"
class="peer opacity-0 w-0 h-0"
name={ field.ID.String() }
aria-label={ option.Label }
value={ option.Value }
if field.Required {
required
}
_={ fmt.Sprintf("on change trigger field_change(field_id: '%s', value: my.value)", field.ID.String()) }
/>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-7 invisible peer-checked:visible bg-sky-200 rounded-full p-1">
<path fill-rule="evenodd" d="M19.916 4.626a.75.75 0 0 1 .208 1.04l-9 13.5a.75.75 0 0 1-1.154.114l-6-6a.75.75 0 0 1 1.06-1.06l5.353 5.353 8.493-12.74a.75.75 0 0 1 1.04-.207Z" clip-rule="evenodd"></path>
</svg>
</label>
}
</div>
</div>
<div
id={ fmt.Sprintf("errors-%s", field.ID.String()) }
class="text-red-400"
></div>
}
}