@bettercms-ai/ui 0.3.0 → 0.5.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.
- package/dist/Video-DRC_fPjV.d.ts +53 -0
- package/dist/blocks.d.ts +3 -3
- package/dist/blocks.js +111 -48
- package/dist/blocks.js.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +178 -90
- package/dist/index.js.map +1 -1
- package/dist/registry.js +138 -48
- package/dist/registry.js.map +1 -1
- package/dist/renderer.d.ts +5 -2
- package/dist/renderer.js +178 -90
- package/dist/renderer.js.map +1 -1
- package/dist/resolve.d.ts +34 -1
- package/dist/resolve.js +65 -0
- package/dist/resolve.js.map +1 -1
- package/package.json +2 -2
- package/dist/Video-Dd3TLlXA.d.ts +0 -45
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { HeadingProps, TextProps, PortableTextDocument, ImageProps, ButtonProps, SpacerProps, ColumnsProps, ContentBlock, VideoProps } from '@bettercms-ai/types';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
/** Preview-only attributes understood by the BetterCMS visual editor. */
|
|
6
|
+
type BcmsBindingProps = {
|
|
7
|
+
"data-bcms-field"?: string;
|
|
8
|
+
"data-bcms-kind"?: "text" | "richtext" | "image";
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
interface HeadingBlockProps extends HeadingProps, BcmsBindingProps {
|
|
12
|
+
className?: string;
|
|
13
|
+
align?: "left" | "center" | "right";
|
|
14
|
+
}
|
|
15
|
+
declare function Heading({ text, level, align, className, "data-bcms-field": field, "data-bcms-kind": kind, }: HeadingBlockProps): react_jsx_runtime.JSX.Element;
|
|
16
|
+
|
|
17
|
+
interface TextBlockProps extends TextProps, BcmsBindingProps {
|
|
18
|
+
className?: string;
|
|
19
|
+
align?: "left" | "center" | "right";
|
|
20
|
+
/** Portable Text source. WINS over `html`, which is the derived cache. */
|
|
21
|
+
content?: PortableTextDocument;
|
|
22
|
+
}
|
|
23
|
+
declare function Text({ html, content, align, className, "data-bcms-field": field, "data-bcms-kind": kind, }: TextBlockProps): react_jsx_runtime.JSX.Element;
|
|
24
|
+
|
|
25
|
+
interface ImageBlockProps extends ImageProps, BcmsBindingProps {
|
|
26
|
+
className?: string;
|
|
27
|
+
sizes?: string;
|
|
28
|
+
}
|
|
29
|
+
declare function Image({ src, alt, width, height, caption, className, sizes, "data-bcms-field": field, "data-bcms-kind": kind, }: ImageBlockProps): react_jsx_runtime.JSX.Element;
|
|
30
|
+
|
|
31
|
+
interface ButtonBlockProps extends ButtonProps, BcmsBindingProps {
|
|
32
|
+
className?: string;
|
|
33
|
+
align?: "left" | "center" | "right";
|
|
34
|
+
}
|
|
35
|
+
declare function Button({ text, href, variant, align, className, "data-bcms-field": field, "data-bcms-kind": kind, }: ButtonBlockProps): react_jsx_runtime.JSX.Element;
|
|
36
|
+
|
|
37
|
+
interface SpacerBlockProps extends SpacerProps {
|
|
38
|
+
className?: string;
|
|
39
|
+
}
|
|
40
|
+
declare function Spacer({ height, className }: SpacerBlockProps): react_jsx_runtime.JSX.Element;
|
|
41
|
+
|
|
42
|
+
interface ColumnsBlockProps extends ColumnsProps {
|
|
43
|
+
className?: string;
|
|
44
|
+
renderBlock?: (block: ContentBlock) => React.ReactNode;
|
|
45
|
+
}
|
|
46
|
+
declare function Columns({ columns, gap, className, renderBlock, }: ColumnsBlockProps): react_jsx_runtime.JSX.Element;
|
|
47
|
+
|
|
48
|
+
interface VideoBlockProps extends VideoProps {
|
|
49
|
+
className?: string;
|
|
50
|
+
}
|
|
51
|
+
declare function Video({ url, poster, autoplay, loop, className, }: VideoBlockProps): react_jsx_runtime.JSX.Element;
|
|
52
|
+
|
|
53
|
+
export { type BcmsBindingProps as B, Columns as C, Heading as H, Image as I, Spacer as S, Text as T, Video as V, Button as a };
|
package/dist/blocks.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { a as Button, C as Columns, H as Heading, I as Image, S as Spacer, T as Text, V as Video } from './Video-DRC_fPjV.js';
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
-
import { SectionProps, ContentBlock, NavbarProps, FooterProps, SliderProps, TabsProps, ComponentProps, FormProps } from '@
|
|
3
|
+
import { SectionProps, ContentBlock, NavbarProps, FooterProps, SliderProps, TabsProps, ComponentProps, FormProps } from '@bettercms-ai/types';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
|
|
6
6
|
interface SectionBlockProps extends SectionProps {
|
|
@@ -40,7 +40,7 @@ declare function Tabs({ tabs, className, renderBlock }: TabsBlockProps): react_j
|
|
|
40
40
|
declare function ComponentInstance({ componentId, className, }: ComponentProps & {
|
|
41
41
|
className?: string;
|
|
42
42
|
}): react_jsx_runtime.JSX.Element;
|
|
43
|
-
/** Builder-preview placeholder for a `form` block (rendered live by @
|
|
43
|
+
/** Builder-preview placeholder for a `form` block (rendered live by @bettercms-ai/next). */
|
|
44
44
|
declare function FormPlaceholder({ formId, className }: FormProps & {
|
|
45
45
|
className?: string;
|
|
46
46
|
}): react_jsx_runtime.JSX.Element;
|
package/dist/blocks.js
CHANGED
|
@@ -6,7 +6,9 @@ function Heading({
|
|
|
6
6
|
text,
|
|
7
7
|
level = 2,
|
|
8
8
|
align = "left",
|
|
9
|
-
className = ""
|
|
9
|
+
className = "",
|
|
10
|
+
"data-bcms-field": field,
|
|
11
|
+
"data-bcms-kind": kind
|
|
10
12
|
}) {
|
|
11
13
|
const alignClass = {
|
|
12
14
|
left: "text-left",
|
|
@@ -16,28 +18,81 @@ function Heading({
|
|
|
16
18
|
const classNames = `font-heading font-bold tracking-tight text-foreground ${alignClass} ${className}`;
|
|
17
19
|
switch (level) {
|
|
18
20
|
case 1:
|
|
19
|
-
return /* @__PURE__ */ jsx("h1", { className: classNames, children: text });
|
|
21
|
+
return /* @__PURE__ */ jsx("h1", { className: classNames, "data-bcms-field": field, "data-bcms-kind": kind, children: text });
|
|
20
22
|
case 2:
|
|
21
|
-
return /* @__PURE__ */ jsx("h2", { className: classNames, children: text });
|
|
23
|
+
return /* @__PURE__ */ jsx("h2", { className: classNames, "data-bcms-field": field, "data-bcms-kind": kind, children: text });
|
|
22
24
|
case 3:
|
|
23
|
-
return /* @__PURE__ */ jsx("h3", { className: classNames, children: text });
|
|
25
|
+
return /* @__PURE__ */ jsx("h3", { className: classNames, "data-bcms-field": field, "data-bcms-kind": kind, children: text });
|
|
24
26
|
default:
|
|
25
|
-
return /* @__PURE__ */ jsx("h2", { className: classNames, children: text });
|
|
27
|
+
return /* @__PURE__ */ jsx("h2", { className: classNames, "data-bcms-field": field, "data-bcms-kind": kind, children: text });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// src/blocks/portableText.tsx
|
|
32
|
+
import React from "react";
|
|
33
|
+
import { Fragment, jsx as jsx2 } from "react/jsx-runtime";
|
|
34
|
+
var MARK_TAGS = {
|
|
35
|
+
strong: "strong",
|
|
36
|
+
em: "em",
|
|
37
|
+
underline: "u",
|
|
38
|
+
"strike-through": "s",
|
|
39
|
+
code: "code"
|
|
40
|
+
};
|
|
41
|
+
var BLOCK_TAGS = {
|
|
42
|
+
normal: "p",
|
|
43
|
+
h1: "h1",
|
|
44
|
+
h2: "h2",
|
|
45
|
+
h3: "h3",
|
|
46
|
+
h4: "h4",
|
|
47
|
+
h5: "h5",
|
|
48
|
+
h6: "h6",
|
|
49
|
+
blockquote: "blockquote"
|
|
50
|
+
};
|
|
51
|
+
function Span({ node, index }) {
|
|
52
|
+
const marks = node.marks ?? [];
|
|
53
|
+
const colour = marks.find((m) => m.startsWith("color:"))?.slice("color:".length);
|
|
54
|
+
let out = node.text ?? "";
|
|
55
|
+
for (const m of marks) {
|
|
56
|
+
const Tag = MARK_TAGS[m];
|
|
57
|
+
if (Tag) out = /* @__PURE__ */ jsx2(Tag, { children: out });
|
|
58
|
+
}
|
|
59
|
+
if (colour && /^[a-z0-9-]+$/i.test(colour)) {
|
|
60
|
+
out = /* @__PURE__ */ jsx2("span", { className: `bcms-color-${colour}`, children: out });
|
|
26
61
|
}
|
|
62
|
+
return /* @__PURE__ */ jsx2(React.Fragment, { children: out }, node._key ?? index);
|
|
63
|
+
}
|
|
64
|
+
function PortableText({ doc }) {
|
|
65
|
+
return /* @__PURE__ */ jsx2(Fragment, { children: doc.content.map((block, i) => {
|
|
66
|
+
const Tag = BLOCK_TAGS[block.style ?? "normal"] ?? "p";
|
|
67
|
+
return /* @__PURE__ */ jsx2(Tag, { children: (block.children ?? []).map((c, j) => /* @__PURE__ */ jsx2(Span, { node: c, index: j }, c._key ?? j)) }, block._key ?? i);
|
|
68
|
+
}) });
|
|
27
69
|
}
|
|
28
70
|
|
|
29
71
|
// src/blocks/Text.tsx
|
|
30
|
-
import { jsx as
|
|
31
|
-
function Text({
|
|
72
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
73
|
+
function Text({
|
|
74
|
+
html,
|
|
75
|
+
content,
|
|
76
|
+
align = "left",
|
|
77
|
+
className = "",
|
|
78
|
+
"data-bcms-field": field,
|
|
79
|
+
"data-bcms-kind": kind
|
|
80
|
+
}) {
|
|
32
81
|
const alignClass = {
|
|
33
82
|
left: "text-left",
|
|
34
83
|
center: "text-center",
|
|
35
84
|
right: "text-right"
|
|
36
85
|
}[align];
|
|
37
|
-
|
|
86
|
+
const cls = `text-muted-foreground leading-relaxed ${alignClass} ${className}`;
|
|
87
|
+
if (content && content.content.length > 0) {
|
|
88
|
+
return /* @__PURE__ */ jsx3("div", { className: cls, children: /* @__PURE__ */ jsx3(PortableText, { doc: content }) });
|
|
89
|
+
}
|
|
90
|
+
return /* @__PURE__ */ jsx3(
|
|
38
91
|
"div",
|
|
39
92
|
{
|
|
40
|
-
className:
|
|
93
|
+
className: cls,
|
|
94
|
+
"data-bcms-field": field,
|
|
95
|
+
"data-bcms-kind": kind,
|
|
41
96
|
dangerouslySetInnerHTML: { __html: html }
|
|
42
97
|
}
|
|
43
98
|
);
|
|
@@ -51,7 +106,7 @@ function cn(...inputs) {
|
|
|
51
106
|
}
|
|
52
107
|
|
|
53
108
|
// src/blocks/Image.tsx
|
|
54
|
-
import { jsx as
|
|
109
|
+
import { jsx as jsx4, jsxs } from "react/jsx-runtime";
|
|
55
110
|
function Image({
|
|
56
111
|
src,
|
|
57
112
|
alt,
|
|
@@ -59,10 +114,12 @@ function Image({
|
|
|
59
114
|
height,
|
|
60
115
|
caption,
|
|
61
116
|
className = "",
|
|
62
|
-
sizes
|
|
117
|
+
sizes,
|
|
118
|
+
"data-bcms-field": field,
|
|
119
|
+
"data-bcms-kind": kind
|
|
63
120
|
}) {
|
|
64
121
|
return /* @__PURE__ */ jsxs("figure", { className: cn("w-full", className), children: [
|
|
65
|
-
/* @__PURE__ */
|
|
122
|
+
/* @__PURE__ */ jsx4(
|
|
66
123
|
"img",
|
|
67
124
|
{
|
|
68
125
|
src,
|
|
@@ -70,22 +127,26 @@ function Image({
|
|
|
70
127
|
width,
|
|
71
128
|
height,
|
|
72
129
|
sizes,
|
|
130
|
+
"data-bcms-field": field,
|
|
131
|
+
"data-bcms-kind": kind,
|
|
73
132
|
className: "w-full h-auto rounded-md object-cover",
|
|
74
133
|
loading: "lazy"
|
|
75
134
|
}
|
|
76
135
|
),
|
|
77
|
-
caption && /* @__PURE__ */
|
|
136
|
+
caption && /* @__PURE__ */ jsx4("figcaption", { className: "mt-2 text-sm text-muted-foreground text-center italic", children: caption })
|
|
78
137
|
] });
|
|
79
138
|
}
|
|
80
139
|
|
|
81
140
|
// src/blocks/Button.tsx
|
|
82
|
-
import { jsx as
|
|
141
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
83
142
|
function Button({
|
|
84
143
|
text,
|
|
85
144
|
href,
|
|
86
145
|
variant = "primary",
|
|
87
146
|
align = "left",
|
|
88
|
-
className = ""
|
|
147
|
+
className = "",
|
|
148
|
+
"data-bcms-field": field,
|
|
149
|
+
"data-bcms-kind": kind
|
|
89
150
|
}) {
|
|
90
151
|
const baseStyles = "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50";
|
|
91
152
|
const variantStyles = {
|
|
@@ -97,10 +158,12 @@ function Button({
|
|
|
97
158
|
center: "justify-center",
|
|
98
159
|
right: "justify-end"
|
|
99
160
|
}[align];
|
|
100
|
-
return /* @__PURE__ */
|
|
161
|
+
return /* @__PURE__ */ jsx5(
|
|
101
162
|
"a",
|
|
102
163
|
{
|
|
103
164
|
href,
|
|
165
|
+
"data-bcms-field": field,
|
|
166
|
+
"data-bcms-kind": kind,
|
|
104
167
|
className: cn(baseStyles, variantStyles[variant], alignClass, "px-4 py-2", className),
|
|
105
168
|
children: text
|
|
106
169
|
}
|
|
@@ -108,9 +171,9 @@ function Button({
|
|
|
108
171
|
}
|
|
109
172
|
|
|
110
173
|
// src/blocks/Spacer.tsx
|
|
111
|
-
import { jsx as
|
|
174
|
+
import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
112
175
|
function Spacer({ height = 32, className = "" }) {
|
|
113
|
-
return /* @__PURE__ */
|
|
176
|
+
return /* @__PURE__ */ jsx6(
|
|
114
177
|
"div",
|
|
115
178
|
{
|
|
116
179
|
className: `w-full border border-dashed border-muted-foreground/20 rounded flex items-center justify-center ${className}`,
|
|
@@ -126,14 +189,14 @@ function Spacer({ height = 32, className = "" }) {
|
|
|
126
189
|
|
|
127
190
|
// src/blocks/Columns.tsx
|
|
128
191
|
import "react";
|
|
129
|
-
import { jsx as
|
|
192
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
130
193
|
function Columns({
|
|
131
194
|
columns,
|
|
132
195
|
gap = 16,
|
|
133
196
|
className = "",
|
|
134
197
|
renderBlock
|
|
135
198
|
}) {
|
|
136
|
-
return /* @__PURE__ */
|
|
199
|
+
return /* @__PURE__ */ jsx7(
|
|
137
200
|
"div",
|
|
138
201
|
{
|
|
139
202
|
className: cn("grid w-full", className),
|
|
@@ -141,14 +204,14 @@ function Columns({
|
|
|
141
204
|
gridTemplateColumns: `repeat(${columns.length}, minmax(0, 1fr))`,
|
|
142
205
|
gap: `${gap}px`
|
|
143
206
|
},
|
|
144
|
-
children: columns.map((columnBlocks, colIndex) => /* @__PURE__ */
|
|
207
|
+
children: columns.map((columnBlocks, colIndex) => /* @__PURE__ */ jsx7("div", { className: "flex flex-col gap-4 min-w-0", children: columnBlocks.map((block) => /* @__PURE__ */ jsx7("span", { children: renderBlock ? renderBlock(block) : null }, block.id)) }, colIndex))
|
|
145
208
|
}
|
|
146
209
|
);
|
|
147
210
|
}
|
|
148
211
|
|
|
149
212
|
// src/blocks/Video.tsx
|
|
150
213
|
import { useState } from "react";
|
|
151
|
-
import { jsx as
|
|
214
|
+
import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
152
215
|
function getEmbedUrl(url) {
|
|
153
216
|
const ytMatch = url.match(
|
|
154
217
|
/(?:youtube\.com\/(?:watch\?v=|embed\/)|youtu\.be\/)([a-zA-Z0-9_-]{11})/
|
|
@@ -178,7 +241,7 @@ function Video({
|
|
|
178
241
|
const [isLoaded, setIsLoaded] = useState(false);
|
|
179
242
|
const { embedUrl, provider } = getEmbedUrl(url);
|
|
180
243
|
if (provider === "unknown") {
|
|
181
|
-
return /* @__PURE__ */
|
|
244
|
+
return /* @__PURE__ */ jsx8(
|
|
182
245
|
"video",
|
|
183
246
|
{
|
|
184
247
|
src: url,
|
|
@@ -193,7 +256,7 @@ function Video({
|
|
|
193
256
|
}
|
|
194
257
|
return /* @__PURE__ */ jsxs3("div", { className: cn("w-full overflow-hidden rounded-md bg-black aspect-video", className), children: [
|
|
195
258
|
!isLoaded && poster && // eslint-disable-next-line @next/next/no-img-element
|
|
196
|
-
/* @__PURE__ */
|
|
259
|
+
/* @__PURE__ */ jsx8(
|
|
197
260
|
"img",
|
|
198
261
|
{
|
|
199
262
|
src: poster,
|
|
@@ -201,7 +264,7 @@ function Video({
|
|
|
201
264
|
className: "w-full h-full object-cover absolute inset-0"
|
|
202
265
|
}
|
|
203
266
|
),
|
|
204
|
-
/* @__PURE__ */
|
|
267
|
+
/* @__PURE__ */ jsx8(
|
|
205
268
|
"iframe",
|
|
206
269
|
{
|
|
207
270
|
src: `${embedUrl}?autoplay=${autoplay ? 1 : 0}&loop=${loop ? 1 : 0}&mute=${autoplay ? 1 : 0}`,
|
|
@@ -217,7 +280,7 @@ function Video({
|
|
|
217
280
|
|
|
218
281
|
// src/blocks/Section.tsx
|
|
219
282
|
import "react";
|
|
220
|
-
import { jsx as
|
|
283
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
221
284
|
function Section({
|
|
222
285
|
children,
|
|
223
286
|
background,
|
|
@@ -226,24 +289,24 @@ function Section({
|
|
|
226
289
|
className = "",
|
|
227
290
|
renderBlock
|
|
228
291
|
}) {
|
|
229
|
-
const inner = (children ?? []).map((block) => /* @__PURE__ */
|
|
230
|
-
return /* @__PURE__ */
|
|
292
|
+
const inner = (children ?? []).map((block) => /* @__PURE__ */ jsx9("span", { children: renderBlock ? renderBlock(block) : null }, block.id));
|
|
293
|
+
return /* @__PURE__ */ jsx9(
|
|
231
294
|
"section",
|
|
232
295
|
{
|
|
233
296
|
className: cn("w-full", className),
|
|
234
297
|
style: { background, paddingTop: paddingY, paddingBottom: paddingY },
|
|
235
|
-
children: maxWidth ? /* @__PURE__ */
|
|
298
|
+
children: maxWidth ? /* @__PURE__ */ jsx9("div", { style: { maxWidth, marginInline: "auto" }, children: inner }) : inner
|
|
236
299
|
}
|
|
237
300
|
);
|
|
238
301
|
}
|
|
239
302
|
|
|
240
303
|
// src/blocks/Navbar.tsx
|
|
241
|
-
import { jsx as
|
|
304
|
+
import { jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
242
305
|
function Navbar({ logo, links, cta, className = "" }) {
|
|
243
306
|
return /* @__PURE__ */ jsxs4("nav", { className: cn("flex items-center gap-6 py-4", className), children: [
|
|
244
|
-
logo?.src ? /* @__PURE__ */
|
|
245
|
-
/* @__PURE__ */
|
|
246
|
-
cta ? /* @__PURE__ */
|
|
307
|
+
logo?.src ? /* @__PURE__ */ jsx10("a", { href: logo.href ?? "/", className: "shrink-0", children: /* @__PURE__ */ jsx10("img", { src: logo.src, alt: logo.alt, className: "h-8 w-auto" }) }) : null,
|
|
308
|
+
/* @__PURE__ */ jsx10("div", { className: "flex flex-1 gap-5", children: (links ?? []).map((l, i) => /* @__PURE__ */ jsx10("a", { href: l.href, className: "text-inherit no-underline", children: l.label }, i)) }),
|
|
309
|
+
cta ? /* @__PURE__ */ jsx10(
|
|
247
310
|
"a",
|
|
248
311
|
{
|
|
249
312
|
href: cta.href,
|
|
@@ -255,40 +318,40 @@ function Navbar({ logo, links, cta, className = "" }) {
|
|
|
255
318
|
}
|
|
256
319
|
|
|
257
320
|
// src/blocks/Footer.tsx
|
|
258
|
-
import { jsx as
|
|
321
|
+
import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
259
322
|
function Footer({ columns, copyright, className = "" }) {
|
|
260
323
|
return /* @__PURE__ */ jsxs5("footer", { className: cn("mt-12 border-t pt-8", className), children: [
|
|
261
|
-
/* @__PURE__ */
|
|
262
|
-
col.heading ? /* @__PURE__ */
|
|
263
|
-
(col.links ?? []).map((l, j) => /* @__PURE__ */
|
|
324
|
+
/* @__PURE__ */ jsx11("div", { className: "flex flex-wrap gap-12", children: (columns ?? []).map((col, i) => /* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-1.5", children: [
|
|
325
|
+
col.heading ? /* @__PURE__ */ jsx11("h4", { className: "mb-2 font-semibold", children: col.heading }) : null,
|
|
326
|
+
(col.links ?? []).map((l, j) => /* @__PURE__ */ jsx11("a", { href: l.href, className: "text-neutral-500 no-underline", children: l.label }, j))
|
|
264
327
|
] }, i)) }),
|
|
265
|
-
copyright ? /* @__PURE__ */
|
|
328
|
+
copyright ? /* @__PURE__ */ jsx11("p", { className: "mt-6 text-sm text-neutral-500", children: copyright }) : null
|
|
266
329
|
] });
|
|
267
330
|
}
|
|
268
331
|
|
|
269
332
|
// src/blocks/Slider.tsx
|
|
270
333
|
import { useState as useState2 } from "react";
|
|
271
|
-
import { jsx as
|
|
334
|
+
import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
272
335
|
function Slider({ slides, className = "", renderBlock }) {
|
|
273
336
|
const [i, setI] = useState2(0);
|
|
274
337
|
const list = slides ?? [];
|
|
275
338
|
const go = (n) => setI((n + list.length) % (list.length || 1));
|
|
276
339
|
const btn = "absolute top-1/2 -translate-y-1/2 flex h-9 w-9 items-center justify-center rounded-full border-0 bg-black/50 text-white cursor-pointer";
|
|
277
340
|
return /* @__PURE__ */ jsxs6("div", { className: cn("relative w-full", className), children: [
|
|
278
|
-
list.map((s, idx) => /* @__PURE__ */
|
|
279
|
-
/* @__PURE__ */
|
|
280
|
-
/* @__PURE__ */
|
|
341
|
+
list.map((s, idx) => /* @__PURE__ */ jsx12("div", { hidden: idx !== i, className: "flex flex-col gap-4", children: (s.children ?? []).map((b) => /* @__PURE__ */ jsx12("span", { children: renderBlock ? renderBlock(b) : null }, b.id)) }, s.id)),
|
|
342
|
+
/* @__PURE__ */ jsx12("button", { type: "button", "aria-label": "Previous", onClick: () => go(i - 1), className: cn(btn, "left-2"), children: "\u2039" }),
|
|
343
|
+
/* @__PURE__ */ jsx12("button", { type: "button", "aria-label": "Next", onClick: () => go(i + 1), className: cn(btn, "right-2"), children: "\u203A" })
|
|
281
344
|
] });
|
|
282
345
|
}
|
|
283
346
|
|
|
284
347
|
// src/blocks/Tabs.tsx
|
|
285
348
|
import { useState as useState3 } from "react";
|
|
286
|
-
import { jsx as
|
|
349
|
+
import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
287
350
|
function Tabs({ tabs, className = "", renderBlock }) {
|
|
288
351
|
const [active, setActive] = useState3(0);
|
|
289
352
|
const list = tabs ?? [];
|
|
290
353
|
return /* @__PURE__ */ jsxs7("div", { className: cn("w-full", className), children: [
|
|
291
|
-
/* @__PURE__ */
|
|
354
|
+
/* @__PURE__ */ jsx13("div", { role: "tablist", className: "mb-4 flex gap-1 border-b", children: list.map((t, idx) => /* @__PURE__ */ jsx13(
|
|
292
355
|
"button",
|
|
293
356
|
{
|
|
294
357
|
role: "tab",
|
|
@@ -303,12 +366,12 @@ function Tabs({ tabs, className = "", renderBlock }) {
|
|
|
303
366
|
},
|
|
304
367
|
t.id
|
|
305
368
|
)) }),
|
|
306
|
-
list.map((t, idx) => /* @__PURE__ */
|
|
369
|
+
list.map((t, idx) => /* @__PURE__ */ jsx13("div", { role: "tabpanel", hidden: idx !== active, className: "flex flex-col gap-4", children: (t.children ?? []).map((b) => /* @__PURE__ */ jsx13("span", { children: renderBlock ? renderBlock(b) : null }, b.id)) }, t.id))
|
|
307
370
|
] });
|
|
308
371
|
}
|
|
309
372
|
|
|
310
373
|
// src/blocks/Placeholders.tsx
|
|
311
|
-
import { jsx as
|
|
374
|
+
import { Fragment as Fragment2, jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
312
375
|
var box = "rounded border border-dashed border-neutral-300 bg-neutral-50 p-4 text-sm text-neutral-500";
|
|
313
376
|
function ComponentInstance({
|
|
314
377
|
componentId,
|
|
@@ -316,13 +379,13 @@ function ComponentInstance({
|
|
|
316
379
|
}) {
|
|
317
380
|
return /* @__PURE__ */ jsxs8("div", { className: cn(box, className), children: [
|
|
318
381
|
"Component instance: ",
|
|
319
|
-
/* @__PURE__ */
|
|
382
|
+
/* @__PURE__ */ jsx14("code", { children: componentId })
|
|
320
383
|
] });
|
|
321
384
|
}
|
|
322
385
|
function FormPlaceholder({ formId, className = "" }) {
|
|
323
386
|
return /* @__PURE__ */ jsxs8("div", { className: cn(box, className), children: [
|
|
324
387
|
"Form: ",
|
|
325
|
-
/* @__PURE__ */
|
|
388
|
+
/* @__PURE__ */ jsx14("code", { children: formId })
|
|
326
389
|
] });
|
|
327
390
|
}
|
|
328
391
|
export {
|
package/dist/blocks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/blocks/Heading.tsx","../src/blocks/Text.tsx","../src/lib/utils.ts","../src/blocks/Image.tsx","../src/blocks/Button.tsx","../src/blocks/Spacer.tsx","../src/blocks/Columns.tsx","../src/blocks/Video.tsx","../src/blocks/Section.tsx","../src/blocks/Navbar.tsx","../src/blocks/Footer.tsx","../src/blocks/Slider.tsx","../src/blocks/Tabs.tsx","../src/blocks/Placeholders.tsx"],"sourcesContent":["import type { HeadingProps } from \"@betttercms/types\";\n\ninterface HeadingBlockProps extends HeadingProps {\n className?: string;\n align?: \"left\" | \"center\" | \"right\";\n}\n\nexport function Heading({\n text,\n level = 2,\n align = \"left\",\n className = \"\",\n}: HeadingBlockProps) {\n const alignClass = {\n left: \"text-left\",\n center: \"text-center\",\n right: \"text-right\",\n }[align];\n\n const classNames = `font-heading font-bold tracking-tight text-foreground ${alignClass} ${className}`;\n\n switch (level) {\n case 1:\n return <h1 className={classNames}>{text}</h1>;\n case 2:\n return <h2 className={classNames}>{text}</h2>;\n case 3:\n return <h3 className={classNames}>{text}</h3>;\n default:\n return <h2 className={classNames}>{text}</h2>;\n }\n}\n","import type { TextProps } from \"@betttercms/types\";\n\ninterface TextBlockProps extends TextProps {\n className?: string;\n align?: \"left\" | \"center\" | \"right\";\n}\n\nexport function Text({ html, align = \"left\", className = \"\" }: TextBlockProps) {\n const alignClass = {\n left: \"text-left\",\n center: \"text-center\",\n right: \"text-right\",\n }[align];\n\n return (\n <div\n className={`text-muted-foreground leading-relaxed ${alignClass} ${className}`}\n // eslint-disable-next-line react/no-danger\n dangerouslySetInnerHTML={{ __html: html }}\n />\n );\n}\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import type { ImageProps } from \"@betttercms/types\";\nimport { cn } from \"../lib/utils\";\n\ninterface ImageBlockProps extends ImageProps {\n className?: string;\n sizes?: string;\n}\n\nexport function Image({\n src,\n alt,\n width,\n height,\n caption,\n className = \"\",\n sizes,\n}: ImageBlockProps) {\n return (\n <figure className={cn(\"w-full\", className)}>\n <img\n src={src}\n alt={alt}\n width={width}\n height={height}\n sizes={sizes}\n className=\"w-full h-auto rounded-md object-cover\"\n loading=\"lazy\"\n />\n {caption && (\n <figcaption className=\"mt-2 text-sm text-muted-foreground text-center italic\">\n {caption}\n </figcaption>\n )}\n </figure>\n );\n}\n","import type { ButtonProps } from \"@betttercms/types\";\nimport { cn } from \"../lib/utils\";\n\ninterface ButtonBlockProps extends ButtonProps {\n className?: string;\n align?: \"left\" | \"center\" | \"right\";\n}\n\nexport function Button({\n text,\n href,\n variant = \"primary\",\n align = \"left\",\n className = \"\",\n}: ButtonBlockProps) {\n const baseStyles =\n \"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50\";\n\n const variantStyles = {\n primary:\n \"bg-primary text-primary-foreground shadow hover:bg-primary/90\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80\",\n };\n\n const alignClass = {\n left: \"justify-start\",\n center: \"justify-center\",\n right: \"justify-end\",\n }[align];\n\n return (\n <a\n href={href}\n className={cn(baseStyles, variantStyles[variant], alignClass, \"px-4 py-2\", className)}\n >\n {text}\n </a>\n );\n}\n","import type { SpacerProps } from \"@betttercms/types\";\n\ninterface SpacerBlockProps extends SpacerProps {\n className?: string;\n}\n\nexport function Spacer({ height = 32, className = \"\" }: SpacerBlockProps) {\n return (\n <div\n className={`w-full border border-dashed border-muted-foreground/20 rounded flex items-center justify-center ${className}`}\n style={{ height: `${height}px` }}\n aria-hidden=\"true\"\n >\n <span className=\"text-xs text-muted-foreground/40 select-none\">\n {height}px\n </span>\n </div>\n );\n}\n","import type { ColumnsProps, ContentBlock } from \"@betttercms/types\";\nimport { cn } from \"../lib/utils\";\nimport React from \"react\";\n\ninterface ColumnsBlockProps extends ColumnsProps {\n className?: string;\n renderBlock?: (block: ContentBlock) => React.ReactNode;\n}\n\nexport function Columns({\n columns,\n gap = 16,\n className = \"\",\n renderBlock,\n}: ColumnsBlockProps) {\n return (\n <div\n className={cn(\"grid w-full\", className)}\n style={{\n gridTemplateColumns: `repeat(${columns.length}, minmax(0, 1fr))`,\n gap: `${gap}px`,\n }}\n >\n {columns.map((columnBlocks, colIndex) => (\n <div key={colIndex} className=\"flex flex-col gap-4 min-w-0\">\n {columnBlocks.map((block) => (\n <span key={block.id}>\n {renderBlock ? renderBlock(block) : null}\n </span>\n ))}\n </div>\n ))}\n </div>\n );\n}\n","import type { VideoProps } from \"@betttercms/types\";\nimport { useState } from \"react\";\nimport { cn } from \"../lib/utils\";\n\ninterface VideoBlockProps extends VideoProps {\n className?: string;\n}\n\nfunction getEmbedUrl(url: string): { embedUrl: string; provider: \"youtube\" | \"vimeo\" | \"unknown\" } {\n // YouTube\n const ytMatch = url.match(\n /(?:youtube\\.com\\/(?:watch\\?v=|embed\\/)|youtu\\.be\\/)([a-zA-Z0-9_-]{11})/\n );\n if (ytMatch) {\n return {\n embedUrl: `https://www.youtube.com/embed/${ytMatch[1]}`,\n provider: \"youtube\",\n };\n }\n\n // Vimeo\n const vimeoMatch = url.match(/vimeo\\.com\\/(\\d+)/);\n if (vimeoMatch) {\n return {\n embedUrl: `https://player.vimeo.com/video/${vimeoMatch[1]}`,\n provider: \"vimeo\",\n };\n }\n\n return { embedUrl: url, provider: \"unknown\" };\n}\n\nexport function Video({\n url,\n poster,\n autoplay = false,\n loop = false,\n className = \"\",\n}: VideoBlockProps) {\n const [isLoaded, setIsLoaded] = useState(false);\n const { embedUrl, provider } = getEmbedUrl(url);\n\n // If not a recognized embed, render a native video tag\n if (provider === \"unknown\") {\n return (\n <video\n src={url}\n poster={poster}\n autoPlay={autoplay}\n loop={loop}\n controls\n className={className}\n playsInline\n />\n );\n }\n\n return (\n <div className={cn(\"w-full overflow-hidden rounded-md bg-black aspect-video\", className)}>\n {!isLoaded && poster && (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={poster}\n alt=\"Video thumbnail\"\n className=\"w-full h-full object-cover absolute inset-0\"\n />\n )}\n <iframe\n src={`${embedUrl}?autoplay=${autoplay ? 1 : 0}&loop=${loop ? 1 : 0}&mute=${autoplay ? 1 : 0}`}\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\"\n allowFullScreen\n loading=\"lazy\"\n onLoad={() => setIsLoaded(true)}\n className=\"w-full h-full\"\n />\n </div>\n );\n}\n","import type { SectionProps, ContentBlock } from \"@betttercms/types\";\nimport { cn } from \"../lib/utils\";\nimport React from \"react\";\n\ninterface SectionBlockProps extends SectionProps {\n className?: string;\n renderBlock?: (block: ContentBlock) => React.ReactNode;\n}\n\nexport function Section({\n children,\n background,\n paddingY,\n maxWidth,\n className = \"\",\n renderBlock,\n}: SectionBlockProps) {\n const inner = (children ?? []).map((block) => (\n <span key={block.id}>{renderBlock ? renderBlock(block) : null}</span>\n ));\n return (\n <section\n className={cn(\"w-full\", className)}\n style={{ background, paddingTop: paddingY, paddingBottom: paddingY }}\n >\n {maxWidth ? <div style={{ maxWidth, marginInline: \"auto\" }}>{inner}</div> : inner}\n </section>\n );\n}\n","import type { NavbarProps } from \"@betttercms/types\";\nimport { cn } from \"../lib/utils\";\n\ninterface NavbarBlockProps extends NavbarProps {\n className?: string;\n}\n\nexport function Navbar({ logo, links, cta, className = \"\" }: NavbarBlockProps) {\n return (\n <nav className={cn(\"flex items-center gap-6 py-4\", className)}>\n {logo?.src ? (\n <a href={logo.href ?? \"/\"} className=\"shrink-0\">\n <img src={logo.src} alt={logo.alt} className=\"h-8 w-auto\" />\n </a>\n ) : null}\n <div className=\"flex flex-1 gap-5\">\n {(links ?? []).map((l, i) => (\n <a key={i} href={l.href} className=\"text-inherit no-underline\">\n {l.label}\n </a>\n ))}\n </div>\n {cta ? (\n <a\n href={cta.href}\n className=\"rounded-lg bg-black px-4 py-2 font-semibold text-white no-underline\"\n >\n {cta.text}\n </a>\n ) : null}\n </nav>\n );\n}\n","import type { FooterProps } from \"@betttercms/types\";\nimport { cn } from \"../lib/utils\";\n\ninterface FooterBlockProps extends FooterProps {\n className?: string;\n}\n\nexport function Footer({ columns, copyright, className = \"\" }: FooterBlockProps) {\n return (\n <footer className={cn(\"mt-12 border-t pt-8\", className)}>\n <div className=\"flex flex-wrap gap-12\">\n {(columns ?? []).map((col, i) => (\n <div key={i} className=\"flex flex-col gap-1.5\">\n {col.heading ? <h4 className=\"mb-2 font-semibold\">{col.heading}</h4> : null}\n {(col.links ?? []).map((l, j) => (\n <a key={j} href={l.href} className=\"text-neutral-500 no-underline\">\n {l.label}\n </a>\n ))}\n </div>\n ))}\n </div>\n {copyright ? <p className=\"mt-6 text-sm text-neutral-500\">{copyright}</p> : null}\n </footer>\n );\n}\n","\"use client\";\n\nimport type { SliderProps, ContentBlock } from \"@betttercms/types\";\nimport { cn } from \"../lib/utils\";\nimport React, { useState } from \"react\";\n\ninterface SliderBlockProps extends SliderProps {\n className?: string;\n renderBlock?: (block: ContentBlock) => React.ReactNode;\n}\n\nexport function Slider({ slides, className = \"\", renderBlock }: SliderBlockProps) {\n const [i, setI] = useState(0);\n const list = slides ?? [];\n const go = (n: number) => setI((n + list.length) % (list.length || 1));\n const btn =\n \"absolute top-1/2 -translate-y-1/2 flex h-9 w-9 items-center justify-center rounded-full border-0 bg-black/50 text-white cursor-pointer\";\n return (\n <div className={cn(\"relative w-full\", className)}>\n {list.map((s, idx) => (\n <div key={s.id} hidden={idx !== i} className=\"flex flex-col gap-4\">\n {(s.children ?? []).map((b) => (\n <span key={b.id}>{renderBlock ? renderBlock(b) : null}</span>\n ))}\n </div>\n ))}\n <button type=\"button\" aria-label=\"Previous\" onClick={() => go(i - 1)} className={cn(btn, \"left-2\")}>\n ‹\n </button>\n <button type=\"button\" aria-label=\"Next\" onClick={() => go(i + 1)} className={cn(btn, \"right-2\")}>\n ›\n </button>\n </div>\n );\n}\n","\"use client\";\n\nimport type { TabsProps, ContentBlock } from \"@betttercms/types\";\nimport { cn } from \"../lib/utils\";\nimport React, { useState } from \"react\";\n\ninterface TabsBlockProps extends TabsProps {\n className?: string;\n renderBlock?: (block: ContentBlock) => React.ReactNode;\n}\n\nexport function Tabs({ tabs, className = \"\", renderBlock }: TabsBlockProps) {\n const [active, setActive] = useState(0);\n const list = tabs ?? [];\n return (\n <div className={cn(\"w-full\", className)}>\n <div role=\"tablist\" className=\"mb-4 flex gap-1 border-b\">\n {list.map((t, idx) => (\n <button\n key={t.id}\n role=\"tab\"\n type=\"button\"\n aria-selected={idx === active}\n onClick={() => setActive(idx)}\n className={cn(\n \"cursor-pointer border-b-2 border-transparent bg-transparent px-4 py-2\",\n idx === active && \"border-black font-semibold\",\n )}\n >\n {t.label}\n </button>\n ))}\n </div>\n {list.map((t, idx) => (\n <div key={t.id} role=\"tabpanel\" hidden={idx !== active} className=\"flex flex-col gap-4\">\n {(t.children ?? []).map((b) => (\n <span key={b.id}>{renderBlock ? renderBlock(b) : null}</span>\n ))}\n </div>\n ))}\n </div>\n );\n}\n","import type { ComponentProps as BcmsComponentProps, FormProps } from \"@betttercms/types\";\nimport { cn } from \"../lib/utils\";\n\nconst box =\n \"rounded border border-dashed border-neutral-300 bg-neutral-50 p-4 text-sm text-neutral-500\";\n\n/**\n * Builder-preview placeholder for a `component` instance. Live instance resolution\n * (definition lookup + override merge) happens server-side in the delivery renderer\n * and in the page-builder, which pass a resolver — the standalone library preview\n * just shows what's referenced.\n */\nexport function ComponentInstance({\n componentId,\n className = \"\",\n}: BcmsComponentProps & { className?: string }) {\n return (\n <div className={cn(box, className)}>\n Component instance: <code>{componentId}</code>\n </div>\n );\n}\n\n/** Builder-preview placeholder for a `form` block (rendered live by @betttercms/next). */\nexport function FormPlaceholder({ formId, className = \"\" }: FormProps & { className?: string }) {\n return (\n <div className={cn(box, className)}>\n Form: <code>{formId}</code>\n </div>\n );\n}\n"],"mappings":"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","names":["jsx","jsx","jsx","jsx","jsxs","jsx","jsx","jsxs","jsx","jsx","jsxs","jsx","jsxs","useState","jsx","jsxs","useState","jsx","jsxs","jsx","jsxs"]}
|
|
1
|
+
{"version":3,"sources":["../src/blocks/Heading.tsx","../src/blocks/portableText.tsx","../src/blocks/Text.tsx","../src/lib/utils.ts","../src/blocks/Image.tsx","../src/blocks/Button.tsx","../src/blocks/Spacer.tsx","../src/blocks/Columns.tsx","../src/blocks/Video.tsx","../src/blocks/Section.tsx","../src/blocks/Navbar.tsx","../src/blocks/Footer.tsx","../src/blocks/Slider.tsx","../src/blocks/Tabs.tsx","../src/blocks/Placeholders.tsx"],"sourcesContent":["import type { HeadingProps } from \"@bettercms-ai/types\";\nimport type { BcmsBindingProps } from \"../binding\";\n\ninterface HeadingBlockProps extends HeadingProps, BcmsBindingProps {\n className?: string;\n align?: \"left\" | \"center\" | \"right\";\n}\n\nexport function Heading({\n text,\n level = 2,\n align = \"left\",\n className = \"\",\n \"data-bcms-field\": field,\n \"data-bcms-kind\": kind,\n}: HeadingBlockProps) {\n const alignClass = {\n left: \"text-left\",\n center: \"text-center\",\n right: \"text-right\",\n }[align];\n\n const classNames = `font-heading font-bold tracking-tight text-foreground ${alignClass} ${className}`;\n\n switch (level) {\n case 1:\n return <h1 className={classNames} data-bcms-field={field} data-bcms-kind={kind}>{text}</h1>;\n case 2:\n return <h2 className={classNames} data-bcms-field={field} data-bcms-kind={kind}>{text}</h2>;\n case 3:\n return <h3 className={classNames} data-bcms-field={field} data-bcms-kind={kind}>{text}</h3>;\n default:\n return <h2 className={classNames} data-bcms-field={field} data-bcms-kind={kind}>{text}</h2>;\n }\n}\n","import React from \"react\";\nimport type { PortableTextDocument, PortableTextNode } from \"@bettercms-ai/types\";\n\n/**\n * Portable Text → React.\n *\n * React rather than an HTML string, deliberately: React escapes text children by default, so\n * author data cannot become markup here at all. The `dangerouslySetInnerHTML` path that the\n * `html` cache still uses has to be trusted; this one does not.\n *\n * Unknown marks and unknown styles are DROPPED, never passed through. A colour mark carries a\n * token NAME (`color:brand-accent`) which becomes a class the consuming site styles — so it is\n * theme-aware and survives a rebrand, which a baked hex does not.\n */\n\nconst MARK_TAGS: Record<string, keyof React.JSX.IntrinsicElements> = {\n strong: \"strong\",\n em: \"em\",\n underline: \"u\",\n \"strike-through\": \"s\",\n code: \"code\",\n};\n\nconst BLOCK_TAGS: Record<string, keyof React.JSX.IntrinsicElements> = {\n normal: \"p\",\n h1: \"h1\",\n h2: \"h2\",\n h3: \"h3\",\n h4: \"h4\",\n h5: \"h5\",\n h6: \"h6\",\n blockquote: \"blockquote\",\n};\n\nfunction Span({ node, index }: { node: PortableTextNode; index: number }) {\n const marks = node.marks ?? [];\n const colour = marks.find((m) => m.startsWith(\"color:\"))?.slice(\"color:\".length);\n\n // Text is a React child, so it is escaped by construction.\n let out: React.ReactNode = node.text ?? \"\";\n for (const m of marks) {\n const Tag = MARK_TAGS[m];\n if (Tag) out = <Tag>{out}</Tag>;\n }\n if (colour && /^[a-z0-9-]+$/i.test(colour)) {\n out = <span className={`bcms-color-${colour}`}>{out}</span>;\n }\n return <React.Fragment key={node._key ?? index}>{out}</React.Fragment>;\n}\n\nexport function PortableText({ doc }: { doc: PortableTextDocument }) {\n return (\n <>\n {doc.content.map((block, i) => {\n const Tag = BLOCK_TAGS[block.style ?? \"normal\"] ?? \"p\";\n return (\n <Tag key={block._key ?? i}>\n {(block.children ?? []).map((c, j) => (\n <Span key={c._key ?? j} node={c} index={j} />\n ))}\n </Tag>\n );\n })}\n </>\n );\n}\n","import type { PortableTextDocument, TextProps } from \"@bettercms-ai/types\";\nimport { PortableText } from \"./portableText\";\nimport type { BcmsBindingProps } from \"../binding\";\n\ninterface TextBlockProps extends TextProps, BcmsBindingProps {\n className?: string;\n align?: \"left\" | \"center\" | \"right\";\n /** Portable Text source. WINS over `html`, which is the derived cache. */\n content?: PortableTextDocument;\n}\n\nexport function Text({\n html,\n content,\n align = \"left\",\n className = \"\",\n \"data-bcms-field\": field,\n \"data-bcms-kind\": kind,\n}: TextBlockProps) {\n const alignClass = {\n left: \"text-left\",\n center: \"text-center\",\n right: \"text-right\",\n }[align];\n\n const cls = `text-muted-foreground leading-relaxed ${alignClass} ${className}`;\n\n // `content` wins when present — it is the source of truth and renders through React, which\n // escapes by construction. `html` remains the fallback so every block authored before\n // Portable Text existed renders exactly as it always did.\n if (content && content.content.length > 0) {\n return (\n <div className={cls}>\n <PortableText doc={content} />\n </div>\n );\n }\n\n return (\n <div\n className={cls}\n data-bcms-field={field}\n data-bcms-kind={kind}\n // eslint-disable-next-line react/no-danger\n dangerouslySetInnerHTML={{ __html: html }}\n />\n );\n}\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import type { ImageProps } from \"@bettercms-ai/types\";\nimport { cn } from \"../lib/utils\";\nimport type { BcmsBindingProps } from \"../binding\";\n\ninterface ImageBlockProps extends ImageProps, BcmsBindingProps {\n className?: string;\n sizes?: string;\n}\n\nexport function Image({\n src,\n alt,\n width,\n height,\n caption,\n className = \"\",\n sizes,\n \"data-bcms-field\": field,\n \"data-bcms-kind\": kind,\n}: ImageBlockProps) {\n return (\n <figure className={cn(\"w-full\", className)}>\n <img\n src={src}\n alt={alt}\n width={width}\n height={height}\n sizes={sizes}\n data-bcms-field={field}\n data-bcms-kind={kind}\n className=\"w-full h-auto rounded-md object-cover\"\n loading=\"lazy\"\n />\n {caption && (\n <figcaption className=\"mt-2 text-sm text-muted-foreground text-center italic\">\n {caption}\n </figcaption>\n )}\n </figure>\n );\n}\n","import type { ButtonProps } from \"@bettercms-ai/types\";\nimport { cn } from \"../lib/utils\";\nimport type { BcmsBindingProps } from \"../binding\";\n\ninterface ButtonBlockProps extends ButtonProps, BcmsBindingProps {\n className?: string;\n align?: \"left\" | \"center\" | \"right\";\n}\n\nexport function Button({\n text,\n href,\n variant = \"primary\",\n align = \"left\",\n className = \"\",\n \"data-bcms-field\": field,\n \"data-bcms-kind\": kind,\n}: ButtonBlockProps) {\n const baseStyles =\n \"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50\";\n\n const variantStyles = {\n primary:\n \"bg-primary text-primary-foreground shadow hover:bg-primary/90\",\n secondary:\n \"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80\",\n };\n\n const alignClass = {\n left: \"justify-start\",\n center: \"justify-center\",\n right: \"justify-end\",\n }[align];\n\n return (\n <a\n href={href}\n data-bcms-field={field}\n data-bcms-kind={kind}\n className={cn(baseStyles, variantStyles[variant], alignClass, \"px-4 py-2\", className)}\n >\n {text}\n </a>\n );\n}\n","import type { SpacerProps } from \"@bettercms-ai/types\";\n\ninterface SpacerBlockProps extends SpacerProps {\n className?: string;\n}\n\nexport function Spacer({ height = 32, className = \"\" }: SpacerBlockProps) {\n return (\n <div\n className={`w-full border border-dashed border-muted-foreground/20 rounded flex items-center justify-center ${className}`}\n style={{ height: `${height}px` }}\n aria-hidden=\"true\"\n >\n <span className=\"text-xs text-muted-foreground/40 select-none\">\n {height}px\n </span>\n </div>\n );\n}\n","import type { ColumnsProps, ContentBlock } from \"@bettercms-ai/types\";\nimport { cn } from \"../lib/utils\";\nimport React from \"react\";\n\ninterface ColumnsBlockProps extends ColumnsProps {\n className?: string;\n renderBlock?: (block: ContentBlock) => React.ReactNode;\n}\n\nexport function Columns({\n columns,\n gap = 16,\n className = \"\",\n renderBlock,\n}: ColumnsBlockProps) {\n return (\n <div\n className={cn(\"grid w-full\", className)}\n style={{\n gridTemplateColumns: `repeat(${columns.length}, minmax(0, 1fr))`,\n gap: `${gap}px`,\n }}\n >\n {columns.map((columnBlocks, colIndex) => (\n <div key={colIndex} className=\"flex flex-col gap-4 min-w-0\">\n {columnBlocks.map((block) => (\n <span key={block.id}>\n {renderBlock ? renderBlock(block) : null}\n </span>\n ))}\n </div>\n ))}\n </div>\n );\n}\n","import type { VideoProps } from \"@bettercms-ai/types\";\nimport { useState } from \"react\";\nimport { cn } from \"../lib/utils\";\n\ninterface VideoBlockProps extends VideoProps {\n className?: string;\n}\n\nfunction getEmbedUrl(url: string): { embedUrl: string; provider: \"youtube\" | \"vimeo\" | \"unknown\" } {\n // YouTube\n const ytMatch = url.match(\n /(?:youtube\\.com\\/(?:watch\\?v=|embed\\/)|youtu\\.be\\/)([a-zA-Z0-9_-]{11})/\n );\n if (ytMatch) {\n return {\n embedUrl: `https://www.youtube.com/embed/${ytMatch[1]}`,\n provider: \"youtube\",\n };\n }\n\n // Vimeo\n const vimeoMatch = url.match(/vimeo\\.com\\/(\\d+)/);\n if (vimeoMatch) {\n return {\n embedUrl: `https://player.vimeo.com/video/${vimeoMatch[1]}`,\n provider: \"vimeo\",\n };\n }\n\n return { embedUrl: url, provider: \"unknown\" };\n}\n\nexport function Video({\n url,\n poster,\n autoplay = false,\n loop = false,\n className = \"\",\n}: VideoBlockProps) {\n const [isLoaded, setIsLoaded] = useState(false);\n const { embedUrl, provider } = getEmbedUrl(url);\n\n // If not a recognized embed, render a native video tag\n if (provider === \"unknown\") {\n return (\n <video\n src={url}\n poster={poster}\n autoPlay={autoplay}\n loop={loop}\n controls\n className={className}\n playsInline\n />\n );\n }\n\n return (\n <div className={cn(\"w-full overflow-hidden rounded-md bg-black aspect-video\", className)}>\n {!isLoaded && poster && (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={poster}\n alt=\"Video thumbnail\"\n className=\"w-full h-full object-cover absolute inset-0\"\n />\n )}\n <iframe\n src={`${embedUrl}?autoplay=${autoplay ? 1 : 0}&loop=${loop ? 1 : 0}&mute=${autoplay ? 1 : 0}`}\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\"\n allowFullScreen\n loading=\"lazy\"\n onLoad={() => setIsLoaded(true)}\n className=\"w-full h-full\"\n />\n </div>\n );\n}\n","import type { SectionProps, ContentBlock } from \"@bettercms-ai/types\";\nimport { cn } from \"../lib/utils\";\nimport React from \"react\";\n\ninterface SectionBlockProps extends SectionProps {\n className?: string;\n renderBlock?: (block: ContentBlock) => React.ReactNode;\n}\n\nexport function Section({\n children,\n background,\n paddingY,\n maxWidth,\n className = \"\",\n renderBlock,\n}: SectionBlockProps) {\n const inner = (children ?? []).map((block) => (\n <span key={block.id}>{renderBlock ? renderBlock(block) : null}</span>\n ));\n return (\n <section\n className={cn(\"w-full\", className)}\n style={{ background, paddingTop: paddingY, paddingBottom: paddingY }}\n >\n {maxWidth ? <div style={{ maxWidth, marginInline: \"auto\" }}>{inner}</div> : inner}\n </section>\n );\n}\n","import type { NavbarProps } from \"@bettercms-ai/types\";\nimport { cn } from \"../lib/utils\";\n\ninterface NavbarBlockProps extends NavbarProps {\n className?: string;\n}\n\nexport function Navbar({ logo, links, cta, className = \"\" }: NavbarBlockProps) {\n return (\n <nav className={cn(\"flex items-center gap-6 py-4\", className)}>\n {logo?.src ? (\n <a href={logo.href ?? \"/\"} className=\"shrink-0\">\n <img src={logo.src} alt={logo.alt} className=\"h-8 w-auto\" />\n </a>\n ) : null}\n <div className=\"flex flex-1 gap-5\">\n {(links ?? []).map((l, i) => (\n <a key={i} href={l.href} className=\"text-inherit no-underline\">\n {l.label}\n </a>\n ))}\n </div>\n {cta ? (\n <a\n href={cta.href}\n className=\"rounded-lg bg-black px-4 py-2 font-semibold text-white no-underline\"\n >\n {cta.text}\n </a>\n ) : null}\n </nav>\n );\n}\n","import type { FooterProps } from \"@bettercms-ai/types\";\nimport { cn } from \"../lib/utils\";\n\ninterface FooterBlockProps extends FooterProps {\n className?: string;\n}\n\nexport function Footer({ columns, copyright, className = \"\" }: FooterBlockProps) {\n return (\n <footer className={cn(\"mt-12 border-t pt-8\", className)}>\n <div className=\"flex flex-wrap gap-12\">\n {(columns ?? []).map((col, i) => (\n <div key={i} className=\"flex flex-col gap-1.5\">\n {col.heading ? <h4 className=\"mb-2 font-semibold\">{col.heading}</h4> : null}\n {(col.links ?? []).map((l, j) => (\n <a key={j} href={l.href} className=\"text-neutral-500 no-underline\">\n {l.label}\n </a>\n ))}\n </div>\n ))}\n </div>\n {copyright ? <p className=\"mt-6 text-sm text-neutral-500\">{copyright}</p> : null}\n </footer>\n );\n}\n","\"use client\";\n\nimport type { SliderProps, ContentBlock } from \"@bettercms-ai/types\";\nimport { cn } from \"../lib/utils\";\nimport React, { useState } from \"react\";\n\ninterface SliderBlockProps extends SliderProps {\n className?: string;\n renderBlock?: (block: ContentBlock) => React.ReactNode;\n}\n\nexport function Slider({ slides, className = \"\", renderBlock }: SliderBlockProps) {\n const [i, setI] = useState(0);\n const list = slides ?? [];\n const go = (n: number) => setI((n + list.length) % (list.length || 1));\n const btn =\n \"absolute top-1/2 -translate-y-1/2 flex h-9 w-9 items-center justify-center rounded-full border-0 bg-black/50 text-white cursor-pointer\";\n return (\n <div className={cn(\"relative w-full\", className)}>\n {list.map((s, idx) => (\n <div key={s.id} hidden={idx !== i} className=\"flex flex-col gap-4\">\n {(s.children ?? []).map((b) => (\n <span key={b.id}>{renderBlock ? renderBlock(b) : null}</span>\n ))}\n </div>\n ))}\n <button type=\"button\" aria-label=\"Previous\" onClick={() => go(i - 1)} className={cn(btn, \"left-2\")}>\n ‹\n </button>\n <button type=\"button\" aria-label=\"Next\" onClick={() => go(i + 1)} className={cn(btn, \"right-2\")}>\n ›\n </button>\n </div>\n );\n}\n","\"use client\";\n\nimport type { TabsProps, ContentBlock } from \"@bettercms-ai/types\";\nimport { cn } from \"../lib/utils\";\nimport React, { useState } from \"react\";\n\ninterface TabsBlockProps extends TabsProps {\n className?: string;\n renderBlock?: (block: ContentBlock) => React.ReactNode;\n}\n\nexport function Tabs({ tabs, className = \"\", renderBlock }: TabsBlockProps) {\n const [active, setActive] = useState(0);\n const list = tabs ?? [];\n return (\n <div className={cn(\"w-full\", className)}>\n <div role=\"tablist\" className=\"mb-4 flex gap-1 border-b\">\n {list.map((t, idx) => (\n <button\n key={t.id}\n role=\"tab\"\n type=\"button\"\n aria-selected={idx === active}\n onClick={() => setActive(idx)}\n className={cn(\n \"cursor-pointer border-b-2 border-transparent bg-transparent px-4 py-2\",\n idx === active && \"border-black font-semibold\",\n )}\n >\n {t.label}\n </button>\n ))}\n </div>\n {list.map((t, idx) => (\n <div key={t.id} role=\"tabpanel\" hidden={idx !== active} className=\"flex flex-col gap-4\">\n {(t.children ?? []).map((b) => (\n <span key={b.id}>{renderBlock ? renderBlock(b) : null}</span>\n ))}\n </div>\n ))}\n </div>\n );\n}\n","import type { ComponentProps as BcmsComponentProps, FormProps, CollectionProps } from \"@bettercms-ai/types\";\nimport { cn } from \"../lib/utils\";\n\nconst box =\n \"rounded border border-dashed border-neutral-300 bg-neutral-50 p-4 text-sm text-neutral-500\";\n\n/**\n * Builder-preview placeholder for a `component` instance. Live instance resolution\n * (definition lookup + override merge) happens server-side in the delivery renderer\n * and in the page-builder, which pass a resolver — the standalone library preview\n * just shows what's referenced.\n */\nexport function ComponentInstance({\n componentId,\n className = \"\",\n}: BcmsComponentProps & { className?: string }) {\n return (\n <div className={cn(box, className)}>\n Component instance: <code>{componentId}</code>\n </div>\n );\n}\n\n/** Builder-preview placeholder for a `form` block (rendered live by @bettercms-ai/next). */\nexport function FormPlaceholder({ formId, className = \"\" }: FormProps & { className?: string }) {\n return (\n <div className={cn(box, className)}>\n Form: <code>{formId}</code>\n </div>\n );\n}\n\n/**\n * Builder-preview placeholder for a `collection` block.\n *\n * The builder canvas has no entries to list — the list is fetched per request by the site\n * renderer, deliberately, so that a published snapshot can never bake in a stale set of\n * posts. A placeholder is therefore the honest render here, not a limitation.\n */\nexport function CollectionPlaceholder({\n cardComponentId,\n className = \"\",\n}: CollectionProps & { className?: string }) {\n return (\n <div className={cn(box, className)}>\n Collection: entries of this page\n {cardComponentId ? <> as <code>{cardComponentId}</code></> : <> (default card)</>}\n </div>\n );\n}\n"],"mappings":";;;AA0Ba;AAlBN,SAAS,QAAQ;AAAA,EACtB;AAAA,EACA,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,mBAAmB;AAAA,EACnB,kBAAkB;AACpB,GAAsB;AACpB,QAAM,aAAa;AAAA,IACjB,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,OAAO;AAAA,EACT,EAAE,KAAK;AAEP,QAAM,aAAa,yDAAyD,UAAU,IAAI,SAAS;AAEnG,UAAQ,OAAO;AAAA,IACb,KAAK;AACH,aAAO,oBAAC,QAAG,WAAW,YAAY,mBAAiB,OAAO,kBAAgB,MAAO,gBAAK;AAAA,IACxF,KAAK;AACH,aAAO,oBAAC,QAAG,WAAW,YAAY,mBAAiB,OAAO,kBAAgB,MAAO,gBAAK;AAAA,IACxF,KAAK;AACH,aAAO,oBAAC,QAAG,WAAW,YAAY,mBAAiB,OAAO,kBAAgB,MAAO,gBAAK;AAAA,IACxF;AACE,aAAO,oBAAC,QAAG,WAAW,YAAY,mBAAiB,OAAO,kBAAgB,MAAO,gBAAK;AAAA,EAC1F;AACF;;;AClCA,OAAO,WAAW;AA0CC,SAUf,UAVe,OAAAA,YAAA;AA3BnB,IAAM,YAA+D;AAAA,EACnE,QAAQ;AAAA,EACR,IAAI;AAAA,EACJ,WAAW;AAAA,EACX,kBAAkB;AAAA,EAClB,MAAM;AACR;AAEA,IAAM,aAAgE;AAAA,EACpE,QAAQ;AAAA,EACR,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,YAAY;AACd;AAEA,SAAS,KAAK,EAAE,MAAM,MAAM,GAA8C;AACxE,QAAM,QAAQ,KAAK,SAAS,CAAC;AAC7B,QAAM,SAAS,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,QAAQ,CAAC,GAAG,MAAM,SAAS,MAAM;AAG/E,MAAI,MAAuB,KAAK,QAAQ;AACxC,aAAW,KAAK,OAAO;AACrB,UAAM,MAAM,UAAU,CAAC;AACvB,QAAI,IAAK,OAAM,gBAAAA,KAAC,OAAK,eAAI;AAAA,EAC3B;AACA,MAAI,UAAU,gBAAgB,KAAK,MAAM,GAAG;AAC1C,UAAM,gBAAAA,KAAC,UAAK,WAAW,cAAc,MAAM,IAAK,eAAI;AAAA,EACtD;AACA,SAAO,gBAAAA,KAAC,MAAM,UAAN,EAAyC,iBAArB,KAAK,QAAQ,KAAY;AACvD;AAEO,SAAS,aAAa,EAAE,IAAI,GAAkC;AACnE,SACE,gBAAAA,KAAA,YACG,cAAI,QAAQ,IAAI,CAAC,OAAO,MAAM;AAC7B,UAAM,MAAM,WAAW,MAAM,SAAS,QAAQ,KAAK;AACnD,WACE,gBAAAA,KAAC,OACG,iBAAM,YAAY,CAAC,GAAG,IAAI,CAAC,GAAG,MAC9B,gBAAAA,KAAC,QAAuB,MAAM,GAAG,OAAO,KAA7B,EAAE,QAAQ,CAAsB,CAC5C,KAHO,MAAM,QAAQ,CAIxB;AAAA,EAEJ,CAAC,GACH;AAEJ;;;AChCQ,gBAAAC,YAAA;AAtBD,SAAS,KAAK;AAAA,EACnB;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,mBAAmB;AAAA,EACnB,kBAAkB;AACpB,GAAmB;AACjB,QAAM,aAAa;AAAA,IACjB,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,OAAO;AAAA,EACT,EAAE,KAAK;AAEP,QAAM,MAAM,yCAAyC,UAAU,IAAI,SAAS;AAK5E,MAAI,WAAW,QAAQ,QAAQ,SAAS,GAAG;AACzC,WACE,gBAAAA,KAAC,SAAI,WAAW,KACd,0BAAAA,KAAC,gBAAa,KAAK,SAAS,GAC9B;AAAA,EAEJ;AAEA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,MACX,mBAAiB;AAAA,MACjB,kBAAgB;AAAA,MAEhB,yBAAyB,EAAE,QAAQ,KAAK;AAAA;AAAA,EAC1C;AAEJ;;;AC/CA,SAAS,YAA6B;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;ACgBI,SACE,OAAAC,MADF;AAZG,SAAS,MAAM;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA,mBAAmB;AAAA,EACnB,kBAAkB;AACpB,GAAoB;AAClB,SACE,qBAAC,YAAO,WAAW,GAAG,UAAU,SAAS,GACvC;AAAA,oBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,mBAAiB;AAAA,QACjB,kBAAgB;AAAA,QAChB,WAAU;AAAA,QACV,SAAQ;AAAA;AAAA,IACV;AAAA,IACC,WACC,gBAAAA,KAAC,gBAAW,WAAU,yDACnB,mBACH;AAAA,KAEJ;AAEJ;;;ACLI,gBAAAC,YAAA;AA1BG,SAAS,OAAO;AAAA,EACrB;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,mBAAmB;AAAA,EACnB,kBAAkB;AACpB,GAAqB;AACnB,QAAM,aACJ;AAEF,QAAM,gBAAgB;AAAA,IACpB,SACE;AAAA,IACF,WACE;AAAA,EACJ;AAEA,QAAM,aAAa;AAAA,IACjB,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,OAAO;AAAA,EACT,EAAE,KAAK;AAEP,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,mBAAiB;AAAA,MACjB,kBAAgB;AAAA,MAChB,WAAW,GAAG,YAAY,cAAc,OAAO,GAAG,YAAY,aAAa,SAAS;AAAA,MAEnF;AAAA;AAAA,EACH;AAEJ;;;ACpCI,gBAAAC,MAKE,QAAAC,aALF;AAFG,SAAS,OAAO,EAAE,SAAS,IAAI,YAAY,GAAG,GAAqB;AACxE,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,mGAAmG,SAAS;AAAA,MACvH,OAAO,EAAE,QAAQ,GAAG,MAAM,KAAK;AAAA,MAC/B,eAAY;AAAA,MAEZ,0BAAAC,MAAC,UAAK,WAAU,gDACb;AAAA;AAAA,QAAO;AAAA,SACV;AAAA;AAAA,EACF;AAEJ;;;AChBA,OAAkB;AAwBN,gBAAAC,YAAA;AAjBL,SAAS,QAAQ;AAAA,EACtB;AAAA,EACA,MAAM;AAAA,EACN,YAAY;AAAA,EACZ;AACF,GAAsB;AACpB,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,eAAe,SAAS;AAAA,MACtC,OAAO;AAAA,QACL,qBAAqB,UAAU,QAAQ,MAAM;AAAA,QAC7C,KAAK,GAAG,GAAG;AAAA,MACb;AAAA,MAEC,kBAAQ,IAAI,CAAC,cAAc,aAC1B,gBAAAA,KAAC,SAAmB,WAAU,+BAC3B,uBAAa,IAAI,CAAC,UACjB,gBAAAA,KAAC,UACE,wBAAc,YAAY,KAAK,IAAI,QAD3B,MAAM,EAEjB,CACD,KALO,QAMV,CACD;AAAA;AAAA,EACH;AAEJ;;;ACjCA,SAAS,gBAAgB;AA4CnB,gBAAAC,MAaF,QAAAC,aAbE;AArCN,SAAS,YAAY,KAA8E;AAEjG,QAAM,UAAU,IAAI;AAAA,IAClB;AAAA,EACF;AACA,MAAI,SAAS;AACX,WAAO;AAAA,MACL,UAAU,iCAAiC,QAAQ,CAAC,CAAC;AAAA,MACrD,UAAU;AAAA,IACZ;AAAA,EACF;AAGA,QAAM,aAAa,IAAI,MAAM,mBAAmB;AAChD,MAAI,YAAY;AACd,WAAO;AAAA,MACL,UAAU,kCAAkC,WAAW,CAAC,CAAC;AAAA,MACzD,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,SAAO,EAAE,UAAU,KAAK,UAAU,UAAU;AAC9C;AAEO,SAAS,MAAM;AAAA,EACpB;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,OAAO;AAAA,EACP,YAAY;AACd,GAAoB;AAClB,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,EAAE,UAAU,SAAS,IAAI,YAAY,GAAG;AAG9C,MAAI,aAAa,WAAW;AAC1B,WACE,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL;AAAA,QACA,UAAU;AAAA,QACV;AAAA,QACA,UAAQ;AAAA,QACR;AAAA,QACA,aAAW;AAAA;AAAA,IACb;AAAA,EAEJ;AAEA,SACE,gBAAAC,MAAC,SAAI,WAAW,GAAG,2DAA2D,SAAS,GACpF;AAAA,KAAC,YAAY;AAAA,IAEZ,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,KAAI;AAAA,QACJ,WAAU;AAAA;AAAA,IACZ;AAAA,IAEF,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK,GAAG,QAAQ,aAAa,WAAW,IAAI,CAAC,SAAS,OAAO,IAAI,CAAC,SAAS,WAAW,IAAI,CAAC;AAAA,QAC3F,OAAM;AAAA,QACN,iBAAe;AAAA,QACf,SAAQ;AAAA,QACR,QAAQ,MAAM,YAAY,IAAI;AAAA,QAC9B,WAAU;AAAA;AAAA,IACZ;AAAA,KACF;AAEJ;;;AC3EA,OAAkB;AAgBd,gBAAAE,YAAA;AATG,SAAS,QAAQ;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AACF,GAAsB;AACpB,QAAM,SAAS,YAAY,CAAC,GAAG,IAAI,CAAC,UAClC,gBAAAA,KAAC,UAAqB,wBAAc,YAAY,KAAK,IAAI,QAA9C,MAAM,EAA6C,CAC/D;AACD,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,UAAU,SAAS;AAAA,MACjC,OAAO,EAAE,YAAY,YAAY,UAAU,eAAe,SAAS;AAAA,MAElE,qBAAW,gBAAAA,KAAC,SAAI,OAAO,EAAE,UAAU,cAAc,OAAO,GAAI,iBAAM,IAAS;AAAA;AAAA,EAC9E;AAEJ;;;ACnBI,SAGM,OAAAC,OAHN,QAAAC,aAAA;AAFG,SAAS,OAAO,EAAE,MAAM,OAAO,KAAK,YAAY,GAAG,GAAqB;AAC7E,SACE,gBAAAA,MAAC,SAAI,WAAW,GAAG,gCAAgC,SAAS,GACzD;AAAA,UAAM,MACL,gBAAAD,MAAC,OAAE,MAAM,KAAK,QAAQ,KAAK,WAAU,YACnC,0BAAAA,MAAC,SAAI,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,WAAU,cAAa,GAC5D,IACE;AAAA,IACJ,gBAAAA,MAAC,SAAI,WAAU,qBACX,oBAAS,CAAC,GAAG,IAAI,CAAC,GAAG,MACrB,gBAAAA,MAAC,OAAU,MAAM,EAAE,MAAM,WAAU,6BAChC,YAAE,SADG,CAER,CACD,GACH;AAAA,IACC,MACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,IAAI;AAAA,QACV,WAAU;AAAA,QAET,cAAI;AAAA;AAAA,IACP,IACE;AAAA,KACN;AAEJ;;;ACpBU,SACiB,OAAAE,OADjB,QAAAC,aAAA;AALH,SAAS,OAAO,EAAE,SAAS,WAAW,YAAY,GAAG,GAAqB;AAC/E,SACE,gBAAAA,MAAC,YAAO,WAAW,GAAG,uBAAuB,SAAS,GACpD;AAAA,oBAAAD,MAAC,SAAI,WAAU,yBACX,sBAAW,CAAC,GAAG,IAAI,CAAC,KAAK,MACzB,gBAAAC,MAAC,SAAY,WAAU,yBACpB;AAAA,UAAI,UAAU,gBAAAD,MAAC,QAAG,WAAU,sBAAsB,cAAI,SAAQ,IAAQ;AAAA,OACrE,IAAI,SAAS,CAAC,GAAG,IAAI,CAAC,GAAG,MACzB,gBAAAA,MAAC,OAAU,MAAM,EAAE,MAAM,WAAU,iCAChC,YAAE,SADG,CAER,CACD;AAAA,SANO,CAOV,CACD,GACH;AAAA,IACC,YAAY,gBAAAA,MAAC,OAAE,WAAU,iCAAiC,qBAAU,IAAO;AAAA,KAC9E;AAEJ;;;ACrBA,SAAgB,YAAAE,iBAAgB;AAc5B,SAIQ,OAAAC,OAJR,QAAAC,aAAA;AAPG,SAAS,OAAO,EAAE,QAAQ,YAAY,IAAI,YAAY,GAAqB;AAChF,QAAM,CAAC,GAAG,IAAI,IAAIF,UAAS,CAAC;AAC5B,QAAM,OAAO,UAAU,CAAC;AACxB,QAAM,KAAK,CAAC,MAAc,MAAM,IAAI,KAAK,WAAW,KAAK,UAAU,EAAE;AACrE,QAAM,MACJ;AACF,SACE,gBAAAE,MAAC,SAAI,WAAW,GAAG,mBAAmB,SAAS,GAC5C;AAAA,SAAK,IAAI,CAAC,GAAG,QACZ,gBAAAD,MAAC,SAAe,QAAQ,QAAQ,GAAG,WAAU,uBACzC,aAAE,YAAY,CAAC,GAAG,IAAI,CAAC,MACvB,gBAAAA,MAAC,UAAiB,wBAAc,YAAY,CAAC,IAAI,QAAtC,EAAE,EAAyC,CACvD,KAHO,EAAE,EAIZ,CACD;AAAA,IACD,gBAAAA,MAAC,YAAO,MAAK,UAAS,cAAW,YAAW,SAAS,MAAM,GAAG,IAAI,CAAC,GAAG,WAAW,GAAG,KAAK,QAAQ,GAAG,oBAEpG;AAAA,IACA,gBAAAA,MAAC,YAAO,MAAK,UAAS,cAAW,QAAO,SAAS,MAAM,GAAG,IAAI,CAAC,GAAG,WAAW,GAAG,KAAK,SAAS,GAAG,oBAEjG;AAAA,KACF;AAEJ;;;AC9BA,SAAgB,YAAAE,iBAAgB;AAW5B,SAGM,OAAAC,OAHN,QAAAC,aAAA;AAJG,SAAS,KAAK,EAAE,MAAM,YAAY,IAAI,YAAY,GAAmB;AAC1E,QAAM,CAAC,QAAQ,SAAS,IAAIF,UAAS,CAAC;AACtC,QAAM,OAAO,QAAQ,CAAC;AACtB,SACE,gBAAAE,MAAC,SAAI,WAAW,GAAG,UAAU,SAAS,GACpC;AAAA,oBAAAD,MAAC,SAAI,MAAK,WAAU,WAAU,4BAC3B,eAAK,IAAI,CAAC,GAAG,QACZ,gBAAAA;AAAA,MAAC;AAAA;AAAA,QAEC,MAAK;AAAA,QACL,MAAK;AAAA,QACL,iBAAe,QAAQ;AAAA,QACvB,SAAS,MAAM,UAAU,GAAG;AAAA,QAC5B,WAAW;AAAA,UACT;AAAA,UACA,QAAQ,UAAU;AAAA,QACpB;AAAA,QAEC,YAAE;AAAA;AAAA,MAVE,EAAE;AAAA,IAWT,CACD,GACH;AAAA,IACC,KAAK,IAAI,CAAC,GAAG,QACZ,gBAAAA,MAAC,SAAe,MAAK,YAAW,QAAQ,QAAQ,QAAQ,WAAU,uBAC9D,aAAE,YAAY,CAAC,GAAG,IAAI,CAAC,MACvB,gBAAAA,MAAC,UAAiB,wBAAc,YAAY,CAAC,IAAI,QAAtC,EAAE,EAAyC,CACvD,KAHO,EAAE,EAIZ,CACD;AAAA,KACH;AAEJ;;;ACzBI,SA6BqB,YAAAE,WA5BC,OAAAC,OADtB,QAAAC,aAAA;AAdJ,IAAM,MACJ;AAQK,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA,YAAY;AACd,GAAgD;AAC9C,SACE,gBAAAA,MAAC,SAAI,WAAW,GAAG,KAAK,SAAS,GAAG;AAAA;AAAA,IACd,gBAAAD,MAAC,UAAM,uBAAY;AAAA,KACzC;AAEJ;AAGO,SAAS,gBAAgB,EAAE,QAAQ,YAAY,GAAG,GAAuC;AAC9F,SACE,gBAAAC,MAAC,SAAI,WAAW,GAAG,KAAK,SAAS,GAAG;AAAA;AAAA,IAC5B,gBAAAD,MAAC,UAAM,kBAAO;AAAA,KACtB;AAEJ;","names":["jsx","jsx","jsx","jsx","jsx","jsxs","jsx","jsx","jsxs","jsx","jsx","jsxs","jsx","jsxs","useState","jsx","jsxs","useState","jsx","jsxs","Fragment","jsx","jsxs"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
export { B as Button, C as Columns, H as Heading, I as Image, S as Spacer, T as Text, V as Video } from './Video-
|
|
1
|
+
export { B as BcmsBindingProps, a as Button, C as Columns, H as Heading, I as Image, S as Spacer, T as Text, V as Video } from './Video-DRC_fPjV.js';
|
|
2
2
|
export { BLOCK_REGISTRY, BLOCK_TYPES, BlockRegistryEntry } from './registry.js';
|
|
3
3
|
export { BlockRenderer, BlocksRenderer } from './renderer.js';
|
|
4
4
|
import { ClassValue } from 'clsx';
|
|
5
5
|
import 'react/jsx-runtime';
|
|
6
|
-
import '@betttercms/types';
|
|
7
|
-
import 'react';
|
|
8
6
|
import '@bettercms-ai/types';
|
|
7
|
+
import 'react';
|
|
9
8
|
|
|
10
9
|
declare function cn(...inputs: ClassValue[]): string;
|
|
11
10
|
|