loco_motion-rails 0.0.7 → 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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +45 -1
  3. data/app/components/daisy/actions/button_component.rb +109 -8
  4. data/app/components/daisy/actions/dropdown_component.html.haml +5 -5
  5. data/app/components/daisy/actions/dropdown_component.rb +94 -25
  6. data/app/components/daisy/actions/modal_component.html.haml +3 -2
  7. data/app/components/daisy/actions/modal_component.rb +94 -45
  8. data/app/components/daisy/actions/swap_component.rb +114 -5
  9. data/app/components/daisy/actions/theme_controller_component.html.haml +1 -1
  10. data/app/components/daisy/actions/theme_controller_component.rb +36 -1
  11. data/app/components/daisy/data_display/accordion_component.rb +79 -3
  12. data/app/components/daisy/data_display/avatar_component.rb +36 -16
  13. data/app/components/daisy/data_display/badge_component.rb +35 -5
  14. data/app/components/daisy/data_display/card_component.html.haml +5 -13
  15. data/app/components/daisy/data_display/card_component.rb +74 -39
  16. data/app/components/daisy/data_display/carousel_component.rb +38 -0
  17. data/app/components/daisy/data_display/chat_component.rb +40 -10
  18. data/app/components/daisy/data_display/collapse_component.rb +58 -1
  19. data/app/components/daisy/data_display/countdown_component.rb +49 -0
  20. data/app/components/daisy/data_display/diff_component.rb +37 -0
  21. data/app/components/daisy/data_display/figure_component.rb +49 -0
  22. data/app/components/daisy/data_display/kbd_component.rb +50 -2
  23. data/app/components/daisy/data_display/stat_component.rb +64 -6
  24. data/app/components/daisy/data_display/table_component.rb +99 -34
  25. data/app/components/daisy/data_display/timeline_component.rb +45 -0
  26. data/app/components/daisy/data_display/timeline_event_component.rb +39 -1
  27. data/app/components/daisy/feedback/alert_component.rb +46 -1
  28. data/app/components/daisy/feedback/loading_component.rb +39 -0
  29. data/app/components/daisy/feedback/progress_component.rb +39 -1
  30. data/app/components/daisy/feedback/radial_progress_component.rb +44 -1
  31. data/app/components/daisy/feedback/skeleton_component.rb +44 -0
  32. data/app/components/daisy/feedback/toast_component.rb +36 -0
  33. data/app/components/daisy/feedback/tooltip_component.rb +46 -10
  34. data/app/components/daisy/layout/artboard_component.rb +48 -0
  35. data/app/components/daisy/layout/divider_component.rb +50 -10
  36. data/app/components/daisy/layout/drawer_component.rb +62 -17
  37. data/app/components/daisy/layout/footer_component.rb +51 -11
  38. data/app/components/daisy/layout/hero_component.rb +67 -5
  39. data/app/components/daisy/layout/indicator_component.rb +55 -8
  40. data/app/components/daisy/layout/join_component.rb +71 -0
  41. data/app/components/daisy/layout/stack_component.rb +59 -0
  42. data/app/components/daisy/mockup/browser_component.rb +78 -0
  43. data/app/components/daisy/mockup/code_component.rb +144 -0
  44. data/app/components/daisy/mockup/device_component.rb +81 -0
  45. data/app/components/daisy/mockup/frame_component.rb +62 -0
  46. data/app/components/daisy/navigation/bottom_nav_component.rb +81 -2
  47. data/app/components/daisy/navigation/breadcrumbs_component.rb +40 -3
  48. data/app/components/daisy/navigation/link_component.rb +31 -6
  49. data/app/components/daisy/navigation/menu_component.rb +52 -20
  50. data/app/components/daisy/navigation/navbar_component.html.haml +1 -1
  51. data/app/components/daisy/navigation/navbar_component.rb +63 -2
  52. data/app/components/daisy/navigation/steps_component.rb +76 -0
  53. data/app/components/daisy/navigation/tabs_component.rb +110 -7
  54. data/app/components/hero/icon_component.rb +40 -0
  55. data/lib/daisy.rb +5 -0
  56. data/lib/loco_motion/helpers.rb +7 -0
  57. data/lib/loco_motion/version.rb +5 -0
  58. metadata +25 -5
