@lit-pigeon/editor 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,839 @@
1
+ import { AssetManagerConfig } from '@lit-pigeon/core';
2
+ import { AssetStorage } from '@lit-pigeon/core';
3
+ import { ButtonBlock } from '@lit-pigeon/core';
4
+ import { ColumnNode } from '@lit-pigeon/core';
5
+ import { CSSResult } from 'lit';
6
+ import { DividerBlock } from '@lit-pigeon/core';
7
+ import { EditorConfig } from '@lit-pigeon/core';
8
+ import { HeroBlock } from '@lit-pigeon/core';
9
+ import { HtmlBlock } from '@lit-pigeon/core';
10
+ import { ImageBlock } from '@lit-pigeon/core';
11
+ import { LitElement } from 'lit';
12
+ import { MergeTag } from '@lit-pigeon/core';
13
+ import { NavBarBlock } from '@lit-pigeon/core';
14
+ import { PigeonDocument } from '@lit-pigeon/core';
15
+ import { Renderer } from '@lit-pigeon/core';
16
+ import { RowNode } from '@lit-pigeon/core';
17
+ import { Selection as Selection_2 } from '@lit-pigeon/core';
18
+ import { SocialBlock } from '@lit-pigeon/core';
19
+ import { SpacerBlock } from '@lit-pigeon/core';
20
+ import { Spacing } from '@lit-pigeon/core';
21
+ import { TemplateResult } from 'lit';
22
+ import { TemplateStorage } from '@lit-pigeon/core';
23
+ import { TextBlock } from '@lit-pigeon/core';
24
+
25
+ /**
26
+ * Given a Y coordinate and a list of block elements within a column,
27
+ * determine which block gap the cursor is closest to.
28
+ */
29
+ export declare function calculateBlockDropIndex(clientY: number, blockElements: HTMLElement[]): number;
30
+
31
+ /**
32
+ * Given a Y coordinate and a list of row elements, determine
33
+ * which row gap the cursor is closest to.
34
+ */
35
+ export declare function calculateRowDropIndex(clientY: number, rowElements: HTMLElement[]): number;
36
+
37
+ export declare function clearDragData(): void;
38
+
39
+ export declare interface DragData {
40
+ type: DragItemType;
41
+ /** Block type for palette-block drags (e.g. 'text', 'image') */
42
+ blockType?: string;
43
+ /** Number of columns for palette-row drags */
44
+ columnCount?: number;
45
+ /** Existing block info for rearranging */
46
+ blockId?: string;
47
+ rowId?: string;
48
+ columnId?: string;
49
+ }
50
+
51
+ /**
52
+ * Drag-and-drop manager using native HTML5 drag/drop API.
53
+ * Stores drag state globally so any component can query it.
54
+ */
55
+ export declare type DragItemType = 'palette-block' | 'palette-row' | 'existing-block' | 'existing-row';
56
+
57
+ /**
58
+ * Drop-zone calculation utilities.
59
+ * Given a mouse position and the set of rendered rows/columns/blocks,
60
+ * determines where the dragged item should be inserted.
61
+ */
62
+ export declare interface DropTarget {
63
+ /** 'row' means inserting a new row between existing rows */
64
+ zone: 'row' | 'block';
65
+ /** Index to insert the row at (for zone=row) */
66
+ rowIndex?: number;
67
+ /** IDs for block drops */
68
+ rowId?: string;
69
+ columnId?: string;
70
+ /** Index within the column's block list */
71
+ blockIndex?: number;
72
+ }
73
+
74
+ export declare function getDragData(): DragData | null;
75
+
76
+ export declare class PigeonAlignmentPicker extends LitElement {
77
+ label: string;
78
+ value: 'left' | 'center' | 'right';
79
+ static styles: CSSResult;
80
+ render(): TemplateResult<1>;
81
+ private _select;
82
+ }
83
+
84
+ export declare class PigeonAssetManager extends LitElement {
85
+ config: AssetManagerConfig;
86
+ /**
87
+ * Optional asset library. When set, the modal shows a "Library" tab where
88
+ * users browse and pick previously-saved assets; folders, search, and tag
89
+ * filters all run through `AssetStorage.list()`.
90
+ */
91
+ storage?: AssetStorage;
92
+ open: boolean;
93
+ /**
94
+ * Explicit tab selection — `null` means "use the default for the current
95
+ * storage state" (library when a storage is attached, upload otherwise).
96
+ * Updating only when the user explicitly clicks a tab keeps Lit's update
97
+ * cycle out of an update→state→update loop on initial property arrival.
98
+ */
99
+ private _tab;
100
+ private _dragOver;
101
+ private _uploading;
102
+ private _progress;
103
+ private _error;
104
+ private _urlInput;
105
+ /** Library state. */
106
+ private _folder;
107
+ private _search;
108
+ private _selectedTags;
109
+ private _folders;
110
+ private _assets;
111
+ private _libraryLoading;
112
+ private _libraryError;
113
+ private _searchTimer;
114
+ /**
115
+ * Monotonic token for in-flight library queries. The latest token wins so
116
+ * a slow folder switch can't overwrite a faster subsequent search.
117
+ */
118
+ private _libraryToken;
119
+ static styles: CSSResult;
120
+ updated(changed: Map<string, unknown>): void;
121
+ private get _activeTab();
122
+ render(): TemplateResult<1>;
123
+ private _renderTabs;
124
+ private _renderLibrary;
125
+ private _renderAssetCard;
126
+ private _renderUpload;
127
+ private _loadFolders;
128
+ private _loadAssets;
129
+ /** Distinct tags surfaced by the *current* result set. */
130
+ private get _availableTags();
131
+ private _onFolderChange;
132
+ private _onSearchInput;
133
+ private _toggleTag;
134
+ private get _acceptedTypes();
135
+ private _close;
136
+ private _openFilePicker;
137
+ private _onDragOver;
138
+ private _onDragLeave;
139
+ private _onDrop;
140
+ private _onFileSelected;
141
+ private _handleFile;
142
+ private _useUrl;
143
+ private _selectAsset;
144
+ }
145
+
146
+ export declare class PigeonBodyPanel extends LitElement {
147
+ doc: PigeonDocument;
148
+ mergeTags: MergeTag[];
149
+ private _pickerOpen;
150
+ private _pickerX;
151
+ private _pickerY;
152
+ private _previewInputRef;
153
+ private _triggerRef;
154
+ static styles: CSSResult[];
155
+ private _fontFamilies;
156
+ render(): TemplateResult<1>;
157
+ private _togglePicker;
158
+ private _onMergeTagInsert;
159
+ private _emit;
160
+ private _onWidthChange;
161
+ private _onBgColorChange;
162
+ private _onFontFamilyChange;
163
+ private _onAlignChange;
164
+ private _onNameChange;
165
+ private _onPreviewTextChange;
166
+ }
167
+
168
+ export declare class PigeonButtonBlock extends LitElement {
169
+ block: ButtonBlock;
170
+ selected: boolean;
171
+ editing: boolean;
172
+ private _editor;
173
+ private _editorHost;
174
+ static styles: CSSResult;
175
+ render(): TemplateResult<1>;
176
+ updated(changed: Map<string, unknown>): void;
177
+ disconnectedCallback(): void;
178
+ private _mountEditor;
179
+ private _teardownEditor;
180
+ private _commit;
181
+ private _exit;
182
+ private _preventNav;
183
+ private _handleClick;
184
+ private _handleDblClick;
185
+ }
186
+
187
+ export declare class PigeonButtonPanel extends LitElement {
188
+ block: ButtonBlock;
189
+ rowId: string;
190
+ columnId: string;
191
+ static styles: CSSResult[];
192
+ render(): TemplateResult<1>;
193
+ private _emit;
194
+ private _onTextChange;
195
+ private _contentToText;
196
+ private _onHrefChange;
197
+ private _onBgColorChange;
198
+ private _onTextColorChange;
199
+ private _onBorderRadiusChange;
200
+ private _onFontSizeChange;
201
+ private _onFontWeightChange;
202
+ private _onAlignChange;
203
+ private _onFullWidthChange;
204
+ private _onPaddingChange;
205
+ private _onInnerPaddingChange;
206
+ }
207
+
208
+ export declare class PigeonCanvas extends LitElement {
209
+ doc: PigeonDocument;
210
+ selection: Selection_2 | null;
211
+ editingBlockId: string | null;
212
+ previewWidth: number;
213
+ /**
214
+ * Active device preset. Drives the device-frame chrome around the canvas;
215
+ * `desktop` shows no frame, `tablet`/`mobile` wrap the sheet in a bezel.
216
+ */
217
+ device: 'desktop' | 'tablet' | 'mobile';
218
+ private _rowDropIndex;
219
+ private _isDragOver;
220
+ static styles: CSSResult;
221
+ render(): TemplateResult<1>;
222
+ /**
223
+ * The email "sheet" — the canvas-area and its rows. Rendered standalone on
224
+ * desktop, or nested inside a device frame for tablet/mobile. When framed,
225
+ * `bg` paints the document background onto the sheet itself (the area behind
226
+ * the frame stays neutral).
227
+ */
228
+ private _renderCanvasArea;
229
+ private _onCanvasClick;
230
+ private _onDragOver;
231
+ private _onDragLeave;
232
+ private _onDrop;
233
+ private _resetDragState;
234
+ }
235
+
236
+ export declare class PigeonColorPicker extends LitElement {
237
+ label: string;
238
+ value: string;
239
+ static styles: CSSResult;
240
+ render(): TemplateResult<1>;
241
+ private _onColorInput;
242
+ private _onTextChange;
243
+ private _emitChange;
244
+ }
245
+
246
+ export declare class PigeonColumn extends LitElement {
247
+ column: ColumnNode;
248
+ rowId: string;
249
+ selection: Selection_2 | null;
250
+ editingBlockId: string | null;
251
+ private _dropIndex;
252
+ private _isDragOver;
253
+ static styles: CSSResult;
254
+ render(): TemplateResult<1>;
255
+ private _renderBlock;
256
+ /**
257
+ * Render a registry-defined custom block. If its definition supplies a
258
+ * `renderCanvas` hook, its HTML is shown; otherwise we render a labelled
259
+ * placeholder so the block is still visible and selectable instead of
260
+ * failing with "Unknown block type".
261
+ */
262
+ private _renderCustomBlock;
263
+ private _onCustomBlockClick;
264
+ private _onDragOver;
265
+ private _onDragLeave;
266
+ private _onDrop;
267
+ }
268
+
269
+ export declare class PigeonDividerBlock extends LitElement {
270
+ block: DividerBlock;
271
+ selected: boolean;
272
+ static styles: CSSResult;
273
+ render(): TemplateResult<1>;
274
+ private _handleClick;
275
+ }
276
+
277
+ export declare class PigeonDropIndicator extends LitElement {
278
+ visible: boolean;
279
+ static styles: CSSResult;
280
+ render(): TemplateResult<1>;
281
+ }
282
+
283
+ /**
284
+ * `<pigeon-editor>` -- the main shell component for the Pigeon email editor.
285
+ *
286
+ * @element pigeon-editor
287
+ * @fires pigeon:change - Fired whenever the document changes
288
+ * @fires pigeon:select - Fired when the selection changes
289
+ * @fires pigeon:ready - Fired once after the editor has initialised
290
+ * @fires pigeon:preview - Fired when the user clicks Preview in the toolbar
291
+ * @fires pigeon:export - Fired when the user clicks Export in the toolbar
292
+ * @fires pigeon:export-json - Fired for JSON export
293
+ * @fires pigeon:export-mjml - Fired for MJML export
294
+ * @fires pigeon:export-html - Fired for HTML export
295
+ * @fires pigeon:merge-tag-request - Fired when merge tag trigger detected but no static tags
296
+ *
297
+ * @csspart toolbar - The toolbar area
298
+ * @csspart palette - The left palette area
299
+ * @csspart canvas - The central canvas area
300
+ * @csspart properties - The right property panel area
301
+ * @csspart canvas-area - The email "sheet" inside the canvas (the rendered body)
302
+ * @csspart panel - The active property-panel wrapper
303
+ * @csspart palette-tab - A palette tab button (Content / Layers)
304
+ * @csspart palette-item - A draggable block/layout chip in the palette
305
+ * @csspart toolbar-button - Any toolbar button; also has a per-action part:
306
+ * toolbar-button-{undo,redo,fullscreen,templates,preview,export}
307
+ *
308
+ * @cssprop [--pigeon-primary] - Brand / primary action colour
309
+ * @cssprop [--pigeon-bg] - Editor surface background
310
+ * @cssprop [--pigeon-text] - Primary text colour
311
+ * @cssprop [--pigeon-border] - Hairline border colour
312
+ * @cssprop [--pigeon-ring] - Focus-ring colour
313
+ * @cssprop [--pigeon-radius] - Base corner radius
314
+ * (see src/themes/tokens.ts for the full token set)
315
+ */
316
+ export declare class PigeonEditor extends LitElement {
317
+ /** Optional initial document. If not set a blank document is created. */
318
+ document: PigeonDocument | undefined;
319
+ /**
320
+ * Colour theme for the editor chrome.
321
+ *
322
+ * - `light` (default) — light tokens.
323
+ * - `dark` — dark tokens applied unconditionally.
324
+ * - `auto` — follows the OS `prefers-color-scheme`.
325
+ *
326
+ * Reflected to an attribute so it can be set declaratively
327
+ * (`<pigeon-editor theme="dark">`). Override individual tokens with the
328
+ * `themeOverrides` map or plain CSS (`pigeon-editor { --pigeon-…: … }`).
329
+ */
330
+ theme: 'light' | 'dark' | 'auto';
331
+ /**
332
+ * Partial map of design-token overrides applied as inline custom properties
333
+ * on the host, e.g. `{ '--pigeon-primary': '#db2777' }`. Useful for
334
+ * white-labelling without writing CSS. Merged on top of the active theme.
335
+ */
336
+ themeOverrides: Record<string, string>;
337
+ /** Additional editor configuration passed to EditorState.create(). */
338
+ config: Partial<EditorConfig>;
339
+ /** Optional renderer for preview mode. */
340
+ renderer?: Renderer;
341
+ /** Optional function to convert document to MJML. */
342
+ documentToMjml?: (doc: PigeonDocument) => string;
343
+ /**
344
+ * Optional template storage backend. When unset, the editor falls back to
345
+ * an in-memory storage seeded with the starter templates so the picker is
346
+ * useful out of the box.
347
+ */
348
+ templateStorage?: TemplateStorage;
349
+ /**
350
+ * Optional asset library backend. When set, the asset modal shows a
351
+ * "Library" tab next to "Upload" so users can browse previously-saved
352
+ * assets (folders, search, tag filters) without re-uploading. Falls back to
353
+ * `config.assetStorage` if not set directly. Without either, the modal
354
+ * keeps its current upload-only behaviour.
355
+ */
356
+ assetStorage?: AssetStorage;
357
+ private _state;
358
+ private _canUndo;
359
+ private _canRedo;
360
+ private _device;
361
+ private _fullscreen;
362
+ private _previewOpen;
363
+ private _templatePickerOpen;
364
+ private _templatePickerLoaded;
365
+ /** Block currently in inline rich-text editing mode, or null when none. */
366
+ private _editingBlockId;
367
+ /** Lazily-initialised default template storage. */
368
+ private _defaultTemplateStorage?;
369
+ /** In-memory clipboard for Cmd/Ctrl+C / Cmd/Ctrl+V on blocks. */
370
+ private _clipboard;
371
+ static styles: CSSResult[];
372
+ connectedCallback(): void;
373
+ disconnectedCallback(): void;
374
+ updated(changed: Map<string, unknown>): void;
375
+ /**
376
+ * Sync the active `theme` to the host classes the token sheet keys off, and
377
+ * apply any `themeOverrides` as inline custom properties.
378
+ */
379
+ private _applyTheme;
380
+ firstUpdated(): void;
381
+ /** Returns the current PigeonDocument. */
382
+ getDocument(): PigeonDocument;
383
+ /** Replaces the document entirely (resets history). */
384
+ loadDocument(doc: PigeonDocument): void;
385
+ /** Undo the last change. */
386
+ undo(): boolean;
387
+ /** Redo the last undone change. */
388
+ redo(): boolean;
389
+ /** Export the document as JSON. */
390
+ exportJson(): PigeonDocument;
391
+ /** Export the document as MJML. Requires documentToMjml to be set. */
392
+ exportMjml(): string | null;
393
+ /** Export the document as HTML. Requires renderer to be set. */
394
+ exportHtml(): Promise<string | null>;
395
+ /** Set merge tags dynamically (for lazy loading). */
396
+ setMergeTags(tags: MergeTag[]): void;
397
+ render(): TemplateResult<1>;
398
+ private _resolveTemplateStorage;
399
+ private _handleTemplatesOpen;
400
+ private _handleTemplateLoad;
401
+ private _handleTemplateSave;
402
+ private _initState;
403
+ /** Central dispatch -- every mutation flows through here. */
404
+ private _dispatch;
405
+ private _syncHistoryFlags;
406
+ private _fireChange;
407
+ private _fireSelect;
408
+ private _handleUndo;
409
+ private _handleRedo;
410
+ private _handleDevice;
411
+ private _handleFullscreen;
412
+ private _handlePreview;
413
+ private _handleExportHtml;
414
+ private _handleExportMjml;
415
+ private _handleExportJson;
416
+ private _handleBlockEnterEdit;
417
+ private _handleBlockExitEdit;
418
+ private _handleBlockSelect;
419
+ private _handleRowSelect;
420
+ private _handleBodySelect;
421
+ private _handleRowMove;
422
+ private _handleRowDuplicate;
423
+ private _handleRowDelete;
424
+ /**
425
+ * Returns true if the event originates from a text-editing context
426
+ * (input, textarea, select, or contentEditable element), in which
427
+ * case shortcuts like Delete and Ctrl+Z should not hijack the keys.
428
+ * Uses composedPath so it works across shadow DOM boundaries.
429
+ */
430
+ private _isInTextInput;
431
+ private _handleKeyDown;
432
+ private _flattenBlockLocations;
433
+ private _moveBlockSelection;
434
+ private _moveRowSelection;
435
+ private _findBlock;
436
+ private _findBlockIndex;
437
+ private _handleRowDrop;
438
+ private _handleBlockDrop;
439
+ private _handleBlockDropNewRow;
440
+ /**
441
+ * Keyboard equivalent of dragging a palette item onto the canvas: append the
442
+ * block/layout to the end of the document. Keeps the palette operable
443
+ * without a pointer (WCAG 2.1 — keyboard accessible).
444
+ */
445
+ private _handlePaletteActivate;
446
+ private _handlePropertyChange;
447
+ private _handleRowPropertyChange;
448
+ private _handleRowLayoutChange;
449
+ private _handleBodyPropertyChange;
450
+ }
451
+
452
+ export declare class PigeonHeroBlock extends LitElement {
453
+ block: HeroBlock;
454
+ selected: boolean;
455
+ editing: boolean;
456
+ private _editor;
457
+ private _editorHost;
458
+ static styles: CSSResult;
459
+ render(): TemplateResult<1>;
460
+ updated(changed: Map<string, unknown>): void;
461
+ disconnectedCallback(): void;
462
+ private _mountEditor;
463
+ private _teardownEditor;
464
+ private _commit;
465
+ private _exit;
466
+ private _handleClick;
467
+ private _handleDblClick;
468
+ }
469
+
470
+ export declare class PigeonHeroPanel extends LitElement {
471
+ block: HeroBlock;
472
+ rowId: string;
473
+ columnId: string;
474
+ assetManagerConfig?: AssetManagerConfig;
475
+ assetStorage?: AssetStorage;
476
+ private _assetManagerOpen;
477
+ static styles: CSSResult[];
478
+ render(): TemplateResult<1>;
479
+ private _emit;
480
+ private _onBackgroundUrlChange;
481
+ private _onBackgroundPositionChange;
482
+ private _onModeChange;
483
+ private _onHeightChange;
484
+ private _onWidthChange;
485
+ private _onVerticalAlignChange;
486
+ private _onBgColorChange;
487
+ private _onContentChange;
488
+ private _onPaddingChange;
489
+ private _onInnerPaddingChange;
490
+ private _onBgAssetSelected;
491
+ }
492
+
493
+ export declare class PigeonHtmlBlock extends LitElement {
494
+ block: HtmlBlock;
495
+ selected: boolean;
496
+ static styles: CSSResult;
497
+ render(): TemplateResult<1>;
498
+ private _handleClick;
499
+ }
500
+
501
+ export declare class PigeonImageBlock extends LitElement {
502
+ block: ImageBlock;
503
+ selected: boolean;
504
+ static styles: CSSResult;
505
+ render(): TemplateResult<1>;
506
+ private _handleClick;
507
+ }
508
+
509
+ export declare class PigeonImagePanel extends LitElement {
510
+ block: ImageBlock;
511
+ rowId: string;
512
+ columnId: string;
513
+ assetManagerConfig?: AssetManagerConfig;
514
+ assetStorage?: AssetStorage;
515
+ private _assetManagerOpen;
516
+ static styles: CSSResult[];
517
+ render(): TemplateResult<1>;
518
+ private _emit;
519
+ private _onSrcChange;
520
+ private _onAltChange;
521
+ private _onWidthChange;
522
+ private _onAlignChange;
523
+ private _onBorderRadiusChange;
524
+ private _onHrefChange;
525
+ private _onPaddingChange;
526
+ private _openAssetManager;
527
+ private _onAssetSelected;
528
+ }
529
+
530
+ export declare class PigeonLayers extends LitElement {
531
+ doc?: PigeonDocument;
532
+ selection: Selection_2 | null;
533
+ static styles: CSSResult;
534
+ render(): TemplateResult<1>;
535
+ private _renderRow;
536
+ private _renderColumn;
537
+ private _renderBlock;
538
+ private _selectRow;
539
+ private _selectBlock;
540
+ }
541
+
542
+ export declare class PigeonMergeTagPicker extends LitElement {
543
+ tags: MergeTag[];
544
+ open: boolean;
545
+ x: number;
546
+ y: number;
547
+ private _search;
548
+ static styles: CSSResult;
549
+ render(): TemplateResult<1>;
550
+ private _getFilteredTags;
551
+ private _groupByCategory;
552
+ private _selectTag;
553
+ }
554
+
555
+ export declare class PigeonNavBarBlock extends LitElement {
556
+ block: NavBarBlock;
557
+ selected: boolean;
558
+ static styles: CSSResult;
559
+ render(): TemplateResult<1>;
560
+ private _preventNav;
561
+ private _handleClick;
562
+ }
563
+
564
+ export declare class PigeonNavBarPanel extends LitElement {
565
+ block: NavBarBlock;
566
+ rowId: string;
567
+ columnId: string;
568
+ static styles: CSSResult[];
569
+ render(): TemplateResult<1>;
570
+ private _emit;
571
+ private _addLink;
572
+ private _removeLink;
573
+ private _onLinkTextChange;
574
+ private _onLinkHrefChange;
575
+ private _onAlignChange;
576
+ private _onHamburgerChange;
577
+ private _onLinkColorChange;
578
+ private _onLinkFontSizeChange;
579
+ private _onLinkPaddingChange;
580
+ private _onPaddingChange;
581
+ }
582
+
583
+ export declare class PigeonPalette extends LitElement {
584
+ doc?: PigeonDocument;
585
+ selection: Selection_2 | null;
586
+ private _blockDefs;
587
+ private _activeTab;
588
+ static styles: CSSResult;
589
+ connectedCallback(): void;
590
+ render(): TemplateResult<1>;
591
+ private _renderContentTab;
592
+ private _renderLayersTab;
593
+ }
594
+
595
+ export declare class PigeonPaletteItem extends LitElement {
596
+ label: string;
597
+ icon: string;
598
+ /** 'palette-block' or 'palette-row' */
599
+ dragType: DragItemType;
600
+ /** Block type for blocks (e.g. 'text'), unused for rows */
601
+ blockType: string;
602
+ /** Number of columns for row items */
603
+ columnCount: number;
604
+ static styles: CSSResult;
605
+ render(): TemplateResult<1>;
606
+ private _onKeyDown;
607
+ private _onDragStart;
608
+ private _onDragEnd;
609
+ }
610
+
611
+ export declare class PigeonPreview extends LitElement {
612
+ renderer?: Renderer;
613
+ doc?: PigeonDocument;
614
+ documentToMjml?: (doc: PigeonDocument) => string;
615
+ open: boolean;
616
+ private _viewMode;
617
+ private _device;
618
+ private _htmlContent;
619
+ private _mjmlContent;
620
+ private _loading;
621
+ static styles: CSSResult;
622
+ connectedCallback(): void;
623
+ disconnectedCallback(): void;
624
+ /** Element focused before the dialog opened, restored on close. */
625
+ private _previouslyFocused;
626
+ updated(changed: Map<string, unknown>): Promise<void>;
627
+ private _onKeyDown;
628
+ /** The deepest focused element, descending through shadow roots. */
629
+ private _deepActiveElement;
630
+ /** Focusable controls inside the modal (the dialog's own chrome). */
631
+ private _focusable;
632
+ /** Keep Tab focus within the dialog (WCAG modal pattern). */
633
+ private _trapTab;
634
+ render(): TemplateResult<1>;
635
+ private _renderContent;
636
+ private _loadPreview;
637
+ private _setView;
638
+ private _close;
639
+ }
640
+
641
+ export declare class PigeonProperties extends LitElement {
642
+ doc: PigeonDocument;
643
+ selection: Selection_2 | null;
644
+ mergeTags: MergeTag[];
645
+ assetManagerConfig?: AssetManagerConfig;
646
+ assetStorage?: AssetStorage;
647
+ static styles: CSSResult;
648
+ render(): TemplateResult<1>;
649
+ private _renderBlockPanel;
650
+ private _findRow;
651
+ private _findBlock;
652
+ }
653
+
654
+ export declare class PigeonRow extends LitElement {
655
+ row: RowNode;
656
+ index: number;
657
+ totalRows: number;
658
+ selection: Selection_2 | null;
659
+ editingBlockId: string | null;
660
+ private _dragging;
661
+ static styles: CSSResult;
662
+ render(): TemplateResult<1>;
663
+ private _onRowClick;
664
+ private _onMoveUp;
665
+ private _onMoveDown;
666
+ private _onDuplicate;
667
+ private _onDelete;
668
+ private _onDragStart;
669
+ private _onDragEnd;
670
+ }
671
+
672
+ export declare class PigeonRowPanel extends LitElement {
673
+ row: RowNode;
674
+ static styles: CSSResult[];
675
+ private _layouts;
676
+ render(): TemplateResult<1>;
677
+ private _emitRowUpdate;
678
+ private _onLayoutSelect;
679
+ private _onBgColorChange;
680
+ private _onBgImageChange;
681
+ private _onFullWidthChange;
682
+ private _onPaddingChange;
683
+ private _onConditionChange;
684
+ }
685
+
686
+ export declare class PigeonSliderInput extends LitElement {
687
+ label: string;
688
+ value: number;
689
+ min: number;
690
+ max: number;
691
+ step: number;
692
+ unit: string;
693
+ static styles: CSSResult;
694
+ render(): TemplateResult<1>;
695
+ private _onSlider;
696
+ private _onNumber;
697
+ private _emitChange;
698
+ }
699
+
700
+ export declare class PigeonSocialBlock extends LitElement {
701
+ block: SocialBlock;
702
+ selected: boolean;
703
+ static styles: CSSResult;
704
+ render(): TemplateResult<1>;
705
+ private _preventNav;
706
+ private _handleClick;
707
+ }
708
+
709
+ export declare class PigeonSpacerBlock extends LitElement {
710
+ block: SpacerBlock;
711
+ selected: boolean;
712
+ static styles: CSSResult;
713
+ render(): TemplateResult<1>;
714
+ private _handleClick;
715
+ }
716
+
717
+ export declare class PigeonSpacingInput extends LitElement {
718
+ label: string;
719
+ value: Spacing;
720
+ static styles: CSSResult;
721
+ render(): TemplateResult<1>;
722
+ private _onChange;
723
+ }
724
+
725
+ /**
726
+ * `<pigeon-template-picker>` — modal for browsing/saving templates.
727
+ *
728
+ * @element pigeon-template-picker
729
+ * @fires template-load - `{ template: Template }` when a card is clicked.
730
+ * @fires template-save - `{ name, description, category }` on save form submit.
731
+ */
732
+ export declare class PigeonTemplatePicker extends LitElement {
733
+ /** Storage used to list templates. Required for the gallery to populate. */
734
+ storage?: TemplateStorage;
735
+ /** Toggles the modal visibility. */
736
+ open: boolean;
737
+ private _templates;
738
+ private _name;
739
+ private _description;
740
+ private _category;
741
+ private _formError;
742
+ static styles: CSSResult;
743
+ updated(changed: Map<string, unknown>): void;
744
+ /** Re-fetch templates from storage and re-render. */
745
+ refresh(): Promise<void>;
746
+ render(): TemplateResult<1>;
747
+ private _renderCard;
748
+ private _close;
749
+ private _onPick;
750
+ private _onSubmit;
751
+ }
752
+
753
+ export declare class PigeonTextBlock extends LitElement {
754
+ block: TextBlock;
755
+ selected: boolean;
756
+ /** When true, a TipTap editor is mounted inside this block. */
757
+ editing: boolean;
758
+ private _editor;
759
+ private _editorHost;
760
+ static styles: CSSResult;
761
+ render(): TemplateResult<1>;
762
+ updated(changed: Map<string, unknown>): void;
763
+ disconnectedCallback(): void;
764
+ private _mountEditor;
765
+ private _teardownEditor;
766
+ private _commit;
767
+ private _exit;
768
+ private _handleClick;
769
+ private _handleDblClick;
770
+ }
771
+
772
+ export declare class PigeonTextPanel extends LitElement {
773
+ block: TextBlock;
774
+ rowId: string;
775
+ columnId: string;
776
+ mergeTags: MergeTag[];
777
+ private _pickerOpen;
778
+ private _pickerX;
779
+ private _pickerY;
780
+ private _textareaRef;
781
+ private _triggerRef;
782
+ static styles: CSSResult[];
783
+ render(): TemplateResult<1>;
784
+ private _togglePicker;
785
+ private _onMergeTagInsert;
786
+ /** Strip `{{` and `}}` from a tag name string. */
787
+ private _extractTagName;
788
+ private _emit;
789
+ private _onContentChange;
790
+ private _onAlignChange;
791
+ private _onLineHeightChange;
792
+ private _onPaddingChange;
793
+ }
794
+
795
+ export declare class PigeonToolbar extends LitElement {
796
+ canUndo: boolean;
797
+ canRedo: boolean;
798
+ device: 'desktop' | 'tablet' | 'mobile';
799
+ fullscreen: boolean;
800
+ private _exportMenuOpen;
801
+ connectedCallback(): void;
802
+ static styles: CSSResult;
803
+ render(): TemplateResult<1>;
804
+ private _onUndo;
805
+ private _onRedo;
806
+ private _onDeviceChange;
807
+ private _onFullscreen;
808
+ private _onPreview;
809
+ private _onTemplates;
810
+ private _toggleExportMenu;
811
+ private _onExportHtml;
812
+ private _onExportMjml;
813
+ private _onExportJson;
814
+ }
815
+
816
+ /**
817
+ * Read drag data from the DataTransfer object.
818
+ * Falls back to the global store if DataTransfer is unavailable (dragover).
819
+ */
820
+ export declare function readDragTransfer(e: DragEvent): DragData | null;
821
+
822
+ export declare function setDragData(data: DragData): void;
823
+
824
+ /**
825
+ * Serialize drag data to the DataTransfer object for native DnD.
826
+ */
827
+ export declare function writeDragTransfer(e: DragEvent, data: DragData): void;
828
+
829
+ export { }
830
+
831
+
832
+ declare module '@tiptap/core' {
833
+ interface Commands<ReturnType> {
834
+ fontSize: {
835
+ setFontSize: (size: string) => ReturnType;
836
+ unsetFontSize: () => ReturnType;
837
+ };
838
+ }
839
+ }