stimulus_plumbers 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -0
  3. data/README.md +3 -1
  4. data/app/assets/javascripts/stimulus-plumbers/stimulus-plumbers-controllers.es.js +78 -52
  5. data/app/assets/javascripts/stimulus-plumbers/stimulus-plumbers-controllers.umd.js +1 -1
  6. data/app/assets/stylesheets/stimulus_plumbers/tokens.css +13 -6
  7. data/lib/stimulus_plumbers/components/action_list/item.rb +13 -10
  8. data/lib/stimulus_plumbers/components/action_list/section.rb +7 -1
  9. data/lib/stimulus_plumbers/components/action_list.rb +14 -8
  10. data/lib/stimulus_plumbers/components/avatar.rb +11 -5
  11. data/lib/stimulus_plumbers/components/button/group.rb +7 -1
  12. data/lib/stimulus_plumbers/components/button.rb +48 -10
  13. data/lib/stimulus_plumbers/components/calendar/month/turbo/days_of_month.rb +9 -5
  14. data/lib/stimulus_plumbers/components/calendar/month/turbo/days_of_week.rb +7 -3
  15. data/lib/stimulus_plumbers/components/calendar/month/turbo.rb +7 -3
  16. data/lib/stimulus_plumbers/components/calendar.rb +4 -1
  17. data/lib/stimulus_plumbers/components/card/section.rb +7 -1
  18. data/lib/stimulus_plumbers/components/card.rb +11 -5
  19. data/lib/stimulus_plumbers/components/combobox/date.rb +7 -3
  20. data/lib/stimulus_plumbers/components/combobox/dropdown.rb +7 -1
  21. data/lib/stimulus_plumbers/components/combobox/options/option.rb +7 -1
  22. data/lib/stimulus_plumbers/components/combobox/options/option_group.rb +7 -1
  23. data/lib/stimulus_plumbers/components/combobox/options.rb +9 -5
  24. data/lib/stimulus_plumbers/components/combobox/popover.rb +30 -7
  25. data/lib/stimulus_plumbers/components/combobox/time/drum.rb +7 -1
  26. data/lib/stimulus_plumbers/components/combobox/time.rb +7 -3
  27. data/lib/stimulus_plumbers/components/combobox/trigger.rb +50 -7
  28. data/lib/stimulus_plumbers/components/combobox/{autocomplete.rb → typeahead.rb} +7 -5
  29. data/lib/stimulus_plumbers/components/combobox.rb +10 -6
  30. data/lib/stimulus_plumbers/components/date_picker/navigation.rb +1 -1
  31. data/lib/stimulus_plumbers/components/date_picker/navigator.rb +7 -15
  32. data/lib/stimulus_plumbers/components/divider.rb +23 -3
  33. data/lib/stimulus_plumbers/components/icon.rb +6 -16
  34. data/lib/stimulus_plumbers/components/input_group.rb +29 -0
  35. data/lib/stimulus_plumbers/components/popover.rb +7 -3
  36. data/lib/stimulus_plumbers/form/builder.rb +1 -1
  37. data/lib/stimulus_plumbers/form/fields/inputs/datetime.rb +24 -12
  38. data/lib/stimulus_plumbers/form/fields/inputs/password.rb +3 -3
  39. data/lib/stimulus_plumbers/form/fields/inputs/search.rb +10 -10
  40. data/lib/stimulus_plumbers/form/fields/inputs/select/grouped.rb +21 -17
  41. data/lib/stimulus_plumbers/form/fields/inputs/select/timezone.rb +7 -5
  42. data/lib/stimulus_plumbers/form/fields/inputs/select/weekday.rb +7 -9
  43. data/lib/stimulus_plumbers/form/fields/inputs/select.rb +40 -28
  44. data/lib/stimulus_plumbers/helpers/action_list_helper.rb +6 -6
  45. data/lib/stimulus_plumbers/helpers/avatar_helper.rb +2 -2
  46. data/lib/stimulus_plumbers/helpers/button_helper.rb +4 -8
  47. data/lib/stimulus_plumbers/helpers/calendar_helper.rb +13 -10
  48. data/lib/stimulus_plumbers/helpers/calendar_turbo_helper.rb +2 -16
  49. data/lib/stimulus_plumbers/helpers/card_helper.rb +4 -4
  50. data/lib/stimulus_plumbers/helpers/combobox_helper.rb +36 -23
  51. data/lib/stimulus_plumbers/helpers/divider_helper.rb +2 -2
  52. data/lib/stimulus_plumbers/helpers/popover_helper.rb +2 -2
  53. data/lib/stimulus_plumbers/themes/base.rb +15 -16
  54. data/lib/stimulus_plumbers/themes/icons/external.rb +60 -0
  55. data/lib/stimulus_plumbers/themes/icons/registry.rb +36 -0
  56. data/lib/stimulus_plumbers/themes/schema/icon.rb +57 -15
  57. data/lib/stimulus_plumbers/themes/schema/ranges.rb +2 -2
  58. data/lib/stimulus_plumbers/themes/schema.rb +59 -55
  59. data/lib/stimulus_plumbers/version.rb +1 -1
  60. data/lib/stimulus_plumbers.rb +2 -2
  61. metadata +5 -3
  62. data/lib/stimulus_plumbers/form/fields/input_group.rb +0 -25
