@blogmcp/community 0.2.0 → 0.3.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 (82) hide show
  1. package/README.md +64 -12
  2. package/dist/blogmcp-community.global.js +7 -7
  3. package/dist/chunks/{mount-WadUnaTa.js → mount--2_V2q3M.js} +4724 -1097
  4. package/dist/core/attrs.d.ts +17 -2
  5. package/dist/core/discussion.d.ts +92 -18
  6. package/dist/core/follow.d.ts +26 -0
  7. package/dist/core/forum-category.d.ts +85 -0
  8. package/dist/core/forum-search.d.ts +35 -0
  9. package/dist/core/forum-state.d.ts +30 -0
  10. package/dist/core/forum-words.d.ts +8 -0
  11. package/dist/core/forum.d.ts +21 -0
  12. package/dist/core/moderation.d.ts +80 -0
  13. package/dist/core/onboarding.d.ts +7 -0
  14. package/dist/core/profile.d.ts +6 -1
  15. package/dist/core/realtime.d.ts +13 -2
  16. package/dist/core/topic.d.ts +47 -0
  17. package/dist/element.d.ts +26 -1
  18. package/dist/global.d.ts +7 -6
  19. package/dist/index.d.ts +13 -4
  20. package/dist/index.js +54 -27
  21. package/dist/mount.d.ts +50 -1
  22. package/dist/react.d.ts +17 -4
  23. package/dist/react.js +32 -8
  24. package/dist/ui/FollowButtonView.vue.d.ts +17 -0
  25. package/dist/ui/FollowToggle.vue.d.ts +6 -0
  26. package/dist/ui/ForumCategoryView.vue.d.ts +13 -0
  27. package/dist/ui/ForumModerationView.vue.d.ts +12 -0
  28. package/dist/ui/ForumNotices.vue.d.ts +7 -0
  29. package/dist/ui/ForumSearchView.vue.d.ts +11 -0
  30. package/dist/ui/ForumView.vue.d.ts +12 -0
  31. package/dist/ui/MembersOnly.vue.d.ts +15 -0
  32. package/dist/ui/MessageComposer.vue.d.ts +6 -2
  33. package/dist/ui/MessageMenu.vue.d.ts +2 -0
  34. package/dist/ui/ModeratorDialog.vue.d.ts +11 -0
  35. package/dist/ui/TopicRow.vue.d.ts +10 -0
  36. package/dist/ui/TopicView.vue.d.ts +32 -0
  37. package/dist/ui/context.d.ts +7 -1
  38. package/dist/ui/discussion-context.d.ts +11 -3
  39. package/dist/vue.d.ts +164 -5
  40. package/dist/vue.js +134 -8
  41. package/package.json +3 -3
  42. package/src/core/attrs.ts +22 -2
  43. package/src/core/discussion.ts +309 -43
  44. package/src/core/follow.ts +139 -0
  45. package/src/core/forum-category.ts +323 -0
  46. package/src/core/forum-search.ts +153 -0
  47. package/src/core/forum-state.ts +59 -0
  48. package/src/core/forum-words.ts +38 -0
  49. package/src/core/forum.ts +83 -0
  50. package/src/core/moderation.ts +414 -0
  51. package/src/core/onboarding.ts +16 -4
  52. package/src/core/outcomes.ts +10 -0
  53. package/src/core/profile.ts +12 -1
  54. package/src/core/realtime.ts +15 -2
  55. package/src/core/topic.ts +234 -0
  56. package/src/element.ts +63 -1
  57. package/src/global.ts +27 -5
  58. package/src/index.ts +49 -2
  59. package/src/mount.ts +144 -2
  60. package/src/react.ts +45 -2
  61. package/src/ui/FollowButtonView.vue +85 -0
  62. package/src/ui/FollowToggle.vue +39 -0
  63. package/src/ui/ForumCategoryView.vue +243 -0
  64. package/src/ui/ForumModerationView.vue +309 -0
  65. package/src/ui/ForumNotices.vue +23 -0
  66. package/src/ui/ForumSearchView.vue +171 -0
  67. package/src/ui/ForumView.vue +128 -0
  68. package/src/ui/MembersOnly.vue +59 -0
  69. package/src/ui/MessageComposer.vue +51 -9
  70. package/src/ui/MessageItem.vue +12 -1
  71. package/src/ui/MessageMenu.vue +3 -2
  72. package/src/ui/ModeratorDialog.vue +102 -0
  73. package/src/ui/MyCommunityView.vue +3 -0
  74. package/src/ui/NoticeStatusView.vue +15 -2
  75. package/src/ui/NotificationCentreView.vue +37 -3
  76. package/src/ui/ProfileView.vue +15 -4
  77. package/src/ui/TopicRow.vue +70 -0
  78. package/src/ui/TopicView.vue +395 -0
  79. package/src/ui/context.ts +8 -3
  80. package/src/ui/discussion-context.ts +11 -3
  81. package/src/ui/styles.css +14 -0
  82. package/src/vue.ts +145 -3
package/dist/element.d.ts CHANGED
@@ -7,6 +7,13 @@ export declare const BADGE_ELEMENT_TAG = "blogmcp-badge";
7
7
  export declare const MEMBER_SETTINGS_ELEMENT_TAG = "blogmcp-member-settings";
8
8
  export declare const PROFILE_ELEMENT_TAG = "blogmcp-profile";
9
9
  export declare const WELCOME_ELEMENT_TAG = "blogmcp-welcome";
