stimulus_plumbers 0.4.0 → 0.4.2

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/README.md +11 -4
  4. data/app/assets/javascripts/stimulus-plumbers/controllers.manifest.json +125 -12
  5. data/app/assets/javascripts/stimulus-plumbers/stimulus-plumbers-controllers.es.js +681 -312
  6. data/app/assets/javascripts/stimulus-plumbers/stimulus-plumbers-controllers.umd.js +1 -1
  7. data/app/assets/stylesheets/stimulus_plumbers/tokens.css +26 -22
  8. data/config/locales/en.yml +21 -0
  9. data/lib/stimulus_plumbers/components/avatar.rb +13 -5
  10. data/lib/stimulus_plumbers/components/calendar/turbo/days_of_month.rb +47 -7
  11. data/lib/stimulus_plumbers/components/calendar/turbo/months_of_year.rb +56 -18
  12. data/lib/stimulus_plumbers/components/calendar/turbo/years_of_decade.rb +44 -16
  13. data/lib/stimulus_plumbers/components/calendar/turbo.rb +59 -12
  14. data/lib/stimulus_plumbers/components/calendar.rb +48 -64
  15. data/lib/stimulus_plumbers/components/card.rb +7 -7
  16. data/lib/stimulus_plumbers/components/combobox/date/navigation.rb +16 -8
  17. data/lib/stimulus_plumbers/components/combobox/date/navigator.rb +3 -1
  18. data/lib/stimulus_plumbers/components/combobox/date.rb +35 -18
  19. data/lib/stimulus_plumbers/components/combobox/time.rb +56 -50
  20. data/lib/stimulus_plumbers/components/input_group.rb +2 -2
  21. data/lib/stimulus_plumbers/components/list/item.rb +2 -2
  22. data/lib/stimulus_plumbers/components/list/section.rb +1 -1
  23. data/lib/stimulus_plumbers/components/popover.rb +1 -1
  24. data/lib/stimulus_plumbers/components/timeline/event/slots.rb +18 -0
  25. data/lib/stimulus_plumbers/components/timeline/event.rb +189 -0
  26. data/lib/stimulus_plumbers/components/timeline/group.rb +42 -0
  27. data/lib/stimulus_plumbers/components/timeline.rb +40 -0
  28. data/lib/stimulus_plumbers/form/builder.rb +11 -3
  29. data/lib/stimulus_plumbers/form/field.rb +4 -5
  30. data/lib/stimulus_plumbers/form/fields/inputs/checkbox.rb +1 -1
  31. data/lib/stimulus_plumbers/form/fields/inputs/combobox.rb +2 -2
  32. data/lib/stimulus_plumbers/form/fields/inputs/datetime.rb +13 -1
  33. data/lib/stimulus_plumbers/form/fields/inputs/file.rb +9 -4
  34. data/lib/stimulus_plumbers/form/fields/inputs/password.rb +35 -24
  35. data/lib/stimulus_plumbers/form/fields/inputs/radio.rb +15 -3
  36. data/lib/stimulus_plumbers/form/fields/inputs/search.rb +62 -31
  37. data/lib/stimulus_plumbers/form/fields/inputs/select.rb +3 -1
  38. data/lib/stimulus_plumbers/form/fields/inputs/submit.rb +4 -4
  39. data/lib/stimulus_plumbers/form/fields/inputs/text.rb +9 -4
  40. data/lib/stimulus_plumbers/form/fields/inputs/text_area.rb +9 -4
  41. data/lib/stimulus_plumbers/form/fields/label/floating.rb +3 -3
  42. data/lib/stimulus_plumbers/helpers/calendar_helper.rb +1 -1
  43. data/lib/stimulus_plumbers/helpers/calendar_turbo_helper.rb +22 -2
  44. data/lib/stimulus_plumbers/helpers/timeline_helper.rb +15 -0
  45. data/lib/stimulus_plumbers/helpers.rb +2 -0
  46. data/lib/stimulus_plumbers/plumber/renderer.rb +2 -2
  47. data/lib/stimulus_plumbers/themes/base.rb +2 -1
  48. data/lib/stimulus_plumbers/themes/schema/form/floating/ranges.rb +15 -0
  49. data/lib/stimulus_plumbers/themes/schema.rb +63 -16
  50. data/lib/stimulus_plumbers/version.rb +1 -1
  51. data/lib/stimulus_plumbers.rb +4 -1
  52. metadata +7 -2
  53. data/lib/stimulus_plumbers/components/combobox/time/drum.rb +0 -43
