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.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +62 -14
  3. data/app/components/daisy/actions/button_component.html.haml +2 -2
  4. data/app/components/daisy/actions/button_component.rb +98 -59
  5. data/app/components/daisy/actions/dropdown_component.html.haml +1 -2
  6. data/app/components/daisy/actions/dropdown_component.rb +7 -10
  7. data/app/components/daisy/actions/modal_component.html.haml +10 -8
  8. data/app/components/daisy/actions/modal_component.rb +6 -6
  9. data/app/components/daisy/actions/swap_component.rb +13 -9
  10. data/app/components/daisy/actions/theme_controller.js +113 -0
  11. data/app/components/daisy/actions/theme_controller_component.rb +58 -17
  12. data/app/components/daisy/actions/theme_preview_component.html.haml +5 -0
  13. data/app/components/daisy/actions/theme_preview_component.rb +68 -0
  14. data/app/components/daisy/data_display/accordion_component.html.haml +0 -1
  15. data/app/components/daisy/data_display/accordion_component.rb +10 -3
  16. data/app/components/daisy/data_display/avatar_component.html.haml +1 -1
  17. data/app/components/daisy/data_display/avatar_component.rb +17 -7
  18. data/app/components/daisy/data_display/badge_component.rb +122 -4
  19. data/app/components/daisy/data_display/card_component.html.haml +1 -1
  20. data/app/components/daisy/data_display/card_component.rb +20 -6
  21. data/app/components/daisy/data_display/chat_component.rb +2 -2
  22. data/app/components/daisy/data_display/collapse_component.rb +9 -5
  23. data/app/components/daisy/data_display/countdown_component.rb +15 -5
  24. data/app/components/daisy/data_display/figure_component.rb +8 -3
  25. data/app/components/daisy/data_display/kbd_component.rb +13 -4
  26. data/app/components/daisy/data_display/list_component.html.haml +5 -0
  27. data/app/components/daisy/data_display/list_component.rb +82 -0
  28. data/app/components/daisy/data_display/list_item_component.rb +39 -0
  29. data/app/components/daisy/data_display/stat_component.html.haml +5 -6
  30. data/app/components/daisy/data_display/stat_component.rb +21 -8
  31. data/app/components/daisy/data_display/status_component.rb +47 -0
  32. data/app/components/daisy/data_display/timeline_component.rb +1 -1
  33. data/app/components/daisy/data_input/cally_component.html.haml +14 -0
  34. data/app/components/daisy/data_input/cally_component.rb +182 -0
  35. data/app/components/daisy/data_input/cally_input_component.html.haml +5 -0
  36. data/app/components/daisy/data_input/cally_input_component.rb +165 -0
  37. data/app/components/daisy/data_input/cally_input_controller.js +235 -0
  38. data/app/components/daisy/data_input/checkbox_component.html.haml +20 -0
  39. data/app/components/daisy/data_input/checkbox_component.rb +106 -0
  40. data/app/components/daisy/data_input/fieldset_component.html.haml +8 -0
  41. data/app/components/daisy/data_input/fieldset_component.rb +57 -0
  42. data/app/components/daisy/data_input/file_input_component.rb +98 -0
  43. data/app/components/daisy/data_input/filter_component.html.haml +3 -0
  44. data/app/components/daisy/data_input/filter_component.rb +221 -0
  45. data/app/components/daisy/data_input/label_component.rb +84 -0
  46. data/app/components/daisy/data_input/radio_button_component.rb +87 -0
  47. data/app/components/daisy/data_input/range_component.rb +95 -0
  48. data/app/components/daisy/data_input/rating_component.html.haml +11 -0
  49. data/app/components/daisy/data_input/rating_component.rb +139 -0
  50. data/app/components/daisy/data_input/select_component.html.haml +27 -0
  51. data/app/components/daisy/data_input/select_component.rb +320 -0
  52. data/app/components/daisy/data_input/text_area_component.rb +127 -0
  53. data/app/components/daisy/data_input/text_input_component.html.haml +27 -0
  54. data/app/components/daisy/data_input/text_input_component.rb +142 -0
  55. data/app/components/daisy/data_input/toggle_component.rb +48 -0
  56. data/app/components/daisy/feedback/alert_component.html.haml +1 -1
  57. data/app/components/daisy/feedback/alert_component.rb +86 -2
  58. data/app/components/daisy/feedback/loading_component.rb +10 -3
  59. data/app/components/daisy/feedback/skeleton_component.rb +1 -1
  60. data/app/components/daisy/layout/divider_component.rb +4 -2
  61. data/app/components/daisy/layout/drawer_component.html.haml +0 -1
  62. data/app/components/daisy/layout/footer_component.rb +6 -6
  63. data/app/components/daisy/mockup/device_component.rb +15 -18
  64. data/app/components/daisy/navigation/breadcrumbs_component.html.haml +0 -1
  65. data/app/components/daisy/navigation/breadcrumbs_component.rb +84 -9
  66. data/app/components/daisy/navigation/dock_component.rb +146 -0
  67. data/app/components/daisy/navigation/link_component.rb +18 -9
  68. data/app/components/daisy/navigation/menu_component.rb +15 -9
  69. data/app/components/daisy/navigation/navbar_component.html.haml +1 -1
  70. data/app/components/daisy/navigation/navbar_component.rb +2 -13
  71. data/app/components/daisy/navigation/steps_component.rb +6 -6
  72. data/app/components/daisy/navigation/tabs_component.html.haml +0 -1
  73. data/app/components/daisy/navigation/tabs_component.rb +26 -16
  74. data/app/components/hero/icon_component.rb +15 -5
  75. data/app/helpers/daisy/form_builder_helper.rb +186 -0
  76. data/app/views/examples/daisy/data_input/filters.html.haml +62 -0
  77. data/lib/daisy.rb +5 -0
  78. data/lib/hero.rb +1 -1
  79. data/lib/loco_motion/base_component.rb +53 -3
  80. data/lib/loco_motion/component_config.rb +1 -0
  81. data/lib/loco_motion/concerns/iconable_component.rb +134 -0
  82. data/lib/loco_motion/concerns/labelable_component.rb +142 -0
  83. data/lib/loco_motion/concerns/linkable_component.rb +40 -0
  84. data/lib/loco_motion/concerns/tippable_component.rb +25 -10
  85. data/lib/loco_motion/engine.rb +6 -0
  86. data/lib/loco_motion/helpers.rb +38 -17
  87. data/lib/loco_motion/patches/view_component/slot_loco_parent_patch.rb +37 -0
  88. data/lib/loco_motion/patches/view_component/slotable_default_patch.rb +21 -0
  89. data/lib/loco_motion/version.rb +1 -1
  90. data/lib/loco_motion.rb +12 -2
  91. metadata +93 -21
  92. data/app/components/daisy/actions/theme_controller_component.html.haml +0 -5
  93. data/app/components/daisy/layout/artboard_component.rb +0 -59
  94. data/app/components/daisy/navigation/bottom_nav_component.rb +0 -138
