loco_motion-rails 0.0.6 → 0.0.8

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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +139 -67
  3. data/app/components/daisy/actions/button_component.rb +112 -8
  4. data/app/components/daisy/actions/dropdown_component.html.haml +5 -5
  5. data/app/components/daisy/actions/dropdown_component.rb +95 -26
  6. data/app/components/daisy/actions/modal_component.html.haml +3 -2
  7. data/app/components/daisy/actions/modal_component.rb +111 -20
  8. data/app/components/daisy/actions/swap_component.rb +117 -6
  9. data/app/components/daisy/actions/theme_controller_component.html.haml +1 -1
  10. data/app/components/daisy/actions/theme_controller_component.rb +37 -2
  11. data/app/components/daisy/data_display/accordion_component.rb +81 -4
  12. data/app/components/daisy/data_display/avatar_component.rb +39 -17
  13. data/app/components/daisy/data_display/badge_component.rb +49 -5
  14. data/app/components/daisy/data_display/card_component.html.haml +5 -13
  15. data/app/components/daisy/data_display/card_component.rb +76 -40
  16. data/app/components/daisy/data_display/carousel_component.rb +39 -1
  17. data/app/components/daisy/data_display/chat_component.rb +42 -15
  18. data/app/components/daisy/data_display/collapse_component.rb +61 -2
  19. data/app/components/daisy/data_display/countdown_component.rb +51 -1
  20. data/app/components/daisy/data_display/diff_component.rb +38 -1
  21. data/app/components/daisy/data_display/figure_component.rb +49 -0
  22. data/app/components/daisy/data_display/kbd_component.rb +64 -3
  23. data/app/components/daisy/data_display/stat_component.rb +67 -7
  24. data/app/components/daisy/data_display/table_component.rb +100 -35
  25. data/app/components/daisy/data_display/timeline_component.rb +46 -1
  26. data/app/components/daisy/data_display/timeline_event_component.rb +40 -2
  27. data/app/components/daisy/feedback/alert_component.rb +47 -2
  28. data/app/components/daisy/feedback/loading_component.rb +50 -0
  29. data/app/components/daisy/feedback/progress_component.rb +58 -0
  30. data/app/components/daisy/feedback/radial_progress_component.rb +72 -0
  31. data/app/components/daisy/feedback/skeleton_component.rb +53 -0
  32. data/app/components/daisy/feedback/toast_component.rb +45 -0
  33. data/app/components/daisy/feedback/tooltip_component.rb +77 -0
  34. data/app/components/daisy/layout/artboard_component.rb +59 -0
  35. data/app/components/daisy/layout/divider_component.rb +72 -0
  36. data/app/components/daisy/layout/drawer_component.html.haml +9 -0
  37. data/app/components/daisy/layout/drawer_component.rb +155 -0
  38. data/app/components/daisy/layout/footer_component.rb +69 -0
  39. data/app/components/daisy/layout/hero_component.html.haml +5 -0
  40. data/app/components/daisy/layout/hero_component.rb +83 -0
  41. data/app/components/daisy/layout/indicator_component.rb +83 -0
  42. data/app/components/daisy/layout/join_component.rb +72 -1
  43. data/app/components/daisy/layout/stack_component.rb +68 -0
  44. data/app/components/daisy/mockup/browser_component.rb +78 -0
  45. data/app/components/daisy/mockup/code_component.rb +144 -0
  46. data/app/components/daisy/mockup/device_component.rb +81 -0
  47. data/app/components/daisy/mockup/frame_component.rb +62 -0
  48. data/app/components/daisy/navigation/bottom_nav_component.rb +83 -4
  49. data/app/components/daisy/navigation/breadcrumbs_component.rb +41 -4
  50. data/app/components/daisy/navigation/link_component.rb +66 -13
  51. data/app/components/daisy/navigation/menu_component.rb +83 -11
  52. data/app/components/daisy/navigation/navbar_component.html.haml +1 -1
  53. data/app/components/daisy/navigation/navbar_component.rb +64 -3
  54. data/app/components/daisy/navigation/steps_component.rb +78 -2
  55. data/app/components/daisy/navigation/tabs_component.rb +112 -9
  56. data/app/components/hero/icon_component.rb +50 -1
  57. data/lib/daisy.rb +18 -3
  58. data/lib/hero.rb +7 -0
  59. data/lib/loco_motion/basic_component.rb +1 -1
  60. data/lib/loco_motion/concerns/tippable_component.rb +26 -0
  61. data/lib/loco_motion/configuration.rb +35 -0
  62. data/lib/loco_motion/helpers.rb +96 -0
  63. data/lib/loco_motion/version.rb +5 -0
  64. data/lib/loco_motion.rb +6 -36
  65. metadata +58 -9
  66. data/app/components/daisy/data_display/badge_component.html.haml +0 -2
  67. data/app/components/daisy/data_display/kbd_component.html.haml +0 -2
  68. data/app/components/daisy/navigation/link_component.html.haml +0 -4
  69. data/lib/daisy/helpers.rb +0 -61
