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.
- checksums.yaml +4 -4
- data/README.md +65 -32
- data/lib/bulma-phlex.rb +1 -17
- data/lib/bulma_phlex/base.rb +18 -0
- data/lib/bulma_phlex/card.rb +89 -0
- data/lib/bulma_phlex/dropdown.rb +107 -0
- data/lib/bulma_phlex/level.rb +67 -0
- data/lib/bulma_phlex/navigation_bar.rb +106 -0
- data/lib/bulma_phlex/navigation_bar_dropdown.rb +44 -0
- data/lib/bulma_phlex/pagination.rb +121 -0
- data/lib/bulma_phlex/tab_components/content.rb +28 -0
- data/lib/bulma_phlex/tab_components/tab.rb +42 -0
- data/lib/bulma_phlex/table.rb +148 -0
- data/lib/bulma_phlex/tabs.rb +117 -0
- data/lib/bulma_phlex/tag.rb +60 -0
- data/lib/bulma_phlex/title.rb +57 -0
- data/lib/bulma_phlex/version.rb +1 -1
- data/lib/{components/bulma.rb → bulma_phlex.rb} +10 -6
- metadata +15 -44
- data/lib/bulma_phlex/rails/card_helper.rb +0 -34
- data/lib/bulma_phlex/rails/table_helper.rb +0 -24
- data/lib/bulma_phlex/railtie.rb +0 -20
- data/lib/components/bulma/base.rb +0 -20
- data/lib/components/bulma/card.rb +0 -83
- data/lib/components/bulma/dropdown.rb +0 -109
- data/lib/components/bulma/level.rb +0 -69
- data/lib/components/bulma/navigation_bar.rb +0 -108
- data/lib/components/bulma/navigation_bar_dropdown.rb +0 -46
- data/lib/components/bulma/pagination.rb +0 -123
- data/lib/components/bulma/tab_components/content.rb +0 -30
- data/lib/components/bulma/tab_components/tab.rb +0 -44
- data/lib/components/bulma/table.rb +0 -150
- data/lib/components/bulma/tabs.rb +0 -119
|
@@ -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
|
data/lib/bulma_phlex/railtie.rb
DELETED
|
@@ -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
|