@@ -1,16 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #
2
4
  # Creates a menu component for displaying a list of items, optionally with group titles.
3
5
  #
6
+ # @note Vertical menus no longer have a default width. Use `w-full` or other width
7
+ # classes if you want to control the width.
8
+ #
4
9
  # @slot items+ {Daisy::Navigation::MenuItemComponent} The menu items to display.
5
10
  #
6
- # @example Basic menu with items
11
+ # @loco_example Basic menu with items
7
12
  # = daisy_menu do |menu|
8
13
  # - menu.with_item do
9
14
  # = link_to "Item 1", "#"
10
15
  # - menu.with_item do
11
16
  # = link_to "Item 2", "#"
12
17
  #
13
- # @example Menu with group titles
18
+ # @loco_example Menu with group titles
14
19
  # = daisy_menu do |menu|
15
20
  # - menu.with_item(title: "Group 1") do
16
21
  # = link_to "Item 1-1", "#"
@@ -19,10 +24,10 @@
19
24
  # = link_to "Item 2-1", "#"
20
25
  # = link_to "Item 2-2", "#"
21
26
  #
22
- # @example Menu with disabled items
27
+ # @loco_example Menu with disabled items
23
28
  # = daisy_menu do |menu|
24
29
  # - menu.with_item do
25
- # = link_to "Active Item", "#"
30
+ # = link_to "Active Item", "#", class: "menu-active"
26
31
  # - menu.with_item(disabled: true) do