@@ -8,13 +8,24 @@ module StimulusPlumbers
8
8
  YEARS_PER_ROW = 4
9
9
  DECADE_SIZE = 10
10
10
 
11
- attr_reader :date, :today, :selected_date
11
+ attr_reader :date, :today, :selected_date, :since, :till, :disabled_years
12
12
 
13
- def initialize(template, date: Date.today, today: Date.today, selected_date: nil)
13
+ def initialize(
14
+ template,
15
+ date: Date.today,
16
+ today: Date.today,
17
+ selected_date: nil,
18
+ since: nil,
19
+ till: nil,
20
+ disabled_years: []
21
+ )
14
22
  super(template)
15
- @date = date
16
- @today = today
17
- @selected_date = selected_date
23
+ @date = date
24
+ @today = today
25
+ @selected_date = selected_date
26
+ @since = since
27
+ @till = till
28
+ @disabled_years = disabled_years
18
29
  end
19
30
 
20
31
  def render(...)
@@ -46,36 +57,53 @@ module StimulusPlumbers
46
57
  def year_names
47
58
  decade_start = (date.year / DECADE_SIZE) * DECADE_SIZE
48
59
  ((decade_start - 1)..(decade_start + DECADE_SIZE)).map do |y|
49
- [y, y < decade_start || y > decade_start + DECADE_SIZE - 1]
60
+ [y, year_disabled?(y, decade_start)]
50
61
  end
51
62
  end
52
63
 
53
64
  def years_in_row(years)
54
- template.safe_join(years.map { |year, outside| year_cell(year, outside) })
65
+ template.safe_join(years.map { |year, disabled| year_cell(year, disabled) })
55
66
  end
56
67
 
57
- def year_cell(year, outside)
58
- template.content_tag(:button, year.to_s, **year_cell_html_options(year, outside))
68
+ def year_cell(year, disabled)
69
+ template.content_tag(:button, year.to_s, **year_cell_html_options(year, disabled))
59
70
  end
60
71
 
61
- def year_cell_html_options(year, outside)
62
- is_current_year = year == today.year
63
- is_focused = selected_date_in_year?(year) || (is_current_year && !selected_date)
72
+ def year_cell_html_options(year, disabled)
64
73
  merge_html_options(
65
- theme.resolve(:calendar_year, outside: outside),
74
+ theme.resolve(:calendar_year),
66
75
  {
67
76
  role: "gridcell",
68
- tabindex: is_focused ? 0 : -1,
77
+ tabindex: focused_year?(year, disabled) ? 0 : -1,
69
78
  data: { year: year },
70
79
  aria: {
71
- current: is_current_year ? "year" : nil,
80
+ current: current_year?(year) ? "year" : nil,
72
81
  selected: selected_date_in_year?(year) ? "true" : "false",
73
- disabled: outside ? "true" : nil
82
+ disabled: disabled ? "true" : nil
74
83
  }
75
84
  }
76
85
  )
77
86
  end
78
87
 
88
+ def year_disabled?(year, decade_start)
89
+ outside_decade?(year, decade_start) ||
90
+ (since && year < since.year) ||
91
+ (till && year > till.year) ||
92
+ disabled_years.any? { |v| v.to_s == year.to_s }
93
+ end
94
+
95
+ def outside_decade?(year, decade_start)
96
+ year < decade_start || year > (decade_start + DECADE_SIZE - 1)
97
+ end
98
+
99
+ def current_year?(year)
100
+ year == today.year
101
+ end
102
+
103
+ def focused_year?(year, disabled)
104
+ !disabled && (selected_date_in_year?(year) || (current_year?(year) && !selected_date))
105
+ end
106
+
79
107
  def selected_date_in_year?(year)
