87 lines
2.2 KiB
Ruby
87 lines
2.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class Dsfr::ComboboxComponent < ApplicationComponent
|
|
def initialize(form: nil, options: nil, url: nil, selected: nil, allows_custom_value: false, limit: nil, input_html_options: {}, hidden_html_options: {})
|
|
@form, @options, @url, @selected, @allows_custom_value, @limit, @input_html_options, @hidden_html_options = form, options, url, selected, allows_custom_value, limit, input_html_options, hidden_html_options
|
|
end
|
|
|
|
attr_reader :form, :options, :url, :selected, :allows_custom_value, :limit
|
|
|
|
private
|
|
|
|
def name
|
|
@input_html_options[:name]
|
|
end
|
|
|
|
def form_id
|
|
@input_html_options[:form_id]
|
|
end
|
|
|
|
def html_input_options
|
|
{
|
|
type: 'text',
|
|
autocomplete: 'off',
|
|
spellcheck: 'false',
|
|
id: input_id,
|
|
class: input_class,
|
|
role: 'combobox',
|
|
'aria-expanded': 'false',
|
|
'aria-describedby': @input_html_options[:describedby]
|
|
}.compact
|
|
end
|
|
|
|
def input_id
|
|
@input_html_options[:id]
|
|
end
|
|
|
|
def input_class
|
|
class_names(
|
|
"#{@input_html_options[:class]}": @input_html_options[:class].presence,
|
|
'fr-select': true,
|
|
'fr-autocomplete': @url.presence
|
|
)
|
|
end
|
|
|
|
def selected_option_label_input_value
|
|
if selected.is_a?(Array) && selected.size == 2
|
|
selected.first
|
|
elsif options.present?
|
|
selected.present? ? options_with_values.find { _1.last == selected }&.first : nil
|
|
else
|
|
selected
|
|
end
|
|
end
|
|
|
|
def selected_option_value_input_value
|
|
if selected.is_a?(Array) && selected.size == 2
|
|
selected.last
|
|
else
|
|
selected
|
|
end
|
|
end
|
|
|
|
def list_id
|
|
input_id.present? ? "#{input_id}-list" : nil
|
|
end
|
|
|
|
def options_with_values
|
|
return [] if url.present?
|
|
options.map { _1.is_a?(Array) ? _1 : [_1, _1] }
|
|
end
|
|
|
|
def options_json
|
|
return nil if url.present?
|
|
options_with_values.map { |(label, value)| { label:, value: } }.to_json
|
|
end
|
|
|
|
def hints_json
|
|
{
|
|
empty: t(".sr.results", count: 0),
|
|
one: t(".sr.results", count: 1),
|
|
many: t(".sr.results", count: 2),
|
|
oneWithLabel: t(".sr.results_with_label", count: 1),
|
|
manyWithLabel: t(".sr.results_with_label", count: 2),
|
|
selected: t(".sr.selected", count: 2)
|
|
}.to_json
|
|
end
|
|
end
|