Skip to content

feat(components): add an optional resize grip to the example shortcode#2019

Merged
markdumay merged 16 commits into
mainfrom
feat/example-resize-grip
Jul 14, 2026
Merged

feat(components): add an optional resize grip to the example shortcode#2019
markdumay merged 16 commits into
mainfrom
feat/example-resize-grip

Conversation

@markdumay

@markdumay markdumay commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

Adds an optional grip to the lower-right corner of an example preview, so readers can drag it narrower and watch the component reflow. Inspired by the Bootstrap v6 navbar docs, but implemented without any Bootstrap 6 code.

{{< example lang="html" resize="true" >}}

How it works

The grip is the browser-native handle of the CSS resize property — five declarations of SCSS, no JavaScript. Bootstrap's own docs do the same thing; nothing needed vendoring.

The resize logic lives in a single partial, utilities/GetResizeClass.html, which returns the wrapper class or an empty string. Both example.html and example-bookshop.html call it, differing only in the caller they pass for warnings. An empty return emits neither the opening nor the closing tag, so they cannot fall out of balance.

Setting resize=true without show-preview warns and degrades to a normal preview — there is nothing to resize.

What it does not do

The grip demonstrates fluid reflow — wrapping, truncation, tables gaining a scrollbar, images scaling. It does not fire responsive breakpoints: Bootstrap 5's navbar-expand-* and col-md-* are viewport media queries, so they answer to the window, not to the preview. What makes Bootstrap's v6 demo collapse a navbar is md:navbar-expand, a container query, and nothing in this theme uses container queries today.

That limitation is documented for readers in the companion mod-docs PR, and it is why the navbar — Bootstrap's own showcase for this feature — is deliberately not among the pages that get a grip. On Bootstrap 5 it would squeeze without ever collapsing, which is precisely the wrong lesson.

No inline styles

The wrapper carries a class, never a computed width, so the theme stays compatible with a CSP that omits unsafe-inline from style-src. layouts/ still contains zero inline style attributes.

An earlier revision of this branch added a configurable min-width taking breakpoint tokens. It was removed before merge: min-width beats max-width: 100% in the cascade, so a min-width="md" preview rendered 768px wide inside a 325px column on a phone and gave the whole page a horizontal scrollbar. Breakpoint tokens are viewport widths, but the thing being floored is a ~650px preview container — so md already overflowed the docs column on desktop, and lgxxl fit nowhere. The floor is now a fixed 200px, matching Bootstrap. The full rationale is in the design spec so it is not reinvented.

No exampleSite demo page

This PR adds no content to the exampleSite — the grip is documented and exercised in mod-docs, so a demo page here would only be noise.

One intended consequence, called out so it is not mistaken for a bug: with nothing in the exampleSite rendering example-resizable, PurgeCSS strips .example-resizable from the exampleSite's CSS bundle. That is correct — no page there needs it. PurgeCSS runs per site against that site's own hugo_stats.json, so a site rendering the mod-docs pages emits the class and keeps the rule. Do not add a safelist entry to "fix" the purge; that would ship dead CSS to every site.

Verification

Every enabled example was driven in a real browser against a local build with the mod-docs branch mounted — measured, not eyeballed:

Component Measured on narrowing Clipped?
navs-and-tabs tabs wrap 1 → 2 → 3 rows No
breadcrumb wraps 2 → 3 → 4 rows No
table .table-responsive scroller tracks the container No
image scales 326 → 150 → 100px No
carousel scales 326 → 200 → 100px, ratio preserved No
card reflows, height adjusts No

Neither the DataTables integration nor the Bootstrap carousel caches its layout, so no JS redraw is needed and the CSS-only remit holds. The 200px floor is safe down to a 390px viewport (229px box in a 325px column, no page overflow).

Because the docs pages live in mod-docs, the Netlify preview for this PR builds against the released mod-docs and therefore shows no grips. They light up once mod-docs ships.

npm test passes. The exampleSite builds clean.

Merge order

Merge this before the mod-docs PR and tag v3.1.0. mod-docs has no require on hinode, so nothing stops a site bumping mod-docs alone — it fails loudly (unsupported argument 'resize', build exits 1) rather than silently, but it is still a hard break.

🤖 Generated with Claude Code

@netlify

netlify Bot commented Jul 14, 2026

Copy link
Copy Markdown

