Class: PhlexKit::DatePicker

Inherits:
BaseComponent show all
Defined in:
app/components/phlex_kit/date_picker/date_picker.rb

Overview

Date picker, ported from ruby_ui's RubyUI::DatePicker: a labelled PhlexKit::Input inside a PhlexKit::Popover whose panel holds a PhlexKit::Calendar. The input carries the phlex-kit--calendar-input controller and the calendar's outlet points at its id, so picking a day writes the formatted date into the field. Upstream's popover_options (hover trigger via @floating-ui) are gone — the kit popover is click-only, CSS-positioned. The phlex-kit--date-picker controller on the root div listens for the calendar's change event and closes the popover once a selection is COMPLETE (single: any pick; range: the second end only; multiple: never), returning focus to the input — see date_picker_controller.js and popover_controller.js#close. Tailwind → vanilla .pk-date-picker* (date_picker.css).

Instance Method Summary collapse

Methods inherited from BaseComponent

#on

Constructor Details

#initialize(id: nil, name: nil, label: "Select a date", value: nil, placeholder: "Select a date", selected_date: value, date_format: "yyyy-MM-dd", input_attrs: {}, calendar_attrs: {}, trigger_attrs: {}, content_attrs: {}, **attrs) ⇒ DatePicker

Returns a new instance of DatePicker.



15
16
17
18
19
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
47
48
49
50
# File 'app/components/phlex_kit/date_picker/date_picker.rb', line 15

def initialize(
  id: nil,
  name: nil,
  label: "Select a date",
  value: nil,
  placeholder: "Select a date",
  selected_date: value,
  date_format: "yyyy-MM-dd",
  input_attrs: {},
  calendar_attrs: {},
  trigger_attrs: {},
  content_attrs: {},
  **attrs
)
  @id = id || "date-picker-#{SecureRandom.hex(4)}"
  @name = name
  @label = label
  @selected_date = selected_date
  @date_format = date_format
  # Seed the input with the same date_format the calendar controller
  # writes — a bare `selected_date.to_s` (ISO) would mismatch the format
  # until the first interaction.
  @value = value || format_selected_date
  @placeholder = placeholder
  # An id smuggled through input_attrs would MERGE with the generated one
  # (mix fuses duplicate string attrs), breaking label[for] and the
  # calendar outlet selector — the top-level id: kwarg is the one path.
  if input_attrs.key?(:id) || input_attrs.key?("id")
    raise ArgumentError, "DatePicker: pass id: as the top-level kwarg, not input_attrs[:id]"
  end
  @input_attrs = input_attrs
  @calendar_attrs = calendar_attrs
  @trigger_attrs = trigger_attrs
  @content_attrs = content_attrs
  @attrs = attrs
end

Instance Method Details

#view_templateObject



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'app/components/phlex_kit/date_picker/date_picker.rb', line 52

def view_template
  div(**mix({
    class: "pk-date-picker",
    data: {
      controller: "phlex-kit--date-picker",
      action: "phlex-kit--calendar:change->phlex-kit--date-picker#onCalendarChange"
    }
  }, @attrs)) do
    render Popover.new do
      render PopoverTrigger.new(**trigger_attrs) do
        div(class: "pk-date-picker-field") do
          label(class: "pk-date-picker-label", for: @id) { @label } if @label
          render Input.new(**input_attrs)
        end
      end
      render PopoverContent.new(**@content_attrs) do
        render Calendar.new(input_id: input_selector, selected_date: @selected_date, date_format: @date_format, **@calendar_attrs)
      end
    end
  end
end