@@ -1,14 +1,81 @@
1
- # This is a Modal component.
2
- # @!parse class Daisy::Actions::ModalComponent < LocoMotion::BaseComponent; end
3
- class Daisy::Actions::ModalComponent < LocoMotion.configuration.base_component_class
1
+ #
2
+ # The Modal component renders a modal dialog that can be opened and closed. It
3
+ # provides a structured way to display content that requires user attention or
4
+ # interaction, such as forms, confirmations, or detailed information.
5
+ #
6
+ # Note that the modal uses the HTML `<dialog>` element and its native methods
7
+ # (`showModal()` and `close()`). This provides better accessibility and keyboard
8
+ # navigation compared to div-based modals.
9
+ #
10
+ # @part dialog The main `<dialog>` container that wraps the modal content.
11
+ # @part box The container for the modal content, providing padding and layout.
12
+ # @part close_icon_wrapper The container for the close icon, positioned in the
13
+ # top-right corner.
14
+ # @part close_icon The default close icon button.
15
+ # @part backdrop The semi-transparent backdrop that covers and dims the main
16
+ # content.
17
+ # @part title Container for the modal title, styled for prominence.
18
+ # @part actions Container for all modal action buttons.
19
+ # @part start_actions Container for left (start) aligned action buttons.
20
+ # @part end_actions Container for right (end) aligned action buttons.
21
+ #
22
+ # @slot activator A custom element that opens the modal. Automatically adds
23
+ # `role="button"` and `tabindex="0"` attributes for accessibility.
24
+ # @slot button The button that opens the modal. Defaults to a standard Daisy
25
+ # button with the modal's title.
26
+ # @slot close_icon A custom close button to replace the default 'X' icon.
27
+ # @slot title Custom title content, replacing the default text title.
28
+ # @slot start_actions Left (start) aligned buttons, typically for secondary actions
29
+ # like "Cancel".
30
+ # @slot end_actions Right (end) aligned buttons, typically for primary actions
31
+ # like "Submit" or "Save".
32
+ #
33
+ # @loco_example Basic Modal
34
+ # = daisy_modal(title: "Simple Modal") do |modal|
35
+ # - modal.with_button(css: "btn-primary") { "Open Modal" }
36
+ # %p This is a basic modal with some content.
37
+ # - modal.with_end_actions do
38
+ # %form{ method: :dialog }
39
+ # = daisy_button { "Close" }
40
+ #
41
+ # @loco_example Form Modal
42
+ # = daisy_modal(title: "Edit Profile") do |modal|
43
+ # - modal.with_button { "Edit Profile" }
44
+ # = form_with(model: @user) do |f|
45
+ # .space-y-4
46
+ # = f.text_field :name, class: "input input-bordered w-full"
47
+ # = f.email_field :email, class: "input input-bordered w-full"
48
+ # - modal.with_start_actions do
49
+ # %form{ method: :dialog }
50
+ # = daisy_button { "Cancel" }
51
+ # - modal.with_end_actions do
52
+ # = daisy_button(css: "btn-primary", type: "submit") { "Save Changes" }
53
+ #
54
+ # @loco_example Custom Activator
55
+ # = daisy_modal(title: "User Details") do |modal|
56
+ # - modal.with_activator do
57
+ # .flex.items-center.gap-2.cursor-pointer
58
+ # = heroicon_tag "user-circle"
59
+ # %span View Details
60
+ #
61
+ # %dl.space-y-2
62
+ # %dt Name
63
+ # %dd John Doe
64
+ # %dt Email
65
+ # %dd john@example.com
66
+ #
67
+ # - modal.with_end_actions do
68
+ # %form{ method: :dialog }
69
+ # = daisy_button { "Close" }
70
+ #
71
+ class Daisy::Actions::ModalComponent < LocoMotion::BaseComponent
4
72
  set_component_name :modal