27
32
  # Disabled Item
28
33
  #
@@ -33,15 +38,15 @@ class Daisy::Navigation::MenuComponent < LocoMotion::BaseComponent
33
38
  #
34
39
  # @part title The title element for the menu item.
35
40
  #
36
- # @example Basic menu item
41
+ # @loco_example Basic menu item
37
42
  # = menu.with_item do
38
43
  # = link_to "Item", "#"
39
44
  #
40
- # @example Menu item with title
45
+ # @loco_example Menu item with title
41
46
  # = menu.with_item(title: "Group") do
42
47
  # = link_to "Item", "#"
43
48
  #
44
- # @example Disabled menu item
49
+ # @loco_example Disabled menu item
45
50
  # = menu.with_item(disabled: true) do
46
51
  # = link_to "Item", "#"
47
52
  #
@@ -63,6 +68,7 @@ class Daisy::Navigation::MenuComponent < LocoMotion::BaseComponent
63
68
  # options include:
64
69
  # - Text: `text-sm`, `text-base-content`
65
70
  # - Spacing: `mt-4`, `mb-2`
71
+ # - State: `menu-active`, `menu-focus`, `menu-disabled`
66
72
  #
67
73
  def initialize(*args, **kws)
68
74
  super(**kws)
@@ -77,7 +83,7 @@ class Daisy::Navigation::MenuComponent < LocoMotion::BaseComponent
77
83
  #
78
84
  def before_render
79
85
  set_tag_name(:component, :li)
80
- add_css(:component, "disabled pointer-events-none") if @disabled
86
+ add_css(:component, "menu-disabled pointer-events-none") if @disabled
81
87
 
82
88
  set_tag_name(:title, :h2)
83
89
  add_css(:title, "menu-title")
@@ -102,7 +108,7 @@ class Daisy::Navigation::MenuComponent < LocoMotion::BaseComponent
102
108
  #
103
109
  # @option kws css [String] Additional CSS classes for styling. Common
104
110
  # options include:
105
- # - Size: `w-56`, `max-w-xs`
111
+ # - Layout: `menu-horizontal`, `w-full`, `w-56`
106
112
  # - Background: `bg-base-100`, `bg-neutral`
107
113
  # - Border: `border`, `rounded-box`
108
114
  # - Shadow: `shadow`, `shadow-lg`
@@ -1,4 +1,4 @@
1
1
  = part(:component) do
2
2
  = start if start?
3
3
  = center if center?
4
- = end_content if end?
4
+ = self.send(:end) if end?
@@ -11,7 +11,7 @@
11
11
  # @slot end {LocoMotion::BasicComponent} The right section of the navbar.
12
12
  # Automatically gets the `navbar-end` CSS class.
13
13
  #
14
- # @example Basic navbar with logo and GitHub link
14
+ # @loco_example Basic navbar with logo and GitHub link
15
15
  # = daisy_navbar(css: "bg-base-100") do |navbar|
16
16
  # - navbar.with_start do
17
17
  # = image_tag("logo.png", class: "h-8")
@@ -20,7 +20,7 @@
20
20
  # - navbar.with_end do
21
21
  # = link_to "GitHub", "https://github.com", target: "_blank"
22
22
  #
23
- # @example Navbar with all sections and dropdown
23
+ # @loco_example Navbar with all sections and dropdown
24
24
  # = daisy_navbar(css: "bg-base-100") do |navbar|
25
25
  # - navbar.with_start do
26
26
  # %span.text-lg.italic Brand
@@ -59,15 +59,4 @@ class Daisy::Navigation::NavbarComponent < LocoMotion::BaseComponent
59
59
  def before_render
60
60
  add_css(:component, "navbar")
61
61
  end
62
-
63
- private
64
-
65
- # Returns the end section content.
66
- #
67
- # Since `end` is a reserved word in Ruby, we need to use a different method
68
- # name in the template.
69
- #
70
- def end_content
71
- self.end
72
- end
73
62
  end