@@ -1,27 +1,67 @@
1
1
  #
2
- # The footer component is a simple container for the footer of a page. It can be
3
- # used to hold copyright information, links to other pages, or any other
4
- # information that should be displayed at the bottom of a page.
2
+ # The FooterComponent creates a responsive container for page footer content.
3
+ # Common use cases include:
4
+ # - Site navigation and sitemap links.
5
+ # - Copyright and legal information.
6
+ # - Contact details and social media links.
7
+ # - Newsletter signup forms.
5
8
  #
6
- # @loco_example Basic Usage
7
- # = daisy_footer(css: "bg-neutral text-neutral-content") do
9
+ # The component is responsive by default and will stack content on smaller
10
+ # screens.
11
+ #
12
+ # @loco_example Basic Navigation Footer
13
+ # = daisy_footer(css: "bg-neutral text-neutral-content p-10") do
14
+ # %nav
15
+ # %h6.footer-title Company
16
+ # = link_to "About", "/about", class: "link-hover"
17
+ # = link_to "Contact", "/contact", class: "link-hover"
18
+ # = link_to "Jobs", "/careers", class: "link-hover"
19
+ #
20
+ # @loco_example Multi-Column Footer
21
+ # = daisy_footer(css: "bg-base-200 text-base-content p-10") do
8
22
  # %nav
9
- # = link_to "Home", root_path
23
+ # %h6.footer-title Products
24
+ # = link_to "Features", "#", class: "link-hover"
25
+ # = link_to "Pricing", "#", class: "link-hover"
10
26
  #
11
- # @loco_example With Text
12
- # = daisy_footer(css: "bg-neutral text-neutral-content p-10 text-center text-sm") do
13
- # Copyright © 2024
27
+ # %nav
28
+ # %h6.footer-title Support
29
+ # = link_to "Documentation", "#", class: "link-hover"
30
+ # = link_to "Help Center", "#", class: "link-hover"
31
+ #
32
+ # @loco_example Copyright Footer
33
+ # = daisy_footer(css: "bg-neutral text-neutral-content p-4 text-center") do
34
+ # %small
35
+ # Copyright © 2024 Company Name.
36
+ # All rights reserved.
14
37
  #
15
38
  class Daisy::Layout::FooterComponent < LocoMotion::BaseComponent
16
39
  #
17
- # Add the `footer` CSS class to the component.
40
+ # Creates a new Footer component.
41
+ #
42
+ # @param kws [Hash] Keyword arguments for customizing the footer.
43
+ #
44
+ # @option kws css [String] Additional CSS classes for styling. Common
45
+ # options include:
46
+ # - Background: `bg-neutral`, `bg-base-200`
47
+ # - Text color: `text-neutral-content`, `text-base-content`
48
+ # - Spacing: `p-4`, `p-10`
49
+ # - Layout: `text-center`, `grid grid-cols-2 gap-4`
50
+ #
51
+ def initialize(**kws)
52
+ super
53
+ end
54
+
55
+ #
56
+ # Sets up the component's CSS classes and HTML tag.
18
57
  #
19
58
  def before_render
20
59
  add_css(:component, "footer")
60
+ set_tag_name(:component, :footer)
21
61
  end
22
62
 
23
63
  #
24
- # Render the component and it's content (inline).
64
+ # Renders the component and its content.
25
65
  #
26
66
  def call
27
67
  part(:component) { content }
@@ -1,10 +1,45 @@
1
1
  #
2
- # The HeroComponent is a layout component that is used to create a hero section.
2
+ # The HeroComponent creates an eye-catching, full-width section typically used
3
+ # at the top of a page. Common use cases include:
4
+ # - Landing page introductions.
5
+ # - Feature showcases.
6
+ # - Call-to-action sections.
7
+ # - Image-rich banners.
3
8
  #
4
- # @part content_wrapper The wrapper for the content of the hero.
9
+ # The component is responsive by default and provides flexible layout options
10
+ # for content positioning and image integration.
5
11
  #
