bulma-phlex 0.10.0 → 0.11.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: 86dcdd7f2c7329c32ae420a8fc095975b4e4a1495802054c85789ee598230335
4
- data.tar.gz: bb42b533fe7b41b347d2e83f89faba27ed519a9d88ca06faf3d73a321e397e27
3
+ metadata.gz: 1ee83e739b84c897bbb801d7be66a49ce909b940399e35b19d2ce0ce310febc6
4
+ data.tar.gz: c3c1c066c77c916a51eb9d604f58a1e88291436e67e0014a821b40f3a2d32e66
5
5
  SHA512:
6
- metadata.gz: d5ad488129b08c46c985c25852da8cbe20486a7059e0429acc64cb2e6eee00889e0a8bb921db8de0175a0d7645762209da9e7e260f1cc139089cbbe9b6b3dc51
7
- data.tar.gz: ea95d770b73c2adfdc60a0eb4bb92541730c35008fafc44e638956bbb00413ba104c2cc8f1c0534671766a559e17d6d11c718e5a9ac8d2bce47215119d7f2702
6
+ metadata.gz: 5afc7194917ea792bf09f7a83ca58d8271b765a2d2a7eabbb6479b631c5935ebca1d3988a19a8d8e79d6ffe5d4a84fc2a4e507d4e455abaac98da0514d542e4d
7
+ data.tar.gz: dc8cee0e55182192282e766c734de97e252f2c5c34019a82061ff26c23dab7b8cddbc7c5888c2b32b728d4801a9441aad953cfeedcc7d613597006150a9cfdd9
data/README.md CHANGED
@@ -24,6 +24,7 @@ Finally, the optional Rails extensions for the Card and Table components have be
24
24
 
