@commercetools-demo/puck-editor 0.5.1 → 0.6.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/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import React, { ReactNode } from 'react';
2
- import { Config, ComponentConfig } from '@measured/puck';
2
+ import { Config, ComponentConfig, CustomField, Data, Overrides } from '@measured/puck';
3
3
  import { PuckData, PuckStateInfo } from '@commercetools-demo/puck-types';
4
4
 
5
5
  interface PuckEditorProps {
@@ -11,6 +11,8 @@ interface PuckEditorProps {
11
11
  businessUnitKey: string;
12
12
  /** JWT bearer token — required for save/publish mutations */
13
13
  jwtToken: string;
14
+ /** Content locale (e.g. "en-US") used for locale-aware calls like product search */
15
+ locale?: string;
14
16
  /** The key of the puck page to edit */
15
17
  pageKey: string;
16
18
  /**
@@ -25,6 +27,10 @@ interface PuckEditorProps {
25
27
  onSave?: (puckData: PuckData) => void;
26
28
  /** Called when an error occurs */
27
29
  onError?: (error: Error) => void;
30
+ /** Opens the preview view; when omitted the toolbar Preview button is hidden. */
31
+ onPreview?: () => void;
32
+ /** Notifies the host when the unsaved-changes state flips (for nav guards). */
33
+ onDirtyChange?: (isDirty: boolean) => void;
28
34
  /** Show the Publish button in the toolbar. Default: true */
29
35
  showPublishButton?: boolean;
30
36
  /** Debounce delay for auto-save in ms. Default: 1500 */
@@ -48,7 +54,9 @@ declare const defaultPuckConfig: Config;
48
54
 
49
55
  interface HeroProps {
50
56
  heading: string;
57
+ headingFontSize?: string;
51
58
  subheading?: string;
59
+ subheadingFontSize?: string;
52
60
  backgroundImage?: string;
53
61
  ctaText?: string;
54
62
  ctaUrl?: string;
@@ -65,11 +73,32 @@ interface RichTextProps {
65
73
  }
66
74
  declare const RichText: ComponentConfig<RichTextProps>;
67
75
 
76
+ interface GridProps {
77
+ columnCount?: 1 | 2 | 3 | 4 | 5 | 6;
78
+ rowCount?: 1 | 2 | 3 | 4 | 5 | 6;
79
+ gap?: string;
80
+ padding?: string;
81
+ }
82
+ /**
83
+ * Grid — a layout container that lays out a `columnCount` × `rowCount` matrix
84
+ * of drop zones. Each cell is an independent Puck DropZone, so components can be
85
+ * dropped into any cell. (Renamed from "Columns"; rows added.)
86
+ *
87
+ * This render function is shared by the editor and the Puck renderer
88
+ * (puck-renderer runs the same config), so updating it here updates both.
89
+ */
90
+ declare const Grid: ComponentConfig<GridProps>;
91
+
68
92
  interface ColumnsProps {
69
93
  columnCount?: 2 | 3 | 4;
70
94
  gap?: string;
71
95
  padding?: string;
72
96
  }
97
+ /**
98
+ * @deprecated Use `Grid` instead (columns + rows). `Columns` is kept registered
99
+ * for backward compatibility so pages saved with the original component (and its
100
+ * `column-N` drop zones) keep rendering. Prefer Grid for new content.
101
+ */
73
102
  declare const Columns: ComponentConfig<ColumnsProps>;
74
103
 
75
104
  interface ImageProps {
@@ -89,6 +118,7 @@ interface ButtonProps {
89
118
  href?: string;
90
119
  variant?: 'primary' | 'secondary' | 'outline';
91
120
  size?: 'sm' | 'md' | 'lg';
121
+ fontSize?: string;
92
122
  align?: 'left' | 'center' | 'right';
93
123
  openInNewTab?: boolean;
94
124
  }
@@ -96,6 +126,7 @@ declare const Button: ComponentConfig<ButtonProps>;
96
126
 
97
127
  interface CardProps {
98
128
  title: string;
129
+ titleFontSize?: string;
99
130
  body?: string;
100
131
  imageUrl?: string;
101
132
  ctaText?: string;
@@ -125,7 +156,15 @@ interface DatasourceFieldProps {
125
156
  }
126
157
  declare const DatasourceField: React.FC<DatasourceFieldProps>;
127
158
 
128
- interface ProductTeaserProps {
159
+ /** How a product link is built — from the product slug or its SKU. */
160
+ type ProductLinkWith = 'slug' | 'sku';
161
+ /** Props every product-linking component shares. */
162
+ interface ProductLinkProps {
163
+ linkWith: ProductLinkWith;
164
+ baseUrl: string;
165
+ }
166
+
167
+ interface ProductTeaserProps extends ProductLinkProps {
129
168
  datasource: DatasourceValue;
130
169
  richText: string;
131
170
  }
@@ -186,7 +225,7 @@ interface CountdownBannerProps {
186
225
  }
187
226
  declare const CountdownBanner: ComponentConfig<CountdownBannerProps>;
188
227
 
189
- interface CrossSellBlockProps {
228
+ interface CrossSellBlockProps extends ProductLinkProps {
190
229
  title: string;
191
230
  products: DatasourceValue;
192
231
  ctaText: string;
@@ -249,7 +288,7 @@ interface NewsletterSignupProps {
249
288
  }
250
289
  declare const NewsletterSignup: ComponentConfig<NewsletterSignupProps>;
251
290
 
252
- interface ProductBannerProps {
291
+ interface ProductBannerProps extends ProductLinkProps {
253
292
  title: string;
254
293
  description: string;
255
294
  ctaText: string;
@@ -266,7 +305,7 @@ interface ProductGridHeaderProps {
266
305
  }
267
306
  declare const ProductGridHeader: ComponentConfig<ProductGridHeaderProps>;
268
307
 
269
- interface ProductSliderProps {
308
+ interface ProductSliderProps extends ProductLinkProps {
270
309
  title: string;
271
310
  subtitle: string;
272
311
  products: DatasourceValue;
@@ -283,7 +322,7 @@ interface PromotionalBannerProps {
283
322
  }
284
323
  declare const PromotionalBanner: ComponentConfig<PromotionalBannerProps>;
285
324
 
286
- interface RelatedProductsSliderProps {
325
+ interface RelatedProductsSliderProps extends ProductLinkProps {
287
326
  title: string;
288
327
  subtitle: string;
289
328
  products: DatasourceValue;
@@ -364,17 +403,135 @@ interface ImagePickerFieldProps {
364
403
  }
365
404
  declare const ImagePickerField: React.FC<ImagePickerFieldProps>;
366
405
 
406
+ interface RichTextFieldProps {
407
+ /** HTML string. */
408
+ value: string | undefined;
409
+ onChange: (value: string) => void;
410
+ }
411
+ declare const RichTextField: React.FC<RichTextFieldProps>;
412
+ /**
413
+ * Puck `custom` field config that renders a rich-text editor (HTML in / out).
414
+ * Use in a component's `fields` for any prop that holds an HTML string, e.g.
415
+ * fields: { body: richTextField('Body') }
416
+ */
417
+ declare const richTextField: (label: string) => CustomField<string>;
418
+
419
+ /**
420
+ * Sanitize rich-text HTML before it is injected via dangerouslySetInnerHTML.
421
+ *
422
+ * RichText/TextBlock/Card store author-controlled HTML produced by the TipTap
423
+ * editor, but content can also arrive from imports or older data, so we always
424
+ * sanitize at render time. isomorphic-dompurify works in both the browser and
425
+ * during SSR, so this is safe wherever the renderer runs.
426
+ *
427
+ * `style` and `class` are allowed because the editor emits inline styles
428
+ * (e.g. font-size from the typography control) and structural classes.
429
+ */
430
+ declare const sanitizeHtml: (html: string | undefined | null) => string;
431
+
367
432
  interface EditorToolbarProps {
433
+ /** Page / content name shown centred in the bar. */
434
+ title: string;
368
435
  saving: boolean;
369
436
  isDirty: boolean;
370
437
  states: PuckStateInfo;
371
438
  onSave: () => void;
372
439
  onPublish: () => void;
373
440
  onRevert: () => void;
441
+ /** When provided, renders a Preview button that opens the preview view. */
442
+ onPreview?: () => void;
443
+ /** When provided, adds a "Create a template from this…" overflow-menu item. */
444
+ onCreateTemplate?: () => void;
445
+ /** Label for the create-template menu item. */
446
+ createTemplateLabel?: string;
374
447
  showPublishButton: boolean;
375
448
  }
449
+ /**
450
+ * Full replacement for Puck's header (wired via the `header` override).
451
+ *
452
+ * Layout: undo/redo + panel toggle on the left, the document name with its
453
+ * status badges centred, and the Save / Publish / Preview actions plus an
454
+ * overflow menu (version history, revert) on the right.
455
+ */
376
456
  declare const EditorToolbar: React.FC<EditorToolbarProps>;
377
457
 
458
+ interface UnsavedChangesDialogProps {
459
+ /** Whether the dialog is visible. */
460
+ isOpen: boolean;
461
+ /** Called when the dialog requests to open/close (backdrop, Esc, Stay). */
462
+ onOpenChange: (isOpen: boolean) => void;
463
+ /** Called when the user confirms they want to leave and discard changes. */
464
+ onConfirm: () => void;
465
+ }
466
+ /**
467
+ * Nimbus confirmation shown when the user tries to navigate away from an editor
468
+ * that has unsaved changes. Replaces the native `window.confirm` so the warning
469
+ * matches the rest of the editor chrome.
470
+ */
471
+ declare const UnsavedChangesDialog: React.FC<UnsavedChangesDialogProps>;
472
+
473
+ interface CreateTemplateDialogProps {
474
+ /** Whether the dialog is visible. */
475
+ isOpen: boolean;
476
+ /** Called when the dialog requests to open/close (backdrop, Esc, Cancel). */
477
+ onOpenChange: (isOpen: boolean) => void;
478
+ /**
479
+ * Called when the user confirms. `withoutData` reflects the
480
+ * "Create template without data" checkbox (default checked).
481
+ */
482
+ onConfirm: (name: string, withoutData: boolean) => void | Promise<void>;
483
+ /** Disables the form while the template is being created. */
484
+ saving?: boolean;
485
+ }
486
+ /**
487
+ * Nimbus dialog for "Create a template from this page/content". Collects a
488
+ * template name and whether to strip component data before saving.
489
+ */
490
+ declare const CreateTemplateDialog: React.FC<CreateTemplateDialogProps>;
491
+
492
+ /**
493
+ * Produce a "without data" copy of Puck data for use as a template.
494
+ *
495
+ * Each **leaf** component's props are reset to its config `defaultProps` (so a
496
+ * new page created from the template shows the component's default contents,
497
+ * not the source page's data). **Container** components — those that hold child
498
+ * components in a zone — keep their props, so structural fields (e.g. a Grid's
499
+ * `columnCount`) survive and the nested layout renders correctly.
500
+ *
501
+ * Nested components live in a flat `data.zones` map keyed `"<parentId>:<zone>"`;
502
+ * `<parentId>` is the parent component's `props.id`. Every component's
503
+ * `props.id` is always preserved so those zone keys stay consistent.
504
+ */
505
+ declare function stripPuckDataToTemplate(data: Data, config: Config): Data;
506
+
507
+ interface DirtyState {
508
+ /** True when the canvas differs from the last saved / loaded baseline. */
509
+ isDirty: boolean;
510
+ /**
511
+ * Feed every Puck `onChange` payload through this. The very first call after
512
+ * a (re)load establishes the baseline and is treated as "clean" — Puck emits
513
+ * an `onChange` on mount while it normalises the incoming data, and that must
514
+ * not be mistaken for an edit by the user.
515
+ */
516
+ markChange: (data: unknown) => void;
517
+ /** Mark the current data as the saved baseline (call after a successful save). */
518
+ markSaved: (data: unknown) => void;
519
+ }
520
+ /**
521
+ * Tracks whether the Puck canvas has unsaved edits.
522
+ *
523
+ * Puck is an uncontrolled editor that fires `onChange` once on mount (to report
524
+ * its normalised version of the initial data). Naively flagging the editor
525
+ * dirty on the first `onChange` makes a freshly-opened page look "Unsaved" even
526
+ * though nothing was touched. We instead capture that first payload as the
527
+ * baseline and only flag dirty when a later payload diverges from it.
528
+ *
529
+ * `resetKey` should change whenever the document shown in the canvas is swapped
530
+ * out (different page/content, or a historical version applied) so a new
531
+ * baseline is captured for the new document.
532
+ */
533
+ declare const useDirtyState: (resetKey: string) => DirtyState;
534
+
378
535
  declare const ComponentSearchProvider: React.FC<{
379
536
  children: ReactNode;
380
537
  }>;
@@ -386,4 +543,25 @@ declare const ComponentItemFilter: React.FC<{
386
543
  name: string;
387
544
  }>;
388
545
 
389
- export { Button, type ButtonProps, Card, type CardProps, CategoryGrid, type CategoryGridProps, CategoryHero, type CategoryHeroProps, CheckoutPromoBanner, type CheckoutPromoBannerProps, Columns, type ColumnsProps, ComponentItemFilter, ComponentSearchProvider, ComponentsPanel, CountdownBanner, type CountdownBannerProps, CrossSellBlock, type CrossSellBlockProps, DatasourceField, type DatasourceFieldProps, type DatasourceType, type DatasourceValue, DeliveryMessage, type DeliveryMessageProps, Divider, type DividerProps, EditorToolbar, type EditorToolbarProps, EmptyState, type EmptyStateProps, FAQAccordion, type FAQAccordionProps, FooterBlock, type FooterBlockProps, Hero, HeroBanner, type HeroBannerProps, type HeroProps, Image, ImageBlock, type ImageBlockProps, ImagePickerField, type ImagePickerFieldProps, type ImageProps, NewsletterSignup, type NewsletterSignupProps, ProductBanner, type ProductBannerProps, ProductGridHeader, type ProductGridHeaderProps, ProductSlider, type ProductSliderProps, ProductTeaser, type ProductTeaserProps, PromotionalBanner, type PromotionalBannerProps, PuckEditor, type PuckEditorProps, RelatedProductsSlider, type RelatedProductsSliderProps, RichText, type RichTextProps, SocialLinks, type SocialLinksProps, Spacer, type SpacerProps, TabContent, type TabContentProps, TestimonialsSlider, type TestimonialsSliderProps, TextBlock, type TextBlockProps, ThankYouContent, type ThankYouContentProps, TrustBadges, type TrustBadgesProps, VideoBlock, type VideoBlockProps, WebsiteLogo, type WebsiteLogoProps, defaultPuckConfig };
546
+ declare const nimbusFieldTypes: NonNullable<Overrides['fieldTypes']>;
547
+
548
+ interface PropertiesResizerProps {
549
+ /** Smallest allowed width in px. */
550
+ minWidth?: number;
551
+ /** Largest allowed width in px. */
552
+ maxWidth?: number;
553
+ }
554
+ /**
555
+ * Draggable divider that resizes the Puck properties (right) panel.
556
+ *
557
+ * Render it as a child of the `.puck-editor-fill` container (a sibling of the
558
+ * Puck editor). It writes the chosen width to a `--puck-properties-width` CSS
559
+ * variable on that container — the grid-template override in
560
+ * ComponentListSearch's injected `<style>` reads it to size only the right
561
+ * column, leaving the left panel and canvas alone. The handle is positioned
562
+ * over the panel's left edge by measuring the live sidebar, and hides itself
563
+ * when the panel is collapsed. The width persists in localStorage.
564
+ */
565
+ declare const PropertiesResizer: React.FC<PropertiesResizerProps>;
566
+
567
+ export { Button, type ButtonProps, Card, type CardProps, CategoryGrid, type CategoryGridProps, CategoryHero, type CategoryHeroProps, CheckoutPromoBanner, type CheckoutPromoBannerProps, Columns, type ColumnsProps, ComponentItemFilter, ComponentSearchProvider, ComponentsPanel, CountdownBanner, type CountdownBannerProps, CreateTemplateDialog, type CreateTemplateDialogProps, CrossSellBlock, type CrossSellBlockProps, DatasourceField, type DatasourceFieldProps, type DatasourceType, type DatasourceValue, DeliveryMessage, type DeliveryMessageProps, type DirtyState, Divider, type DividerProps, EditorToolbar, type EditorToolbarProps, EmptyState, type EmptyStateProps, FAQAccordion, type FAQAccordionProps, FooterBlock, type FooterBlockProps, Grid, type GridProps, Hero, HeroBanner, type HeroBannerProps, type HeroProps, Image, ImageBlock, type ImageBlockProps, ImagePickerField, type ImagePickerFieldProps, type ImageProps, NewsletterSignup, type NewsletterSignupProps, ProductBanner, type ProductBannerProps, ProductGridHeader, type ProductGridHeaderProps, ProductSlider, type ProductSliderProps, ProductTeaser, type ProductTeaserProps, PromotionalBanner, type PromotionalBannerProps, PropertiesResizer, type PropertiesResizerProps, PuckEditor, type PuckEditorProps, RelatedProductsSlider, type RelatedProductsSliderProps, RichText, RichTextField, type RichTextFieldProps, type RichTextProps, SocialLinks, type SocialLinksProps, Spacer, type SpacerProps, TabContent, type TabContentProps, TestimonialsSlider, type TestimonialsSliderProps, TextBlock, type TextBlockProps, ThankYouContent, type ThankYouContentProps, TrustBadges, type TrustBadgesProps, UnsavedChangesDialog, type UnsavedChangesDialogProps, VideoBlock, type VideoBlockProps, WebsiteLogo, type WebsiteLogoProps, defaultPuckConfig, nimbusFieldTypes, richTextField, sanitizeHtml, stripPuckDataToTemplate, useDirtyState };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import React, { ReactNode } from 'react';
2
- import { Config, ComponentConfig } from '@measured/puck';
2
+ import { Config, ComponentConfig, CustomField, Data, Overrides } from '@measured/puck';
3
3
  import { PuckData, PuckStateInfo } from '@commercetools-demo/puck-types';
4
4
 
5
5
  interface PuckEditorProps {
@@ -11,6 +11,8 @@ interface PuckEditorProps {
11
11
  businessUnitKey: string;
12
12
  /** JWT bearer token — required for save/publish mutations */
13
13
  jwtToken: string;
14
+ /** Content locale (e.g. "en-US") used for locale-aware calls like product search */
15
+ locale?: string;
14
16
  /** The key of the puck page to edit */
15
17
  pageKey: string;
16
18
  /**
@@ -25,6 +27,10 @@ interface PuckEditorProps {
25
27
  onSave?: (puckData: PuckData) => void;
26
28
  /** Called when an error occurs */
27
29
  onError?: (error: Error) => void;
30
+ /** Opens the preview view; when omitted the toolbar Preview button is hidden. */
31
+ onPreview?: () => void;
32
+ /** Notifies the host when the unsaved-changes state flips (for nav guards). */
33
+ onDirtyChange?: (isDirty: boolean) => void;
28
34
  /** Show the Publish button in the toolbar. Default: true */
29
35
  showPublishButton?: boolean;
30
36
  /** Debounce delay for auto-save in ms. Default: 1500 */
@@ -48,7 +54,9 @@ declare const defaultPuckConfig: Config;
48
54
 
49
55
  interface HeroProps {
50
56
  heading: string;
57
+ headingFontSize?: string;
51
58
  subheading?: string;
59
+ subheadingFontSize?: string;
52
60
  backgroundImage?: string;
53
61
  ctaText?: string;
54
62
  ctaUrl?: string;
@@ -65,11 +73,32 @@ interface RichTextProps {
65
73
  }
66
74
  declare const RichText: ComponentConfig<RichTextProps>;
67
75
 
76
+ interface GridProps {
77
+ columnCount?: 1 | 2 | 3 | 4 | 5 | 6;
78
+ rowCount?: 1 | 2 | 3 | 4 | 5 | 6;
79
+ gap?: string;
80
+ padding?: string;
81
+ }
82
+ /**
83
+ * Grid — a layout container that lays out a `columnCount` × `rowCount` matrix
84
+ * of drop zones. Each cell is an independent Puck DropZone, so components can be
85
+ * dropped into any cell. (Renamed from "Columns"; rows added.)
86
+ *
87
+ * This render function is shared by the editor and the Puck renderer
88
+ * (puck-renderer runs the same config), so updating it here updates both.
89
+ */
90
+ declare const Grid: ComponentConfig<GridProps>;
91
+
68
92
  interface ColumnsProps {
69
93
  columnCount?: 2 | 3 | 4;
70
94
  gap?: string;
71
95
  padding?: string;
72
96
  }
97
+ /**
98
+ * @deprecated Use `Grid` instead (columns + rows). `Columns` is kept registered
99
+ * for backward compatibility so pages saved with the original component (and its
100
+ * `column-N` drop zones) keep rendering. Prefer Grid for new content.
101
+ */
73
102
  declare const Columns: ComponentConfig<ColumnsProps>;
74
103
 
75
104
  interface ImageProps {
@@ -89,6 +118,7 @@ interface ButtonProps {
89
118
  href?: string;
90
119
  variant?: 'primary' | 'secondary' | 'outline';
91
120
  size?: 'sm' | 'md' | 'lg';
121
+ fontSize?: string;
92
122
  align?: 'left' | 'center' | 'right';
93
123
  openInNewTab?: boolean;
94
124
  }
@@ -96,6 +126,7 @@ declare const Button: ComponentConfig<ButtonProps>;
96
126
 
97
127
  interface CardProps {
98
128
  title: string;
129
+ titleFontSize?: string;
99
130
  body?: string;
100
131
  imageUrl?: string;
101
132
  ctaText?: string;
@@ -125,7 +156,15 @@ interface DatasourceFieldProps {
125
156
  }
126
157
  declare const DatasourceField: React.FC<DatasourceFieldProps>;
127
158
 
128
- interface ProductTeaserProps {
159
+ /** How a product link is built — from the product slug or its SKU. */
160
+ type ProductLinkWith = 'slug' | 'sku';
161
+ /** Props every product-linking component shares. */
162
+ interface ProductLinkProps {
163
+ linkWith: ProductLinkWith;
164
+ baseUrl: string;
165
+ }
166
+
167
+ interface ProductTeaserProps extends ProductLinkProps {
129
168
  datasource: DatasourceValue;
130
169
  richText: string;
131
170
  }
@@ -186,7 +225,7 @@ interface CountdownBannerProps {
186
225
  }
187
226
  declare const CountdownBanner: ComponentConfig<CountdownBannerProps>;
188
227
 
189
- interface CrossSellBlockProps {
228
+ interface CrossSellBlockProps extends ProductLinkProps {
190
229
  title: string;
191
230
  products: DatasourceValue;
192
231
  ctaText: string;
@@ -249,7 +288,7 @@ interface NewsletterSignupProps {
249
288
  }
250
289
  declare const NewsletterSignup: ComponentConfig<NewsletterSignupProps>;
251
290
 
252
- interface ProductBannerProps {
291
+ interface ProductBannerProps extends ProductLinkProps {
253
292
  title: string;
254
293
  description: string;
255
294
  ctaText: string;
@@ -266,7 +305,7 @@ interface ProductGridHeaderProps {
266
305
  }
267
306
  declare const ProductGridHeader: ComponentConfig<ProductGridHeaderProps>;
268
307
 
269
- interface ProductSliderProps {
308
+ interface ProductSliderProps extends ProductLinkProps {
270
309
  title: string;
271
310
  subtitle: string;
272
311
  products: DatasourceValue;
@@ -283,7 +322,7 @@ interface PromotionalBannerProps {
283
322
  }
284
323
  declare const PromotionalBanner: ComponentConfig<PromotionalBannerProps>;
285
324
 
286
- interface RelatedProductsSliderProps {
325
+ interface RelatedProductsSliderProps extends ProductLinkProps {
287
326
  title: string;
288
327
  subtitle: string;
289
328
  products: DatasourceValue;
@@ -364,17 +403,135 @@ interface ImagePickerFieldProps {
364
403
  }
365
404
  declare const ImagePickerField: React.FC<ImagePickerFieldProps>;
366
405
 
406
+ interface RichTextFieldProps {
407
+ /** HTML string. */
408
+ value: string | undefined;
409
+ onChange: (value: string) => void;
410
+ }
411
+ declare const RichTextField: React.FC<RichTextFieldProps>;
412
+ /**
413
+ * Puck `custom` field config that renders a rich-text editor (HTML in / out).
414
+ * Use in a component's `fields` for any prop that holds an HTML string, e.g.
415
+ * fields: { body: richTextField('Body') }
416
+ */
417
+ declare const richTextField: (label: string) => CustomField<string>;
418
+
419
+ /**
420
+ * Sanitize rich-text HTML before it is injected via dangerouslySetInnerHTML.
421
+ *
422
+ * RichText/TextBlock/Card store author-controlled HTML produced by the TipTap
423
+ * editor, but content can also arrive from imports or older data, so we always
424
+ * sanitize at render time. isomorphic-dompurify works in both the browser and
425
+ * during SSR, so this is safe wherever the renderer runs.
426
+ *
427
+ * `style` and `class` are allowed because the editor emits inline styles
428
+ * (e.g. font-size from the typography control) and structural classes.
429
+ */
430
+ declare const sanitizeHtml: (html: string | undefined | null) => string;
431
+
367
432
  interface EditorToolbarProps {
433
+ /** Page / content name shown centred in the bar. */
434
+ title: string;
368
435
  saving: boolean;
369
436
  isDirty: boolean;
370
437
  states: PuckStateInfo;
371
438
  onSave: () => void;
372
439
  onPublish: () => void;
373
440
  onRevert: () => void;
441
+ /** When provided, renders a Preview button that opens the preview view. */
442
+ onPreview?: () => void;
443
+ /** When provided, adds a "Create a template from this…" overflow-menu item. */
444
+ onCreateTemplate?: () => void;
445
+ /** Label for the create-template menu item. */
446
+ createTemplateLabel?: string;
374
447
  showPublishButton: boolean;
375
448
  }
449
+ /**
450
+ * Full replacement for Puck's header (wired via the `header` override).
451
+ *
452
+ * Layout: undo/redo + panel toggle on the left, the document name with its
453
+ * status badges centred, and the Save / Publish / Preview actions plus an
454
+ * overflow menu (version history, revert) on the right.
455
+ */
376
456
  declare const EditorToolbar: React.FC<EditorToolbarProps>;
377
457
 
458
+ interface UnsavedChangesDialogProps {
459
+ /** Whether the dialog is visible. */
460
+ isOpen: boolean;
461
+ /** Called when the dialog requests to open/close (backdrop, Esc, Stay). */
462
+ onOpenChange: (isOpen: boolean) => void;
463
+ /** Called when the user confirms they want to leave and discard changes. */
464
+ onConfirm: () => void;
465
+ }
466
+ /**
467
+ * Nimbus confirmation shown when the user tries to navigate away from an editor
468
+ * that has unsaved changes. Replaces the native `window.confirm` so the warning
469
+ * matches the rest of the editor chrome.
470
+ */
471
+ declare const UnsavedChangesDialog: React.FC<UnsavedChangesDialogProps>;
472
+
473
+ interface CreateTemplateDialogProps {
474
+ /** Whether the dialog is visible. */
475
+ isOpen: boolean;
476
+ /** Called when the dialog requests to open/close (backdrop, Esc, Cancel). */
477
+ onOpenChange: (isOpen: boolean) => void;
478
+ /**
479
+ * Called when the user confirms. `withoutData` reflects the
480
+ * "Create template without data" checkbox (default checked).
481
+ */
482
+ onConfirm: (name: string, withoutData: boolean) => void | Promise<void>;
483
+ /** Disables the form while the template is being created. */
484
+ saving?: boolean;
485
+ }
486
+ /**
487
+ * Nimbus dialog for "Create a template from this page/content". Collects a
488
+ * template name and whether to strip component data before saving.
489
+ */
490
+ declare const CreateTemplateDialog: React.FC<CreateTemplateDialogProps>;
491
+
492
+ /**
493
+ * Produce a "without data" copy of Puck data for use as a template.
494
+ *
495
+ * Each **leaf** component's props are reset to its config `defaultProps` (so a
496
+ * new page created from the template shows the component's default contents,
497
+ * not the source page's data). **Container** components — those that hold child
498
+ * components in a zone — keep their props, so structural fields (e.g. a Grid's
499
+ * `columnCount`) survive and the nested layout renders correctly.
500
+ *
501
+ * Nested components live in a flat `data.zones` map keyed `"<parentId>:<zone>"`;
502
+ * `<parentId>` is the parent component's `props.id`. Every component's
503
+ * `props.id` is always preserved so those zone keys stay consistent.
504
+ */
505
+ declare function stripPuckDataToTemplate(data: Data, config: Config): Data;
506
+
507
+ interface DirtyState {
508
+ /** True when the canvas differs from the last saved / loaded baseline. */
509
+ isDirty: boolean;
510
+ /**
511
+ * Feed every Puck `onChange` payload through this. The very first call after
512
+ * a (re)load establishes the baseline and is treated as "clean" — Puck emits
513
+ * an `onChange` on mount while it normalises the incoming data, and that must
514
+ * not be mistaken for an edit by the user.
515
+ */
516
+ markChange: (data: unknown) => void;
517
+ /** Mark the current data as the saved baseline (call after a successful save). */
518
+ markSaved: (data: unknown) => void;
519
+ }
520
+ /**
521
+ * Tracks whether the Puck canvas has unsaved edits.
522
+ *
523
+ * Puck is an uncontrolled editor that fires `onChange` once on mount (to report
524
+ * its normalised version of the initial data). Naively flagging the editor
525
+ * dirty on the first `onChange` makes a freshly-opened page look "Unsaved" even
526
+ * though nothing was touched. We instead capture that first payload as the
527
+ * baseline and only flag dirty when a later payload diverges from it.
528
+ *
529
+ * `resetKey` should change whenever the document shown in the canvas is swapped
530
+ * out (different page/content, or a historical version applied) so a new
531
+ * baseline is captured for the new document.
532
+ */
533
+ declare const useDirtyState: (resetKey: string) => DirtyState;
534
+
378
535
  declare const ComponentSearchProvider: React.FC<{
379
536
  children: ReactNode;
380
537
  }>;
@@ -386,4 +543,25 @@ declare const ComponentItemFilter: React.FC<{
386
543
  name: string;
387
544
  }>;
388
545
 
389
- export { Button, type ButtonProps, Card, type CardProps, CategoryGrid, type CategoryGridProps, CategoryHero, type CategoryHeroProps, CheckoutPromoBanner, type CheckoutPromoBannerProps, Columns, type ColumnsProps, ComponentItemFilter, ComponentSearchProvider, ComponentsPanel, CountdownBanner, type CountdownBannerProps, CrossSellBlock, type CrossSellBlockProps, DatasourceField, type DatasourceFieldProps, type DatasourceType, type DatasourceValue, DeliveryMessage, type DeliveryMessageProps, Divider, type DividerProps, EditorToolbar, type EditorToolbarProps, EmptyState, type EmptyStateProps, FAQAccordion, type FAQAccordionProps, FooterBlock, type FooterBlockProps, Hero, HeroBanner, type HeroBannerProps, type HeroProps, Image, ImageBlock, type ImageBlockProps, ImagePickerField, type ImagePickerFieldProps, type ImageProps, NewsletterSignup, type NewsletterSignupProps, ProductBanner, type ProductBannerProps, ProductGridHeader, type ProductGridHeaderProps, ProductSlider, type ProductSliderProps, ProductTeaser, type ProductTeaserProps, PromotionalBanner, type PromotionalBannerProps, PuckEditor, type PuckEditorProps, RelatedProductsSlider, type RelatedProductsSliderProps, RichText, type RichTextProps, SocialLinks, type SocialLinksProps, Spacer, type SpacerProps, TabContent, type TabContentProps, TestimonialsSlider, type TestimonialsSliderProps, TextBlock, type TextBlockProps, ThankYouContent, type ThankYouContentProps, TrustBadges, type TrustBadgesProps, VideoBlock, type VideoBlockProps, WebsiteLogo, type WebsiteLogoProps, defaultPuckConfig };
546
+ declare const nimbusFieldTypes: NonNullable<Overrides['fieldTypes']>;
547
+
548
+ interface PropertiesResizerProps {
549
+ /** Smallest allowed width in px. */
550
+ minWidth?: number;
551
+ /** Largest allowed width in px. */
552
+ maxWidth?: number;
553
+ }
554
+ /**
555
+ * Draggable divider that resizes the Puck properties (right) panel.
556
+ *
557
+ * Render it as a child of the `.puck-editor-fill` container (a sibling of the
558
+ * Puck editor). It writes the chosen width to a `--puck-properties-width` CSS
559
+ * variable on that container — the grid-template override in
560
+ * ComponentListSearch's injected `<style>` reads it to size only the right
561
+ * column, leaving the left panel and canvas alone. The handle is positioned
562
+ * over the panel's left edge by measuring the live sidebar, and hides itself
563
+ * when the panel is collapsed. The width persists in localStorage.
564
+ */
565
+ declare const PropertiesResizer: React.FC<PropertiesResizerProps>;
566
+
567
+ export { Button, type ButtonProps, Card, type CardProps, CategoryGrid, type CategoryGridProps, CategoryHero, type CategoryHeroProps, CheckoutPromoBanner, type CheckoutPromoBannerProps, Columns, type ColumnsProps, ComponentItemFilter, ComponentSearchProvider, ComponentsPanel, CountdownBanner, type CountdownBannerProps, CreateTemplateDialog, type CreateTemplateDialogProps, CrossSellBlock, type CrossSellBlockProps, DatasourceField, type DatasourceFieldProps, type DatasourceType, type DatasourceValue, DeliveryMessage, type DeliveryMessageProps, type DirtyState, Divider, type DividerProps, EditorToolbar, type EditorToolbarProps, EmptyState, type EmptyStateProps, FAQAccordion, type FAQAccordionProps, FooterBlock, type FooterBlockProps, Grid, type GridProps, Hero, HeroBanner, type HeroBannerProps, type HeroProps, Image, ImageBlock, type ImageBlockProps, ImagePickerField, type ImagePickerFieldProps, type ImageProps, NewsletterSignup, type NewsletterSignupProps, ProductBanner, type ProductBannerProps, ProductGridHeader, type ProductGridHeaderProps, ProductSlider, type ProductSliderProps, ProductTeaser, type ProductTeaserProps, PromotionalBanner, type PromotionalBannerProps, PropertiesResizer, type PropertiesResizerProps, PuckEditor, type PuckEditorProps, RelatedProductsSlider, type RelatedProductsSliderProps, RichText, RichTextField, type RichTextFieldProps, type RichTextProps, SocialLinks, type SocialLinksProps, Spacer, type SpacerProps, TabContent, type TabContentProps, TestimonialsSlider, type TestimonialsSliderProps, TextBlock, type TextBlockProps, ThankYouContent, type ThankYouContentProps, TrustBadges, type TrustBadgesProps, UnsavedChangesDialog, type UnsavedChangesDialogProps, VideoBlock, type VideoBlockProps, WebsiteLogo, type WebsiteLogoProps, defaultPuckConfig, nimbusFieldTypes, richTextField, sanitizeHtml, stripPuckDataToTemplate, useDirtyState };