@@ -8,21 +8,21 @@
8
8
  # @slot steps+ {Daisy::Navigation::StepsComponent::StepComponent} The individual
9
9
  # steps to display.
10
10
  #
11
- # @example Basic steps with progress
11
+ # @loco_example Basic steps with progress
12
12
  # = daisy_steps do |steps|
13
13
  # - steps.with_step(title: "Write Code", css: "step-primary")
14
14
  # - steps.with_step(title: "Release Code", css: "step-primary")
15
15
  # - steps.with_step(title: "Profit", css: "step-secondary")
16
16
  # - steps.with_step(title: "Rule the World")
17
17
  #
18
- # @example Vertical steps
18
+ # @loco_example Vertical steps
19
19
  # = daisy_steps(css: "steps-vertical") do |steps|
20
20
  # - steps.with_step(title: "Write Code", css: "step-primary")
21
21
  # - steps.with_step(title: "Release Code", css: "step-primary")
22
22
  # - steps.with_step(title: "Profit", css: "step-secondary")
23
23
  # - steps.with_step(title: "Rule the World")
24
24
  #
25
- # @example Custom step content
25
+ # @loco_example Custom step content
26
26
  # = daisy_steps do |steps|
27
27
  # - steps.with_step(number: "AB")
28
28
  # - steps.with_step(number: "★")
@@ -33,13 +33,13 @@ class Daisy::Navigation::StepsComponent < LocoMotion::BaseComponent
33
33
  #
34
34
  # A step within a StepsComponent.
35
35
  #
36
- # @example Basic step with title
36
+ # @loco_example Basic step with title
37
37
  # = steps.with_step(title: "Step 1")
38
38
  #
39
- # @example Step with custom number
39
+ # @loco_example Step with custom number
40
40
  # = steps.with_step(number: "★", title: "Special Step")
41
41
  #
42
- # @example Step with custom content
42
+ # @loco_example Step with custom content
43
43
  # = steps.with_step(number: "1") do
44
44
  # .flex.gap-2
45
45
  # = hero_icon("check")
@@ -1,4 +1,3 @@
1
1
  = part(:component) do
2
2
  - tabs.each do |tab|
3
- - tab.set_loco_parent(component_ref)
4
3
  = tab
@@ -8,21 +8,21 @@
8
8
  # @slot tabs+ {Daisy::Navigation::TabsComponent::TabComponent} The individual
9
9
  # tabs to display.
10
10
  #
11
- # @example Basic tabs with links
12
- # = daisy_tabs(css: "tabs-bordered") do |tabs|
11
+ # @loco_example Basic tabs with links
12
+ # = daisy_tabs(css: "tabs-border") do |tabs|
13
13
  # - tabs.with_tab(title: "Home", active: true)
14
14
  # - tabs.with_tab(title: "Click Me", html: { onclick: "alert('Clicked!')" })
15
15
  # - tabs.with_tab(title: "Google", href: "https://google.com", target: "_blank")
16
16
  #
17
- # @example Radio button tabs with content
18
- # = daisy_tabs(css: "tabs-lifted", radio: true) do |tabs|
17
+ # @loco_example Radio button tabs with content
18
+ # = daisy_tabs(css: "tabs-lift", radio: true) do |tabs|
19
19
  # - tabs.with_tab(title: "Tab 1", checked: true) do
20
20
  # %p Tab 1 content
21
21
  # - tabs.with_tab(title: "Tab 2") do
22
22
  # %p Tab 2 content
23
23
  #
24
- # @example Tabs with custom titles and content
25
- # = daisy_tabs(css: "tabs-lifted") do |tabs|
24
+ # @loco_example Tabs with custom titles and content
25
+ # = daisy_tabs(css: "tabs-lift") do |tabs|
26
26
  # - tabs.with_tab do |tab|
27
27
  # - tab.with_title do
28
28
  # .flex.gap-2
@@ -31,6 +31,16 @@
31
31
  # - tab.with_custom_content(css: "tab-content p-4") do
32
32
  # %p Welcome home!
33
33
  #
