@foliokit/cms-admin-ui 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/esm2022/index.js +14 -0
  2. package/esm2022/index.js.map +1 -1
  3. package/esm2022/lib/cms-admin-ui/cms-admin-ui.js +3 -3
  4. package/esm2022/lib/page-editor/about-editor-form.component.js +84 -0
  5. package/esm2022/lib/page-editor/about-editor-form.component.js.map +1 -0
  6. package/esm2022/lib/page-editor/links-editor-form.component.js +474 -0
  7. package/esm2022/lib/page-editor/links-editor-form.component.js.map +1 -0
  8. package/esm2022/lib/page-editor/page-editor-hero-image.component.js +216 -0
  9. package/esm2022/lib/page-editor/page-editor-hero-image.component.js.map +1 -0
  10. package/esm2022/lib/page-editor/page-editor.store.js +198 -0
  11. package/esm2022/lib/page-editor/page-editor.store.js.map +1 -0
  12. package/esm2022/lib/post-editor/post-editor-cover-image.component.js +251 -0
  13. package/esm2022/lib/post-editor/post-editor-cover-image.component.js.map +1 -0
  14. package/esm2022/lib/post-editor/post-editor-embedded-media-item.component.js +99 -0
  15. package/esm2022/lib/post-editor/post-editor-embedded-media-item.component.js.map +1 -0
  16. package/esm2022/lib/post-editor/post-editor-embedded-media.component.js +173 -0
  17. package/esm2022/lib/post-editor/post-editor-embedded-media.component.js.map +1 -0
  18. package/esm2022/lib/post-editor/post-editor-media-tab.component.js +23 -0
  19. package/esm2022/lib/post-editor/post-editor-media-tab.component.js.map +1 -0
  20. package/esm2022/lib/post-editor/post-editor.store.js +189 -0
  21. package/esm2022/lib/post-editor/post-editor.store.js.map +1 -0
  22. package/esm2022/lib/posts-list/posts-board.component.js +66 -0
  23. package/esm2022/lib/posts-list/posts-board.component.js.map +1 -0
  24. package/esm2022/lib/posts-list/posts-draft-column.component.js +71 -0
  25. package/esm2022/lib/posts-list/posts-draft-column.component.js.map +1 -0
  26. package/esm2022/lib/posts-list/posts-list.component.js +79 -0
  27. package/esm2022/lib/posts-list/posts-list.component.js.map +1 -0
  28. package/esm2022/lib/posts-list/posts-list.store.js +43 -0
  29. package/esm2022/lib/posts-list/posts-list.store.js.map +1 -0
  30. package/esm2022/lib/posts-list/posts-published-column.component.js +129 -0
  31. package/esm2022/lib/posts-list/posts-published-column.component.js.map +1 -0
  32. package/esm2022/lib/posts-list/posts-queue-column.component.js +112 -0
  33. package/esm2022/lib/posts-list/posts-queue-column.component.js.map +1 -0
  34. package/index.d.ts +14 -0
  35. package/lib/page-editor/about-editor-form.component.d.ts +32 -0
  36. package/lib/page-editor/links-editor-form.component.d.ts +52 -0
  37. package/lib/page-editor/page-editor-hero-image.component.d.ts +51 -0
  38. package/lib/page-editor/page-editor.store.d.ts +37 -0
  39. package/lib/post-editor/post-editor-cover-image.component.d.ts +50 -0
  40. package/lib/post-editor/post-editor-embedded-media-item.component.d.ts +37 -0
  41. package/lib/post-editor/post-editor-embedded-media.component.d.ts +43 -0
  42. package/lib/post-editor/post-editor-media-tab.component.d.ts +5 -0
  43. package/lib/post-editor/post-editor.store.d.ts +37 -0
  44. package/lib/posts-list/posts-board.component.d.ts +24 -0
  45. package/lib/posts-list/posts-draft-column.component.d.ts +8 -0
  46. package/lib/posts-list/posts-list.component.d.ts +28 -0
  47. package/lib/posts-list/posts-list.store.d.ts +24 -0
  48. package/lib/posts-list/posts-published-column.component.d.ts +10 -0
  49. package/lib/posts-list/posts-queue-column.component.d.ts +14 -0
  50. package/package.json +1 -1