6
- # @slot overlay [LocoMotion::BasicComponent] An optional `<div>` positioned to
7
- # overlay underneath the hero and allow for styling behind it.
12
+ # @part content_wrapper [LocoMotion::BaseComponent] The wrapper for the hero
13
+ # content, providing flex-based layout control.
14
+ #
15
+ # @slot overlay [LocoMotion::BasicComponent] An optional `<div>` positioned
16
+ # behind the content for background effects like semi-transparency or blur.
17
+ #
18
+ # @loco_example Basic Hero
19
+ # = daisy_hero(css: "bg-base-200 text-center") do
20
+ # %div
21
+ # %h1.text-5xl.font-bold Welcome
22
+ # %p.my-6 Discover amazing features.
23
+ # = daisy_button(css: "btn btn-primary",
24
+ # title: "Get Started")
25
+ #
26
+ # @loco_example Hero with Image
27
+ # = daisy_hero(css: "bg-base-200",
28
+ # content_wrapper_css: "flex-col md:flex-row") do
29
+ # %img.h-40.rounded{
30
+ # src: image_path("hero-image.jpg"),
31
+ # alt: "Hero Image" }
32
+ # %div
33
+ # %h1.text-5xl.font-bold Features
34
+ # %p.my-6 Explore what we offer.
35
+ #
36
+ # @loco_example Hero with Background Overlay
37
+ # = daisy_hero(css: "min-h-96",
38
+ # html: { style: "background-image: url('bg.jpg')" }) do |hero|
39
+ # - hero.with_overlay(css: "bg-black/50 backdrop-blur")
40
+ # %div.text-white
41
+ # %h1.text-5xl.font-bold Discover
42
+ # %p.my-6 Start your journey today.
8
43
  #
9
44
  class Daisy::Layout::HeroComponent < LocoMotion::BaseComponent
10
45
  define_part :content_wrapper
@@ -12,7 +47,34 @@ class Daisy::Layout::HeroComponent < LocoMotion::BaseComponent
12
47
  renders_one :overlay, LocoMotion::BasicComponent.build(css: "hero-overlay")
13
48
 
14
49
  #
15
- # Adds the necessary CSS classes to the component.
50
+ # Creates a new Hero component.
51
+ #
52
+ # @param kws [Hash] Keyword arguments for customizing the hero.
53
+ #
54
+ # @option kws css [String] Additional CSS classes for styling. Common
55
+ # options include:
56
+ # - Height: `min-h-screen`, `min-h-[50vh]`
57
+ # - Background: `bg-base-200`, `bg-primary`
58
+ # - Text: `text-center`, `text-primary-content`
59
+ #
60
+ # @option kws content_wrapper_css [String] CSS classes for the content
61
+ # wrapper. Common options include:
62
+ # - Layout: `flex-col`, `flex-col md:flex-row`
63
+ # - Spacing: `gap-4`, `space-y-4`
64
+ # - Alignment: `items-center`, `justify-between`
65
+ #
66
+ # @option kws html [Hash] HTML attributes for the hero container.
67
+ # Commonly used for background images:
68
+ # ```ruby
69
+ # html: { style: "background-image: url('image.jpg')" }
70
+ # ```
71
+ #
72
+ def initialize(**kws)
73
+ super
74
+ end
75
+
76
+ #
77
+ # Sets up the component's CSS classes.
16
78
  #
17
79
  def before_render
18
80
  add_css(:component, "hero")
@@ -1,28 +1,75 @@
1
1
  #
2
- # The IndicatorComponent provides items positioned around it's content with the
3
- # intention of indicating a callout or something needing attention.
2
+ # The IndicatorComponent positions notification elements around its content to
3
+ # draw attention to important information. Common use cases include:
4
+ # - Notification badges on avatars.
5
+ # - Cart item counters.
6
+ # - "New" badges on features.
7
+ # - Status indicators on elements.
4
8
  #
5
- # @slot item The items to be rendered around the content. Allows multiple.
9
+ # By default, indicators are positioned in the top-right corner, but they can
10
+ # be positioned anywhere around the content using CSS classes.
6
11
  #
