@reblu/site-blocks 0.3.1 → 0.4.1
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.
- package/README.md +49 -0
- package/dist/client.cjs +7 -7
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +2 -2
- package/dist/client.js.map +1 -1
- package/dist/index.cjs +94 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -3
- package/dist/index.d.ts +7 -3
- package/dist/index.js +91 -22
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all3) => {
|
|
9
7
|
for (var name in all3)
|
|
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
|
|
30
20
|
// src/index.ts
|
|
@@ -13053,9 +13043,13 @@ function markdownToSafeHtml(markdown) {
|
|
|
13053
13043
|
}
|
|
13054
13044
|
|
|
13055
13045
|
// src/components/markdown-renderer.tsx
|
|
13056
|
-
var
|
|
13057
|
-
var import_html_react_parser =
|
|
13046
|
+
var import_utils = require("@reblu/site-ui/utils");
|
|
13047
|
+
var import_html_react_parser = require("html-react-parser");
|
|
13058
13048
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
13049
|
+
var HTML_TO_DOM_OPTIONS = { lowerCaseAttributeNames: false };
|
|
13050
|
+
function parse3(html5, options) {
|
|
13051
|
+
return (0, import_html_react_parser.domToReact)((0, import_html_react_parser.htmlToDOM)(html5, HTML_TO_DOM_OPTIONS), options);
|
|
13052
|
+
}
|
|
13059
13053
|
var HEADING_CLASSES = {
|
|
13060
13054
|
1: "text-3xl font-bold mt-8 mb-4 first:mt-0",
|
|
13061
13055
|
2: "text-2xl font-bold mt-7 mb-3 first:mt-0",
|
|
@@ -13067,6 +13061,41 @@ var HEADING_CLASSES = {
|
|
|
13067
13061
|
function hasClass(el, name) {
|
|
13068
13062
|
return typeof el.attribs.class === "string" && el.attribs.class.split(/\s+/).includes(name);
|
|
13069
13063
|
}
|
|
13064
|
+
var PRESERVED_GLOBAL_ATTRIBUTES = [
|
|
13065
|
+
// Anchor targets. In-document links ("see clause 4" → `#clause-4`) resolve to
|
|
13066
|
+
// nothing without them.
|
|
13067
|
+
"id",
|
|
13068
|
+
// Language and direction of a passage — a bilingual legal page is the normal case
|
|
13069
|
+
// here, and screen readers switch voice on it.
|
|
13070
|
+
"lang",
|
|
13071
|
+
"dir",
|
|
13072
|
+
// Advisory text the author wrote; it is content, not styling.
|
|
13073
|
+
"title",
|
|
13074
|
+
// Explicit "do not publish this". Without it a block authored as `<p hidden>`
|
|
13075
|
+
// becomes VISIBLE — publishing what the author marked as not-for-publication.
|
|
13076
|
+
"hidden",
|
|
13077
|
+
// Accessible semantics. `../lib/markdown` restores these through the sanitiser
|
|
13078
|
+
// precisely so they are not lost (REB-286's axe gate); dropping them one layer
|
|
13079
|
+
// later would undo that.
|
|
13080
|
+
"role"
|
|
13081
|
+
];
|
|
13082
|
+
var PRESERVED_ATTRIBUTE_PREFIXES = ["aria-", "data-"];
|
|
13083
|
+
var PRESERVED_TAG_ATTRIBUTES = {
|
|
13084
|
+
ol: ["start", "type"],
|
|
13085
|
+
li: ["value", "type"]
|
|
13086
|
+
};
|
|
13087
|
+
var BOOLEAN_ATTRIBUTES = /* @__PURE__ */ new Set(["hidden"]);
|
|
13088
|
+
function authorAttributes(el) {
|
|
13089
|
+
const tagSpecific = PRESERVED_TAG_ATTRIBUTES[el.name] ?? [];
|
|
13090
|
+
const preserved = {};
|
|
13091
|
+
for (const [rawName, value] of Object.entries(el.attribs)) {
|
|
13092
|
+
const name = rawName.toLowerCase();
|
|
13093
|
+
const keep = PRESERVED_GLOBAL_ATTRIBUTES.includes(name) || tagSpecific.includes(name) || PRESERVED_ATTRIBUTE_PREFIXES.some((prefix) => name.startsWith(prefix));
|
|
13094
|
+
if (!keep) continue;
|
|
13095
|
+
preserved[name] = BOOLEAN_ATTRIBUTES.has(name) ? true : value;
|
|
13096
|
+
}
|
|
13097
|
+
return preserved;
|
|
13098
|
+
}
|
|
13070
13099
|
function isExternalHref(href) {
|
|
13071
13100
|
return !!href && /^(https?:)?\/\//.test(href);
|
|
13072
13101
|
}
|
|
@@ -13076,29 +13105,46 @@ function buildOptions(headingOffset) {
|
|
|
13076
13105
|
if (!(node instanceof import_html_react_parser.Element)) return void 0;
|
|
13077
13106
|
const children2 = () => (0, import_html_react_parser.domToReact)(node.children, options);
|
|
13078
13107
|
const { name, attribs } = node;
|
|
13108
|
+
const author = authorAttributes(node);
|
|
13079
13109
|
const headingMatch = /^h([1-6])$/.exec(name);
|
|
13080
13110
|
if (headingMatch) {
|
|
13081
13111
|
const rendered = Math.min(6, Number(headingMatch[1]) + headingOffset);
|
|
13082
13112
|
const Tag = `h${rendered}`;
|
|
13083
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Tag, { className: HEADING_CLASSES[rendered], children: children2() });
|
|
13113
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Tag, { ...author, className: HEADING_CLASSES[rendered], children: children2() });
|
|
13084
13114
|
}
|
|
13085
13115
|
switch (name) {
|
|
13086
13116
|
case "p":
|
|
13087
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "my-4 leading-relaxed text-foreground/90", children: children2() });
|
|
13117
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { ...author, className: "my-4 leading-relaxed text-foreground/90", children: children2() });
|
|
13088
13118
|
case "ul":
|
|
13089
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { className: hasClass(node, "contains-task-list") ? "list-none pl-0 my-4 space-y-1" : "list-disc ml-6 my-4", children: children2() });
|
|
13119
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { ...author, className: hasClass(node, "contains-task-list") ? "list-none pl-0 my-4 space-y-1" : "list-disc ml-6 my-4", children: children2() });
|
|
13090
13120
|
case "ol":
|
|
13091
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "list-decimal ml-6 my-4", children: children2() });
|
|
13121
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { ...author, className: "list-decimal ml-6 my-4", children: children2() });
|
|
13092
13122
|
case "li":
|
|
13093
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { className: hasClass(node, "task-list-item") ? "flex items-start gap-2 my-1" : "my-1", children: children2() });
|
|
13123
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { ...author, className: hasClass(node, "task-list-item") ? "flex items-start gap-2 my-1" : "my-1", children: children2() });
|
|
13094
13124
|
case "blockquote":
|
|
13095
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
13125
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
13126
|
+
"blockquote",
|
|
13127
|
+
{
|
|
13128
|
+
...author,
|
|
13129
|
+
className: "border-l-4 border-primary/50 pl-6 italic my-6 text-muted-foreground",
|
|
13130
|
+
children: children2()
|
|
13131
|
+
}
|
|
13132
|
+
);
|
|
13096
13133
|
case "pre":
|
|
13097
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
13134
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
13135
|
+
"pre",
|
|
13136
|
+
{
|
|
13137
|
+
...author,
|
|
13138
|
+
className: "rounded-lg border border-input bg-muted p-4 my-6 overflow-x-auto font-mono text-sm",
|
|
13139
|
+
children: children2()
|
|
13140
|
+
}
|
|
13141
|
+
);
|
|
13098
13142
|
case "code": {
|
|
13099
13143
|
const isBlock = node.parent instanceof import_html_react_parser.Element && node.parent.name === "pre";
|
|
13100
|
-
if (isBlock)
|
|
13101
|
-
|
|
13144
|
+
if (isBlock) {
|
|
13145
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { ...author, className: "block", children: children2() });
|
|
13146
|
+
}
|
|
13147
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { ...author, className: "rounded bg-muted px-1.5 py-0.5 font-mono text-sm", children: children2() });
|
|
13102
13148
|
}
|
|
13103
13149
|
case "a": {
|
|
13104
13150
|
const href = attribs.href;
|
|
@@ -13106,6 +13152,7 @@ function buildOptions(headingOffset) {
|
|
|
13106
13152
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
13107
13153
|
"a",
|
|
13108
13154
|
{
|
|
13155
|
+
...author,
|
|
13109
13156
|
href,
|
|
13110
13157
|
className: "text-primary underline underline-offset-4 hover:text-primary/80",
|
|
13111
13158
|
...external ? { target: "_blank", rel: "noopener noreferrer" } : {},
|
|
@@ -13122,6 +13169,7 @@ function buildOptions(headingOffset) {
|
|
|
13122
13169
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
13123
13170
|
"img",
|
|
13124
13171
|
{
|
|
13172
|
+
...author,
|
|
13125
13173
|
src: attribs.src,
|
|
13126
13174
|
alt: attribs.alt ?? "",
|
|
13127
13175
|
loading: "lazy",
|
|
@@ -13133,6 +13181,7 @@ function buildOptions(headingOffset) {
|
|
|
13133
13181
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "relative my-6 aspect-video w-full overflow-hidden rounded-lg", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
13134
13182
|
"iframe",
|
|
13135
13183
|
{
|
|
13184
|
+
...author,
|
|
13136
13185
|
src: attribs.src,
|
|
13137
13186
|
title: attribs.title ?? "Embedded video",
|
|
13138
13187
|
allow: attribs.allow ?? "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
|
|
@@ -13141,13 +13190,13 @@ function buildOptions(headingOffset) {
|
|
|
13141
13190
|
}
|
|
13142
13191
|
) });
|
|
13143
13192
|
case "hr":
|
|
13144
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { className: "my-8 border-muted-foreground/30" });
|
|
13193
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { ...author, className: "my-8 border-muted-foreground/30" });
|
|
13145
13194
|
case "strong":
|
|
13146
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { className: "font-bold text-foreground", children: children2() });
|
|
13195
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { ...author, className: "font-bold text-foreground", children: children2() });
|
|
13147
13196
|
case "em":
|
|
13148
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("em", { className: "italic", children: children2() });
|
|
13197
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("em", { ...author, className: "italic", children: children2() });
|
|
13149
13198
|
case "del":
|
|
13150
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("del", { className: "line-through", children: children2() });
|
|
13199
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("del", { ...author, className: "line-through", children: children2() });
|
|
13151
13200
|
default:
|
|
13152
13201
|
return void 0;
|
|
13153
13202
|
}
|
|
@@ -13158,18 +13207,19 @@ function buildOptions(headingOffset) {
|
|
|
13158
13207
|
function MarkdownRenderer({ content, className, headingOffset = 0 }) {
|
|
13159
13208
|
const html5 = markdownToSafeHtml(content);
|
|
13160
13209
|
if (!html5) return null;
|
|
13161
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0,
|
|
13210
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_utils.cn)("max-w-none", className), "data-slot": "markdown", children: parse3(html5, buildOptions(headingOffset)) });
|
|
13162
13211
|
}
|
|
13163
13212
|
function SafeHtml({ html: html5, className, headingOffset = 0 }) {
|
|
13164
13213
|
if (!html5) return null;
|
|
13165
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0,
|
|
13214
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_utils.cn)("max-w-none", className), "data-slot": "safe-html", children: parse3(html5, buildOptions(headingOffset)) });
|
|
13166
13215
|
}
|
|
13167
13216
|
|
|
13168
13217
|
// src/components/treatment.tsx
|
|
13169
|
-
var
|
|
13218
|
+
var import_utils3 = require("@reblu/site-ui/utils");
|
|
13170
13219
|
|
|
13171
13220
|
// src/components/_page-parts.tsx
|
|
13172
|
-
var
|
|
13221
|
+
var import_utils2 = require("@reblu/site-ui/utils");
|
|
13222
|
+
var import_button_variants = require("@reblu/site-ui/button-variants");
|
|
13173
13223
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
13174
13224
|
var KNOWN_BUTTON_VARIANTS = /* @__PURE__ */ new Set([
|
|
13175
13225
|
"default",
|
|
@@ -13200,18 +13250,23 @@ function PageHero({ page }) {
|
|
|
13200
13250
|
}
|
|
13201
13251
|
function SectionCta({ section }) {
|
|
13202
13252
|
if (!section.ctaLabel || !section.ctaUrl) return null;
|
|
13203
|
-
|
|
13253
|
+
const variant = toButtonVariant(section.ctaVariant);
|
|
13254
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
13204
13255
|
"a",
|
|
13205
13256
|
{
|
|
13206
13257
|
href: section.ctaUrl,
|
|
13258
|
+
"data-slot": "button",
|
|
13259
|
+
"data-variant": variant,
|
|
13260
|
+
"data-size": "default",
|
|
13261
|
+
className: (0, import_utils2.cn)((0, import_button_variants.buttonVariants)({ variant, size: "default" })),
|
|
13207
13262
|
...section.ctaIsExternal ? { target: "_blank", rel: "noopener noreferrer" } : {},
|
|
13208
13263
|
children: section.ctaLabel
|
|
13209
13264
|
}
|
|
13210
|
-
) })
|
|
13265
|
+
) });
|
|
13211
13266
|
}
|
|
13212
13267
|
function SectionImages({ section }) {
|
|
13213
13268
|
if (section.images.length === 0) return null;
|
|
13214
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: (0,
|
|
13269
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: (0, import_utils2.cn)("grid gap-4", section.images.length > 1 ? "sm:grid-cols-2" : "grid-cols-1"), children: section.images.map((img) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("figure", { className: "space-y-1", children: [
|
|
13215
13270
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "relative aspect-video w-full overflow-hidden rounded-lg bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("img", { src: img.url, alt: img.alt, loading: "lazy", className: "h-full w-full object-cover" }) }),
|
|
13216
13271
|
img.caption && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("figcaption", { className: "text-sm text-muted-foreground", children: img.caption })
|
|
13217
13272
|
] }, `${img.url}-${img.order}`)) });
|
|
@@ -13248,14 +13303,14 @@ function PageSectionList({ sections }) {
|
|
|
13248
13303
|
// src/components/treatment.tsx
|
|
13249
13304
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
13250
13305
|
function Treatment({ page, className }) {
|
|
13251
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("article", { className: (0,
|
|
13306
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("article", { className: (0, import_utils3.cn)("space-y-12", className), "data-slot": "treatment", children: [
|
|
13252
13307
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PageHero, { page }),
|
|
13253
13308
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PageSectionList, { sections: page.sections })
|
|
13254
13309
|
] });
|
|
13255
13310
|
}
|
|
13256
13311
|
|
|
13257
13312
|
// src/components/specialty.tsx
|
|
13258
|
-
var
|
|
13313
|
+
var import_utils4 = require("@reblu/site-ui/utils");
|
|
13259
13314
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
13260
13315
|
function Specialty({
|
|
13261
13316
|
page,
|
|
@@ -13264,7 +13319,7 @@ function Specialty({
|
|
|
13264
13319
|
treatmentsLabel = "Treatments",
|
|
13265
13320
|
className
|
|
13266
13321
|
}) {
|
|
13267
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("article", { className: (0,
|
|
13322
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("article", { className: (0, import_utils4.cn)("space-y-12", className), "data-slot": "specialty", children: [
|
|
13268
13323
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PageHero, { page }),
|
|
13269
13324
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PageSectionList, { sections: page.sections }),
|
|
13270
13325
|
treatments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "space-y-6", children: [
|
|
@@ -13296,7 +13351,7 @@ function Specialty({
|
|
|
13296
13351
|
}
|
|
13297
13352
|
|
|
13298
13353
|
// src/components/profile-card.tsx
|
|
13299
|
-
var
|
|
13354
|
+
var import_utils5 = require("@reblu/site-ui/utils");
|
|
13300
13355
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
13301
13356
|
function initials(name) {
|
|
13302
13357
|
return name.split(/\s+/).filter(Boolean).slice(0, 2).map((part) => part[0]?.toUpperCase() ?? "").join("");
|
|
@@ -13306,7 +13361,7 @@ function ProfileCard({ name, role, imageUrl, specialties = [], bio, href, classN
|
|
|
13306
13361
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
13307
13362
|
"article",
|
|
13308
13363
|
{
|
|
13309
|
-
className: (0,
|
|
13364
|
+
className: (0, import_utils5.cn)(
|
|
13310
13365
|
"flex flex-col items-center gap-3 rounded-lg border bg-card p-6 text-center",
|
|
13311
13366
|
className
|
|
13312
13367
|
),
|
|
@@ -13338,7 +13393,7 @@ function ProfileCard({ name, role, imageUrl, specialties = [], bio, href, classN
|
|
|
13338
13393
|
}
|
|
13339
13394
|
|
|
13340
13395
|
// src/components/product-card.tsx
|
|
13341
|
-
var
|
|
13396
|
+
var import_utils6 = require("@reblu/site-ui/utils");
|
|
13342
13397
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
13343
13398
|
function ProductCard({ product, href, currencyCode = "EUR", locale, className }) {
|
|
13344
13399
|
const image = product.images.find((i) => i.isPrimary) ?? product.images[0];
|
|
@@ -13346,7 +13401,7 @@ function ProductCard({ product, href, currencyCode = "EUR", locale, className })
|
|
|
13346
13401
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
13347
13402
|
"article",
|
|
13348
13403
|
{
|
|
13349
|
-
className: (0,
|
|
13404
|
+
className: (0, import_utils6.cn)(
|
|
13350
13405
|
"group flex flex-col overflow-hidden rounded-lg border bg-card transition-shadow hover:shadow-lg",
|
|
13351
13406
|
className
|
|
13352
13407
|
),
|