@@ -21,7 +21,13 @@ module StimulusPlumbers
21
21
  }
22
22
  end
23
23
 
24
- def render(options: [], value: nil, label: nil, labelledby: nil)
24
+ def render(...)
25
+ render_dropdown(...)
26
+ end
27
+
28
+ private
29
+
30
+ def render_dropdown(options: [], value: nil, label: nil, labelledby: nil)
25
31
  listbox_attrs = merge_html_options(
26
32
  { classes: theme.resolve(:combobox_listbox).fetch(:classes, "") },
27
33
  { role: "listbox", data: { "#{STIMULUS_CONTROLLER}_target": "listbox" } }
@@ -5,7 +5,13 @@ module StimulusPlumbers
5
5
  class Combobox
6
6
  class Options
7
7
  class Option < Plumber::Base
8
- def render(label:, value:, description: nil, disabled: false, selected: false)
8
+ def render(...)
9
+ render_option(...)
10
+ end
11
+
12
+ private
13
+
14
+ def render_option(label:, value:, description: nil, disabled: false, selected: false)
9
15
  aria = { selected: selected ? "true" : "false" }
10
16
  aria[:disabled] = "true" if disabled
11
17
 
@@ -5,7 +5,13 @@ module StimulusPlumbers
5
5
  class Combobox
6
6
  class Options
7
7
  class OptionGroup < Plumber::Base
8
- def render(label:, options:, value: nil)
8
+ def render(...)
9
+ render_option_group(...)
10
+ end
11
+
12
+ private
13
+
14
+ def render_option_group(label:, options:, value: nil)
9
15
  attrs = merge_html_options(
10
16
  { classes: theme.resolve(:combobox_option_group).fetch(:classes, "") },
11
17
  { role: "group", aria: { label: label } }
@@ -4,21 +4,25 @@ module StimulusPlumbers
4
4
  module Components
5
5
  class Combobox
6
6
  class Options < Plumber::Base
7
- def render(items, value: nil, &block)
8
- @selected_value = value.to_s
9
- template.safe_join(items.filter_map { |item| render_item(item, &block) })
7
+ def render(...)
8
+ render_options(...)
10
9
  end
11
10
 
12
11
  private
13
12
 
13
+ def render_options(items, value: nil, &block)
14
+ @selected_value = value.to_s
15
+ template.safe_join(items.filter_map { |item| render_item(item, &block) })
16
+ end
17
+
14
18
  def render_item(item, &block)
15
19
  attrs = normalize_item(item)
16
20
  return nil if attrs.nil?
17
21
 
18
22
  if attrs.key?(:optgroup)
19
- block ? block.call(attrs) : OptionGroup.new(template).render(**attrs[:optgroup], value: @selected_value)
23
+ block ? template.capture(attrs, &block) : OptionGroup.new(template).render(**attrs[:optgroup], value: @selected_value)
20
24
  else
21
- block ? block.call(attrs) : Option.new(template).render(**attrs)
25
+ block ? template.capture(attrs, &block) : Option.new(template).render(**attrs)
22
26
  end
23
27
  end
24
28
 
@@ -4,19 +4,42 @@ module StimulusPlumbers
4
4
  module Components
5
5
  class Combobox
6
6
  class Popover < Plumber::Base
7
- def render(stimulus_controller:, id:, tag: :div, role: nil, label: nil, labelledby: nil, content: nil, data: {}, &block)
8
- stimulus_data = { "#{stimulus_controller}_target": "popover" }
7
+ def render(...)
8
+ render_popover(...)
9
+ end
10
+
11
+ private
9
12
 
10
- attrs = { id: id, hidden: "", data: merge_data_options(stimulus_data, data) }
11
- attrs[:role] = role if role
13
+ def render_popover(
14
+ stimulus_controller:,
15
+ id:,
16
+ tag: :div,
17
+ role: nil,
18
+ label: nil,
19
+ labelledby: nil,
20
+ content: nil,
21
+ data: {},
22
+ **kwargs,
23
+ &block
24
+ )
25
+ opts = {}
26
+ opts[:role] = role if role
12
27
  if labelledby
13
- attrs[:aria] = { labelledby: labelledby }
28
+ opts[:aria] = { labelledby: labelledby }
14
29
  elsif label
15
- attrs[:aria] = { label: label }
30
+ opts[:aria] = { label: label }
16
31
  end
17
32
 
33
+ html_options = merge_html_options(
34
+ { id: id, hidden: "" },
35
+ { data: { "#{stimulus_controller}_target": "popover" } },
36
+ { data: data },
37
+ opts,
38
+ kwargs
39
+ )
40
+
18
41
  html_content = block_given? ? template.capture(id, &block) : content
19
- template.content_tag(tag, **attrs) { html_content }
42
+ template.content_tag(tag, html_content, **html_options)
20
43
  end
21
44
  end
22
45
  end
@@ -5,7 +5,13 @@ module StimulusPlumbers
5
5
  class Combobox
6
6
  class Time
7
7
  class Drum < Plumber::Base
8
- def render(stimulus_controller:, target:, label:, items:, selected: nil)
8
+ def render(...)
9
+ render_drum(...)
10
+ end
11
+
12
+ private
13
+
14
+ def render_drum(stimulus_controller:, target:, label:, items:, selected: nil)
9
15
  template.content_tag(
10
16
  :ul,
11
17
  **merge_html_options(
@@ -12,7 +12,13 @@ module StimulusPlumbers
12
12
  }
13
13
  end
14
14
 
15
- def render(format: :h12, step: 1, value: nil)
15
+ def render(...)
16
+ render_time(...)
17
+ end
18
+
19
+ private
20
+
21
+ def render_time(format: :h12, step: 1, value: nil)
16
22
  @format = format
17
23
  @step = [1, step.to_i].max
18
24
  @time = parse_time(value)
@@ -31,8 +37,6 @@ module StimulusPlumbers
31
37
  end
32
38
  end
33
39
 
34
- private
35
-
36
40
  def drums
37
41
  cols = [hour_drum, minute_drum]
38
42
  cols << period_drum if @format == :h12
@@ -4,27 +4,57 @@ module StimulusPlumbers
4
4
  module Components
5
5
  class Combobox
6
6
  class Trigger < Plumber::Base
7
- def render(
7
+ def render(...)
8
+ render_trigger(...)
9
+ end
10
+
11
+ private
12
+
13
+ def render_trigger(
8
14
  stimulus_controller:,
9
15
  popover_id:,
10
16
  haspopup:,
11
17
  readonly: true,
12
- aria_autocomplete: nil,
13
- aria_label: nil,
14
18
  aria: {},
15
19
  id: nil,
16
20
  data: {},
21
+ icon_leading: nil,
22
+ icon_trailing: nil,
23
+ **kwargs
24
+ )
25
+ input_html = render_input(
26
+ stimulus_controller: stimulus_controller,
27
+ popover_id: popover_id,
28
+ haspopup: haspopup,
29
+ readonly: readonly,
30
+ aria: aria,
31
+ id: id,
32
+ data: data,
33
+ **kwargs
34
+ )
35
+
36
+ return input_html unless icon_leading || icon_trailing
37
+
38
+ render_trigger_group(icon_leading, icon_trailing) { input_html }
39
+ end
40
+
41
+ def render_input(
42
+ stimulus_controller:,
43
+ popover_id:,
44
+ haspopup:,
45
+ readonly:,
46
+ aria:,
47
+ id:,
48
+ data:,
17
49
  **kwargs
18
50
  )
19
51
  stimulus_data = {
20
52
  "#{stimulus_controller}_target": "trigger",
21
- input_format_target: "input",
53
+ input_formatter_target: "input",
22
54
  action: "focus->#{stimulus_controller}#open keydown.esc->#{stimulus_controller}#close"
23
55
  }
24
56
 
25
57
  trigger_aria = { haspopup: haspopup, expanded: "false", controls: popover_id }
26
- trigger_aria[:autocomplete] = aria_autocomplete if aria_autocomplete
27
- trigger_aria[:label] = aria_label if aria_label
28
58
 
29
59
  template.tag.input(
30
60
  **merge_html_options(
@@ -35,12 +65,25 @@ module StimulusPlumbers
35
65
  readonly: (readonly ? true : nil),
36
66
  role: "combobox",
37
67
  aria: trigger_aria.deep_merge(aria),
38
- data: merge_data_options(stimulus_data, data)
68
+ data: stimulus_data
39
69
  },
70
+ { data: data },
40
71
  kwargs
41
72
  )
42
73
  )
43
74
  end
75
+
76
+ def render_trigger_group(icon_leading, icon_trailing, &block)
77
+ InputGroup.new(template).render(
78
+ leading: icon_leading ? -> { render_trigger_icon(icon_leading) } : nil,
79
+ trailing: icon_trailing ? -> { render_trigger_icon(icon_trailing) } : nil,
80
+ **theme.resolve(:combobox_trigger_group)
81
+ ) { template.capture(&block) }
82
+ end
83
+
84
+ def render_trigger_icon(name)
85
+ Icon.new(template).render(name: name, aria: { hidden: "true" })
86
+ end
44
87
  end
45
88
  end
46
89
  end
@@ -3,10 +3,10 @@
3
3
  module StimulusPlumbers
4
4
  module Components
5
5
  class Combobox
6
- class Autocomplete < Plumber::Base
6
+ class Typeahead < Plumber::Base
7
7
  def self.default_opts
8
8
  Dropdown.default_opts.deep_merge(
9
- trigger: { aria_autocomplete: "list", readonly: false }
9
+ trigger: { aria: { autocomplete: "list" }, readonly: false }
10
10
  )
11
11
  end
12
12
 
@@ -26,17 +26,19 @@ module StimulusPlumbers
26
26
  template.content_tag(
27
27
  :div,
28
28
  **merge_html_options(
29
- { classes: theme.resolve(:combobox_autocomplete_loading).fetch(:classes, "") },
29
+ { classes: theme.resolve(:combobox_typeahead_loading).fetch(:classes, "") },
30
30
  { hidden: "", aria: { live: "polite" }, data: { "#{Dropdown::STIMULUS_CONTROLLER}_target": "loading" } }
31
31
  )
32
- ) { "" }
32
+ ) do
33
+ Icon.new(template).render(name: "spinner", classes: "size-(--sp-icon-size) animate-spin")
34
+ end
33
35
  end
34
36
 
35
37
  def empty
36
38
  template.content_tag(
37
39
  :div,
38
40
  **merge_html_options(
39
- { classes: theme.resolve(:combobox_autocomplete_empty).fetch(:classes, "") },
41
+ { classes: theme.resolve(:combobox_typeahead_empty).fetch(:classes, "") },
40
42
  { hidden: "", role: "status", data: { "#{Dropdown::STIMULUS_CONTROLLER}_target": "empty" } }
41
43
  )
42
44
  ) { "No results" }
@@ -4,14 +4,20 @@ module StimulusPlumbers
4
4
  module Components
5
5
  class Combobox < Plumber::Base
6
6
  STIMULUS_CONTROLLER = "input-combobox"
7
- FORMAT_CONTROLLER = "input-format"
8
- FORMAT_ACTION = "input-combobox:changed->input-format#format"
7
+ FORMAT_CONTROLLER = "input-formatter"
8
+ FORMAT_ACTION = "input-combobox:changed->input-formatter#format"
9
9
 
10
10
  def self.popover_id_for(trigger_id)
11
11
  [trigger_id, "popover"].compact.join("_")
12
12
  end
13
13
 
14
- def render(trigger: {}, input: {}, popover: {}, **kwargs, &block)
14
+ def render(...)
15
+ render_combobox(...)
16
+ end
17
+
18
+ private
19
+
20
+ def render_combobox(trigger: {}, input: {}, popover: {}, **kwargs, &block)
15
21
  popover_id = self.class.popover_id_for(trigger[:id])
16
22
  initial_value = input[:value]
17
23
  haspopup = popover.delete(:haspopup) { popover[:role] || "dialog" }
@@ -28,8 +34,6 @@ module StimulusPlumbers
28
34
  end
29
35
  end
30
36
 
31
- private
32
-
33
37
  def build_stimulus_data(initial_value)
34
38
  {
35
39
  controller: "#{STIMULUS_CONTROLLER} #{FORMAT_CONTROLLER}",
@@ -59,7 +63,7 @@ module StimulusPlumbers
59
63
 
60
64
  def hidden_input(input)
61
65
  stimulus_data = merge_html_options(
62
- { "#{STIMULUS_CONTROLLER}_target": "value" },
66
+ { "#{STIMULUS_CONTROLLER}_target": "input" },
63
67
  input.fetch(:data, {})
64
68
  )
65
69
  template.tag.input(type: "hidden", name: input[:name], value: input[:value], data: stimulus_data)
@@ -32,7 +32,7 @@ module StimulusPlumbers
32
32
  aria: { label: label },
33
33
  data: { "#{stimulus_controller}-target" => target }
34
34
  }
35
- opts[:icon_options] = { name: icon } if icon
35
+ opts[:icon] = icon if icon
36
36
  Navigator.new(template).render(**opts)
37
37
  end
38
38
  end
@@ -4,26 +4,18 @@ module StimulusPlumbers
4
4
  module Components
5
5
  module DatePicker
6
6
  class Navigator < Plumber::Base
7
- def render(icon_options: nil, **kwargs)
8
- html_options = merge_html_options(
9
- { classes: theme.resolve(:calendar_navigation_navigator).fetch(:classes, "") },
10
- kwargs
11
- )
12
-
13
- if icon_options.nil?
14
- template.content_tag(:button, nil, **html_options)
15
- else
16
- template.content_tag(:button, icon(icon_options), **html_options)
17
- end
7
+ def render(...)
8
+ render_navigator(...)
18
9
  end
19
10
 
20
11
  private
21
12
 
22
- def icon(icon_options)
23
- Icon.new(template).render(
24
- classes: theme.resolve(:calendar_navigation_navigator_icon).fetch(:classes, ""),
25
- **icon_options
13
+ def render_navigator(icon: nil, **kwargs)
14
+ html_options = merge_html_options(
15
+ { classes: theme.resolve(:calendar_navigation_navigator).fetch(:classes, "") },
16
+ kwargs
26
17
  )
18
+ Components::Button.new(template).render(variant: :ghost, size: nil, icon_leading: icon, **html_options)
27
19
  end
28
20
  end
29
21
  end
@@ -3,13 +3,33 @@
3
3
  module StimulusPlumbers
4
4
  module Components
5
5
  class Divider < Plumber::Base
6
- def render(**kwargs)
7
- html_options = merge_html_options(
6
+ def render(label = nil, **kwargs)
7
+ divider_opts = merge_html_options(
8
8
  { classes: theme.resolve(:divider).fetch(:classes, "") },
9
9
  kwargs
10
10
  )
11
+ template.content_tag(:div, role: "separator", **divider_opts) do
12
+ if label.blank?
13
+ hr_classes = theme.resolve(:divider_separator).fetch(:classes, "")
14
+ template.tag.hr(class: hr_classes)
15
+ else
16
+ render_with(label)
17
+ end
18
+ end
19
+ end
20
+
21
+ private
11
22
 
12
- template.tag.hr(**html_options)
23
+ def render_with(label)
24
+ hr_classes = theme.resolve(:divider_separator).fetch(:classes, "")
25
+ label_classes = theme.resolve(:divider_label).fetch(:classes, "")
26
+ template.safe_join(
27
+ [
28
+ template.tag.hr(class: hr_classes),
29
+ template.content_tag(:span, label, class: label_classes),
30
+ template.tag.hr(class: hr_classes)
31
+ ]
32
+ )
13
33
  end
14
34
  end
15
35
  end
@@ -9,7 +9,7 @@ module StimulusPlumbers
9
9
  kwargs
10
10
  )
11
11
 
12
- icon_data = Themes::Schema::Icon.resolve(theme.icons[name])
12
+ icon_data = Themes::Schema::Icon.resolve(theme.icons[name.to_s])
13
13
  if icon_data
14
14
  svg_icon(icon_data, html_options)
15
15
  else
@@ -20,21 +20,11 @@ module StimulusPlumbers
20
20
  private
21
21
 
22
22
  def svg_icon(icon_data, html_options)
23
- template.content_tag(
24
- :svg,
25
- xmlns: "http://www.w3.org/2000/svg",
26
- fill: icon_data[:fill],
27
- viewBox: icon_data[:view_box],
28
- width: icon_data[:width],
29
- height: icon_data[:height],
30
- stroke: icon_data[:stroke],
31
- "stroke-width": icon_data[:stroke_width],
32
- **html_options
33
- ) do
34
- template.tag.path(
35
- "stroke-linecap": icon_data[:stroke_linecap],
36
- "stroke-linejoin": icon_data[:stroke_linejoin],
37
- d: icon_data[:d]
23
+ template.content_tag(:svg, nil, icon_data.except(:elements).merge(html_options)) do
24
+ template.safe_join(
25
+ icon_data[:elements].map do |element|
26
+ template.content_tag(element[:tag], nil, element.except(:tag))
27
+ end
38
28
  )
39
29
  end
40
30
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StimulusPlumbers
4
+ module Components
5
+ class InputGroup < Plumber::Base
6
+ def render(leading: nil, trailing: nil, error: false, **kwargs, &block)
7
+ html_options = merge_html_options(
8
+ theme.resolve(:input_group, error: error),
9
+ kwargs
10
+ )
11
+ template.content_tag(:div, **html_options) do
12
+ build_input_group(leading, trailing, &block)
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def build_input_group(leading, trailing, &block)
19
+ template.safe_join(
20
+ [
21
+ leading.respond_to?(:call) ? template.capture(&leading) : leading,
22
+ template.capture(&block),
23
+ trailing.respond_to?(:call) ? template.capture(&trailing) : trailing
24
+ ]
25
+ )
26
+ end
27
+ end
28
+ end
29
+ end
@@ -3,7 +3,13 @@
3
3
  module StimulusPlumbers
4
4
  module Components
5
5
  class Popover < Plumber::Base
6
- def render(interactive: true, **kwargs, &block)
6
+ def render(...)
7
+ render_popover(...)
8
+ end
9
+
10
+ private
11
+
12
+ def render_popover(interactive: true, **kwargs, &block)
7
13
  html_options = merge_html_options(
8
14
  { classes: theme.resolve(:popover).fetch(:classes, "") },
9
15
  kwargs
@@ -17,8 +23,6 @@ module StimulusPlumbers
17
23
  end
18
24
  end
19
25
 
20
- private
21
-
22
26
  def wrap_content(interactive, builder)
23
27
  if interactive
24
28
  template.content_tag(:template, builder.content_html)
@@ -42,7 +42,7 @@ module StimulusPlumbers
42
42
  end
43
43
 
44
44
  def render_input_group(error:, leading: nil, trailing: nil, **wrapper_opts, &block)
45
- Fields::InputGroup.new(@template).render(leading: leading, trailing: trailing, error: error, **wrapper_opts, &block)
45
+ Components::InputGroup.new(@template).render(leading: leading, trailing: trailing, error: error, **wrapper_opts, &block)
46
46
  end
47
47
 
48
48
  def render_combobox(attribute, input_id:, opts:, err:, **wrapper_opts, &block)
@@ -6,7 +6,9 @@ module StimulusPlumbers
6
6
  module Inputs
7
7
  module Datetime
8
8
  def date_field(attribute, options = {})
9
- html_native = options.delete(:html_native) { false }
9
+ html_native = options.delete(:html_native) { false }
10
+ icon_leading = options.delete(:icon_leading)
11
+ icon_trailing = options.delete(:icon_trailing) { "calendar" }
10
12
  Field.new(@template, **options).render(
11
13
  object,
12
14
  attribute,
@@ -16,15 +18,17 @@ module StimulusPlumbers
16
18
  html_options = merge_html_options(opts, html_opts, field_theme(:form_input, error: error))
17
19
  super(attribute, html_options)
18
20
  else
19
- render_date_combobox(attribute, html_opts, error)
21
+ render_date_combobox(attribute, html_opts, error, icon_leading: icon_leading, icon_trailing: icon_trailing)
20
22
  end
21
23
  end
22
24
  end
23
25
 
24
26
  def time_field(attribute, options = {})
25
- html_native = options.delete(:html_native) { false }
26
- format = options.delete(:format) { :h12 }
27
- step = options.delete(:step) { 1 }
27
+ html_native = options.delete(:html_native) { false }
28
+ format = options.delete(:format) { :h12 }
29
+ step = options.delete(:step) { 1 }
30
+ icon_leading = options.delete(:icon_leading)
31
+ icon_trailing = options.delete(:icon_trailing) { "clock" }
28
32
  Field.new(@template, **options).render(
29
33
  object,
30
34
  attribute,
@@ -34,18 +38,26 @@ module StimulusPlumbers
34
38
  html_options = merge_html_options(opts, html_opts, field_theme(:form_input, error: error))
35
39
  super(attribute, html_options)
36
40
  else
37
- render_time_combobox(attribute, html_opts, error, format: format, step: step)
41
+ render_time_combobox(
42
+ attribute,
43
+ html_opts,
44
+ error,
45
+ format: format,
46
+ step: step,
47
+ icon_leading: icon_leading,
48
+ icon_trailing: icon_trailing
49
+ )
38
50
  end
39
51
  end
40
52
  end
41
53
 
42
54
  private
43
55
 
44
- def render_date_combobox(attribute, html_opts, error)
56
+ def render_date_combobox(attribute, html_opts, error, icon_leading:, icon_trailing:)
45
57
  current_value = object.respond_to?(attribute) ? object.public_send(attribute) : nil
46
58
  opts = Components::Combobox::Date.default_opts.deep_merge(
47
59
  input: { value: current_value, data: { combobox_date_date_value: current_value } },
48
- trigger: { aria: html_opts[:aria] },
60
+ trigger: { aria: html_opts[:aria], icon_leading: icon_leading, icon_trailing: icon_trailing }.compact,
49
61
  popover: { labelledby: Field.label_id(html_opts[:id]) }
50
62
  )
51
63
  render_combobox(
@@ -53,17 +65,17 @@ module StimulusPlumbers
53
65
  input_id: html_opts[:id],
54
66
  opts: opts,
55
67
  err: error,
56
- data: { input_format_type_value: "date" }
68
+ data: { input_formatter_format_value: "date" }
57
69
  ) do |popover_id|
58
70
  Components::Combobox::Date.new(@template).render(value: current_value, popover_id: popover_id)
59
71
  end
60
72
  end
61
73
 
62
- def render_time_combobox(attribute, html_opts, error, format:, step:)
74
+ def render_time_combobox(attribute, html_opts, error, format:, step:, icon_leading:, icon_trailing:)
63
75
  current_value = object.respond_to?(attribute) ? object.public_send(attribute) : nil
64
76
  opts = Components::Combobox::Time.default_opts.deep_merge(
65
77
  input: { value: current_value },
66
- trigger: { aria: html_opts[:aria] },
78
+ trigger: { aria: html_opts[:aria], icon_leading: icon_leading, icon_trailing: icon_trailing }.compact,
67
79
  popover: { labelledby: Field.label_id(html_opts[:id]) }
68
80
  )
69
81
  render_combobox(
@@ -71,7 +83,7 @@ module StimulusPlumbers
71
83
  input_id: html_opts[:id],
72
84
  opts: opts,
73
85
  err: error,
74
- data: { input_format_type_value: "time", input_format_options_value: { format: format }.to_json }
86
+ data: { input_formatter_format_value: "time", input_formatter_options_value: { format: format }.to_json }
75
87
  ) { Components::Combobox::Time.new(@template).render(format: format, step: step, value: current_value) }
76
88
  end
77
89
  end
@@ -29,14 +29,14 @@ module StimulusPlumbers
29
29
  html_options = merge_html_options(
30
30
  html_opts,
31
31
  field_theme(:form_input, error: error),
32
- { data: { input_format_target: "input" } }
32
+ { data: { input_formatter_target: "input" } }
33
33
  )
34
34
  render_input_group(
35
35
  error: error,
36
36
  trailing: method(:reveal_button),
37
37
  **merge_html_options(
38
38
  field_theme(:form_input_reveal, error: error),
39
- { data: { controller: "input-format", input_format_type_value: "password" } }
39
+ { data: { controller: "input-formatter", input_formatter_format_value: "password" } }
40
40
  )
41
41
  ) { @template.capture(html_options, &block) }
42
42
  end
@@ -47,7 +47,7 @@ module StimulusPlumbers
47
47
  {
48
48
  type: "button",
49
49
  aria: { label: "Show password", pressed: "false" },
50
- data: { input_format_target: "toggle", action: "click->input-format#toggle" }
50
+ data: { input_formatter_target: "toggle", action: "click->input-formatter#toggle" }
51
51
  }
52
52
  )
53
53
  @template.content_tag(:button, "", **html_options)