5
73
 
6
- define_parts :dialog, :box, :actions,
7
- :activator, :close_icon_wrapper, :close_icon,
8
- :backdrop,
9
- :title, :start_actions, :end_actions
74
+ define_parts :dialog, :box, :actions, :close_icon_wrapper, :close_icon,
75
+ :backdrop, :title, :start_actions, :end_actions
10
76
 
11
- renders_one :activator
77
+ renders_one :activator, LocoMotion::BasicComponent.build(html: { role: "button", tabindex: 0 })
78
+ renders_one :button, Daisy::Actions::ButtonComponent
12
79
  renders_one :close_icon
13
80
  renders_one :title
14
81
  renders_one :start_actions
@@ -26,28 +93,35 @@ class Daisy::Actions::ModalComponent < LocoMotion.configuration.base_component_c
26
93
  attr_reader :simple_title
27
94
 
28
95
  #
29
- # Instantiate a new Modal component. All options are expected to be passed as
30
- # keyword arguments.
96
+ # Creates a new instance of the ModalComponent.
31
97
  #
32
- # @overload initialize(dialog_id: nil, closable: true, title: nil)
33
- # @param dialog_id [String] A specific ID you would like the dialog to use.
34
- # Auto-generates a random ID using `SecureRandom.uuid` if not provided.
98
+ # @param title [String] The title of the modal. Used in both the modal header
99
+ # and the default trigger button.
35
100
  #
36
- # @param closable [Boolean] Whether or not the modal should allow closing.
101
+ # @param kws [Hash] The keyword arguments for the component.
37
102
  #
38
- # @param title [String] A simple title that you would like the component to
39
- # render above the main content of the modal. Accessible through the
40
- # {simple_title} accessor.
103
+ # @option kws title [String] The title of the modal. You can also pass this as
104
+ # the first argument.
41
105
  #
42
- def initialize(*args, **kws, &block)
106
+ # @option kws closable [Boolean] If true (default), shows a close icon in the
107
+ # top-right corner.
108
+ #
109
+ # @option kws dialog_id [String] A custom ID for the dialog element. If not
110
+ # provided, a unique ID will be generated.
111
+ #
112
+ def initialize(title = nil, **kws, &block)
43
113
  super
44
114
 
45
- @dialog_id ||= SecureRandom.uuid
115
+ @dialog_id = config_option(:dialog_id, SecureRandom.uuid)
46
116
  @closable = config_option(:closable, true)
47
- @simple_title = config_option(:title)
117
+ @simple_title = config_option(:title, title)
48
118
  end
49
119
 
120
+ #
121
+ # Sets up the component with various CSS classes and HTML attributes.
122
+ #
50
123
  def before_render
124
+ setup_activator_or_button
51
125
  setup_component
52
126
  setup_backdrop
53
127
  setup_box
@@ -58,6 +132,18 @@ class Daisy::Actions::ModalComponent < LocoMotion.configuration.base_component_c
58
132
 
59
133
  private
60
134
 
135
+ def setup_activator_or_button
136
+ onclick = "document.getElementById('#{dialog_id}').showModal()"
137
+
138
+ element = if activator?
139
+ activator
140
+ else
141
+ button || default_button
142
+ end
143
+
144
+ element.add_html(:component, { onclick: onclick })
145
+ end
146
+
61
147
  def setup_component
62
148
  set_tag_name(:component, :dialog)
63
149
  add_html(:component, id: dialog_id)
@@ -89,4 +175,9 @@ class Daisy::Actions::ModalComponent < LocoMotion.configuration.base_component_c
89
175
  def setup_actions
90
176
  add_css(:actions, "mt-2 flex flex-row items-center justify-between")
91
177
  end
