Class: Charming::Components::Autocomplete

Inherits:
Charming::Component show all
Defined in:
lib/charming/presentation/components/autocomplete.rb

Overview

Autocomplete is a combobox: a TextInput with a suggestion list beneath it, filtered live against the typed value. Up/down move through suggestions, Enter submits the highlighted suggestion (or the free text when nothing matches), Escape cancels.

Autocomplete.new(suggestions: ["ruby", "rails", "rspec"], value: "r")

‘handle_key` returns `[:submitted, value]` on Enter, `:cancelled` on Escape, `:handled` for consumed keys, nil otherwise.

Constant Summary collapse

DEFAULT_MAX_SUGGESTIONS =
6

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from View

#focused?, #layout_assigns

Constructor Details

#initialize(suggestions:, value: "", cursor: nil, placeholder: "", selected_index: 0, max_suggestions: DEFAULT_MAX_SUGGESTIONS, theme: nil) ⇒ Autocomplete

suggestions is the full candidate list. value/cursor seed the inner TextInput. max_suggestions caps the visible dropdown rows.



22
23
24
25
26
27
28
29
30
# File 'lib/charming/presentation/components/autocomplete.rb', line 22

def initialize(suggestions:, value: "", cursor: nil, placeholder: "", selected_index: 0,
  max_suggestions: DEFAULT_MAX_SUGGESTIONS, theme: nil)
  super(theme: theme)
  @suggestions = Array(suggestions).map(&:to_s)
  @input = TextInput.new(value: value, cursor: cursor, placeholder: placeholder)
  @selected_index = selected_index
  @max_suggestions = max_suggestions
  clamp_selection
end

Instance Attribute Details

#selected_indexObject (readonly)

The current typed value and the highlighted suggestion index.



18
19
20
# File 'lib/charming/presentation/components/autocomplete.rb', line 18

def selected_index
  @selected_index
end

Instance Method Details

#captures_text?Boolean

Free-typed characters belong to this component while it is focused.

Returns:

  • (Boolean)


51
52
53
# File 'lib/charming/presentation/components/autocomplete.rb', line 51

def captures_text?
  true
end

#cursorObject

The inner input’s cursor offset.



38
39
40
# File 'lib/charming/presentation/components/autocomplete.rb', line 38

def cursor
  @input.cursor
end

#filtered_suggestionsObject

The suggestions matching the current value (case-insensitive substring), capped at max_suggestions. All suggestions when the value is empty.



44
45
46
47
48
# File 'lib/charming/presentation/components/autocomplete.rb', line 44

def filtered_suggestions
  query = value.downcase
  matches = query.empty? ? @suggestions : @suggestions.select { |s| s.downcase.include?(query) }
  matches.first(@max_suggestions)
end

#handle_key(event) ⇒ Object

Enter submits, Escape cancels, up/down move the highlight, everything else edits the text (resetting the highlight).



57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/charming/presentation/components/autocomplete.rb', line 57

def handle_key(event)
  case Charming.key_of(event)
  when :escape then :cancelled
  when :enter then [:submitted, submission_value]
  when :up then move_selection(-1)
  when :down then move_selection(+1)
  else
    result = @input.handle_key(event)
    clamp_selection if result
    result
  end
end

#renderObject

Renders the input row followed by the suggestion dropdown.



71
72
73
# File 'lib/charming/presentation/components/autocomplete.rb', line 71

def render
  [input_line, *suggestion_lines].join("\n")
end

#valueObject

The typed text.



33
34
35
# File 'lib/charming/presentation/components/autocomplete.rb', line 33

def value
  @input.value
end