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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5caa2176372f45d0002153e7a4272e79bd3ae01eb530e58c16a29864a3e90c09
4
- data.tar.gz: 4ed606f6cb03296a7c0c52eccbe2e31bb2c7eb1c0e2fbbaef1510f8ad8f7d48f
3
+ metadata.gz: 5b499f6bde82abd9ba89e17560678b305bb3c1ee7f87c68f8bc4d0495e39d343
4
+ data.tar.gz: ec25f4dbe4c6ef3f10ba99abb961a078076b26fabba4cadff638b350dc090574
5
5
  SHA512:
6
- metadata.gz: 2d3173c063bb8fc27fa653b34a2f4a57d6b653c313361d1bd1661d13feb760a31e5f8a102407a4024c5e48671031ae5d1b11b6d3414d38b17a3d43d38b2c3918
7
- data.tar.gz: 9ec45c90c5060eb1d812d939ae03687c1027ed49c3959bf3f8855216c4e331c7ebb221f4a46903022a0a0d753cebab4a9ff0465528b5dfa424ce37e9b6b7340e
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
- Bulma::Card() do |card|
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
- Bulma::Card() do |card|
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
- Bulma::Dropdown("Next Actions...") do |dropdown|
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
- Bulma::Level() do |level|
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
- Bulma::NavigationBar(classes: "is-primary") do |navbar|
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. The background color of the navbar will still span the full width of the viewport.
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
- Bulma::Pagination(@products, ->(page) { products_path(page: page) })
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
- Bulma::Table(users, fullwidth: true, hoverable: true) do |table|
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 amount, date, and icon columns:
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
- Bulma::Tabs(tabs_class: "is-boxed", contents_class: "ml-4") do |tabs|
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/version"
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