7
- # @loco_example Basic Usage
12
+ # @slot item+ [LocoMotion::BasicComponent] The items to be rendered around
13
+ # the content. Multiple items can be added and positioned independently.
14
+ #
15
+ # @loco_example Basic Badge Indicator
8
16
  # = daisy_indicator do |indicator|
9
17
  # - indicator.with_item do
10
- # = daisy_badge(title: "New!", css: "badge-accent")
18
+ # = daisy_badge(title: "8",
19
+ # css: "badge-secondary")
20
+ #
21
+ # = daisy_avatar(src: "avatar.jpg")
22
+ #
23
+ # @loco_example Multiple Indicators
24
+ # = daisy_indicator do |indicator|
25
+ # - indicator.with_item(css: "indicator-top indicator-start") do
26
+ # = daisy_badge(title: "New",
27
+ # css: "badge-accent")
28
+ #
29
+ # - indicator.with_item(css: "indicator-bottom indicator-end") do
30
+ # = daisy_badge(title: "Sale",
31
+ # css: "badge-secondary")
32
+ #
33
+ # = daisy_button(title: "View Item")
34
+ #
35
+ # @loco_example Custom Positioning
36
+ # = daisy_indicator do |indicator|
37
+ # - # Center of left edge
38
+ # - indicator.with_item(css: "indicator-middle indicator-start") do
39
+ # Online
11
40
  #
12
- # = daisy_button(title: "Checkout", left_icon: "shopping-cart")
41
+ # - # Center of right edge
42
+ # - indicator.with_item(css: "indicator-middle indicator-end") do
43
+ # Available
44
+ #
45
+ # .w-40.h-40.bg-base-200
13
46
  #
14
47
  class Daisy::Layout::IndicatorComponent < LocoMotion::BaseComponent
15
48
  renders_many :items, LocoMotion::BasicComponent.build(css: "indicator-item")
16
49
 
17
50
  #
18
- # Adds the `indicator` CSS to the component
51
+ # Creates a new Indicator component.
52
+ #
53
+ # @param kws [Hash] Keyword arguments for customizing the indicator.
54
+ #
55
+ # @option kws css [String] Additional CSS classes for styling. Common
56
+ # options include:
57
+ # - Spacing: `p-2`, `m-4`
58
+ # - Alignment: `inline-flex`, `inline-grid`
59
+ #
60
+ def initialize(**kws)
61
+ super
62
+ end
63
+
64
+ #
65
+ # Sets up the component's CSS classes.
19
66
  #
20
67
  def before_render
21
68
  add_css(:component, "indicator")
22
69
  end
23
70
 
24
71
  #
25
- # Renders the component, all of the items, and any user-provided content.
72
+ # Renders the component, all indicator items, and the main content.
26
73
  #
27
74
  def call
28
75
  part(:component) do
@@ -1,10 +1,81 @@
1
+ #
2
+ # The JoinComponent combines multiple elements into a cohesive group without
3
+ # gaps between them. Common use cases include:
4
+ # - Button groups for toolbars.
5
+ # - Input fields with prefix/suffix elements.
6
+ # - Segmented navigation controls.
7
+ # - Pagination controls.
8
+ #
9
+ # Note: Each joined item must include the `join-item` CSS class manually, as
10
+ # automatic application could cause rendering issues in complex scenarios.
11
+ #
12
+ # @slot item+ [LocoMotion::BaseComponent] The elements to be joined together.
13
+ # Each item should include the `join-item` CSS class.
14
+ #
15
+ # @loco_example Basic Button Group
16
+ # = daisy_join do |join|
17
+ # - join.with_item do
18
+ # = daisy_button(title: "Previous",
19
+ # css: "join-item")
20
+ # - join.with_item do
21
+ # = daisy_button(title: "Current",
22
+ # css: "join-item btn-active")
23
+ # - join.with_item do
24
+ # = daisy_button(title: "Next",
25
+ # css: "join-item")
26
+ #
27
+ # @loco_example Icon Button Group
28
+ # = daisy_join do |join|
29
+ # - join.with_item do
30
+ # = daisy_button(icon: "chevron-left",
31
+ # css: "join-item")
32
+ # - join.with_item do
33
+ # = daisy_button(icon: "home",
34
+ # css: "join-item")
35
+ # - join.with_item do
36
+ # = daisy_button(icon: "chevron-right",
37
+ # css: "join-item")
38
+ #
39
+ # @loco_example Vertical Join
40
+ # = daisy_join(css: "join-vertical") do |join|
41
+ # - join.with_item do
42
+ # = daisy_button(title: "Menu",
43
+ # css: "w-full join-item")
44
+ # - join.with_item do
45
+ # = daisy_button(title: "Settings",
46
+ # css: "w-full join-item")
47
+ # - join.with_item do
48
+ # = daisy_button(title: "Account",
49
+ # css: "w-full join-item")
50
+ #
1
51
  class Daisy::Layout::JoinComponent < LocoMotion::BaseComponent