10
+ /** M3 (m3-contracts.md §5.3): the forum's elements — they live here, not in the SDK (A33). */
11
+ export declare const FORUM_ELEMENT_TAG = "blogmcp-forum";
12
+ export declare const FORUM_CATEGORY_ELEMENT_TAG = "blogmcp-forum-category";
13
+ export declare const TOPIC_ELEMENT_TAG = "blogmcp-topic";
14
+ export declare const FORUM_SEARCH_ELEMENT_TAG = "blogmcp-forum-search";
15
+ export declare const FOLLOW_BUTTON_ELEMENT_TAG = "blogmcp-follow-button";
16
+ export declare const FORUM_MODERATION_ELEMENT_TAG = "blogmcp-forum-moderation";
10
17
  export interface DefineCommunityElementOptions {
11
18
  /** Another tag name for the element. */
12
19
  tag?: string;
@@ -25,6 +32,12 @@ export interface DefineCommunityElementsOptions {
25
32
  memberSettings?: string;
26
33
  profile?: string;
27
34
  welcome?: string;
35
+ forum?: string;
36
+ forumCategory?: string;
37
+ topic?: string;
38
+ forumSearch?: string;
39
+ followButton?: string;
40
+ forumModeration?: string;
28
41
  };
29
42
  }
30
43
  /** Register `<blogmcp-discussion>` (once; later calls are no-ops). Browser only. */