34
+ # @loco_example Tabs with different sizes
35
+ # = daisy_tabs(css: "tabs-border tabs-xl") do |tabs|
36
+ # - tabs.with_tab(title: "Extra Large Tab", active: true)
37
+ # - tabs.with_tab(title: "Another Tab")
38
+ #
39
+ # @loco_example Tabs with different sizes
40
+ # = daisy_tabs(css: "tabs-border tabs-lg") do |tabs|
41
+ # - tabs.with_tab(title: "Large Tab", active: true)
42
+ # - tabs.with_tab(title: "Another Tab")
43
+ #
34
44
  class Daisy::Navigation::TabsComponent < LocoMotion::BaseComponent
35
45
 
36
46
  #
@@ -45,21 +55,21 @@ class Daisy::Navigation::TabsComponent < LocoMotion::BaseComponent
45
55
  # @slot custom_content Custom content to be rendered after the tab. Use this
46
56
  # instead of the block content for complete control over the content's HTML.
47
57
  #
48
- # @example Basic tab with title
58
+ # @loco_example Basic tab with title
49
59
  # = tabs.with_tab(title: "Home")
50
60
  #
51
- # @example Tab with custom title
61
+ # @loco_example Tab with custom title
52
62
  # = tabs.with_tab do |tab|
53
63
  # - tab.with_title do
54
64
  # .flex.gap-2
55
65
  # = hero_icon("home")
56
66
  # Home
57
67
  #
58
- # @example Tab with content
68
+ # @loco_example Tab with content
59
69
  # = tabs.with_tab(title: "Content") do
60
70
  # %p This is the tab's content
61
71
  #
62
- # @example Tab with custom content
72
+ # @loco_example Tab with custom content
63
73
  # = tabs.with_tab do |tab|
64
74
  # - tab.with_custom_content(css: "tab-content p-4") do
65
75
  # %p Custom content with custom wrapper
@@ -94,7 +104,7 @@ class Daisy::Navigation::TabsComponent < LocoMotion::BaseComponent
94
104
  #
95
105
  # @option kws css [String] Additional CSS classes for styling. Common
96
106
  # options include:
97
- # - Size: `tab-lg`, `tab-md`, `tab-sm`, `tab-xs`
107
+ # - Size: `tab-lg`, `tab-md` (default), `tab-sm`, `tab-xs`
98
108
  # - Width: `w-full`, `!w-14`
99
109
  # - Cursor: `cursor-pointer`, `!cursor-auto`
100
110
  #
@@ -112,9 +122,9 @@ class Daisy::Navigation::TabsComponent < LocoMotion::BaseComponent
112
122
 
113
123
  def before_render
114
124
  # Reset the name to the config option or the parent name if available
115
- @name = config_option(:name, loco_parent&.name)
125
+ @name = config_option(:name, loco_parent.name)
116
126
 
117
- if loco_parent&.radio?
127
+ if loco_parent.radio?
118
128
  setup_radio_button
119
129
  else
120
130
  setup_component
@@ -157,7 +167,7 @@ class Daisy::Navigation::TabsComponent < LocoMotion::BaseComponent
157
167
  # custom_content.to_s if custom_content?
158
168
 
159
169
  capture do
160
- if loco_parent&.radio?
170
+ if loco_parent.radio?
161
171
  concat(part(:component))
162
172
  else
163
173
  concat(part(:component) { concat(title? ? title : @simple_title) })
@@ -187,8 +197,8 @@ class Daisy::Navigation::TabsComponent < LocoMotion::BaseComponent
187
197
  #
188
198
  # @option kws css [String] Additional CSS classes for styling. Common
189
199
  # options include:
190
- # - Style: `tabs-bordered`, `tabs-lifted`
191
- # - Size: `tabs-lg`, `tabs-md`, `tabs-sm`, `tabs-xs`
200
+ # - Style: `tabs-border`, `tabs-lift`
201
+ # - Size: `tabs-xl`, `tabs-lg`, `tabs-md` (default), `tabs-sm`, `tabs-xs`
192
202
  # - Width: `w-full`, `w-[500px]`
193
203
  #
194
204
  def initialize(*args, **kws, &block)
@@ -8,19 +8,22 @@
8
8
  # `:where()` pseudo-class to ensure our default classes have the lowest CSS
9
9
  # specificity.
10
10
  #
