loco_motion-rails 0.0.8 → 0.5.0
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.
- checksums.yaml +4 -4
- data/README.md +62 -14
- data/app/components/daisy/actions/button_component.html.haml +2 -2
- data/app/components/daisy/actions/button_component.rb +98 -59
- data/app/components/daisy/actions/dropdown_component.html.haml +1 -2
- data/app/components/daisy/actions/dropdown_component.rb +7 -10
- data/app/components/daisy/actions/modal_component.html.haml +10 -8
- data/app/components/daisy/actions/modal_component.rb +6 -6
- data/app/components/daisy/actions/swap_component.rb +13 -9
- data/app/components/daisy/actions/theme_controller.js +113 -0
- data/app/components/daisy/actions/theme_controller_component.rb +58 -17
- data/app/components/daisy/actions/theme_preview_component.html.haml +5 -0
- data/app/components/daisy/actions/theme_preview_component.rb +68 -0
- data/app/components/daisy/data_display/accordion_component.html.haml +0 -1
- data/app/components/daisy/data_display/accordion_component.rb +10 -3
- data/app/components/daisy/data_display/avatar_component.html.haml +1 -1
- data/app/components/daisy/data_display/avatar_component.rb +17 -7
- data/app/components/daisy/data_display/badge_component.rb +122 -4
- data/app/components/daisy/data_display/card_component.html.haml +1 -1
- data/app/components/daisy/data_display/card_component.rb +20 -6
- data/app/components/daisy/data_display/chat_component.rb +2 -2
- data/app/components/daisy/data_display/collapse_component.rb +9 -5
- data/app/components/daisy/data_display/countdown_component.rb +15 -5
- data/app/components/daisy/data_display/figure_component.rb +8 -3
- data/app/components/daisy/data_display/kbd_component.rb +13 -4
- data/app/components/daisy/data_display/list_component.html.haml +5 -0
- data/app/components/daisy/data_display/list_component.rb +82 -0
- data/app/components/daisy/data_display/list_item_component.rb +39 -0
- data/app/components/daisy/data_display/stat_component.html.haml +5 -6
- data/app/components/daisy/data_display/stat_component.rb +21 -8
- data/app/components/daisy/data_display/status_component.rb +47 -0
- data/app/components/daisy/data_display/timeline_component.rb +1 -1
- data/app/components/daisy/data_input/cally_component.html.haml +14 -0
- data/app/components/daisy/data_input/cally_component.rb +182 -0
- data/app/components/daisy/data_input/cally_input_component.html.haml +5 -0
- data/app/components/daisy/data_input/cally_input_component.rb +165 -0
- data/app/components/daisy/data_input/cally_input_controller.js +235 -0
- data/app/components/daisy/data_input/checkbox_component.html.haml +20 -0
- data/app/components/daisy/data_input/checkbox_component.rb +106 -0
- data/app/components/daisy/data_input/fieldset_component.html.haml +8 -0
- data/app/components/daisy/data_input/fieldset_component.rb +57 -0
- data/app/components/daisy/data_input/file_input_component.rb +98 -0
- data/app/components/daisy/data_input/filter_component.html.haml +3 -0
- data/app/components/daisy/data_input/filter_component.rb +221 -0
- data/app/components/daisy/data_input/label_component.rb +84 -0
- data/app/components/daisy/data_input/radio_button_component.rb +87 -0
- data/app/components/daisy/data_input/range_component.rb +95 -0
- data/app/components/daisy/data_input/rating_component.html.haml +11 -0
- data/app/components/daisy/data_input/rating_component.rb +139 -0
- data/app/components/daisy/data_input/select_component.html.haml +27 -0
- data/app/components/daisy/data_input/select_component.rb +320 -0
- data/app/components/daisy/data_input/text_area_component.rb +127 -0
- data/app/components/daisy/data_input/text_input_component.html.haml +27 -0
- data/app/components/daisy/data_input/text_input_component.rb +142 -0
- data/app/components/daisy/data_input/toggle_component.rb +48 -0
- data/app/components/daisy/feedback/alert_component.html.haml +1 -1
- data/app/components/daisy/feedback/alert_component.rb +86 -2
- data/app/components/daisy/feedback/loading_component.rb +10 -3
- data/app/components/daisy/feedback/skeleton_component.rb +1 -1
- data/app/components/daisy/layout/divider_component.rb +4 -2
- data/app/components/daisy/layout/drawer_component.html.haml +0 -1
- data/app/components/daisy/layout/footer_component.rb +6 -6
- data/app/components/daisy/mockup/device_component.rb +15 -18
- data/app/components/daisy/navigation/breadcrumbs_component.html.haml +0 -1
- data/app/components/daisy/navigation/breadcrumbs_component.rb +84 -9
- data/app/components/daisy/navigation/dock_component.rb +146 -0
- data/app/components/daisy/navigation/link_component.rb +18 -9
- data/app/components/daisy/navigation/menu_component.rb +15 -9
- data/app/components/daisy/navigation/navbar_component.html.haml +1 -1
- data/app/components/daisy/navigation/navbar_component.rb +2 -13
- data/app/components/daisy/navigation/steps_component.rb +6 -6
- data/app/components/daisy/navigation/tabs_component.html.haml +0 -1
- data/app/components/daisy/navigation/tabs_component.rb +26 -16
- data/app/components/hero/icon_component.rb +15 -5
- data/app/helpers/daisy/form_builder_helper.rb +186 -0
- data/app/views/examples/daisy/data_input/filters.html.haml +62 -0
- data/lib/daisy.rb +5 -0
- data/lib/hero.rb +1 -1
- data/lib/loco_motion/base_component.rb +53 -3
- data/lib/loco_motion/component_config.rb +1 -0
- data/lib/loco_motion/concerns/iconable_component.rb +134 -0
- data/lib/loco_motion/concerns/labelable_component.rb +142 -0
- data/lib/loco_motion/concerns/linkable_component.rb +40 -0
- data/lib/loco_motion/concerns/tippable_component.rb +25 -10
- data/lib/loco_motion/engine.rb +6 -0
- data/lib/loco_motion/helpers.rb +38 -17
- data/lib/loco_motion/patches/view_component/slot_loco_parent_patch.rb +37 -0
- data/lib/loco_motion/patches/view_component/slotable_default_patch.rb +21 -0
- data/lib/loco_motion/version.rb +1 -1
- data/lib/loco_motion.rb +12 -2
- metadata +93 -21
- data/app/components/daisy/actions/theme_controller_component.html.haml +0 -5
- data/app/components/daisy/layout/artboard_component.rb +0 -59
- data/app/components/daisy/navigation/bottom_nav_component.rb +0 -138
@@ -27,9 +27,9 @@
|
|
27
27
|
# %p
|
28
28
|
# Press
|
29
29
|
# = daisy_kbd("Alt")
|
30
|
-
# +
|
30
|
+
# +
|
31
31
|
# = daisy_kbd("Shift")
|
32
|
-
# +
|
32
|
+
# +
|
33
33
|
# = daisy_kbd("M")
|
34
34
|
# to open the menu.
|
35
35
|
#
|
@@ -42,10 +42,12 @@
|
|
42
42
|
# to confirm.
|
43
43
|
#
|
44
44
|
class Daisy::DataDisplay::KbdComponent < LocoMotion::BaseComponent
|
45
|
-
|
45
|
+
include LocoMotion::Concerns::TippableComponent
|
46
46
|
|
47
47
|
set_component_name :kbd
|
48
48
|
|
49
|
+
attr_reader :simple_title
|
50
|
+
|
49
51
|
#
|
50
52
|
# Creates a new kbd component.
|
51
53
|
#
|
@@ -53,13 +55,20 @@ class Daisy::DataDisplay::KbdComponent < LocoMotion::BaseComponent
|
|
53
55
|
#
|
54
56
|
# @param kws [Hash] The keyword arguments for the component.
|
55
57
|
#
|
58
|
+
# @option kws [String] :tip The tooltip text to display when hovering over
|
59
|
+
# the component.
|
60
|
+
#
|
56
61
|
def initialize(*args, **kws, &block)
|
57
62
|
super
|
58
63
|
|
64
|
+
@simple_title = args[0]
|
65
|
+
|
59
66
|
set_tag_name(:component, :span)
|
60
67
|
end
|
61
68
|
|
62
69
|
def before_render
|
70
|
+
super
|
71
|
+
|
63
72
|
setup_component
|
64
73
|
end
|
65
74
|
|
@@ -71,7 +80,7 @@ class Daisy::DataDisplay::KbdComponent < LocoMotion::BaseComponent
|
|
71
80
|
# additional whitespace gets added to the output.
|
72
81
|
#
|
73
82
|
def call
|
74
|
-
part(:component) { content }
|
83
|
+
part(:component) { content || simple_title }
|
75
84
|
end
|
76
85
|
|
77
86
|
private
|
@@ -0,0 +1,82 @@
|
|
1
|
+
#
|
2
|
+
# The List component is a vertical layout to display information in rows. It can
|
3
|
+
# contain various content types including text, images, and actions arranged in a
|
4
|
+
# consistent format.
|
5
|
+
#
|
6
|
+
# The List component is useful for displaying structured data like user profiles,
|
7
|
+
# media libraries, or content collections with a consistent layout.
|
8
|
+
#
|
9
|
+
# @part component The main list container (ul element)
|
10
|
+
# @part header The optional header container for the list
|
11
|
+
#
|
12
|
+
# @slot item+ {Daisy::DataDisplay::ListItemComponent} Individual list items or
|
13
|
+
# rows in the list
|
14
|
+
#
|
15
|
+
# @loco_example Basic Usage
|
16
|
+
# = daisy_list do |list|
|
17
|
+
# - list.with_item { "Item 1" }
|
18
|
+
# - list.with_item { "Item 2" }
|
19
|
+
# - list.with_item { "Item 3" }
|
20
|
+
#
|
21
|
+
# @loco_example With Header
|
22
|
+
# = daisy_list(header: "Featured Items") do |list|
|
23
|
+
# - list.with_item { "Featured Item 1" }
|
24
|
+
# - list.with_item { "Featured Item 2" }
|
25
|
+
# - list.with_item { "Featured Item 3" }
|
26
|
+
#
|
27
|
+
# @loco_example With Rich Content
|
28
|
+
# = daisy_list(header: "Most played songs", css: "bg-base-100 rounded-box shadow-md") do |list|
|
29
|
+
# - list.with_item do |item|
|
30
|
+
# .flex.items-center.gap-2
|
31
|
+
# = image_tag("album_cover.jpg", class: "size-10 rounded-box")
|
32
|
+
# .flex.flex-col
|
33
|
+
# .font-medium Song Title
|
34
|
+
# .text-xs.opacity-60 Artist Name
|
35
|
+
# = daisy_button(icon: "play", css: "btn-ghost btn-square")
|
36
|
+
#
|
37
|
+
# @loco_example With Dividers
|
38
|
+
# = daisy_list(css: "divide-y") do |list|
|
39
|
+
# - list.with_item { "Item with divider below" }
|
40
|
+
# - list.with_item { "Another divided item" }
|
41
|
+
# - list.with_item { "Last item" }
|
42
|
+
#
|
43
|
+
# @!parse class Daisy::DataDisplay::ListComponent < LocoMotion::BaseComponent; end
|
44
|
+
class Daisy::DataDisplay::ListComponent < LocoMotion::BaseComponent
|
45
|
+
renders_many :items, "Daisy::DataDisplay::ListItemComponent"
|
46
|
+
renders_one :header, LocoMotion::BasicComponent.build(tag_name: :li)
|
47
|
+
|
48
|
+
set_component_name :list
|
49
|
+
|
50
|
+
# @return [String] Optional header text for the list
|
51
|
+
attr_reader :simple_header, :header_css, :header_html
|
52
|
+
|
53
|
+
#
|
54
|
+
# Create a new List component.
|
55
|
+
#
|
56
|
+
# @param kwargs [Hash] The keyword arguments for the component.
|
57
|
+
#
|
58
|
+
# @option kwargs [String] :header Optional header text to display at the top
|
59
|
+
# of the list.
|
60
|
+
#
|
61
|
+
# @option kwargs [String] :css Additional CSS classes to apply to the list.
|
62
|
+
# Common options include:
|
63
|
+
# - `bg-base-100` for background color
|
64
|
+
# - `rounded-box` for rounded corners
|
65
|
+
# - `shadow-md` for drop shadow
|
66
|
+
# - `divide-y` for dividers between items
|
67
|
+
#
|
68
|
+
def initialize(**kws, &block)
|
69
|
+
super
|
70
|
+
|
71
|
+
@simple_header = config_option(:header)
|
72
|
+
@header_css = config_option(:header_css)
|
73
|
+
@header_html = config_option(:header_html)
|
74
|
+
end
|
75
|
+
|
76
|
+
def before_render
|
77
|
+
add_css(:component, "list")
|
78
|
+
set_tag_name(:component, :ul)
|
79
|
+
|
80
|
+
with_header(tag_name: :li, css: header_css, html: header_html) { simple_header } if simple_header && !header?
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#
|
2
|
+
# The ListItem component represents an individual row within a List component.
|
3
|
+
# It provides a consistent layout for displaying content in a list format.
|
4
|
+
#
|
5
|
+
# @part image Optional image container for the item
|
6
|
+
#
|
7
|
+
# @loco_example Basic Usage
|
8
|
+
# = daisy_list do |list|
|
9
|
+
# - list.with_item { "Simple list item" }
|
10
|
+
#
|
11
|
+
# @loco_example With Image
|
12
|
+
# = daisy_list do |list|
|
13
|
+
# - list.with_item do
|
14
|
+
# = image_tag(src: "profile.jpg", class: "rounded-full size-8")
|
15
|
+
# User Profile
|
16
|
+
#
|
17
|
+
# @!parse class Daisy::DataDisplay::ListItemComponent < LocoMotion::BaseComponent; end
|
18
|
+
class Daisy::DataDisplay::ListItemComponent < LocoMotion::BaseComponent
|
19
|
+
#
|
20
|
+
# Create a new ListItem component.
|
21
|
+
#
|
22
|
+
# @param kwargs [Hash] The keyword arguments for the component.
|
23
|
+
#
|
24
|
+
# @option kwargs [String] :css Additional CSS classes to apply to the list item.
|
25
|
+
#
|
26
|
+
def initialize(**kwargs, &block)
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
30
|
+
# Called before rendering to setup the component CSS and structure
|
31
|
+
def before_render
|
32
|
+
set_tag_name(:component, :li)
|
33
|
+
add_css(:component, "list-row")
|
34
|
+
end
|
35
|
+
|
36
|
+
def call
|
37
|
+
part(:component) { content }
|
38
|
+
end
|
39
|
+
end
|
@@ -4,17 +4,17 @@
|
|
4
4
|
= part(:figure) do
|
5
5
|
- if figure?
|
6
6
|
= figure
|
7
|
-
|
8
|
-
|
7
|
+
|
8
|
+
= render_icon
|
9
|
+
|
9
10
|
- if @src.present?
|
10
11
|
= daisy_avatar(src: @src)
|
11
|
-
|
12
12
|
|
13
13
|
- if title?
|
14
14
|
= title
|
15
15
|
- elsif @simple_title.present?
|
16
16
|
= part(:title) do
|
17
|
-
= @simple_title
|
17
|
+
= @simple_title
|
18
18
|
|
19
19
|
= part(:value) do
|
20
20
|
= content
|
@@ -23,5 +23,4 @@
|
|
23
23
|
= description
|
24
24
|
- elsif @simple_description.present?
|
25
25
|
= part(:description) do
|
26
|
-
= @simple_description
|
27
|
-
|
26
|
+
= @simple_description
|
@@ -3,6 +3,9 @@
|
|
3
3
|
# description, and figure. It's perfect for dashboards, summaries, or any
|
4
4
|
# situation where you need to highlight important numbers or metrics.
|
5
5
|
#
|
6
|
+
# @note Stats have a transparent background by default. Use `bg-base-100` if you
|
7
|
+
# need a background color.
|
8
|
+
#
|
6
9
|
# Includes the {LocoMotion::Concerns::TippableComponent} module to enable easy
|
7
10
|
# tooltip addition.
|
8
11
|
#
|
@@ -21,27 +24,29 @@
|
|
21
24
|
# image via the src option or an icon via the icon option.
|
22
25
|
#
|
23
26
|
# @loco_example Basic Usage
|
24
|
-
# = daisy_stat(title: "Downloads", value: "31K"
|
27
|
+
# = daisy_stat(title: "Downloads", value: "31K")
|
25
28
|
#
|
26
29
|
# @loco_example With Description
|
27
|
-
# = daisy_stat(title: "New Users", value: "2.6K", description: "↗︎ 400 (22%)"
|
30
|
+
# = daisy_stat(title: "New Users", value: "2.6K", description: "↗︎ 400 (22%)")
|
28
31
|
#
|
29
32
|
# @loco_example With Icon
|
30
|
-
# = daisy_stat(title: "Page Views", value: "89,400", icon: "eye"
|
33
|
+
# = daisy_stat(title: "Page Views", value: "89,400", icon: "eye") do |stat|
|
31
34
|
# = stat.with_description do
|
32
35
|
# .flex.items-center.gap-1
|
33
|
-
# =
|
36
|
+
# = heroicon "arrow-up", class: "size-4 text-success"
|
34
37
|
# %span.text-success 14%
|
35
38
|
# from last month
|
36
39
|
#
|
37
40
|
# @loco_example With Custom Figure
|
38
|
-
# = daisy_stat(title: "Success Rate", value: "98%"
|
41
|
+
# = daisy_stat(title: "Success Rate", value: "98%") do |stat|
|
39
42
|
# = stat.with_figure do
|
40
43
|
# .text-success
|
41
|
-
# =
|
44
|
+
# = heroicon "check-circle", class: "size-10"
|
42
45
|
#
|
43
46
|
class Daisy::DataDisplay::StatComponent < LocoMotion::BaseComponent
|
44
|
-
|
47
|
+
include LocoMotion::Concerns::IconableComponent
|
48
|
+
include LocoMotion::Concerns::LinkableComponent
|
49
|
+
include LocoMotion::Concerns::TippableComponent
|
45
50
|
|
46
51
|
set_component_name :stat
|
47
52
|
|
@@ -76,17 +81,25 @@ class Daisy::DataDisplay::StatComponent < LocoMotion::BaseComponent
|
|
76
81
|
# @option kws [String] :icon Name of a heroicon to display in the figure
|
77
82
|
# section.
|
78
83
|
#
|
84
|
+
# @option kws [String] :tip The tooltip text to display when hovering over
|
85
|
+
# the component.
|
86
|
+
#
|
79
87
|
def initialize(*args, **kws, &block)
|
80
88
|
super
|
81
89
|
|
82
90
|
@simple_title = config_option(:title)
|
83
91
|
@simple_description = config_option(:description)
|
84
92
|
@src = config_option(:src)
|
85
|
-
@icon = config_option(:icon)
|
86
93
|
end
|
87
94
|
|
88
95
|
def before_render
|
89
96
|
setup_component
|
97
|
+
|
98
|
+
super
|
99
|
+
end
|
100
|
+
|
101
|
+
def default_icon_size
|
102
|
+
"where:size-8"
|
90
103
|
end
|
91
104
|
|
92
105
|
private
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#
|
2
|
+
# The StatusComponent displays a small icon to visually show the current status of an element,
|
3
|
+
# such as online, offline, error, etc. It follows the DaisyUI status component pattern.
|
4
|
+
#
|
5
|
+
# @loco_example Basic Status
|
6
|
+
# = daisy_status()
|
7
|
+
#
|
8
|
+
# @loco_example Status with Size
|
9
|
+
# = daisy_status(css: "status-xs")
|
10
|
+
# = daisy_status(css: "status-sm")
|
11
|
+
# = daisy_status(css: "status-md")
|
12
|
+
# = daisy_status(css: "status-lg")
|
13
|
+
# = daisy_status(css: "status-xl")
|
14
|
+
#
|
15
|
+
# @loco_example Status with Color
|
16
|
+
# = daisy_status(css: "status-primary")
|
17
|
+
# = daisy_status(css: "status-secondary")
|
18
|
+
# = daisy_status(css: "status-accent")
|
19
|
+
# = daisy_status(css: "status-info")
|
20
|
+
# = daisy_status(css: "status-success")
|
21
|
+
# = daisy_status(css: "status-warning")
|
22
|
+
# = daisy_status(css: "status-error")
|
23
|
+
#
|
24
|
+
# @loco_example Status with Accessibility
|
25
|
+
# = daisy_status(css: "status-success", html: { aria: { label: "Status: Online" } })
|
26
|
+
class Daisy::DataDisplay::StatusComponent < LocoMotion::BaseComponent
|
27
|
+
include LocoMotion::Concerns::TippableComponent
|
28
|
+
|
29
|
+
def initialize(**kws)
|
30
|
+
super(**kws)
|
31
|
+
end
|
32
|
+
|
33
|
+
def before_render
|
34
|
+
setup_component
|
35
|
+
super # Call super after setup
|
36
|
+
end
|
37
|
+
|
38
|
+
def call
|
39
|
+
part(:component)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def setup_component
|
45
|
+
add_css(:component, "status")
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
= part(:component) do
|
2
|
+
= previous_icon if previous_icon?
|
3
|
+
= next_icon if next_icon?
|
4
|
+
|
5
|
+
- if @month_count
|
6
|
+
= part(:months) do
|
7
|
+
- @month_count.times do |index|
|
8
|
+
= render(MonthComponent.new(**month_options(index)))
|
9
|
+
|
10
|
+
- elsif months?
|
11
|
+
= months
|
12
|
+
|
13
|
+
- else
|
14
|
+
= content
|
@@ -0,0 +1,182 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Daisy
|
4
|
+
module DataInput
|
5
|
+
# The Cally component provides a customizable calendar interface for date selection.
|
6
|
+
# It supports both single date and date range selection, with configurable display
|
7
|
+
# options including the number of months to show and navigation controls.
|
8
|
+
#
|
9
|
+
# @part component The root calendar element that contains all other parts.
|
10
|
+
# @part months The container element that holds the individual month components.
|
11
|
+
#
|
12
|
+
# @slot previous_icon [PreviousIcon] The icon used for navigating to the
|
13
|
+
# previous month. Defaults to a chevron-left icon.
|
14
|
+
# @see #default_previous_icon
|
15
|
+
# @slot next_icon [NextIcon] The icon used for navigating to the next month.
|
16
|
+
# Defaults to a chevron-right icon.
|
17
|
+
# @see #default_next_icon
|
18
|
+
# @slot months+ [MonthComponent] The month components to display in the calendar.
|
19
|
+
# Multiple months can be displayed side by side.
|
20
|
+
# @see #month_options
|
21
|
+
#
|
22
|
+
# @loco_example Basic calendar with default options
|
23
|
+
# = daisy_cally
|
24
|
+
#
|
25
|
+
# @loco_example Calendar with range selection enabled
|
26
|
+
# = daisy_cally(modifier: :range)
|
27
|
+
#
|
28
|
+
# @loco_example Calendar showing multiple months with custom value
|
29
|
+
# = daisy_cally(months: 2, value: Date.today)
|
30
|
+
#
|
31
|
+
# @loco_example Calendar with min/max date constraints
|
32
|
+
# = daisy_cally(min: 1.month.ago, max: 1.month.from_now)
|
33
|
+
class CallyComponent < LocoMotion::BaseComponent
|
34
|
+
include ViewComponent::SlotableDefault
|
35
|
+
|
36
|
+
# A component for the previous navigation icon in the calendar header.
|
37
|
+
#
|
38
|
+
# @note This is used internally by CallyComponent
|
39
|
+
class PreviousIcon < Hero::IconComponent
|
40
|
+
def before_render
|
41
|
+
super
|
42
|
+
|
43
|
+
add_html(:component, { slot: "previous" })
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# A component for the next navigation icon in the calendar header.
|
48
|
+
#
|
49
|
+
# @note This is used internally by CallyComponent
|
50
|
+
class NextIcon < Hero::IconComponent
|
51
|
+
def before_render
|
52
|
+
super
|
53
|
+
|
54
|
+
add_html(:component, { slot: "next" })
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# A component representing a single month in the calendar.
|
59
|
+
#
|
60
|
+
# @note This is used internally by CallyComponent
|
61
|
+
class MonthComponent < LocoMotion::BaseComponent
|
62
|
+
# @param offset [Integer, nil] The offset of this month from the start date
|
63
|
+
def initialize(**kws)
|
64
|
+
super
|
65
|
+
|
66
|
+
@offset = config_option(:offset)
|
67
|
+
end
|
68
|
+
|
69
|
+
def before_render
|
70
|
+
super
|
71
|
+
|
72
|
+
set_tag_name(:component, "calendar-month")
|
73
|
+
add_html(:component, { offset: @offset }) if @offset
|
74
|
+
end
|
75
|
+
|
76
|
+
def call
|
77
|
+
part(:component)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
define_modifiers :range
|
82
|
+
|
83
|
+
renders_one :previous_icon, PreviousIcon
|
84
|
+
renders_one :next_icon, NextIcon
|
85
|
+
renders_many :months, MonthComponent
|
86
|
+
|
87
|
+
define_parts :months
|
88
|
+
|
89
|
+
# Initializes a new CallyComponent.
|
90
|
+
#
|
91
|
+
# The Cally component provides a customizable calendar interface for date
|
92
|
+
# selection. It supports single date selection by default and can be
|
93
|
+
# configured for date range selection. The component automatically
|
94
|
+
# handles navigation between months and can display multiple months.
|
95
|
+
#
|
96
|
+
# @param change [String] ID of an input to update with the selected date.
|
97
|
+
# Mutually exclusive with `update`.
|
98
|
+
# @param update [String] ID of an element to update with the selected
|
99
|
+
# date. Mutually exclusive with `change`.
|
100
|
+
# @param id [String] The ID of the calendar element
|
101
|
+
# @param value [String, Date] The currently selected date or range
|
102
|
+
# @param min [String, Date] The minimum selectable date
|
103
|
+
# @param max [String, Date] The maximum selectable date
|
104
|
+
# @param today [String, Date] The date to consider as 'today'
|
105
|
+
# @param months [Integer] Number of months to display (default: 1)
|
106
|
+
def initialize(**kws)
|
107
|
+
super
|
108
|
+
|
109
|
+
# If we don't have any modifiers, assume we want a single month for a date select
|
110
|
+
@month_count = config_option(:months, modifiers.blank? ? 1 : nil)
|
111
|
+
@change = config_option(:change)
|
112
|
+
@update = config_option(:update)
|
113
|
+
|
114
|
+
@id = config_option(:id)
|
115
|
+
@value = config_option(:value)
|
116
|
+
@min = config_option(:min)
|
117
|
+
@max = config_option(:max)
|
118
|
+
@today = config_option(:today)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Configures the calendar component before rendering.
|
122
|
+
#
|
123
|
+
# Sets up the appropriate tag name based on whether range selection is
|
124
|
+
# enabled, adds CSS classes, and configures HTML attributes for the
|
125
|
+
# calendar component.
|
126
|
+
def before_render
|
127
|
+
super
|
128
|
+
|
129
|
+
if modifiers.include?(:range)
|
130
|
+
set_tag_name(:component, "calendar-range")
|
131
|
+
else
|
132
|
+
set_tag_name(:component, "calendar-date")
|
133
|
+
end
|
134
|
+
|
135
|
+
add_css(:component, "cally")
|
136
|
+
add_html(:component, { months: @month_count }) if @month_count
|
137
|
+
|
138
|
+
add_html(:component, {
|
139
|
+
id: @id,
|
140
|
+
value: @value,
|
141
|
+
min: @min,
|
142
|
+
max: @max,
|
143
|
+
today: @today
|
144
|
+
})
|
145
|
+
|
146
|
+
if @change
|
147
|
+
add_html(:component, { onchange: "document.getElementById('#{@change}').value = this.value" })
|
148
|
+
end
|
149
|
+
|
150
|
+
if @update
|
151
|
+
add_html(:component, { onchange: "document.getElementById('#{@update}').innerHTML = this.value" })
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# Generates options for a month component at the given index.
|
156
|
+
#
|
157
|
+
# @param index [Integer] The 0-based index of the month
|
158
|
+
# @return [Hash] Options hash for the month component
|
159
|
+
def month_options(index)
|
160
|
+
options = {}
|
161
|
+
|
162
|
+
options[:offset] = index if index > 0
|
163
|
+
|
164
|
+
options
|
165
|
+
end
|
166
|
+
|
167
|
+
# Provides a default previous icon if none is specified.
|
168
|
+
#
|
169
|
+
# @return [PreviousIcon] A chevron-left icon
|
170
|
+
def default_previous_icon
|
171
|
+
PreviousIcon.new(icon: "chevron-left")
|
172
|
+
end
|
173
|
+
|
174
|
+
# Provides a default next icon if none is specified.
|
175
|
+
#
|
176
|
+
# @return [NextIcon] A chevron-right icon
|
177
|
+
def default_next_icon
|
178
|
+
NextIcon.new(icon: "chevron-right")
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|