element_component 0.5.0 → 0.7.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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/AGENTS.md +126 -0
  3. data/README.md +440 -25
  4. data/examples/alert_example.rb +97 -0
  5. data/examples/badge_example.rb +63 -0
  6. data/examples/breadcrumb_example.rb +36 -0
  7. data/examples/button_example.rb +86 -0
  8. data/examples/button_group_example.rb +55 -0
  9. data/examples/card_example.rb +62 -0
  10. data/examples/carousel_example.rb +95 -0
  11. data/examples/close_button_example.rb +40 -0
  12. data/examples/dropdown_example.rb +123 -0
  13. data/examples/list_group_example.rb +60 -0
  14. data/examples/modal_example.rb +120 -0
  15. data/examples/nav_example.rb +75 -0
  16. data/examples/navbar_example.rb +96 -0
  17. data/examples/pagination_example.rb +47 -0
  18. data/examples/progress_example.rb +54 -0
  19. data/examples/spinner_example.rb +49 -0
  20. data/examples/table_example.rb +41 -0
  21. data/lib/element_component/components/alert/close_button.rb +17 -0
  22. data/lib/element_component/components/alert/heading.rb +14 -0
  23. data/lib/element_component/components/alert/link.rb +15 -0
  24. data/lib/element_component/components/alert.rb +25 -0
  25. data/lib/element_component/components/badge.rb +18 -0
  26. data/lib/element_component/components/breadcrumb/item.rb +29 -0
  27. data/lib/element_component/components/breadcrumb.rb +26 -0
  28. data/lib/element_component/components/button.rb +25 -0
  29. data/lib/element_component/components/button_group.rb +18 -0
  30. data/lib/element_component/components/card/body.rb +14 -0
  31. data/lib/element_component/components/card/footer.rb +14 -0
  32. data/lib/element_component/components/card/header.rb +14 -0
  33. data/lib/element_component/components/card/image.rb +17 -0
  34. data/lib/element_component/components/card/text.rb +14 -0
  35. data/lib/element_component/components/card/title.rb +14 -0
  36. data/lib/element_component/components/card.rb +21 -0
  37. data/lib/element_component/components/carousel/caption.rb +14 -0
  38. data/lib/element_component/components/carousel/item.rb +16 -0
  39. data/lib/element_component/components/carousel.rb +70 -0
  40. data/lib/element_component/components/close_button.rb +17 -0
  41. data/lib/element_component/components/dropdown/divider.rb +20 -0
  42. data/lib/element_component/components/dropdown/header.rb +22 -0
  43. data/lib/element_component/components/dropdown/item.rb +33 -0
  44. data/lib/element_component/components/dropdown/menu.rb +15 -0
  45. data/lib/element_component/components/dropdown.rb +43 -0
  46. data/lib/element_component/components/list_group/item.rb +23 -0
  47. data/lib/element_component/components/list_group.rb +18 -0
  48. data/lib/element_component/components/modal/body.rb +14 -0
  49. data/lib/element_component/components/modal/content.rb +14 -0
  50. data/lib/element_component/components/modal/dialog.rb +21 -0
  51. data/lib/element_component/components/modal/footer.rb +14 -0
  52. data/lib/element_component/components/modal/header.rb +16 -0
  53. data/lib/element_component/components/modal/title.rb +14 -0
  54. data/lib/element_component/components/modal.rb +42 -0
  55. data/lib/element_component/components/nav/item.rb +14 -0
  56. data/lib/element_component/components/nav/link.rb +18 -0
  57. data/lib/element_component/components/nav.rb +23 -0
  58. data/lib/element_component/components/navbar/brand.rb +15 -0
  59. data/lib/element_component/components/navbar/collapse.rb +16 -0
  60. data/lib/element_component/components/navbar/nav.rb +14 -0
  61. data/lib/element_component/components/navbar/toggler.rb +22 -0
  62. data/lib/element_component/components/navbar.rb +51 -0
  63. data/lib/element_component/components/pagination/item.rb +27 -0
  64. data/lib/element_component/components/pagination.rb +33 -0
  65. data/lib/element_component/components/progress/bar.rb +24 -0
  66. data/lib/element_component/components/progress.rb +17 -0
  67. data/lib/element_component/components/spinner.rb +19 -0
  68. data/lib/element_component/components/table.rb +21 -0
  69. data/lib/element_component/components.rb +24 -0
  70. data/lib/element_component/element.rb +21 -7
  71. data/lib/element_component/version.rb +3 -1
  72. data/lib/element_component.rb +3 -1
  73. metadata +68 -1
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../lib/element_component"
4
+
5
+ # =============================================================================
6
+ # Basic Alert
7
+ # =============================================================================
8
+ alert = ElementComponent::Components::Alert.new(variant: :success)
9
+ alert.add_content("Operation completed successfully!")
10
+ puts "=== Basic Alert ==="
11
+ puts alert.render
12
+ puts
13
+
14
+ # =============================================================================
15
+ # All Variants
16
+ # =============================================================================
17
+ puts "=== All Alert Contexts ==="
18
+ ElementComponent::Components::Alert::VALID_VARIANTS.each do |variant|
19
+ alert = ElementComponent::Components::Alert.new(variant: variant)
20
+ alert.add_content("#{variant.capitalize} alert message here.")
21
+ puts alert.render
22
+ end
23
+ puts
24
+
25
+ # =============================================================================
26
+ # Dismissible Alert (use block DSL so close button is always last)
27
+ # =============================================================================
28
+ alert = ElementComponent::Components::Alert.new(variant: :warning, dismissible: true) do
29
+ add_content("This alert can be dismissed.")
30
+ end
31
+ puts "=== Dismissible Alert ==="
32
+ puts alert.render
33
+ puts
34
+
35
+ # =============================================================================
36
+ # Alert with Custom Attributes
37
+ # =============================================================================
38
+ alert = ElementComponent::Components::Alert.new(
39
+ variant: :primary,
40
+ id: "main-alert",
41
+ style: "margin-top: 20px;"
42
+ )
43
+ alert.add_content("This alert has a custom ID and inline style.")
44
+ puts "=== Alert with Custom Attributes ==="
45
+ puts alert.render
46
+ puts
47
+
48
+ # =============================================================================
49
+ # Alert with Heading and Link (block DSL)
50
+ # =============================================================================
51
+ alert = ElementComponent::Components::Alert.new(variant: :info) do
52
+ add_content(ElementComponent::Components::AlertHeading.new.tap { |h| h.add_content("Information") })
53
+ add_content("This is an important notice. ")
54
+ add_content(ElementComponent::Components::AlertLink.new(href: "/details").tap { |l| l.add_content("View details") })
55
+ end
56
+ puts "=== Alert with Heading and Link ==="
57
+ puts alert.render
58
+ puts
59
+
60
+ # =============================================================================
61
+ # Dismissible Alert with Heading and Link
62
+ # =============================================================================
63
+ alert = ElementComponent::Components::Alert.new(variant: :danger, dismissible: true) do
64
+ add_content(ElementComponent::Components::AlertHeading.new.tap { |h| h.add_content("Error!") })
65
+ add_content("Something went wrong. ")
66
+ add_content(ElementComponent::Components::AlertLink.new(href: "/support").tap do |l|
67
+ l.add_content("Contact support")
68
+ end)
69
+ end
70
+ puts "=== Dismissible Alert with Heading and Link ==="
71
+ puts alert.render
72
+ puts
73
+
74
+ # =============================================================================
75
+ # Chained API Usage
76
+ # =============================================================================
77
+ alert = ElementComponent::Components::Alert.new(variant: :secondary)
78
+ .add_content("This alert was built using chained calls.")
79
+ puts "=== Chained API ==="
80
+ puts alert.render
81
+ puts
82
+
83
+ # =============================================================================
84
+ # Using Sub-Components Independently
85
+ # =============================================================================
86
+ heading = ElementComponent::Components::AlertHeading.new
87
+ heading.add_content("Standalone Heading")
88
+
89
+ link = ElementComponent::Components::AlertLink.new(href: "https://example.com")
90
+ link.add_content("Standalone Link")
91
+
92
+ close_btn = ElementComponent::Components::AlertCloseButton.new
93
+
94
+ puts "=== Sub-Components Rendered Independently ==="
95
+ puts heading.render
96
+ puts link.render
97
+ puts close_btn.render
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../lib/element_component"
4
+
5
+ # =============================================================================
6
+ # Basic Badge
7
+ # =============================================================================
8
+ badge = ElementComponent::Components::Badge.new(variant: :primary)
9
+ badge.add_content("New")
10
+ puts "=== Basic Badge ==="
11
+ puts badge.render
12
+ puts
13
+
14
+ # =============================================================================
15
+ # Pill Badge
16
+ # =============================================================================
17
+ badge = ElementComponent::Components::Badge.new(variant: :danger, pill: true)
18
+ badge.add_content("99+")
19
+ puts "=== Pill Badge ==="
20
+ puts badge.render
21
+ puts
22
+
23
+ # =============================================================================
24
+ # All Contexts
25
+ # =============================================================================
26
+ puts "=== All Badge Variants ==="
27
+ ElementComponent::Components::Badge::VALID_VARIANTS.each do |variant|
28
+ badge = ElementComponent::Components::Badge.new(variant: variant)
29
+ badge.add_content(variant.to_s.capitalize)
30
+ puts badge.render
31
+ end
32
+ puts
33
+
34
+ # =============================================================================
35
+ # Badge with Block
36
+ # =============================================================================
37
+ badge = ElementComponent::Components::Badge.new(variant: :success) do
38
+ add_content("Completed")
39
+ end
40
+ puts "=== Badge with Block ==="
41
+ puts badge.render
42
+ puts
43
+
44
+ # =============================================================================
45
+ # Chained API
46
+ # =============================================================================
47
+ badge = ElementComponent::Components::Badge.new(variant: :warning)
48
+ .add_content("Warning")
49
+ puts "=== Chained API ==="
50
+ puts badge.render
51
+ puts
52
+
53
+ # =============================================================================
54
+ # Badge with Custom Attributes
55
+ # =============================================================================
56
+ badge = ElementComponent::Components::Badge.new(
57
+ variant: :info,
58
+ id: "badge-1",
59
+ style: "font-size: 1.2em;"
60
+ )
61
+ badge.add_content("Custom")
62
+ puts "=== Badge with Custom Attributes ==="
63
+ puts badge.render
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../lib/element_component"
4
+
5
+ # =============================================================================
6
+ # Basic Breadcrumb
7
+ # =============================================================================
8
+ breadcrumb = ElementComponent::Components::Breadcrumb.new do
9
+ add_content(ElementComponent::Components::BreadcrumbItem.new(href: "/") { add_content("Home") })
10
+ add_content(ElementComponent::Components::BreadcrumbItem.new(href: "/library") { add_content("Library") })
11
+ add_content(ElementComponent::Components::BreadcrumbItem.new(active: true) { add_content("Data") })
12
+ end
13
+ puts "=== Basic Breadcrumb ==="
14
+ puts breadcrumb.render
15
+ puts
16
+
17
+ # =============================================================================
18
+ # Breadcrumb with Two Items
19
+ # =============================================================================
20
+ breadcrumb = ElementComponent::Components::Breadcrumb.new do
21
+ add_content(ElementComponent::Components::BreadcrumbItem.new(href: "/") { add_content("Home") })
22
+ add_content(ElementComponent::Components::BreadcrumbItem.new(active: true) { add_content("Current Page") })
23
+ end
24
+ puts "=== Two-Item Breadcrumb ==="
25
+ puts breadcrumb.render
26
+ puts
27
+
28
+ # =============================================================================
29
+ # Breadcrumb with Custom Class
30
+ # =============================================================================
31
+ breadcrumb = ElementComponent::Components::Breadcrumb.new(class: "custom-breadcrumb") do
32
+ add_content(ElementComponent::Components::BreadcrumbItem.new(href: "/") { add_content("Home") })
33
+ add_content(ElementComponent::Components::BreadcrumbItem.new(active: true) { add_content("Active") })
34
+ end
35
+ puts "=== Breadcrumb with Custom Class ==="
36
+ puts breadcrumb.render
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../lib/element_component"
4
+
5
+ # =============================================================================
6
+ # Basic Button
7
+ # =============================================================================
8
+ btn = ElementComponent::Components::Button.new(variant: :primary)
9
+ btn.add_content("Click Me")
10
+ puts "=== Basic Button ==="
11
+ puts btn.render
12
+ puts
13
+
14
+ # =============================================================================
15
+ # Outline Button
16
+ # =============================================================================
17
+ btn = ElementComponent::Components::Button.new(variant: :danger, outline: true)
18
+ btn.add_content("Delete")
19
+ puts "=== Outline Button ==="
20
+ puts btn.render
21
+ puts
22
+
23
+ # =============================================================================
24
+ # Size Variants
25
+ # =============================================================================
26
+ btn_lg = ElementComponent::Components::Button.new(variant: :success, size: :lg)
27
+ btn_lg.add_content("Large Button")
28
+
29
+ btn_sm = ElementComponent::Components::Button.new(variant: :secondary, size: :sm)
30
+ btn_sm.add_content("Small Button")
31
+
32
+ puts "=== Size Variants ==="
33
+ puts btn_lg.render
34
+ puts btn_sm.render
35
+ puts
36
+
37
+ # =============================================================================
38
+ # Button as Link
39
+ # =============================================================================
40
+ btn = ElementComponent::Components::Button.new(variant: :primary, href: "/home")
41
+ btn.add_content("Home")
42
+ puts "=== Button as Link ==="
43
+ puts btn.render
44
+ puts
45
+
46
+ # =============================================================================
47
+ # All Contexts
48
+ # =============================================================================
49
+ puts "=== All Button Variants ==="
50
+ ElementComponent::Components::Button::VALID_VARIANTS.each do |variant|
51
+ btn = ElementComponent::Components::Button.new(variant: variant)
52
+ btn.add_content(variant.to_s.capitalize)
53
+ puts btn.render
54
+ end
55
+ puts
56
+
57
+ # =============================================================================
58
+ # Button with Block
59
+ # =============================================================================
60
+ btn = ElementComponent::Components::Button.new(variant: :info) do
61
+ add_content("Info Button")
62
+ end
63
+ puts "=== Button with Block ==="
64
+ puts btn.render
65
+ puts
66
+
67
+ # =============================================================================
68
+ # Chained API
69
+ # =============================================================================
70
+ btn = ElementComponent::Components::Button.new(variant: :warning)
71
+ .add_content("Caution")
72
+ puts "=== Chained API ==="
73
+ puts btn.render
74
+ puts
75
+
76
+ # =============================================================================
77
+ # Button with Custom Attributes
78
+ # =============================================================================
79
+ btn = ElementComponent::Components::Button.new(
80
+ variant: :dark,
81
+ id: "btn-submit",
82
+ data: { action: "submit" }
83
+ )
84
+ btn.add_content("Submit")
85
+ puts "=== Button with Custom Attributes ==="
86
+ puts btn.render
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../lib/element_component"
4
+
5
+ # =============================================================================
6
+ # Basic Button Group
7
+ # =============================================================================
8
+ group = ElementComponent::Components::ButtonGroup.new
9
+ group.add_content(
10
+ ElementComponent::Components::Button.new(variant: :primary).add_content("Left")
11
+ )
12
+ group.add_content(
13
+ ElementComponent::Components::Button.new(variant: :primary).add_content("Middle")
14
+ )
15
+ group.add_content(
16
+ ElementComponent::Components::Button.new(variant: :primary).add_content("Right")
17
+ )
18
+ puts "=== Basic Button Group ==="
19
+ puts group.render
20
+ puts
21
+
22
+ # =============================================================================
23
+ # Vertical Button Group
24
+ # =============================================================================
25
+ group = ElementComponent::Components::ButtonGroup.new(vertical: true)
26
+ group.add_content(
27
+ ElementComponent::Components::Button.new(variant: :secondary).add_content("Top")
28
+ )
29
+ group.add_content(
30
+ ElementComponent::Components::Button.new(variant: :secondary).add_content("Bottom")
31
+ )
32
+ puts "=== Vertical Button Group ==="
33
+ puts group.render
34
+ puts
35
+
36
+ # =============================================================================
37
+ # Button Group with Size
38
+ # =============================================================================
39
+ group = ElementComponent::Components::ButtonGroup.new(size: :sm) do
40
+ add_content(ElementComponent::Components::Button.new(variant: :success) { add_content("Save") })
41
+ add_content(ElementComponent::Components::Button.new(variant: :danger) { add_content("Delete") })
42
+ end
43
+ puts "=== Small Button Group ==="
44
+ puts group.render
45
+ puts
46
+
47
+ # =============================================================================
48
+ # Chained API
49
+ # =============================================================================
50
+ group = ElementComponent::Components::ButtonGroup.new(class: "my-group")
51
+ group.add_content(
52
+ ElementComponent::Components::Button.new(variant: :info).add_content("Action")
53
+ )
54
+ puts "=== Button Group with Custom Class ==="
55
+ puts group.render
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../lib/element_component"
4
+
5
+ # =============================================================================
6
+ # Basic Card
7
+ # =============================================================================
8
+ card = ElementComponent::Components::Card.new
9
+ card.add_content("Simple card content")
10
+ puts "=== Basic Card ==="
11
+ puts card.render
12
+ puts
13
+
14
+ # =============================================================================
15
+ # Card with Header, Body, and Footer
16
+ # =============================================================================
17
+ card = ElementComponent::Components::Card.new do
18
+ add_content(ElementComponent::Components::CardHeader.new { add_content("Header") })
19
+ add_content(ElementComponent::Components::CardBody.new { add_content("Body content here") })
20
+ add_content(ElementComponent::Components::CardFooter.new { add_content("Footer") })
21
+ end
22
+ puts "=== Card with Header, Body, Footer ==="
23
+ puts card.render
24
+ puts
25
+
26
+ # =============================================================================
27
+ # Card with Title and Text
28
+ # =============================================================================
29
+ card = ElementComponent::Components::Card.new do
30
+ add_content(ElementComponent::Components::CardBody.new do
31
+ add_content(ElementComponent::Components::CardTitle.new { add_content("Card Title") })
32
+ add_content(ElementComponent::Components::CardText.new { add_content("Some quick example text.") })
33
+ end)
34
+ end
35
+ puts "=== Card with Title and Text ==="
36
+ puts card.render
37
+ puts
38
+
39
+ # =============================================================================
40
+ # Card with Image
41
+ # =============================================================================
42
+ card = ElementComponent::Components::Card.new do
43
+ add_content(ElementComponent::Components::CardImage.new(src: "image.jpg", top: true))
44
+ add_content(ElementComponent::Components::CardBody.new do
45
+ add_content(ElementComponent::Components::CardTitle.new { add_content("Image Card") })
46
+ add_content(ElementComponent::Components::CardText.new { add_content("Card with an image on top.") })
47
+ end)
48
+ end
49
+ puts "=== Card with Image ==="
50
+ puts card.render
51
+ puts
52
+
53
+ # =============================================================================
54
+ # Chained API
55
+ # =============================================================================
56
+ card = ElementComponent::Components::Card.new
57
+ card.add_content(
58
+ ElementComponent::Components::CardBody.new
59
+ .add_content("Chained content")
60
+ )
61
+ puts "=== Chained API ==="
62
+ puts card.render
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../lib/element_component"
4
+
5
+ # =============================================================================
6
+ # Basic Carousel
7
+ # =============================================================================
8
+ carousel = ElementComponent::Components::Carousel.new(id: "basicCarousel") do
9
+ add_content(ElementComponent::Components::CarouselItem.new(active: true) do
10
+ add_content(%(<img src="slide1.jpg" class="d-block w-100" alt="Slide 1">))
11
+ end)
12
+ add_content(ElementComponent::Components::CarouselItem.new do
13
+ add_content(%(<img src="slide2.jpg" class="d-block w-100" alt="Slide 2">))
14
+ end)
15
+ end
16
+ puts "=== Basic Carousel ==="
17
+ puts carousel.render
18
+ puts
19
+
20
+ # =============================================================================
21
+ # Carousel with Captions
22
+ # =============================================================================
23
+ carousel = ElementComponent::Components::Carousel.new(id: "captionCarousel") do
24
+ add_content(ElementComponent::Components::CarouselItem.new(active: true) do
25
+ add_content(%(<img src="hero.jpg" class="d-block w-100" alt="Hero">))
26
+ add_content(ElementComponent::Components::CarouselCaption.new do
27
+ add_content(%(<h5>First slide</h5><p>Some description here.</p>))
28
+ end)
29
+ end)
30
+ add_content(ElementComponent::Components::CarouselItem.new do
31
+ add_content(%(<img src="hero2.jpg" class="d-block w-100" alt="Hero 2">))
32
+ add_content(ElementComponent::Components::CarouselCaption.new do
33
+ add_content(%(<h5>Second slide</h5><p>Another description.</p>))
34
+ end)
35
+ end)
36
+ end
37
+ puts "=== Carousel with Captions ==="
38
+ puts carousel.render
39
+ puts
40
+
41
+ # =============================================================================
42
+ # Fade Carousel
43
+ # =============================================================================
44
+ carousel = ElementComponent::Components::Carousel.new(id: "fadeCarousel", fade: true) do
45
+ add_content(ElementComponent::Components::CarouselItem.new(active: true) { add_content("Slide 1") })
46
+ add_content(ElementComponent::Components::CarouselItem.new { add_content("Slide 2") })
47
+ end
48
+ puts "=== Fade Carousel ==="
49
+ puts carousel.render
50
+ puts
51
+
52
+ # =============================================================================
53
+ # Carousel Without Indicators
54
+ # =============================================================================
55
+ carousel = ElementComponent::Components::Carousel.new(id: "noIndicators", indicators: false) do
56
+ add_content(ElementComponent::Components::CarouselItem.new(active: true) { add_content("Slide 1") })
57
+ end
58
+ puts "=== Carousel Without Indicators ==="
59
+ puts carousel.render
60
+ puts
61
+
62
+ # =============================================================================
63
+ # Carousel Without Controls
64
+ # =============================================================================
65
+ carousel = ElementComponent::Components::Carousel.new(id: "noControls", controls: false) do
66
+ add_content(ElementComponent::Components::CarouselItem.new(active: true) { add_content("Slide 1") })
67
+ end
68
+ puts "=== Carousel Without Controls ==="
69
+ puts carousel.render
70
+ puts
71
+
72
+ # =============================================================================
73
+ # Custom Interval
74
+ # =============================================================================
75
+ carousel = ElementComponent::Components::Carousel.new(id: "intervalCarousel") do
76
+ add_content(ElementComponent::Components::CarouselItem.new(active: true, interval: 5000) { add_content("Slide 1") })
77
+ add_content(ElementComponent::Components::CarouselItem.new(interval: 2000) { add_content("Slide 2") })
78
+ end
79
+ puts "=== Carousel with Custom Interval ==="
80
+ puts carousel.render
81
+ puts
82
+
83
+ # =============================================================================
84
+ # Sub-Components Rendered Independently
85
+ # =============================================================================
86
+ puts "=== CarouselItem ==="
87
+ puts ElementComponent::Components::CarouselItem.new.render
88
+ puts
89
+
90
+ puts "=== CarouselItem Active ==="
91
+ puts ElementComponent::Components::CarouselItem.new(active: true).render
92
+ puts
93
+
94
+ puts "=== CarouselCaption ==="
95
+ puts ElementComponent::Components::CarouselCaption.new.render
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../lib/element_component"
4
+
5
+ # =============================================================================
6
+ # Basic Close Button
7
+ # =============================================================================
8
+ btn = ElementComponent::Components::CloseButton.new
9
+ puts "=== Basic Close Button ==="
10
+ puts btn.render
11
+ puts
12
+
13
+ # =============================================================================
14
+ # Disabled Close Button
15
+ # =============================================================================
16
+ btn = ElementComponent::Components::CloseButton.new(disabled: true)
17
+ puts "=== Disabled Close Button ==="
18
+ puts btn.render
19
+ puts
20
+
21
+ # =============================================================================
22
+ # Close Button with Custom Attributes
23
+ # =============================================================================
24
+ btn = ElementComponent::Components::CloseButton.new(
25
+ class: "custom-close",
26
+ id: "close-btn-1",
27
+ data: { dismiss: "modal" }
28
+ )
29
+ puts "=== Close Button with Custom Attributes ==="
30
+ puts btn.render
31
+ puts
32
+
33
+ # =============================================================================
34
+ # Close Button Inside an Alert (simulated)
35
+ # =============================================================================
36
+ alert = ElementComponent::Components::Alert.new(variant: :warning, dismissible: true) do
37
+ add_content("This alert has a close button.")
38
+ end
39
+ puts "=== Close Button Inside Alert ==="
40
+ puts alert.render
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../lib/element_component"
4
+
5
+ # =============================================================================
6
+ # Basic Dropdown
7
+ # =============================================================================
8
+ dropdown = ElementComponent::Components::Dropdown.new do
9
+ add_content(
10
+ ElementComponent::Element.new("button",
11
+ class: "btn btn-secondary dropdown-toggle",
12
+ type: "button",
13
+ "data-bs-toggle": "dropdown",
14
+ "aria-expanded": "false") do
15
+ add_content("Dropdown")
16
+ end
17
+ )
18
+ add_content(
19
+ ElementComponent::Components::DropdownMenu.new do
20
+ add_content(ElementComponent::Components::DropdownItem.new { add_content("Action") })
21
+ add_content(ElementComponent::Components::DropdownItem.new { add_content("Another action") })
22
+ add_content(ElementComponent::Components::DropdownDivider.new)
23
+ add_content(ElementComponent::Components::DropdownItem.new { add_content("Something else") })
24
+ end
25
+ )
26
+ end
27
+ puts "=== Basic Dropdown ==="
28
+ puts dropdown.render
29
+ puts
30
+
31
+ # =============================================================================
32
+ # Dropdown with Active and Disabled Items
33
+ # =============================================================================
34
+ dropdown = ElementComponent::Components::Dropdown.new do
35
+ add_content(
36
+ ElementComponent::Element.new("button",
37
+ class: "btn btn-primary dropdown-toggle",
38
+ type: "button",
39
+ "data-bs-toggle": "dropdown",
40
+ "aria-expanded": "false") do
41
+ add_content("Menu")
42
+ end
43
+ )
44
+ add_content(
45
+ ElementComponent::Components::DropdownMenu.new do
46
+ add_content(ElementComponent::Components::DropdownHeader.new { add_content("Section 1") })
47
+ add_content(ElementComponent::Components::DropdownItem.new { add_content("Regular item") })
48
+ add_content(ElementComponent::Components::DropdownItem.new(active: true) { add_content("Active item") })
49
+ add_content(ElementComponent::Components::DropdownItem.new(disabled: true) { add_content("Disabled item") })
50
+ end
51
+ )
52
+ end
53
+ puts "=== Dropdown with States ==="
54
+ puts dropdown.render
55
+ puts
56
+
57
+ # =============================================================================
58
+ # Dropdown Type Button Items
59
+ # =============================================================================
60
+ dropdown = ElementComponent::Components::Dropdown.new do
61
+ add_content(
62
+ ElementComponent::Element.new("button",
63
+ class: "btn btn-success dropdown-toggle",
64
+ type: "button",
65
+ "data-bs-toggle": "dropdown",
66
+ "aria-expanded": "false") do
67
+ add_content("Actions")
68
+ end
69
+ )
70
+ add_content(
71
+ ElementComponent::Components::DropdownMenu.new do
72
+ add_content(ElementComponent::Components::DropdownItem.new(type: :button) { add_content("Save") })
73
+ add_content(ElementComponent::Components::DropdownItem.new(type: :button) { add_content("Delete") })
74
+ end
75
+ )
76
+ end
77
+ puts "=== Dropdown with Button Items ==="
78
+ puts dropdown.render
79
+ puts
80
+
81
+ # =============================================================================
82
+ # Dropup Direction
83
+ # =============================================================================
84
+ dropdown = ElementComponent::Components::Dropdown.new(direction: :dropup) do
85
+ add_content(
86
+ ElementComponent::Element.new("button",
87
+ class: "btn btn-warning dropdown-toggle",
88
+ type: "button",
89
+ "data-bs-toggle": "dropdown",
90
+ "aria-expanded": "false") do
91
+ add_content("Up")
92
+ end
93
+ )
94
+ add_content(
95
+ ElementComponent::Components::DropdownMenu.new do
96
+ add_content(ElementComponent::Components::DropdownItem.new { add_content("Item 1") })
97
+ add_content(ElementComponent::Components::DropdownItem.new { add_content("Item 2") })
98
+ end
99
+ )
100
+ end
101
+ puts "=== Dropup ==="
102
+ puts dropdown.render
103
+ puts
104
+
105
+ # =============================================================================
106
+ # Sub-Components Rendered Independently
107
+ # =============================================================================
108
+ puts "=== DropdownMenu ==="
109
+ puts ElementComponent::Components::DropdownMenu.new.render
110
+ puts
111
+
112
+ puts "=== DropdownItem ==="
113
+ dropdown_item = ElementComponent::Components::DropdownItem.new { add_content("Item") }
114
+ puts dropdown_item.render
115
+ puts
116
+
117
+ puts "=== DropdownDivider ==="
118
+ puts ElementComponent::Components::DropdownDivider.new.render
119
+ puts
120
+
121
+ puts "=== DropdownHeader ==="
122
+ dropdown_header = ElementComponent::Components::DropdownHeader.new { add_content("Header") }
123
+ puts dropdown_header.render