178
+
179
+ # Provide a default button if no button is supplied.
180
+ def default_button
181
+ with_button(simple_title)
182
+ end
92
183
  end
@@ -1,4 +1,70 @@
1
- class Daisy::Actions::SwapComponent < LocoMotion.configuration.base_component_class
1
+ #
2
+ # The Swap component allows toggling between two states, "on" and "off", with an
3
+ # optional indeterminate state. It provides a flexible way to create animated
4
+ # toggles, switches, or any other element that needs to alternate between
5
+ # different visual states. The component supports both simple text/emoji swaps
6
+ # and complex HTML content swaps.
7
+ #
8
+ # It also includes built-in animations that can be enabled through CSS classes
9
+ # like `swap-rotate` or `swap-flip`.
10
+ #
11
+ # Includes the {LocoMotion::Concerns::TippableComponent} module to enable easy
12
+ # tooltip addition.
13
+ #
14
+ # @part checkbox The checkbox input element that handles the toggle state.
15
+ # @part on Wraps the HTML content displayed when the swap is in the "on" state.
16
+ # @part off Wraps the HTML content displayed when the swap is in the "off" state.
17
+ # @part indeterminate Wraps the HTML content displayed when the swap is in an
18
+ # indeterminate state. Only shown when the checkbox is in an indeterminate
19
+ # state.
20
+ #
21
+ # @slot on The HTML content to be displayed when the swap is in the "on" state.
22
+ # @slot off The HTML content to be displayed when the swap is in the "off" state.
23
+ # @slot indeterminate The HTML content to be displayed when the swap is in an
24
+ # indeterminate state.
25
+ #
26
+ # @loco_example Basic Text Swap
27
+ # = daisy_swap(checked: true, on: "✅ On", off: "❌ Off", css: "swap-rotate")
28
+ #
29
+ # @loco_example Basic Usage with Args
30
+ # = daisy_swap("✅ On", "❌ Off", true, css: "swap-rotate")
31
+ #
32
+ # @loco_example Icon Swap with Tooltip
33
+ # = daisy_swap(tip: "Toggle Theme") do |swap|
34
+ # - swap.with_on do
35
+ # = heroicon_tag "sun", css: "size-6"
36
+ # - swap.with_off do
37
+ # = heroicon_tag "moon", css: "size-6"
38
+ #
39
+ # @loco_example Complex Content with Animation
40
+ # = daisy_swap(css: "swap-flip") do |swap|
41
+ # - swap.with_on do
42
+ # .bg-primary.text-primary-content.p-4.rounded-lg
43
+ # .font-bold Subscribed
44
+ # %p You're all set!
45
+ # - swap.with_off do
46
+ # .bg-base-200.p-4.rounded-lg
47
+ # .font-bold Subscribe
48
+ # %p Click to join
49
+ #
50
+ # @loco_example With Indeterminate State
51
+ # = daisy_swap(css: "swap-flip", tip: "Task Status") do |swap|
52
+ # - swap.with_on do
53
+ # .text-success
54
+ # = heroicon_tag "check-circle"
55
+ # %span Complete
56
+ # - swap.with_off do
57
+ # .text-error
58
+ # = heroicon_tag "x-circle"
59
+ # %span Failed
60
+ # - swap.with_indeterminate do
61
+ # .text-warning
62
+ # = heroicon_tag "clock"
63
+ # %span Processing
64
+ #
65
+ class Daisy::Actions::SwapComponent < LocoMotion::BaseComponent
66
+ prepend LocoMotion::Concerns::TippableComponent
67
+
2
68
  class SwapOn < LocoMotion::BasicComponent
3
69
  def before_render
4
70
  add_css(:component, "swap-on")
@@ -23,32 +89,77 @@ class Daisy::Actions::SwapComponent < LocoMotion.configuration.base_component_cl
23
89
  renders_one :off, SwapOff
24
90
  renders_one :indeterminate, SwapIndeterminate
25
91
 
26
- attr_reader :simple_on, :simple_off
92
+ # @return [String] The value of the `on` option. Usually text or emoji.
93
+ attr_reader :simple_on
94
+
95
+ # @return [String] The value of the `off` option. Usually text or emoji.
96
+ attr_reader :simple_off
27
97
 
