bulma-phlex 0.16.0 → 0.18.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 +147 -29
- data/lib/bulma_phlex/card.rb +38 -8
- data/lib/bulma_phlex/configuration.rb +28 -0
- data/lib/bulma_phlex/dropdown.rb +19 -11
- data/lib/bulma_phlex/file_upload.rb +5 -1
- data/lib/bulma_phlex/form_control.rb +2 -2
- data/lib/bulma_phlex/form_field.rb +2 -2
- data/lib/bulma_phlex/icon.rb +19 -6
- data/lib/bulma_phlex/image.rb +48 -0
- data/lib/bulma_phlex/media_object.rb +118 -0
- data/lib/bulma_phlex/menu.rb +95 -0
- data/lib/bulma_phlex/modal.rb +8 -3
- data/lib/bulma_phlex/navigation_bar_dropdown.rb +43 -11
- data/lib/bulma_phlex/tab_components/tab.rb +1 -1
- data/lib/bulma_phlex/table/sort.rb +111 -0
- data/lib/bulma_phlex/table.rb +26 -11
- data/lib/bulma_phlex/tabs.rb +3 -3
- data/lib/bulma_phlex/version.rb +1 -1
- data/lib/bulma_phlex.rb +10 -0
- metadata +7 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d62a43330834f293718993ab3227796dbb76d3ae57b4c0efca10df5dc1e35a6b
|
|
4
|
+
data.tar.gz: 1b310813d75fe054a993a02d258a05fa52ba4f15db249d2e269c1871fdf2a025
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a0b4c95ba751e8a2f5718b08bcd389ebe055f087271a1ee77f06c2e9292088bc4a770aeeacdb31c304349ac372373cd40ae5fd90f498eef15a1c6502732028cc
|
|
7
|
+
data.tar.gz: 2579cf14a6d59153dc4e44781eba67b451513e50d551e59141be6f61be9d130862c6553643b150393941a40f7ea99f10f40ff10dd824489ea12d18afdaeff875
|
data/README.md
CHANGED
|
@@ -9,6 +9,7 @@ This gem provides a set of ready-to-use [Phlex](https://github.com/phlex-ruby/ph
|
|
|
9
9
|
## Table of Contents
|
|
10
10
|
|
|
11
11
|
- [Installation](#installation)
|
|
12
|
+
- [Configuration](#configuration)
|
|
12
13
|
- [Usage](#usage)
|
|
13
14
|
- [Breadcrumb](#breadcrumb)
|
|
14
15
|
- [Button](#button)
|
|
@@ -20,7 +21,10 @@ This gem provides a set of ready-to-use [Phlex](https://github.com/phlex-ruby/ph
|
|
|
20
21
|
- [Grid](#grid)
|
|
21
22
|
- [Hero](#hero)
|
|
22
23
|
- [Icon](#icon)
|
|
24
|
+
- [Image](#image)
|
|
23
25
|
- [Level](#level)
|
|
26
|
+
- [Media Object](#media-object)
|
|
27
|
+
- [Menu](#menu)
|
|
24
28
|
- [Message](#message)
|
|
25
29
|
- [Modal](#modal)
|
|
26
30
|
- [NavigationBar](#navigationbar)
|
|
@@ -74,6 +78,24 @@ This gem requires:
|
|
|
74
78
|
require "bulma-phlex"
|
|
75
79
|
```
|
|
76
80
|
|
|
81
|
+
## Configuration
|
|
82
|
+
|
|
83
|
+
Icons chosen internally by components can be configured globally. The default icons are Font Awesome 7 solid icons, but you can change them to other icons by providing the appropriate class names.
|
|
84
|
+
|
|
85
|
+
```ruby
|
|
86
|
+
BulmaPhlex.configure do |config|
|
|
87
|
+
config.icons.sort = {
|
|
88
|
+
ascending: "fa-solid fa-arrow-up",
|
|
89
|
+
descending: "fa-solid fa-arrow-down",
|
|
90
|
+
inactive: "fa-solid fa-sort"
|
|
91
|
+
}
|
|
92
|
+
config.icons.dropdown = "fa-solid fa-chevron-down"
|
|
93
|
+
config.icons.file_upload = "fa-solid fa-upload"
|
|
94
|
+
config.icons.conditional = "fa-solid fa-check"
|
|
95
|
+
end
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Sortable columns also accept an `icons:` hash for a per-column override. Dropdowns accept `icon:` and conditional table columns accept `icon_class:`.
|
|
77
99
|
|
|
78
100
|
## Usage
|
|
79
101
|
|
|
@@ -93,7 +115,6 @@ end
|
|
|
93
115
|
|
|
94
116
|
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
117
|
|
|
96
|
-
|
|
97
118
|
### Button
|
|
98
119
|
|
|
99
120
|
Renders a [Bulma button](https://bulma.io/documentation/elements/button/) element with support for color, size, style modifiers, and left/right icons.
|
|
@@ -101,7 +122,7 @@ Renders a [Bulma button](https://bulma.io/documentation/elements/button/) elemen
|
|
|
101
122
|
The component generates a `<button>` by default. Pass an `href:` attribute to generate an `<a>` element instead. Pass `input: "submit"` (or `"button"` or `"reset"`) to generate an `<input>` element.
|
|
102
123
|
|
|
103
124
|
```ruby
|
|
104
|
-
BulmaPhlex::Button("Like", color: "primary", size: "large", icon: "
|
|
125
|
+
BulmaPhlex::Button("Like", color: "primary", size: "large", icon: "fa-solid fa-thumbs-up")
|
|
105
126
|
BulmaPhlex::Button(href: "/profile") { "View Profile" }
|
|
106
127
|
BulmaPhlex::Button(input: "submit", color: "success")
|
|
107
128
|
```
|
|
@@ -110,22 +131,24 @@ The button label can be passed in as a string or in a block.
|
|
|
110
131
|
|
|
111
132
|
### Card
|
|
112
133
|
|
|
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.
|
|
134
|
+
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
135
|
|
|
115
136
|
```ruby
|
|
116
137
|
render BulmaPhlex::Card.new do |card|
|
|
117
|
-
card.
|
|
138
|
+
card.header("Card Title")
|
|
139
|
+
card.image(src: "image.jpg", alt: "Card image")
|
|
118
140
|
card.content do
|
|
119
141
|
"This is some card content"
|
|
120
142
|
end
|
|
121
143
|
card.footer_link("View", "/view", target: "_blank")
|
|
122
|
-
card.footer_link("Edit", "/edit", icon: "
|
|
144
|
+
card.footer_link("Edit", "/edit", icon: "fa-solid fa-pen-to-square")
|
|
123
145
|
end
|
|
124
146
|
```
|
|
125
147
|
|
|
126
|
-
|
|
127
|
-
of the block.
|
|
148
|
+
The `header` method accepts a string, for a simple title, or a block for custom content.
|
|
128
149
|
|
|
150
|
+
Use method `footer_item` for full control of the footer items. Class `footer-item` must be on the outer element
|
|
151
|
+
of the block.
|
|
129
152
|
|
|
130
153
|
### Columns
|
|
131
154
|
|
|
@@ -141,7 +164,6 @@ end
|
|
|
141
164
|
|
|
142
165
|
The `gap:` option accepts either an integer (0–8) or a hash keyed by breakpoint for responsive gap sizes.
|
|
143
166
|
|
|
144
|
-
|
|
145
167
|
### Dropdown
|
|
146
168
|
|
|
147
169
|
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 +180,11 @@ end
|
|
|
158
180
|
|
|
159
181
|
Set `click: false` to use hover mode instead of the Stimulus controller.
|
|
160
182
|
|
|
183
|
+
Use method `header` to add a non-clickable header item. The method takes an optional `divider` argument. (This is not in the Bulma library.)
|
|
184
|
+
|
|
185
|
+
```ruby
|
|
186
|
+
dropdown.header("Actions", divider: true)
|
|
187
|
+
```
|
|
161
188
|
|
|
162
189
|
### File Upload
|
|
163
190
|
|
|
@@ -171,7 +198,6 @@ end
|
|
|
171
198
|
|
|
172
199
|
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
200
|
|
|
174
|
-
|
|
175
201
|
### Form Field
|
|
176
202
|
|
|
177
203
|
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 +211,6 @@ end
|
|
|
185
211
|
|
|
186
212
|
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
213
|
|
|
188
|
-
|
|
189
214
|
### Grid
|
|
190
215
|
|
|
191
216
|
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 +223,6 @@ render BulmaPhlex::Grid.new(minimum_column_width: 16) do
|
|
|
198
223
|
end
|
|
199
224
|
```
|
|
200
225
|
|
|
201
|
-
|
|
202
226
|
### Hero
|
|
203
227
|
|
|
204
228
|
Renders a [Bulma hero](https://bulma.io/documentation/layout/hero/) section with support for color and size options.
|
|
@@ -215,16 +239,33 @@ render BulmaPhlex::Hero.new(color: "info", size: "large") do |hero|
|
|
|
215
239
|
end
|
|
216
240
|
```
|
|
217
241
|
|
|
218
|
-
|
|
219
242
|
### Icon
|
|
220
243
|
|
|
221
244
|
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.
|
|
222
245
|
|
|
246
|
+
When text is rendered alongside the icon, Bulma allows the text and icon to wrap by default. Pass `nowrap: true` when they form a compact UI unit that should stay together, such as a sortable table heading, toolbar action, button label, or navigation item. Leave it unset when the text should be allowed to wrap in a constrained container.
|
|
247
|
+
|
|
223
248
|
```ruby
|
|
224
|
-
render BulmaPhlex::Icon.new("
|
|
225
|
-
render BulmaPhlex::Icon.new("
|
|
249
|
+
render BulmaPhlex::Icon.new("fa-solid fa-user")
|
|
250
|
+
render BulmaPhlex::Icon.new("fa-solid fa-home", size: :large, color: :primary, text_right: "Home")
|
|
251
|
+
render BulmaPhlex::Icon.new("fa-solid fa-sort", text_left: "Revenue", nowrap: true)
|
|
226
252
|
```
|
|
227
253
|
|
|
254
|
+
### Image
|
|
255
|
+
|
|
256
|
+
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).
|
|
257
|
+
|
|
258
|
+
```ruby
|
|
259
|
+
render BulmaPhlex::Image.new(src: "image.jpg", size: 64)
|
|
260
|
+
|
|
261
|
+
render BulmaPhlex::Image.new(
|
|
262
|
+
src: "image.jpg",
|
|
263
|
+
alt: "An image",
|
|
264
|
+
rounded: true,
|
|
265
|
+
ratio: "16by9",
|
|
266
|
+
img_attributes: { class: "custom-img-class", id: "image-id" },
|
|
267
|
+
class: "custom-class", id: "figure-image-id")
|
|
268
|
+
```
|
|
228
269
|
|
|
229
270
|
### Level
|
|
230
271
|
|
|
@@ -237,6 +278,65 @@ render BulmaPhlex::Level.new do |level|
|
|
|
237
278
|
end
|
|
238
279
|
```
|
|
239
280
|
|
|
281
|
+
### Media Object
|
|
282
|
+
|
|
283
|
+
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.
|
|
284
|
+
|
|
285
|
+
```ruby
|
|
286
|
+
render BulmaPhlex::MediaObject.new do |media|
|
|
287
|
+
media.left { img(src: "/avatar.png", alt: "Avatar") }
|
|
288
|
+
media.content { "This is the main content of the media object." }
|
|
289
|
+
media.right { button(class: "button is-small") { "Action" } }
|
|
290
|
+
end
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
If the left content is an image, method `image` can be used instead of `left` to automatically build the supporting HTML structure.
|
|
294
|
+
|
|
295
|
+
```ruby
|
|
296
|
+
render BulmaPhlex::MediaObject.new do |media|
|
|
297
|
+
media.image(src: "/avatar.png", alt: "Avatar", size: 64, rounded: true)
|
|
298
|
+
media.content { "This is the main content of the media object." }
|
|
299
|
+
end
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Menu
|
|
303
|
+
|
|
304
|
+
Renders a [Bulma menu](https://bulma.io/documentation/components/menu/) with support for labels, lists, and nested lists.
|
|
305
|
+
|
|
306
|
+
```ruby
|
|
307
|
+
render BulmaPhlex::Menu.new do |menu|
|
|
308
|
+
menu.label("General")
|
|
309
|
+
menu.list do
|
|
310
|
+
menu.item("Dashboard", href: "/dashboard", active: true)
|
|
311
|
+
menu.item("Customers", href: "/customers")
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
menu.label("Administration")
|
|
315
|
+
menu.list do
|
|
316
|
+
menu.item("Team Settings", href: "/teams/settings")
|
|
317
|
+
menu.item("Manage Your Team", href: "/teams/dashboard") do
|
|
318
|
+
menu.item("Members", href: "/members")
|
|
319
|
+
menu.item("Plugins", href: "/plugins")
|
|
320
|
+
menu.item("Add a member", href: "/add-member")
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Nested lists can be created by passing a block to the `item` method. An expandable section (header opens and closes but is not a link) can be created with the `expandable_item` method.
|
|
327
|
+
|
|
328
|
+
```ruby
|
|
329
|
+
render BulmaPhlex::Menu.new do |menu|
|
|
330
|
+
menu.label("General")
|
|
331
|
+
menu.list do
|
|
332
|
+
menu.item("Dashboard", href: "/dashboard", active: true)
|
|
333
|
+
menu.expandable_item("Customers") do
|
|
334
|
+
menu.item("Active Customers", href: "/customers/active")
|
|
335
|
+
menu.item("Inactive Customers", href: "/customers/inactive")
|
|
336
|
+
end
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
```
|
|
240
340
|
|
|
241
341
|
### Message
|
|
242
342
|
|
|
@@ -248,7 +348,6 @@ render BulmaPhlex::Message.new("Hello World", color: "info", delete: true) do
|
|
|
248
348
|
end
|
|
249
349
|
```
|
|
250
350
|
|
|
251
|
-
|
|
252
351
|
### Modal
|
|
253
352
|
|
|
254
353
|
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 +363,6 @@ end
|
|
|
264
363
|
|
|
265
364
|
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
365
|
|
|
267
|
-
|
|
268
366
|
### NavigationBar
|
|
269
367
|
|
|
270
368
|
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 +385,6 @@ end
|
|
|
287
385
|
> [!NOTE]
|
|
288
386
|
> 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
387
|
|
|
290
|
-
|
|
291
388
|
### Notification
|
|
292
389
|
|
|
293
390
|
Renders a [Bulma notification](https://bulma.io/documentation/elements/notification/) alert box with support for color and mode options.
|
|
@@ -306,7 +403,6 @@ render BulmaPhlex::Notification.new(color: "warning", delete: { data: { action:
|
|
|
306
403
|
end
|
|
307
404
|
```
|
|
308
405
|
|
|
309
|
-
|
|
310
406
|
### Pagination
|
|
311
407
|
|
|
312
408
|
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 +413,6 @@ render BulmaPhlex::Pagination.new(@products, ->(page) { products_path(page: page
|
|
|
317
413
|
|
|
318
414
|
The first argument must be a pager object responding to `current_page`, `total_pages`, `per_page`, `total_count`, `previous_page`, and `next_page`.
|
|
319
415
|
|
|
320
|
-
|
|
321
416
|
### Progress Bar
|
|
322
417
|
|
|
323
418
|
Renders a [Bulma progress bar](https://bulma.io/documentation/elements/progress/) element. Supports color and size options.
|
|
@@ -328,7 +423,6 @@ render BulmaPhlex::ProgressBar.new(color: "success", size: "large", value: 75, m
|
|
|
328
423
|
|
|
329
424
|
Omitting `value:` and `max:` produces an indeterminate (animated) progress bar.
|
|
330
425
|
|
|
331
|
-
|
|
332
426
|
### Table
|
|
333
427
|
|
|
334
428
|
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.
|
|
@@ -346,7 +440,32 @@ end
|
|
|
346
440
|
In addition to `column`, two specialized column methods are available:
|
|
347
441
|
|
|
348
442
|
- `date_column(header, format: "%Y-%m-%d")` — formats the value with `strftime`
|
|
349
|
-
- `conditional_icon(header, icon_class:
|
|
443
|
+
- `conditional_icon(header, icon_class:)` — shows the configured conditional icon, or the supplied icon, when the block returns truthy
|
|
444
|
+
|
|
445
|
+
#### Sortable columns
|
|
446
|
+
|
|
447
|
+
Pass a sort hash with the URL for the next sort state to add a sortable header. The component renders the sort link, icon, and accessible sort state; your application remains responsible for interpreting the sort parameters and ordering the records.
|
|
448
|
+
|
|
449
|
+
```ruby
|
|
450
|
+
render BulmaPhlex::Table.new(@users) do |table|
|
|
451
|
+
table.column(
|
|
452
|
+
"Name",
|
|
453
|
+
sort: { href: users_path(sort: "name") }
|
|
454
|
+
) { |user| user.full_name }
|
|
455
|
+
|
|
456
|
+
table.date_column(
|
|
457
|
+
"Joined",
|
|
458
|
+
sort: {
|
|
459
|
+
href: users_path(sort: "created_at"),
|
|
460
|
+
current_direction: :descending
|
|
461
|
+
}
|
|
462
|
+
) { |user| user.created_at }
|
|
463
|
+
end
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
Set `current_direction:` to `:ascending` or `:descending` for the currently active column. Pass additional attributes for the generated link with `link_attributes:`. The component generates an accessible label from the column header and sort state.
|
|
467
|
+
|
|
468
|
+
#### Pagination
|
|
350
469
|
|
|
351
470
|
To add pagination to the table, call `paginate` with a block that returns a path given a page number:
|
|
352
471
|
|
|
@@ -354,20 +473,23 @@ To add pagination to the table, call `paginate` with a block that returns a path
|
|
|
354
473
|
table.paginate { |page| products_path(page: page) }
|
|
355
474
|
```
|
|
356
475
|
|
|
357
|
-
|
|
476
|
+
#### Custom row attributes
|
|
477
|
+
|
|
478
|
+
Pass HTML attributes to the `tr` elements via the `row` method, using either keyword arguments or a block
|
|
358
479
|
that receives the record for the row:
|
|
359
480
|
|
|
360
481
|
```ruby
|
|
361
482
|
table.row(class: "custom-row-class") { |row| { id: "row-id-#{row.id}" } }
|
|
362
483
|
```
|
|
363
484
|
|
|
485
|
+
#### Responsive columns
|
|
486
|
+
|
|
364
487
|
Hide columns on smaller screens with the column `hidden` option:
|
|
365
488
|
|
|
366
489
|
```ruby
|
|
367
490
|
table.column("Email", hidden: { mobile: true }) { |user| user.email }
|
|
368
491
|
```
|
|
369
492
|
|
|
370
|
-
|
|
371
493
|
### Tabs
|
|
372
494
|
|
|
373
495
|
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).
|
|
@@ -375,7 +497,7 @@ Renders a [Bulma tabs](https://bulma.io/documentation/components/tabs/) componen
|
|
|
375
497
|
```ruby
|
|
376
498
|
render BulmaPhlex::Tabs.new(boxed: true) do |tabs|
|
|
377
499
|
tabs.tab(id: "profile", title: "Profile", active: true) { "Profile content" }
|
|
378
|
-
tabs.tab(id: "settings", title: "Settings", icon: "
|
|
500
|
+
tabs.tab(id: "settings", title: "Settings", icon: "fa-solid fa-gear") { "Settings content" }
|
|
379
501
|
end
|
|
380
502
|
```
|
|
381
503
|
|
|
@@ -383,7 +505,6 @@ Tab switching is handled by the `bulma-phlex--tabs` Stimulus controller. The con
|
|
|
383
505
|
|
|
384
506
|
An optional right-side element (e.g. a button) can be placed alongside the tab bar via `right_content`.
|
|
385
507
|
|
|
386
|
-
|
|
387
508
|
### Tag
|
|
388
509
|
|
|
389
510
|
Renders the [Bulma tag](https://bulma.io/documentation/elements/tag/) component. Supports color, size, rounded, and an optional inline delete button.
|
|
@@ -395,7 +516,6 @@ render BulmaPhlex::Tag.new("Sale", light: "danger")
|
|
|
395
516
|
|
|
396
517
|
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
518
|
|
|
398
|
-
|
|
399
519
|
### Title and Subtitle
|
|
400
520
|
|
|
401
521
|
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 +527,12 @@ render BulmaPhlex::Title.new("Dr. Strangelove", size: 2, subtitle: "Or: How I Le
|
|
|
407
527
|
|
|
408
528
|
When `size:` is set but `subtitle_size:` is not, the subtitle size defaults to `size + 2`.
|
|
409
529
|
|
|
410
|
-
|
|
411
530
|
## Upgrading to 0.8
|
|
412
531
|
|
|
413
532
|
> [!IMPORTANT]
|
|
414
533
|
> The 0.8.0 release includes breaking changes. The namespace for the components has been changed from `Components::Bulma` to `Components::BulmaPhlex`.
|
|
415
534
|
|
|
416
|
-
This can generally be handled with a
|
|
535
|
+
This can generally be handled with a _Find-and-Replace_:
|
|
417
536
|
|
|
418
537
|
**Find:** `Bulma::`
|
|
419
538
|
**Replace:** `BulmaPhlex::`
|
|
@@ -422,7 +541,6 @@ Note that this change was also applied to the expected Stimulus controllers. Ref
|
|
|
422
541
|
|
|
423
542
|
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
543
|
|
|
425
|
-
|
|
426
544
|
## Development
|
|
427
545
|
|
|
428
546
|
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.
|
data/lib/bulma_phlex/card.rb
CHANGED
|
@@ -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
|
-
@
|
|
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.
|
|
@@ -59,7 +80,7 @@ module BulmaPhlex
|
|
|
59
80
|
#
|
|
60
81
|
# - `text` — The link label text
|
|
61
82
|
# - `href` — The URL the link points to
|
|
62
|
-
# - `icon:` — Optional icon class string (e.g. `"
|
|
83
|
+
# - `icon:` — Optional icon class string (e.g. `"fa-solid fa-pen-to-square"`) to render an icon alongside the text
|
|
63
84
|
# - `**html_attributes` — Additional HTML attributes for the `<a>` element (e.g. `target:`, `class:`)
|
|
64
85
|
def footer_link(text, href, **html_attributes)
|
|
65
86
|
(@footer_items ||= []) << [text, href, html_attributes]
|
|
@@ -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
|
-
|
|
80
|
-
|
|
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
|
-
|
|
118
|
+
@card_content.call
|
|
89
119
|
end
|
|
90
120
|
end
|
|
91
121
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BulmaPhlex
|
|
4
|
+
# Stores application-wide defaults for component-owned icons.
|
|
5
|
+
class Configuration
|
|
6
|
+
# Stores the icon classes used by components when no local override is supplied.
|
|
7
|
+
class Icons
|
|
8
|
+
attr_accessor :sort, :dropdown, :file_upload, :conditional
|
|
9
|
+
|
|
10
|
+
def initialize
|
|
11
|
+
@sort = {
|
|
12
|
+
ascending: "fa-solid fa-sort-up",
|
|
13
|
+
descending: "fa-solid fa-sort-down",
|
|
14
|
+
inactive: "fa-solid fa-sort"
|
|
15
|
+
}
|
|
16
|
+
@dropdown = "fa-solid fa-angle-down"
|
|
17
|
+
@file_upload = "fa-solid fa-upload"
|
|
18
|
+
@conditional = "fa-solid fa-check"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
attr_reader :icons
|
|
23
|
+
|
|
24
|
+
def initialize
|
|
25
|
+
@icons = Icons.new
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
data/lib/bulma_phlex/dropdown.rb
CHANGED
|
@@ -23,19 +23,19 @@ module BulmaPhlex
|
|
|
23
23
|
# - `label` — The text displayed in the dropdown trigger button
|
|
24
24
|
# - `click` — Stimulus controller name for toggling; set to `false` for hover mode instead
|
|
25
25
|
# - `alignment` — Alignment of the dropdown menu: `"left"` (default), `"right"`, or `"up"`
|
|
26
|
-
# - `icon` — Icon class for the trigger button (default:
|
|
26
|
+
# - `icon` — Icon class for the trigger button (default: configured dropdown icon)
|
|
27
27
|
# - `**html_attributes` — Additional HTML attributes for the outermost dropdown element
|
|
28
|
-
def self.new(label, click: "bulma-phlex--dropdown", alignment: "left", icon:
|
|
28
|
+
def self.new(label, click: "bulma-phlex--dropdown", alignment: "left", icon: nil,
|
|
29
29
|
**html_attributes)
|
|
30
30
|
super
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
def initialize(label, click: "bulma-phlex--dropdown", alignment: "left", icon:
|
|
33
|
+
def initialize(label, click: "bulma-phlex--dropdown", alignment: "left", icon: nil,
|
|
34
34
|
**html_attributes)
|
|
35
35
|
@label = label
|
|
36
36
|
@click = click
|
|
37
37
|
@alignment = alignment
|
|
38
|
-
@icon = icon
|
|
38
|
+
@icon = icon || BulmaPhlex.config.icons.dropdown
|
|
39
39
|
@html_attributes = html_attributes
|
|
40
40
|
end
|
|
41
41
|
|
|
@@ -61,20 +61,28 @@ module BulmaPhlex
|
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
|
|
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(
|
|
74
|
+
div(**attributes, &)
|
|
67
75
|
else
|
|
68
|
-
div(
|
|
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
|
|
@@ -25,6 +25,7 @@ module BulmaPhlex
|
|
|
25
25
|
# - `align` — Aligns the file input: `"right"` or `"centered"`
|
|
26
26
|
# - `fullwidth` — If `true`, makes the file input full width
|
|
27
27
|
# - `boxed` — If `true`, makes the file input boxed
|
|
28
|
+
# - `icon` — Icon class for the upload control (default: configured file upload icon)
|
|
28
29
|
# - `data_attributes_builder` — A custom builder for the data attributes used for Stimulus integration;
|
|
29
30
|
# defaults to a builder with the controller name `"bulma-phlex--file-input-display"`
|
|
30
31
|
def self.new(color: nil,
|
|
@@ -33,6 +34,7 @@ module BulmaPhlex
|
|
|
33
34
|
align: nil,
|
|
34
35
|
fullwidth: false,
|
|
35
36
|
boxed: false,
|
|
37
|
+
icon: nil,
|
|
36
38
|
data_attributes_builder: nil)
|
|
37
39
|
super
|
|
38
40
|
end
|
|
@@ -43,6 +45,7 @@ module BulmaPhlex
|
|
|
43
45
|
align: nil,
|
|
44
46
|
fullwidth: false,
|
|
45
47
|
boxed: false,
|
|
48
|
+
icon: nil,
|
|
46
49
|
data_attributes_builder: nil)
|
|
47
50
|
@color = color
|
|
48
51
|
@size = size
|
|
@@ -50,6 +53,7 @@ module BulmaPhlex
|
|
|
50
53
|
@align = align
|
|
51
54
|
@fullwidth = fullwidth
|
|
52
55
|
@boxed = boxed
|
|
56
|
+
@icon = icon || BulmaPhlex.config.icons.file_upload
|
|
53
57
|
|
|
54
58
|
return unless @name
|
|
55
59
|
|
|
@@ -63,7 +67,7 @@ module BulmaPhlex
|
|
|
63
67
|
yield(@data_attributes_builder&.for_file_input)
|
|
64
68
|
span(class: "file-cta") do
|
|
65
69
|
span(class: "file-icon") do
|
|
66
|
-
i(class:
|
|
70
|
+
i(class: @icon)
|
|
67
71
|
end
|
|
68
72
|
span(class: "file-label") { plain " Choose a file… " }
|
|
69
73
|
end
|
|
@@ -6,8 +6,8 @@ module BulmaPhlex
|
|
|
6
6
|
class FormControl < Base
|
|
7
7
|
# **Parameters**
|
|
8
8
|
#
|
|
9
|
-
# - `icon_left` — Icon class for the left side of the control (e.g. `"
|
|
10
|
-
# - `icon_right` — Icon class for the right side of the control (e.g. `"
|
|
9
|
+
# - `icon_left` — Icon class for the left side of the control (e.g. `"fa-solid fa-check"`)
|
|
10
|
+
# - `icon_right` — Icon class for the right side of the control (e.g. `"fa-solid fa-check"`)
|
|
11
11
|
# - `**html_attributes` — Additional HTML attributes for the control element
|
|
12
12
|
def self.new(icon_left: nil, icon_right: nil, **html_attributes)
|
|
13
13
|
super
|
|
@@ -21,8 +21,8 @@ module BulmaPhlex
|
|
|
21
21
|
# **Parameters**
|
|
22
22
|
#
|
|
23
23
|
# - `help` — Optional help text displayed below the input
|
|
24
|
-
# - `icon_left` — Icon class for an icon to the left of the input (e.g. `"
|
|
25
|
-
# - `icon_right` — Icon class for an icon to the right of the input (e.g. `"
|
|
24
|
+
# - `icon_left` — Icon class for an icon to the left of the input (e.g. `"fa-solid fa-user"`)
|
|
25
|
+
# - `icon_right` — Icon class for an icon to the right of the input (e.g. `"fa-solid fa-check"`)
|
|
26
26
|
# - `column` — If `true`, makes the field a column; a size string (e.g. `"half"`) sets the size for
|
|
27
27
|
# all breakpoints; a hash (e.g. `{ mobile: "full", desktop: "half" }`) sets responsive sizes
|
|
28
28
|
# - `grid` — If `true`, makes the field a grid cell; a size string sets the cell size
|