80
108
  selected_date && year == selected_date.year
81
109
  end
@@ -4,22 +4,25 @@ module StimulusPlumbers
4
4
  module Components
5
5
  class Calendar
6
6
  class Turbo < Plumber::Base
7
- STIMULUS_CONTROLLER = "calendar-observer"
8
- STIMULUS_ACTION = "click->#{STIMULUS_CONTROLLER}#onSelect".freeze
7
+ MONTH_SELECTOR_CONTROLLER = "calendar-month-selector"
8
+ YEAR_SELECTOR_CONTROLLER = "calendar-year-selector"
9
+ DECADE_SELECTOR_CONTROLLER = "calendar-decade-selector"
9
10
 
10
11
  def month(
11
12
  date: Date.today,
12
13
  today: Date.today,
13
14
  show_other_months: false,
14
15
  weekday_format: :short,
16
+ selectable: false,
17
+ selected_date: nil,
18
+ since: nil,
19
+ till: nil,
15
20
  **kwargs
16
21
  )
17
- selectable = kwargs.delete(:selectable) { false }
18
- selected_date = kwargs.delete(:selected_date) { nil }
19
22
  html_options = merge_html_options(
20
23
  theme.resolve(:calendar),
21
24
  kwargs,
22
- { data: { controller: STIMULUS_CONTROLLER, action: STIMULUS_ACTION } }
25
+ { data: { controller: MONTH_SELECTOR_CONTROLLER } }
23
26
  )
24
27
  template.content_tag(:div, role: "grid", **html_options) do
25
28
  template.safe_join(
@@ -31,32 +34,76 @@ module StimulusPlumbers
31
34
  today: today,
32
35
  selectable: selectable,
33
36
  selected_date: selected_date,
34
- show_other_months: show_other_months
37
+ show_other_months: show_other_months,
38
+ since: since,
39
+ till: till
35
40
  ).render
36
41
  ]
37
42
  )
38
43
  end
39
44
  end
40
45
 
41
- def year(date: Date.today, today: Date.today, selected_date: nil, month_format: :short, **kwargs)
46
+ def year(
47
+ date: Date.today,
48
+ today: Date.today,
49
+ selected_date: nil,
50
+ month_format: :short,
51
+ since: nil,
52
+ till: nil,
53
+ disabled_months: [],
54
+ **kwargs
55
+ )
42
56
  html_options = merge_html_options(
43
57
  theme.resolve(:calendar_quarter_grid),
44
58
  kwargs,
45
- { role: "grid", aria: { label: "Year view" } }
59
+ {
60
+ role: "grid",
61
+ aria: { label: I18n.t("stimulus_plumbers.calendar.year_view") },
62
+ data: { controller: YEAR_SELECTOR_CONTROLLER }
63
+ }
46
64
  )
47
65
  template.content_tag(:div, **html_options) do
48
- Turbo::MonthsOfYear.new(template, date: date, today: today, selected_date: selected_date, format: month_format).render
66
+ Turbo::MonthsOfYear.new(
67
+ template,
68
+ date: date,
69
+ today: today,
70
+ selected_date: selected_date,
71
+ format: month_format,
72
+ since: since,
73
+ till: till,
74
+ disabled_months: disabled_months
75
+ ).render
49
76
  end
50
77
  end
51
78
 
52
- def decade(date: Date.today, today: Date.today, selected_date: nil, **kwargs)
79
+ def decade(
80
+ date: Date.today,
81
+ today: Date.today,
82
+ selected_date: nil,
83
+ since: nil,
84
+ till: nil,
85
+ disabled_years: [],
86
+ **kwargs
87
+ )
53
88
  html_options = merge_html_options(
54
89
  theme.resolve(:calendar_quarter_grid),
55
90
  kwargs,
56
- { role: "grid", aria: { label: "Decade view" } }
91
+ {
92
+ role: "grid",
93
+ aria: { label: I18n.t("stimulus_plumbers.calendar.decade_view") },
94
+ data: { controller: DECADE_SELECTOR_CONTROLLER }
95
+ }
57
96
  )