28
- def initialize(*args, **kwargs, &block)
98
+ #
99
+ # Creates a new instance of the SwapComponent.
100
+ #
101
+ # @param on [String] Simple text/emoji to display in the "on" state. If provided
102
+ # along with `off`, enables simple text swap mode.
103
+ #
104
+ # @param off [String] Simple text/emoji to display in the "off" state. If provided
105
+ # along with `on`, enables simple text swap mode.
106
+ #
107
+ # @param checked [Boolean] Whether the swap should start in the checked ("on")
108
+ # state. Defaults to false.
109
+ #
110
+ # @param kws [Hash] The keyword arguments for the component.
111
+ #
112
+ # @option kws on [String] Simple text/emoji for the "on" state. Alternative to
113
+ # providing it as the first argument.
114
+ #
115
+ # @option kws off [String] Simple text/emoji for the "off" state. Alternative to
116
+ # providing it as the second argument.
117
+ #
118
+ # @option kws checked [Boolean] Whether the swap should start checked. Alternative
119
+ # to providing it as the third argument.
120
+ #
121
+ # @option kws indeterminate [Boolean] If true, starts the swap in an indeterminate
122
+ # state. Requires the indeterminate slot to be meaningful.
123
+ #
124
+ def initialize(on = nil, off = nil, checked = nil, **kws, &block)
29
125
  super
30
126
 
31
- @checked = config_option(:checked, false)
32
- @simple_on = config_option(:on)
33
- @simple_off = config_option(:off)
127
+ @checked = config_option(:checked, checked || false)
128
+ @simple_on = config_option(:on, on)
129
+ @simple_off = config_option(:off, off)
34
130
  end
35
131
 
132
+ #
133
+ # Sets up the component with various CSS classes and HTML attributes.
134
+ #
36
135
  def before_render
37
136
  setup_component
38
137
  setup_checkbox
39
138
  setup_on_off
40
139
  end
41
140
 
141
+ private
142
+
143
+ #
144
+ # Sets up the main component structure. The component is rendered as a label
145
+ # element to allow clicking anywhere on it to toggle the checkbox.
146
+ #
42
147
  def setup_component
43
148
  set_tag_name(:component, :label)
44
149
  add_css(:component, "swap")
45
150
  end
46
151
 
152
+ #
153
+ # Sets up the checkbox input element that handles the toggle state.
154
+ #
47
155
  def setup_checkbox
48
156
  set_tag_name(:checkbox, :input)
49
157
  add_html(:checkbox, { type: "checkbox", checked: @checked })
50
158
  end
51
159
 
160
+ #
161
+ # Sets up the CSS classes for the "on" and "off" states.
162
+ #
52
163
  def setup_on_off
53
164
  add_css(:on, "swap-on")
54
165
  add_css(:off, "swap-off")
@@ -1,5 +1,5 @@
1
1
  = part(:component) do
2
- - SOME_THEMES.map do |theme|
2
+ - @themes.map do |theme|
3
3
  %label.label.cursor-pointer.gap-4
4
4
  %span.label-text= theme.titleize
5
5
  %input.radio.theme-controller{ name: "theme", type: "radio", value: theme, checked: theme == "light"}
@@ -1,7 +1,42 @@
1
- # Renders a very basic radio-button theme controller.
2
- class Daisy::Actions::ThemeControllerComponent < LocoMotion.configuration.base_component_class
1
+ #
2
+ # The Theme Controller component provides a simple interface for switching
3
+ # between different DaisyUI themes. It renders a set of radio buttons that
4
+ # allow users to select from a predefined list of themes.
5
+ #
6
+ # The component is designed to work with DaisyUI's theme system and
7
+ # automatically updates the `data-theme` attribute on the HTML element when
8
+ # a theme is selected.
9
+ #
10
+ # @loco_example Basic Usage
11
+ # = daisy_theme_controller
12
+ #
13
+ # @loco_example Custom Theme List
14
+ # = daisy_theme_controller(themes: ["light", "dark", "cyberpunk"])
15
+ #
16
+ # @loco_example With Custom Styling
17
+ # = daisy_theme_controller(css: "gap-6 p-4 bg-base-200 rounded-lg")
18
+ #
19
+ class Daisy::Actions::ThemeControllerComponent < LocoMotion::BaseComponent
20
+ # Default list of themes to display in the controller
3
21
  SOME_THEMES = ["light", "dark", "synthwave", "retro", "cyberpunk", "wireframe"].freeze