25
25
  - [Installation](#installation)
26
26
  - [Usage](#usage)
27
+ - [Button](#button)
27
28
  - [Card](#card)
28
29
  - [Columns](#columns)
29
30
  - [Dropdown](#dropdown)
@@ -34,6 +35,7 @@ Finally, the optional Rails extensions for the Card and Table components have be
34
35
  - [NavigationBar](#navigationbar)
35
36
  - [Notification](#notification)
36
37
  - [Pagination](#pagination)
38
+ - [Progress Bar](#progress-bar)
37
39
  - [Table](#table)
38
40
  - [Tabs](#tabs)
39
41
  - [Tag](#tag)
@@ -86,6 +88,34 @@ require "bulma-phlex"
86
88
 
87
89
  Use the Phlex components in your Rails views or any Ruby application that supports Phlex components.
88
90
 
91
+ ### Button
92
+
93
+ The [Button](https://bulma.io/documentation/elements/button/) component provides a way to create styled buttons with various options for colors, sizes, and icons.
94
+
95
+ ```ruby
96
+ BulmaPhlex::Button(color: "primary", size: "large", icon: "fas fa-thumbs-up") { "Like" }
97
+ ```
98
+
99
+ **Constructor Keyword Arguments:**
100
+
101
+ - `color`: Sets the button color (e.g., "primary", "link", "info", "success", "warning", "danger").
102
+ - `mode`: Sets the mode of the notification: "light" or "dark".
103
+ - `size`: Sets the button size: "small", "normal" (the default), "medium", or "large".
104
+ - `responsive`: If `true`, makes the button responsive.
105
+ - `fullwidth`: If `true`, makes the button full width.
106
+ - `outlined`: If `true`, makes the button outlined.
107
+ - `inverted`: If `true`, makes the button inverted.
108
+ - `rounded`: If `true`, makes the button rounded.
109
+ - `icon`: If provided, adds an icon to the button. Should be a string representing the
110
+ icon class (e.g., "fa-solid fa-check").
111
+ - `icon_left`: If provided, adds an icon to the left of the button text. Should be a string
112
+ representing the icon class (e.g., "fa-solid fa-check").
113
+ - `icon_right`: If provided, adds an icon to the right of the button text. Should be a string
114
+ representing the icon class (e.g., "fa-solid fa-check").
115
+
116
+ Any additional HTML attributes passed to the constructor will be applied to the button element.
117
+
118
+
89
119
  ### Card
90
120
 
91
121
  [Cards](https://bulma.io/documentation/components/card/) are flexible containers that can display various types of content including headers and content sections.
@@ -101,6 +131,10 @@ BulmaPhlex::Card() do |card|
101
131
  end
102
132
  ```
103
133
 
134
+ **Constructor Arguments:**
135
+
136
+ - `html_attributes`: Any additional HTML attributes to be passed to the card container div.
137
+
104
138
  **Arguments for `footer_link`:**
105
139
 
106
140
  - text: the link text
@@ -156,9 +190,10 @@ end
156
190
  **Options:**
157
191
 
158
192
  - `label` (required): The dropdown button label.
159
- - `click`: Stimulus controller name for click-to-toggle (default: `"bulma-phlex--dropdown"`). Set to `false` for hoverable.
160
- - `alignment`: `:left` (default), `:right`, or `:up`.
161
- - `icon`: Icon class for the dropdown arrow (default: `"fas fa-angle-down"`).
193
+ - `click` (keyword): Stimulus controller name for click-to-toggle (default: `"bulma-phlex--dropdown"`). Set to `false` for hoverable.
194
+ - `alignment` (keyword): `:left` (default), `:right`, or `:up`.
195
+ - `icon` (keyword): Icon class for the dropdown arrow (default: `"fas fa-angle-down"`).
196
+ - `html_attributes`: Any additional HTML attributes to be passed to the dropdown container div.
162
197
 
163
198
  **Dropdown methods:**
164
199
 
@@ -261,6 +296,8 @@ BulmaPhlex::Level() do |level|
261
296
  end
262
297
  ```
263
298
 
299
+ Pass in any HTML attributes to the constructor to have them applied to the level container div.
300
+
264
301
  ### NavigationBar
265
302
 
266
303
  The [NavigationBar](https://bulma.io/documentation/components/navbar/) component provides a responsive navigation header with support for branding, navigation links, and dropdown menus.
@@ -289,8 +326,13 @@ end
289
326
 
290
327
  **Constructor Keyword Arguments:**
291
328
 
292
- - `classes`: Additional classes to be added to the `nav` element, such as "is-primary" or "has-shadow".
293
329
  - `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)
330
+ - `color`: Sets the navbar color (e.g., "primary", "light", "dark").
331
+ - `transparent`: If `true`, makes the navbar transparent.
332
+ - `spaced`: If `true`, adds spacing to the navbar.
333
+ - `shadow`: If `true`, adds a shadow to the navbar.
334
+
335
+ Any additional HTML attributes passed to the component will be applied to the `<nav>` element.
294
336
 
295
337
  > [!NOTE]
296
338
  > 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.
@@ -337,7 +379,14 @@ The [Pagination](https://bulma.io/documentation/components/pagination/) componen
337
379
  BulmaPhlex::Pagination(@products, ->(page) { products_path(page: page) })
338
380
  ```
339
381
 
340
- In order to support pagination, the argument passed into the constructor must repond with integers to the following:
382
+ **Constructor Arguments:**
383
+
384
+ - `pager`: An object that responds to pagination methods (see below).
385
+ - `path_builder`: A lambda that takes a page number and returns the URL for that page. This is used to generate the links for the pagination controls.
386
+
387
+ Any additional HTML attributes passed to the constructor will be applied to the pagination container element.
388
+
389
+ In order to support pagination, the first argument in the constructor must repond with integers to the following:
341
390
 
342
391
  - current_page
343
392
  - total_pages
@@ -347,6 +396,24 @@ In order to support pagination, the argument passed into the constructor must re
347
396
  - next_page (can be nil)
348
397
 
349
398
 
399
+ ### Progress Bar
400
+
401
+ The [Progress Bar](https://bulma.io/documentation/components/progress/) component provides a visual representation of progress or completion status, with support for different colors and sizes.
402
+
403
+ ```ruby
404
+ BulmaPhlex::ProgressBar(color: "success", size: "large", value: 75, max: 100) { "75%" }
405
+ ```
406
+
407
+ **Constructor Keyword Arguments:**
408
+
409
+ - `color`: (optional) The [Bulma color class](https://bulma.io/documentation/elements/progress/#colors) to apply.
410
+ - `size`: (optional) The [Bulma size class](https://bulma.io/documentation/elements/progress/#sizes) to apply: small, medium, or large.
411
+ - `html_attributes`: Any additional HTML attributes to be passed to the `progress` element. Include the `value` and `max` attributes here to set the progress level.
412
+
413
+ Leaving out the `value` and `max` attributes will render an indeterminate progress bar, which can be used to indicate that a process is ongoing without specifying the exact progress.
414
+
415
+
416
+
350
417
  ### Table
351
418
 
352
419
  The [Table](https://bulma.io/documentation/elements/table/) component provides a way to display data in rows and columns with customizable headers and formatting options.
@@ -371,13 +438,14 @@ end
371
438
  **Constructor Keyword Arguments:**
372
439
 
373
440
  - `rows`: the data for the table as an enumerable (anything that responds to `each`)
374
- - `id`: the Id for the table element (defaults to "table")
375
441
  - `bordered`: adds the `is-bordered` class (boolean, defaults to false)
376
442
  - `striped`: adds the `is-striped` class (boolean, defaults to false)
377
443
  - `narrow`: adds the `is-narrow` class (boolean, defaults to false)
378
444
  - `hoverable`: adds the `is-hoverable` class (boolean, defaults to false)
379
445
  - `fullwidth`: adds the `is-fullwidth` class (boolean, defaults to false)
380
446
 
447
+ Any additional HTML attributes passed to the constructor will be applied to the table element.
448
+
381
449
  **Arguments for `column` Method:**
382
450
 
383
451
  The `column` method takes the column name and any html attributes to be assigned to the table cell element. The block will be called with the row as the parameter.
@@ -424,10 +492,10 @@ This generates the [Bulma pagination](https://bulma.io/documentation/components/
424
492
 
425
493
  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.
426
494
 
427
- 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).
495
+ 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-phlex-rails/blob/main/app/javascript/controllers/bulma_phlex/tabs_controller.js).
428
496
 
429
497
  ```ruby
430
- BulmaPhlex::Tabs(tabs_class: "is-boxed", contents_class: "ml-4") do |tabs|
498
+ BulmaPhlex::Tabs(boxed: true) do |tabs|
431
499
  tabs.tab(id: "profile", title: "Profile", active: true) do
432
500
  "Profile content goes here"
433
501
  end
@@ -444,10 +512,16 @@ end
444
512
 
445
513
  **Constructor Keyword Arguments:**
446
514
 
447
- - `tabs_class`: Classes to be added to the tabs div, such as `is-boxed`, `is-medium`, `is-centered`, or `is-toggle`.
448
- - `contents_class`: Classes added to the div that wraps the content (no Bulma related tabs functionality here, just a hook).
515
+ - `align`: Can be `centered` or `right` to align the tabs accordingly.
516
+ - `size`: Can be `small`, `medium`, or `large` to set the size of the tabs.
517
+ - `boxed`: If `true`, uses classic style tabs.
518
+ - `toggle`: If `true`, makes the tabs look like buttons.
519
+ - `rounded`: If `true`, makes the tabs look like buttons with the first and last rounded.
520
+ - `fullwidth`: If `true`, makes the tabs take up the full width of the container.
449
521
  - `data_attributes_builder`: Builder object that responds to `for_container`, `for_tab`, and `for_content` (with the latter two receiving the tab `id`). See the default `StimulusDataAttributes` for an example.
450
522
 
523
+ Any additional HTML attributes passed to the component will be applied to the outer `<div>` element.
524
+
451
525
  **Keyword Arguments for `tab` Method:**
452
526
 
453
527
  - `id`: The id to be assigned to the content. The tab will be assigned the same id with the suffix `-tab`.
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BulmaPhlex
4
+ # # Button
5
+ #
6
+ # This component implements the [Bulma button](https://bulma.io/documentation/elements/button/)
7
+ # interface. It provides a simple way to create buttons with the appropriate Bulma classes.
8
+ #
9
+ # ## Options
10
+ #
11
+ # - `color`: Sets the button color (e.g., "primary", "link", "info", "success", "warning", "danger").
12
+ # - `mode`: Sets the mode of the notification: "light" or "dark".
13
+ # - `size`: Sets the button size: "small", "normal" (the default), "medium", or "large".
14
+ # - `responsive`: If `true`, makes the button responsive.
15
+ # - `fullwidth`: If `true`, makes the button full width.
16
+ # - `outlined`: If `true`, makes the button outlined.
17
+ # - `inverted`: If `true`, makes the button inverted.
18
+ # - `rounded`: If `true`, makes the button rounded.
19
+ # - `icon`: If provided, adds an icon to the button. Should be a string representing
20
+ # the icon class (e.g., "fa-solid fa-check").
21
+ # - `icon_left`: If provided, adds an icon to the left of the button text. Should be a string
22
+ # representing the icon class (e.g., "fa-solid fa-check").
23
+ # - `icon_right`: If provided, adds an icon to the right of the button text. Should be a string
24
+ # representing the icon class (e.g., "fa-solid fa-check").
25
+ class Button < Base
26
+ def initialize(color: nil, # rubocop:disable Metrics/ParameterLists
27
+ mode: nil,
28
+ size: nil,
29
+ responsive: false,
30
+ fullwidth: false,
31
+ outlined: false,
32
+ inverted: false,
33
+ rounded: false,
34
+ icon: nil,
35
+ icon_left: nil,
36
+ icon_right: nil,
37
+ **html_attributes)
38
+ @color = color
39
+ @mode = mode
40
+ @size = size
41
+ @responsive = responsive
42
+ @fullwidth = fullwidth
43
+ @outlined = outlined
44
+ @inverted = inverted
45
+ @rounded = rounded
46
+ @icon_left = icon || icon_left
47
+ @icon_right = icon_right
48
+ @html_attributes = html_attributes
49
+ end
50
+
51
+ def view_template(&)
52
+ button(**mix({ class: button_classes }, @html_attributes)) do
53
+ Icon(@icon_left) if @icon_left
54
+ yield if block_given?
55
+ Icon(@icon_right) if @icon_right
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ def button_classes # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
62
+ classes = ["button"]
63
+ classes << "is-#{@color}" if @color
64
+ classes << "is-#{@mode}" if @mode
65
+ classes << "is-#{@size}" if @size
66
+ classes << "is-responsive" if @responsive
67
+ classes << "is-fullwidth" if @fullwidth
68
+ classes << "is-outlined" if @outlined
69
+ classes << "is-inverted" if @inverted
70
+ classes << "is-rounded" if @rounded
71
+ classes
72
+ end
73
+ end
74
+ end
@@ -20,10 +20,14 @@ module BulmaPhlex
20
20
  # end
21
21
  # ```
22
22
  class Card < BulmaPhlex::Base
23
+ def initialize(**html_attributes)
24
+ @html_attributes = html_attributes
25
+ end
26
+
23
27
  def view_template(&)
24
28
  vanish(&)
25
29
 
26
- div(class: "card") do
30
+ div(**mix(class: "card", **@html_attributes)) do
27
31
  card_header
28
32
  card_content
29
33
  card_footer
@@ -36,15 +36,17 @@ module BulmaPhlex
36
36
  # ```
37
37
  #
38
38
  class Dropdown < BulmaPhlex::Base
39
- def initialize(label, click: "bulma-phlex--dropdown", alignment: "left", icon: "fas fa-angle-down")
39
+ def initialize(label, click: "bulma-phlex--dropdown", alignment: "left", icon: "fas fa-angle-down",
40
+ **html_attributes)
40
41
  @label = label
41
42
  @click = click
42
43
  @alignment = alignment
43
44
  @icon = icon
45
+ @html_attributes = html_attributes
44
46
  end
45
47
 
46
48
  def view_template(&)
47
- div(class: "dropdown #{"is-hoverable" unless @click} #{alignment_class}".strip, **stimulus_controller) do
49
+ div(**mix({ class: dropdown_classes, **stimulus_controller }, @html_attributes)) do
48
50
  div(class: "dropdown-trigger") do
49
51
  button(
50
52
  class: "button",
@@ -83,6 +85,13 @@ module BulmaPhlex
83
85
 
84
86
  private
85
87
 
88
+ def dropdown_classes
89
+ classes = ["dropdown"]
90
+ classes << "is-hoverable" unless @click
91
+ classes << "is-#{@alignment}" unless @alignment == "left"
92
+ classes.join(" ")
93
+ end
94
+
86
95
  def alignment_class
87
96
  case @alignment.to_sym
88
97
  when :right
@@ -24,7 +24,8 @@ module BulmaPhlex
24
24
  # ```
25
25
  #
26
26
  class Level < BulmaPhlex::Base
27
- def initialize
27
+ def initialize(**html_attributes)
28
+ @html_attributes = html_attributes
28
29
  @items = []
29
30
  @left = []
30
31
  @right = []
@@ -33,15 +34,15 @@ module BulmaPhlex
33
34
  def view_template(&)
34
35
  vanish(&)
35
36
 
36
- div(class: "level") do
37
+ div(**mix({ class: "level" }, @html_attributes)) do
37
38
  div(class: "level-left") do
38
- @left.each { level_item(it) }
39
+ @left.each { |item| level_item(item) }
39
40
  end
40
41
 
41
- @items.each { level_item(it) }
42
+ @items.each { |item| level_item(item) }
42
43
 
43
44
  div(class: "level-right") do
44
- @right.each { level_item(it) }
45
+ @right.each { |item| level_item(item) }
45
46
  end
46
47
  end
47
48
  end
@@ -7,6 +7,10 @@ module BulmaPhlex
7
7
  # interface. It provides a responsive navigation header with support for branding, navigation
8
8
  # links, and dropdown menus, automatically collapsing on mobile devices.
9
9
  #
10
+ # The component is rendered with data attributes to enable JavaScript behavior for toggling the mobile
11
+ # menu. It is hardcoded to the Stimulus controller `bulma-phlex--navigation-bar` (available via the
12
+ # `bulma-phlex-rails` gem).
13
+ #
10
14
  # ## Example
11
15
  #
12
16
  # ```ruby
@@ -34,10 +38,30 @@ module BulmaPhlex
34
38
  # end
35
39
  # ```
36
40
  #
41
+ # ## Options
42
+ #
43
+ # - `container`: If `true`, wraps the navbar content in a `.container` for fixed-width layout. Can also
44
+ # be a string or symbol to specify a custom container class.
45
+ # - `color`: Sets the navbar color (e.g., "primary", "light", "dark").
46
+ # - `transparent`: If `true`, makes the navbar transparent.
47
+ # - `spaced`: If `true`, adds spacing to the navbar.
48
+ # - `shadow`: If `true`, adds a shadow to the navbar.
49
+ #
50
+ # Any additional HTML attributes passed to the component will be applied to the `<nav>` element.
37
51
  class NavigationBar < BulmaPhlex::Base
38
- def initialize(container: false, classes: "")
52
+ def initialize(container: false, # rubocop:disable Metrics/ParameterLists
53
+ color: nil,
54
+ transparent: false,
55
+ spaced: false,
56
+ shadow: false,
57
+ **html_attributes)
39
58
  @container = container
40
- @classes = classes
59
+ @color = color
60
+ @transparent = transparent
61
+ @spaced = spaced
62
+ @shadow = shadow
63
+ @html_attributes = html_attributes
64
+
41
65
  @brand = []
42
66
  @left = []
43
67
  @right = []
@@ -46,10 +70,7 @@ module BulmaPhlex
46
70
  def view_template(&)
47
71
  vanish(&)
48
72
 
49
- nav(class: "navbar #{@classes}".rstrip,
50
- role: "navigation",
51
- aria_label: "main navigation",
52
- data: { controller: "bulma-phlex--navigation-bar" }) do
73
+ nav(**mix(nav_attributes, @html_attributes)) do
53
74
  optional_container do
54
75
  div(class: "navbar-brand") do
55
76
  @brand.each(&:call)
@@ -94,6 +115,22 @@ module BulmaPhlex
94
115
 
95
116
  private
96
117
 
118
+ def nav_attributes
119
+ { class: nav_classes,
120
+ role: "navigation",
121
+ aria_label: "main navigation",
122
+ data: { controller: "bulma-phlex--navigation-bar" } }
123
+ end
124
+
125
+ def nav_classes
126
+ classes = ["navbar"]
127
+ classes << "is-#{@color}" if @color
128
+ classes << "is-transparent" if @transparent
129
+ classes << "is-spaced" if @spaced
130
+ classes << "has-shadow" if @shadow
131
+ classes
132
+ end
133
+
97
134
  def optional_container(&)
98
135
  if @container
99
136
  constraint = @container if @container.is_a?(String) || @container.is_a?(Symbol)
@@ -34,15 +34,16 @@ module BulmaPhlex
34
34
  # - `previous_page` - Integer or nil representing the previous page number
35
35
  # - `next_page` - Integer or nil representing the next page number
36
36
  # @param path_builder [Proc] A callable that takes a page number and returns a URL string
37
- def initialize(pager, path_builder)
37
+ def initialize(pager, path_builder, **html_attributes)
38
38
  @pager = pager
39
39
  @path_builder = path_builder
40
+ @html_attributes = html_attributes
40
41
  end
41
42
 
42
43
  def view_template
43
44
  return unless pager.total_pages > 1
44
45
 
45
- div(class: "pagination-container mt-5") do
46
+ div(**mix({ class: "pagination-container" }, @html_attributes)) do
46
47
  nav(class: "pagination", role: "navigation", aria_label: "pagination") do
47
48
  # Previous page link
48
49
  if pager.previous_page
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BulmaPhlex
4
+ # Progress Bar
5
+ #
6
+ # This component implements the [Bulma progress bar element](https://bulma.io/documentation/elements/progress/).
7
+ #
8
+ # ## Options
9
+ #
10
+ # - `color`: Sets the [color of the progress bar](https://bulma.io/documentation/elements/progress/#colors)
11
+ # - `size`: Sets the [size of the progress bar](https://bulma.io/documentation/elements/progress/#sizes): small,
12
+ # normal, medium, or large.
13
+ # - `html_attributes`: Additional HTML attributes to add to the progress element. It is expected that the
14
+ # `value` and `max` attributes will be included here to set the progress bar's value and maximum value.
15
+ #
16
+ # Leaving out the `value` and `max` attributes will result in an indeterminate progress bar, which is useful for
17
+ # indicating that a process is ongoing without specifying how much of it is complete.
18
+ class ProgressBar < Base
19
+ def initialize(color: nil, size: nil, **html_attributes)
20
+ @color = color
21
+ @size = size
22
+ @html_attributes = html_attributes
23
+ end
24
+
25
+ def view_template(&)
26
+ progress(**mix({ class: classes }, @html_attributes), &)
27
+ end
28
+
29
+ private
30
+
31
+ def classes
32
+ classes = ["progress"]
33
+ classes << "is-#{@color}" if @color
34
+ classes << "is-#{@size}" if @size
35
+ classes
36
+ end
37
+ end
38
+ end
@@ -27,17 +27,43 @@ module BulmaPhlex
27
27
  # end
28
28
  # ```
29
29
  #
30
+ # ## Options
31
+ #
32
+ # - `bordered`: Adds borders to the table.
33
+ # - `striped`: Adds zebra-striping to the table rows.
34
+ # - `narrow`: Makes the table more compact.
35
+ # - `hoverable`: Adds a hover effect to the table rows.
36
+ # - `fullwidth`: Makes the table take up the full width of its container.
37
+ #
38
+ # Any additional HTML attributes passed to the component will be applied to the `<table>` element.
39
+ #
40
+ # ## Pagination
41
+ #
42
+ # If the `paginate` method is called with a block that builds pagination paths, a pagination control
43
+ # will be rendered in the table footer. The block should accept a page number and return the
44
+ # corresponding URL for that page.
30
45
  class Table < BulmaPhlex::Base
31
- def initialize(rows, id_or_options = nil, **options)
46
+ def initialize(rows, # rubocop:disable Metrics/ParameterLists
47
+ bordered: false,
48
+ striped: false,
49
+ narrow: false,
50
+ hoverable: false,
51
+ fullwidth: false,
52
+ **html_attributes)
32
53
  @rows = rows
33
- @id, @table_class = parse_id_and_options(id_or_options, options, rows)
54
+ @bordered = bordered
55
+ @striped = striped
56
+ @narrow = narrow
57
+ @hoverable = hoverable
58
+ @fullwidth = fullwidth
59
+ @html_attributes = html_attributes
34
60
  @columns = []
35
61
  end
36
62
 
37
63
  def view_template(&)
38
64
  vanish(&)
39
65
 
40
- table(id: @id, class: @table_class) do
66
+ table(**mix({ class: table_classes }, @html_attributes)) do
41
67
  thead do
42
68
  @columns.each do |column|
43
69
  table_header(column)
@@ -82,36 +108,14 @@ module BulmaPhlex
82
108
 
83
109
  private
84
110
 
85
- def parse_id_and_options(id_or_options, options, rows)
86
- if id_or_options.is_a?(String)
87
- id = id_or_options
88
- opts = options
89
- else
90
- opts = (id_or_options || {}).merge(options)
91
- id = opts.delete(:id) || id_from_array_or_arel(rows)
92
- end
93
- table_class = "table #{parse_table_classes(opts)}"
94
- [id, table_class]
95
- end
96
-
97
- def id_from_array_or_arel(rows)
98
- if rows.respond_to? :model
99
- rows.model.model_name.plural
100
- elsif rows.empty?
101
- "table"
102
- else
103
- rows.first.model_name.plural
104
- end
105
- rescue StandardError
106
- "table"
107
- end
108
-
109
- def parse_table_classes(options)
110
- options.slice(*%i[bordered striped narrow hoverable fullwidth])
111
- .transform_keys { |key| "is-#{key}" }
112
- .select { |_, value| value }
113
- .keys
114
- .join(" ")
111
+ def table_classes
112
+ classes = ["table"]
113
+ classes << "is-bordered" if @bordered
114
+ classes << "is-striped" if @striped
115
+ classes << "is-narrow" if @narrow
116
+ classes << "is-hoverable" if @hoverable
117
+ classes << "is-fullwidth" if @fullwidth
118
+ classes
115
119
  end
116
120
 
117
121
  # this derives a th class from the column html attributes
@@ -139,7 +143,7 @@ module BulmaPhlex
139
143
  tfoot do
140
144
  tr do
141
145
  td(class: "py-0", colspan: @columns.size) do
142
- Pagination(@rows, @path_builder)
146
+ Pagination(@rows, @path_builder, class: "mt-5")
143
147
  end
144
148
  end
145
149
  end
@@ -7,15 +7,12 @@ module BulmaPhlex
7
7
  # interface, providing a way to toggle between different content sections using
8
8
  # tabbed navigation. Includes support for icons and active state management.
9
9
  #
10
- # Classes can be assigned to either the tabs or contents wrappers. The tabs div is where Bulma
11
- # options such as `is-boxed`, `is-centered`, or `is-small` can be added.
12
- #
13
10
  # Use method `right_content` to add content to the right of the tabs, such as a button.
14
11
  #
15
12
  # The tabs behavior can be managed by the data attributes provided by the `data_attributes_builder` argument. By
16
13
  # default, this will use the `StimulusDataAttributes` class with the controller name `bulma-phlex--tabs`. That
17
14
  # controlleris not provided by this library, but you can create your own Stimulus controller to handle the tab
18
- # 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).
15
+ # switching logic. Here is an implementation of a [Stimulus controller for Bulma tabs](https://github.com/RockSolt/bulma-phlex-rails/blob/main/app/javascript/controllers/bulma_phlex/tabs_controller.js).
19
16
  #
20
17
  # ## Example
21
18
  #
@@ -35,6 +32,18 @@ module BulmaPhlex
35
32
  # end
36
33
  # ```
37
34
  #
35
+ # ## Options
36
+ #
37
+ # - `align`: Can be `centered` or `right` to align the tabs accordingly.
38
+ # - `size`: Can be `small`, `medium`, or `large` to set the size of the tabs.
39
+ # - `boxed`: If `true`, uses classic style tabs.
40
+ # - `toggle`: If `true`, makes the tabs look like buttons.
41
+ # - `rounded`: If `true`, makes the tabs look like buttons with the first and last rounded.
42
+ # - `fullwidth`: If `true`, makes the tabs take up the full width of the container.
43
+ # - `data_attributes_builder`: An object that provides methods to generate data attributes for the
44
+ # tabs. By default, this is an instance of `StimulusDataAttributes` with "bulma-phlex--tabs".
45
+ #
46
+ # Any additional HTML attributes passed to the component will be applied to the outer `<div>` element.
38
47
  class Tabs < BulmaPhlex::Base
39
48
  StimulusDataAttributes = Data.define(:stimulus_controller) do
40
49
  def for_container
@@ -60,12 +69,22 @@ module BulmaPhlex
60
69
  end
61
70
  end
62
71
 
63
- def initialize(id: nil, tabs_class: nil, contents_class: nil,
64
- data_attributes_builder: StimulusDataAttributes.new("bulma-phlex--tabs"))
65
- @id = id || "tabs"
66
- @tabs_class = tabs_class
67
- @contents_class = contents_class
72
+ def initialize(align: nil, # rubocop:disable Metrics/ParameterLists
73
+ size: nil,
74
+ boxed: false,
75
+ toggle: false,
76
+ rounded: false,
77
+ fullwidth: false,
78
+ data_attributes_builder: StimulusDataAttributes.new("bulma-phlex--tabs"),
79
+ **html_attributes)
80
+ @align = align
81
+ @size = size
82
+ @boxed = boxed
83
+ @toggle = toggle || rounded
84
+ @rounded = rounded
85
+ @fullwidth = fullwidth
68
86
  @data_attributes_builder = data_attributes_builder
87
+ @html_attributes = html_attributes
69
88
  @tabs = []
70
89
  @contents = []
71
90
  end
@@ -85,9 +104,9 @@ module BulmaPhlex
85
104
  def view_template(&)
86
105
  vanish(&)
87
106
 
88
- div(id: @id, data: @data_attributes_builder.for_container) do
107
+ div(**mix({ data: @data_attributes_builder.for_container }, @html_attributes)) do
89
108
  build_tabs_with_optional_right_content
90
- div(id: "#{@id}-content", class: @contents_class) { build_content }
109
+ build_content
91
110
  end
92
111
  end
93
112
 
@@ -103,15 +122,34 @@ module BulmaPhlex
103
122
  end
104
123
 
105
124
  def build_tabs
106
- div(class: "tabs #{@tabs_class}".strip) do
107
- ul(id: "#{@id}-tabs") do
125
+ attributes = {}
126
+ attributes[:id] = "#{@html_attributes[:id]}-tabs" if @html_attributes[:id]
127
+
128
+ div(class: tabs_classes) do
129
+ ul(**attributes) do
108
130
  @tabs.each { render it }
109
131
  end
110
132
  end
111
133
  end
112
134
 
135
+ def tabs_classes
136
+ classes = ["tabs"]
137
+ classes << "is-boxed" if @boxed
138
+ classes << "is-#{@align}" if @align
139
+ classes << "is-#{@size}" if @size
140
+ classes << "is-toggle" if @toggle
141
+ classes << "is-toggle-rounded" if @rounded
142
+ classes << "is-fullwidth" if @fullwidth
143
+ classes
144
+ end
145
+
113
146
  def build_content
114
- @contents.each { render it }
147
+ attributes = {}
148
+ attributes[:id] = "#{@html_attributes[:id]}-content" if @html_attributes[:id]
149
+
150
+ div(**attributes) do
151
+ @contents.each { render it }
152
+ end
115
153
  end
116
154
  end
117
155
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BulmaPhlex
4
- VERSION = "0.10.0"
4
+ VERSION = "0.11.0"
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bulma-phlex
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Todd Kummer
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-02-01 00:00:00.000000000 Z
10
+ date: 2026-02-13 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: phlex
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: 2.0.2
18
+ version: 2.4.1
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: 2.0.2
25
+ version: 2.4.1
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: actionpack
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -65,6 +65,7 @@ files:
65
65
  - lib/bulma-phlex.rb
66
66
  - lib/bulma_phlex.rb
67
67
  - lib/bulma_phlex/base.rb
68
+ - lib/bulma_phlex/button.rb
68
69
  - lib/bulma_phlex/card.rb
69
70
  - lib/bulma_phlex/columns.rb
70
71
  - lib/bulma_phlex/dropdown.rb
@@ -77,6 +78,7 @@ files:
77
78
  - lib/bulma_phlex/navigation_bar_dropdown.rb
78
79
  - lib/bulma_phlex/notification.rb
79
80
  - lib/bulma_phlex/pagination.rb
81
+ - lib/bulma_phlex/progress_bar.rb
80
82
  - lib/bulma_phlex/tab_components/content.rb
81
83
  - lib/bulma_phlex/tab_components/tab.rb
82
84
  - lib/bulma_phlex/table.rb