markawesome 0.18.0 → 0.19.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: b3ce7a2c074d2d33074977cfe3f20c474ba14908e4c07e283c8067e9adce65f4
4
- data.tar.gz: 54c1bdd4ab2c53d11c14589757707b3325555afa5315142fa5341f6842d0b90a
3
+ metadata.gz: fcd58ebaea11af858fd0b4e922bdf4447035df09cc91b9acfa9dea047a908cf8
4
+ data.tar.gz: de54c7cb14e781a63d4bc22a132bb637cc62c1ec0383a0404e46b81efd3a3500
5
5
  SHA512:
6
- metadata.gz: ae0b842c192958678ed64bca94c3f637d16c58c4c641c8cc02bc69234ca35e322fd4f677d424c959499c692a5b6f1c7acc477123ad86c3c4eb94a2c91c2ae654
7
- data.tar.gz: d870d957d821ca0cd44c46a6afa7175d26436538ed3dae3ce2f7363afb8b1d20aa79a5195743fbfe7b47f5c7494402c89c32ce630acb6010d3f5fa91f1bb2b03
6
+ metadata.gz: ebbc8bb6f73131839e94bc1b1d79a875bdd2de65e980832c59fb3305b03324b76c6259b800e16be111bdfd6e3c0df14d6f80820052474d635e2a982c1cd5d987
7
+ data.tar.gz: 2a768f945ecb99d16b4aa3e60d64dce34e97bf518239344d83a440a9cba0cd0c60caeac5315c8fbfee5545c3212f6d28376dc3dc181b903cfb0a68f1649c640c
data/CHANGELOG.md CHANGED
@@ -6,6 +6,28 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.19.0] - 2026-08-26
10
+
11
+ ### Fixed
12
+
13
+ - **Repeated dialogs no longer share a DOM id.** The id is an MD5 of the trigger text plus body, so two dialogs differing only by a param (e.g. width) collided — and byte-identical ones always did. Both triggers then emitted the same `data-dialog='open …'`, so `getElementById` resolved every one of them to the first dialog and the others were unreachable. Repeats now get a `-2`, `-3`, … suffix, the scheme `generate_popover_id`/`generate_tooltip_id` already used. The first occurrence keeps its bare id, so existing single-dialog output is unchanged.
14
+
15
+ ### Changed
16
+
17
+ - **Image-dialog trigger buttons now style both `::part(base)` and `::part(button)`.** Web Awesome 3.11.0 gives every component a CSS part named after itself and softly deprecates the generic `base` part — for `<wa-button>` the wrapper part is now `button`, and WA's own manifest marks `base` as *"Deprecated. Use the `button` part instead."* The chrome-stripping `<style>` block emitted for an image trigger (`![alt](src)` under `image_dialog: true`) now lists both selectors in each of its three rules, so the trigger stays chrome-less on 3.10-pinned sites (which have no `button` part) **and** on 3.11+ sites once `base` is eventually removed. Purely additive — no existing selector was dropped. The style block moved into a private `image_button_style` helper; output is byte-identical to `markawesome-js` and now locked by specs in `spec/dialog_transformer_spec.rb` (the emitted selectors were previously untested in either engine).
18
+
19
+ ### Internal
20
+
21
+ - **Refreshed the Web Awesome manifest fixture to 3.12.0** (August 2026). `rake wa:manifest[3.12.0]` regenerated `spec/fixtures/webawesome-enums.json` and `WA_VERSION` moved to `3.12.0`. The enum diff is a **single additive line** — `wa-dropdown-item` gained a `target` enum (`_blank`/`_parent`/`_self`/`_top`) alongside its new `href`/`rel`/`download` navigation attributes — on a component that is [explicitly out of scope](ROADMAP.md) for a static-Markdown model, so there is **zero DRIFT and zero GAP** against the enums we accept and no transformer constant changed. Nothing else in WA 3.12.0 touches a component we emit: the other additions are `<wa-data-grid>`'s `filterOptions` (JS-supplied data) and the Figma kit, and every fix/change is internal to Web Awesome's own shadow DOM. Two of those fixes land on our output for free — `<wa-button>` now keeps its accessible name and gains `aria-busy` while loading (we already accept a bare `loading` token in `BUTTON_ATTRIBUTES`), and duplicate landmarks were removed from `<wa-card>`, `<wa-dialog>` and `<wa-drawer>`. Fixture remains byte-identical to `markawesome-js`'s copy. Example-site CDN pins bumped to 3.12.0 in `jekyll-webawesome` and `eleventy-plugin-webawesome`.
22
+ - **Refreshed the Web Awesome manifest fixture to 3.11.0** (July 30th, 2026). `rake wa:manifest[3.11.0]` regenerated `spec/fixtures/webawesome-enums.json` and `WA_VERSION` moved to `3.11.0`. The diff was **purely additive** — four new tags (`wa-otp-input`, `wa-pagination`, and `wa-toast`/`wa-toast-item`, which moved from Pro to Core) — with **zero DRIFT and zero GAP** against the enums we accept, so no transformer constant changed. `IconAttributes::SCHEMA` was separately verified against WA 3.11.0's `IconAnimation` (18 values) and `IconCanvas` types and still matches exactly, as do every slot our transformers emit (`footer`, `icon`, `summary`). Fixture remains byte-identical to `markawesome-js`'s copy.
23
+ - **Web Awesome manifest coverage spec** (`spec/webawesome_manifest_coverage_spec.rb`) — a deterministic guard that checks every enum our transformers accept against a vendored slice of Web Awesome's machine-readable Custom Elements Manifest, pinned to **WA 3.11.0**. For 39 `(constant → wa-tag/attribute)` mappings across 15 components it fails on **DRIFT** (a value we accept that WA no longer lists — exempting the deliberate `callout` `info`→`brand` input alias) and **GAP** (a WA value we don't expose, gated by an `INTENTIONALLY_OMITTED` map that starts empty, so a new WA value turns the build red until adopted or recorded with a reason). 6 entries WA can't describe as an inline enum (`wa-icon` family/variant/animation/canvas are freeform/opaque types; `wa-video` is absent from WA core's manifest) are surfaced as `skip`s, not silently dropped. The fixture `spec/fixtures/webawesome-enums.json` is a **derived artifact** regenerated with `rake wa:manifest[X.Y.Z]` (`script/update_wa_manifest.rb`) — never hand-edited, and byte-identical to `markawesome-js`'s copy. Dev-only (not packaged in the gem); no version bump. See CLAUDE.md → "Web Awesome manifest coverage" for the WA-bump workflow.
24
+
25
+ ## [0.18.1] - 2026-07-04
26
+
27
+ ### Fixed
28
+
29
+ - **Horizontal cards no longer overflow with multi-block bodies.** A `===horizontal` card whose body has more than one block (e.g. a `#` heading plus a paragraph) now wraps the body in a single `<div>`, so Web Awesome's `:host([orientation='horizontal']) .body slot::slotted(*) { height: 100% }` rule — which it applies to **every** direct body child — targets the one wrapper instead of each block. Previously each block was stretched to the full card height and the extra ones spilled out below the card. Vertical cards are unchanged (no wrapper is emitted). Parity locked by the new `card-horizontal-body-wrap` case in `markawesome-js`'s `test/parity-corpus.test.ts`.
30
+
9
31
  ## [0.18.0] - 2026-07-04