4
22
 
23
+ #
24
+ # Creates a new instance of the ThemeControllerComponent.
25
+ #
26
+ # @param kws [Hash] The keyword arguments for the component.
27
+ #
28
+ # @option kws themes [Array<String>] List of DaisyUI theme names to include
29
+ # in the controller. Defaults to {SOME_THEMES}.
30
+ #
31
+ def initialize(**kws, &block)
32
+ super
33
+
34
+ @themes = config_option(:themes, SOME_THEMES)
35
+ end
36
+
37
+ #
38
+ # Sets up the component's CSS classes for proper layout and spacing.
39
+ #
5
40
  def before_render
6
41
  add_css(:component, "flex flex-col lg:flex-row gap-4 items-center")
7
42
  end
@@ -1,7 +1,55 @@
1
- # The Accordion component shows sections that can be expanded or collapsed.
2
- class Daisy::DataDisplay::AccordionComponent < LocoMotion.configuration.base_component_class
1
+ #
2
+ # The Accordion component shows collapsible sections of content, with only one
3
+ # section open at a time. Each section has a title that can be clicked to show
4
+ # or hide its content.
5
+ #
6
+ # Includes the {LocoMotion::Concerns::TippableComponent} module to enable easy
7
+ # tooltip addition.
8
+ #
9
+ # @slot section+ Multiple sections that can be expanded or collapsed. Each
10
+ # section can have a title and content.
11
+ #
12
+ # @loco_example Basic Usage
13
+ # = daisy_accordion do |accordion|
14
+ # - accordion.with_section(title: "Section 1") do
15
+ # This is the content of section 1
16
+ # - accordion.with_section(title: "Section 2") do
17
+ # This is the content of section 2
18
+ #
19
+ # @loco_example With Arrow Icons
20
+ # = daisy_accordion(:arrow) do |accordion|
21
+ # - accordion.with_section(title: "Section 1") do
22
+ # This is the content of section 1
23
+ # - accordion.with_section(title: "Section 2") do
24
+ # This is the content of section 2
25
+ #
26
+ # @loco_example With Plus Icons
27
+ # = daisy_accordion(:plus) do |accordion|
28
+ # - accordion.with_section(title: "Section 1") do
29
+ # This is the content of section 1
30
+ # - accordion.with_section(title: "Section 2") do
31
+ # This is the content of section 2
32
+ #
33
+ # @loco_example With Custom Title Content
34
+ # = daisy_accordion do |accordion|
35
+ # - accordion.with_section do |section|
36
+ # - section.with_title do
37
+ # .flex.items-center.gap-2
38
+ # = heroicon_tag "star"
39
+ # Featured Section
40
+ # This is the content of the featured section
41
+ #
42
+ class Daisy::DataDisplay::AccordionComponent < LocoMotion::BaseComponent
43
+ prepend LocoMotion::Concerns::TippableComponent
3
44
 
4
45
  # Renders a single section of the accordion.
46
+ #
47
+ # @part radio_button The radio input that controls the section's state.
48
+ # @part title The title bar that can be clicked to expand/collapse the section.
49
+ # @part content The container for the section's content.
50
+ #
51
+ # @slot title Custom content for the section's title bar.
52
+ #
5
53
  class AccordionSectionComponent < LocoMotion::BasicComponent
6
54
  define_parts :radio_button, :title, :content
7
55
 
@@ -11,7 +59,23 @@ class Daisy::DataDisplay::AccordionComponent < LocoMotion.configuration.base_com
11
59
  # config.
12
60
  attr_reader :simple_title
13
61
 
14
- def initialize(*args, **kws, &block)
62
+ # Creates a new accordion section.
63
+ #
64
+ # @param kws [Hash] The keyword arguments for the component.
65
+ #
66
+ # @option kws title [String] The text to display in the section's title bar.
67
+ # You can also provide a custom title content using the title slot.
68
+ #
69
+ # @option kws value [String] The value for the radio button that controls
70
+ # this section. Defaults to a random string.
71
+ #
72
+ # @option kws checked [Boolean] Whether this section should start expanded.
73
+ # Defaults to false.
74
+ #
75
+ # @option kws name [String] The name attribute for the radio button group.
76
+ # Usually provided by the parent accordion.
77
+ #
78
+ def initialize(**kws, &block)
15
79
  super
