@htmlbricks/hb-paragraps-around-image
v0.76.5
Published
Editorial block with a central image and up to six text blocks in two side columns using hb-paragraps-around-image-cell (indices 0,2,4 left; 1,3,5 right). Parses paragraphs from JSON and bubbles paragraphPressed when a cell fires it.
Readme
hb-paragraps-around-image — integrator guide
Category: content · Tags: content · Package: @htmlbricks/hb-paragraps-around-image
Dependency: registers hb-paragraps-around-image-cell at runtime (addComponent, same bundle version).
Summary
hb-paragraps-around-image is an editorial layout: a center column image flanked by up to six rich text blocks rendered as hb-paragraps-around-image-cell instances. Paragraph data is supplied as a JSON string; each cell is capped at eight lines of body text (max_lines="8" in the implementation).
The host does not render until both a non-empty paragraphs array (after parsing) and a non-empty img URL are present.
Layout and paragraph order
On viewports 900px and wider, the outer container is a horizontal flex row with three columns: left, center (image), right. Below that breakpoint the block still uses the same DOM order; spacing and flex behavior follow styles/webcomponent.scss.
Paragraphs map to columns by array index (0-based):
| Index | Column | |-------|--------| | 0, 2, 4 | Left | | 1, 3, 5 | Right |
Omitted indices simply leave a gap in that column (for example, a single object only fills the top-left cell). You can use up to six entries for a full two-column stack.
Paragraph object shape
Each item in the paragraphs array matches the Paragraphs type:
| Field | Required | Description |
|-------|----------|-------------|
| text | Yes | Body copy (line-clamped per cell). |
| title | No | Heading shown by the cell. |
| icon | No | Bootstrap Icons icon name (e.g. globe, journal-text) used inside the cell. |
| link | No | If set, the title behaves as a link to this URL. |
| key | No | Identifier forwarded on paragraphPressed when the cell reports a press (see Events). |
Icons rely on Bootstrap Icons; the component loads the icon font from a CDN (<svelte:head> in the implementation, plus a font import in styles/webcomponent.scss).
Custom element tag
<hb-paragraps-around-image …></hb-paragraps-around-image>Attributes (HTML / reflected props)
Web component attributes are strings (snake_case).
| Attribute | Required | Description |
|-----------|----------|-------------|
| img | No | Center column image URL (non-empty img plus parsed paragraphs required for the layout to render). |
| paragraphs | No | JSON string or array: paragraph objects (see above). Parsed in an $effect; invalid JSON is ignored. |
| id | No | Optional host id. |
| style | No | Optional on Component; host style still applies in the light DOM. |
Events
| Event | detail | When |
|-------|----------|------|
| paragraphPressed | { key: string } | Bubbled from a child hb-paragraps-around-image-cell when it emits paragraphPressed. Consumers should set a stable key on each paragraph object if they need to identify which block was activated. |
Listen with addEventListener("paragraphPressed", ...) or your framework’s equivalent.
Styling (Bulma theme variables)
The component forwards shared Bulma setup (styles/bulma.scss) and local layout (styles/webcomponent.scss). Set public --bulma-* variables on body, :root, or an ancestor so they cascade into :host and nested cells. See Bulma CSS variables.
| Variable | Role |
|----------|------|
| --bulma-block-spacing | Horizontal padding on the left and right columns (.col). Default in metadata: 1.5rem. |
| --bulma-text | Default body text color (inherited by nested hb-paragraps-around-image-cell). |
| --bulma-link | Title links and interactive affordances in child cells. |
| --bulma-text-strong | Strong / title-weight copy where the theme distinguishes it. |
Slots: none — layout is entirely data-driven.
CSS parts: none on this host.
Minimal example
<hb-paragraps-around-image
img="https://placehold.co/300x200"
paragraphs='[{"text":"Body copy here.","title":"Title","icon":"globe","link":"https://example.com","key":"intro"}]'
></hb-paragraps-around-image>Multi-block example (two columns)
<hb-paragraps-around-image
img="https://placehold.co/300x200"
paragraphs='[
{"text":"Left column first block.","title":"Left 1","icon":"journal-text","link":"https://example.com","key":"L1"},
{"text":"Right column first block.","title":"Right 1","icon":"journal-text","link":"https://example.org","key":"R1"},
{"text":"Left column second block.","title":"Left 2","icon":"journal-text","key":"L2"},
{"text":"Right column second block.","title":"Right 2","icon":"journal-text","key":"R2"}
]'
></hb-paragraps-around-image>Script listener example
<hb-paragraps-around-image
id="editorial"
img="https://placehold.co/300x200"
paragraphs='[{"text":"Click the title if it is a link; keys identify blocks.","title":"Press me","key":"block-a"}]'
></hb-paragraps-around-image>
<script>
document.getElementById("editorial")?.addEventListener("paragraphPressed", (e) => {
console.log("key:", e.detail.key);
});
</script>Implementation notes for integrators
- Empty state: If
paragraphsis missing, empty, not parseable as JSON, orimgis missing, nothing inside#containeris shown. - Child package: Ensure
hb-paragraps-around-image-cellis available (same bundle or registered before use) so nested custom elements upgrade correctly. - Accessibility: Central image uses
alt=""; prefer meaningfulimgURLs or extend the cell package if you need richer semantics.