10
32
 
11
33
  ### Added
data/README.md CHANGED
@@ -4,6 +4,8 @@ A framework-agnostic Ruby library that transforms custom Markdown syntax into [W
4
4
 
5
5
  Used as the transformation engine for the [jekyll-webawesome](https://github.com/jannewaren/jekyll-webawesome) plugin.
6
6
 
7
+ > **🔗 See it live — [hosted examples site](https://jannewaren.github.io/jekyll-webawesome/).** Every supported component shown side by side: the Markawesome markdown on the left, the live Web Awesome component it renders on the right. The clearest way to see what this project does.
8
+
7
9
  ## Features
8
10
 
9
11
  - 🎯 **Framework Agnostic** - Works with any static site generator or Ruby application
@@ -53,7 +55,7 @@ Layout utilities use `::::` (quadruple colon) syntax to wrap content in CSS layo
53
55
 
54
56
  All layouts support these key:value attributes:
55
57
 
56
- - `gap:SIZE` — Sets spacing (`0`, `3xs`, `2xs`, `xs`, `s`, `m`, `l`, `xl`, `2xl`, `3xl`)
58
+ - `gap:SIZE` — Sets spacing (`0`, `3xs`, `2xs`, `xs`, `s`, `m`, `l`, `xl`, `2xl`, `3xl`, `4xl`, `5xl`)
57
59
  - `align:VALUE` — Align items (`start`, `end`, `center`, `stretch`, `baseline`)
58
60
  - `justify:VALUE` — Justify content (`start`, `end`, `center`, `space-between`, `space-around`, `space-evenly`)
59
61
 
@@ -138,8 +138,7 @@ module Markawesome
138
138
 
139
139
  # Main content
140
140
  if parts[:content] && !parts[:content].empty?
141
- content_html = markdown_to_html(parts[:content])
142
- html_parts << content_html
141
+ html_parts << body_content_html(parts[:content], orientation)
143
142
  end
144
143
 
145
144
  # Footer slot
@@ -149,6 +148,17 @@ module Markawesome
149
148
 
150
149
  "<wa-card#{attr_string}>#{html_parts.join}</wa-card>"
151
150
  end
151
+
152
+ # Horizontal cards wrap the body in a single <div> so Web Awesome's
153
+ # `:host([orientation='horizontal']) .body slot::slotted(*) { height: 100% }`
154
+ # rule — which it applies to EVERY direct body child — targets one wrapper
155
+ # instead of each block. Without the wrapper a multi-block body (e.g. a
156
+ # heading plus a paragraph) has each child stretched to the full card
157
+ # height, so the extra ones overflow below it.
158
+ def body_content_html(content, orientation)
159
+ content_html = markdown_to_html(content)
160
+ orientation == 'horizontal' ? "<div>#{content_html}</div>" : content_html
161
+ end
152
162
  end
153
163
  end
154
164
  end
@@ -25,6 +25,10 @@ module Markawesome
25
25
  primary_regex = /^\?\?\?([^\n]*)$\n(.*?)\n^>>>$\n(.*?)\n^\?\?\?$/m
26
26
  alternative_regex = /^:::wa-dialog([^\n]*)$\n(.*?)\n^>>>$\n(.*?)\n^:::$/m
27
27
 
28
+ # Two dialogs with the same trigger and body hash alike, so suffix repeats
29
+ # (-2, -3, …) to keep ids unique — same scheme as popover/tooltip.
30
+ seen_ids = Hash.new(0)
31
+
28
32
  # Define shared transformation logic
29
33
  transform_proc = proc do |params_string, button_text, dialog_content|
30
34
  button_text = button_text.strip
@@ -37,7 +41,7 @@ module Markawesome
37
41
  label, content_without_label = extract_label(dialog_content, button_text)
38
42
 
39
43
  # Generate unique ID based on content
40
- dialog_id = generate_dialog_id(button_text, dialog_content)
44
+ dialog_id = generate_dialog_id(button_text, dialog_content, seen_ids)
41
45
 
42
46
  # Convert markdown to HTML
43
47
  content_html = markdown_to_html(content_without_label)
@@ -104,11 +108,17 @@ module Markawesome
104
108
  end
105
109
  end
106
110
 
107
- # Generate a unique ID for the dialog using MD5 hash
108
- def generate_dialog_id(button_text, content)
111
+ # Generate a unique ID for the dialog using MD5 hash.
112
+ # The hash covers the trigger and body only, so two dialogs differing solely
113
+ # by a param (e.g. width) would collide — and identical ones always do. The
114
+ # occurrence counter disambiguates: the first keeps the bare id, later ones
115
+ # get -2, -3, … Mirrors generate_popover_id / generate_tooltip_id.
116
+ def generate_dialog_id(button_text, content, seen_ids)
109
117
  hash_input = "#{button_text}#{content}"
110
118
  hash = Digest::MD5.hexdigest(hash_input)
111
- "dialog-#{hash[0..7]}" # Use first 8 characters of hash
119
+ base = "dialog-#{hash[0..7]}" # Use first 8 characters of hash
120
+ occurrence = seen_ids[base] += 1
121
+ occurrence == 1 ? base : "#{base}-#{occurrence}"
112
122
  end
113
123
 
114
124
  # Build the complete dialog HTML with trigger button
@@ -134,26 +144,7 @@ module Markawesome
134
144
  # Add CSS Parts styling for image buttons to make them invisible
135
145
  if is_image_button
136
146
  button_id = "#{dialog_id}-btn"
137
- html << '<style>'
138
- html << " ##{button_id}::part(base) {"
139
- html << ' padding: 0;'
140
- html << ' margin: 0;'
141
- html << ' border: none;'
142
- html << ' background: transparent;'
143
- html << ' box-shadow: none;'
144
- html << ' color: inherit;'
145
- html << ' min-width: 0;'
146
- html << ' height: auto;'
147
- html << ' }'
148
- html << " ##{button_id}::part(base):hover {"
149
- html << ' background: transparent;'
150
- html << ' border-color: transparent;'
151
- html << ' }'
152
- html << " ##{button_id}::part(base):active {"
153
- html << ' background: transparent;'
154
- html << ' border-color: transparent;'
155
- html << ' }'
156
- html << '</style>'
147
+ html.concat(image_button_style(button_id))
157
148
  end
158
149
 
159
150
  # Trigger button
@@ -175,6 +166,27 @@ module Markawesome
175
166
  html.join("\n")
176
167
  end
177
168
 
169
+ # Strip the trigger button's chrome so an image trigger reads as a bare image.
170
+ #
171
+ # WA 3.11 deprecated wa-button's generic `base` part in favour of a part named after
172
+ # the component (`button`). `base` still works but is on its way out, so target both —
173
+ # the output then styles correctly on 3.10-pinned and 3.11+ sites.
174
+ def image_button_style(button_id)
175
+ wrapper = lambda do |state|
176
+ " ##{button_id}::part(base)#{state}, ##{button_id}::part(button)#{state} {"
177
+ end
178
+
179
+ ['<style>', wrapper.call(''),
180
+ ' padding: 0;', ' margin: 0;', ' border: none;',
181
+ ' background: transparent;', ' box-shadow: none;', ' color: inherit;',
182
+ ' min-width: 0;', ' height: auto;', ' }',
183
+ wrapper.call(':hover'),
184
+ ' background: transparent;', ' border-color: transparent;', ' }',
185
+ wrapper.call(':active'),
186
+ ' background: transparent;', ' border-color: transparent;', ' }',
187
+ '</style>']
188
+ end
189
+
178
190
  # Escape HTML entities in text
179
191
  def escape_html(text)
180
192
  text.gsub('&', '&amp;')
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Markawesome
4
- VERSION = '0.18.0'
4
+ VERSION = '0.19.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: markawesome
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.0
4
+ version: 0.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Janne Waren