16
80
 
17
81
  @value = config_option(:value)
@@ -72,9 +136,22 @@ class Daisy::DataDisplay::AccordionComponent < LocoMotion.configuration.base_com
72
136
 
73
137
  renders_many :sections, AccordionSectionComponent
74
138
 
139
+ # @return [String] The name attribute for all radio buttons in this accordion.
75
140
  attr_reader :name
76
141
 
77
- def initialize(*args, **kws, &block)
142
+ #
143
+ # Creates a new accordion component.
144
+ #
145
+ # @param kws [Hash] The keyword arguments for the component.
146
+ #
147
+ # @option kws name [String] The name attribute for all radio buttons in this
148
+ # accordion. Defaults to a random string.
149
+ #
150
+ # @option kws modifier [Symbol] Optional modifier for the accordion's appearance.
151
+ # Use `:arrow` to show arrow indicators, or `:plus` to show plus/minus
152
+ # indicators.
153
+ #
154
+ def initialize(**kws, &block)
78
155
  super
79
156
 
80
157
  @name = config_option(:name, "accordion-#{SecureRandom.uuid}")
@@ -1,35 +1,57 @@
1
- # The Avatar Component displays in image, icon, or placeholder text to represent
2
- # a user.
1
+ # The Avatar component displays an image, icon, or placeholder text to represent
2
+ # a user or entity. It provides a consistent, circular display with fallback
3
+ # options when an image is not available.
4
+ #
5
+ # Includes the {LocoMotion::Concerns::TippableComponent} module to enable easy
6
+ # tooltip addition.
3
7
  #
4
8
  # It utilizes the CSS `where()` pseudo-class to reduce the specificity to 0 to
5
9
  # allow for easy overriding while giving you some sane defaults.
6
10
  #
7
- # - Width: <code>w-24</code> (can override with w-10, h-10, etc.)
8
- # - Corners: `rounded-full`
11
+ # @part wrapper The outer container that maintains the avatar's shape and size.
12
+ # @part img The image element when an image source is provided.
13
+ # @part icon The icon element when an icon is specified.
14
+ # @part placeholder The container for placeholder content when no image or icon
15
+ # is provided.
16
+ #
17
+ # @loco_example Basic Usage with Image
18
+ # = daisy_avatar(src: "https://example.com/avatar.jpg")
9
19
  #
10
- # If no image is provided, these additional classes will be added so that any
11
- # text or icons are visible.
20
+ # @loco_example With Icon
21
+ # = daisy_avatar(icon: "user")
12
22
  #
13
- # - Background: +bg-neutral+
14
- # - Text Color: `text-neutral-content`
23
+ # @loco_example With Custom Icon Styling
24
+ # = daisy_avatar(icon: "user", icon_css: "text-yellow-400")
15
25
  #
16
- # ## Examples
26
+ # @loco_example With Placeholder Text
27
+ # = daisy_avatar do
28
+ # JD
17
29
  #
18
- # ```language-haml
19
- # - # Display an avatar with an image
20
- # = daisy_avatar src: "https://example.com/avatar.jpg"
30
+ # @loco_example With Custom Size
31
+ # = daisy_avatar(src: "avatar.jpg", css: "w-16 h-16")
21
32
  #
22
- # - # Display an avatar with an icon
23
- # = daisy_avatar icon: "user", icon_css: "text-yellow-400"
24
- # ```
33
+ # @loco_example With Tooltip
34
+ # = daisy_avatar(src: "avatar.jpg", tip: "John Doe")
25
35
  #
26
- class Daisy::DataDisplay::AvatarComponent < LocoMotion.configuration.base_component_class
36
+ class Daisy::DataDisplay::AvatarComponent < LocoMotion::BaseComponent
37
+ prepend LocoMotion::Concerns::TippableComponent
38
+
27
39
  set_component_name :avatar
28
40
 
29
41
  define_parts :wrapper, :img, :icon, :placeholder
30
42
 
