element_component 0.6.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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/AGENTS.md +3 -3
  3. data/README.md +339 -32
  4. data/examples/alert_example.rb +10 -10
  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.rb +3 -3
  22. data/lib/element_component/components/badge.rb +18 -0
  23. data/lib/element_component/components/breadcrumb/item.rb +29 -0
  24. data/lib/element_component/components/breadcrumb.rb +26 -0
  25. data/lib/element_component/components/button.rb +25 -0
  26. data/lib/element_component/components/button_group.rb +18 -0
  27. data/lib/element_component/components/card/body.rb +14 -0
  28. data/lib/element_component/components/card/footer.rb +14 -0
  29. data/lib/element_component/components/card/header.rb +14 -0
  30. data/lib/element_component/components/card/image.rb +17 -0
  31. data/lib/element_component/components/card/text.rb +14 -0
  32. data/lib/element_component/components/card/title.rb +14 -0
  33. data/lib/element_component/components/card.rb +21 -0
  34. data/lib/element_component/components/carousel/caption.rb +14 -0
  35. data/lib/element_component/components/carousel/item.rb +16 -0
  36. data/lib/element_component/components/carousel.rb +70 -0
  37. data/lib/element_component/components/close_button.rb +17 -0
  38. data/lib/element_component/components/dropdown/divider.rb +20 -0
  39. data/lib/element_component/components/dropdown/header.rb +22 -0
  40. data/lib/element_component/components/dropdown/item.rb +33 -0
  41. data/lib/element_component/components/dropdown/menu.rb +15 -0
  42. data/lib/element_component/components/dropdown.rb +43 -0
  43. data/lib/element_component/components/list_group/item.rb +23 -0
  44. data/lib/element_component/components/list_group.rb +18 -0
  45. data/lib/element_component/components/modal/body.rb +14 -0
  46. data/lib/element_component/components/modal/content.rb +14 -0
  47. data/lib/element_component/components/modal/dialog.rb +21 -0
  48. data/lib/element_component/components/modal/footer.rb +14 -0
  49. data/lib/element_component/components/modal/header.rb +16 -0
  50. data/lib/element_component/components/modal/title.rb +14 -0
  51. data/lib/element_component/components/modal.rb +42 -0
  52. data/lib/element_component/components/nav/item.rb +14 -0
  53. data/lib/element_component/components/nav/link.rb +18 -0
  54. data/lib/element_component/components/nav.rb +23 -0
  55. data/lib/element_component/components/navbar/brand.rb +15 -0
  56. data/lib/element_component/components/navbar/collapse.rb +16 -0
  57. data/lib/element_component/components/navbar/nav.rb +14 -0
  58. data/lib/element_component/components/navbar/toggler.rb +22 -0
  59. data/lib/element_component/components/navbar.rb +51 -0
  60. data/lib/element_component/components/pagination/item.rb +27 -0
  61. data/lib/element_component/components/pagination.rb +33 -0
  62. data/lib/element_component/components/progress/bar.rb +24 -0
  63. data/lib/element_component/components/progress.rb +17 -0
  64. data/lib/element_component/components/spinner.rb +19 -0
  65. data/lib/element_component/components/table.rb +21 -0
  66. data/lib/element_component/components.rb +16 -0
  67. data/lib/element_component/version.rb +1 -1
  68. metadata +61 -1
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../lib/element_component"
4
+
5
+ # =============================================================================
6
+ # Basic Nav
7
+ # =============================================================================
8
+ nav = ElementComponent::Components::Nav.new
9
+ puts "=== Basic Nav ==="
10
+ puts nav.render
11
+ puts
12
+
13
+ # =============================================================================
14
+ # Nav Tabs
15
+ # =============================================================================
16
+ nav = ElementComponent::Components::Nav.new(type: :tabs) do
17
+ add_content(ElementComponent::Components::NavItem.new do
18
+ add_content(ElementComponent::Components::NavLink.new(href: "/", active: true) { add_content("Home") })
19
+ end)
20
+ add_content(ElementComponent::Components::NavItem.new do
21
+ add_content(ElementComponent::Components::NavLink.new(href: "/profile") { add_content("Profile") })
22
+ end)
23
+ add_content(ElementComponent::Components::NavItem.new do
24
+ add_content(ElementComponent::Components::NavLink.new(href: "/messages", disabled: true) do
25
+ add_content("Messages")
26
+ end)
27
+ end)
28
+ end
29
+ puts "=== Nav Tabs ==="
30
+ puts nav.render
31
+ puts
32
+
33
+ # =============================================================================
34
+ # Nav Pills
35
+ # =============================================================================
36
+ nav = ElementComponent::Components::Nav.new(type: :pills) do
37
+ add_content(ElementComponent::Components::NavItem.new do
38
+ add_content(ElementComponent::Components::NavLink.new(href: "/") { add_content("Home") })
39
+ end)
40
+ add_content(ElementComponent::Components::NavItem.new do
41
+ add_content(ElementComponent::Components::NavLink.new(href: "/about") { add_content("About") })
42
+ end)
43
+ end
44
+ puts "=== Nav Pills ==="
45
+ puts nav.render
46
+ puts
47
+
48
+ # =============================================================================
49
+ # Nav Fill and Justified
50
+ # =============================================================================
51
+ nav = ElementComponent::Components::Nav.new(type: :pills, fill: true) do
52
+ add_content(ElementComponent::Components::NavItem.new do
53
+ add_content(ElementComponent::Components::NavLink.new(href: "/") { add_content("Home") })
54
+ end)
55
+ add_content(ElementComponent::Components::NavItem.new do
56
+ add_content(ElementComponent::Components::NavLink.new(href: "/about") { add_content("About") })
57
+ end)
58
+ end
59
+ puts "=== Nav Fill ==="
60
+ puts nav.render
61
+ puts
62
+
63
+ # =============================================================================
64
+ # Vertical Nav
65
+ # =============================================================================
66
+ nav = ElementComponent::Components::Nav.new(vertical: true) do
67
+ add_content(ElementComponent::Components::NavItem.new do
68
+ add_content(ElementComponent::Components::NavLink.new(href: "/") { add_content("Home") })
69
+ end)
70
+ add_content(ElementComponent::Components::NavItem.new do
71
+ add_content(ElementComponent::Components::NavLink.new(href: "/about") { add_content("About") })
72
+ end)
73
+ end
74
+ puts "=== Vertical Nav ==="
75
+ puts nav.render
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../lib/element_component"
4
+
5
+ # =============================================================================
6
+ # Basic Navbar
7
+ # =============================================================================
8
+ navbar = ElementComponent::Components::Navbar.new do
9
+ add_content(ElementComponent::Components::NavbarBrand.new(href: "/") { add_content("Navbar") })
10
+ add_content(ElementComponent::Components::NavbarToggler.new(target: "basicNav"))
11
+ add_content(ElementComponent::Components::NavbarCollapse.new(id: "basicNav") do
12
+ add_content(ElementComponent::Components::NavbarNav.new do
13
+ add_content(ElementComponent::Components::NavItem.new do
14
+ add_content(ElementComponent::Components::NavLink.new(href: "/", active: true) { add_content("Home") })
15
+ end)
16
+ add_content(ElementComponent::Components::NavItem.new do
17
+ add_content(ElementComponent::Components::NavLink.new(href: "/about") { add_content("About") })
18
+ end)
19
+ end)
20
+ end)
21
+ end
22
+ puts "=== Basic Navbar ==="
23
+ puts navbar.render
24
+ puts
25
+
26
+ # =============================================================================
27
+ # Dark Navbar
28
+ # =============================================================================
29
+ navbar = ElementComponent::Components::Navbar.new(theme: :dark, background: :dark) do
30
+ add_content(ElementComponent::Components::NavbarBrand.new(href: "/") { add_content("Dark") })
31
+ add_content(ElementComponent::Components::NavbarToggler.new(target: "darkNav"))
32
+ add_content(ElementComponent::Components::NavbarCollapse.new(id: "darkNav") do
33
+ add_content(ElementComponent::Components::NavbarNav.new do
34
+ add_content(ElementComponent::Components::NavItem.new do
35
+ add_content(ElementComponent::Components::NavLink.new(href: "/", active: true) { add_content("Home") })
36
+ end)
37
+ add_content(ElementComponent::Components::NavItem.new do
38
+ add_content(ElementComponent::Components::NavLink.new(href: "/contact") { add_content("Contact") })
39
+ end)
40
+ add_content(ElementComponent::Components::NavItem.new do
41
+ add_content(ElementComponent::Components::NavLink.new(href: "/disabled", disabled: true) do
42
+ add_content("Disabled")
43
+ end)
44
+ end)
45
+ end)
46
+ end)
47
+ end
48
+ puts "=== Dark Navbar ==="
49
+ puts navbar.render
50
+ puts
51
+
52
+ # =============================================================================
53
+ # Navbar with Container
54
+ # =============================================================================
55
+ navbar = ElementComponent::Components::Navbar.new(container: "container") do
56
+ add_content(ElementComponent::Components::NavbarBrand.new(href: "/") { add_content("Container") })
57
+ add_content(ElementComponent::Components::NavbarToggler.new(target: "containerNav"))
58
+ add_content(ElementComponent::Components::NavbarCollapse.new(id: "containerNav") do
59
+ add_content(ElementComponent::Components::NavbarNav.new do
60
+ add_content(ElementComponent::Components::NavItem.new do
61
+ add_content(ElementComponent::Components::NavLink.new(href: "/", active: true) { add_content("Home") })
62
+ end)
63
+ end)
64
+ end)
65
+ end
66
+ puts "=== Navbar with Container ==="
67
+ puts navbar.render
68
+ puts
69
+
70
+ # =============================================================================
71
+ # Navbar Without Container
72
+ # =============================================================================
73
+ navbar = ElementComponent::Components::Navbar.new(container: false) do
74
+ add_content(ElementComponent::Components::NavbarBrand.new(href: "/") { add_content("Fluid") })
75
+ end
76
+ puts "=== Navbar Without Container ==="
77
+ puts navbar.render
78
+ puts
79
+
80
+ # =============================================================================
81
+ # Sub-Components Rendered Independently
82
+ # =============================================================================
83
+ puts "=== NavbarBrand ==="
84
+ puts ElementComponent::Components::NavbarBrand.new(href: "/").render
85
+ puts
86
+
87
+ puts "=== NavbarToggler ==="
88
+ puts ElementComponent::Components::NavbarToggler.new(target: "myNav").render
89
+ puts
90
+
91
+ puts "=== NavbarCollapse ==="
92
+ puts ElementComponent::Components::NavbarCollapse.new(id: "myNav").render
93
+ puts
94
+
95
+ puts "=== NavbarNav ==="
96
+ puts ElementComponent::Components::NavbarNav.new.render
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../lib/element_component"
4
+
5
+ # =============================================================================
6
+ # Basic Pagination
7
+ # =============================================================================
8
+ pager = ElementComponent::Components::Pagination.new do
9
+ add_content(ElementComponent::Components::PageItem.new { add_content("1") })
10
+ add_content(ElementComponent::Components::PageItem.new(active: true) { add_content("2") })
11
+ add_content(ElementComponent::Components::PageItem.new { add_content("3") })
12
+ end
13
+ puts "=== Basic Pagination ==="
14
+ puts pager.render
15
+ puts
16
+
17
+ # =============================================================================
18
+ # Pagination with Previous/Next
19
+ # =============================================================================
20
+ pager = ElementComponent::Components::Pagination.new do
21
+ add_content(ElementComponent::Components::PageItem.new(disabled: true) { add_content("Previous") })
22
+ add_content(ElementComponent::Components::PageItem.new { add_content("1") })
23
+ add_content(ElementComponent::Components::PageItem.new(active: true) { add_content("2") })
24
+ add_content(ElementComponent::Components::PageItem.new { add_content("3") })
25
+ add_content(ElementComponent::Components::PageItem.new { add_content("Next") })
26
+ end
27
+ puts "=== Pagination with Previous/Next ==="
28
+ puts pager.render
29
+ puts
30
+
31
+ # =============================================================================
32
+ # Pagination Sizes
33
+ # =============================================================================
34
+ pager_sm = ElementComponent::Components::Pagination.new(size: :sm) do
35
+ add_content(ElementComponent::Components::PageItem.new { add_content("1") })
36
+ add_content(ElementComponent::Components::PageItem.new(active: true) { add_content("2") })
37
+ end
38
+ puts "=== Small Pagination ==="
39
+ puts pager_sm.render
40
+ puts
41
+
42
+ pager_lg = ElementComponent::Components::Pagination.new(size: :lg) do
43
+ add_content(ElementComponent::Components::PageItem.new { add_content("1") })
44
+ add_content(ElementComponent::Components::PageItem.new(active: true) { add_content("2") })
45
+ end
46
+ puts "=== Large Pagination ==="
47
+ puts pager_lg.render
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../lib/element_component"
4
+
5
+ # =============================================================================
6
+ # Basic Progress Bar
7
+ # =============================================================================
8
+ progress = ElementComponent::Components::Progress.new do
9
+ add_content(ElementComponent::Components::ProgressBar.new(value: 75))
10
+ end
11
+ puts "=== Basic Progress Bar ==="
12
+ puts progress.render
13
+ puts
14
+
15
+ # =============================================================================
16
+ # Progress Bar with Variant
17
+ # =============================================================================
18
+ progress = ElementComponent::Components::Progress.new do
19
+ add_content(ElementComponent::Components::ProgressBar.new(value: 50, variant: :info))
20
+ end
21
+ puts "=== Progress Bar with Variant ==="
22
+ puts progress.render
23
+ puts
24
+
25
+ # =============================================================================
26
+ # Striped and Animated Progress Bar
27
+ # =============================================================================
28
+ progress = ElementComponent::Components::Progress.new do
29
+ add_content(ElementComponent::Components::ProgressBar.new(
30
+ value: 60, variant: :warning, striped: true, animated: true
31
+ ))
32
+ end
33
+ puts "=== Striped and Animated ==="
34
+ puts progress.render
35
+ puts
36
+
37
+ # =============================================================================
38
+ # Multiple Progress Bars
39
+ # =============================================================================
40
+ progress = ElementComponent::Components::Progress.new do
41
+ add_content(ElementComponent::Components::ProgressBar.new(value: 30, variant: :danger))
42
+ add_content(ElementComponent::Components::ProgressBar.new(value: 20, variant: :warning))
43
+ add_content(ElementComponent::Components::ProgressBar.new(value: 40, variant: :success))
44
+ end
45
+ puts "=== Multiple Progress Bars ==="
46
+ puts progress.render
47
+ puts
48
+
49
+ # =============================================================================
50
+ # Standalone Progress Bar
51
+ # =============================================================================
52
+ bar = ElementComponent::Components::ProgressBar.new(value: 85, variant: :success)
53
+ puts "=== Standalone Progress Bar ==="
54
+ puts bar.render
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../lib/element_component"
4
+
5
+ # =============================================================================
6
+ # Basic Border Spinner
7
+ # =============================================================================
8
+ spinner = ElementComponent::Components::Spinner.new
9
+ puts "=== Basic Border Spinner ==="
10
+ puts spinner.render
11
+ puts
12
+
13
+ # =============================================================================
14
+ # Grow Spinner
15
+ # =============================================================================
16
+ spinner = ElementComponent::Components::Spinner.new(type: :grow)
17
+ puts "=== Grow Spinner ==="
18
+ puts spinner.render
19
+ puts
20
+
21
+ # =============================================================================
22
+ # Color Variants
23
+ # =============================================================================
24
+ puts "=== Color Variants ==="
25
+ %i[primary secondary success danger warning info light dark].each do |variant|
26
+ spinner = ElementComponent::Components::Spinner.new(variant: variant)
27
+ puts spinner.render
28
+ end
29
+ puts
30
+
31
+ # =============================================================================
32
+ # Spinner with Screen Reader Text
33
+ # =============================================================================
34
+ spinner = ElementComponent::Components::Spinner.new do
35
+ add_content(ElementComponent::Element.new("span", class: "visually-hidden") { add_content("Loading...") })
36
+ end
37
+ puts "=== Spinner with Text ==="
38
+ puts spinner.render
39
+ puts
40
+
41
+ # =============================================================================
42
+ # Spinner with Custom Attributes
43
+ # =============================================================================
44
+ spinner = ElementComponent::Components::Spinner.new(
45
+ variant: :primary,
46
+ style: "width: 3rem; height: 3rem;"
47
+ )
48
+ puts "=== Spinner with Custom Attributes ==="
49
+ puts spinner.render
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../lib/element_component"
4
+
5
+ # =============================================================================
6
+ # Basic Table
7
+ # =============================================================================
8
+ table = ElementComponent::Components::Table.new
9
+ puts "=== Basic Table ==="
10
+ puts table.render
11
+ puts
12
+
13
+ # =============================================================================
14
+ # Table with All Options
15
+ # =============================================================================
16
+ table = ElementComponent::Components::Table.new(
17
+ striped: true, bordered: true, hover: true, small: true, variant: :dark
18
+ )
19
+ puts "=== Table with All Options ==="
20
+ puts table.render
21
+ puts
22
+
23
+ # =============================================================================
24
+ # Table with Content
25
+ # =============================================================================
26
+ table = ElementComponent::Components::Table.new(striped: true) do
27
+ add_content("<thead><tr><th>Name</th><th>Age</th></tr></thead>")
28
+ add_content("<tbody><tr><td>John</td><td>30</td></tr></tbody>")
29
+ end
30
+ puts "=== Table with Content ==="
31
+ puts table.render
32
+ puts
33
+
34
+ # =============================================================================
35
+ # Table Variants
36
+ # =============================================================================
37
+ puts "=== Table Variants ==="
38
+ %i[primary secondary success danger warning info light dark].each do |variant|
39
+ t = ElementComponent::Components::Table.new(variant: variant)
40
+ puts t.render
41
+ end
@@ -7,13 +7,13 @@ require_relative "alert/close_button"
7
7
  module ElementComponent
8
8
  module Components
9
9
  class Alert < Element
10
- VALID_CONTEXTS = %i[primary secondary success danger warning info light dark].freeze
10
+ VALID_VARIANTS = %i[primary secondary success danger warning info light dark].freeze
11
11
 
12
- def initialize(context: :primary, dismissible: false, **attributes, &block)
12
+ def initialize(variant: :primary, dismissible: false, **attributes, &block)
13
13
  super("div", &block)
14
14
 
15
15
  add_attribute(class: "alert")
16
- add_attribute(class: "alert-#{context}")
16
+ add_attribute(class: "alert-#{variant}")
17
17
  add_attribute(class: "alert-dismissible") if dismissible
18
18
  add_attribute(role: "alert")
19
19
 
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ElementComponent
4
+ module Components
5
+ class Badge < Element
6
+ VALID_VARIANTS = %i[primary secondary success danger warning info light dark].freeze
7
+
8
+ def initialize(variant: :primary, pill: false, **attributes, &block)
9
+ super("span", &block)
10
+
11
+ add_attribute(class: "badge")
12
+ add_attribute(class: "bg-#{variant}")
13
+ add_attribute(class: "rounded-pill") if pill
14
+ add_attribute(attributes) unless attributes.empty?
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ElementComponent
4
+ module Components
5
+ class BreadcrumbItem < Element
6
+ def initialize(href: nil, active: false, **attributes, &block)
7
+ super("li", &block)
8
+
9
+ add_attribute(class: "breadcrumb-item")
10
+ add_attribute(class: "active") if active
11
+ add_attribute("aria-current": "page") if active
12
+ add_attribute(attributes) unless attributes.empty?
13
+
14
+ @href = href
15
+ end
16
+
17
+ private
18
+
19
+ def mount_content
20
+ inner = super
21
+ if @href && @contents.none?(Element)
22
+ "<a href=\"#{@href}\">#{inner}</a>"
23
+ else
24
+ inner
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "breadcrumb/item"
4
+
5
+ module ElementComponent
6
+ module Components
7
+ class Breadcrumb < Element
8
+ def initialize(**attributes, &)
9
+ super("nav", &)
10
+
11
+ add_attribute("aria-label": "breadcrumb")
12
+ add_attribute(attributes) unless attributes.empty?
13
+ end
14
+
15
+ def build
16
+ @html << "<#{@element}"
17
+ @html << (mount_attributes.empty? ? ">" : " #{mount_attributes}>")
18
+ @html << "<ol class=\"breadcrumb\">"
19
+ @html << mount_content
20
+ @html << "</ol>"
21
+ @html << "</#{@element}>" if @closing_tag
22
+ @html
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ElementComponent
4
+ module Components
5
+ class Button < Element
6
+ VALID_VARIANTS = %i[primary secondary success danger warning info light dark link].freeze
7
+ VALID_SIZES = %i[sm lg].freeze
8
+
9
+ def initialize(variant: :primary, outline: false, size: nil, href: nil, **attributes, &block)
10
+ if href
11
+ super("a", &block)
12
+ add_attribute(href: href)
13
+ else
14
+ super("button", &block)
15
+ add_attribute(type: "button")
16
+ end
17
+
18
+ add_attribute(class: "btn")
19
+ add_attribute(class: outline ? "btn-outline-#{variant}" : "btn-#{variant}")
20
+ add_attribute(class: "btn-#{size}") if size
21
+ add_attribute(attributes) unless attributes.empty?
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ElementComponent
4
+ module Components
5
+ class ButtonGroup < Element
6
+ VALID_SIZES = %i[sm lg].freeze
7
+
8
+ def initialize(size: nil, vertical: false, **attributes, &block)
9
+ super("div", &block)
10
+
11
+ add_attribute(class: vertical ? "btn-group-vertical" : "btn-group")
12
+ add_attribute(class: "btn-group-#{size}") if size
13
+ add_attribute(role: "group")
14
+ add_attribute(attributes) unless attributes.empty?
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ElementComponent
4
+ module Components
5
+ class CardBody < Element
6
+ def initialize(**attributes, &)
7
+ super("div", &)
8
+
9
+ add_attribute(class: "card-body")
10
+ add_attribute(attributes) unless attributes.empty?
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ElementComponent
4
+ module Components
5
+ class CardFooter < Element
6
+ def initialize(**attributes, &)
7
+ super("div", &)
8
+
9
+ add_attribute(class: "card-footer")
10
+ add_attribute(attributes) unless attributes.empty?
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ElementComponent
4
+ module Components
5
+ class CardHeader < Element
6
+ def initialize(**attributes, &)
7
+ super("div", &)
8
+
9
+ add_attribute(class: "card-header")
10
+ add_attribute(attributes) unless attributes.empty?
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ElementComponent
4
+ module Components
5
+ class CardImage < Element
6
+ def initialize(src: "", top: false, bottom: false, **attributes, &block)
7
+ super("img", closing_tag: false, &block)
8
+
9
+ add_attribute(class: "card-img")
10
+ add_attribute(class: "card-img-top") if top
11
+ add_attribute(class: "card-img-bottom") if bottom
12
+ add_attribute(src: src)
13
+ add_attribute(attributes) unless attributes.empty?
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ElementComponent
4
+ module Components
5
+ class CardText < Element
6
+ def initialize(**attributes, &)
7
+ super("p", &)
8
+
9
+ add_attribute(class: "card-text")
10
+ add_attribute(attributes) unless attributes.empty?
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ElementComponent
4
+ module Components
5
+ class CardTitle < Element
6
+ def initialize(**attributes, &)
7
+ super("h5", &)
8
+
9
+ add_attribute(class: "card-title")
10
+ add_attribute(attributes) unless attributes.empty?
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "card/header"
4
+ require_relative "card/body"
5
+ require_relative "card/footer"
6
+ require_relative "card/title"
7
+ require_relative "card/text"
8
+ require_relative "card/image"
9
+
10
+ module ElementComponent
11
+ module Components
12
+ class Card < Element
13
+ def initialize(**attributes, &)
14
+ super("div", &)
15
+
16
+ add_attribute(class: "card")
17
+ add_attribute(attributes) unless attributes.empty?
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ElementComponent
4
+ module Components
5
+ class CarouselCaption < Element
6
+ def initialize(**attributes, &)
7
+ super("div", &)
8
+
9
+ add_attribute(class: "carousel-caption")
10
+ add_attribute(attributes) unless attributes.empty?
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ElementComponent
4
+ module Components
5
+ class CarouselItem < Element
6
+ def initialize(active: false, interval: nil, **attributes, &block)
7
+ super("div", &block)
8
+
9
+ add_attribute(class: "carousel-item")
10
+ add_attribute(class: "active") if active
11
+ add_attribute("data-bs-interval": interval.to_s) if interval
12
+ add_attribute(attributes) unless attributes.empty?
13
+ end
14
+ end
15
+ end
16
+ end