2
52
  renders_many :items
3
53
 
54
+ #
55
+ # Creates a new Join component.
56
+ #
57
+ # @param kws [Hash] Keyword arguments for customizing the join.
58
+ #
59
+ # @option kws css [String] Additional CSS classes for styling. Common
60
+ # options include:
61
+ # - Direction: `join-vertical` for vertical stacking
62
+ # - Size: `min-w-32`, `w-full`
63
+ # - Spacing: `gap-0`, `gap-px` (if gaps are needed)
64
+ #
65
+ def initialize(**kws)
66
+ super
67
+ end
68
+
69
+ #
70
+ # Sets up the component's CSS classes.
71
+ #
4
72
  def before_render
5
73
  add_css(:component, "join")
6
74
  end
7
75
 
76
+ #
77
+ # Renders all joined items in sequence.
78
+ #
8
79
  def call
9
80
  part(:component) do
10
81
  items.each do |item|
@@ -1,8 +1,67 @@
1
+ #
2
+ # The StackComponent creates a 3D stacking effect by layering elements on top
3
+ # of each other. Common use cases include:
4
+ # - Notification cards or alerts.
5
+ # - Photo galleries with overlap.
6
+ # - Interactive card games.
7
+ # - Animated content transitions.
8
+ #
9
+ # The component automatically positions children in a stack, with each element
10
+ # appearing on top of the previous one. This creates depth and visual interest
11
+ # in your layouts.
12
+ #
13
+ # @loco_example Basic Card Stack
14
+ # = daisy_stack do
15
+ # = daisy_card(css: "bg-base-100/80 shadow") do
16
+ # Top Card
17
+ # = daisy_card(css: "bg-base-100/80 shadow") do
18
+ # Middle Card
19
+ # = daisy_card(css: "bg-base-100/80 shadow") do
20
+ # Bottom Card
21
+ #
22
+ # @loco_example Animated Stack
23
+ # = daisy_stack do
24
+ # = daisy_card(css: "bg-primary cursor-pointer",
25
+ # html: { onclick: "anime({
26
+ # targets: this,
27
+ # translateY: '-100%',
28
+ # opacity: 0,
29
+ # complete: (el) => el.remove()
30
+ # })" }) do
31
+ # Click to Remove
32
+ #
33
+ # @loco_example Image Stack
34
+ # = daisy_stack(css: "w-96") do
35
+ # %img{ src: "image1.jpg" }
36
+ # %img{ src: "image2.jpg" }
37
+ # %img{ src: "image3.jpg" }
38
+ #
1
39
  class Daisy::Layout::StackComponent < LocoMotion::BaseComponent
40
+ #
41
+ # Creates a new Stack component.
42
+ #
43
+ # @param kws [Hash] Keyword arguments for customizing the stack.
44
+ #
45
+ # @option kws css [String] Additional CSS classes for styling. Common
46
+ # options include:
47
+ # - Size: `w-96`, `h-64`
48
+ # - Spacing: `gap-2`, `space-y-4`
49
+ # - Position: `relative`, `absolute`
50
+ #
51
+ def initialize(**kws)
52
+ super
53
+ end
54
+
55
+ #
56
+ # Sets up the component's CSS classes.
57
+ #
2
58
  def before_render