11
- # @example Basic icon usage
11
+ # @loco_example Basic icon usage
12
12
  # = hero_icon("academic-cap")
13
13
  # = hero_icon(icon: "adjustments-horizontal")
14
14
  # %span.text-blue-500
15
15
  # = hero_icon("archive-box")
16
16
  #
17
- # @example Customized icons
17
+ # @loco_example Customized icons
18
18
  # = hero_icon("no-symbol", css: "size-4 text-red-600")
19
19
  # = hero_icon("arrow-trending-up", css: "size-10 text-green-600")
20
20
  # = hero_icon("exclamation-triangle", css: "size-14 text-yellow-400 animate-pulse")
21
21
  #
22
22
  class Hero::IconComponent < LocoMotion::BaseComponent
23
- prepend LocoMotion::Concerns::TippableComponent
23
+ # Tippable concern provides tooltip functionality.
24
+ include LocoMotion::Concerns::TippableComponent
25
+
26
+ set_component_name :icon
24
27
 
25
28
  # Create a new instance of the IconComponent.
26
29
  #
@@ -41,17 +44,24 @@ class Hero::IconComponent < LocoMotion::BaseComponent
41
44
  # - Color: `text-red-600`, `text-green-600`, `text-yellow-400`
42
45
  # - Animation: `animate-pulse`, `animate-spin`
43
46
  #
47
+ # @option kws tip [String] The tooltip text to display when hovering over
48
+ # the icon.
49
+ #
44
50
  def initialize(*args, **kws, &block)
45
51
  super
46
52
 
47
53
  # Accept either the :icon keyword argument or the first positional argument
48
54
  @icon = config_option(:icon, args[0])
49
55
  @variant = config_option(:variant)
56
+
57
+ @css = config_option(:css, "")
50
58
  end
51
59
 
52
60
  def before_render
61
+ super
62
+
53
63
  add_html(:component, { variant: @variant }) if @variant
54
- add_css(:component, "[:where(&)]:size-5")
64
+ add_css(:component, "where:size-5") unless @css.include?("size-")
55
65
  end
56
66
 
57
67
  #
@@ -62,6 +72,6 @@ class Hero::IconComponent < LocoMotion::BaseComponent
62
72
  # additional whitespace gets added to the output.
63
73
  #
64
74
  def call
65
- heroicon_tag(@icon, **rendered_html(:component))
75
+ heroicon(@icon, **rendered_html(:component))
66
76
  end
67
77
  end
