@bettercms-ai/next 0.24.0 → 0.26.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.
@@ -0,0 +1,88 @@
1
+ import { CSSProperties, ReactNode, ReactElement } from 'react';
2
+ import { ContentBlock, DeliveryComponent } from '@bettercms-ai/types';
3
+ import { DeliveryForm } from '@bettercms-ai/sdk';
4
+
5
+ /**
6
+ * C3/C4 — `sectionRootAttrs(block)`: the props a site's OWN section root spreads so the
7
+ * BetterCMS editor offers that section's spacing and style handles.
8
+ *
9
+ * <section className="hero" {...sectionRootAttrs(block)}>…</section>
10
+ *
11
+ * The editor shows those handles on a site-rendered page only when EVERY root the site stamps
12
+ * with `data-bcms-block` also carries `data-bcms-style`, which is the site's promise that "this
13
+ * root's inline style is `blockStyleToCss(block.style)`" — the same declarations `<BcmsBlocks>`
14
+ * puts on its own wrapper. The marker is present even when the style is EMPTY (then there is no
15
+ * `style` prop at all): an unstyled section is the one an author is about to give its first
16
+ * spacing edit. Twin: `sectionRootAttrs` in @bettercms-ai/astro (style as a string there).
17
+ */
18
+
19
+ interface SectionRootAttrs {
20
+ "data-bcms-block"?: string;
21
+ "data-bcms-style": "";
22
+ /** `"mobile tablet"` when `style.hideOn` hides it there; the site ships `RESPONSIVE_CSS` for it. */
23
+ "data-bcms-hide"?: string;
24
+ /** `blockStyleToCss(block.style)`; absent when the block has no style. */
25
+ style?: CSSProperties;
26
+ }
27
+
28
+ /**
29
+ * <BcmsSections> — a code-built page's sections, in the order its CMS page lists them.
30
+ *
31
+ * <BcmsSections {...sectionsFor("home")}>
32
+ * <BcmsSection bind="hero"><Hero /></BcmsSection>
33
+ * <BcmsSection bind="features">{(root) => <Features rootProps={root} />}</BcmsSection>
34
+ * </BcmsSections>
35
+ *
36
+ * Each section the page can draw is a `<BcmsSection>` child, named by its placement's bind: what is
37
+ * inside is the site's own and is rendered as written. The CMS page's block list decides the rest:
38
+ *
39
+ * - a block bound to a section renders it at the block's position, stamped (below);
40
+ * - a block with no bind (a section added from the library) renders through `<BcmsBlocks>`;
41
+ * - a section no block names: `code:<bind>` always renders where the source has it; a bare `<bind>`
42
+ * does too until the list names one of this page's sections, and from then on it is a removed one.
43
+ *
44
+ * With `blocks` null (a build without a snapshot) every child renders in source order, untouched.
45
+ *
46
+ * THE STAMP goes on the section's own root, never on a box of ours that changes layout:
47
+ * - one DOM element (`<section>`): `data-bcms-block`, `data-bcms-style` and the block's style are
48
+ * cloned onto it, its own style first;
49
+ * - a function child is handed those props and puts them on its root itself: the way a COMPONENT
50
+ * section takes its style, since a component may not pass unknown props on;
51
+ * - a component or several children: a box of ours carries the stamp. `display:contents` while
52
+ * the block has no style, so the page lays out as written; `display:flow-root` with the style on
53
+ * it once the block has one, because a box that draws nothing cannot show a padding. A styled
54
+ * box is ONE block box: in a flex or grid parent its children are one item, and their margins
55
+ * stop collapsing with the neighbours'. The function-child form has no box and no such limit.
56
+ *
57
+ * Server-safe (no hooks, no "use client"): a Server Component in the App Router, and plain React
58
+ * in the Pages Router, where `blocks` must come through page props so the client renders the same
59
+ * list (`sectionsStaticProps`). Twin: BcmsSections.astro in @bettercms-ai/astro; the order is
60
+ * `planSections` in @bettercms-ai/types.
61
+ */
62
+
63
+ /** What a function child receives: spread it on the section's root element. Empty when no block places the section. */
64
+ type SectionRootProps = Partial<SectionRootAttrs> & {
65
+ "data-bcms-sections"?: string;
66
+ };
67
+ interface BcmsSectionProps {
68
+ /** The placement's bind (`hero`), or `code:<bind>` for a section the CMS did not hold when the page was wrapped. */
69
+ bind: string;
70
+ children: ReactNode | ((root: SectionRootProps) => ReactNode);
71
+ }
72
+ /** One section of the page. Outside `<BcmsSections>` it renders its children as they are. */
73
+ declare function BcmsSection({ children }: BcmsSectionProps): ReactElement;
74
+ interface BcmsSectionsProps {
75
+ /** The CMS page's slug: `home`, `services`. */
76
+ page: string;
77
+ /** The page's block list: `sectionsFor(slug).blocks`, or a draft read. Null or absent renders the source order. */
78
+ blocks?: ContentBlock[] | null;
79
+ /** Component definitions and forms for the sections `<BcmsBlocks>` draws. */
80
+ components?: DeliveryComponent[];
81
+ forms?: DeliveryForm[];
82
+ /** The instant block windows are read against. Defaults to the render time. */
83
+ now?: Date;
84
+ children?: ReactNode;
85
+ }
86
+ declare function BcmsSections({ page, blocks, components, forms, now, children }: BcmsSectionsProps): ReactElement;
87
+
88
+ export { BcmsSection, type BcmsSectionProps, BcmsSections, type BcmsSectionsProps, type SectionRootProps };
@@ -0,0 +1,73 @@
1
+ // src/sections.tsx
2
+ import { Children, Fragment, cloneElement, isValidElement } from "react";
3
+ import { CODE_SLOT_PREFIX, RESPONSIVE_CSS, planSections, usesHideOn, visibleBlocks } from "@bettercms-ai/types";
4
+ import { BcmsBlocks } from "./blocks.js";
5
+
6
+ // src/section-root.ts
7
+ import { blockStyleToColumnCss, blockStyleToCss, hideOnAttr } from "@bettercms-ai/types";
8
+ function sectionRootAttrs(block) {
9
+ const css = blockStyleToCss(block?.style ?? void 0);
10
+ const id = typeof block?.id === "string" && block.id !== "" ? block.id : void 0;
11
+ const hide = hideOnAttr(block?.style);
12
+ return {
13
+ ...id !== void 0 ? { "data-bcms-block": id } : {},
14
+ "data-bcms-style": "",
15
+ ...hide ? { "data-bcms-hide": hide } : {},
16
+ ...css ? { style: css } : {}
17
+ };
18
+ }
19
+
20
+ // src/sections.tsx
21
+ import { Fragment as Fragment2, jsx, jsxs } from "react/jsx-runtime";
22
+ var contentOf = (children, root) => typeof children === "function" ? children(root) : children;
23
+ function BcmsSection({ children }) {
24
+ return /* @__PURE__ */ jsx(Fragment2, { children: contentOf(children, {}) });
25
+ }
26
+ function stamped(children, block, page) {
27
+ const attrs = sectionRootAttrs(block);
28
+ if (attrs["data-bcms-block"] === void 0) return contentOf(children, {});
29
+ const root = { ...attrs, "data-bcms-sections": page };
30
+ if (typeof children === "function") return children(root);
31
+ const only = Children.toArray(children);
32
+ const sole = only.length === 1 && isValidElement(only[0]) && typeof only[0].type === "string" ? only[0] : null;
33
+ if (sole) {
34
+ if (sole.props["data-bcms-block"] !== void 0) return sole;
35
+ const style = attrs.style ? { ...sole.props.style, ...attrs.style } : sole.props.style;
36
+ return cloneElement(sole, { ...root, style });
37
+ }
38
+ if (only.length === 0) return null;
39
+ const box = !attrs.style ? { display: "contents" } : attrs.style.display !== void 0 ? attrs.style : { display: "flow-root", ...attrs.style };
40
+ return /* @__PURE__ */ jsx("div", { style: box, "data-bcms-block": attrs["data-bcms-block"], "data-bcms-style": "", "data-bcms-hide": attrs["data-bcms-hide"], "data-bcms-box": "", "data-bcms-sections": page, children });
41
+ }
42
+ function BcmsSections({ page, blocks, components, forms, now, children }) {
43
+ const slots = /* @__PURE__ */ new Map();
44
+ Children.toArray(children).forEach((child, n) => {
45
+ const section = isValidElement(child) && child.type === BcmsSection ? child.props : null;
46
+ const name = section ? section.bind : `${CODE_SLOT_PREFIX}~${n}`;
47
+ if (!slots.has(name)) slots.set(name, section ? section.children : child);
48
+ });
49
+ const plan = planSections([...slots.keys()], Array.isArray(blocks) ? visibleBlocks(blocks, now ?? /* @__PURE__ */ new Date()) : null);
50
+ const parts = [];
51
+ for (const item of plan) {
52
+ if (item.slot !== null) {
53
+ const content = slots.get(item.slot);
54
+ parts.push({ node: item.block ? stamped(content, item.block, page) : contentOf(content, {}) });
55
+ continue;
56
+ }
57
+ const last = parts[parts.length - 1];
58
+ if (last && "blocks" in last) last.blocks.push(item.block);
59
+ else parts.push({ blocks: [item.block] });
60
+ }
61
+ const hides = usesHideOn(plan.filter((item) => item.slot !== null).map((item) => item.block));
62
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
63
+ hides && /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: RESPONSIVE_CSS } }),
64
+ parts.map(
65
+ (part, n) => "node" in part ? /* @__PURE__ */ jsx(Fragment, { children: part.node }, n) : /* @__PURE__ */ jsx(BcmsBlocks, { blocks: part.blocks, components, forms, now }, n)
66
+ )
67
+ ] });
68
+ }
69
+ export {
70
+ BcmsSection,
71
+ BcmsSections
72
+ };
73
+ //# sourceMappingURL=sections.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sections.tsx","../src/section-root.ts"],"sourcesContent":["/**\n * <BcmsSections> — a code-built page's sections, in the order its CMS page lists them.\n *\n * <BcmsSections {...sectionsFor(\"home\")}>\n * <BcmsSection bind=\"hero\"><Hero /></BcmsSection>\n * <BcmsSection bind=\"features\">{(root) => <Features rootProps={root} />}</BcmsSection>\n * </BcmsSections>\n *\n * Each section the page can draw is a `<BcmsSection>` child, named by its placement's bind: what is\n * inside is the site's own and is rendered as written. The CMS page's block list decides the rest:\n *\n * - a block bound to a section renders it at the block's position, stamped (below);\n * - a block with no bind (a section added from the library) renders through `<BcmsBlocks>`;\n * - a section no block names: `code:<bind>` always renders where the source has it; a bare `<bind>`\n * does too until the list names one of this page's sections, and from then on it is a removed one.\n *\n * With `blocks` null (a build without a snapshot) every child renders in source order, untouched.\n *\n * THE STAMP goes on the section's own root, never on a box of ours that changes layout:\n * - one DOM element (`<section>`): `data-bcms-block`, `data-bcms-style` and the block's style are\n * cloned onto it, its own style first;\n * - a function child is handed those props and puts them on its root itself: the way a COMPONENT\n * section takes its style, since a component may not pass unknown props on;\n * - a component or several children: a box of ours carries the stamp. `display:contents` while\n * the block has no style, so the page lays out as written; `display:flow-root` with the style on\n * it once the block has one, because a box that draws nothing cannot show a padding. A styled\n * box is ONE block box: in a flex or grid parent its children are one item, and their margins\n * stop collapsing with the neighbours'. The function-child form has no box and no such limit.\n *\n * Server-safe (no hooks, no \"use client\"): a Server Component in the App Router, and plain React\n * in the Pages Router, where `blocks` must come through page props so the client renders the same\n * list (`sectionsStaticProps`). Twin: BcmsSections.astro in @bettercms-ai/astro; the order is\n * `planSections` in @bettercms-ai/types.\n */\nimport { Children, Fragment, cloneElement, isValidElement, type CSSProperties, type ReactElement, type ReactNode } from \"react\";\nimport { CODE_SLOT_PREFIX, RESPONSIVE_CSS, planSections, usesHideOn, visibleBlocks, type ContentBlock, type DeliveryComponent } from \"@bettercms-ai/types\";\nimport type { DeliveryForm } from \"@bettercms-ai/sdk\";\nimport { BcmsBlocks } from \"./blocks.js\";\nimport { sectionRootAttrs, type SectionRootAttrs } from \"./section-root.js\";\n\n/** What a function child receives: spread it on the section's root element. Empty when no block places the section. */\nexport type SectionRootProps = Partial<SectionRootAttrs> & { \"data-bcms-sections\"?: string };\n\nexport interface BcmsSectionProps {\n /** The placement's bind (`hero`), or `code:<bind>` for a section the CMS did not hold when the page was wrapped. */\n bind: string;\n children: ReactNode | ((root: SectionRootProps) => ReactNode);\n}\n\nconst contentOf = (children: BcmsSectionProps[\"children\"], root: SectionRootProps): ReactNode =>\n typeof children === \"function\" ? children(root) : children;\n\n/** One section of the page. Outside `<BcmsSections>` it renders its children as they are. */\nexport function BcmsSection({ children }: BcmsSectionProps): ReactElement {\n return <>{contentOf(children, {})}</>;\n}\n\nexport interface BcmsSectionsProps {\n /** The CMS page's slug: `home`, `services`. */\n page: string;\n /** The page's block list: `sectionsFor(slug).blocks`, or a draft read. Null or absent renders the source order. */\n blocks?: ContentBlock[] | null;\n /** Component definitions and forms for the sections `<BcmsBlocks>` draws. */\n components?: DeliveryComponent[];\n forms?: DeliveryForm[];\n /** The instant block windows are read against. Defaults to the render time. */\n now?: Date;\n children?: ReactNode;\n}\n\nfunction stamped(children: BcmsSectionProps[\"children\"], block: ContentBlock, page: string): ReactNode {\n const attrs = sectionRootAttrs(block);\n if (attrs[\"data-bcms-block\"] === undefined) return contentOf(children, {});\n const root: SectionRootProps = { ...attrs, \"data-bcms-sections\": page };\n if (typeof children === \"function\") return children(root);\n const only = Children.toArray(children);\n const sole = only.length === 1 && isValidElement(only[0]) && typeof only[0].type === \"string\" ? (only[0] as ReactElement<Record<string, unknown>>) : null;\n if (sole) {\n // A root that already stamps a block is the site's own work.\n if (sole.props[\"data-bcms-block\"] !== undefined) return sole;\n // The site's declarations first, the block's after, as the in-place painter orders them.\n const style = attrs.style ? { ...(sole.props.style as CSSProperties | undefined), ...attrs.style } : sole.props.style;\n return cloneElement(sole, { ...root, style });\n }\n if (only.length === 0) return null;\n // As `stampSectionRoot` in @bettercms-ai/astro writes it, attribute for attribute.\n const box: CSSProperties = !attrs.style ? { display: \"contents\" } : attrs.style.display !== undefined ? attrs.style : { display: \"flow-root\", ...attrs.style };\n return (\n <div style={box} data-bcms-block={attrs[\"data-bcms-block\"]} data-bcms-style=\"\" data-bcms-hide={attrs[\"data-bcms-hide\"]} data-bcms-box=\"\" data-bcms-sections={page}>\n {children}\n </div>\n );\n}\n\nexport function BcmsSections({ page, blocks, components, forms, now, children }: BcmsSectionsProps): ReactElement {\n // A child that is not a <BcmsSection> is the page's too: it keeps its place, like a `code:` section.\n const slots = new Map<string, BcmsSectionProps[\"children\"]>();\n Children.toArray(children).forEach((child, n) => {\n const section = isValidElement(child) && child.type === BcmsSection ? (child.props as BcmsSectionProps) : null;\n const name = section ? section.bind : `${CODE_SLOT_PREFIX}~${n}`;\n if (!slots.has(name)) slots.set(name, section ? section.children : child);\n });\n const plan = planSections([...slots.keys()], Array.isArray(blocks) ? visibleBlocks(blocks, now ?? new Date()) : null);\n\n // Consecutive CMS blocks share one <BcmsBlocks>, so its container wraps the run once.\n const parts: Array<{ node: ReactNode } | { blocks: ContentBlock[] }> = [];\n for (const item of plan) {\n if (item.slot !== null) {\n const content = slots.get(item.slot)!;\n parts.push({ node: item.block ? stamped(content, item.block, page) : contentOf(content, {}) });\n continue;\n }\n const last = parts[parts.length - 1];\n if (last && \"blocks\" in last) last.blocks.push(item.block);\n else parts.push({ blocks: [item.block] });\n }\n // Only when a placed section hides somewhere, so a page without `hideOn` renders exactly as before.\n const hides = usesHideOn(plan.filter((item) => item.slot !== null).map((item) => item.block));\n return (\n <>\n {hides && <style dangerouslySetInnerHTML={{ __html: RESPONSIVE_CSS }} />}\n {parts.map((part, n) =>\n \"node\" in part ? (\n <Fragment key={n}>{part.node}</Fragment>\n ) : (\n <BcmsBlocks key={n} blocks={part.blocks} components={components} forms={forms} now={now} />\n ),\n )}\n </>\n );\n}\n","/**\n * C3/C4 — `sectionRootAttrs(block)`: the props a site's OWN section root spreads so the\n * BetterCMS editor offers that section's spacing and style handles.\n *\n * <section className=\"hero\" {...sectionRootAttrs(block)}>…</section>\n *\n * The editor shows those handles on a site-rendered page only when EVERY root the site stamps\n * with `data-bcms-block` also carries `data-bcms-style`, which is the site's promise that \"this\n * root's inline style is `blockStyleToCss(block.style)`\" — the same declarations `<BcmsBlocks>`\n * puts on its own wrapper. The marker is present even when the style is EMPTY (then there is no\n * `style` prop at all): an unstyled section is the one an author is about to give its first\n * spacing edit. Twin: `sectionRootAttrs` in @bettercms-ai/astro (style as a string there).\n */\nimport type { CSSProperties } from \"react\";\nimport { blockStyleToColumnCss, blockStyleToCss, hideOnAttr, type BlockStyle } from \"@bettercms-ai/types\";\n\nexport interface SectionRootBlock {\n id?: string | null;\n style?: BlockStyle | Record<string, unknown> | null;\n}\n\nexport interface SectionRootAttrs {\n \"data-bcms-block\"?: string;\n \"data-bcms-style\": \"\";\n /** `\"mobile tablet\"` when `style.hideOn` hides it there; the site ships `RESPONSIVE_CSS` for it. */\n \"data-bcms-hide\"?: string;\n /** `blockStyleToCss(block.style)`; absent when the block has no style. */\n style?: CSSProperties;\n}\n\nexport function sectionRootAttrs(block: SectionRootBlock | null | undefined): SectionRootAttrs {\n const css = blockStyleToCss((block?.style ?? undefined) as BlockStyle | undefined);\n const id = typeof block?.id === \"string\" && block.id !== \"\" ? block.id : undefined;\n const hide = hideOnAttr(block?.style);\n return {\n ...(id !== undefined ? { \"data-bcms-block\": id } : {}),\n \"data-bcms-style\": \"\",\n ...(hide ? { \"data-bcms-hide\": hide } : {}),\n ...(css ? { style: css as CSSProperties } : {}),\n };\n}\n\nexport interface SectionColumnAttrs {\n \"data-bcms-column\": \"\";\n /** `blockStyleToColumnCss(block.style)`; absent when the section has no column. */\n style?: CSSProperties;\n}\n\n/**\n * C3 — `sectionColumnAttrs(block)`: the props a site's own INNER container spreads so the section's\n * content WIDTH ships (`style.contentWidth`, placed by `contentAlign`). The column BetterCMS draws as\n * `.bcms-block-inner`, never on the root (its background stays full-bleed); `data-bcms-column` is the\n * site's promise that this box's inline style is that column. Twin: @bettercms-ai/astro.\n */\nexport function sectionColumnAttrs(block: SectionRootBlock | null | undefined): SectionColumnAttrs {\n const css = blockStyleToColumnCss((block?.style ?? undefined) as BlockStyle | undefined);\n return { \"data-bcms-column\": \"\", ...(css ? { style: css as CSSProperties } : {}) };\n}\n"],"mappings":"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","names":["Fragment"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bettercms-ai/next",
3
- "version": "0.24.0",
3
+ "version": "0.26.0",
4
4
  "type": "module",