@@ -43,5 +56,17 @@ export declare function defineMemberSettingsElement(opts?: DefineCommunityElemen
43
56
  export declare function defineProfileElement(opts?: DefineCommunityElementOptions): void;
44
57
  /** Register `<blogmcp-welcome>` (once). Browser only. */
45
58
  export declare function defineWelcomeElement(opts?: DefineCommunityElementOptions): void;
46
- /** Register all eight (once). Browser only. */
59
+ /** M3: register `<blogmcp-forum>` (once). Browser only. */
60
+ export declare function defineForumElement(opts?: DefineCommunityElementOptions): void;
61
+ /** M3: register `<blogmcp-forum-category>` (once). Browser only. */
62
+ export declare function defineForumCategoryElement(opts?: DefineCommunityElementOptions): void;
63
+ /** M3: register `<blogmcp-topic>` (once). Browser only. */
64
+ export declare function defineTopicElement(opts?: DefineCommunityElementOptions): void;
65
+ /** M3: register `<blogmcp-forum-search>` (once). Browser only. */
66
+ export declare function defineForumSearchElement(opts?: DefineCommunityElementOptions): void;
67
+ /** M3: register `<blogmcp-follow-button>` (once). Browser only. */
68
+ export declare function defineFollowButtonElement(opts?: DefineCommunityElementOptions): void;
69
+ /** M3: register `<blogmcp-forum-moderation>` (once). Browser only. */
70
+ export declare function defineForumModerationElement(opts?: DefineCommunityElementOptions): void;
71
+ /** Register all fourteen (once). Browser only. */
47
72
  export declare function defineCommunityElements(opts?: DefineCommunityElementsOptions): void;
package/dist/global.d.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  /**
2
2
  * The `<script>` build: registers every element — `<blogmcp-discussion>`, `<blogmcp-notice-form>`,
3
- * `<blogmcp-my-community>` and (M2) `<blogmcp-notification-centre>`, `<blogmcp-badge>`, `<blogmcp-member-settings>`,
4
- * `<blogmcp-profile>`, `<blogmcp-welcome>` — with the script tag's own CSP nonce, and exposes
5
- * `window.BlogmcpCommunity`. Live updates are not in it: a site that wants them bundles `@blogmcp/sdk/community/realtime`
6
- * and sets the discussion's `realtime` property.
3
+ * `<blogmcp-my-community>`, (M2) `<blogmcp-notification-centre>`, `<blogmcp-badge>`, `<blogmcp-member-settings>`,
4
+ * `<blogmcp-profile>`, `<blogmcp-welcome>` and (M3) `<blogmcp-forum>`, `<blogmcp-forum-category>`, `<blogmcp-topic>`,
5
+ * `<blogmcp-forum-search>`, `<blogmcp-follow-button>`, `<blogmcp-forum-moderation>` — with the script tag's own CSP
6
+ * nonce, and exposes `window.BlogmcpCommunity`. Live updates are not in it: a site that wants them bundles
7
+ * `@blogmcp/sdk/community/realtime` and sets the discussion's (or the topic's) `realtime` property.
7
8
  */
8
9
  import { defineCommunityElements } from './element';
9
- import { mountBadge, mountDiscussion, mountMemberSettings, mountMyCommunity, mountNoticeForm, mountNotificationCentre, mountProfile, mountWelcome } from './mount';
10
+ import { mountBadge, mountDiscussion, mountFollowButton, mountForum, mountForumCategory, mountForumModeration, mountForumSearch, mountMemberSettings, mountMyCommunity, mountNoticeForm, mountNotificationCentre, mountProfile, mountTopic, mountWelcome } from './mount';
10
11
  import { VERSION } from './version';
11
- export { defineCommunityElements, mountDiscussion, mountMyCommunity, mountNoticeForm, mountNotificationCentre, mountBadge, mountMemberSettings, mountProfile, mountWelcome, VERSION, };
12
+ export { defineCommunityElements, mountDiscussion, mountMyCommunity, mountNoticeForm, mountNotificationCentre, mountBadge, mountMemberSettings, mountProfile, mountWelcome, mountForum, mountForumCategory, mountTopic, mountForumSearch, mountFollowButton, mountForumModeration, VERSION, };
package/dist/index.d.ts CHANGED
@@ -10,19 +10,28 @@
10
10
  * - M2: `<blogmcp-notification-centre>` the notifications, `<blogmcp-badge>` the header's unread count,
11
11
  * `<blogmcp-member-settings>` the switches, push and the digest's unsubscribe, `<blogmcp-profile>` a member's
12
12
  * public profile, `<blogmcp-welcome>` the welcome page; the discussion's `realtime` property (live updates);
13
+ * - M3, the forum: `<blogmcp-forum>` its index, `<blogmcp-forum-category slug>` a category, `<blogmcp-topic
14
+ * conversation-id>` a topic (the discussion's view, with its `realtime` property), `<blogmcp-forum-search>`,
15
+ * `<blogmcp-follow-button target-kind target-id>`, `<blogmcp-forum-moderation>` a category moderator's queue;
13
16
  * - `defineCommunityElements()` and one `define…Element()` each — the custom elements;
14
17
  * - `mountDiscussion(…)`, `mountNoticeForm(…)`, `mountMyCommunity(…)` — mount one from code;
15
18
  * - `@blogmcp/community/vue`, `@blogmcp/community/react` — `<KbDiscussion>`, `<KbNoticeForm>`, `<KbMyCommunity>`;
16
19
  * - `@blogmcp/community/global` — one `<script>` for sites without a bundler.
17
20
  */
18
- export { defineCommunityElements, defineDiscussionElement, defineNoticeFormElement, defineMyCommunityElement, defineNotificationCentreElement, defineBadgeElement, defineMemberSettingsElement, defineProfileElement, defineWelcomeElement, DISCUSSION_ELEMENT_TAG, NOTICE_FORM_ELEMENT_TAG, MY_COMMUNITY_ELEMENT_TAG, NOTIFICATION_CENTRE_ELEMENT_TAG, BADGE_ELEMENT_TAG, MEMBER_SETTINGS_ELEMENT_TAG, PROFILE_ELEMENT_TAG, WELCOME_ELEMENT_TAG, type DefineCommunityElementOptions, type DefineCommunityElementsOptions, } from './element';
19
- export { mountDiscussion, mountNoticeForm, mountMyCommunity, mountNotificationCentre, mountBadge, mountMemberSettings, mountProfile, mountWelcome, type MountDiscussionOptions, type MountNoticeFormOptions, type MountMyCommunityOptions, type MountNotificationCentreOptions, type MountBadgeOptions, type MountMemberSettingsOptions, type MountProfileOptions, type MountWelcomeOptions, } from './mount';
21
+ export { defineCommunityElements, defineDiscussionElement, defineNoticeFormElement, defineMyCommunityElement, defineNotificationCentreElement, defineBadgeElement, defineMemberSettingsElement, defineProfileElement, defineWelcomeElement, defineForumElement, defineForumCategoryElement, defineTopicElement, defineForumSearchElement, defineFollowButtonElement, defineForumModerationElement, DISCUSSION_ELEMENT_TAG, NOTICE_FORM_ELEMENT_TAG, MY_COMMUNITY_ELEMENT_TAG, NOTIFICATION_CENTRE_ELEMENT_TAG, BADGE_ELEMENT_TAG, MEMBER_SETTINGS_ELEMENT_TAG, PROFILE_ELEMENT_TAG, WELCOME_ELEMENT_TAG, FORUM_ELEMENT_TAG, FORUM_CATEGORY_ELEMENT_TAG, TOPIC_ELEMENT_TAG, FORUM_SEARCH_ELEMENT_TAG, FOLLOW_BUTTON_ELEMENT_TAG, FORUM_MODERATION_ELEMENT_TAG, type DefineCommunityElementOptions, type DefineCommunityElementsOptions, } from './element';
22
+ export { mountDiscussion, mountNoticeForm, mountMyCommunity, mountNotificationCentre, mountBadge, mountMemberSettings, mountProfile, mountWelcome, mountForum, mountForumCategory, mountTopic, mountForumSearch, mountFollowButton, mountForumModeration, type MountDiscussionOptions, type MountNoticeFormOptions, type MountMyCommunityOptions, type MountNotificationCentreOptions, type MountBadgeOptions, type MountMemberSettingsOptions, type MountProfileOptions, type MountWelcomeOptions, type MountForumOptions, type MountForumCategoryOptions, type MountTopicOptions, type MountForumSearchOptions, type MountFollowButtonOptions, type MountForumModerationOptions, } from './mount';
20
23
  export { createNotificationCentre, type NotificationCentreController, type CentreUi } from './core/centre';
21
24
  export { createBadge, badgeText, BADGE_INTERVAL_MS, type BadgeController, type BadgeOptions, type BadgeUi } from './core/badge';
22
25
  export { createMemberSettings, SETTING_KEYS, type MemberSettingsController, type MemberSettingsOptions, type SettingsUi, type SettingKey } from './core/settings';
23
26
  export { createProfile, createWelcome, type ProfileController, type WelcomeController } from './core/profile';
24
- export type { DiscussionRealtime, DiscussionRealtimeOptions, DiscussionRealtimeSession, DiscussionRealtimeMode } from './core/realtime';
25
- export { createDiscussionController, type DiscussionController, type DiscussionControllerOptions, type DiscussionUi, type ComposerMode, type Draft } from './core/discussion';
27
+ export type { DiscussionRealtime, DiscussionRealtimeOptions, DiscussionRealtimeSession, DiscussionRealtimeMode, TopicRealtime, TopicRealtimeOptions } from './core/realtime';
28
+ export { createDiscussionController, createTopicThreadController, type DiscussionController, type DiscussionControllerOptions, type DiscussionUi, type ComposerMode, type Draft, type ThreadController, type ThreadState, type ThreadUi, type TopicThreadController, type TopicThreadControllerOptions, } from './core/discussion';
29
+ export { createForum, type ForumController, type ForumUi } from './core/forum';
30
+ export { createCategory, type CategoryController, type CategoryUi, type TopicDraft } from './core/forum-category';
31
+ export { createTopicController, type TopicController, type ModeratorDialog } from './core/topic';
32
+ export { createSearch, queryFromHash, searchLink, type SearchController, type SearchUi } from './core/forum-search';
33
+ export { createFollow, type FollowController, type FollowUi } from './core/follow';
34
+ export { createModeration, type ModerationController, type ModerationUi } from './core/moderation';
26
35
  export { createNoticeForm, type NoticeFormController, type NoticeFormOptions, type NoticeFormUi } from './core/notice';
27
36
  export { createPanel, type PanelController, type PanelOptions, type PanelUi } from './core/panel';
28
37
  export { createOnboarding, type OnboardingModel, type OnboardingOptions, type OnboardingStep } from './core/onboarding';
package/dist/index.js CHANGED
@@ -1,45 +1,72 @@
1
- import { H, B, w, I, D, k, M, N, j, P, S, W, v, u, A, x, C, t, F, E, y, z, f, d, a, g, c, b, e, h, i, p, m, q, n, l, o, r, s, G } from "./chunks/mount-WadUnaTa.js";
2
- const VERSION = "0.2.0";
1
+ import { ab, B, S, ac, D, t, r, F, u, s, q, M, N, p, P, V, T, W, R, Q, a0, Z, a5, $, U, a6, a7, O, a9, a8, X, a2, a1, _, Y, f, d, a, n, k, j, o, m, g, c, b, e, h, l, i, z, v, K, G, H, L, J, A, x, w, y, C, I, E, aa, a3, a4 } from "./chunks/mount--2_V2q3M.js";
2
+ const VERSION = "0.3.0";
3
3
  export {
4
- H as AVATAR_PRESETS,
4
+ ab as AVATAR_PRESETS,
5
5
  B as BADGE_ELEMENT_TAG,
6
- w as BADGE_INTERVAL_MS,
7
- I as DEFAULT_API_BASE,
6
+ S as BADGE_INTERVAL_MS,
7
+ ac as DEFAULT_API_BASE,
8
8
  D as DISCUSSION_ELEMENT_TAG,
9
- k as MEMBER_SETTINGS_ELEMENT_TAG,
9
+ t as FOLLOW_BUTTON_ELEMENT_TAG,
10
+ r as FORUM_CATEGORY_ELEMENT_TAG,
11
+ F as FORUM_ELEMENT_TAG,
12
+ u as FORUM_MODERATION_ELEMENT_TAG,
13
+ s as FORUM_SEARCH_ELEMENT_TAG,
14
+ q as MEMBER_SETTINGS_ELEMENT_TAG,
10
15
  M as MY_COMMUNITY_ELEMENT_TAG,
11
16
  N as NOTICE_FORM_ELEMENT_TAG,
12
- j as NOTIFICATION_CENTRE_ELEMENT_TAG,
17
+ p as NOTIFICATION_CENTRE_ELEMENT_TAG,
13
18
  P as PROFILE_ELEMENT_TAG,
14
- S as SETTING_KEYS,
19
+ V as SETTING_KEYS,
20
+ T as TOPIC_ELEMENT_TAG,
15
21
  VERSION,
16
22
  W as WELCOME_ELEMENT_TAG,
17
- v as badgeText,
18
- u as createBadge,
19
- A as createDiscussionController,
20
- x as createMemberSettings,
21
- C as createNoticeForm,
22
- t as createNotificationCentre,
23
- F as createOnboarding,
24
- E as createPanel,
25
- y as createProfile,
26
- z as createWelcome,
23
+ R as badgeText,
24
+ Q as createBadge,
25
+ a0 as createCategory,
26
+ Z as createDiscussionController,
27
+ a5 as createFollow,
28
+ $ as createForum,
29
+ U as createMemberSettings,
30
+ a6 as createModeration,
31
+ a7 as createNoticeForm,
32
+ O as createNotificationCentre,
33
+ a9 as createOnboarding,
34
+ a8 as createPanel,
35
+ X as createProfile,
36
+ a2 as createSearch,
37
+ a1 as createTopicController,
38
+ _ as createTopicThreadController,
39
+ Y as createWelcome,
27
40
  f as defineBadgeElement,
28
41
  d as defineCommunityElements,
29
42
  a as defineDiscussionElement,
43
+ n as defineFollowButtonElement,
44
+ k as defineForumCategoryElement,
45
+ j as defineForumElement,
46
+ o as defineForumModerationElement,
47
+ m as defineForumSearchElement,
30
48
  g as defineMemberSettingsElement,
31
49
  c as defineMyCommunityElement,
32
50
  b as defineNoticeFormElement,
33
51
  e as defineNotificationCentreElement,
34
52
  h as defineProfileElement,
53
+ l as defineTopicElement,
35
54
  i as defineWelcomeElement,
36
- p as mountBadge,
37
- m as mountDiscussion,
38
- q as mountMemberSettings,
39
- n as mountMyCommunity,
40
- l as mountNoticeForm,
41
- o as mountNotificationCentre,
42
- r as mountProfile,
43
- s as mountWelcome,
44
- G as pickLang
55
+ z as mountBadge,
56
+ v as mountDiscussion,
57
+ K as mountFollowButton,
58
+ G as mountForum,
59
+ H as mountForumCategory,
60
+ L as mountForumModeration,
61
+ J as mountForumSearch,
62
+ A as mountMemberSettings,
63
+ x as mountMyCommunity,
64
+ w as mountNoticeForm,
65
+ y as mountNotificationCentre,
66
+ C as mountProfile,
67
+ I as mountTopic,
68
+ E as mountWelcome,
69
+ aa as pickLang,
70
+ a3 as queryFromHash,
71
+ a4 as searchLink
45
72
  };
package/dist/mount.d.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import type { CommunityTransport } from '@blogmcp/sdk/community';
9
9
  import type { CommunityRoutes } from './core/attrs';
10
- import type { DiscussionRealtime } from './core/realtime';
10
+ import type { DiscussionRealtime, TopicRealtime } from './core/realtime';
11
11
  interface CommonMountOptions {
12
12
  /** The host's relative base (default `/api/community` under `siteBase`): its proxy or BFF. Never kb-api's URL. */
13
13
  apiBase?: string;
@@ -86,6 +86,43 @@ export interface MountWelcomeOptions extends CommonMountOptions {
86
86
  /** The site's sign-in page (a visitor's link in the profile's place). */
87
87
  signInHref?: string;
88
88
  }
89
+ /** M3 (m3-contracts.md §5.3): the forum's index — its categories, their latest topics, the search box. */
90
+ export interface MountForumOptions extends CommonMountOptions {
91
+ /** The site's sign-in page (the members-only sentence's link for a visitor). */
92
+ signInHref?: string;
93
+ }
94
+ /** M3: one category's page — its topics, its follow button, the new-topic composer. */
95
+ export interface MountForumCategoryOptions extends CommonMountOptions {
96
+ /** The category's slug. */
97
+ slug: string;
98
+ signInHref?: string;
99
+ }
100
+ /** M3: one topic's page — the discussion's view over the topic, with its header. */
101
+ export interface MountTopicOptions extends CommonMountOptions {
102
+ /** The topic's conversation id. */
103
+ conversationId: string;
104
+ signInHref?: string;
105
+ /** Head poll interval in ms (default 20 000; 0 = off). */
106
+ pollMs?: number;
107
+ /** Live updates — `createRealtimeSession` of `@blogmcp/sdk/community/realtime` (the host imports it). Absent: the head poll. */
108
+ realtime?: TopicRealtime;
109
+ }
110
+ /** M3: the forum's search. */
111
+ export interface MountForumSearchOptions extends CommonMountOptions {
112
+ signInHref?: string;
113
+ }
114
+ /** M3: a follow button — a topic or an article discussion (`conversation`) or a category, by its id. */
115
+ export interface MountFollowButtonOptions extends CommonMountOptions {
116
+ targetKind: 'conversation' | 'category';
117
+ targetId: string;
118
+ /** Whether the member follows it, when the host knows (absent: the member's follows are read). */
119
+ following?: boolean;
120
+ }
121
+ /** M3: a category moderator's queue (renders nothing for a member who moderates nothing). */
122
+ export interface MountForumModerationOptions extends CommonMountOptions {
123
+ /** Narrow the queue to one of the moderator's categories. */
124
+ categoryId?: string;
125
+ }
89
126
  /** Mount `<blogmcp-discussion>`; returns the function that removes it. */
90
127
  export declare function mountDiscussion(o: MountDiscussionOptions): () => void;
91
128
  /** Mount `<blogmcp-notice-form>`; returns the function that removes it. */
@@ -102,4 +139,16 @@ export declare function mountMemberSettings(o?: MountMemberSettingsOptions): ()
102
139
  export declare function mountProfile(o: MountProfileOptions): () => void;
103
140
  /** Mount `<blogmcp-welcome>`; returns the function that removes it. */
104
141
  export declare function mountWelcome(o?: MountWelcomeOptions): () => void;
142
+ /** M3: mount `<blogmcp-forum>`; returns the function that removes it. */
143
+ export declare function mountForum(o?: MountForumOptions): () => void;
144
+ /** M3: mount `<blogmcp-forum-category>`; returns the function that removes it. */
145
+ export declare function mountForumCategory(o: MountForumCategoryOptions): () => void;
146
+ /** M3: mount `<blogmcp-topic>`; returns the function that removes it. */
147
+ export declare function mountTopic(o: MountTopicOptions): () => void;
148
+ /** M3: mount `<blogmcp-forum-search>`; returns the function that removes it. */
149
+ export declare function mountForumSearch(o?: MountForumSearchOptions): () => void;
150
+ /** M3: mount `<blogmcp-follow-button>`; returns the function that removes it. */
151
+ export declare function mountFollowButton(o: MountFollowButtonOptions): () => void;
152
+ /** M3: mount `<blogmcp-forum-moderation>`; returns the function that removes it. */
153
+ export declare function mountForumModeration(o?: MountForumModerationOptions): () => void;
105
154
  export {};
package/dist/react.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  /**
2
- * `<KbDiscussion>`, `<KbNoticeForm>`, `<KbMyCommunity>` and (M2) `<KbNotificationCentre>`, `<KbBadge>`,
3
- * `<KbMemberSettings>`, `<KbProfile>`, `<KbWelcome>` for React (18 and 19, Next.js App Router included — this
2
+ * `<KbDiscussion>`, `<KbNoticeForm>`, `<KbMyCommunity>`, (M2) `<KbNotificationCentre>`, `<KbBadge>`,
3
+ * `<KbMemberSettings>`, `<KbProfile>`, `<KbWelcome>` and (M3) `<KbForum>`, `<KbForumCategory>`, `<KbTopic>`,
4
+ * `<KbForumSearch>`, `<KbFollowButton>`, `<KbForumModeration>` for React (18 and 19, Next.js App Router included — this
4
5
  * module is a client component): each mounts its element after hydration and removes it on unmount. Each
5
6
  * renders one empty `<div>` as the mount point — nothing else, on the server or the client — so the element
6
7
  * sits where the component does and the page's markup is otherwise the site's alone.
@@ -8,7 +9,7 @@
8
9
  * <KbDiscussion articleId={article.id} apiBase="/api/community" signInHref={`/sign-in#${pathname}`} />
9
10
  */
10
11
  import { type ReactElement } from 'react';
11
- import type { MountBadgeOptions, MountDiscussionOptions, MountMemberSettingsOptions, MountMyCommunityOptions, MountNoticeFormOptions, MountNotificationCentreOptions, MountProfileOptions, MountWelcomeOptions } from './mount';
12
+ import type { MountBadgeOptions, MountDiscussionOptions, MountFollowButtonOptions, MountForumCategoryOptions, MountForumModerationOptions, MountForumOptions, MountForumSearchOptions, MountMemberSettingsOptions, MountMyCommunityOptions, MountNoticeFormOptions, MountNotificationCentreOptions, MountProfileOptions, MountTopicOptions, MountWelcomeOptions } from './mount';
12
13
  export type KbDiscussionProps = Omit<MountDiscussionOptions, 'container'>;
13
14
  export type KbNoticeFormProps = Omit<MountNoticeFormOptions, 'container'>;
14
15
  export type KbMyCommunityProps = Omit<MountMyCommunityOptions, 'container'>;
@@ -17,6 +18,12 @@ export type KbBadgeProps = Omit<MountBadgeOptions, 'container'>;
17
18
  export type KbMemberSettingsProps = Omit<MountMemberSettingsOptions, 'container'>;
18
19
  export type KbProfileProps = Omit<MountProfileOptions, 'container'>;
19
20
  export type KbWelcomeProps = Omit<MountWelcomeOptions, 'container'>;
21
+ export type KbForumProps = Omit<MountForumOptions, 'container'>;
22
+ export type KbForumCategoryProps = Omit<MountForumCategoryOptions, 'container'>;
23
+ export type KbTopicProps = Omit<MountTopicOptions, 'container'>;
24
+ export type KbForumSearchProps = Omit<MountForumSearchOptions, 'container'>;
25
+ export type KbFollowButtonProps = Omit<MountFollowButtonOptions, 'container'>;
26
+ export type KbForumModerationProps = Omit<MountForumModerationOptions, 'container'>;
20
27
  export declare function KbDiscussion(props: KbDiscussionProps): ReactElement;
21
28
  export declare function KbNoticeForm(props: KbNoticeFormProps): ReactElement;
22
29
  export declare function KbMyCommunity(props: KbMyCommunityProps): ReactElement;
@@ -25,4 +32,10 @@ export declare function KbBadge(props: KbBadgeProps): ReactElement;
25
32
  export declare function KbMemberSettings(props: KbMemberSettingsProps): ReactElement;
26
33
  export declare function KbProfile(props: KbProfileProps): ReactElement;
27
34
  export declare function KbWelcome(props: KbWelcomeProps): ReactElement;
28
- export type { MountDiscussionOptions, MountNoticeFormOptions, MountMyCommunityOptions, MountNotificationCentreOptions, MountBadgeOptions, MountMemberSettingsOptions, MountProfileOptions, MountWelcomeOptions, };
35
+ export declare function KbForum(props: KbForumProps): ReactElement;
36
+ export declare function KbForumCategory(props: KbForumCategoryProps): ReactElement;
37
+ export declare function KbTopic(props: KbTopicProps): ReactElement;
38
+ export declare function KbForumSearch(props: KbForumSearchProps): ReactElement;
39
+ export declare function KbFollowButton(props: KbFollowButtonProps): ReactElement;
40
+ export declare function KbForumModeration(props: KbForumModerationProps): ReactElement;
41
+ export type { MountDiscussionOptions, MountNoticeFormOptions, MountMyCommunityOptions, MountNotificationCentreOptions, MountBadgeOptions, MountMemberSettingsOptions, MountProfileOptions, MountWelcomeOptions, MountForumOptions, MountForumCategoryOptions, MountTopicOptions, MountForumSearchOptions, MountFollowButtonOptions, MountForumModerationOptions, };
package/dist/react.js CHANGED
@@ -20,36 +20,60 @@ function useMounted(kind, props, load) {
20
20
  return createElement("div", { ref: host, "data-blogmcp-community": kind });
21
21
  }
22
22
  function KbDiscussion(props) {
23
- return useMounted("discussion", props, async () => (await import("./chunks/mount-WadUnaTa.js").then((n) => n.J)).mountDiscussion);
23
+ return useMounted("discussion", props, async () => (await import("./chunks/mount--2_V2q3M.js").then((n) => n.ad)).mountDiscussion);
24
24
  }
25
25
  function KbNoticeForm(props) {
26
- return useMounted("notice-form", props, async () => (await import("./chunks/mount-WadUnaTa.js").then((n) => n.J)).mountNoticeForm);
26
+ return useMounted("notice-form", props, async () => (await import("./chunks/mount--2_V2q3M.js").then((n) => n.ad)).mountNoticeForm);
27
27
  }
28
28
  function KbMyCommunity(props) {
29
- return useMounted("my-community", props, async () => (await import("./chunks/mount-WadUnaTa.js").then((n) => n.J)).mountMyCommunity);
29
+ return useMounted("my-community", props, async () => (await import("./chunks/mount--2_V2q3M.js").then((n) => n.ad)).mountMyCommunity);
30
30
  }
31
31
  function KbNotificationCentre(props) {
32
- return useMounted("notification-centre", props, async () => (await import("./chunks/mount-WadUnaTa.js").then((n) => n.J)).mountNotificationCentre);
32
+ return useMounted("notification-centre", props, async () => (await import("./chunks/mount--2_V2q3M.js").then((n) => n.ad)).mountNotificationCentre);
33
33
  }
34
34
  function KbBadge(props) {
35
- return useMounted("badge", props, async () => (await import("./chunks/mount-WadUnaTa.js").then((n) => n.J)).mountBadge);
35
+ return useMounted("badge", props, async () => (await import("./chunks/mount--2_V2q3M.js").then((n) => n.ad)).mountBadge);
36
36
  }
37
37
  function KbMemberSettings(props) {
38
- return useMounted("member-settings", props, async () => (await import("./chunks/mount-WadUnaTa.js").then((n) => n.J)).mountMemberSettings);
38
+ return useMounted("member-settings", props, async () => (await import("./chunks/mount--2_V2q3M.js").then((n) => n.ad)).mountMemberSettings);
39
39
  }
40
40
  function KbProfile(props) {
41
- return useMounted("profile", props, async () => (await import("./chunks/mount-WadUnaTa.js").then((n) => n.J)).mountProfile);
41
+ return useMounted("profile", props, async () => (await import("./chunks/mount--2_V2q3M.js").then((n) => n.ad)).mountProfile);
42
42
  }
43
43
  function KbWelcome(props) {
44
- return useMounted("welcome", props, async () => (await import("./chunks/mount-WadUnaTa.js").then((n) => n.J)).mountWelcome);
44
+ return useMounted("welcome", props, async () => (await import("./chunks/mount--2_V2q3M.js").then((n) => n.ad)).mountWelcome);
45
+ }
46
+ function KbForum(props) {
47
+ return useMounted("forum", props, async () => (await import("./chunks/mount--2_V2q3M.js").then((n) => n.ad)).mountForum);
48
+ }
49
+ function KbForumCategory(props) {
50
+ return useMounted("forum-category", props, async () => (await import("./chunks/mount--2_V2q3M.js").then((n) => n.ad)).mountForumCategory);
51
+ }
52
+ function KbTopic(props) {
53
+ return useMounted("topic", props, async () => (await import("./chunks/mount--2_V2q3M.js").then((n) => n.ad)).mountTopic);
54
+ }
55
+ function KbForumSearch(props) {
56
+ return useMounted("forum-search", props, async () => (await import("./chunks/mount--2_V2q3M.js").then((n) => n.ad)).mountForumSearch);
57
+ }
58
+ function KbFollowButton(props) {
59
+ return useMounted("follow-button", props, async () => (await import("./chunks/mount--2_V2q3M.js").then((n) => n.ad)).mountFollowButton);
60
+ }
61
+ function KbForumModeration(props) {
62
+ return useMounted("forum-moderation", props, async () => (await import("./chunks/mount--2_V2q3M.js").then((n) => n.ad)).mountForumModeration);
45
63
  }
46
64
  export {
47
65
  KbBadge,
48
66
  KbDiscussion,
67
+ KbFollowButton,
68
+ KbForum,
69
+ KbForumCategory,
70
+ KbForumModeration,
71
+ KbForumSearch,
49
72
  KbMemberSettings,
50
73
  KbMyCommunity,
51
74
  KbNoticeForm,
52
75
  KbNotificationCentre,
53
76
  KbProfile,
77
+ KbTopic,
54
78
  KbWelcome
55
79
  };
@@ -0,0 +1,17 @@
1
+ import { type CommunityTransport } from '@blogmcp/sdk/community';
2
+ type __VLS_Props = {
3
+ /** `conversation` (a topic, an article discussion) or `category`. */
4
+ targetKind?: string;
5
+ /** The conversation's or the category's id. */
6
+ targetId?: string;
7
+ /** `true` / `false` when the host knows whether the member follows it (absent: the member's follows are read). */
8
+ following?: string | boolean;
9
+ apiBase?: string;
10
+ siteBase?: string;
11
+ lang?: string;
12
+ transport?: CommunityTransport;
13
+ };
14
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
15
+ following: string | boolean;
16
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
17
+ export default _default;
@@ -0,0 +1,6 @@
1
+ import type { FollowController } from '../core/follow';
2
+ type __VLS_Props = {
3
+ ctl: FollowController;
4
+ };
5
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
+ export default _default;
@@ -0,0 +1,13 @@
1
+ import { type CommunityTransport } from '@blogmcp/sdk/community';
2
+ type __VLS_Props = {
3
+ /** The category's slug (`les-a-sber`). */
4
+ slug?: string;
5
+ apiBase?: string;
6
+ siteBase?: string;
7
+ lang?: string;
8
+ routes?: string | Record<string, unknown>;
9
+ signInHref?: string;
10
+ transport?: CommunityTransport;
11
+ };
12
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ export default _default;
@@ -0,0 +1,12 @@
1
+ import { type CommunityTransport } from '@blogmcp/sdk/community';
2
+ type __VLS_Props = {
3
+ /** Narrow the queue to one of the moderator's categories (its id). */
4
+ categoryId?: string;
5
+ apiBase?: string;
6
+ siteBase?: string;
7
+ lang?: string;
8
+ routes?: string | Record<string, unknown>;
9
+ transport?: CommunityTransport;
10
+ };
11
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
+ export default _default;
@@ -0,0 +1,7 @@
1
+ import type { MyState } from '@blogmcp/sdk/community';
2
+ type __VLS_Props = {
3
+ me: MyState | null;
4
+ now?: number;
5
+ };
6
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
7
+ export default _default;
@@ -0,0 +1,11 @@
1
+ import { type CommunityTransport } from '@blogmcp/sdk/community';
2
+ type __VLS_Props = {
3
+ apiBase?: string;
4
+ siteBase?: string;
5
+ lang?: string;
6
+ routes?: string | Record<string, unknown>;
7
+ signInHref?: string;
8
+ transport?: CommunityTransport;
9
+ };
10
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
11
+ export default _default;
@@ -0,0 +1,12 @@
1
+ import { type CommunityTransport } from '@blogmcp/sdk/community';
2
+ type __VLS_Props = {
3
+ apiBase?: string;
4
+ siteBase?: string;
5
+ lang?: string;
6
+ /** JSON (or an object): the host's pages — `forumPath`, `categoryPath`, `topicPath`, `searchPath`, `rulesPath`, … */
7
+ routes?: string | Record<string, unknown>;
8
+ signInHref?: string;
9
+ transport?: CommunityTransport;
10
+ };
11
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
+ export default _default;
@@ -0,0 +1,15 @@
1
+ import { type CommunityClient, type CommunityFailure } from '@blogmcp/sdk/community';
2
+ import type { Lang } from '../core/i18n';
3
+ type __VLS_Props = {
4
+ failure: CommunityFailure | null;
5
+ client: CommunityClient;
6
+ lang: Lang;
7
+ signInHref?: string;
8
+ rulesHref: string;
9
+ };
10
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
11
+ joined: () => any;
12
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
13
+ onJoined?: (() => any) | undefined;
14
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
+ export default _default;
@@ -1,7 +1,11 @@
1
1
  import type { Draft } from '../core/discussion';
2
2
  type __VLS_Props = {
3
- draft: Draft;
4
- kind: 'new' | 'reply' | 'edit';
3
+ /** M3: `title` (a string) asks for a topic's title too; null or absent: no title. */
4
+ draft: Draft & {
5
+ title?: string | null;
6
+ };
7
+ /** M3: `topic` — a new topic (the title and its opening post). */
8
+ kind: 'new' | 'reply' | 'edit' | 'topic';
5
9
  /** Seconds the draft still waits (the controller's clock). */
6
10
  wait: number;
7
11
  replyingTo?: string | null;
@@ -1,6 +1,8 @@
1
1
  import type { MenuItem } from './types';
2
+ /** M3: the toggle's own text (a topic's moderator menu); absent: „Další akce". */
2
3
  type __VLS_Props = {
3
4
  items: MenuItem[];
5
+ label?: string;
4
6
  };
5
7
  declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
6
8
  select: (id: string) => any;
@@ -0,0 +1,11 @@
1
+ import type { TopicController } from '../core/topic';
2
+ type __VLS_Props = {
3
+ ctl: TopicController;
4
+ fallbackFocus?: () => HTMLElement | null;
5
+ };
6
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
7
+ close: () => any;
8
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
9
+ onClose?: (() => any) | undefined;
10
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
11
+ export default _default;
@@ -0,0 +1,10 @@
1
+ import { type KnownTopicItem } from '@blogmcp/sdk/community';
2
+ import type { FollowController } from '../core/follow';
3
+ type __VLS_Props = {
4
+ item: KnownTopicItem;
5
+ topicHref: string;
6
+ articleHref?: string | null;
7
+ follow?: FollowController | null;
8
+ };
9
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
10
+ export default _default;
@@ -0,0 +1,32 @@
1
+ import { type CommunityTransport } from '@blogmcp/sdk/community';
2
+ import type { TopicRealtime } from '../core/realtime';
3
+ declare const _default: import("vue").DefineComponent<{
4
+ /** The topic's conversation id. */
5
+ conversationId?: string;
6
+ apiBase?: string;
7
+ siteBase?: string;
8
+ lang?: string;
9
+ signInHref?: string;
10
+ /** JSON (or an object): the host's pages — `forumPath`, `categoryPath`, `topicPath`, `rulesPath`, `myCommunityPath`, … */
11
+ routes?: string | Record<string, unknown>;
12
+ /** Head poll interval in ms (default 20 000; 0 = off). */
13
+ pollMs?: number;
14
+ transport?: CommunityTransport;
15
+ /** Live updates — `createRealtimeSession` of `@blogmcp/sdk/community/realtime`, a property. Absent: the head poll. */
16
+ realtime?: TopicRealtime;
17
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{
18
+ /** The topic's conversation id. */
19
+ conversationId?: string;
20
+ apiBase?: string;
21
+ siteBase?: string;
22
+ lang?: string;
23
+ signInHref?: string;
24
+ /** JSON (or an object): the host's pages — `forumPath`, `categoryPath`, `topicPath`, `rulesPath`, `myCommunityPath`, … */
25
+ routes?: string | Record<string, unknown>;
26
+ /** Head poll interval in ms (default 20 000; 0 = off). */
27
+ pollMs?: number;
28
+ transport?: CommunityTransport;
29
+ /** Live updates — `createRealtimeSession` of `@blogmcp/sdk/community/realtime`, a property. Absent: the head poll. */
30
+ realtime?: TopicRealtime;
31
+ }> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
32
+ export default _default;
@@ -3,6 +3,7 @@
3
3
  * `communityMessage` and nothing else), ids unique to the element, and the dialog's focus handling.
4
4
  */
5
5
  import { type Ref } from 'vue';
6
+ import { type CommunityMessageKey } from '@blogmcp/sdk/community';
6
7
  import type { Lang, TextRef, Translate } from '../core/i18n';
7
8
  export interface TextContext {
8
9
  lang: Ref<Lang>;
@@ -10,7 +11,12 @@ export interface TextContext {
10
11
  /** A TextRef (a controller's outcome) as text. */
11
12
  text(ref: TextRef | null | undefined): string;
12
13
  }
13
- export declare function provideText(lang: Ref<Lang>): TextContext;
14
+ /**
15
+ * The element's texts. `words` (M3) maps a key the shared components name to another key of the catalogue — a topic's
16
+ * thread reads the discussion's components with the forum's words (`composer.label` → `forumText.composer.label`, a
17
+ * post, not a comment) — and a plural key maps by its name without the suffix.
18
+ */
19
+ export declare function provideText(lang: Ref<Lang>, words?: Readonly<Partial<Record<CommunityMessageKey, CommunityMessageKey>>>): TextContext;
14
20
  export declare function useText(): TextContext;
15
21
  /** An id unique on the page (ids live in each element's shadow root, but the labels reference them). */
16
22
  export declare function uid(prefix: string): string;