58
97
  template.content_tag(:div, **html_options) do
59
- Turbo::YearsOfDecade.new(template, date: date, today: today, selected_date: selected_date).render
98
+ Turbo::YearsOfDecade.new(
99
+ template,
100
+ date: date,
101
+ today: today,
102
+ selected_date: selected_date,
103
+ since: since,
104
+ till: till,
105
+ disabled_years: disabled_years
106
+ ).render
60
107
  end
61
108
  end
62
109
  end
@@ -6,93 +6,77 @@ module StimulusPlumbers
6
6
  MONTH_STIMULUS_CONTROLLER = "calendar-month"
7
7
  YEAR_STIMULUS_CONTROLLER = "calendar-year"
8
8
  DECADE_STIMULUS_CONTROLLER = "calendar-decade"
9
- OBSERVER_STIMULUS_CONTROLLER = "calendar-observer"
10
- STIMULUS_ACTION = "click->#{OBSERVER_STIMULUS_CONTROLLER}#onSelect".freeze
11
9
 
12
- def render(**kwargs)
10
+ def month(**kwargs)
13
11
  html_options = merge_html_options(
14
12
  theme.resolve(:calendar),
15
13
  kwargs,
16
- {
17
- data: {
18
- controller: "#{MONTH_STIMULUS_CONTROLLER} #{OBSERVER_STIMULUS_CONTROLLER}",
19
- action: STIMULUS_ACTION
20
- }
21
- }
14
+ { data: { controller: MONTH_STIMULUS_CONTROLLER } },
15
+ { data: stimulus_theme_options }
22
16
  )
23
17
  template.content_tag(:div, **html_options, role: "grid") do
24
- template.safe_join([month, year, decade])
18
+ template.safe_join([days_of_week, days_of_month])
25
19
  end
26
20
  end
27
21
 
28
- def month
29
- template.content_tag(:div, **month_options) do
30
- template.safe_join(
31
- [
32
- template.tag.div(**dow_options),
33
- template.tag.div(**dom_options)
34
- ]
35
- )
22
+ def year(**kwargs)
23
+ html_options = merge_html_options(
24
+ {
25
+ hidden: true,
26
+ role: "grid",
27
+ aria: { label: I18n.t("stimulus_plumbers.calendar.year_view") },
28
+ data: { controller: YEAR_STIMULUS_CONTROLLER }
29
+ },
30
+ kwargs
31
+ )
32
+ template.content_tag(:div, **html_options) do
33
+ template.tag.div(data: { "#{YEAR_STIMULUS_CONTROLLER}-target": "grid" }, role: "rowgroup")
36
34
  end
37
35
  end
38
36
 
39
- def year
40
- template.tag.div(**year_options)
41
- end
42
-
43
- def decade
44
- template.tag.div(**decade_options)
45
- end
46
-
47
- private
48
-
49
- def month_options
50
- merge_html_options(
37
+ def decade(**kwargs)
38
+ html_options = merge_html_options(
51
39
  {
52
- data: {
53
- "#{MONTH_STIMULUS_CONTROLLER}-row-class": theme.resolve(:calendar_row).fetch(:classes, ""),
54
- "#{MONTH_STIMULUS_CONTROLLER}-day-of-month-class": theme.resolve(:calendar_day).fetch(:classes, "")
55
- }
56
- }
40
+ hidden: true,
41
+ role: "grid",
42
+ aria: { label: I18n.t("stimulus_plumbers.calendar.decade_view") },
43
+ data: { controller: DECADE_STIMULUS_CONTROLLER }
44
+ },
45
+ kwargs
57
46
  )
47
+ template.content_tag(:div, **html_options) do
48
+ template.tag.div(data: { "#{DECADE_STIMULUS_CONTROLLER}-target": "grid" }, role: "rowgroup")
49
+ end
58
50
  end
