@brandlab-digital/site-next 2.1.0 → 3.0.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.
Files changed (96) hide show
  1. package/dist/analytics.d.ts +111 -52
  2. package/dist/analytics.d.ts.map +1 -1
  3. package/dist/analytics.js +281 -153
  4. package/dist/analytics.js.map +1 -1
  5. package/dist/blog.d.ts +4 -2
  6. package/dist/blog.d.ts.map +1 -1
  7. package/dist/blog.js +7 -7
  8. package/dist/blog.js.map +1 -1
  9. package/dist/contact/client-entry.d.ts +2 -0
  10. package/dist/contact/client-entry.d.ts.map +1 -1
  11. package/dist/contact/client-entry.js +1 -0
  12. package/dist/contact/client-entry.js.map +1 -1
  13. package/dist/contact/client.d.ts +12 -22
  14. package/dist/contact/client.d.ts.map +1 -1
  15. package/dist/contact/client.js +28 -21
  16. package/dist/contact/client.js.map +1 -1
  17. package/dist/contact/form-client.d.ts +148 -0
  18. package/dist/contact/form-client.d.ts.map +1 -0
  19. package/dist/contact/form-client.js +234 -0
  20. package/dist/contact/form-client.js.map +1 -0
  21. package/dist/contact/index.d.ts +1 -1
  22. package/dist/contact/index.d.ts.map +1 -1
  23. package/dist/contact/index.js +1 -1
  24. package/dist/contact/index.js.map +1 -1
  25. package/dist/contact/route-handler.d.ts +32 -0
  26. package/dist/contact/route-handler.d.ts.map +1 -0
  27. package/dist/contact/route-handler.js +44 -0
  28. package/dist/contact/route-handler.js.map +1 -0
  29. package/dist/contact/server-entry.d.ts +1 -0
  30. package/dist/contact/server-entry.d.ts.map +1 -1
  31. package/dist/contact/server-entry.js +1 -0
  32. package/dist/contact/server-entry.js.map +1 -1
  33. package/dist/contact/server.d.ts +5 -0
  34. package/dist/contact/server.d.ts.map +1 -1
  35. package/dist/contact/server.js +13 -7
  36. package/dist/contact/server.js.map +1 -1
  37. package/dist/contact/shared.d.ts +4 -0
  38. package/dist/contact/shared.d.ts.map +1 -1
  39. package/dist/contact/shared.js.map +1 -1
  40. package/dist/contact/testing.d.ts +29 -0
  41. package/dist/contact/testing.d.ts.map +1 -1
  42. package/dist/contact/testing.js +27 -0
  43. package/dist/contact/testing.js.map +1 -1
  44. package/dist/google-tag-plan.d.ts +1 -4
  45. package/dist/google-tag-plan.d.ts.map +1 -1
  46. package/dist/google-tag-plan.js +1 -14
  47. package/dist/google-tag-plan.js.map +1 -1
  48. package/dist/google-tag.d.ts +5 -4
  49. package/dist/google-tag.d.ts.map +1 -1
  50. package/dist/google-tag.js +5 -4
  51. package/dist/google-tag.js.map +1 -1
  52. package/dist/headers.d.ts +21 -28
  53. package/dist/headers.d.ts.map +1 -1
  54. package/dist/headers.js +62 -51
  55. package/dist/headers.js.map +1 -1
  56. package/dist/instrumentation-client.d.ts +21 -1
  57. package/dist/instrumentation-client.d.ts.map +1 -1
  58. package/dist/instrumentation-client.js +62 -7
  59. package/dist/instrumentation-client.js.map +1 -1
  60. package/dist/lead-registry.d.ts +34 -0
  61. package/dist/lead-registry.d.ts.map +1 -0
  62. package/dist/lead-registry.js +30 -0
  63. package/dist/lead-registry.js.map +1 -0
  64. package/dist/lead-reporting.d.ts +37 -0
  65. package/dist/lead-reporting.d.ts.map +1 -0
  66. package/dist/lead-reporting.js +74 -0
  67. package/dist/lead-reporting.js.map +1 -0
  68. package/dist/metadata.d.ts +10 -11
  69. package/dist/metadata.d.ts.map +1 -1
  70. package/dist/metadata.js +17 -19
  71. package/dist/metadata.js.map +1 -1
  72. package/dist/next-config.d.ts +102 -0
  73. package/dist/next-config.d.ts.map +1 -0
  74. package/dist/next-config.js +140 -0
  75. package/dist/next-config.js.map +1 -0
  76. package/dist/robots.d.ts +14 -6
  77. package/dist/robots.d.ts.map +1 -1
  78. package/dist/robots.js +26 -17
  79. package/dist/robots.js.map +1 -1
  80. package/dist/sitemaps.d.ts +34 -0
  81. package/dist/sitemaps.d.ts.map +1 -1
  82. package/dist/sitemaps.js +66 -1
  83. package/dist/sitemaps.js.map +1 -1
  84. package/dist/testing/server-only.d.ts +8 -0
  85. package/dist/testing/server-only.d.ts.map +1 -0
  86. package/dist/testing/server-only.js +8 -0
  87. package/dist/testing/server-only.js.map +1 -0
  88. package/dist/ui-client.d.ts +1 -12
  89. package/dist/ui-client.d.ts.map +1 -1
  90. package/dist/ui-client.js +0 -17
  91. package/dist/ui-client.js.map +1 -1
  92. package/dist/ui.d.ts +22 -2
  93. package/dist/ui.d.ts.map +1 -1
  94. package/dist/ui.js +67 -6
  95. package/dist/ui.js.map +1 -1
  96. package/package.json +16 -3