@@ -0,0 +1,186 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Daisy
4
+ module FormBuilderHelper
5
+ # Extends ActionView::Helpers::FormBuilder with Daisy UI component methods
6
+ def self.included(base)
7
+ base.class_eval do
8
+ # Add the daisy_checkbox method to FormBuilder
9
+ def daisy_checkbox(name, **options)
10
+ # Get the object name from the form builder
11
+ object_name = @object_name.to_s
12
+
13
+ # Create a unique ID if not provided
14
+ options[:id] ||= "#{object_name}_#{name}"
15
+
16
+ # Set the name attribute
17
+ options[:name] = "#{object_name}[#{name}]"
18
+
19
+ # Pass the form builder's object to the component if it exists
20
+ if @object && @object.respond_to?(name) && !options.key?(:checked)
21
+ options[:checked] = @object.send(name)
22
+ end
23
+
24
+ # Render the checkbox component
25
+ @template.daisy_checkbox(**options)
26
+ end
27
+
28
+ # Add the daisy_toggle method to FormBuilder
29
+ def daisy_toggle(name, **options)
30
+ # Get the object name from the form builder
31
+ object_name = @object_name.to_s
32
+
33
+ # Create a unique ID if not provided
34
+ options[:id] ||= "#{object_name}_#{name}"
35
+
36
+ # Set the name attribute
37
+ options[:name] = "#{object_name}[#{name}]"
38
+
39
+ # Pass the form builder's object to the component if it exists
40
+ if @object && @object.respond_to?(name) && !options.key?(:checked)
41
+ options[:checked] = @object.send(name)
42
+ end
43
+
44
+ # Render the toggle component
45
+ @template.daisy_toggle(**options)
46
+ end
47
+
48
+ # Add the daisy_radio method to FormBuilder
49
+ def daisy_radio(name, **options)
50
+ # Get the object name from the form builder
51
+ object_name = @object_name.to_s
52
+
53
+ # Create a unique ID if not provided
54
+ value = options[:value].to_s
55
+ options[:id] ||= "#{object_name}_#{name}_#{value}"
56
+
57
+ # Set the name attribute
58
+ options[:name] = "#{object_name}[#{name}]"
59
+
60
+ # Pass the form builder's object to the component if it exists
61
+ if @object && @object.respond_to?(name) && !options.key?(:checked)
62
+ options[:checked] = @object.send(name).to_s == value
63
+ end
64
+
65
+ # Render the radio button component
66
+ @template.daisy_radio(**options)
67
+ end
68
+
69
+ # Add the daisy_label method to FormBuilder
70
+ def daisy_label(name, text = nil, **options, &block)
71
+ # Get the object name from the form builder
72
+ object_name = @object_name.to_s
73
+
74
+ # Create a for_id based on the name if not provided
75
+ options[:for] ||= "#{object_name}_#{name}"
76
+
77
+ # Add a humanized title from the name if not provided
78
+ options[:title] ||= text || name.to_s.humanize
79
+
80
+ # Render the label component
81
+ @template.daisy_label(**options, &block)
82
+ end
83
+
84
+ # Add the daisy_range method to FormBuilder
85
+ def daisy_range(method, **options)
86
+ render_daisy_component(Daisy::DataInput::RangeComponent, method, **options)
87
+ end
88
+
89
+ # Add the daisy_rating method to FormBuilder
90
+ def daisy_rating(method, **options)
91
+ render_daisy_component(Daisy::DataInput::RatingComponent, method, **options)
92
+ end
93
+
94
+ # Add the daisy_file_input method to FormBuilder
95
+ def daisy_file_input(method, **options)
96
+ render_daisy_component(Daisy::DataInput::FileInputComponent, method, **options)
97
+ end
98
+
99
+ # Add the daisy_text_input method to FormBuilder
100
+ def daisy_text_input(method, **options)
101
+ render_daisy_component(Daisy::DataInput::TextInputComponent, method, **options)
102
+ end
103
+
104
+ # Add the daisy_text_area method to FormBuilder
105
+ def daisy_text_area(method, **options)
106
+ render_daisy_component(Daisy::DataInput::TextAreaComponent, method, **options)
107
+ end
108
+
109
+ # Add the daisy_cally_input method to FormBuilder
110
+ def daisy_cally_input(method, **options, &block)
111
+ render_daisy_component(Daisy::DataInput::CallyInputComponent, method, **options, &block)
112
+ end
113
+
114
+ # Add the daisy_select method to FormBuilder
115
+ def daisy_select(method, options: nil, option_groups: nil, placeholder: nil,
116
+ options_css: nil, options_html: {}, **args, &block)
117
+ # Extract the name from the form builder's object_name and method
118
+ name = "#{object_name}[#{method}]"
119
+
120
+ # Get the current value from the object
121
+ value = object.try(method)
122
+
123
+ # Generate a default ID if not provided
124
+ id = args[:id] || "#{object_name}_#{method}"
125
+
126
+ # Build the component with the extracted form values and any additional options
127
+ @template.daisy_select(
128
+ name: name,
129
+ id: id,
130
+ value: value,
131
+ options: options,
132
+ options_css: options_css,
133
+ options_html: options_html,
134
+ placeholder: placeholder,
135
+ **args,
136
+ &block
137
+ )
138
+ end
139
+
140
+ # Add the daisy_filter method to FormBuilder
141
+ def daisy_filter(method, options: nil, **args, &block)
142
+ # Extract the name from the form builder's object_name and method
143
+ name = "#{object_name}[#{method}]"
144
+
145
+ # Get the current value from the object
146
+ value = object.try(method)
147
+
148
+ # Generate a default ID if not provided
149
+ id = args[:id] || "#{object_name}_#{method}"
150
+
151
+ # Build the component with the extracted form values and any additional options
152
+ @template.daisy_filter(
153
+ name: name,
154
+ id: id,
155
+ value: value,
156
+ options: options,
157
+ **args,
158
+ &block
159
+ )
160
+ end
161
+
162
+ private
163
+
164
+ def render_daisy_component(component_class, method, **options, &block)
165
+ # Get the object name from the form builder
166
+ object_name = @object_name.to_s
167
+
168
+ # Create a unique ID if not provided
169
+ options[:id] ||= "#{object_name}_#{method}"
170
+
171
+ # Set the name attribute
172
+ options[:name] ||= "#{object_name}[#{method}]"
173
+
174
+ # Pass the form builder's object to the component if it exists
175
+ options[:value] ||= object.try(method)
176
+
177
+ # Render the component
178
+ @template.render(component_class.new(**options), &block)
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
184
+
185
+ # Include the FormBuilderHelper in ActionView::Helpers::FormBuilder
186
+ ActionView::Helpers::FormBuilder.include(Daisy::FormBuilderHelper)
@@ -0,0 +1,62 @@
1
+ = doc_title(title: "Filters", comp: @comp) do |title|
2
+ :markdown
3
+ The Filter component is a group of radio buttons where choosing one option
4
+ hides the others and shows a reset button.
5
+
6
+ = doc_example(title: "Basic Usage") do |doc|
7
+ - doc.with_description do
8
+ :markdown
9
+ The basic filter component takes an `options` array and uses a div element
10
+ with radio buttons styled as buttons.
11
+
12
+ = daisy_filter(name: "frameworks", options: ["Svelte", "Vue", "React"])
13
+
14
+
15
+ = doc_example(title: "With Hash Options") do |doc|
16
+ - doc.with_description do
17
+ :markdown
18
+ You can also provide options as a hash with values and labels to customize
19
+ the display.
20
+
21
+ :ruby
22
+ options = [
23
+ { label: "Ruby", value: "ruby" },
24
+ { label: "JavaScript", value: "js" },
25
+ { label: "Python", value: "py" }
26
+ ]
27
+
28
+ = daisy_filter(name: "languages", options: options)
29
+
30
+
31
+ = doc_example(title: "Custom Button Styles") do |doc|
32
+ - doc.with_description do
33
+ :markdown
34
+ You can customize the styles of the buttons and reset button using CSS classes.
35
+
36
+ = daisy_filter(name: "priorities", css: "items-center") do |f|
37
+ - f.with_reset_button(css: "btn-accent btn-sm rounded-full")
38
+ - f.with_option(label: "Low", css: "btn-outline btn-success")
39
+ - f.with_option(label: "Medium", css: "btn-outline btn-warning")
40
+ - f.with_option(label: "High", css: "btn-outline btn-error")
41
+
42
+
43
+ = doc_example(title: "Filter Within Form") do |doc|
44
+ - doc.with_description do
45
+ :markdown
46
+ Filters can be used within forms to submit the selected value.
47
+
48
+ = form_with(url: "", method: :get, scope: :search, class: "mb-4") do |form|
49
+ = daisy_filter(name: "categories") do |f|
50
+ - f.with_option(label: "Category 1")
51
+ - f.with_option(label: "Category 2")
52
+ = form.submit "Apply Filters", class: "btn btn-primary mt-4"
53
+
54
+
55
+ = doc_example(title: "Form Builder") do |doc|
56
+ - doc.with_description do
57
+ :markdown
58
+ You can also use the form builder to create a filter.
59
+
60
+ = form_with(url: "", method: :get, scope: :search, class: "mb-4") do |form|
61
+ = form.daisy_filter(:category, options: ["Technology", "Science", "Arts"])
62
+ = form.submit "Apply Filters", class: "btn btn-primary mt-4"
data/lib/daisy.rb CHANGED
@@ -22,6 +22,11 @@ module Daisy
22
22
  #
23
23
  module Feedback; end
24
24
 
25
+ #
26
+ # Holds all Data Input-type components.
27
+ #
28
+ module DataInput; end
29
+
25
30
  #
26
31
  # Holds all Layout-type components.
27
32
  #
data/lib/hero.rb CHANGED
@@ -1,4 +1,4 @@
1
- require "heroicons-rails"
1
+ require "rails_heroicon"
2
2
 
3
3
  #
4
4
  # Parent module for all Hero components.