3
59
  add_css(:component, "stack")
4
60
  end
5
61
 
62
+ #
63
+ # Renders the component and its stacked content.
64
+ #
6
65
  def call
7
66
  part(:component) { content }
8
67
  end
@@ -0,0 +1,78 @@
1
+ #
2
+ # The BrowserComponent creates a realistic browser window mockup, perfect for:
3
+ # - Showcasing web applications.
4
+ # - Creating website previews.
5
+ # - Demonstrating responsive designs.
6
+ # - Building marketing materials.
7
+ #
8
+ # The component includes an optional toolbar for URL input and browser
9
+ # controls, and a content area that can contain any content you wish to
10
+ # display.
11
+ #
12
+ # @slot toolbar [LocoMotion::BasicComponent] An optional toolbar section,
13
+ # typically containing a URL input field or navigation controls.
14
+ #
15
+ # @loco_example Basic Browser with URL
16
+ # = daisy_browser(css: "w-full border border-base-300") do |browser|
17
+ # - browser.with_toolbar do
18
+ # %input.input.input-bordered{
19
+ # placeholder: "https://example.com" }
20
+ #
21
+ # .border-t.border-base-300.p-4
22
+ # Your website content here
23
+ #
24
+ # @loco_example Styled Browser
25
+ # = daisy_browser(css: "bg-primary border-2") do |browser|
26
+ # - browser.with_toolbar do
27
+ # .flex.gap-2.px-4
28
+ # = daisy_button(icon: "chevron-left",
29
+ # css: "btn-circle btn-sm")
30
+ # = daisy_button(icon: "chevron-right",
31
+ # css: "btn-circle btn-sm")
32
+ # %input.input.input-sm.flex-1{
33
+ # placeholder: "Search..." }
34
+ #
35
+ # .bg-base-100.p-8.text-center
36
+ # Professional website mockup
37
+ #
38
+ # @loco_example Content-Only Browser
39
+ # = daisy_browser(css: "border shadow-lg") do
40
+ # .p-4
41
+ # Simple browser frame without toolbar
42
+ #
43
+ class Daisy::Mockup::BrowserComponent < LocoMotion::BaseComponent
44
+
45
+ renders_one :toolbar, LocoMotion::BasicComponent.build(css: "mockup-browser-toolbar")
46
+
47
+ #
48
+ # Creates a new Browser component.
49
+ #
50
+ # @option kws css [String] Additional CSS classes for styling. Common
51
+ # options include:
52
+ # - Size: `w-full`, `max-w-4xl`
53
+ # - Border: `border`, `border-2`, `border-primary`
54
+ # - Background: `bg-base-100`, `bg-primary`
55
+ # - Shadow: `shadow`, `shadow-lg`
56
+ #
57
+ def initialize(**kws)
58
+ super(**kws)
59
+ end
60
+
61
+ #
62
+ # Sets up the component's CSS classes.
63
+ #
64
+ def before_render
65
+ add_css(:component, "mockup-browser")
66
+ end
67
+
68
+ #
69
+ # Renders the toolbar (if present) and content.
70
+ #
71
+ def call
72
+ part(:component) do
73
+ concat(toolbar) if toolbar
74
+ concat(content)
75
+ end
76
+ end
77
+
78
+ end
@@ -0,0 +1,144 @@
1
+ #
2
+ # The CodeComponent creates stylized code blocks for displaying code snippets,
3
+ # terminal output, or any text that benefits from monospace formatting.
4
+ # Common use cases include:
5
+ # - Displaying code examples.
6
+ # - Showing terminal commands and output.
7
+ # - Highlighting important configuration settings.
8
+ # - Creating interactive tutorials.
9
+ #
10
+ # The component supports line prefixes (e.g., for line numbers or command
11
+ # prompts), syntax highlighting via CSS classes, and multi-line code blocks.
12
+ #
13
+ # @slot lines+ [Daisy::Mockup::CodeLineComponent] Individual lines of code,
14
+ # each with optional prefix and styling.
15
+ #
16
+ # @loco_example Basic Command with Prefix
17
+ # = daisy_code(prefix: "$") do
18
+ # yarn add @profoundry-us/loco_motion
19
+ #
20
+ # @loco_example Multi-line Terminal Output
21
+ # = daisy_code do |code|
22
+ # - code.with_line(prefix: "$") do
23
+ # npm install
24
+ # - code.with_line(prefix: ">", css: "text-warning") do
25
+ # Installing packages...
26
+ # - code.with_line(prefix: ">", css: "text-success") do
27
+ # Done in 2.45s
28
+ #
29
+ # @loco_example Code Block with Highlighting
30
+ # = daisy_code do |code|
31
+ # - code.with_line(prefix: "1") do
32
+ # def hello_world
33
+ # - code.with_line(prefix: "2", css: "bg-warning") do
34
+ # puts "Hello, world!"
35
+ # - code.with_line(prefix: "3") do
36
+ # end
37
+ #
38
+ # @loco_example Plain Code Block
39
+ # = daisy_code do
40
+ # :plain
41
+ # class Example
42
+ # def initialize
43
+ # @value = 42
44
+ # end
45
+ # end
46
+ #
47
+ class Daisy::Mockup::CodeComponent < LocoMotion::BaseComponent
48
+
49
+ #
50
+ # A component for rendering individual lines within a code block.
51
+ #
52
+ # @part code The code content for this line.
53
+ #
54
+ class Daisy::Mockup::CodeLineComponent < LocoMotion::BaseComponent
55
+ define_parts :code
56
+
57
+ #
58
+ # Creates a new code line.
59
+ #
60
+ # @option kws prefix [String] Optional prefix for the line (e.g., "$",
61
+ # ">", or line numbers).
62
+ # @option kws css [String] Additional CSS classes for styling the line.
63
+ #
64
+ def initialize(**kws)
65
+ super(**kws)
66
+
67
+ @prefix = config_option(:prefix)
68
+ end
69
+
70
+ #
71
+ # Sets up the component's HTML tags and attributes.
72
+ #
73
+ def before_render
74
+ set_tag_name(:component, :pre)
75
+ set_tag_name(:code, :code)
76
+
77
+ add_html(:component, { "data-prefix": @prefix }) if @prefix
78
+ end
79
+
80
+ #
81
+ # Renders the line with its code content.
82
+ #
83
+ def call
84
+ part(:component) do
85
+ part(:code) do
86
+ content
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ define_parts :pre, :code
93
+ renders_many :lines, Daisy::Mockup::CodeLineComponent
94
+
95
+ #
96
+ # Creates a new code block component.
97
+ #
98
+ # @option kws prefix [String] Optional prefix for all lines (if not using
99
+ # individual line prefixes).
100
+ # @option kws css [String] Additional CSS classes for styling. Common
101
+ # options include:
102
+ # - Size: `w-full`, `max-w-3xl`
103
+ # - Background: `bg-base-300`, `bg-neutral`
104
+ # - Text: `text-sm`, `text-base-content`
105
+ #
106
+ def initialize(**kws)
107
+ super(**kws)
108
+
109
+ @prefix = config_option(:prefix)
110
+ end
111
+
112
+ #
113
+ # Sets up the component's CSS classes and HTML attributes.
114
+ #
115
+ def before_render
116
+ add_css(:component, "mockup-code")
117
+
118
+ set_tag_name(:pre, :pre)
119
+ set_tag_name(:code, :code)
120
+
121
+ add_html(:pre, { "data-prefix": @prefix }) if @prefix
122
+
123
+ # If the prefix is blank, add some left margin and hide the :before
124
+ # pseudo-element used for the prefix
125
+ add_css(:pre, "before:!hidden ml-6") if @prefix.blank?
126
+ end
127
+
128
+ #
129
+ # Renders the code block with its lines or direct content.
130
+ #
131
+ def call
132
+ part(:component) do
133
+ if lines.any?
134
+ lines.each { |line| concat(line) }
135
+ else
136
+ part(:pre) do
137
+ part(:code) do
138
+ content
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end