package/dist/ui.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,EACd,SAAS,EACV,MAAM,OAAO,CAAA;AAGd,MAAM,WAAW,oBAAqB,SAAQ,cAAc,CAAC,WAAW,CAAC;IACvE,OAAO,EAAE,SAAS,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,wBAAgB,eAAe,CAAC,EAC9B,OAAO,EACP,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,QAAQ,EACR,GAAG,YAAY,EAChB,EAAE,oBAAoB,2CAStB;AAED,MAAM,WAAW,uBAAwB,SAAQ,qBAAqB,CAAC,kBAAkB,CAAC;IACxF,OAAO,EAAE,SAAS,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,gBAAgB,EAChB,gBAAgB,EAChB,QAAQ,EACR,GAAG,YAAY,EAChB,EAAE,uBAAuB,2CAOzB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,SAAS,CAAA;IAChB,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,EAAE,CAAC,KAAK,EAAE;QAChB,EAAE,EAAE,MAAM,CAAA;QACV,QAAQ,EAAE,OAAO,CAAA;QACjB,cAAc,EAAE,IAAI,GAAG,SAAS,CAAA;QAChC,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAA;KACvC,KAAK,SAAS,CAAA;CAChB;AAED,wBAAgB,aAAa,CAAC,EAC5B,EAAE,EACF,KAAK,EACL,WAAW,EACX,KAAK,EACL,QAAgB,EAChB,QAAQ,EACR,GAAG,OAAO,EACX,EAAE,kBAAkB,2CA2BpB;AAED,MAAM,WAAW,mBAAoB,SAAQ,cAAc,CAAC,cAAc,CAAC;IACzE,QAAQ,EAAE,SAAS,CAAA;IACnB,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAA;CAC1B;AAED,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,IAAe,EAAE,GAAG,KAAK,EAAE,EAAE,mBAAmB,2CAM1F;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,SAAS,CAAA;CACnB;AAED,MAAM,WAAW,yBAA0B,SAAQ,cAAc,CAAC,cAAc,CAAC;IAC/E,OAAO,EAAE,SAAS,CAAA;IAClB,MAAM,EAAE,SAAS,wBAAwB,EAAE,CAAA;IAC3C,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,wBAAgB,oBAAoB,CAAC,EACnC,OAAO,EACP,MAAM,EACN,SAAS,EACT,aAAa,EACb,GAAG,KAAK,EACT,EAAE,yBAAyB,kDAmB3B;AAED,MAAM,WAAW,aAAc,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;IAC5E,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,wBAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,aAAa,2CAOvE;AASD,MAAM,MAAM,gBAAgB,GACxB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAA;CAAE,GACjE;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAA;CAAE,GAC5D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GACzF;IAAE,IAAI,EAAE,gBAAgB,GAAG,cAAc,CAAC;IAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAA;CAAE,GAClF;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAA;CAAE,GAC5D;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,CAAA;AAE1B,MAAM,WAAW,iBAAkB,SAAQ,cAAc,CAAC,cAAc,CAAC;IACvE,KAAK,EAAE,SAAS,gBAAgB,EAAE,CAAA;CACnC;AA6BD,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,iBAAiB,2CAMlE"}
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.tsx"],"names":[],"mappings":"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"}
package/dist/ui.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { assertSafeRichTextHref } from '@brandlab-digital/site-core/rich-text';
2
+ import { assertSafeRichTextHref, sanitizeRichTextHref } from '@brandlab-digital/site-core/rich-text';
3
3
  export function HeadlessSection({ heading, headingId, headingClassName, contentClassName, children, ...sectionProps }) {
4
4
  return (_jsxs("section", { ...sectionProps, "aria-labelledby": headingId, children: [_jsx("h2", { className: headingClassName, id: headingId, children: heading }), _jsx("div", { className: contentClassName, children: children })] }));
5
5
  }
@@ -35,7 +35,17 @@ function assertHtmlIdentifier(value, label) {
35
35
  }
36
36
  return value;
37
37
  }
38
- function renderSafeRichTextNode(node, key) {
38
+ const INLINE_RICH_TEXT_TYPES = new Set(['text', 'link', 'line-break']);
39
+ function assertInlineRichText(nodes, element) {
40
+ for (const node of nodes) {
41
+ if (!INLINE_RICH_TEXT_TYPES.has(node.type)) {
42
+ throw new Error(`SafeRichText as="${element}" renders inline content only; "${node.type}" is a block node.`);
43
+ }
44
+ if (node.type === 'link')
45
+ assertInlineRichText(node.children, element);
46
+ }
47
+ }
48
+ function renderSafeRichTextNode(node, key, linkClassName) {
39
49
  if (node.type === 'text') {
40
50
  if (node.emphasis === 'strong')
41
51
  return _jsx("strong", { children: node.value }, key);
@@ -45,7 +55,7 @@ function renderSafeRichTextNode(node, key) {
45
55
  }
46
56
  if (node.type === 'line-break')
47
57
  return _jsx("br", {}, key);
48
- const children = node.children.map((child, index) => renderSafeRichTextNode(child, `${key}-${index}`));
58
+ const children = node.children.map((child, index) => renderSafeRichTextNode(child, `${key}-${index}`, linkClassName));
49
59
  if (node.type === 'paragraph')
50
60
  return _jsx("p", { children: children }, key);
51
61
  if (node.type === 'list-item')
@@ -57,9 +67,60 @@ function renderSafeRichTextNode(node, key) {
57
67
  if (node.type !== 'link')
58
68
  throw new Error('Unsupported rich text node.');
59
69
  const href = assertSafeRichTextHref(node.href);
60
- return (_jsx("a", { href: href, ...(node.external ? { rel: 'noopener noreferrer', target: '_blank' } : {}), children: children }, key));
70
+ return (_jsx("a", { href: href, className: linkClassName, ...(node.external ? { rel: 'noopener noreferrer', target: '_blank' } : {}), children: children }, key));
71
+ }
72
+ export function SafeRichText({ nodes, as: Element = 'div', linkClassName, ...props }) {
73
+ if (Element !== 'div' && Element !== 'p' && Element !== 'span') {
74
+ throw new Error('SafeRichText renders as "div", "p" or "span".');
75
+ }
76
+ if (Element !== 'div')
77
+ assertInlineRichText(nodes, Element);
78
+ return (_jsx(Element, { ...props, children: nodes.map((node, index) => renderSafeRichTextNode(node, String(index), linkClassName)) }));
79
+ }
80
+ const INLINE_MARKUP_PATTERN = /<(strong|b)>(.*?)<\/\1>|<a\s+[^>]*href=(["'])(.*?)\3[^>]*>(.*?)<\/a>/gis;
81
+ /**
82
+ * Inline rich-text markup as nodes, for content written as short HTML
83
+ * strings: `<strong>` and `<b>` become strong text, `<a href>` becomes a link
84
+ * when its href passes sanitizeRichTextHref (otherwise its text stays as plain
85
+ * text), every other tag is dropped and text is kept exactly as written
86
+ * (React escapes it). Nothing is ever rendered as HTML. Strong text holds text
87
+ * only; markup nested inside it throws.
88
+ */
89
+ export function parseInlineRichText(markup) {
90
+ if (typeof markup !== 'string')
91
+ throw new TypeError('Inline rich text must be a string.');
92
+ return parseInlineMarkup(markup, false);
61
93
  }
62
- export function SafeRichText({ nodes, ...props }) {
63
- return (_jsx("div", { ...props, children: nodes.map((node, index) => renderSafeRichTextNode(node, String(index))) }));
94
+ function parseInlineMarkup(markup, insideLink) {
95
+ const nodes = [];
96
+ const pattern = new RegExp(INLINE_MARKUP_PATTERN.source, INLINE_MARKUP_PATTERN.flags);
97
+ const text = (value) => nodes.push({ type: 'text', value: value.replace(/<[^>]*>/g, '') });
98
+ let cursor = 0;
99
+ for (let match = pattern.exec(markup); match !== null; match = pattern.exec(markup)) {
100
+ if (match.index > cursor)
101
+ text(markup.slice(cursor, match.index));
102
+ const [, , strong, , href, linkText] = match;
103
+ if (typeof strong === 'string') {
104
+ const inner = parseInlineMarkup(strong, insideLink);
105
+ if (inner.length > 1 || (inner[0] && (inner[0].type !== 'text' || inner[0].emphasis))) {
106
+ throw new Error('Inline rich text supports only text inside <strong>.');
107
+ }
108
+ nodes.push({ type: 'text', value: inner[0]?.type === 'text' ? inner[0].value : '', emphasis: 'strong' });
109
+ }
110
+ else if (typeof href === 'string' && typeof linkText === 'string') {
111
+ const safeHref = insideLink ? null : sanitizeRichTextHref(href);
112
+ if (insideLink && sanitizeRichTextHref(href))
113
+ throw new Error('Inline rich text links cannot be nested.');
114
+ const children = parseInlineMarkup(linkText, true);
115
+ if (safeHref)
116
+ nodes.push({ type: 'link', href: safeHref, children });
117
+ else
118
+ nodes.push(...children);
119
+ }
120
+ cursor = match.index + match[0].length;
121
+ }
122
+ if (cursor < markup.length)
123
+ text(markup.slice(cursor));
124
+ return nodes;
64
125
  }
65
126
  //# sourceMappingURL=ui.js.map
package/dist/ui.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.tsx"],"names":[],"mappings":"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","sourcesContent":["import type {\n AnchorHTMLAttributes,\n DetailsHTMLAttributes,\n HTMLAttributes,\n ReactNode,\n} from 'react'\nimport { assertSafeRichTextHref } from '@brandlab-digital/site-core/rich-text'\n\nexport interface HeadlessSectionProps extends HTMLAttributes<HTMLElement> {\n heading: ReactNode\n headingId: string\n headingClassName?: string\n contentClassName?: string\n children: ReactNode\n}\n\nexport function HeadlessSection({\n heading,\n headingId,\n headingClassName,\n contentClassName,\n children,\n ...sectionProps\n}: HeadlessSectionProps) {\n return (\n <section {...sectionProps} aria-labelledby={headingId}>\n <h2 className={headingClassName} id={headingId}>\n {heading}\n </h2>\n <div className={contentClassName}>{children}</div>\n </section>\n )\n}\n\nexport interface HeadlessDisclosureProps extends DetailsHTMLAttributes<HTMLDetailsElement> {\n summary: ReactNode\n summaryClassName?: string\n contentClassName?: string\n children: ReactNode\n}\n\nexport function HeadlessDisclosure({\n summary,\n summaryClassName,\n contentClassName,\n children,\n ...detailsProps\n}: HeadlessDisclosureProps) {\n return (\n <details {...detailsProps}>\n <summary className={summaryClassName}>{summary}</summary>\n <div className={contentClassName}>{children}</div>\n </details>\n )\n}\n\nexport interface HeadlessFieldProps {\n id: string\n label: ReactNode\n description?: ReactNode\n error?: ReactNode\n required?: boolean\n className?: string\n labelClassName?: string\n descriptionClassName?: string\n errorClassName?: string\n children: (input: {\n id: string\n required: boolean\n 'aria-invalid': true | undefined\n 'aria-describedby': string | undefined\n }) => ReactNode\n}\n\nexport function HeadlessField({\n id,\n label,\n description,\n error,\n required = false,\n children,\n ...classes\n}: HeadlessFieldProps) {\n const descriptionId = description ? `${id}-description` : undefined\n const errorId = error ? `${id}-error` : undefined\n const describedBy = [descriptionId, errorId].filter(Boolean).join(' ') || undefined\n return (\n <div className={classes.className}>\n <label className={classes.labelClassName} htmlFor={id}>\n {label}\n </label>\n {description ? (\n <div className={classes.descriptionClassName} id={descriptionId}>\n {description}\n </div>\n ) : null}\n {children({\n id,\n required,\n 'aria-invalid': error ? true : undefined,\n 'aria-describedby': describedBy,\n })}\n {error ? (\n <div className={classes.errorClassName} id={errorId} role=\"alert\">\n {error}\n </div>\n ) : null}\n </div>\n )\n}\n\nexport interface HeadlessStatusProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode\n kind?: 'status' | 'error'\n}\n\nexport function HeadlessStatus({ children, kind = 'status', ...props }: HeadlessStatusProps) {\n return (\n <div {...props} aria-live={kind === 'error' ? 'assertive' : 'polite'} role={kind === 'error' ? 'alert' : 'status'}>\n {children}\n </div>\n )\n}\n\nexport interface HeadlessErrorSummaryItem {\n fieldId: string\n message: ReactNode\n}\n\nexport interface HeadlessErrorSummaryProps extends HTMLAttributes<HTMLDivElement> {\n heading: ReactNode\n errors: readonly HeadlessErrorSummaryItem[]\n headingId: string\n linkClassName?: string\n}\n\nexport function HeadlessErrorSummary({\n heading,\n errors,\n headingId,\n linkClassName,\n ...props\n}: HeadlessErrorSummaryProps) {\n if (errors.length === 0) return null\n return (\n <div {...props} aria-labelledby={headingId} role=\"alert\" tabIndex={-1}>\n <h2 id={headingId}>{heading}</h2>\n <ul>\n {errors.map((error) => (\n <li key={error.fieldId}>\n <a\n className={linkClassName}\n href={`#${assertHtmlIdentifier(error.fieldId, 'Error summary fieldId')}`}\n >\n {error.message}\n </a>\n </li>\n ))}\n </ul>\n </div>\n )\n}\n\nexport interface SkipLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n targetId: string\n children: ReactNode\n}\n\nexport function SkipLink({ targetId, children, ...props }: SkipLinkProps) {\n assertHtmlIdentifier(targetId, 'SkipLink targetId')\n return (\n <a {...props} href={`#${targetId}`}>\n {children}\n </a>\n )\n}\n\nfunction assertHtmlIdentifier(value: string, label: string) {\n if (!/^[A-Za-z][A-Za-z0-9_:.-]*$/.test(value)) {\n throw new Error(`${label} must be a valid HTML identifier.`)\n }\n return value\n}\n\nexport type SafeRichTextNode =\n | { type: 'text'; value: string; emphasis?: 'strong' | 'emphasis' }\n | { type: 'paragraph'; children: readonly SafeRichTextNode[] }\n | { type: 'link'; href: string; children: readonly SafeRichTextNode[]; external?: boolean }\n | { type: 'unordered-list' | 'ordered-list'; children: readonly SafeRichTextNode[] }\n | { type: 'list-item'; children: readonly SafeRichTextNode[] }\n | { type: 'line-break' }\n\nexport interface SafeRichTextProps extends HTMLAttributes<HTMLDivElement> {\n nodes: readonly SafeRichTextNode[]\n}\n\nfunction renderSafeRichTextNode(node: SafeRichTextNode, key: string): ReactNode {\n if (node.type === 'text') {\n if (node.emphasis === 'strong') return <strong key={key}>{node.value}</strong>\n if (node.emphasis === 'emphasis') return <em key={key}>{node.value}</em>\n return node.value\n }\n if (node.type === 'line-break') return <br key={key} />\n const children = node.children.map((child, index) =>\n renderSafeRichTextNode(child, `${key}-${index}`),\n )\n if (node.type === 'paragraph') return <p key={key}>{children}</p>\n if (node.type === 'list-item') return <li key={key}>{children}</li>\n if (node.type === 'unordered-list') return <ul key={key}>{children}</ul>\n if (node.type === 'ordered-list') return <ol key={key}>{children}</ol>\n if (node.type !== 'link') throw new Error('Unsupported rich text node.')\n const href = assertSafeRichTextHref(node.href)\n return (\n <a\n href={href}\n key={key}\n {...(node.external ? { rel: 'noopener noreferrer', target: '_blank' } : {})}\n >\n {children}\n </a>\n )\n}\n\nexport function SafeRichText({ nodes, ...props }: SafeRichTextProps) {\n return (\n <div {...props}>\n {nodes.map((node, index) => renderSafeRichTextNode(node, String(index)))}\n </div>\n )\n}\n"]}
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.tsx"],"names":[],"mappings":"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","sourcesContent":["import type {\n AnchorHTMLAttributes,\n DetailsHTMLAttributes,\n HTMLAttributes,\n ReactNode,\n} from 'react'\nimport { assertSafeRichTextHref, sanitizeRichTextHref } from '@brandlab-digital/site-core/rich-text'\n\nexport interface HeadlessSectionProps extends HTMLAttributes<HTMLElement> {\n heading: ReactNode\n headingId: string\n headingClassName?: string\n contentClassName?: string\n children: ReactNode\n}\n\nexport function HeadlessSection({\n heading,\n headingId,\n headingClassName,\n contentClassName,\n children,\n ...sectionProps\n}: HeadlessSectionProps) {\n return (\n <section {...sectionProps} aria-labelledby={headingId}>\n <h2 className={headingClassName} id={headingId}>\n {heading}\n </h2>\n <div className={contentClassName}>{children}</div>\n </section>\n )\n}\n\nexport interface HeadlessDisclosureProps extends DetailsHTMLAttributes<HTMLDetailsElement> {\n summary: ReactNode\n summaryClassName?: string\n contentClassName?: string\n children: ReactNode\n}\n\nexport function HeadlessDisclosure({\n summary,\n summaryClassName,\n contentClassName,\n children,\n ...detailsProps\n}: HeadlessDisclosureProps) {\n return (\n <details {...detailsProps}>\n <summary className={summaryClassName}>{summary}</summary>\n <div className={contentClassName}>{children}</div>\n </details>\n )\n}\n\nexport interface HeadlessFieldProps {\n id: string\n label: ReactNode\n description?: ReactNode\n error?: ReactNode\n required?: boolean\n className?: string\n labelClassName?: string\n descriptionClassName?: string\n errorClassName?: string\n children: (input: {\n id: string\n required: boolean\n 'aria-invalid': true | undefined\n 'aria-describedby': string | undefined\n }) => ReactNode\n}\n\nexport function HeadlessField({\n id,\n label,\n description,\n error,\n required = false,\n children,\n ...classes\n}: HeadlessFieldProps) {\n const descriptionId = description ? `${id}-description` : undefined\n const errorId = error ? `${id}-error` : undefined\n const describedBy = [descriptionId, errorId].filter(Boolean).join(' ') || undefined\n return (\n <div className={classes.className}>\n <label className={classes.labelClassName} htmlFor={id}>\n {label}\n </label>\n {description ? (\n <div className={classes.descriptionClassName} id={descriptionId}>\n {description}\n </div>\n ) : null}\n {children({\n id,\n required,\n 'aria-invalid': error ? true : undefined,\n 'aria-describedby': describedBy,\n })}\n {error ? (\n <div className={classes.errorClassName} id={errorId} role=\"alert\">\n {error}\n </div>\n ) : null}\n </div>\n )\n}\n\nexport interface HeadlessStatusProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode\n kind?: 'status' | 'error'\n}\n\nexport function HeadlessStatus({ children, kind = 'status', ...props }: HeadlessStatusProps) {\n return (\n <div {...props} aria-live={kind === 'error' ? 'assertive' : 'polite'} role={kind === 'error' ? 'alert' : 'status'}>\n {children}\n </div>\n )\n}\n\nexport interface HeadlessErrorSummaryItem {\n fieldId: string\n message: ReactNode\n}\n\nexport interface HeadlessErrorSummaryProps extends HTMLAttributes<HTMLDivElement> {\n heading: ReactNode\n errors: readonly HeadlessErrorSummaryItem[]\n headingId: string\n linkClassName?: string\n}\n\nexport function HeadlessErrorSummary({\n heading,\n errors,\n headingId,\n linkClassName,\n ...props\n}: HeadlessErrorSummaryProps) {\n if (errors.length === 0) return null\n return (\n <div {...props} aria-labelledby={headingId} role=\"alert\" tabIndex={-1}>\n <h2 id={headingId}>{heading}</h2>\n <ul>\n {errors.map((error) => (\n <li key={error.fieldId}>\n <a\n className={linkClassName}\n href={`#${assertHtmlIdentifier(error.fieldId, 'Error summary fieldId')}`}\n >\n {error.message}\n </a>\n </li>\n ))}\n </ul>\n </div>\n )\n}\n\nexport interface SkipLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n targetId: string\n children: ReactNode\n}\n\nexport function SkipLink({ targetId, children, ...props }: SkipLinkProps) {\n assertHtmlIdentifier(targetId, 'SkipLink targetId')\n return (\n <a {...props} href={`#${targetId}`}>\n {children}\n </a>\n )\n}\n\nfunction assertHtmlIdentifier(value: string, label: string) {\n if (!/^[A-Za-z][A-Za-z0-9_:.-]*$/.test(value)) {\n throw new Error(`${label} must be a valid HTML identifier.`)\n }\n return value\n}\n\nexport type SafeRichTextNode =\n | { type: 'text'; value: string; emphasis?: 'strong' | 'emphasis' }\n | { type: 'paragraph'; children: readonly SafeRichTextNode[] }\n | { type: 'link'; href: string; children: readonly SafeRichTextNode[]; external?: boolean }\n | { type: 'unordered-list' | 'ordered-list'; children: readonly SafeRichTextNode[] }\n | { type: 'list-item'; children: readonly SafeRichTextNode[] }\n | { type: 'line-break' }\n\nexport type SafeRichTextElement = 'div' | 'p' | 'span'\n\nexport interface SafeRichTextProps extends HTMLAttributes<HTMLElement> {\n nodes: readonly SafeRichTextNode[]\n /**\n * The wrapper element. `div` (default) holds block content: paragraphs and\n * lists. `p` and `span` hold inline content only (text, emphasis, links and\n * line breaks), so the output has no block element and can sit where only\n * phrasing content is allowed, such as inside a button; a block node under\n * them throws.\n */\n as?: SafeRichTextElement\n /** Class for every link, rendered after `href`. */\n linkClassName?: string\n}\n\nconst INLINE_RICH_TEXT_TYPES = new Set<SafeRichTextNode['type']>(['text', 'link', 'line-break'])\n\nfunction assertInlineRichText(nodes: readonly SafeRichTextNode[], element: SafeRichTextElement) {\n for (const node of nodes) {\n if (!INLINE_RICH_TEXT_TYPES.has(node.type)) {\n throw new Error(`SafeRichText as=\"${element}\" renders inline content only; \"${node.type}\" is a block node.`)\n }\n if (node.type === 'link') assertInlineRichText(node.children, element)\n }\n}\n\nfunction renderSafeRichTextNode(node: SafeRichTextNode, key: string, linkClassName?: string): ReactNode {\n if (node.type === 'text') {\n if (node.emphasis === 'strong') return <strong key={key}>{node.value}</strong>\n if (node.emphasis === 'emphasis') return <em key={key}>{node.value}</em>\n return node.value\n }\n if (node.type === 'line-break') return <br key={key} />\n const children = node.children.map((child, index) =>\n renderSafeRichTextNode(child, `${key}-${index}`, linkClassName),\n )\n if (node.type === 'paragraph') return <p key={key}>{children}</p>\n if (node.type === 'list-item') return <li key={key}>{children}</li>\n if (node.type === 'unordered-list') return <ul key={key}>{children}</ul>\n if (node.type === 'ordered-list') return <ol key={key}>{children}</ol>\n if (node.type !== 'link') throw new Error('Unsupported rich text node.')\n const href = assertSafeRichTextHref(node.href)\n return (\n <a\n href={href}\n className={linkClassName}\n key={key}\n {...(node.external ? { rel: 'noopener noreferrer', target: '_blank' } : {})}\n >\n {children}\n </a>\n )\n}\n\nexport function SafeRichText({ nodes, as: Element = 'div', linkClassName, ...props }: SafeRichTextProps) {\n if (Element !== 'div' && Element !== 'p' && Element !== 'span') {\n throw new Error('SafeRichText renders as \"div\", \"p\" or \"span\".')\n }\n if (Element !== 'div') assertInlineRichText(nodes, Element)\n return (\n <Element {...props}>\n {nodes.map((node, index) => renderSafeRichTextNode(node, String(index), linkClassName))}\n </Element>\n )\n}\n\nconst INLINE_MARKUP_PATTERN = /<(strong|b)>(.*?)<\\/\\1>|<a\\s+[^>]*href=([\"'])(.*?)\\3[^>]*>(.*?)<\\/a>/gis\n\n/**\n * Inline rich-text markup as nodes, for content written as short HTML\n * strings: `<strong>` and `<b>` become strong text, `<a href>` becomes a link\n * when its href passes sanitizeRichTextHref (otherwise its text stays as plain\n * text), every other tag is dropped and text is kept exactly as written\n * (React escapes it). Nothing is ever rendered as HTML. Strong text holds text\n * only; markup nested inside it throws.\n */\nexport function parseInlineRichText(markup: string): SafeRichTextNode[] {\n if (typeof markup !== 'string') throw new TypeError('Inline rich text must be a string.')\n return parseInlineMarkup(markup, false)\n}\n\nfunction parseInlineMarkup(markup: string, insideLink: boolean): SafeRichTextNode[] {\n const nodes: SafeRichTextNode[] = []\n const pattern = new RegExp(INLINE_MARKUP_PATTERN.source, INLINE_MARKUP_PATTERN.flags)\n const text = (value: string) => nodes.push({ type: 'text', value: value.replace(/<[^>]*>/g, '') })\n let cursor = 0\n for (let match = pattern.exec(markup); match !== null; match = pattern.exec(markup)) {\n if (match.index > cursor) text(markup.slice(cursor, match.index))\n const [, , strong, , href, linkText] = match\n if (typeof strong === 'string') {\n const inner = parseInlineMarkup(strong, insideLink)\n if (inner.length > 1 || (inner[0] && (inner[0].type !== 'text' || inner[0].emphasis))) {\n throw new Error('Inline rich text supports only text inside <strong>.')\n }\n nodes.push({ type: 'text', value: inner[0]?.type === 'text' ? inner[0].value : '', emphasis: 'strong' })\n } else if (typeof href === 'string' && typeof linkText === 'string') {\n const safeHref = insideLink ? null : sanitizeRichTextHref(href)\n if (insideLink && sanitizeRichTextHref(href)) throw new Error('Inline rich text links cannot be nested.')\n const children = parseInlineMarkup(linkText, true)\n if (safeHref) nodes.push({ type: 'link', href: safeHref, children })\n else nodes.push(...children)\n }\n cursor = match.index + match[0].length\n }\n if (cursor < markup.length) text(markup.slice(cursor))\n return nodes\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brandlab-digital/site-next",
3
- "version": "2.1.0",
3
+ "version": "3.0.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/RomieDandan/brandlab.git",
@@ -20,7 +20,7 @@
20
20
  "typecheck": "tsc --noEmit -p tsconfig.json"
21
21
  },
22
22
  "dependencies": {
23
- "@brandlab-digital/site-core": "2.1.0",
23
+ "@brandlab-digital/site-core": "3.0.0",
24
24
  "browser-image-compression": "2.0.2",
25
25
  "pdf-lib": "1.17.1",
26
26
  "server-only": "0.0.1",
@@ -28,7 +28,8 @@
28
28
  },
29
29
  "peerDependencies": {
30
30
  "next": ">=16",
31
- "react": ">=19"
31
+ "react": ">=19",
32
+ "resend": ">=6"
32
33
  },
33
34
  "peerDependenciesMeta": {
34
35
  "next": {
@@ -36,6 +37,9 @@
36
37
  },
37
38
  "react": {
38
39
  "optional": true
40
+ },
41
+ "resend": {
42
+ "optional": true
39
43
  }
40
44
  },
41
45
  "exports": {
@@ -112,6 +116,11 @@
112
116
  "import": "./dist/headers.js",
113
117
  "require": "./dist/headers.js"
114
118
  },
119
+ "./next-config": {
120
+ "types": "./dist/next-config.d.ts",
121
+ "import": "./dist/next-config.js",
122
+ "require": "./dist/next-config.js"
123
+ },
115
124
  "./google-reviews/server": {
116
125
  "types": "./dist/google-reviews-server.d.ts",
117
126
  "import": "./dist/google-reviews-server.js"
@@ -128,6 +137,10 @@
128
137
  "types": "./dist/image-runtime.d.ts",
129
138
  "import": "./dist/image-runtime.js",
130
139
  "require": "./dist/image-runtime.js"
140
+ },
141
+ "./testing/server-only": {
142
+ "types": "./dist/testing/server-only.d.ts",
143
+ "import": "./dist/testing/server-only.js"
131
144
  }
132
145
  }
133
146
  }