bulma-phlex 0.16.0 → 0.17.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: 358df6739ab960f7d8b3799001c40b0d80a6e1c1d599b31b115b67bdcae46645
4
- data.tar.gz: 54a368dec6bf6dfa7c21f32779e63651bea141070367880f7b1b938da86c92f3
3
+ metadata.gz: 6a4e33701b1ed15897b743789cc3fb1923fdaf70fd065035f8342836058927ed
4
+ data.tar.gz: 772252cf5d5660a0a926f4d24a2ffd73898947a6db4ce3f8ea880978acdda0bf
5
5
  SHA512:
6
- metadata.gz: 81cea339f39b95a17bd43e18f294944327744c81601fb03d1d7e7975e397973ebfa488350540eeb008e587c74ae3805ce8ff3ec15aa193277bd68bae03cee201
7
- data.tar.gz: 021f7fc3b32d02a16c1c08a695e915b8beca73219b86da9766c58077afa5b13e205d337fd2ccace80378905076ccb821d2c9c244313ace1c1c32c38752258045
6
+ metadata.gz: 7ec1799752698497e06b075b7378d18a3b820e80ec9e95c7448eb1999ac93514c785d6a61f95434ba02962edb103aa398bd6994506a0954804af52becb56f9ac
7
+ data.tar.gz: 4071dd6000764651b7a677d1ab6ac94c15b59043692602be997924ec094977f41eaf704222554e89ce33f0a49feadc65eeb680ef8c3d36963034995c7b867570
data/README.md CHANGED
@@ -20,7 +20,9 @@ This gem provides a set of ready-to-use [Phlex](https://github.com/phlex-ruby/ph
20
20
  - [Grid](#grid)
21
21
  - [Hero](#hero)
22
22
  - [Icon](#icon)
23
+ - [Image](#image)
23
24
  - [Level](#level)
25
+ - [Media Object](#media-object)
24
26
  - [Message](#message)
25
27
  - [Modal](#modal)
26
28
  - [NavigationBar](#navigationbar)
@@ -74,7 +76,6 @@ This gem requires:
74
76
  require "bulma-phlex"
75
77
  ```
76
78
 
77
-
78
79
  ## Usage
79
80
 
80
81
  Use the Phlex components in your Rails views or any Ruby application that supports Phlex components.
@@ -93,7 +94,6 @@ end
93
94
 
94
95
  It supports options for **alignment** (centered, right-aligned), **separator** style (arrow, bullet, dot, or succeeds), and **size** (small, medium, large). Items also support an optional `icon` argument.
95
96
 
96
-
97
97
  ### Button
98
98
 
99
99
  Renders a [Bulma button](https://bulma.io/documentation/elements/button/) element with support for color, size, style modifiers, and left/right icons.
@@ -110,11 +110,12 @@ The button label can be passed in as a string or in a block.
110
110
 
111
111
  ### Card
112
112
 
113
- Renders a [Bulma card](https://bulma.io/documentation/components/card/) with an optional header, content area, and footer links. Each section is populated via builder methods on the yielded component.
113
+ Renders a [Bulma card](https://bulma.io/documentation/components/card/) with an optional header, image, content area, and footer links. Each section is populated via builder methods on the yielded component.
114
114
 
115
115
  ```ruby
116
116
  render BulmaPhlex::Card.new do |card|
117
- card.head("Card Title")
117
+ card.header("Card Title")
118
+ card.image(src: "image.jpg", alt: "Card image")
118
119
  card.content do
119
120
  "This is some card content"
120
121
  end
@@ -123,9 +124,10 @@ render BulmaPhlex::Card.new do |card|
123
124
  end
124
125
  ```
125
126
 
126
- Use method `footer_item` for full control of the footer items. Class `footer-item` must be on the outer element
127
- of the block.
127
+ The `header` method accepts a string, for a simple title, or a block for custom content.
128
128
 
129
+ Use method `footer_item` for full control of the footer items. Class `footer-item` must be on the outer element
130
+ of the block.
129
131
 
130
132
  ### Columns
131
133
 
@@ -141,7 +143,6 @@ end
141
143
 
142
144
  The `gap:` option accepts either an integer (0–8) or a hash keyed by breakpoint for responsive gap sizes.
143
145
 
144
-
145
146
  ### Dropdown
146
147
 
147
148
  Renders a [Bulma dropdown](https://bulma.io/documentation/components/dropdown/) menu. Supports click-to-toggle (default, via a Stimulus controller) and hoverable (no JavaScript) modes.
@@ -158,6 +159,11 @@ end
158
159
 
159
160
  Set `click: false` to use hover mode instead of the Stimulus controller.
160
161
 
162
+ Use method `header` to add a non-clickable header item. The method takes an optional `divider` argument. (This is not in the Bulma library.)
163
+
164
+ ```ruby
165
+ dropdown.header("Actions", divider: true)
166
+ ```
161
167
 
162
168
  ### File Upload
163
169
 
@@ -171,7 +177,6 @@ end
171
177
 
172
178
  Set `name: true` to include a file name display element. When enabled, Stimulus data attributes are wired up automatically. The controller is not included in this gem; an [example implementation](https://github.com/RockSolt/bulma-phlex-rails/blob/main/app/javascript/controllers/bulma_phlex/file_input_display_controller.js) is available in the `bulma-phlex-rails` gem.
173
179
 
174
-
175
180
  ### Form Field
176
181
 
177
182
  Renders a [Bulma form field](https://bulma.io/documentation/form/general/#form-field) grouping a label, control, and optional help text. Set the label via the `label` method (string or block) and the input via the `control` method.
@@ -185,7 +190,6 @@ end
185
190
 
186
191
  The `column:` and `grid:` options integrate the field into Bulma's column and grid layout systems. Both accept `true`, a size string, or a breakpoint hash.
187
192
 
188
-
189
193
  ### Grid
190
194
 
191
195
  Renders a [Bulma smart grid](https://bulma.io/documentation/grid/smart-grid/) layout. Supports fixed column counts, auto-count, minimum column width, and independent gap control.
@@ -198,7 +202,6 @@ render BulmaPhlex::Grid.new(minimum_column_width: 16) do
198
202
  end
199
203
  ```
200
204
 
201
-
202
205
  ### Hero
203
206
 
204
207
  Renders a [Bulma hero](https://bulma.io/documentation/layout/hero/) section with support for color and size options.
@@ -215,7 +218,6 @@ render BulmaPhlex::Hero.new(color: "info", size: "large") do |hero|
215
218
  end
216
219
  ```
217
220
 
218
-
219
221
  ### Icon
220
222
 
221
223
  Renders a [Bulma icon](https://bulma.io/documentation/elements/icon/) element. Supports color, size, optional text alongside the icon, and left/right positioning for use inside form controls.
@@ -225,6 +227,21 @@ render BulmaPhlex::Icon.new("fas fa-user")
225
227
  render BulmaPhlex::Icon.new("fas fa-home", size: :large, color: :primary, text_right: "Home")
226
228
  ```
227
229
 
230
+ ### Image
231
+
232
+ Renders a [Bulma image](https://bulma.io/documentation/elements/image/) element. Supports size, ratio, rounded, and additional HTML attributes (on either the wrapping `figure` element or the `img` element).
233
+
234
+ ```ruby
235
+ render BulmaPhlex::Image.new(src: "image.jpg", size: 64)
236
+
237
+ render BulmaPhlex::Image.new(
238
+ src: "image.jpg",
239
+ alt: "An image",
240
+ rounded: true,
241
+ ratio: "16by9",
242
+ img_attributes: { class: "custom-img-class", id: "image-id" },
243
+ class: "custom-class", id: "figure-image-id")
244
+ ```
228
245
 
229
246
  ### Level
230
247
 
@@ -237,6 +254,26 @@ render BulmaPhlex::Level.new do |level|
237
254
  end
238
255
  ```
239
256
 
257
+ ### Media Object
258
+
259
+ Renders a [Bulma media object](https://bulma.io/documentation/layout/media-object/) with an optional left image/icon, right content, and main body content. Each section is populated via builder methods on the yielded component.
260
+
261
+ ```ruby
262
+ render BulmaPhlex::MediaObject.new do |media|
263
+ media.left { img(src: "/avatar.png", alt: "Avatar") }
264
+ media.content { "This is the main content of the media object." }
265
+ media.right { button(class: "button is-small") { "Action" } }
266
+ end
267
+ ```
268
+
269
+ If the left content is an image, method `image` can be used instead of `left` to automatically build the supporting HTML structure.
270
+
271
+ ```ruby
272
+ render BulmaPhlex::MediaObject.new do |media|
273
+ media.image(src: "/avatar.png", alt: "Avatar", size: 64, rounded: true)
274
+ media.content { "This is the main content of the media object." }
275
+ end
276
+ ```
240
277
 
241
278
  ### Message
242
279
 
@@ -248,7 +285,6 @@ render BulmaPhlex::Message.new("Hello World", color: "info", delete: true) do
248
285
  end
249
286
  ```
250
287
 
251
-
252
288
  ### Modal
253
289
 
254
290
  Renders a [Bulma modal](https://bulma.io/documentation/components/modal/) dialog overlay with a background, content area, and close button. Content is provided via a block.
@@ -264,7 +300,6 @@ end
264
300
 
265
301
  The modal is shown by adding the `is-active` class to the container — nothing in the component does this automatically. The default Stimulus controller (`bulma-phlex--modal`) handles open/close behavior. Pass a custom `data_attributes_builder:` to integrate with a different JavaScript setup.
266
302
 
267
-
268
303
  ### NavigationBar
269
304
 
270
305
  Renders a [Bulma navbar](https://bulma.io/documentation/components/navbar/) with support for branding, left/right nav links, and dropdown menus. Collapses automatically on mobile via the `bulma-phlex--navigation-bar` Stimulus controller (provided by the `bulma-phlex-rails` gem).
@@ -287,7 +322,6 @@ end
287
322
  > [!NOTE]
288
323
  > Setting `container: true` (or a constraint string like `"is-max-desktop"`) wraps the navbar content in a Bulma container for fixed-width layout. The navbar's background color still spans the full viewport width.
289
324
 
290
-
291
325
  ### Notification
292
326
 
293
327
  Renders a [Bulma notification](https://bulma.io/documentation/elements/notification/) alert box with support for color and mode options.
@@ -306,7 +340,6 @@ render BulmaPhlex::Notification.new(color: "warning", delete: { data: { action:
306
340
  end
307
341
  ```
308
342
 
309
-
310
343
  ### Pagination
311
344
 
312
345
  Renders the [Bulma pagination](https://bulma.io/documentation/components/pagination/) component with previous/next links, numbered page links, ellipses for skipped ranges, and an item count summary. Only renders when there is more than one page of results.
@@ -317,7 +350,6 @@ render BulmaPhlex::Pagination.new(@products, ->(page) { products_path(page: page
317
350
 
318
351
  The first argument must be a pager object responding to `current_page`, `total_pages`, `per_page`, `total_count`, `previous_page`, and `next_page`.
319
352
 
320
-
321
353
  ### Progress Bar
322
354
 
323
355
  Renders a [Bulma progress bar](https://bulma.io/documentation/elements/progress/) element. Supports color and size options.
@@ -328,7 +360,6 @@ render BulmaPhlex::ProgressBar.new(color: "success", size: "large", value: 75, m
328
360
 
329
361
  Omitting `value:` and `max:` produces an indeterminate (animated) progress bar.
330
362
 
331
-
332
363
  ### Table
333
364
 
334
365
  Renders a [Bulma table](https://bulma.io/documentation/elements/table/) for a collection of records. Columns are defined via builder methods on the yielded component.
@@ -354,7 +385,7 @@ To add pagination to the table, call `paginate` with a block that returns a path
354
385
  table.paginate { |page| products_path(page: page) }
355
386
  ```
356
387
 
357
- Pass HTML attributes to the `tr` elements via the `row` method, using either keyword arguments or a block
388
+ Pass HTML attributes to the `tr` elements via the `row` method, using either keyword arguments or a block
358
389
  that receives the record for the row:
359
390
 
360
391
  ```ruby
@@ -367,7 +398,6 @@ Hide columns on smaller screens with the column `hidden` option:
367
398
  table.column("Email", hidden: { mobile: true }) { |user| user.email }
368
399
  ```
369
400
 
370
-
371
401
  ### Tabs
372
402
 
373
403
  Renders a [Bulma tabs](https://bulma.io/documentation/components/tabs/) component with tabbed navigation and associated content panels. Supports alignment, size, and style options (boxed, toggle, rounded, fullwidth).
@@ -383,7 +413,6 @@ Tab switching is handled by the `bulma-phlex--tabs` Stimulus controller. The con
383
413
 
384
414
  An optional right-side element (e.g. a button) can be placed alongside the tab bar via `right_content`.
385
415
 
386
-
387
416
  ### Tag
388
417
 
389
418
  Renders the [Bulma tag](https://bulma.io/documentation/elements/tag/) component. Supports color, size, rounded, and an optional inline delete button.
@@ -395,7 +424,6 @@ render BulmaPhlex::Tag.new("Sale", light: "danger")
395
424
 
396
425
  The element type is inferred from the attributes: an `href:` produces an `<a>`, a `data-action` or `delete: true` produces a `<button>`, and otherwise a `<span>` is used.
397
426
 
398
-
399
427
  ### Title and Subtitle
400
428
 
401
429
  Renders a [Bulma title](https://bulma.io/documentation/elements/title/) with an optional subtitle. Supports sizes 1–6 for both elements and a `spaced:` option to increase the gap between them.
@@ -407,13 +435,12 @@ render BulmaPhlex::Title.new("Dr. Strangelove", size: 2, subtitle: "Or: How I Le
407
435
 
408
436
  When `size:` is set but `subtitle_size:` is not, the subtitle size defaults to `size + 2`.
409
437
 
410
-
411
438
  ## Upgrading to 0.8
412
439
 
413
440
  > [!IMPORTANT]
414
441
  > The 0.8.0 release includes breaking changes. The namespace for the components has been changed from `Components::Bulma` to `Components::BulmaPhlex`.
415
442
 
416
- This can generally be handled with a *Find-and-Replace*:
443
+ This can generally be handled with a _Find-and-Replace_:
417
444
 
418
445
  **Find:** `Bulma::`
419
446
  **Replace:** `BulmaPhlex::`
@@ -422,7 +449,6 @@ Note that this change was also applied to the expected Stimulus controllers. Ref
422
449
 
423
450
  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.
424
451
 
425
-
426
452
  ## Development
427
453
 
428
454
  After checking out the repo, run `bundle install` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -3,7 +3,7 @@
3
3
  module BulmaPhlex
4
4
  # Renders a [Bulma card](https://bulma.io/documentation/components/card/) component.
5
5
  #
6
- # Supports an optional **header** (with title and custom classes), a **content** area, and a
6
+ # Supports an optional **header** (with title and custom classes), an **image**, a **content** area, and a
7
7
  # **footer** with one or more link items (which can include icons). Each section is populated
8
8
  # via builder methods on the yielded component.
9
9
  #
@@ -32,8 +32,9 @@ module BulmaPhlex
32
32
  def view_template(&)
33
33
  vanish(&)
34
34
 
35
- div(**mix(class: "card", **@html_attributes)) do
35
+ div(**mix({ class: "card" }, **@html_attributes)) do
36
36
  card_header
37
+ card_image
37
38
  card_content
38
39
  card_footer
39
40
  end
@@ -44,8 +45,28 @@ module BulmaPhlex
44
45
  # - `title` — The text to display in the card header
45
46
  # - `classes` — Optional additional CSS classes for the header element
46
47
  def head(title, classes: nil)
48
+ warn "[DEPRECATION] `BulmaPhlex::Card#head` is deprecated. Use `header` instead.", category: :deprecated
49
+
50
+ header(title, class: classes)
51
+ end
52
+
53
+ # in order to use the method name `header`, we need to grab a reference to the method on the base class
54
+ # so it is still available to us
55
+ alias html_header header
56
+
57
+ # Sets the card header. Pass in the title as a string and/or provide a block to render custom content
58
+ # in the header.
59
+ #
60
+ # - `title` — The text to display in the card header (optional)
61
+ # - `**html_attributes` — Additional HTML attributes for the header element (optional)
62
+ def header(title = nil, **html_attributes, &block)
47
63
  @header_title = title
48
- @header_classes = classes
64
+ @header_attributes = html_attributes
65
+ @header_content = block
66
+ end
67
+
68
+ def image(src:, alt: nil, size: nil, rounded: false)
69
+ @image = BulmaPhlex::Image.new(src:, alt:, size:, rounded:)
49
70
  end
50
71
 
51
72
  # Sets the card body content.
@@ -74,10 +95,19 @@ module BulmaPhlex
74
95
  private
75
96
 
76
97
  def card_header
77
- return if @header_title.nil?
98
+ return if @header_title.nil? && @header_content.nil?
99
+
100
+ html_header(**mix({ class: "card-header" }, @header_attributes)) do
101
+ p(class: "card-header-title") { plain @header_title } if @header_title
102
+ @header_content&.call
103
+ end
104
+ end
105
+
106
+ def card_image
107
+ return if @image.nil?
78
108
 
79
- header(class: "card-header #{@header_classes}") do
80
- p(class: "card-header-title") { plain @header_title }
109
+ div(class: "card-image") do
110
+ render @image
81
111
  end
82
112
  end
83
113
 
@@ -85,7 +115,7 @@ module BulmaPhlex
85
115
  return if @card_content.nil?
86
116
 
87
117
  div(class: "card-content") do
88
- div(class: "content") { @card_content.call }
118
+ @card_content.call
89
119
  end
90
120
  end
91
121
 
@@ -61,20 +61,28 @@ module BulmaPhlex
61
61
  end
62
62
  end
63
63
 
64
- def item(content = nil, &)
64
+ # Adds a non-clickable header item to the dropdown menu. Optionally add a divider before the header with
65
+ # the `divder: true` parameter.
66
+ def header(label, divider: false)
67
+ self.divider if divider
68
+ div(class: "dropdown-item has-text-weight-semibold is-unselectable") { label }
69
+ end
70
+
71
+ def item(content = nil, **html_attributes, &)
72
+ attributes = mix({ class: "dropdown-item" }, html_attributes)
65
73
  if block_given?
66
- div(class: "dropdown-item", &)
74
+ div(**attributes, &)
67
75
  else
68
- div(class: "dropdown-item") { content }
76
+ div(**attributes) { content }
69
77
  end
70
78
  end
71
79
 
72
- def link(label, path)
73
- a(class: "dropdown-item", href: path) { label }
80
+ def link(label, path, **html_attributes)
81
+ a(**mix({ class: "dropdown-item" }, html_attributes), href: path) { label }
74
82
  end
75
83
 
76
- def divider
77
- hr(class: "dropdown-divider")
84
+ def divider(**html_attributes)
85
+ hr(**mix({ class: "dropdown-divider" }, html_attributes))
78
86
  end
79
87
 
80
88
  private
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BulmaPhlex
4
+ # Renders a [Bulma image](https://bulma.io/documentation/elements/image/) component.
5
+ class Image < BulmaPhlex::Base
6
+ # **Parameters**
7
+ #
8
+ # - `src:` — The image source URL (required)
9
+ # - `alt:` — The image alt text (optional)
10
+ # - `rounded:` — Whether to apply the `is-rounded` class (optional, default: false)
11
+ # - `size:` — The image size (optional, e.g., 64 for `is-64x64`)
12
+ # - `ratio:` — The image ratio (optional, e.g., "1by1", "4by3", "16by9")
13
+ # - `img_attributes:` — Additional HTML attributes for the img element (optional)
14
+ # - `**html_attributes` — Additional HTML attributes for the figure element (optional)
15
+ def self.new(src:, alt: nil, rounded: false, size: nil, ratio: nil, img_attributes: {}, **html_attributes)
16
+ super
17
+ end
18
+
19
+ def initialize(src:, alt: nil, rounded: false, size: nil, ratio: nil, img_attributes: {}, **html_attributes)
20
+ @src = src
21
+ @alt = alt
22
+ @rounded = rounded
23
+ @size = size
24
+ @ratio = ratio
25
+ @img_attributes = img_attributes
26
+ @html_attributes = html_attributes
27
+ end
28
+
29
+ def view_template
30
+ figure(**mix({ class: figure_classes }, @html_attributes)) do
31
+ img(**mix({ src: @src, alt: @alt, class: img_classes }, @img_attributes))
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def figure_classes
38
+ classes = ["image"]
39
+ classes << "is-#{@size}x#{@size}" if @size
40
+ classes << "is-#{@ratio}" if @ratio
41
+ classes.join(" ")
42
+ end
43
+
44
+ def img_classes
45
+ "is-rounded" if @rounded
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BulmaPhlex
4
+ # Renders a [Bulma media object](https://bulma.io/documentation/components/media-object/) component.
5
+ #
6
+ # Optional HTML attributes can be passed to the constructor as well as any of the three block methods,
7
+ # `left`, `content`, and `right`, to customize the rendered HTML elements.
8
+ #
9
+ # ## Example
10
+ #
11
+ # render BulmaPhlex::MediaObject.new do |media|
12
+ # media.left do
13
+ # p(class: "image is-64x64") do
14
+ # img(src: "/assets/images/placeholders/128x128.png")
15
+ # end
16
+ # end
17
+ #
18
+ # media.content do
19
+ # p { "This is the main content of the media object." }
20
+ # end
21
+ #
22
+ # media.right do
23
+ # button(class: "delete")
24
+ # end
25
+ # end
26
+ class MediaObject < BulmaPhlex::Base
27
+ # **Parameters**
28
+ #
29
+ # - `**html_attributes` — Additional HTML attributes for the wrapping `article` element
30
+ def self.new(**html_attributes)
31
+ super
32
+ end
33
+
34
+ def initialize(**html_attributes)
35
+ @html_attributes = html_attributes
36
+ end
37
+
38
+ def view_template(&)
39
+ vanish(&)
40
+
41
+ article(**mix({ class: "media" }, @html_attributes)) do
42
+ render_media_left if @media_left
43
+ render_media_content if @media_content
44
+ render_media_right if @media_right
45
+ end
46
+ end
47
+
48
+ # Use a block to provide the left content, which will be wrapped in a `figure` element. Additional
49
+ # HTML attributes can be passed to customize the element.
50
+ #
51
+ # <figure class="media-left">
52
+ # <!-- Left content goes here -->
53
+ # </figure>
54
+ def left(**html_attributes, &block)
55
+ @left_attributes = html_attributes
56
+ @media_left = block
57
+ end
58
+
59
+ # If the left content is an image, you can use this method to provide the image source,
60
+ # alt text, size, and whether it should be rounded. Additional HTML attributes can be
61
+ # passed to customize the `figure` element.
62
+ def image(src:, alt: nil, size: nil, rounded: false, **html_attributes)
63
+ left(**html_attributes) do
64
+ p(class: image_classes(size:)) do
65
+ img(src:, alt:, class: ("is-rounded" if rounded))
66
+ end
67
+ end
68
+ end
69
+
70
+ # Use a block to provide the main content, which will be wrapped in a `div` element. Additional
71
+ # HTML attributes can be passed to customize the element.
72
+ #
73
+ # <div class="media-content">
74
+ # <!-- Main content goes here -->
75
+ # </div>
76
+ def content(**html_attributes, &block)
77
+ @content_attributes = html_attributes
78
+ @media_content = block
79
+ end
80
+
81
+ # Use a block to provide the right content, which will be wrapped in a `div` element. Additional
82
+ # HTML attributes can be passed to customize the element.
83
+ #
84
+ # <div class="media-right">
85
+ # <!-- Right content goes here -->
86
+ # </div>
87
+ def right(**html_attributes, &block)
88
+ @right_attributes = html_attributes
89
+ @media_right = block
90
+ end
91
+
92
+ private
93
+
94
+ def render_media_left
95
+ figure(**mix({ class: "media-left" }, @left_attributes)) do
96
+ @media_left.call
97
+ end
98
+ end
99
+
100
+ def render_media_content
101
+ div(**mix({ class: "media-content" }, @content_attributes)) do
102
+ @media_content.call
103
+ end
104
+ end
105
+
106
+ def render_media_right
107
+ div(**mix({ class: "media-right" }, @right_attributes)) do
108
+ @media_right.call
109
+ end
110
+ end
111
+
112
+ def image_classes(size:)
113
+ classes = ["image"]
114
+ classes << "is-#{size}x#{size}" if size
115
+ classes.join(" ")
116
+ end
117
+ end
118
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BulmaPhlex
4
- VERSION = "0.16.0"
4
+ VERSION = "0.17.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.16.0
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Todd Kummer
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-05-27 00:00:00.000000000 Z
10
+ date: 2026-07-21 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: phlex
@@ -76,7 +76,9 @@ files:
76
76
  - lib/bulma_phlex/grid.rb
77
77
  - lib/bulma_phlex/hero.rb
78
78
  - lib/bulma_phlex/icon.rb
79
+ - lib/bulma_phlex/image.rb
79
80
  - lib/bulma_phlex/level.rb
81
+ - lib/bulma_phlex/media_object.rb
80
82
  - lib/bulma_phlex/message.rb
81
83
  - lib/bulma_phlex/modal.rb
82
84
  - lib/bulma_phlex/navigation_bar.rb