Deploy Preview for gethinode-demo ready!

Name Link
🔨 Latest commit 2a53429
🔍 Latest deploy log https://app.netlify.com/projects/gethinode-demo/deploys/6a56220900d7a300085bd453
😎 Deploy Preview https://deploy-preview-2019--gethinode-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

markdumay and others added 14 commits July 14, 2026 13:31
Adds a CSS-only resize grip to the example and example-bookshop preview,
using the browser-native resize property. Requires no JavaScript and no
Bootstrap 6 code.

- min-width is a breakpoint token select rather than a CSS length, because
  templates may not emit inline styles (CSP)
- Documents that Bootstrap 5 breakpoints will not fire on resize, since its
  responsive classes are viewport media queries, not container queries

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Adds mod-docs as the application surface; the Hinode exampleSite imports it,
  so both halves can be verified together on a local dev server
- Defines an evidence-based eligibility criterion (real flex-wrap/intrinsic
  reflow) and applies it to every documented component
- Enables 6 pages: navs-and-tabs, breadcrumb, table, image, carousel, card
- Rejects navbar despite it being Bootstrap's own showcase: navbar-expand-* is a
  viewport media query on Bootstrap 5, so the grip would never collapse it
- Adds a dev-server review gate before any commit

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Eight tasks across hinode (capability) and mod-docs (application), with a
dev-server review gate before any mod-docs commit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The three resize commits are interleaved with the table-wrap commits, so the
original reset --hard would have destroyed table work. Replaced with an additive
cherry-pick, a backup branch, and a gated rebuild step.
- Records the worktree/branch (origin/main based) and marks Task 0 done
- Every Hugo call now exports node_modules/.bin onto PATH; without it Hugo panics
  with 'POSTCSS: binary with name postcss not found in PATH'
- Corrects the mod-docs workspace directive to climb out of .claude/worktrees
Tasks 2 and 3 duplicated ~15 lines of identical logic verbatim, which the code
review rubric treats as a defect. The logic now lives in one partial,
utilities/GetResizeClass.html, that both shortcodes call.
…code

Declares the arguments and adds an exampleSite page that exercises them. The
grip markup and styling follow.
Emits a bounded resize class instead of an inline style, so the markup stays
compatible with a CSP that omits unsafe-inline for styles. Warns when resize is
set without a preview to resize.
Mirrors the example shortcode so both previews share one argument
contract.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Uses the browser-native resize grip. Breakpoint floors are generated from
$grid-breakpoints so they track the theme's own breakpoints.
Adds the copyright header carried by the other recent utility partials, and replaces the
JSDoc-style @param block (which has no precedent in this repo or mod-utils) with the prose
form used by its siblings.
Drop the min-width argument from the example shortcode's resize grip.
Breakpoint floors used viewport widths (e.g. 768px for md) inside a
~650-770px preview container, and min-width beats max-width: 100% in
CSS, so previews could not shrink to fit narrow columns and caused a
horizontal scrollbar on small viewports. The base 200px floor and the
resize/overflow rules on .example-resizable are unchanged.

Also move the GetResizeClass partial call in both example shortcodes
so it only runs once argument validation passes, avoiding a redundant
"resize requires show-preview" warning alongside the fatal invalid
arguments error.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The spec described a configurable min-width that was removed at final review. It now
documents the shipped design (a fixed 200px floor) and records why the breakpoint-token
approach failed: min-width beats max-width, and breakpoint tokens are viewport widths
while the thing being floored is a much narrower preview container.
@markdumay markdumay force-pushed the feat/example-resize-grip branch from bbb47b6 to 7311191 Compare July 14, 2026 11:33
The resize grip is documented and exercised in mod-docs, so a dedicated demo page only
pollutes the exampleSite. PurgeCSS now purges the .example-resizable rule from the
exampleSite bundle, which is correct: nothing there renders the class. Consuming sites
render it via mod-docs, so their own hugo_stats.json keeps the rule.
Explains why PurgeCSS now strips .example-resizable from the exampleSite bundle (nothing
there renders it) and why that must not be 'fixed' with a safelist entry: consuming sites
render the class via mod-docs and keep the rule through their own hugo_stats.json.
@markdumay markdumay merged commit e914126 into main Jul 14, 2026
16 checks passed
@markdumay

Copy link
Copy Markdown
Collaborator Author

🎉 This PR is included in version 3.2.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant