philiprehberger-html_builder 0.6.0 → 0.7.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: 2422583ee49313a76a8eb70b50d6d8de0040b3f8ea9a9e22722013b0ab7537f5
4
- data.tar.gz: b61ca71f0b42e279fdd9fa4375b7d67c7c9c8db7a85cc4c6575d5e9ba455b87e
3
+ metadata.gz: 9a1ed5d63b82c40002240f74e0f808a5e62926efd8b55a0c52b482d804a23bab
4
+ data.tar.gz: 814fd3cf20cf2cf358f25e38d14dcf9f02e84e32827a584c0c94a947d4404f48
5
5
  SHA512:
6
- metadata.gz: 16b555765bd466535c05261da722bdacd670ee72bae7fc635e09de789a02eed4ad6f9020e17404fcb140e34060e1c1be2c5bfff05674e8c5d3867e4f9c8917ed
7
- data.tar.gz: 75d90b85a6a865213dda114f6e3880d1f059a96ebbfbe348ad872b702fd644c5eece3e86bb56bb1237eae573b74c721dcbf004d3377a05503fce95319e200b69
6
+ metadata.gz: 0e0214af812ff0754349ee79c494f544f34b6b5a16852387d3c51c30b1580c7e88f75d0392f4761dacf754c91722cc83015f95131f065c60eaa073df64453217
7
+ data.tar.gz: eb761b219b3a40319752ba84628ed2a7a88f0ea423581619a641a98932a3c39f8deabb83edb077be8c0319436d60f7ccac2f53f5acaa6e63cb5d469e4d04b271
data/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.7.0] - 2026-04-26
11
+
12
+ ### Added
13
+ - `merge_attrs(*hashes)` helper for merging attribute hashes; concatenates `:class` (space-separated) and `:style` (semicolon-separated) values rather than overwriting
14
+ - `aria(**pairs)` helper for building ARIA attribute hashes from snake_case keyword pairs (converted to `aria-kebab-case` string keys; nil values omitted)
15
+
10
16
  ## [0.6.0] - 2026-04-16
11
17
 
12
18
  ### Added
data/README.md CHANGED
@@ -163,6 +163,28 @@ end
163
163
  # => '<ul><li><strong>Alice</strong></li><li><strong>Bob</strong></li></ul>'
164
164
  ```
165
165
 
166
+ ### Attribute Helpers
167
+
168
+ Merge multiple attribute hashes — concatenating `:class` (single space) and `:style` (`'; '`) values rather than overwriting — and build ARIA attribute hashes from snake_case keyword pairs:
169
+
170
+ ```ruby
171
+ Philiprehberger::HtmlBuilder.build do
172
+ base = { class: 'btn', style: 'color: red' }
173
+ variant = { class: 'btn-primary', style: 'font-weight: bold' }
174
+ attrs = merge_attrs(base, variant)
175
+
176
+ button('Save', **attrs)
177
+ end
178
+ # => '<button class="btn btn-primary" style="color: red; font-weight: bold">Save</button>'
179
+
180
+ Philiprehberger::HtmlBuilder.build do
181
+ aria(label: 'Save', expanded: false, describedby: nil)
182
+ end
183
+ # => { 'aria-label' => 'Save', 'aria-expanded' => 'false' }
184
+ ```
185
+
186
+ `merge_attrs` joins `:class` values with a single space and `:style` values with `'; '`. Other keys follow last-write-wins, and input hashes are not mutated. `aria` converts snake_case keys to `aria-kebab-case` string keys, stringifies values, and omits keys whose value is `nil`.
187
+
166
188
  ### CSS Class Helpers
167
189
 
168
190
  Build conditional CSS class strings from mixed arguments. Strings are included as-is, hash keys are included when their value is truthy:
@@ -324,6 +346,8 @@ Philiprehberger::HtmlBuilder.merge(header, body, footer)
324
346
  | `Builder#submit(text, **attrs)` | Generate a submit button (default text "Submit") |
325
347
  | `Builder#list(items, ordered:, **attrs, &block)` | Build a `<ul>` or `<ol>` from an array of items |
326
348
  | `Builder#class_names(*args)` | Build a conditional CSS class string from strings and hashes |
349
+ | `Builder#merge_attrs(*hashes)` | Merge attribute hashes, concatenating `:class` (space) and `:style` (`'; '`) values |
350
+ | `Builder#aria(**pairs)` | Build an ARIA attribute hash from snake_case keys (rendered as `aria-kebab-case`); omits nil values |
327
351
  | `Builder#cache(key) { ... }` | Cache rendered block output by key; return cached HTML on repeat calls |
328
352
  | `Escape.html(value)` | Escape HTML special characters in a string |
329
353
 
@@ -265,6 +265,49 @@ module Philiprehberger
265
265
  result.join(' ')
266
266
  end
267
267
 
268
+ # Merge multiple attribute hashes into one
269
+ #
270
+ # `:class` values are concatenated with a single space, and `:style` values
271
+ # are concatenated with a semicolon and space. All other keys follow last-write-wins
272
+ # semantics. Input hashes are not mutated.
273
+ #
274
+ # @param hashes [Array<Hash>] one or more attribute hashes to merge
275
+ # @return [Hash] the merged attribute hash
276
+ def merge_attrs(*hashes)
277
+ result = {}
278
+ hashes.each do |h|
279
+ next if h.nil?
280
+
281
+ h.each do |key, value|
282
+ if key == :class && result.key?(:class)
283
+ result[:class] = "#{result[:class]} #{value}"
284
+ elsif key == :style && result.key?(:style)
285
+ result[:style] = "#{result[:style]}; #{value}"
286
+ else
287
+ result[key] = value
288
+ end
289
+ end
290
+ end
291
+ result
292
+ end
293
+
294
+ # Build an ARIA attribute hash from keyword pairs
295
+ #
296
+ # snake_case keys are converted to `aria-kebab-case` string keys. Values are
297
+ # converted to strings. Keys whose value is `nil` are omitted from the result.
298
+ #
299
+ # @param pairs [Hash] keyword pairs to convert into ARIA attributes
300
+ # @return [Hash<String, String>] hash with `"aria-*"` string keys and string values
301
+ def aria(**pairs)
302
+ result = {}
303
+ pairs.each do |key, value|
304
+ next if value.nil?
305
+
306
+ result["aria-#{key.to_s.tr('_', '-')}"] = value.to_s
307
+ end
308
+ result
309
+ end
310
+
268
311
  # Cache a rendered block result by key
269
312
  #
270
313
  # On the first call with a given key, the block is executed, its rendered
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Philiprehberger
4
4
  module HtmlBuilder
5
- VERSION = '0.6.0'
5
+ VERSION = '0.7.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philiprehberger-html_builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Philip Rehberger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-04-16 00:00:00.000000000 Z
11
+ date: 2026-04-27 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Build HTML programmatically using a clean tag DSL with nested blocks,
14
14
  automatic content escaping, void element support, and attribute hashes.