Module: MaquinaComponents::CalendarHelper

Defined in:
app/helpers/maquina_components/calendar_helper.rb

Overview

Calendar Helper

Provides utility methods for working with calendar and date picker data.

Examples:

Generate month data

calendar_month_data(Date.current, :sunday)

Check if date is in range

calendar_date_in_range?(date, start_date, end_date)

Instance Method Summary collapse

Instance Method Details

#calendar_data_attrs(mode: :single, selected: nil, selected_end: nil, month: nil, year: nil) ⇒ Hash

Generate data attributes hash for calendar

Parameters:

  • mode (Symbol) (defaults to: :single)

    :single or :range

  • selected (Date, String, nil) (defaults to: nil)

    Selected date

  • selected_end (Date, String, nil) (defaults to: nil)

    End date for range

  • month (Integer, nil) (defaults to: nil)

    Display month

  • year (Integer, nil) (defaults to: nil)

    Display year

Returns:

  • (Hash)

    Data attributes for use with content_tag



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'app/helpers/maquina_components/calendar_helper.rb', line 81

def calendar_data_attrs(mode: :single, selected: nil, selected_end: nil, month: nil, year: nil)
  selected_str = case selected
  when Date, Time, DateTime then selected.to_date.iso8601
  when String then selected
  end

  selected_end_str = case selected_end
  when Date, Time, DateTime then selected_end.to_date.iso8601
  when String then selected_end
  end

  display_date = selected_str ? Date.parse(selected_str) : Date.current
  display_month = month || display_date.month
  display_year = year || display_date.year

  {
    data: {
      controller: "calendar",
      component: "calendar",
      "calendar-mode-value": mode,
      "calendar-month-value": display_month,
      "calendar-year-value": display_year,
      "calendar-selected-value": selected_str,
      "calendar-selected-end-value": selected_end_str
    }.compact
  }
end

#calendar_date_in_range?(date, start_date, end_date) ⇒ Boolean

Check if a date falls within a range

Parameters:

  • date (Date)

    The date to check

  • start_date (Date, nil)

    Range start (inclusive)

  • end_date (Date, nil)

    Range end (inclusive)

Returns:

  • (Boolean)


68
69
70
71
# File 'app/helpers/maquina_components/calendar_helper.rb', line 68

def calendar_date_in_range?(date, start_date, end_date)
  return false unless start_date && end_date
  date.between?(start_date, end_date)
end

#calendar_month_data(date, week_starts_on = :sunday) ⇒ Hash

Generate calendar month data

Parameters:

  • date (Date)

    Any date within the target month

  • week_starts_on (Symbol) (defaults to: :sunday)

    :sunday or :monday

Returns:

  • (Hash)

    Month metadata and weeks array



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'app/helpers/maquina_components/calendar_helper.rb', line 20

def calendar_month_data(date, week_starts_on = :sunday)
  first_of_month = date.beginning_of_month
  last_of_month = date.end_of_month

  # Calculate start of calendar grid
  week_start = (week_starts_on == :monday) ? 1 : 0
  days_before = (first_of_month.wday - week_start) % 7
  calendar_start = first_of_month - days_before.days

  # Calculate end of calendar grid (6 weeks max)
  total_days = days_before + last_of_month.day
  weeks_needed = (total_days / 7.0).ceil
  weeks_needed = [weeks_needed, 6].min
  calendar_end = calendar_start + (weeks_needed * 7 - 1).days

  # Build weeks array
  weeks = (calendar_start..calendar_end).each_slice(7).to_a

  {
    month: date.month,
    year: date.year,
    first_of_month: first_of_month,
    last_of_month: last_of_month,
    weeks: weeks,
    week_starts_on: week_starts_on
  }
end

#calendar_month_name(date, format = :long) ⇒ String

Format month name with year

Parameters:

  • date (Date)

    Any date within the target month

  • format (Symbol) (defaults to: :long)

    :long (%B %Y) or :short (%b %Y)

Returns:

  • (String)

    Formatted month name



53
54
55
56
57
58
59
60
# File 'app/helpers/maquina_components/calendar_helper.rb', line 53

def calendar_month_name(date, format = :long)
  case format
  when :short
    I18n.l(date, format: "%b %Y")
  else
    I18n.l(date, format: "%B %Y")
  end
end

#calendar_weekday_names(week_starts_on = :sunday, format = :short) ⇒ Array<String>

Get weekday names based on week start

Parameters:

  • week_starts_on (Symbol) (defaults to: :sunday)

    :sunday or :monday

  • format (Symbol) (defaults to: :short)

    :short (Mo, Tu) or :narrow (M, T) or :long (Monday)

Returns:

  • (Array<String>)


114
115
116
117
118
119
120
121
122
123
124
125
# File 'app/helpers/maquina_components/calendar_helper.rb', line 114

def calendar_weekday_names(week_starts_on = :sunday, format = :short)
  names = case format
  when :narrow
    %w[S M T W T F S]
  when :long
    I18n.t("date.day_names")
  else
    %w[Su Mo Tu We Th Fr Sa]
  end

  (week_starts_on == :monday) ? names.rotate(1) : names
end

#date_picker_data_attrs(mode: :single, selected: nil, selected_end: nil) ⇒ Hash

Generate data attributes hash for date picker

Parameters:

  • mode (Symbol) (defaults to: :single)

    :single or :range

  • selected (Date, String, nil) (defaults to: nil)

    Selected date

  • selected_end (Date, String, nil) (defaults to: nil)

    End date for range

Returns:

  • (Hash)

    Data attributes for use with content_tag



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'app/helpers/maquina_components/calendar_helper.rb', line 133

def date_picker_data_attrs(mode: :single, selected: nil, selected_end: nil)
  selected_str = case selected
  when Date, Time, DateTime then selected.to_date.iso8601
  when String then selected
  end

  selected_end_str = case selected_end
  when Date, Time, DateTime then selected_end.to_date.iso8601
  when String then selected_end
  end

  {
    data: {
      controller: "date-picker",
      component: "date-picker",
      "date-picker-mode-value": mode,
      "date-picker-selected-value": selected_str,
      "date-picker-selected-end-value": selected_end_str
    }.compact
  }
end

#date_picker_format(date, format = :long) ⇒ String?

Format date for display in date picker

Parameters:

  • date (Date, String, nil)

    Date to format

  • format (Symbol) (defaults to: :long)

    :short, :long, or :full

Returns:

  • (String, nil)


160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'app/helpers/maquina_components/calendar_helper.rb', line 160

def date_picker_format(date, format = :long)
  return nil unless date

  date = Date.parse(date) if date.is_a?(String)

  case format
  when :short
    I18n.l(date, format: :short)
  when :full
    I18n.l(date, format: :long)
  else
    I18n.l(date, format: :long)
  end
rescue ArgumentError
  nil
end

#date_picker_format_range(start_date, end_date, format = :short) ⇒ String?

Format date range for display

Parameters:

  • start_date (Date, String, nil)

    Start date

  • end_date (Date, String, nil)

    End date

  • format (Symbol) (defaults to: :short)

    :short or :long

Returns:

  • (String, nil)


183
184
185
186
187
188
189
190
191
192
193
194
# File 'app/helpers/maquina_components/calendar_helper.rb', line 183

def date_picker_format_range(start_date, end_date, format = :short)
  start_str = date_picker_format(start_date, format)
  end_str = date_picker_format(end_date, format)

  return nil unless start_str

  if end_str
    "#{start_str} - #{end_str}"
  else
    "#{start_str} - ..."
  end
end