Class: Shadcn::Calendar::Month

Inherits:
Object
  • Object
show all
Defined in:
app/components/shadcn/calendar/month.rb

Overview

One month, as a grid of weeks.

This is the part react-day-picker mostly ishelpers/getDates.js, helpers/getWeeks.js and the 576 lines of classes/DateLib.js that wrap date-fns — and it is the part Ruby already has. Date does the arithmetic and I18n does the names, so nothing here needs a dependency.

A plain object rather than a component: it renders nothing, and being able to assert on a grid without a browser is worth more than the symmetry.

Constant Summary collapse

DAYS_IN_WEEK =
7

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(date = Date.current, week_starts_on: nil, fixed_weeks: false) ⇒ Month

week_starts_on is a weekday number, 0 for Sunday, matching Date#wday — and defaulting to the host application's own Date.beginning_of_week rather than to a constant, because that is the setting a Rails app has already made. Upstream takes it from the locale.



24
25
26
27
28
# File 'app/components/shadcn/calendar/month.rb', line 24

def initialize(date = Date.current, week_starts_on: nil, fixed_weeks: false)
  @date = date.to_date
  @week_starts_on = week_starts_on || Date::DAYNAMES.index(Date.beginning_of_week.to_s.capitalize)
  @fixed_weeks = fixed_weeks
end

Instance Attribute Details

#dateObject (readonly)

Returns the value of attribute date.



18
19
20
# File 'app/components/shadcn/calendar/month.rb', line 18

def date
  @date
end

#fixed_weeksObject (readonly)

Returns the value of attribute fixed_weeks.



18
19
20
# File 'app/components/shadcn/calendar/month.rb', line 18

def fixed_weeks
  @fixed_weeks
end

#week_starts_onObject (readonly)

Returns the value of attribute week_starts_on.



18
19
20
# File 'app/components/shadcn/calendar/month.rb', line 18

def week_starts_on
  @week_starts_on
end

Instance Method Details

#daysObject



46
# File 'app/components/shadcn/calendar/month.rb', line 46

def days = weeks.flatten

#firstObject



30
# File 'app/components/shadcn/calendar/month.rb', line 30

def first = date.beginning_of_month

#lastObject



31
# File 'app/components/shadcn/calendar/month.rb', line 31

def last = date.end_of_month

#nextObject



56
# File 'app/components/shadcn/calendar/month.rb', line 56

def next = self.class.new(first.next_month, **options)

#number_of(week) ⇒ Object

ISO-8601, which is Date#cweek. Upstream's week number follows the locale and can differ — the US counts from a different week — and this port does not reproduce that; see features/calendar.md.



53
# File 'app/components/shadcn/calendar/month.rb', line 53

def number_of(week) = week.first.cweek

#outside?(day) ⇒ Boolean

Returns:

  • (Boolean)


48
# File 'app/components/shadcn/calendar/month.rb', line 48

def outside?(day) = day.month != date.month

#plus_months(count) ⇒ Object



57
# File 'app/components/shadcn/calendar/month.rb', line 57

def plus_months(count) = self.class.new(first + count.months, **options)

#previousObject



55
# File 'app/components/shadcn/calendar/month.rb', line 55

def previous = self.class.new(first.prev_month, **options)

#weekday_numbersObject

Sunday-first Date::DAYNAMES, rotated to whichever day the week starts on. The names themselves come from I18n at render time, not from here.



61
62
63
# File 'app/components/shadcn/calendar/month.rb', line 61

def weekday_numbers
  Array.new(DAYS_IN_WEEK) { |offset| (week_starts_on + offset) % DAYS_IN_WEEK }
end

#weeksObject

Every date the grid holds, including the days either side that fill the first and last weeks out. Six rows when fixed_weeks is asked for, so a calendar that is navigated does not change height under the pointer — upstream's fixedWeeks, and the reason it exists.



37
38
39
40
41
42
43
44
# File 'app/components/shadcn/calendar/month.rb', line 37

def weeks
  start = shift_back(first)
  rows = fixed_weeks ? 6 : ((shift_forward(last) - start + 1) / DAYS_IN_WEEK)

  Array.new(rows) do |row|
    Array.new(DAYS_IN_WEEK) { |column| start + (row * DAYS_IN_WEEK) + column }
  end
end