59
51
 
60
- def dow_options
61
- merge_html_options(
62
- theme.resolve(:calendar_days_of_week),
63
- { data: { "#{MONTH_STIMULUS_CONTROLLER}-target": "daysOfWeek" } }
64
- )
65
- end
52
+ private
66
53
 
67
- def dom_options
68
- merge_html_options(
69
- theme.resolve(:calendar_days_of_month),
70
- {
71
- role: "rowgroup",
72
- data: { "#{MONTH_STIMULUS_CONTROLLER}-target": "daysOfMonth" }
73
- }
74
- )
54
+ def stimulus_theme_options
55
+ {
56
+ "#{MONTH_STIMULUS_CONTROLLER}-row-class": theme.resolve(:calendar_row).fetch(:classes, ""),
57
+ "#{MONTH_STIMULUS_CONTROLLER}-day-of-month-class": theme.resolve(:calendar_day).fetch(:classes, ""),
58
+ "#{MONTH_STIMULUS_CONTROLLER}-day-of-other-month-class": theme.resolve(:calendar_day, outside: true).fetch(:classes, "")
59
+ }
75
60
  end
76
61
 
77
- def year_options
78
- merge_html_options(
79
- { hidden: true, data: { controller: YEAR_STIMULUS_CONTROLLER } },
80
- {
81
- data: {
82
- "#{YEAR_STIMULUS_CONTROLLER}-month-class": theme.resolve(:calendar_month).fetch(:classes, "")
83
- }
84
- }
62
+ def days_of_week
63
+ template.tag.div(
64
+ **merge_html_options(
65
+ theme.resolve(:calendar_days_of_week),
66
+ { data: { "#{MONTH_STIMULUS_CONTROLLER}-target": "daysOfWeek" } }
67
+ )
85
68
  )
86
69
  end
87
70
 
88
- def decade_options
89
- merge_html_options(
90
- { hidden: true, data: { controller: DECADE_STIMULUS_CONTROLLER } },
91
- {
92
- data: {
93
- "#{DECADE_STIMULUS_CONTROLLER}-year-class": theme.resolve(:calendar_year).fetch(:classes, "")
71
+ def days_of_month
72
+ template.tag.div(
73
+ **merge_html_options(
74
+ theme.resolve(:calendar_days_of_month),
75
+ {
76
+ role: "rowgroup",
77
+ data: { "#{MONTH_STIMULUS_CONTROLLER}-target": "daysOfMonth" }
94
78
  }
95
- }
79
+ )
96
80
  )
97
81
  end
98
82
  end
@@ -14,7 +14,7 @@ module StimulusPlumbers
14
14
  render_header(slots, title_tag),
15
15
  render_body(slots),
16
16
  render_action(slots)
17
- ].compact
17
+ ]
18
18
  )
19
19
  end
20
20
  end
@@ -31,7 +31,7 @@ module StimulusPlumbers
31
31
  [
32
32
  icon,
33
33
  (template.content_tag(title_tag, title, **merge_html_options(theme.resolve(:card_title))) if title)
34
- ].compact
34
+ ]
35
35
  )
36
36
  end
37
37
  end
@@ -60,11 +60,11 @@ module StimulusPlumbers
60
60
  return unless content
61
61
 
62
62
  url = slots.options_for(:action)[:url]
63
- template.content_tag(:div, **merge_html_options(theme.resolve(:card_action))) do
64
- if url.present?
65
- template.content_tag(:a, href: url) { content }
66
- else
67
- template.content_tag(:button, type: "button") { content }
63
+ Components::Button.new(template).build(type: :ghost, variant: :tertiary) do |attrs|
64
+ element = url.present? ? :a : :button
65
+ extra = url.present? ? { href: url } : { type: "button" }
66
+ template.content_tag(element, **merge_html_options(attrs, extra, theme.resolve(:card_action))) do
67
+ template.content_tag(:span, content)
68
68
  end
69
69
  end
70
70
  end
