bulma-phlex 0.7.0 → 0.8.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.
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module BulmaPhlex
4
- module Rails
5
- # # Card Helper
6
- #
7
- # This module provides method `turbo_frame_content` to create a card with a turbo frame as its content.
8
- module CardHelper
9
- extend ActiveSupport::Concern
10
-
11
- included do
12
- include Phlex::Rails::Helpers::TurboFrameTag
13
- end
14
-
15
- # Renders a Bulma-styled card with a Turbo Frame as its content. This uses the same signatures as
16
- # `turbo_frame_tag`, with the addition of two optional attributes: `pending_message` and `pending_icon`.
17
- #
18
- # The two pending attributes have the following defaults:
19
- # - pending_message: "Loading..."
20
- # - pending_icon: "fas fa-spinner fa-pulse"
21
- def turbo_frame_content(*ids, src: nil, target: nil, **attributes)
22
- pending_message = attributes.delete(:pending_message) || "Loading..."
23
- pending_icon = attributes.delete(:pending_icon) || "fas fa-spinner fa-pulse"
24
-
25
- content do
26
- turbo_frame_tag ids, src: src, target: target, **attributes do
27
- span(class: "icon") { i class: pending_icon }
28
- span { plain pending_message }
29
- end
30
- end
31
- end
32
- end
33
- end
34
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module BulmaPhlex
4
- module Rails
5
- # # Table Helper
6
- #
7
- # This module provides method `amount_column` to create an amount column in a table.
8
- module TableHelper
9
- extend ActiveSupport::Concern
10
-
11
- included do
12
- include Phlex::Rails::Helpers::NumberToCurrency
13
- end
14
-
15
- def amount_column(header, currency: {}, **html_attributes, &content)
16
- html_attributes[:class] = [html_attributes[:class], "has-text-right"].compact.join(" ")
17
-
18
- column(header, **html_attributes) do |row|
19
- number_to_currency(content.call(row), **currency)
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bulma_phlex/rails/card_helper"
4
- require "bulma_phlex/rails/table_helper"
5
-
6
- module BulmaPhlex
7
- # # Railtie for BulmaPhlex
8
- #
9
- # This Railtie adds Rails-specific features to the BulmaPhlex library.
10
- class Railtie < ::Rails::Railtie
11
- initializer "bulma_phlex" do
12
- ActiveSupport.on_load(:action_view) do
13
- if defined?(Phlex::Rails)
14
- Components::Bulma::Card.include(BulmaPhlex::Rails::CardHelper) if defined?(Turbo)
15
- Components::Bulma::Table.include(BulmaPhlex::Rails::TableHelper)
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Components
4
- module Bulma
5
- # Base component for all Bulma components
6
- #
7
- # This is the parent class for all Bulma components in this library.
8
- # It provides common utility methods and inherits from `Phlex::HTML`.
9
- #
10
- class Base < Phlex::HTML
11
- private
12
-
13
- def icon_span(icon, additional_classes = nil)
14
- span(class: "icon #{additional_classes}".strip) do
15
- i(class: icon)
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,83 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Components
4
- module Bulma
5
- # Card component for content display
6
- #
7
- # This component implements the [Bulma card](https://bulma.io/documentation/components/card/)
8
- # interface. Cards are flexible containers that can display various types of content
9
- # including headers, content sections, and more.
10
- #
11
- # ## Example
12
- #
13
- # ```ruby
14
- # Bulma::Card() do |card|
15
- # card.head("Card Title")
16
- # card.content do
17
- # "This is some card content"
18
- # end
19
- # card.footer_link("View", "/view", target: "_blank")
20
- # card.footer_link("Edit", "/edit", class: "has-text-primary")
21
- # end
22
- # ```
23
- #
24
- # ## Rails Feature: Turbo Frame Content
25
- #
26
- # If the project includes Rails and the Phlex::Rails gem, the `BulmaPhlex::Rails::CardHelper` module
27
- # provides a `turbo_frame_content` method to create a card with a turbo frame
28
- # as its content. This allows for dynamic loading of card content.
29
- class Card < Components::Bulma::Base
30
- def view_template(&)
31
- vanish(&)
32
-
33
- div(class: "card") do
34
- card_header
35
- card_content
36
- card_footer
37
- end
38
- end
39
-
40
- def head(title, classes: nil)
41
- @header_title = title
42
- @header_classes = classes
43
- end
44
-
45
- def content(&block)
46
- @card_content = block
47
- end
48
-
49
- def footer_link(text, href, **html_attributes)
50
- (@footer_items ||= []) << [text, href, html_attributes]
51
- end
52
-
53
- private
54
-
55
- def card_header
56
- return if @header_title.nil?
57
-
58
- header(class: "card-header #{@header_classes}") do
59
- p(class: "card-header-title") { plain @header_title }
60
- end
61
- end
62
-
63
- def card_content
64
- return if @card_content.nil?
65
-
66
- div(class: "card-content") do
67
- div(class: "content") { @card_content.call }
68
- end
69
- end
70
-
71
- def card_footer
72
- return if @footer_items.nil? || @footer_items.empty?
73
-
74
- footer(class: "card-footer") do
75
- @footer_items.each do |text, href, html_attributes|
76
- html_attributes[:class] = [html_attributes[:class], "card-footer-item"].compact.join(" ")
77
- a(href:, **html_attributes) { text }
78
- end
79
- end
80
- end
81
- end
82
- end
83
- end
@@ -1,109 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Components
4
- module Bulma
5
- # Dropdown component
6
- #
7
- # This component implements the [Bulma Dropdown](https://bulma.io/documentation/components/dropdown/).
8
- #
9
- # ## [Hoverable or Toggable](https://bulma.io/documentation/components/dropdown/#hoverable-or-toggable)
10
- #
11
- # By default the dropdown is in Click Mode and assumes a Stimulus controller named `bulma--dropdown` is present to
12
- # handle the click events. The controller name can be customized using the `click` option.
13
- #
14
- # Set click to `false` to make the dropdown hoverable instead of togglable.
15
- #
16
- # ## Alignment
17
- #
18
- # Use the `alignment` option to control the dropdown's alignment. By default, it aligns to the left. Pass in
19
- # `:right` or `:up` to change the alignment.
20
- #
21
- # ## Icon
22
- #
23
- # Use the `icon` option to customize the dropdown's icon. By default, it uses the Font Awesome angle down icon.
24
- #
25
- # ## Example
26
- #
27
- # ```ruby
28
- # Bulma::Dropdown("Next Actions...") do |dropdown|
29
- # dropdown.link "View Profile", "/profile"
30
- # dropdown.link "Go to Settings", "/settings"
31
- # dropdown.divider
32
- # dropdown.item("This is just a text item")
33
- # dropdown.item do
34
- # div(class: "has-text-weight-bold") { "This is a bold item" }
35
- # end
36
- # end
37
- # ```
38
- #
39
- class Dropdown < Components::Bulma::Base
40
- def initialize(label, click: "bulma--dropdown", alignment: "left", icon: "fas fa-angle-down")
41
- @label = label
42
- @click = click
43
- @alignment = alignment
44
- @icon = icon
45
- end
46
-
47
- def view_template(&)
48
- div(class: "dropdown #{"is-hoverable" unless @click} #{alignment_class}".strip, **stimulus_controller) do
49
- div(class: "dropdown-trigger") do
50
- button(
51
- class: "button",
52
- aria_haspopup: "true",
53
- aria_controls: "dropdown-menu",
54
- **stimulus_action
55
- ) do
56
- span { @label }
57
- span(class: "icon is-small") do
58
- i(class: @icon, aria_hidden: "true")
59
- end
60
- end
61
- end
62
-
63
- div(class: "dropdown-menu", id: "dropdown-menu", role: "menu") do
64
- div(class: "dropdown-content", &)
65
- end
66
- end
67
- end
68
-
69
- def item(content = nil, &)
70
- if block_given?
71
- div(class: "dropdown-item", &)
72
- else
73
- div(class: "dropdown-item") { content }
74
- end
75
- end
76
-
77
- def link(label, path)
78
- a(class: "dropdown-item", href: path) { label }
79
- end
80
-
81
- def divider
82
- hr(class: "dropdown-divider")
83
- end
84
-
85
- private
86
-
87
- def alignment_class
88
- case @alignment.to_sym
89
- when :right
90
- "is-right"
91
- when :up
92
- "is-up"
93
- end
94
- end
95
-
96
- def stimulus_controller
97
- return {} unless @click
98
-
99
- { data: { controller: @click } }
100
- end
101
-
102
- def stimulus_action
103
- return {} unless @click
104
-
105
- { data: { action: "#{@click}#toggle" } }
106
- end
107
- end
108
- end
109
- end
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Components
4
- module Bulma
5
- # Level component for responsive horizontal layouts
6
- #
7
- # This component implements the [Bulma level](https://bulma.io/documentation/layout/level/)
8
- # interface, providing a flexible horizontal layout system with left and right alignment.
9
- #
10
- # ## Example:
11
- #
12
- # ```ruby
13
- # Bulma::Level() do |level|
14
- # level.left do
15
- # button(class: "button") { "Left" }
16
- # end
17
- #
18
- # level.right do
19
- # button(class: "button") { "Right" }
20
- # end
21
- # level.right do
22
- # button(class: "button") { "Right 2" }
23
- # end
24
- # end
25
- # ```
26
- #
27
- class Level < Components::Bulma::Base
28
- def initialize
29
- @items = []
30
- @left = []
31
- @right = []
32
- end
33
-
34
- def view_template(&)
35
- vanish(&)
36
-
37
- div(class: "level") do
38
- div(class: "level-left") do
39
- @left.each { level_item(it) }
40
- end
41
-
42
- @items.each { level_item(it) }
43
-
44
- div(class: "level-right") do
45
- @right.each { level_item(it) }
46
- end
47
- end
48
- end
49
-
50
- def item(&content)
51
- @items << content
52
- end
53
-
54
- def left(&content)
55
- @left << content
56
- end
57
-
58
- def right(&content)
59
- @right << content
60
- end
61
-
62
- private
63
-
64
- def level_item(content)
65
- div(class: "level-item") { content.call }
66
- end
67
- end
68
- end
69
- end
@@ -1,108 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Components
4
- module Bulma
5
- # Navigation bar component for site navigation
6
- #
7
- # This component implements the [Bulma navbar](https://bulma.io/documentation/components/navbar/)
8
- # interface. It provides a responsive navigation header with support for branding, navigation
9
- # links, and dropdown menus, automatically collapsing on mobile devices.
10
- #
11
- # ## Example
12
- #
13
- # ```ruby
14
- # Bulma::NavigationBar() do |navbar|
15
- # navbar.brand do
16
- # a(href: "/", class: "navbar-item") { "My App" }
17
- # end
18
- #
19
- # navbar.left do
20
- # a(href: "/", class: "navbar-item") { "Home" }
21
- # a(href: "/products", class: "navbar-item") { "Products" }
22
- # end
23
- #
24
- # navbar.right do
25
- # a(href: "/about", class: "navbar-item") { "About" }
26
- #
27
- # div(class: "navbar-item has-dropdown is-hoverable") do
28
- # a(class: "navbar-link") { "Account" }
29
- # Bulma::NavigationBarDropdown() do |dropdown|
30
- # dropdown.item "Sign In", "/login"
31
- # dropdown.item "Register", "/register"
32
- # end
33
- # end
34
- # end
35
- # end
36
- # ```
37
- #
38
- class NavigationBar < Components::Bulma::Base
39
- def initialize(container: false, classes: "")
40
- @container = container
41
- @classes = classes
42
- @brand = []
43
- @left = []
44
- @right = []
45
- end
46
-
47
- def view_template(&)
48
- vanish(&)
49
-
50
- nav(class: "navbar #{@classes}".rstrip,
51
- role: "navigation",
52
- aria_label: "main navigation",
53
- data: { controller: "bulma--navigation-bar" }) do
54
- optional_container do
55
- div(class: "navbar-brand") do
56
- @brand.each(&:call)
57
-
58
- a(class: "navbar-burger",
59
- role: "button",
60
- aria_label: "menu",
61
- aria_expanded: "false",
62
- data: {
63
- action: "bulma--navigation-bar#toggle",
64
- "bulma--navigation-bar-target": "burger"
65
- }) do
66
- 4.times { span(aria_hidden: "true") }
67
- end
68
- end
69
-
70
- div(class: "navbar-menu",
71
- data: { "bulma--navigation-bar-target": "menu" }) do
72
- div(class: "navbar-start") do
73
- @left.each(&:call)
74
- end
75
-
76
- div(class: "navbar-end") do
77
- @right.each(&:call)
78
- end
79
- end
80
- end
81
- end
82
- end
83
-
84
- def brand(&block)
85
- @brand << block
86
- end
87
-
88
- def left(&block)
89
- @left << block
90
- end
91
-
92
- def right(&block)
93
- @right << block
94
- end
95
-
96
- private
97
-
98
- def optional_container(&)
99
- if @container
100
- constraint = @container if @container.is_a?(String) || @container.is_a?(Symbol)
101
- div(class: "container #{constraint}".rstrip, &)
102
- else
103
- yield
104
- end
105
- end
106
- end
107
- end
108
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Components
4
- module Bulma
5
- # Dropdown component for the Bulma navigation bar
6
- #
7
- # This component implements the dropdown portion of the [Bulma navbar](https://bulma.io/documentation/components/navbar/#dropdown-menu).
8
- # It provides a structured way to add dropdown menus to a navigation bar with headers, items, and dividers.
9
- #
10
- # ## Example
11
- #
12
- # ```ruby
13
- # Bulma::NavigationBar() do |navbar|
14
- # navbar.brand_item "My App", "/"
15
- #
16
- # navbar.right do |menu|
17
- # menu.dropdown "Account" do |dropdown|
18
- # dropdown.header "User"
19
- # dropdown.item "Profile", "/profile"
20
- # dropdown.item "Settings", "/settings"
21
- # dropdown.divider
22
- # dropdown.item "Sign Out", "/logout"
23
- # end
24
- # end
25
- # end
26
- # ```
27
- #
28
- class NavigationBarDropdown < Components::Bulma::Base
29
- def view_template(&)
30
- div(class: "navbar-dropdown is-right", &)
31
- end
32
-
33
- def header(label)
34
- div(class: "navbar-item header has-text-weight-medium") { label }
35
- end
36
-
37
- def item(label, path)
38
- a(class: "navbar-item", href: path) { label }
39
- end
40
-
41
- def divider
42
- hr(class: "navbar-divider")
43
- end
44
- end
45
- end
46
- end
@@ -1,123 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Components
4
- module Bulma
5
- # Pagination component for navigating through multi-page content
6
- #
7
- # This component implements the [Bulma pagination](https://bulma.io/documentation/components/pagination/)
8
- # interface, providing navigation controls for paginated content. It shows:
9
- # - Previous/next page links
10
- # - First/last page links when appropriate
11
- # - Current page indicator
12
- # - Ellipses for skipped page ranges
13
- # - Summary of items being displayed
14
- #
15
- # ## Example
16
- #
17
- # ```ruby
18
- # # In a controller action:
19
- # @products = Product.page(params[:page]).per(20)
20
- #
21
- # # In the view:
22
- # Bulma::Pagination(@products, ->(page) { products_path(page: page) })
23
- # ```
24
- #
25
- class Pagination < Components::Bulma::Base
26
- attr_reader :pager, :path_builder
27
-
28
- # Initializes the pagination component
29
- #
30
- # @param pager [Object] An object that responds to:
31
- # - `current_page` - Integer representing the current page number
32
- # - `total_pages` - Integer representing the total number of pages
33
- # - `per_page` - Integer representing the number of items per page
34
- # - `total_count` - Integer representing the total number of items
35
- # - `previous_page` - Integer or nil representing the previous page number
36
- # - `next_page` - Integer or nil representing the next page number
37
- # @param path_builder [Proc] A callable that takes a page number and returns a URL string
38
- def initialize(pager, path_builder)
39
- @pager = pager
40
- @path_builder = path_builder
41
- end
42
-
43
- def view_template
44
- return unless pager.total_pages > 1
45
-
46
- div(class: "pagination-container mt-5") do
47
- nav(class: "pagination", role: "navigation", aria_label: "pagination") do
48
- # Previous page link
49
- if pager.previous_page
50
- a(class: "pagination-previous", href: page_url(pager.previous_page)) { "Previous" }
51
- else
52
- a(class: "pagination-previous", disabled: true) { "Previous" }
53
- end
54
-
55
- # Next page link
56
- if pager.next_page
57
- a(class: "pagination-next", href: page_url(pager.next_page)) { "Next" }
58
- else
59
- a(class: "pagination-next", disabled: true) { "Next" }
60
- end
61
-
62
- # Page number links
63
- ul(class: "pagination-list") do
64
- # First page and ellipsis if needed
65
- if pager.current_page > 3
66
- render_page_item(1)
67
- render_ellipsis if pager.current_page > 4
68
- end
69
-
70
- # Pages around current page
71
- page_window.each do |page_number|
72
- render_page_item(page_number)
73
- end
74
-
75
- # Ellipsis and last page if needed
76
- if pager.current_page < pager.total_pages - 2
77
- render_ellipsis if pager.current_page < pager.total_pages - 3
78
- render_page_item(pager.total_pages)
79
- end
80
- end
81
- end
82
-
83
- div(class: "has-text-centered mt-2 is-size-7") do
84
- start_item = ((pager.current_page - 1) * pager.per_page) + 1
85
- end_item = [start_item + pager.per_page - 1, pager.total_count].min
86
-
87
- plain "Showing #{start_item}-#{end_item} of #{pager.total_count} items"
88
- end
89
- end
90
- end
91
-
92
- private
93
-
94
- def render_page_item(page_number)
95
- li do
96
- if page_number == pager.current_page
97
- a(class: "pagination-link is-current",
98
- aria_label: "Page #{page_number}",
99
- aria_current: "page") { page_number.to_s }
100
- else
101
- a(class: "pagination-link",
102
- href: page_url(page_number),
103
- aria_label: "Go to page #{page_number}") { page_number.to_s }
104
- end
105
- end
106
- end
107
-
108
- def render_ellipsis
109
- li { span(class: "pagination-ellipsis") { "…" } }
110
- end
111
-
112
- def page_window
113
- start_page = [pager.current_page - 2, 1].max
114
- end_page = [pager.current_page + 2, pager.total_pages].min
115
- (start_page..end_page).to_a
116
- end
117
-
118
- def page_url(page_number)
119
- @path_builder.call(page_number)
120
- end
121
- end
122
- end
123
- end
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Components
4
- module Bulma
5
- module TabComponents
6
- # # Content
7
- #
8
- # This component represents a single content section within the Bulma Tabs component.
9
- #
10
- # ## Arguments:
11
- # - `id`: Unique identifier for the content.
12
- # - `active`: Boolean indicating if the content is currently active.
13
- # - `data_attributes_proc`: A proc that generates data attributes for the content.
14
- class Content < Components::Bulma::Base
15
- def initialize(id:, active:, data_attributes_proc: nil)
16
- @id = id
17
- @active = active
18
- @data_attributes = data_attributes_proc ||
19
- Components::Bulma::Tabs::StimulusDataAttributes.new("bulma--tabs").method(:for_content)
20
- end
21
-
22
- def view_template(&)
23
- div(id: @id,
24
- class: @active ? "" : "is-hidden",
25
- data: @data_attributes.call(@id), &)
26
- end
27
- end
28
- end
29
- end
30
- end