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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5b499f6bde82abd9ba89e17560678b305bb3c1ee7f87c68f8bc4d0495e39d343
|
|
4
|
+
data.tar.gz: ec25f4dbe4c6ef3f10ba99abb961a078076b26fabba4cadff638b350dc090574
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b0920e4a4fb8c5d1f0effab1a35ff3993360611d4c78925403e29638ef060e15b906da7f5a5bce08ab8a42994b1cbd6c8c31362e3d0f000b4d64f97b23aaff59
|
|
7
|
+
data.tar.gz: e0b6357b7da70427297a68cc48258acd97508f3ead2b547af422fdc3ea444f9a2c04cb12c5d96f37827bd780fc5836b9c022ca0c32aa8bfc0bfdfc9c1976c38a
|
data/README.md
CHANGED
|
@@ -6,6 +6,20 @@
|
|
|
6
6
|
|
|
7
7
|
This gem provides a set of ready-to-use [Phlex](https://github.com/phlex-ruby/phlex) components for common [Bulma](https://bulma.io/) components and elements, making it easy to build beautiful, responsive interfaces with a clean, Ruby-focused API.
|
|
8
8
|
|
|
9
|
+
## Upgrading to 0.8.0
|
|
10
|
+
|
|
11
|
+
> [!IMPORTANT]
|
|
12
|
+
> The 0.8.0 release includes breaking changes. The namespace for the components has been changed from `Components::Bulma` to `Components::BulmaPhlex`.
|
|
13
|
+
|
|
14
|
+
This can generally be handled with a *Find-and-Replace*:
|
|
15
|
+
|
|
16
|
+
**Find:** `Bulma::`
|
|
17
|
+
**Replace:** `BulmaPhlex::`
|
|
18
|
+
|
|
19
|
+
Note that this change was also applied to the expected Stimulus controllers. References such as the Navigation bar have been updated from `bulma--navigation-bar` to `bulma-phlex--navigation-bar`.
|
|
20
|
+
|
|
21
|
+
Finally, the optional Rails extensions for the Card and Table components have been moved to the `bulma-phlex-rails` gem. If you are using this with Rails, you should use [the `bulma-phlex-rails` gem](https://github.com/RockSolt/bulma-phlex-rails). It provides both the component extensions as well as JavaScript for the Dropdown, Navigation Bar, and Tabs components.
|
|
22
|
+
|
|
9
23
|
## Table of Contents
|
|
10
24
|
|
|
11
25
|
- [Installation](#installation)
|
|
@@ -17,6 +31,7 @@ This gem provides a set of ready-to-use [Phlex](https://github.com/phlex-ruby/ph
|
|
|
17
31
|
- [Pagination](#pagination)
|
|
18
32
|
- [Table](#table)
|
|
19
33
|
- [Tabs](#tabs)
|
|
34
|
+
- [Title and Subtitle](#title-and-subtitle)
|
|
20
35
|
- [Development](#development)
|
|
21
36
|
- [Contributing](#contributing)
|
|
22
37
|
- [License](#license)
|
|
@@ -70,7 +85,7 @@ Use the Phlex components in your Rails views or any Ruby application that suppor
|
|
|
70
85
|
[Cards](https://bulma.io/documentation/components/card/) are flexible containers that can display various types of content including headers and content sections.
|
|
71
86
|
|
|
72
87
|
```ruby
|
|
73
|
-
|
|
88
|
+
BulmaPhlex::Card() do |card|
|
|
74
89
|
card.head("Card Title")
|
|
75
90
|
card.content do
|
|
76
91
|
"This is some card content"
|
|
@@ -86,19 +101,10 @@ end
|
|
|
86
101
|
- href: passed to the anchor's `href` attribute
|
|
87
102
|
- Any additional HTML attributes can be passed as keyword arguments.
|
|
88
103
|
|
|
89
|
-
|
|
90
|
-
#### Rails Feature: Turbo Frame Content
|
|
91
|
-
|
|
92
|
-
When the `turbo-rails` and `phlex-rails` gems are installed, the Card component also provides method `turbo_frame_content`, which allows the content to be deferred to a turbo frame. The method accepts the same parameters as [the Turbo Rails helper method `turbo_frame_tag`](https://github.com/hotwired/turbo-rails?tab=readme-ov-file#decompose-with-turbo-frames), with the addition of the following two attributes:
|
|
93
|
-
|
|
94
|
-
- pending_message (default: "Loading...")
|
|
95
|
-
- pending_icon (default: "fas fa-spinner fa-pulse")
|
|
104
|
+
Icons can be added to the links by passing an `icon` keyword argument with the icon class:
|
|
96
105
|
|
|
97
106
|
```ruby
|
|
98
|
-
|
|
99
|
-
card.head("Product Info")
|
|
100
|
-
card.turbo_frame_content("product", src: product_path(@product), pending_message: "Loading product...")
|
|
101
|
-
end
|
|
107
|
+
card.footer_link("View", "/view", icon: "fas fa-eye")
|
|
102
108
|
```
|
|
103
109
|
|
|
104
110
|
|
|
@@ -107,7 +113,7 @@ end
|
|
|
107
113
|
The [Dropdown](https://bulma.io/documentation/components/dropdown/) component provides a flexible dropdown menu for navigation or actions. It supports both click-to-toggle (default, requires a Stimulus controller) and hoverable modes, as well as alignment and icon customization.
|
|
108
114
|
|
|
109
115
|
```ruby
|
|
110
|
-
|
|
116
|
+
BulmaPhlex::Dropdown("Next Actions...") do |dropdown|
|
|
111
117
|
dropdown.link "View Profile", "/profile"
|
|
112
118
|
dropdown.link "Go to Settings", "/settings"
|
|
113
119
|
dropdown.divider
|
|
@@ -121,7 +127,7 @@ end
|
|
|
121
127
|
**Options:**
|
|
122
128
|
|
|
123
129
|
- `label` (required): The dropdown button label.
|
|
124
|
-
- `click`: Stimulus controller name for click-to-toggle (default: `"bulma--dropdown"`). Set to `false` for hoverable.
|
|
130
|
+
- `click`: Stimulus controller name for click-to-toggle (default: `"bulma-phlex--dropdown"`). Set to `false` for hoverable.
|
|
125
131
|
- `alignment`: `:left` (default), `:right`, or `:up`.
|
|
126
132
|
- `icon`: Icon class for the dropdown arrow (default: `"fas fa-angle-down"`).
|
|
127
133
|
|
|
@@ -136,7 +142,7 @@ end
|
|
|
136
142
|
The [Level](https://bulma.io/documentation/layout/level/) component provides a flexible horizontal layout system with left and right alignment.
|
|
137
143
|
|
|
138
144
|
```ruby
|
|
139
|
-
|
|
145
|
+
BulmaPhlex::Level() do |level|
|
|
140
146
|
level.left do
|
|
141
147
|
button(class: "button") { "Left" }
|
|
142
148
|
end
|
|
@@ -155,7 +161,7 @@ end
|
|
|
155
161
|
The [NavigationBar](https://bulma.io/documentation/components/navbar/) component provides a responsive navigation header with support for branding, navigation links, and dropdown menus.
|
|
156
162
|
|
|
157
163
|
```ruby
|
|
158
|
-
|
|
164
|
+
BulmaPhlex::NavigationBar(classes: "is-primary") do |navbar|
|
|
159
165
|
navbar.brand_item "My App", "/"
|
|
160
166
|
|
|
161
167
|
navbar.left do |menu|
|
|
@@ -182,7 +188,7 @@ end
|
|
|
182
188
|
- `container`: When true, wraps the content in a Bulma container. To set a constraint, such as "is-max-desktop", pass that string instead of true. (defaults to false)
|
|
183
189
|
|
|
184
190
|
> [!NOTE]
|
|
185
|
-
> Adding a container will limit the width of the Navigation Bar content according to Bulma's container rules.
|
|
191
|
+
> Adding a container will limit the width of the Navigation Bar content according to Bulma's container rules. However, the background color of the navbar will still span the full width of the viewport.
|
|
186
192
|
|
|
187
193
|
### Pagination
|
|
188
194
|
|
|
@@ -193,7 +199,7 @@ The [Pagination](https://bulma.io/documentation/components/pagination/) componen
|
|
|
193
199
|
@products = Product.page(params[:page]).per(20)
|
|
194
200
|
|
|
195
201
|
# In the view:
|
|
196
|
-
|
|
202
|
+
BulmaPhlex::Pagination(@products, ->(page) { products_path(page: page) })
|
|
197
203
|
```
|
|
198
204
|
|
|
199
205
|
### Table
|
|
@@ -203,7 +209,7 @@ The [Table](https://bulma.io/documentation/elements/table/) component provides a
|
|
|
203
209
|
```ruby
|
|
204
210
|
users = User.all
|
|
205
211
|
|
|
206
|
-
|
|
212
|
+
BulmaPhlex::Table(users, fullwidth: true, hoverable: true) do |table|
|
|
207
213
|
table.column "Name" do |user|
|
|
208
214
|
user.full_name
|
|
209
215
|
end
|
|
@@ -233,17 +239,7 @@ The `column` method takes the column name and any html attributes to be assigned
|
|
|
233
239
|
|
|
234
240
|
#### Additional Column Types
|
|
235
241
|
|
|
236
|
-
Instead of calling `column`, you can also invoke the following methods to add
|
|
237
|
-
|
|
238
|
-
**Arguments for `amount_column` (Rails only):**
|
|
239
|
-
|
|
240
|
-
- name: content for the `th` element
|
|
241
|
-
- `currency` (keyword): options that will be passed to [Rails helper number_to_currency](https://api.rubyonrails.org/classes/ActiveSupport/NumberHelper.html#method-i-number_to_currency, uses Rails defaults)
|
|
242
|
-
|
|
243
|
-
```ruby
|
|
244
|
-
table.amount_column("Payment Amount") { |row| row.payment_amount }
|
|
245
|
-
table.amount_column("Total", currency: { unit: "€" }, class: "is-bold", &:total)
|
|
246
|
-
```
|
|
242
|
+
Instead of calling `column`, you can also invoke the following methods to add date and icon columns:
|
|
247
243
|
|
|
248
244
|
**Arguments for `date_column`:**
|
|
249
245
|
|
|
@@ -292,10 +288,10 @@ This generates the [Bulma pagination](https://bulma.io/documentation/components/
|
|
|
292
288
|
|
|
293
289
|
The [Tabs](https://bulma.io/documentation/components/tabs/) component provides a way to toggle between different content sections using tabbed navigation, with support for icons and active state management.
|
|
294
290
|
|
|
295
|
-
Behavior of the tabs can be driven by the data attributes, which are assigned by the object passed in as the `data_attributes_builder`. By default, this will use the `StimulusDataAttributes` class with the controller name `bulma--tabs`. The controller is not provided by this library, but you can create your own Stimulus controller to handle the tab switching logic. Here is [an implementation of a Stimulus controller for Bulma tabs](https://github.com/RockSolt/bulma-rails-helpers/blob/main/app/javascript/controllers/bulma/tabs_controller.js).
|
|
291
|
+
Behavior of the tabs can be driven by the data attributes, which are assigned by the object passed in as the `data_attributes_builder`. By default, this will use the `StimulusDataAttributes` class with the controller name `bulma-phlex--tabs`. The controller is not provided by this library, but you can create your own Stimulus controller to handle the tab switching logic. Here is [an implementation of a Stimulus controller for Bulma tabs](https://github.com/RockSolt/bulma-rails-helpers/blob/main/app/javascript/controllers/bulma/tabs_controller.js).
|
|
296
292
|
|
|
297
293
|
```ruby
|
|
298
|
-
|
|
294
|
+
BulmaPhlex::Tabs(tabs_class: "is-boxed", contents_class: "ml-4") do |tabs|
|
|
299
295
|
tabs.tab(id: "profile", title: "Profile", active: true) do
|
|
300
296
|
"Profile content goes here"
|
|
301
297
|
end
|
|
@@ -323,6 +319,43 @@ end
|
|
|
323
319
|
- `active`: Adds the `is-active` class to the tab and shows the related content. Non-active content is assigned the `is-hidden` class. Defaults to `false`.
|
|
324
320
|
- `icon`: Specify an optional icon class.
|
|
325
321
|
|
|
322
|
+
### Tag
|
|
323
|
+
|
|
324
|
+
The [Tag](https://bulma.io/documentation/elements/tag/) component provides a way to display small, colored labels or tags with customizable styles. The component generates either a `span`, `a`, or `button` element based on the provided options and HTML attributes.
|
|
325
|
+
|
|
326
|
+
If the HTML attributes include an `href`, an anchor (`a`) element is generated; if not and either the `delete` option is true or there is a `data-action` attribute, a `button` element is generated; otherwise, a `span` element is used.
|
|
327
|
+
|
|
328
|
+
```ruby
|
|
329
|
+
BulmaPhlex::Tag("New", color: "primary", rounded: true)
|
|
330
|
+
BulmaPhlex::Tag("Sale", light: "danger")
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
**Constructor Arguments:**
|
|
334
|
+
- `text`: (positional, required) The tag text to display.
|
|
335
|
+
- `color`: (optional) The [Bulma color class](https://bulma.io/documentation/elements/tag/#colors) to apply.
|
|
336
|
+
- `light`: (optional) Use instead of `color` to apply a light color variant.
|
|
337
|
+
- `rounded`: (optional) A boolean indicating whether the tag should have rounded corners.
|
|
338
|
+
- `size`: (optional) The [Bulma tag size](https://bulma.io/documentation/elements/tag/#sizes): normal, medium, or large.
|
|
339
|
+
- `delete`: (optional) A boolean indicating whether to include a delete button on the tag.
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
### Title and Subtitle
|
|
343
|
+
|
|
344
|
+
The [Title](https://bulma.io/documentation/elements/title/) component provide a way to display headings and subheadings with customizable sizes and styles.
|
|
345
|
+
|
|
346
|
+
```ruby
|
|
347
|
+
BulmaPhlex::Title("Hello World")
|
|
348
|
+
|
|
349
|
+
BulmaPhlex::Title("Dr. Strangelove", size: 2, subtitle: "Or: How I Learned to Stop Worrying and Love the Bomb")
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
**Constructor Arguments:**
|
|
353
|
+
|
|
354
|
+
- `text`: (positional, required) The main title text to display.
|
|
355
|
+
- `size`: (optional) An integer from 1 to 6 indicating the size of the title. Corresponds to Bulma's `is-<size>` classes.
|
|
356
|
+
- `subtitle`: (optional) The subtitle text to display below the main title.
|
|
357
|
+
- `subtitle_size`: (optional) An integer from 1 to 6 indicating the size of the subtitle. If not provided and a title size is given, it defaults to `size + 2`.
|
|
358
|
+
- `spaced`: (optional) A boolean indicating whether to add the `is-spaced` class to the title.
|
|
326
359
|
|
|
327
360
|
## Development
|
|
328
361
|
|
data/lib/bulma-phlex.rb
CHANGED
|
@@ -1,19 +1,3 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "bulma_phlex
|
|
4
|
-
require "phlex"
|
|
5
|
-
|
|
6
|
-
require "components/bulma"
|
|
7
|
-
require "components/bulma/base"
|
|
8
|
-
require "components/bulma/card"
|
|
9
|
-
require "components/bulma/dropdown"
|
|
10
|
-
require "components/bulma/level"
|
|
11
|
-
require "components/bulma/navigation_bar_dropdown"
|
|
12
|
-
require "components/bulma/navigation_bar"
|
|
13
|
-
require "components/bulma/pagination"
|
|
14
|
-
require "components/bulma/table"
|
|
15
|
-
require "components/bulma/tabs"
|
|
16
|
-
require "components/bulma/tab_components/content"
|
|
17
|
-
require "components/bulma/tab_components/tab"
|
|
18
|
-
|
|
19
|
-
require "bulma_phlex/railtie" if defined?(Rails::Railtie)
|
|
3
|
+
require "bulma_phlex"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BulmaPhlex
|
|
4
|
+
# Base component for all Bulma components
|
|
5
|
+
#
|
|
6
|
+
# This is the parent class for all Bulma components in this library.
|
|
7
|
+
# It provides common utility methods and inherits from `Phlex::HTML`.
|
|
8
|
+
#
|
|
9
|
+
class Base < Phlex::HTML
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def icon_span(icon, additional_classes = nil)
|
|
13
|
+
span(class: "icon #{additional_classes}".strip) do
|
|
14
|
+
i(class: icon)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BulmaPhlex
|
|
4
|
+
# Card component for content display
|
|
5
|
+
#
|
|
6
|
+
# This component implements the [Bulma card](https://bulma.io/documentation/components/card/)
|
|
7
|
+
# interface. Cards are flexible containers that can display various types of content
|
|
8
|
+
# including headers, content sections, and more.
|
|
9
|
+
#
|
|
10
|
+
# ## Example
|
|
11
|
+
#
|
|
12
|
+
# ```ruby
|
|
13
|
+
# BulmaPhlex::Card() do |card|
|
|
14
|
+
# card.head("Card Title")
|
|
15
|
+
# card.content do
|
|
16
|
+
# "This is some card content"
|
|
17
|
+
# end
|
|
18
|
+
# card.footer_link("View", "/view", target: "_blank")
|
|
19
|
+
# card.footer_link("Edit", "/edit", class: "has-text-primary")
|
|
20
|
+
# end
|
|
21
|
+
# ```
|
|
22
|
+
class Card < BulmaPhlex::Base
|
|
23
|
+
def view_template(&)
|
|
24
|
+
vanish(&)
|
|
25
|
+
|
|
26
|
+
div(class: "card") do
|
|
27
|
+
card_header
|
|
28
|
+
card_content
|
|
29
|
+
card_footer
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def head(title, classes: nil)
|
|
34
|
+
@header_title = title
|
|
35
|
+
@header_classes = classes
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def content(&block)
|
|
39
|
+
@card_content = block
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def footer_link(text, href, **html_attributes)
|
|
43
|
+
(@footer_items ||= []) << [text, href, html_attributes]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def card_header
|
|
49
|
+
return if @header_title.nil?
|
|
50
|
+
|
|
51
|
+
header(class: "card-header #{@header_classes}") do
|
|
52
|
+
p(class: "card-header-title") { plain @header_title }
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def card_content
|
|
57
|
+
return if @card_content.nil?
|
|
58
|
+
|
|
59
|
+
div(class: "card-content") do
|
|
60
|
+
div(class: "content") { @card_content.call }
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def card_footer
|
|
65
|
+
return if @footer_items.nil? || @footer_items.empty?
|
|
66
|
+
|
|
67
|
+
footer(class: "card-footer") do
|
|
68
|
+
@footer_items.each do |text, href, html_attributes|
|
|
69
|
+
icon = html_attributes.delete(:icon)
|
|
70
|
+
html_attributes[:class] = [html_attributes[:class], "card-footer-item"].compact.join(" ")
|
|
71
|
+
a(href:, **html_attributes) do
|
|
72
|
+
if icon.present?
|
|
73
|
+
icon_text(icon, text)
|
|
74
|
+
else
|
|
75
|
+
plain text
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def icon_text(icon, text)
|
|
83
|
+
span(class: "icon-text") do
|
|
84
|
+
span(class: "icon") { i(class: icon) }
|
|
85
|
+
span { text }
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BulmaPhlex
|
|
4
|
+
# Dropdown component
|
|
5
|
+
#
|
|
6
|
+
# This component implements the [Bulma Dropdown](https://bulma.io/documentation/components/dropdown/).
|
|
7
|
+
#
|
|
8
|
+
# ## [Hoverable or Toggable](https://bulma.io/documentation/components/dropdown/#hoverable-or-toggable)
|
|
9
|
+
#
|
|
10
|
+
# By default the dropdown is in Click Mode and assumes a Stimulus controller named `bulma-phlex--dropdown` is present
|
|
11
|
+
# to handle the click events. The controller name can be customized using the `click` option.
|
|
12
|
+
#
|
|
13
|
+
# Set click to `false` to make the dropdown hoverable instead of togglable.
|
|
14
|
+
#
|
|
15
|
+
# ## Alignment
|
|
16
|
+
#
|
|
17
|
+
# Use the `alignment` option to control the dropdown's alignment. By default, it aligns to the left. Pass in
|
|
18
|
+
# `:right` or `:up` to change the alignment.
|
|
19
|
+
#
|
|
20
|
+
# ## Icon
|
|
21
|
+
#
|
|
22
|
+
# Use the `icon` option to customize the dropdown's icon. By default, it uses the Font Awesome angle down icon.
|
|
23
|
+
#
|
|
24
|
+
# ## Example
|
|
25
|
+
#
|
|
26
|
+
# ```ruby
|
|
27
|
+
# BulmaPhlex::Dropdown("Next Actions...") do |dropdown|
|
|
28
|
+
# dropdown.link "View Profile", "/profile"
|
|
29
|
+
# dropdown.link "Go to Settings", "/settings"
|
|
30
|
+
# dropdown.divider
|
|
31
|
+
# dropdown.item("This is just a text item")
|
|
32
|
+
# dropdown.item do
|
|
33
|
+
# div(class: "has-text-weight-bold") { "This is a bold item" }
|
|
34
|
+
# end
|
|
35
|
+
# end
|
|
36
|
+
# ```
|
|
37
|
+
#
|
|
38
|
+
class Dropdown < BulmaPhlex::Base
|
|
39
|
+
def initialize(label, click: "bulma-phlex--dropdown", alignment: "left", icon: "fas fa-angle-down")
|
|
40
|
+
@label = label
|
|
41
|
+
@click = click
|
|
42
|
+
@alignment = alignment
|
|
43
|
+
@icon = icon
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def view_template(&)
|
|
47
|
+
div(class: "dropdown #{"is-hoverable" unless @click} #{alignment_class}".strip, **stimulus_controller) do
|
|
48
|
+
div(class: "dropdown-trigger") do
|
|
49
|
+
button(
|
|
50
|
+
class: "button",
|
|
51
|
+
aria_haspopup: "true",
|
|
52
|
+
aria_controls: "dropdown-menu",
|
|
53
|
+
**stimulus_action
|
|
54
|
+
) do
|
|
55
|
+
span { @label }
|
|
56
|
+
span(class: "icon is-small") do
|
|
57
|
+
i(class: @icon, aria_hidden: "true")
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
div(class: "dropdown-menu", id: "dropdown-menu", role: "menu") do
|
|
63
|
+
div(class: "dropdown-content", &)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def item(content = nil, &)
|
|
69
|
+
if block_given?
|
|
70
|
+
div(class: "dropdown-item", &)
|
|
71
|
+
else
|
|
72
|
+
div(class: "dropdown-item") { content }
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def link(label, path)
|
|
77
|
+
a(class: "dropdown-item", href: path) { label }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def divider
|
|
81
|
+
hr(class: "dropdown-divider")
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
private
|
|
85
|
+
|
|
86
|
+
def alignment_class
|
|
87
|
+
case @alignment.to_sym
|
|
88
|
+
when :right
|
|
89
|
+
"is-right"
|
|
90
|
+
when :up
|
|
91
|
+
"is-up"
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def stimulus_controller
|
|
96
|
+
return {} unless @click
|
|
97
|
+
|
|
98
|
+
{ data: { controller: @click } }
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def stimulus_action
|
|
102
|
+
return {} unless @click
|
|
103
|
+
|
|
104
|
+
{ data: { action: "#{@click}#toggle" } }
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BulmaPhlex
|
|
4
|
+
# Level component for responsive horizontal layouts
|
|
5
|
+
#
|
|
6
|
+
# This component implements the [Bulma level](https://bulma.io/documentation/layout/level/)
|
|
7
|
+
# interface, providing a flexible horizontal layout system with left and right alignment.
|
|
8
|
+
#
|
|
9
|
+
# ## Example:
|
|
10
|
+
#
|
|
11
|
+
# ```ruby
|
|
12
|
+
# BulmaPhlex::Level() do |level|
|
|
13
|
+
# level.left do
|
|
14
|
+
# button(class: "button") { "Left" }
|
|
15
|
+
# end
|
|
16
|
+
#
|
|
17
|
+
# level.right do
|
|
18
|
+
# button(class: "button") { "Right" }
|
|
19
|
+
# end
|
|
20
|
+
# level.right do
|
|
21
|
+
# button(class: "button") { "Right 2" }
|
|
22
|
+
# end
|
|
23
|
+
# end
|
|
24
|
+
# ```
|
|
25
|
+
#
|
|
26
|
+
class Level < BulmaPhlex::Base
|
|
27
|
+
def initialize
|
|
28
|
+
@items = []
|
|
29
|
+
@left = []
|
|
30
|
+
@right = []
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def view_template(&)
|
|
34
|
+
vanish(&)
|
|
35
|
+
|
|
36
|
+
div(class: "level") do
|
|
37
|
+
div(class: "level-left") do
|
|
38
|
+
@left.each { level_item(it) }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
@items.each { level_item(it) }
|
|
42
|
+
|
|
43
|
+
div(class: "level-right") do
|
|
44
|
+
@right.each { level_item(it) }
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def item(&content)
|
|
50
|
+
@items << content
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def left(&content)
|
|
54
|
+
@left << content
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def right(&content)
|
|
58
|
+
@right << content
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
def level_item(content)
|
|
64
|
+
div(class: "level-item") { content.call }
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BulmaPhlex
|
|
4
|
+
# Navigation bar component for site navigation
|
|
5
|
+
#
|
|
6
|
+
# This component implements the [Bulma navbar](https://bulma.io/documentation/components/navbar/)
|
|
7
|
+
# interface. It provides a responsive navigation header with support for branding, navigation
|
|
8
|
+
# links, and dropdown menus, automatically collapsing on mobile devices.
|
|
9
|
+
#
|
|
10
|
+
# ## Example
|
|
11
|
+
#
|
|
12
|
+
# ```ruby
|
|
13
|
+
# BulmaPhlex::NavigationBar() do |navbar|
|
|
14
|
+
# navbar.brand do
|
|
15
|
+
# a(href: "/", class: "navbar-item") { "My App" }
|
|
16
|
+
# end
|
|
17
|
+
#
|
|
18
|
+
# navbar.left do
|
|
19
|
+
# a(href: "/", class: "navbar-item") { "Home" }
|
|
20
|
+
# a(href: "/products", class: "navbar-item") { "Products" }
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
# navbar.right do
|
|
24
|
+
# a(href: "/about", class: "navbar-item") { "About" }
|
|
25
|
+
#
|
|
26
|
+
# div(class: "navbar-item has-dropdown is-hoverable") do
|
|
27
|
+
# a(class: "navbar-link") { "Account" }
|
|
28
|
+
# BulmaPhlex::NavigationBarDropdown() do |dropdown|
|
|
29
|
+
# dropdown.item "Sign In", "/login"
|
|
30
|
+
# dropdown.item "Register", "/register"
|
|
31
|
+
# end
|
|
32
|
+
# end
|
|
33
|
+
# end
|
|
34
|
+
# end
|
|
35
|
+
# ```
|
|
36
|
+
#
|
|
37
|
+
class NavigationBar < BulmaPhlex::Base
|
|
38
|
+
def initialize(container: false, classes: "")
|
|
39
|
+
@container = container
|
|
40
|
+
@classes = classes
|
|
41
|
+
@brand = []
|
|
42
|
+
@left = []
|
|
43
|
+
@right = []
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def view_template(&)
|
|
47
|
+
vanish(&)
|
|
48
|
+
|
|
49
|
+
nav(class: "navbar #{@classes}".rstrip,
|
|
50
|
+
role: "navigation",
|
|
51
|
+
aria_label: "main navigation",
|
|
52
|
+
data: { controller: "bulma-phlex--navigation-bar" }) do
|
|
53
|
+
optional_container do
|
|
54
|
+
div(class: "navbar-brand") do
|
|
55
|
+
@brand.each(&:call)
|
|
56
|
+
|
|
57
|
+
a(class: "navbar-burger",
|
|
58
|
+
role: "button",
|
|
59
|
+
aria_label: "menu",
|
|
60
|
+
aria_expanded: "false",
|
|
61
|
+
data: {
|
|
62
|
+
action: "bulma-phlex--navigation-bar#toggle",
|
|
63
|
+
"bulma-phlex--navigation-bar-target": "burger"
|
|
64
|
+
}) do
|
|
65
|
+
4.times { span(aria_hidden: "true") }
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
div(class: "navbar-menu",
|
|
70
|
+
data: { "bulma-phlex--navigation-bar-target": "menu" }) do
|
|
71
|
+
div(class: "navbar-start") do
|
|
72
|
+
@left.each(&:call)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
div(class: "navbar-end") do
|
|
76
|
+
@right.each(&:call)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def brand(&block)
|
|
84
|
+
@brand << block
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def left(&block)
|
|
88
|
+
@left << block
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def right(&block)
|
|
92
|
+
@right << block
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
private
|
|
96
|
+
|
|
97
|
+
def optional_container(&)
|
|
98
|
+
if @container
|
|
99
|
+
constraint = @container if @container.is_a?(String) || @container.is_a?(Symbol)
|
|
100
|
+
div(class: "container #{constraint}".rstrip, &)
|
|
101
|
+
else
|
|
102
|
+
yield
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BulmaPhlex
|
|
4
|
+
# Dropdown component for the Bulma navigation bar
|
|
5
|
+
#
|
|
6
|
+
# This component implements the dropdown portion of the [Bulma navbar](https://bulma.io/documentation/components/navbar/#dropdown-menu).
|
|
7
|
+
# It provides a structured way to add dropdown menus to a navigation bar with headers, items, and dividers.
|
|
8
|
+
#
|
|
9
|
+
# ## Example
|
|
10
|
+
#
|
|
11
|
+
# ```ruby
|
|
12
|
+
# BulmaPhlex::NavigationBar() do |navbar|
|
|
13
|
+
# navbar.brand_item "My App", "/"
|
|
14
|
+
#
|
|
15
|
+
# navbar.right do |menu|
|
|
16
|
+
# menu.dropdown "Account" do |dropdown|
|
|
17
|
+
# dropdown.header "User"
|
|
18
|
+
# dropdown.item "Profile", "/profile"
|
|
19
|
+
# dropdown.item "Settings", "/settings"
|
|
20
|
+
# dropdown.divider
|
|
21
|
+
# dropdown.item "Sign Out", "/logout"
|
|
22
|
+
# end
|
|
23
|
+
# end
|
|
24
|
+
# end
|
|
25
|
+
# ```
|
|
26
|
+
#
|
|
27
|
+
class NavigationBarDropdown < BulmaPhlex::Base
|
|
28
|
+
def view_template(&)
|
|
29
|
+
div(class: "navbar-dropdown is-right", &)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def header(label)
|
|
33
|
+
div(class: "navbar-item header has-text-weight-medium") { label }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def item(label, path)
|
|
37
|
+
a(class: "navbar-item", href: path) { label }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def divider
|
|
41
|
+
hr(class: "navbar-divider")
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|