@@ -9,7 +9,7 @@ module StimulusPlumbers
9
9
  html_options = merge_html_options(
10
10
  theme.resolve(:combobox_date_navigation),
11
11
  kwargs,
12
- { aria: { label: "Date picker navigation" } }
12
+ { aria: { label: t("navigation_label") } }
13
13
  )
14
14
 
15
15
  template.content_tag(:nav, **html_options) do
@@ -22,7 +22,7 @@ module StimulusPlumbers
22
22
  def navigators(stimulus_controller, step, view, date)
23
23
  [
24
24
  navigator(stimulus_controller, target: "previous", icon: "arrow-left", label: prev_label(step)),
25
- view_title_navigator(stimulus_controller, view, date),
25
+ view(stimulus_controller, view, date),
26
26
  navigator(stimulus_controller, target: "next", icon: "arrow-right", label: next_label(step))
27
27
  ]
28
28
  end
@@ -36,16 +36,20 @@ module StimulusPlumbers
36
36
  Navigator.new(template).render(**opts)
37
37
  end
38
38
 
39
- def view_title_navigator(stimulus_controller, view, date)
40
- Navigator.new(template).render(
39
+ def view(stimulus_controller, view, date)
40
+ html_options = merge_html_options(
41
+ theme.resolve(:combobox_date_navigation_title),
41
42
  data: {
42
43
  "#{stimulus_controller}-target" => "viewTitle",
43
44
  action: "click->#{stimulus_controller}#zoomOut"
44
45
  }
45
- ) { view_title_label(view, date) }
46
+ )
47
+ Components::Button.new(template).render(
48
+ type: :ghost, variant: :tertiary, size: :sm, **html_options
49
+ ) { view_label(view, date) }
46
50
  end
47
51
 
48
- def view_title_label(view, date)
52
+ def view_label(view, date)
49
53
  case view
50
54
  when "year" then date.year.to_s
51
55
  when "decade" then decade_label(date)
@@ -59,11 +63,15 @@ module StimulusPlumbers
59
63
  end
60
64
 
61
65
  def prev_label(step)
62
- "Previous #{step.to_s.titleize}"
66
+ t("previous_#{step}")
63
67
  end
64
68
 
65
69
  def next_label(step)
66
- "Next #{step.to_s.titleize}"
70
+ t("next_#{step}")
71
+ end
72
+
73
+ def t(key)
74
+ I18n.t("stimulus_plumbers.combobox.date.#{key}")
67
75
  end
68
76
  end
69
77
  end
@@ -16,7 +16,9 @@ module StimulusPlumbers
16
16
  theme.resolve(:combobox_date_navigation_navigator),
17
17
  kwargs
18
18
  )
19
- Components::Button.new(template).render(variant: :ghost, size: nil, icon_leading: icon, **html_options, &block)
19
+ Components::Button.new(template).render(
20
+ type: :ghost, variant: :tertiary, size: :sm, icon_leading: icon, **html_options, &block
21
+ )
20
22
  end
21
23
  end
22
24
  end
@@ -4,17 +4,21 @@ module StimulusPlumbers
4
4
  module Components
5
5
  class Combobox
6
6
  class Date < Plumber::Base