5
5
  "description": "The BetterCMS adapter for Next.js — typed, cache-aware content reads (getEntry/listEntries), draft preview, build-time content snapshot, and llms.txt generation for the App Router. The /blocks, /form, /field, /search and /visual-editing entries are framework-free React and work in any React app (see the React+TS starter), which is why `next` is an OPTIONAL peer.",
6
6
  "bin": {
@@ -31,6 +31,11 @@
31
31
  "import": "./dist/blocks.js",
32
32
  "default": "./dist/blocks.js"
33
33
  },
34
+ "./sections": {
35
+ "types": "./dist/sections.d.ts",
36
+ "import": "./dist/sections.js",
37
+ "default": "./dist/sections.js"
38
+ },
34
39
  "./live": {
35
40
  "types": "./dist/live.d.ts",
36
41
  "import": "./dist/live.js",
@@ -58,12 +63,12 @@
58
63
  "test:watch": "vitest"
59
64
  },
60
65
  "dependencies": {
61
- "@bettercms-ai/icons": "^0.2.0",
66
+ "@bettercms-ai/icons": "^0.3.0",
62
67
  "@bettercms-ai/image-url": "^0.4.0",
63
- "@bettercms-ai/richtext": "^0.8.1",
68
+ "@bettercms-ai/richtext": "^0.8.2",
64
69
  "@bettercms-ai/sdk": "^1.29.0",
65
- "@bettercms-ai/types": "^1.41.0",
66
- "@bettercms-ai/ui": "^0.15.1",
70
+ "@bettercms-ai/types": "^1.43.0",
71
+ "@bettercms-ai/ui": "^0.16.0",
67
72
  "react-phone-number-input": "^3.4.18"
68
73
  },
69
74
  "peerDependencies": {