@@ -0,0 +1,129 @@
1
+ import { ChangeDetectionStrategy, Component, input, output, signal, } from '@angular/core';
2
+ import { DatePipe } from '@angular/common';
3
+ import { MatCardModule } from '@angular/material/card';
4
+ import { MatButtonModule } from '@angular/material/button';
5
+ import { MatIconModule } from '@angular/material/icon';
6
+ import * as i0 from "@angular/core";
7
+ import * as i1 from "@angular/material/card";
8
+ import * as i2 from "@angular/material/button";
9
+ import * as i3 from "@angular/material/icon";
10
+ export class PostsPublishedColumnComponent {
11
+ posts = input.required(...(ngDevMode ? [{ debugName: "posts" }] : /* istanbul ignore next */ []));
12
+ archivedPosts = input.required(...(ngDevMode ? [{ debugName: "archivedPosts" }] : /* istanbul ignore next */ []));
13
+ postSelected = output();
14
+ showArchived = signal(false, ...(ngDevMode ? [{ debugName: "showArchived" }] : /* istanbul ignore next */ []));
15
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PostsPublishedColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
16
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: PostsPublishedColumnComponent, isStandalone: true, selector: "folio-posts-published-column", inputs: { posts: { classPropertyName: "posts", publicName: "posts", isSignal: true, isRequired: true, transformFunction: null }, archivedPosts: { classPropertyName: "archivedPosts", publicName: "archivedPosts", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { postSelected: "postSelected" }, host: { classAttribute: "contents" }, ngImport: i0, template: `
17
+ <mat-card appearance="outlined" class="flex flex-col overflow-hidden">
18
+ <div class="shrink-0 flex items-center gap-2 px-4 py-3 border-b border-[var(--mat-sys-outline-variant)]">
19
+ <span class="text-sm font-semibold">Published</span>
20
+ <span class="inline-flex items-center justify-center rounded-full bg-[var(--mat-sys-secondary-container)] text-[var(--mat-sys-on-secondary-container)] text-xs font-medium min-w-[1.25rem] h-5 px-1.5">
21
+ {{ posts().length }}
22
+ </span>
23
+ </div>
24
+
25
+ <div class="flex-1 overflow-y-auto divide-y divide-[var(--mat-sys-outline-variant)]">
26
+ @for (post of posts(); track post.id) {
27
+ <button
28
+ type="button"
29
+ class="w-full flex items-center justify-between gap-3 px-4 py-3 text-left hover:bg-[var(--mat-sys-surface-container-high)] transition-colors"
30
+ (click)="postSelected.emit(post.id)"
31
+ >
32
+ <span class="truncate text-sm font-medium">{{ post.title || '(Untitled)' }}</span>
33
+ <span class="shrink-0 text-xs opacity-50">{{ post.publishedAt | date: 'mediumDate' }}</span>
34
+ </button>
35
+ } @empty {
36
+ <div class="py-10 text-center text-sm opacity-40">No published posts</div>
37
+ }
38
+
39
+ @if (showArchived()) {
40
+ @for (post of archivedPosts(); track post.id) {
41
+ <button
42
+ type="button"
43
+ class="w-full flex items-center justify-between gap-3 px-4 py-3 text-left opacity-50 hover:opacity-70 transition-opacity"
44
+ (click)="postSelected.emit(post.id)"
45
+ >
46
+ <span class="truncate text-sm font-medium">{{ post.title || '(Untitled)' }}</span>
47
+ <span class="shrink-0 text-xs">{{ post.updatedAt | date: 'mediumDate' }}</span>
48
+ </button>
49
+ }
50
+ }
51
+ </div>
52
+
53
+ @if (archivedPosts().length > 0) {
54
+ <div class="shrink-0 border-t border-[var(--mat-sys-outline-variant)] px-4 py-2">
55
+ <button
56
+ mat-button
57
+ class="w-full text-xs"
58
+ (click)="showArchived.set(!showArchived())"
59
+ >
60
+ <mat-icon class="text-sm mr-1">{{ showArchived() ? 'expand_less' : 'expand_more' }}</mat-icon>
61
+ {{ showArchived() ? 'Hide archived' : 'Show archived (' + archivedPosts().length + ')' }}
62
+ </button>
63
+ </div>
64
+ }
65
+ </mat-card>
66
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
67
+ }
68
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PostsPublishedColumnComponent, decorators: [{
69
+ type: Component,
70
+ args: [{
71
+ selector: 'folio-posts-published-column',
72
+ standalone: true,
73
+ changeDetection: ChangeDetectionStrategy.OnPush,
74
+ imports: [DatePipe, MatCardModule, MatButtonModule, MatIconModule],
75
+ host: { class: 'contents' },
76
+ template: `
77
+ <mat-card appearance="outlined" class="flex flex-col overflow-hidden">
78
+ <div class="shrink-0 flex items-center gap-2 px-4 py-3 border-b border-[var(--mat-sys-outline-variant)]">
79
+ <span class="text-sm font-semibold">Published</span>
80
+ <span class="inline-flex items-center justify-center rounded-full bg-[var(--mat-sys-secondary-container)] text-[var(--mat-sys-on-secondary-container)] text-xs font-medium min-w-[1.25rem] h-5 px-1.5">
81
+ {{ posts().length }}
82
+ </span>
83
+ </div>
84
+
85
+ <div class="flex-1 overflow-y-auto divide-y divide-[var(--mat-sys-outline-variant)]">
86
+ @for (post of posts(); track post.id) {
87
+ <button
88
+ type="button"
89
+ class="w-full flex items-center justify-between gap-3 px-4 py-3 text-left hover:bg-[var(--mat-sys-surface-container-high)] transition-colors"
90
+ (click)="postSelected.emit(post.id)"
91
+ >
92
+ <span class="truncate text-sm font-medium">{{ post.title || '(Untitled)' }}</span>
93
+ <span class="shrink-0 text-xs opacity-50">{{ post.publishedAt | date: 'mediumDate' }}</span>
94
+ </button>
95
+ } @empty {
96
+ <div class="py-10 text-center text-sm opacity-40">No published posts</div>
97
+ }
98
+
99
+ @if (showArchived()) {
100
+ @for (post of archivedPosts(); track post.id) {
101
+ <button
102
+ type="button"
103
+ class="w-full flex items-center justify-between gap-3 px-4 py-3 text-left opacity-50 hover:opacity-70 transition-opacity"
104
+ (click)="postSelected.emit(post.id)"
105
+ >
106
+ <span class="truncate text-sm font-medium">{{ post.title || '(Untitled)' }}</span>
107
+ <span class="shrink-0 text-xs">{{ post.updatedAt | date: 'mediumDate' }}</span>
108
+ </button>
109
+ }
110
+ }
111
+ </div>
112
+
113
+ @if (archivedPosts().length > 0) {
114
+ <div class="shrink-0 border-t border-[var(--mat-sys-outline-variant)] px-4 py-2">
115
+ <button
116
+ mat-button
117
+ class="w-full text-xs"
118
+ (click)="showArchived.set(!showArchived())"
119
+ >
120
+ <mat-icon class="text-sm mr-1">{{ showArchived() ? 'expand_less' : 'expand_more' }}</mat-icon>
121
+ {{ showArchived() ? 'Hide archived' : 'Show archived (' + archivedPosts().length + ')' }}
122
+ </button>
123
+ </div>
124
+ }
125
+ </mat-card>
126
+ `,
127
+ }]
128
+ }], propDecorators: { posts: [{ type: i0.Input, args: [{ isSignal: true, alias: "posts", required: true }] }], archivedPosts: [{ type: i0.Input, args: [{ isSignal: true, alias: "archivedPosts", required: true }] }], postSelected: [{ type: i0.Output, args: ["postSelected"] }] } });
129
+ //# sourceMappingURL=posts-published-column.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"posts-published-column.component.js","sourceRoot":"","sources":["../../../../../../libs/cms-admin-ui/src/lib/posts-list/posts-published-column.component.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,SAAS,EACT,KAAK,EACL,MAAM,EACN,MAAM,GACP,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;;;;;AA6DvD,MAAM,OAAO,6BAA6B;IACxC,KAAK,GAAG,KAAK,CAAC,QAAQ,2EAAc,CAAC;IACrC,aAAa,GAAG,KAAK,CAAC,QAAQ,mFAAc,CAAC;IAC7C,YAAY,GAAG,MAAM,EAAU,CAAC;IAEb,YAAY,GAAG,MAAM,CAAC,KAAK,mFAAC,CAAC;uGALrC,6BAA6B;2FAA7B,6BAA6B,2bApD9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDT,2DApDmB,aAAa,4IAAE,eAAe,mXAAE,aAAa,+KAAvD,QAAQ;;2FAsDP,6BAA6B;kBA1DzC,SAAS;mBAAC;oBACT,QAAQ,EAAE,8BAA8B;oBACxC,UAAU,EAAE,IAAI;oBAChB,eAAe,EAAE,uBAAuB,CAAC,MAAM;oBAC/C,OAAO,EAAE,CAAC,QAAQ,EAAE,aAAa,EAAE,eAAe,EAAE,aAAa,CAAC;oBAClE,IAAI,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE;oBAC3B,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDT;iBACF","sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { DatePipe } from '@angular/common';\nimport { MatCardModule } from '@angular/material/card';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { BlogPost } from '@foliokit/cms-core';\n\n@Component({\n selector: 'folio-posts-published-column',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [DatePipe, MatCardModule, MatButtonModule, MatIconModule],\n host: { class: 'contents' },\n template: `\n <mat-card appearance=\"outlined\" class=\"flex flex-col overflow-hidden\">\n <div class=\"shrink-0 flex items-center gap-2 px-4 py-3 border-b border-[var(--mat-sys-outline-variant)]\">\n <span class=\"text-sm font-semibold\">Published</span>\n <span class=\"inline-flex items-center justify-center rounded-full bg-[var(--mat-sys-secondary-container)] text-[var(--mat-sys-on-secondary-container)] text-xs font-medium min-w-[1.25rem] h-5 px-1.5\">\n {{ posts().length }}\n </span>\n </div>\n\n <div class=\"flex-1 overflow-y-auto divide-y divide-[var(--mat-sys-outline-variant)]\">\n @for (post of posts(); track post.id) {\n <button\n type=\"button\"\n class=\"w-full flex items-center justify-between gap-3 px-4 py-3 text-left hover:bg-[var(--mat-sys-surface-container-high)] transition-colors\"\n (click)=\"postSelected.emit(post.id)\"\n >\n <span class=\"truncate text-sm font-medium\">{{ post.title || '(Untitled)' }}</span>\n <span class=\"shrink-0 text-xs opacity-50\">{{ post.publishedAt | date: 'mediumDate' }}</span>\n </button>\n } @empty {\n <div class=\"py-10 text-center text-sm opacity-40\">No published posts</div>\n }\n\n @if (showArchived()) {\n @for (post of archivedPosts(); track post.id) {\n <button\n type=\"button\"\n class=\"w-full flex items-center justify-between gap-3 px-4 py-3 text-left opacity-50 hover:opacity-70 transition-opacity\"\n (click)=\"postSelected.emit(post.id)\"\n >\n <span class=\"truncate text-sm font-medium\">{{ post.title || '(Untitled)' }}</span>\n <span class=\"shrink-0 text-xs\">{{ post.updatedAt | date: 'mediumDate' }}</span>\n </button>\n }\n }\n </div>\n\n @if (archivedPosts().length > 0) {\n <div class=\"shrink-0 border-t border-[var(--mat-sys-outline-variant)] px-4 py-2\">\n <button\n mat-button\n class=\"w-full text-xs\"\n (click)=\"showArchived.set(!showArchived())\"\n >\n <mat-icon class=\"text-sm mr-1\">{{ showArchived() ? 'expand_less' : 'expand_more' }}</mat-icon>\n {{ showArchived() ? 'Hide archived' : 'Show archived (' + archivedPosts().length + ')' }}\n </button>\n </div>\n }\n </mat-card>\n `,\n})\nexport class PostsPublishedColumnComponent {\n posts = input.required<BlogPost[]>();\n archivedPosts = input.required<BlogPost[]>();\n postSelected = output<string>();\n\n protected readonly showArchived = signal(false);\n}\n"]}
@@ -0,0 +1,112 @@
1
+ import { ChangeDetectionStrategy, Component, input, output } from '@angular/core';
2
+ import { DatePipe } from '@angular/common';
3
+ import { MatCardModule } from '@angular/material/card';
4
+ import { MatIconModule } from '@angular/material/icon';
5
+ import { CdkDrag, CdkDragHandle, CdkDragPlaceholder, CdkDropList, } from '@angular/cdk/drag-drop';
6
+ import * as i0 from "@angular/core";
7
+ import * as i1 from "@angular/material/card";
8
+ import * as i2 from "@angular/material/icon";
9
+ export class PostsQueueColumnComponent {
10
+ posts = input.required(...(ngDevMode ? [{ debugName: "posts" }] : /* istanbul ignore next */ []));
11
+ postSelected = output();
12
+ reorderQueue = output();
13
+ onDrop(event) {
14
+ this.reorderQueue.emit({
15
+ previousIndex: event.previousIndex,
16
+ currentIndex: event.currentIndex,
17
+ });
18
+ }
19
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PostsQueueColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
20
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: PostsQueueColumnComponent, isStandalone: true, selector: "folio-posts-queue-column", inputs: { posts: { classPropertyName: "posts", publicName: "posts", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { postSelected: "postSelected", reorderQueue: "reorderQueue" }, host: { classAttribute: "contents" }, ngImport: i0, template: `
21
+ <mat-card appearance="outlined" class="flex flex-col overflow-hidden">
22
+ <div class="shrink-0 flex items-center gap-2 px-4 py-3 border-b border-[var(--mat-sys-outline-variant)]">
23
+ <span class="text-sm font-semibold">Queued</span>
24
+ <span class="inline-flex items-center justify-center rounded-full bg-[var(--mat-sys-secondary-container)] text-[var(--mat-sys-on-secondary-container)] text-xs font-medium min-w-[1.25rem] h-5 px-1.5">
25
+ {{ posts().length }}
26
+ </span>
27
+ </div>
28
+
29
+ <div
30
+ class="post-list flex-1 overflow-y-auto divide-y divide-[var(--mat-sys-outline-variant)]"
31
+ cdkDropList
32
+ (cdkDropListDropped)="onDrop($event)"
33
+ >
34
+ @for (post of posts(); track post.id) {
35
+ <div class="post-row flex items-center gap-2 pr-4 hover:bg-[var(--mat-sys-surface-container-high)] transition-colors" cdkDrag>
36
+ <button
37
+ type="button"
38
+ class="flex items-center gap-1 px-2 py-3 cursor-grab active:cursor-grabbing text-[var(--mat-sys-outline)] hover:text-[var(--mat-sys-on-surface)] transition-colors"
39
+ cdkDragHandle
40
+ aria-label="Drag to reorder"
41
+ >
42
+ <mat-icon class="text-[1.1rem] leading-none">drag_indicator</mat-icon>
43
+ </button>
44
+
45
+ <button
46
+ type="button"
47
+ class="flex-1 flex items-center justify-between gap-3 py-3 text-left min-w-0"
48
+ (click)="postSelected.emit(post.id)"
49
+ >
50
+ <span class="truncate text-sm font-medium">{{ post.title || '(Untitled)' }}</span>
51
+ <span class="shrink-0 text-xs opacity-50">
52
+ {{ post.scheduledPublishAt | date: 'mediumDate' }}
53
+ </span>
54
+ </button>
55
+
56
+ <div *cdkDragPlaceholder class="h-12 rounded bg-[var(--mat-sys-surface-container)]"></div>
57
+ </div>
58
+ } @empty {
59
+ <div class="py-10 text-center text-sm opacity-40">No queued posts</div>
60
+ }
61
+ </div>
62
+ </mat-card>
63
+ `, isInline: true, styles: [".cdk-drag-preview{box-shadow:0 4px 12px #0003;border-radius:4px;background:var(--mat-sys-surface-container-high)}.cdk-drag-placeholder{opacity:.3}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.post-list.cdk-drop-list-dragging .post-row:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i1.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
64
+ }
65
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: PostsQueueColumnComponent, decorators: [{
66
+ type: Component,
67
+ args: [{ selector: 'folio-posts-queue-column', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [DatePipe, MatCardModule, MatIconModule, CdkDropList, CdkDrag, CdkDragHandle, CdkDragPlaceholder], host: { class: 'contents' }, template: `
68
+ <mat-card appearance="outlined" class="flex flex-col overflow-hidden">
69
+ <div class="shrink-0 flex items-center gap-2 px-4 py-3 border-b border-[var(--mat-sys-outline-variant)]">
70
+ <span class="text-sm font-semibold">Queued</span>
71
+ <span class="inline-flex items-center justify-center rounded-full bg-[var(--mat-sys-secondary-container)] text-[var(--mat-sys-on-secondary-container)] text-xs font-medium min-w-[1.25rem] h-5 px-1.5">
72
+ {{ posts().length }}
73
+ </span>
74
+ </div>
75
+
76
+ <div
77
+ class="post-list flex-1 overflow-y-auto divide-y divide-[var(--mat-sys-outline-variant)]"
78
+ cdkDropList
79
+ (cdkDropListDropped)="onDrop($event)"
80
+ >
81
+ @for (post of posts(); track post.id) {
82
+ <div class="post-row flex items-center gap-2 pr-4 hover:bg-[var(--mat-sys-surface-container-high)] transition-colors" cdkDrag>
83
+ <button
84
+ type="button"
85
+ class="flex items-center gap-1 px-2 py-3 cursor-grab active:cursor-grabbing text-[var(--mat-sys-outline)] hover:text-[var(--mat-sys-on-surface)] transition-colors"
86
+ cdkDragHandle
87
+ aria-label="Drag to reorder"
88
+ >
89
+ <mat-icon class="text-[1.1rem] leading-none">drag_indicator</mat-icon>
90
+ </button>
91
+
92
+ <button
93
+ type="button"
94
+ class="flex-1 flex items-center justify-between gap-3 py-3 text-left min-w-0"
95
+ (click)="postSelected.emit(post.id)"
96
+ >
97
+ <span class="truncate text-sm font-medium">{{ post.title || '(Untitled)' }}</span>
98
+ <span class="shrink-0 text-xs opacity-50">
99
+ {{ post.scheduledPublishAt | date: 'mediumDate' }}
100
+ </span>
101
+ </button>
102
+
103
+ <div *cdkDragPlaceholder class="h-12 rounded bg-[var(--mat-sys-surface-container)]"></div>
104
+ </div>
105
+ } @empty {
106
+ <div class="py-10 text-center text-sm opacity-40">No queued posts</div>
107
+ }
108
+ </div>
109
+ </mat-card>
110
+ `, styles: [".cdk-drag-preview{box-shadow:0 4px 12px #0003;border-radius:4px;background:var(--mat-sys-surface-container-high)}.cdk-drag-placeholder{opacity:.3}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.post-list.cdk-drop-list-dragging .post-row:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}\n"] }]
111
+ }], propDecorators: { posts: [{ type: i0.Input, args: [{ isSignal: true, alias: "posts", required: true }] }], postSelected: [{ type: i0.Output, args: ["postSelected"] }], reorderQueue: [{ type: i0.Output, args: ["reorderQueue"] }] } });
112
+ //# sourceMappingURL=posts-queue-column.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"posts-queue-column.component.js","sourceRoot":"","sources":["../../../../../../libs/cms-admin-ui/src/lib/posts-list/posts-queue-column.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EACL,OAAO,EAEP,aAAa,EACb,kBAAkB,EAClB,WAAW,GACZ,MAAM,wBAAwB,CAAC;;;;AAkEhC,MAAM,OAAO,yBAAyB;IACpC,KAAK,GAAG,KAAK,CAAC,QAAQ,2EAAc,CAAC;IACrC,YAAY,GAAG,MAAM,EAAU,CAAC;IAChC,YAAY,GAAG,MAAM,EAAmD,CAAC;IAE/D,MAAM,CAAC,KAA8B;QAC7C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;YACrB,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,YAAY,EAAE,KAAK,CAAC,YAAY;SACjC,CAAC,CAAC;IACL,CAAC;uGAVU,yBAAyB;2FAAzB,yBAAyB,sUA7C1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CT,0ZAzDmB,aAAa,4IAAE,aAAa,oLAAE,WAAW,shBAAE,OAAO,wcAAE,aAAa,+FAAE,kBAAkB,yFAA/F,QAAQ;;2FA2DP,yBAAyB;kBA/DrC,SAAS;+BACE,0BAA0B,cACxB,IAAI,mBACC,uBAAuB,CAAC,MAAM,WACtC,CAAC,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,kBAAkB,CAAC,QACpG,EAAE,KAAK,EAAE,UAAU,EAAE,YAajB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CT","sourcesContent":["import { ChangeDetectionStrategy, Component, input, output } from '@angular/core';\nimport { DatePipe } from '@angular/common';\nimport { MatCardModule } from '@angular/material/card';\nimport { MatIconModule } from '@angular/material/icon';\nimport {\n CdkDrag,\n CdkDragDrop,\n CdkDragHandle,\n CdkDragPlaceholder,\n CdkDropList,\n} from '@angular/cdk/drag-drop';\nimport { BlogPost } from '@foliokit/cms-core';\n\n@Component({\n selector: 'folio-posts-queue-column',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [DatePipe, MatCardModule, MatIconModule, CdkDropList, CdkDrag, CdkDragHandle, CdkDragPlaceholder],\n host: { class: 'contents' },\n styles: [`\n .cdk-drag-preview {\n box-shadow: 0 4px 12px rgba(0,0,0,0.2);\n border-radius: 4px;\n background: var(--mat-sys-surface-container-high);\n }\n .cdk-drag-placeholder { opacity: 0.3; }\n .cdk-drag-animating { transition: transform 250ms cubic-bezier(0,0,0.2,1); }\n .post-list.cdk-drop-list-dragging .post-row:not(.cdk-drag-placeholder) {\n transition: transform 250ms cubic-bezier(0,0,0.2,1);\n }\n `],\n template: `\n <mat-card appearance=\"outlined\" class=\"flex flex-col overflow-hidden\">\n <div class=\"shrink-0 flex items-center gap-2 px-4 py-3 border-b border-[var(--mat-sys-outline-variant)]\">\n <span class=\"text-sm font-semibold\">Queued</span>\n <span class=\"inline-flex items-center justify-center rounded-full bg-[var(--mat-sys-secondary-container)] text-[var(--mat-sys-on-secondary-container)] text-xs font-medium min-w-[1.25rem] h-5 px-1.5\">\n {{ posts().length }}\n </span>\n </div>\n\n <div\n class=\"post-list flex-1 overflow-y-auto divide-y divide-[var(--mat-sys-outline-variant)]\"\n cdkDropList\n (cdkDropListDropped)=\"onDrop($event)\"\n >\n @for (post of posts(); track post.id) {\n <div class=\"post-row flex items-center gap-2 pr-4 hover:bg-[var(--mat-sys-surface-container-high)] transition-colors\" cdkDrag>\n <button\n type=\"button\"\n class=\"flex items-center gap-1 px-2 py-3 cursor-grab active:cursor-grabbing text-[var(--mat-sys-outline)] hover:text-[var(--mat-sys-on-surface)] transition-colors\"\n cdkDragHandle\n aria-label=\"Drag to reorder\"\n >\n <mat-icon class=\"text-[1.1rem] leading-none\">drag_indicator</mat-icon>\n </button>\n\n <button\n type=\"button\"\n class=\"flex-1 flex items-center justify-between gap-3 py-3 text-left min-w-0\"\n (click)=\"postSelected.emit(post.id)\"\n >\n <span class=\"truncate text-sm font-medium\">{{ post.title || '(Untitled)' }}</span>\n <span class=\"shrink-0 text-xs opacity-50\">\n {{ post.scheduledPublishAt | date: 'mediumDate' }}\n </span>\n </button>\n\n <div *cdkDragPlaceholder class=\"h-12 rounded bg-[var(--mat-sys-surface-container)]\"></div>\n </div>\n } @empty {\n <div class=\"py-10 text-center text-sm opacity-40\">No queued posts</div>\n }\n </div>\n </mat-card>\n `,\n})\nexport class PostsQueueColumnComponent {\n posts = input.required<BlogPost[]>();\n postSelected = output<string>();\n reorderQueue = output<{ previousIndex: number; currentIndex: number }>();\n\n protected onDrop(event: CdkDragDrop<BlogPost[]>): void {\n this.reorderQueue.emit({\n previousIndex: event.previousIndex,\n currentIndex: event.currentIndex,\n });\n }\n}\n"]}
package/index.d.ts CHANGED
@@ -1 +1,15 @@
1
1
  export * from './lib/cms-admin-ui/cms-admin-ui';
2
+ export * from './lib/post-editor/post-editor.store';
3
+ export * from './lib/page-editor/page-editor.store';
4
+ export * from './lib/page-editor/about-editor-form.component';
5
+ export * from './lib/page-editor/links-editor-form.component';
6
+ export * from './lib/post-editor/post-editor-media-tab.component';
7
+ export * from './lib/post-editor/post-editor-cover-image.component';
8
+ export * from './lib/post-editor/post-editor-embedded-media.component';
9
+ export * from './lib/post-editor/post-editor-embedded-media-item.component';
10
+ export * from './lib/posts-list/posts-list.store';
11
+ export * from './lib/posts-list/posts-board.component';
12
+ export * from './lib/posts-list/posts-draft-column.component';
13
+ export * from './lib/posts-list/posts-queue-column.component';
14
+ export * from './lib/posts-list/posts-published-column.component';
15
+ export * from './lib/posts-list/posts-list.component';
@@ -0,0 +1,32 @@
1
+ import * as i0 from "@angular/core";
2
+ export declare class AboutEditorFormComponent {
3
+ readonly store: {
4
+ page: import("@angular/core").Signal<import("@foliokit/cms-core").CmsPageUnion | null>;
5
+ isDirty: import("@angular/core").Signal<boolean>;
6
+ isSaving: import("@angular/core").Signal<boolean>;
7
+ saveError: import("@angular/core").Signal<string | null>;
8
+ mode: import("@angular/core").Signal<"new" | "edit">;
9
+ cursorPosition: import("@angular/core").Signal<number>;
10
+ tempPageId: import("@angular/core").Signal<string>;
11
+ isNew: import("@angular/core").Signal<boolean>;
12
+ canPublish: import("@angular/core").Signal<boolean>;
13
+ loadPage: (id: string) => void;
14
+ initNew: (type?: import("@foliokit/cms-core").CmsPageUnion["type"]) => void;
15
+ updateField: (field: string, value: unknown) => void;
16
+ setCursorPosition: (position: number) => void;
17
+ insertMediaAtCursor: (token: string) => void;
18
+ removeEmbeddedMedia: (token: string) => void;
19
+ save: () => void;
20
+ toggleStatus: () => void;
21
+ } & import("@ngrx/signals").StateSource<{
22
+ page: import("@foliokit/cms-core").CmsPageUnion | null;
23
+ isDirty: boolean;
24
+ isSaving: boolean;
25
+ saveError: string | null;
26
+ mode: "new" | "edit";
27
+ cursorPosition: number;
28
+ tempPageId: string;
29
+ }>;
30
+ static ɵfac: i0.ɵɵFactoryDeclaration<AboutEditorFormComponent, never>;
31
+ static ɵcmp: i0.ɵɵComponentDeclaration<AboutEditorFormComponent, "admin-about-editor-form", never, {}, {}, never, never, true, never>;
32
+ }
@@ -0,0 +1,52 @@
1
+ import { ElementRef } from '@angular/core';
2
+ import { CdkDragDrop } from '@angular/cdk/drag-drop';
3
+ import type { LinksLink } from '@foliokit/cms-core';
4
+ import * as i0 from "@angular/core";
5
+ export declare class LinksEditorFormComponent {
6
+ avatarInput: ElementRef<HTMLInputElement>;
7
+ readonly store: {
8
+ page: import("@angular/core").Signal<import("@foliokit/cms-core").CmsPageUnion | null>;
9
+ isDirty: import("@angular/core").Signal<boolean>;
10
+ isSaving: import("@angular/core").Signal<boolean>;
11
+ saveError: import("@angular/core").Signal<string | null>;
12
+ mode: import("@angular/core").Signal<"new" | "edit">;
13
+ cursorPosition: import("@angular/core").Signal<number>;
14
+ tempPageId: import("@angular/core").Signal<string>;
15
+ isNew: import("@angular/core").Signal<boolean>;
16
+ canPublish: import("@angular/core").Signal<boolean>;
17
+ loadPage: (id: string) => void;
18
+ initNew: (type?: import("@foliokit/cms-core").CmsPageUnion["type"]) => void;
19
+ updateField: (field: string, value: unknown) => void;
20
+ setCursorPosition: (position: number) => void;
21
+ insertMediaAtCursor: (token: string) => void;
22
+ removeEmbeddedMedia: (token: string) => void;
23
+ save: () => void;
24
+ toggleStatus: () => void;
25
+ } & import("@ngrx/signals").StateSource<{
26
+ page: import("@foliokit/cms-core").CmsPageUnion | null;
27
+ isDirty: boolean;
28
+ isSaving: boolean;
29
+ saveError: string | null;
30
+ mode: "new" | "edit";
31
+ cursorPosition: number;
32
+ tempPageId: string;
33
+ }>;
34
+ private readonly storage;
35
+ private readonly pageService;
36
+ private readonly platformId;
37
+ readonly isBrowser: boolean;
38
+ readonly platformOptions: (import("@foliokit/cms-core").SocialPlatform | undefined)[];
39
+ readonly avatarUploading: import("@angular/core").WritableSignal<boolean>;
40
+ readonly avatarProgress: import("@angular/core").WritableSignal<number>;
41
+ readonly avatarError: import("@angular/core").WritableSignal<string | null>;
42
+ private avatarStoragePath;
43
+ onAvatarSelected(files: FileList | null): void;
44
+ onDeleteAvatar(): void;
45
+ addLink(links: LinksLink[]): void;
46
+ deleteLink(links: LinksLink[], id: string): void;
47
+ updateLink<K extends keyof LinksLink>(links: LinksLink[], id: string, field: K, value: LinksLink[K]): void;
48
+ onDrop(event: CdkDragDrop<LinksLink[]>, links: LinksLink[]): void;
49
+ private uploadAvatar;
50
+ static ɵfac: i0.ɵɵFactoryDeclaration<LinksEditorFormComponent, never>;
51
+ static ɵcmp: i0.ɵɵComponentDeclaration<LinksEditorFormComponent, "admin-links-editor-form", never, {}, {}, never, never, true, never>;
52
+ }
@@ -0,0 +1,51 @@
1
+ import { ElementRef } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export declare class PageEditorHeroImageComponent {
4
+ fileInput: ElementRef<HTMLInputElement>;
5
+ readonly store: {
6
+ page: import("@angular/core").Signal<import("@foliokit/cms-core").CmsPageUnion | null>;
7
+ isDirty: import("@angular/core").Signal<boolean>;
8
+ isSaving: import("@angular/core").Signal<boolean>;
9
+ saveError: import("@angular/core").Signal<string | null>;
10
+ mode: import("@angular/core").Signal<"new" | "edit">;
11
+ cursorPosition: import("@angular/core").Signal<number>;
12
+ tempPageId: import("@angular/core").Signal<string>;
13
+ isNew: import("@angular/core").Signal<boolean>;
14
+ canPublish: import("@angular/core").Signal<boolean>;
15
+ loadPage: (id: string) => void;
16
+ initNew: (type?: import("@foliokit/cms-core").CmsPageUnion["type"]) => void;
17
+ updateField: (field: string, value: unknown) => void;
18
+ setCursorPosition: (position: number) => void;
19
+ insertMediaAtCursor: (token: string) => void;
20
+ removeEmbeddedMedia: (token: string) => void;
21
+ save: () => void;
22
+ toggleStatus: () => void;
23
+ } & import("@ngrx/signals").StateSource<{
24
+ page: import("@foliokit/cms-core").CmsPageUnion | null;
25
+ isDirty: boolean;
26
+ isSaving: boolean;
27
+ saveError: string | null;
28
+ mode: "new" | "edit";
29
+ cursorPosition: number;
30
+ tempPageId: string;
31
+ }>;
32
+ private readonly storage;
33
+ private readonly pageService;
34
+ private readonly platformId;
35
+ readonly isBrowser: boolean;
36
+ readonly uploading: import("@angular/core").WritableSignal<boolean>;
37
+ readonly uploadProgress: import("@angular/core").WritableSignal<number>;
38
+ readonly uploadError: import("@angular/core").WritableSignal<string | null>;
39
+ readonly isDragOver: import("@angular/core").WritableSignal<boolean>;
40
+ readonly storagePath: import("@angular/core").WritableSignal<string | null>;
41
+ get heroImageUrl(): () => string | undefined;
42
+ get heroImageAlt(): () => string;
43
+ onDragOver(event: DragEvent): void;
44
+ onDragLeave(): void;
45
+ onDrop(event: DragEvent): void;
46
+ onFileSelected(files: FileList | null): void;
47
+ onDelete(): void;
48
+ private upload;
49
+ static ɵfac: i0.ɵɵFactoryDeclaration<PageEditorHeroImageComponent, never>;
50
+ static ɵcmp: i0.ɵɵComponentDeclaration<PageEditorHeroImageComponent, "admin-page-editor-hero-image", never, {}, {}, never, never, true, never>;
51
+ }
@@ -0,0 +1,37 @@
1
+ import type { CmsPageUnion } from '@foliokit/cms-core';
2
+ export interface PageEditorState {
3
+ page: CmsPageUnion | null;
4
+ isDirty: boolean;
5
+ isSaving: boolean;
6
+ saveError: string | null;
7
+ mode: 'new' | 'edit';
8
+ cursorPosition: number;
9
+ tempPageId: string;
10
+ }
11
+ export declare const PageEditorStore: import("@angular/core").Type<{
12
+ page: import("@angular/core").Signal<CmsPageUnion | null>;
13
+ isDirty: import("@angular/core").Signal<boolean>;
14
+ isSaving: import("@angular/core").Signal<boolean>;
15
+ saveError: import("@angular/core").Signal<string | null>;
16
+ mode: import("@angular/core").Signal<"new" | "edit">;
17
+ cursorPosition: import("@angular/core").Signal<number>;
18
+ tempPageId: import("@angular/core").Signal<string>;
19
+ isNew: import("@angular/core").Signal<boolean>;
20
+ canPublish: import("@angular/core").Signal<boolean>;
21
+ loadPage: (id: string) => void;
22
+ initNew: (type?: CmsPageUnion["type"]) => void;
23
+ updateField: (field: string, value: unknown) => void;
24
+ setCursorPosition: (position: number) => void;
25
+ insertMediaAtCursor: (token: string) => void;
26
+ removeEmbeddedMedia: (token: string) => void;
27
+ save: () => void;
28
+ toggleStatus: () => void;
29
+ } & import("@ngrx/signals").StateSource<{
30
+ page: CmsPageUnion | null;
31
+ isDirty: boolean;
32
+ isSaving: boolean;
33
+ saveError: string | null;
34
+ mode: "new" | "edit";
35
+ cursorPosition: number;
36
+ tempPageId: string;
37
+ }>>;
@@ -0,0 +1,50 @@
1
+ import { ElementRef } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export declare class PostEditorCoverImageComponent {
4
+ fileInput: ElementRef<HTMLInputElement>;
5
+ readonly store: {
6
+ post: import("@angular/core").Signal<import("@foliokit/cms-core").BlogPost | null>;
7
+ isDirty: import("@angular/core").Signal<boolean>;
8
+ isSaving: import("@angular/core").Signal<boolean>;
9
+ saveError: import("@angular/core").Signal<string | null>;
10
+ mode: import("@angular/core").Signal<"new" | "edit">;
11
+ cursorPosition: import("@angular/core").Signal<number>;
12
+ tempPostId: import("@angular/core").Signal<string>;
13
+ isNew: import("@angular/core").Signal<boolean>;
14
+ canPublish: import("@angular/core").Signal<boolean>;
15
+ loadPost: (id: string) => void;
16
+ initNew: () => void;
17
+ updateField: <K extends keyof import("@foliokit/cms-core").BlogPost>(field: K, value: import("@foliokit/cms-core").BlogPost[K]) => void;
18
+ save: () => void;
19
+ setCursorPosition: (position: number) => void;
20
+ insertMediaAtCursor: (token: string) => void;
21
+ removeEmbeddedMedia: (token: string) => void;
22
+ publish: () => void;
23
+ } & import("@ngrx/signals").StateSource<{
24
+ post: import("@foliokit/cms-core").BlogPost | null;
25
+ isDirty: boolean;
26
+ isSaving: boolean;
27
+ saveError: string | null;
28
+ mode: "new" | "edit";
29
+ cursorPosition: number;
30
+ tempPostId: string;
31
+ }>;
32
+ private readonly storage;
33
+ private readonly postService;
34
+ private readonly platformId;
35
+ readonly isBrowser: boolean;
36
+ readonly uploading: import("@angular/core").WritableSignal<boolean>;
37
+ readonly uploadProgress: import("@angular/core").WritableSignal<number>;
38
+ readonly uploadError: import("@angular/core").WritableSignal<string | null>;
39
+ readonly isDragOver: import("@angular/core").WritableSignal<boolean>;
40
+ readonly storagePath: import("@angular/core").WritableSignal<string | null>;
41
+ onDragOver(event: DragEvent): void;
42
+ onDragLeave(): void;
43
+ onDrop(event: DragEvent): void;
44
+ onFileSelected(files: FileList | null): void;
45
+ onDeleteCover(): void;
46
+ private clearCover;
47
+ private upload;
48
+ static ɵfac: i0.ɵɵFactoryDeclaration<PostEditorCoverImageComponent, never>;
49
+ static ɵcmp: i0.ɵɵComponentDeclaration<PostEditorCoverImageComponent, "folio-post-editor-cover-image", never, {}, {}, never, never, true, never>;
50
+ }
@@ -0,0 +1,37 @@
1
+ import { EmbeddedMediaEntry } from '@foliokit/cms-core';
2
+ import * as i0 from "@angular/core";
3
+ export declare class PostEditorEmbeddedMediaItemComponent {
4
+ readonly entry: import("@angular/core").InputSignal<EmbeddedMediaEntry>;
5
+ readonly token: import("@angular/core").InputSignal<string>;
6
+ readonly store: {
7
+ post: import("@angular/core").Signal<import("@foliokit/cms-core").BlogPost | null>;
8
+ isDirty: import("@angular/core").Signal<boolean>;
9
+ isSaving: import("@angular/core").Signal<boolean>;
10
+ saveError: import("@angular/core").Signal<string | null>;
11
+ mode: import("@angular/core").Signal<"new" | "edit">;
12
+ cursorPosition: import("@angular/core").Signal<number>;
13
+ tempPostId: import("@angular/core").Signal<string>;
14
+ isNew: import("@angular/core").Signal<boolean>;
15
+ canPublish: import("@angular/core").Signal<boolean>;
16
+ loadPost: (id: string) => void;
17
+ initNew: () => void;
18
+ updateField: <K extends keyof import("@foliokit/cms-core").BlogPost>(field: K, value: import("@foliokit/cms-core").BlogPost[K]) => void;
19
+ save: () => void;
20
+ setCursorPosition: (position: number) => void;
21
+ insertMediaAtCursor: (token: string) => void;
22
+ removeEmbeddedMedia: (token: string) => void;
23
+ publish: () => void;
24
+ } & import("@ngrx/signals").StateSource<{
25
+ post: import("@foliokit/cms-core").BlogPost | null;
26
+ isDirty: boolean;
27
+ isSaving: boolean;
28
+ saveError: string | null;
29
+ mode: "new" | "edit";
30
+ cursorPosition: number;
31
+ tempPostId: string;
32
+ }>;
33
+ onInsert(): void;
34
+ onDelete(): void;
35
+ static ɵfac: i0.ɵɵFactoryDeclaration<PostEditorEmbeddedMediaItemComponent, never>;
36
+ static ɵcmp: i0.ɵɵComponentDeclaration<PostEditorEmbeddedMediaItemComponent, "folio-post-editor-embedded-media-item", never, { "entry": { "alias": "entry"; "required": true; "isSignal": true; }; "token": { "alias": "token"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
37
+ }
@@ -0,0 +1,43 @@
1
+ import { ElementRef } from '@angular/core';
2
+ import { EmbeddedMediaEntry } from '@foliokit/cms-core';
3
+ import * as i0 from "@angular/core";
4
+ export declare class PostEditorEmbeddedMediaComponent {
5
+ fileInput: ElementRef<HTMLInputElement>;
6
+ readonly store: {
7
+ post: import("@angular/core").Signal<import("@foliokit/cms-core").BlogPost | null>;
8
+ isDirty: import("@angular/core").Signal<boolean>;
9
+ isSaving: import("@angular/core").Signal<boolean>;
10
+ saveError: import("@angular/core").Signal<string | null>;
11
+ mode: import("@angular/core").Signal<"new" | "edit">;
12
+ cursorPosition: import("@angular/core").Signal<number>;
13
+ tempPostId: import("@angular/core").Signal<string>;
14
+ isNew: import("@angular/core").Signal<boolean>;
15
+ canPublish: import("@angular/core").Signal<boolean>;
16
+ loadPost: (id: string) => void;
17
+ initNew: () => void;
18
+ updateField: <K extends keyof import("@foliokit/cms-core").BlogPost>(field: K, value: import("@foliokit/cms-core").BlogPost[K]) => void;
19
+ save: () => void;
20
+ setCursorPosition: (position: number) => void;
21
+ insertMediaAtCursor: (token: string) => void;
22
+ removeEmbeddedMedia: (token: string) => void;
23
+ publish: () => void;
24
+ } & import("@ngrx/signals").StateSource<{
25
+ post: import("@foliokit/cms-core").BlogPost | null;
26
+ isDirty: boolean;
27
+ isSaving: boolean;
28
+ saveError: string | null;
29
+ mode: "new" | "edit";
30
+ cursorPosition: number;
31
+ tempPostId: string;
32
+ }>;
33
+ private readonly storage;
34
+ private readonly platformId;
35
+ readonly isBrowser: boolean;
36
+ readonly uploading: import("@angular/core").WritableSignal<boolean>;
37
+ readonly uploadError: import("@angular/core").WritableSignal<string | null>;
38
+ readonly entries: import("@angular/core").Signal<EmbeddedMediaEntry[]>;
39
+ onFileSelected(files: FileList | null): void;
40
+ private upload;
41
+ static ɵfac: i0.ɵɵFactoryDeclaration<PostEditorEmbeddedMediaComponent, never>;
42
+ static ɵcmp: i0.ɵɵComponentDeclaration<PostEditorEmbeddedMediaComponent, "folio-post-editor-embedded-media", never, {}, {}, never, never, true, never>;
43
+ }
@@ -0,0 +1,5 @@
1
+ import * as i0 from "@angular/core";
2
+ export declare class PostEditorMediaTabComponent {
3
+ static ɵfac: i0.ɵɵFactoryDeclaration<PostEditorMediaTabComponent, never>;
4
+ static ɵcmp: i0.ɵɵComponentDeclaration<PostEditorMediaTabComponent, "folio-post-editor-media-tab", never, {}, {}, never, never, true, never>;
5
+ }