31
43
  # Create a new avatar component.
32
- def initialize(*args, **kws, &block)
44
+ #
45
+ # @param kws [Hash] The keyword arguments for the component.
46
+ #
47
+ # @option kws src [String] URL to the avatar image. If not provided, the
48
+ # component will display an icon or placeholder content.
49
+ #
50
+ # @option kws icon [String] Name of the Heroicon to display when no image is
51
+ # provided. If neither src nor icon is provided, placeholder content from
52
+ # the block will be shown.
53
+ #
54
+ def initialize(**kws, &block)
33
55
  super
34
56
 
35
57
  @src = config_option(:src)
@@ -1,27 +1,71 @@
1
1
  #
2
- # The Badge component renders as a small, rounded element with various
3
- # background colors.
2
+ # The Badge component renders as a small, rounded element used to display status,
3
+ # labels, or notifications. It supports various background colors and can be used
4
+ # inline with text.
5
+ #
6
+ # Includes the {LocoMotion::Concerns::TippableComponent} module to enable easy
7
+ # tooltip addition.
8
+ #
9
+ # @loco_example Basic Usage
10
+ # = daisy_badge("New!")
11
+ #
12
+ # @loco_example With Different Colors
13
+ # = daisy_badge("Primary", css: "badge-primary")
14
+ # = daisy_badge("Secondary", css: "badge-secondary")
15
+ # = daisy_badge("Accent", css: "badge-accent")
16
+ # = daisy_badge("Ghost", css: "badge-ghost")
17
+ #
18
+ # @loco_example With Tooltip
19
+ # = daisy_badge("Beta", tip: "This feature is in beta testing")
20
+ #
21
+ # @loco_example Using a Block
22
+ # = daisy_badge do
23
+ # %span.flex.items-center.gap-1
24
+ # = heroicon_tag "star", css: "size-4"
25
+ # Featured
4
26
  #
5
27
  # @!parse class Daisy::DataDisplay::BadgeComponent < LocoMotion::BaseComponent; end
6
- class Daisy::DataDisplay::BadgeComponent < LocoMotion.configuration.base_component_class
28
+ class Daisy::DataDisplay::BadgeComponent < LocoMotion::BaseComponent
29
+ prepend LocoMotion::Concerns::TippableComponent
30
+
7
31
  set_component_name :badge
8
32
 
9
33
  #
10
34
  # Create a new Badge component.
11
35
  #
12
- def initialize(*args, **kws, &block)
36
+ # @param title [String] The text to display in the badge. You can also pass
37
+ # the title as a keyword argument or provide content via a block.
38
+ #
39
+ # @param kwargs [Hash] The keyword arguments for the component.
40
+ #
41
+ # @option kwargs title [String] The text to display in the badge. You can also
42
+ # pass the title as the first argument or provide content via a block.
43
+ #
44
+ def initialize(title = nil, **kws, &block)
13
45
  super
14
46
 
15
- set_tag_name(:component, :span)
47
+ @title = config_option(:title, title)
16
48
  end
17
49
 
18
50
  def before_render
19
51
  setup_component
20
52
  end
21
53
 
54
+ #
55
+ # Renders the badge component.
56
+ #
57
+ # Because this is an inline component which might be utlized alongside text,
58
+ # we utilize the `call` method instead of a template to ensure that no
59
+ # additional whitespace gets added to the output.
60
+ #
61
+ def call
62
+ part(:component) { content || @title }
63
+ end
64
+
22
65
  private
23
66
 
24
67
  def setup_component
68
+ set_tag_name(:component, :span)
25
69
  add_css(:component, "badge")
26
70
  end
27
71
  end
@@ -1,17 +1,9 @@
1
1
  = part(:component) do
2
- - if top_figure?
3
- = top_figure
4
-
5
- = part(:body) do
6
- - if title?
7
- = title
8
- - elsif @simple_title
9
- %h2.card-title= @simple_title
2
+ = top_figure if top_figure?
10
3
 
4
+ .card-body
5
+ = title if title?
11
6
  = content
7
+ = actions if actions?
12
8
 
13
- - if actions?
14
- = actions
15
-
16
- - if bottom_figure?
17
- = bottom_figure
9
+ = bottom_figure if bottom_figure?