7
- STIMULUS_CONTROLLER = "combobox-date"
8
- CALENDAR_OUTLET = "#{STIMULUS_CONTROLLER}-calendar-month-outlet".freeze
9
- STIMULUS_ACTION = [
10
- "calendar-observer:selected->#{STIMULUS_CONTROLLER}#onSelect",
7
+ STIMULUS_CONTROLLER = "combobox-date"
8
+ CALENDAR_MONTH_OUTLET = "#{STIMULUS_CONTROLLER}-calendar-month-outlet".freeze
9
+ CALENDAR_YEAR_OUTLET = "#{STIMULUS_CONTROLLER}-calendar-year-outlet".freeze
10
+ CALENDAR_DECADE_OUTLET = "#{STIMULUS_CONTROLLER}-calendar-decade-outlet".freeze
11
+ STIMULUS_ACTION = [
12
+ "calendar-month:selected->#{STIMULUS_CONTROLLER}#onDaySelect",
13
+ "calendar-year:selected->#{STIMULUS_CONTROLLER}#onMonthSelect",
14
+ "calendar-decade:selected->#{STIMULUS_CONTROLLER}#onYearSelect",
11
15
  "#{STIMULUS_CONTROLLER}:selected->#{Combobox::STIMULUS_CONTROLLER}#onSelect",
12
16
  "#{STIMULUS_CONTROLLER}:selected->#{Components::Popover::STIMULUS_CONTROLLER}#closeOnSelect"
13
17
  ].join(" ").freeze
14
18
 
15
- def self.calendar_id_for(panel_id)
16
- [panel_id, "calendar"].compact.join("_")
17
- end
19
+ def self.month_id_for(panel_id) = [panel_id, "calendar_month"].compact.join("_")
20
+ def self.year_id_for(panel_id) = [panel_id, "calendar_year"].compact.join("_")
21
+ def self.decade_id_for(panel_id) = [panel_id, "calendar_decade"].compact.join("_")
18
22
 
19
23
  module Metadata
20
24
  module_function
@@ -30,26 +34,32 @@ module StimulusPlumbers
30
34
 
31
35
  private
32
36
 
33
- def render_date(panel_attrs: {}, value: nil, label: "Picker", labelledby: nil)
34
- calendar_id = self.class.calendar_id_for(panel_attrs[:id])
37
+ def render_date(panel_attrs: {}, value: nil, label: nil, labelledby: nil)
38
+ panel_id = panel_attrs[:id]
39
+ month_id = self.class.month_id_for(panel_id)
40
+ year_id = self.class.year_id_for(panel_id)
41
+ decade_id = self.class.decade_id_for(panel_id)
35
42
 
36
43
  template.content_tag(
37
44
  :div,
38
- **merge_html_options(panel_attrs, dialog_attrs(value, calendar_id, label, labelledby))
45
+ **merge_html_options(panel_attrs, dialog_attrs(value, month_id, year_id, decade_id, label, labelledby))
39
46
  ) do
40
- template.safe_join([navigation, calendar(id: calendar_id)])
47
+ template.safe_join([navigation, calendar(month_id: month_id, year_id: year_id, decade_id: decade_id)])
41
48
  end
42
49
  end
43
50
 
44
- def dialog_attrs(value, calendar_id, label, labelledby)
51
+ def dialog_attrs(value, month_id, year_id, decade_id, label, labelledby)
45
52
  data = {
46
- controller: STIMULUS_CONTROLLER,
47
- CALENDAR_OUTLET => "##{calendar_id}",
48
- action: STIMULUS_ACTION,
53
+ controller: STIMULUS_CONTROLLER,
54
+ CALENDAR_MONTH_OUTLET => "##{month_id}",
55
+ CALENDAR_YEAR_OUTLET => "##{year_id}",
56
+ CALENDAR_DECADE_OUTLET => "##{decade_id}",
57
+ action: STIMULUS_ACTION,
49
58
  "#{STIMULUS_CONTROLLER}-date-value" => value
50
59
  }.compact
51
60
 
52
- { role: "dialog", aria: labelled_aria(label, labelledby: labelledby), data: data }
61
+ resolved_label = label || I18n.t("stimulus_plumbers.combobox.date.dialog_label")
62
+ { role: "dialog", aria: labelled_aria(resolved_label, labelledby: labelledby), data: data }
53
63
  end
54
64
 
55
65
  def navigation
@@ -59,8 +69,15 @@ module StimulusPlumbers
59
69
  )
60
70
  end
61
71
 
62
- def calendar(**kwargs)
63
- Calendar.new(template).render(**kwargs)
72
+ def calendar(month_id:, year_id:, decade_id:)
73
+ cal = Calendar.new(template)
74
+ template.safe_join(
75
+ [
76
+ cal.month(id: month_id),
77
+ cal.year(id: year_id),
78
+ cal.decade(id: decade_id)
79
+ ]
80
+ )
64
81
  end
65
82
  end
66
83
  end