@btst/stack 2.11.7 → 2.11.8

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 (43) hide show
  1. package/dist/packages/stack/src/plugins/blog/client/components/pages/post-page.internal.cjs +2 -6
  2. package/dist/packages/stack/src/plugins/blog/client/components/pages/post-page.internal.mjs +5 -9
  3. package/dist/packages/stack/src/plugins/blog/client/components/shared/collapsible-tag-list.cjs +44 -0
  4. package/dist/packages/stack/src/plugins/blog/client/components/shared/collapsible-tag-list.mjs +42 -0
  5. package/dist/packages/stack/src/plugins/blog/client/components/shared/tags-list.cjs +2 -8
  6. package/dist/packages/stack/src/plugins/blog/client/components/shared/tags-list.mjs +2 -8
  7. package/dist/packages/stack/src/plugins/blog/client/localization/blog-common.cjs +3 -1
  8. package/dist/packages/stack/src/plugins/blog/client/localization/blog-common.mjs +3 -1
  9. package/dist/plugins/blog/api/index.d.cts +2 -2
  10. package/dist/plugins/blog/api/index.d.mts +2 -2
  11. package/dist/plugins/blog/api/index.d.ts +2 -2
  12. package/dist/plugins/blog/client/hooks/index.d.cts +2 -2
  13. package/dist/plugins/blog/client/hooks/index.d.mts +2 -2
  14. package/dist/plugins/blog/client/hooks/index.d.ts +2 -2
  15. package/dist/plugins/blog/client/index.d.cts +4 -2
  16. package/dist/plugins/blog/client/index.d.mts +4 -2
  17. package/dist/plugins/blog/client/index.d.ts +4 -2
  18. package/dist/plugins/blog/query-keys.d.cts +2 -2
  19. package/dist/plugins/blog/query-keys.d.mts +2 -2
  20. package/dist/plugins/blog/query-keys.d.ts +2 -2
  21. package/dist/plugins/kanban/api/index.d.cts +1 -1
  22. package/dist/plugins/kanban/api/index.d.mts +1 -1
  23. package/dist/plugins/kanban/api/index.d.ts +1 -1
  24. package/dist/plugins/kanban/query-keys.d.cts +1 -1
  25. package/dist/plugins/kanban/query-keys.d.mts +1 -1
  26. package/dist/plugins/kanban/query-keys.d.ts +1 -1
  27. package/dist/shared/{stack.CLWhMntf.d.cts → stack.04aMRz_W.d.cts} +5 -5
  28. package/dist/shared/{stack.DNLuzDb3.d.cts → stack.BvuqACtA.d.cts} +3 -3
  29. package/dist/shared/{stack.Dfc44JiE.d.mts → stack.Cs8R5HxD.d.mts} +3 -3
  30. package/dist/shared/{stack.ufcExQIR.d.ts → stack.CxWEN62M.d.ts} +5 -5
  31. package/dist/shared/{stack.BnSAhKJi.d.ts → stack.DPTRuLUH.d.ts} +3 -3
  32. package/dist/shared/{stack.DiodAFAa.d.mts → stack.ueI-K4xy.d.mts} +5 -5
  33. package/package.json +1 -1
  34. package/src/plugins/blog/client/components/pages/post-page.internal.tsx +4 -21
  35. package/src/plugins/blog/client/components/shared/collapsible-tag-list.tsx +76 -0
  36. package/src/plugins/blog/client/components/shared/tags-list.tsx +2 -18
  37. package/src/plugins/blog/client/localization/blog-common.ts +2 -0
  38. package/dist/shared/{stack.Rtcvl8sS.d.cts → stack.B6S3cgwN.d.cts} +13 -13
  39. package/dist/shared/{stack.HE_IvqV5.d.mts → stack.Bzfx-_lq.d.mts} +13 -13
  40. package/dist/shared/{stack.CuhcFsAx.d.ts → stack.DuQOcInS.d.cts} +3 -3
  41. package/dist/shared/{stack.CuhcFsAx.d.cts → stack.DuQOcInS.d.mts} +3 -3
  42. package/dist/shared/{stack.CuhcFsAx.d.mts → stack.DuQOcInS.d.ts} +3 -3
  43. package/dist/shared/{stack.D4Cea8II.d.ts → stack.j5SFLC1d.d.ts} +13 -13
@@ -13,13 +13,13 @@ const defaults = require('../shared/defaults.cjs');
13
13
  const index = require('../../localization/index.cjs');
14
14
  const postNavigation = require('../shared/post-navigation.cjs');
15
15
  const recentPostsCarousel = require('../shared/recent-posts-carousel.cjs');
16
- const badge = require('../../../../../../../ui/src/components/badge.cjs');
17
16
  const useRouteLifecycle = require('../../../../../../../ui/src/hooks/use-route-lifecycle.cjs');
18
17
  const onThisPage = require('../shared/on-this-page.cjs');
19
18
  const context$1 = require('@btst/stack/plugins/ai-chat/client/context');
20
19
  const whenVisible = require('../../../../../../../ui/src/components/when-visible.cjs');
21
20
  const postNavigationSkeleton = require('../loading/post-navigation-skeleton.cjs');
22
21
  const recentPostsCarouselSkeleton = require('../loading/recent-posts-carousel-skeleton.cjs');
22
+ const collapsibleTagList = require('../shared/collapsible-tag-list.cjs');
23
23
 
24
24
  function PostPage({ slug }) {
25
25
  const overrides = context.usePluginOverrides("blog", {
@@ -119,13 +119,9 @@ ${post.content ?? ""}`.slice(
119
119
  ] }) });
120
120
  }
121
121
  function PostHeaderTop({ post }) {
122
- const { Link } = context.usePluginOverrides("blog", {
123
- Link: defaults.DefaultLink
124
- });
125
- const basePath = context.useBasePath();
126
122
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-row items-center justify-center gap-2 flex-wrap mt-8", children: [
127
123
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-light text-muted-foreground text-sm", children: dateFns.formatDate(post.createdAt, "MMMM d, yyyy") }),
128
- post.tags && post.tags.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: post.tags.map((tag) => /* @__PURE__ */ jsxRuntime.jsx(Link, { href: `${basePath}/blog/tag/${tag.slug}`, children: /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { variant: "secondary", className: "text-xs", children: tag.name }) }, tag.id)) })
124
+ /* @__PURE__ */ jsxRuntime.jsx(collapsibleTagList.CollapsibleTagList, { tags: post.tags ?? [] })
129
125
  ] });
130
126
  }
131
127
 
@@ -1,23 +1,23 @@
1
1
  "use client";
2
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
- import { usePluginOverrides, useBasePath } from '@btst/stack/context';
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import { usePluginOverrides } from '@btst/stack/context';
4
4
  import { formatDate } from 'date-fns';
5
5
  import { useSuspensePost, useNextPreviousPosts, useRecentPosts } from '../../hooks/blog-hooks.mjs';
6
6
  import { EmptyList } from '../shared/empty-list.mjs';
7
7
  import { MarkdownContent } from '../shared/markdown-content.mjs';
8
8
  import { PageHeader } from '../shared/page-header.mjs';
9
9
  import { PageWrapper } from '../shared/page-wrapper.mjs';
10
- import { DefaultImage, DefaultLink } from '../shared/defaults.mjs';
10
+ import { DefaultImage } from '../shared/defaults.mjs';
11
11
  import { BLOG_LOCALIZATION } from '../../localization/index.mjs';
12
12
  import { PostNavigation } from '../shared/post-navigation.mjs';
13
13
  import { RecentPostsCarousel } from '../shared/recent-posts-carousel.mjs';
14
- import { Badge } from '../../../../../../../ui/src/components/badge.mjs';
15
14
  import { useRouteLifecycle } from '../../../../../../../ui/src/hooks/use-route-lifecycle.mjs';
16
15
  import { OnThisPageSelect, OnThisPage } from '../shared/on-this-page.mjs';
17
16
  import { useRegisterPageAIContext } from '@btst/stack/plugins/ai-chat/client/context';
18
17
  import { WhenVisible } from '../../../../../../../ui/src/components/when-visible.mjs';
19
18
  import { PostNavigationSkeleton } from '../loading/post-navigation-skeleton.mjs';
20
19
  import { RecentPostsCarouselSkeleton } from '../loading/recent-posts-carousel-skeleton.mjs';
20
+ import { CollapsibleTagList } from '../shared/collapsible-tag-list.mjs';
21
21
 
22
22
  function PostPage({ slug }) {
23
23
  const overrides = usePluginOverrides("blog", {
@@ -117,13 +117,9 @@ ${post.content ?? ""}`.slice(
117
117
  ] }) });
118
118
  }
119
119
  function PostHeaderTop({ post }) {
120
- const { Link } = usePluginOverrides("blog", {
121
- Link: DefaultLink
122
- });
123
- const basePath = useBasePath();
124
120
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-row items-center justify-center gap-2 flex-wrap mt-8", children: [
125
121
  /* @__PURE__ */ jsx("span", { className: "font-light text-muted-foreground text-sm", children: formatDate(post.createdAt, "MMMM d, yyyy") }),
126
- post.tags && post.tags.length > 0 && /* @__PURE__ */ jsx(Fragment, { children: post.tags.map((tag) => /* @__PURE__ */ jsx(Link, { href: `${basePath}/blog/tag/${tag.slug}`, children: /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs", children: tag.name }) }, tag.id)) })
122
+ /* @__PURE__ */ jsx(CollapsibleTagList, { tags: post.tags ?? [] })
127
123
  ] });
128
124
  }
129
125
 
@@ -0,0 +1,44 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const context = require('@btst/stack/context');
6
+ const defaults = require('./defaults.cjs');
7
+ const badge = require('../../../../../../../ui/src/components/badge.cjs');
8
+ const index = require('../../localization/index.cjs');
9
+ const LucideIcons = require('lucide-react');
10
+ const React = require('react');
11
+
12
+ const MAX_VISIBLE_TAGS = 15;
13
+ function CollapsibleTagList({
14
+ tags,
15
+ maxVisible = MAX_VISIBLE_TAGS
16
+ }) {
17
+ const { Link, localization } = context.usePluginOverrides("blog", {
18
+ Link: defaults.DefaultLink,
19
+ localization: index.BLOG_LOCALIZATION
20
+ });
21
+ const basePath = context.useBasePath();
22
+ const [showAll, setShowAll] = React.useState(false);
23
+ if (!tags || tags.length === 0) {
24
+ return null;
25
+ }
26
+ const hasMore = tags.length > maxVisible;
27
+ const visibleTags = showAll || !hasMore ? tags : tags.slice(0, maxVisible);
28
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
29
+ visibleTags.map((tag) => /* @__PURE__ */ jsxRuntime.jsx(Link, { href: `${basePath}/blog/tag/${tag.slug}`, children: /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { variant: "secondary", className: "text-xs", children: tag.name }) }, tag.id)),
30
+ hasMore && /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { asChild: true, variant: "secondary", className: "text-xs cursor-pointer", children: /* @__PURE__ */ jsxRuntime.jsx(
31
+ "button",
32
+ {
33
+ type: "button",
34
+ onClick: () => setShowAll((prev) => !prev),
35
+ "aria-expanded": showAll,
36
+ "aria-label": showAll ? localization.BLOG_TAGS_SHOW_LESS : localization.BLOG_TAGS_SHOW_ALL,
37
+ title: showAll ? localization.BLOG_TAGS_SHOW_LESS : localization.BLOG_TAGS_SHOW_ALL,
38
+ children: showAll ? /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.ChevronUp, { "aria-hidden": "true" }) : /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.ChevronDown, { "aria-hidden": "true" })
39
+ }
40
+ ) })
41
+ ] });
42
+ }
43
+
44
+ exports.CollapsibleTagList = CollapsibleTagList;
@@ -0,0 +1,42 @@
1
+ "use client";
2
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
+ import { usePluginOverrides, useBasePath } from '@btst/stack/context';
4
+ import { DefaultLink } from './defaults.mjs';
5
+ import { Badge } from '../../../../../../../ui/src/components/badge.mjs';
6
+ import { BLOG_LOCALIZATION } from '../../localization/index.mjs';
7
+ import { ChevronUp, ChevronDown } from 'lucide-react';
8
+ import { useState } from 'react';
9
+
10
+ const MAX_VISIBLE_TAGS = 15;
11
+ function CollapsibleTagList({
12
+ tags,
13
+ maxVisible = MAX_VISIBLE_TAGS
14
+ }) {
15
+ const { Link, localization } = usePluginOverrides("blog", {
16
+ Link: DefaultLink,
17
+ localization: BLOG_LOCALIZATION
18
+ });
19
+ const basePath = useBasePath();
20
+ const [showAll, setShowAll] = useState(false);
21
+ if (!tags || tags.length === 0) {
22
+ return null;
23
+ }
24
+ const hasMore = tags.length > maxVisible;
25
+ const visibleTags = showAll || !hasMore ? tags : tags.slice(0, maxVisible);
26
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
27
+ visibleTags.map((tag) => /* @__PURE__ */ jsx(Link, { href: `${basePath}/blog/tag/${tag.slug}`, children: /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs", children: tag.name }) }, tag.id)),
28
+ hasMore && /* @__PURE__ */ jsx(Badge, { asChild: true, variant: "secondary", className: "text-xs cursor-pointer", children: /* @__PURE__ */ jsx(
29
+ "button",
30
+ {
31
+ type: "button",
32
+ onClick: () => setShowAll((prev) => !prev),
33
+ "aria-expanded": showAll,
34
+ "aria-label": showAll ? localization.BLOG_TAGS_SHOW_LESS : localization.BLOG_TAGS_SHOW_ALL,
35
+ title: showAll ? localization.BLOG_TAGS_SHOW_LESS : localization.BLOG_TAGS_SHOW_ALL,
36
+ children: showAll ? /* @__PURE__ */ jsx(ChevronUp, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true" })
37
+ }
38
+ ) })
39
+ ] });
40
+ }
41
+
42
+ export { CollapsibleTagList };
@@ -2,21 +2,15 @@
2
2
  'use strict';
3
3
 
4
4
  const jsxRuntime = require('react/jsx-runtime');
5
- const context = require('@btst/stack/context');
6
- const defaults = require('./defaults.cjs');
7
- const badge = require('../../../../../../../ui/src/components/badge.cjs');
8
5
  const blogHooks = require('../../hooks/blog-hooks.cjs');
6
+ const collapsibleTagList = require('./collapsible-tag-list.cjs');
9
7
 
10
8
  function TagsList() {
11
9
  const { tags } = blogHooks.useSuspenseTags();
12
- const { Link } = context.usePluginOverrides("blog", {
13
- Link: defaults.DefaultLink
14
- });
15
- const basePath = context.useBasePath();
16
10
  if (!tags || tags.length === 0) {
17
11
  return null;
18
12
  }
19
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2 justify-center", children: tags.map((tag) => /* @__PURE__ */ jsxRuntime.jsx(Link, { href: `${basePath}/blog/tag/${tag.slug}`, children: /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { variant: "secondary", className: "text-xs", children: tag.name }) }, tag.id)) });
13
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2 justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(collapsibleTagList.CollapsibleTagList, { tags }) });
20
14
  }
21
15
 
22
16
  exports.TagsList = TagsList;
@@ -1,20 +1,14 @@
1
1
  "use client";
2
2
  import { jsx } from 'react/jsx-runtime';
3
- import { usePluginOverrides, useBasePath } from '@btst/stack/context';
4
- import { DefaultLink } from './defaults.mjs';
5
- import { Badge } from '../../../../../../../ui/src/components/badge.mjs';
6
3
  import { useSuspenseTags } from '../../hooks/blog-hooks.mjs';
4
+ import { CollapsibleTagList } from './collapsible-tag-list.mjs';
7
5
 
8
6
  function TagsList() {
9
7
  const { tags } = useSuspenseTags();
10
- const { Link } = usePluginOverrides("blog", {
11
- Link: DefaultLink
12
- });
13
- const basePath = useBasePath();
14
8
  if (!tags || tags.length === 0) {
15
9
  return null;
16
10
  }
17
- return /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2 justify-center", children: tags.map((tag) => /* @__PURE__ */ jsx(Link, { href: `${basePath}/blog/tag/${tag.slug}`, children: /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs", children: tag.name }) }, tag.id)) });
11
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2 justify-center", children: /* @__PURE__ */ jsx(CollapsibleTagList, { tags }) });
18
12
  }
19
13
 
20
14
  export { TagsList };
@@ -4,7 +4,9 @@ const BLOG_COMMON = {
4
4
  BLOG_GENERIC_ERROR_TITLE: "Something went wrong",
5
5
  BLOG_GENERIC_ERROR_MESSAGE: "An unexpected error occurred.",
6
6
  BLOG_PAGE_NOT_FOUND_TITLE: "Not Found",
7
- BLOG_PAGE_NOT_FOUND_DESCRIPTION: "The page you are looking for does not exist."
7
+ BLOG_PAGE_NOT_FOUND_DESCRIPTION: "The page you are looking for does not exist.",
8
+ BLOG_TAGS_SHOW_ALL: "Show all tags",
9
+ BLOG_TAGS_SHOW_LESS: "Show fewer tags"
8
10
  };
9
11
 
10
12
  exports.BLOG_COMMON = BLOG_COMMON;
@@ -2,7 +2,9 @@ const BLOG_COMMON = {
2
2
  BLOG_GENERIC_ERROR_TITLE: "Something went wrong",
3
3
  BLOG_GENERIC_ERROR_MESSAGE: "An unexpected error occurred.",
4
4
  BLOG_PAGE_NOT_FOUND_TITLE: "Not Found",
5
- BLOG_PAGE_NOT_FOUND_DESCRIPTION: "The page you are looking for does not exist."
5
+ BLOG_PAGE_NOT_FOUND_DESCRIPTION: "The page you are looking for does not exist.",
6
+ BLOG_TAGS_SHOW_ALL: "Show all tags",
7
+ BLOG_TAGS_SHOW_LESS: "Show fewer tags"
6
8
  };
7
9
 
8
10
  export { BLOG_COMMON };
@@ -1,4 +1,4 @@
1
- export { B as BLOG_QUERY_KEYS, j as BlogApiContext, m as BlogApiRouter, k as BlogBackendHooks, h as BlogRouteKey, C as CreatePostInput, N as NextPreviousPostsQuerySchema, P as PostListParams, i as PostListQuerySchema, c as PostListResult, U as UpdatePostInput, l as blogBackendPlugin, f as createBlogQueryKeys, d as createPost, e as deletePost, g as getAllPosts, b as getAllTags, a as getPostBySlug, u as updatePost } from '../../../shared/stack.CLWhMntf.cjs';
1
+ export { B as BLOG_QUERY_KEYS, j as BlogApiContext, m as BlogApiRouter, k as BlogBackendHooks, h as BlogRouteKey, C as CreatePostInput, N as NextPreviousPostsQuerySchema, P as PostListParams, i as PostListQuerySchema, c as PostListResult, U as UpdatePostInput, l as blogBackendPlugin, f as createBlogQueryKeys, d as createPost, e as deletePost, g as getAllPosts, b as getAllTags, a as getPostBySlug, u as updatePost } from '../../../shared/stack.04aMRz_W.cjs';
2
2
  import { P as Post, T as Tag, S as SerializedPost, a as SerializedTag } from '../../../shared/stack.Dsatjh0B.cjs';
3
3
  import '@tanstack/react-query';
4
4
  import '@btst/stack/plugins/client';
@@ -6,7 +6,7 @@ import '@btst/stack/plugins/api';
6
6
  import '@btst/db';
7
7
  import 'better-call';
8
8
  import 'zod';
9
- import '../../../shared/stack.CuhcFsAx.cjs';
9
+ import '../../../shared/stack.DuQOcInS.cjs';
10
10
 
11
11
  /**
12
12
  * Serialize a Tag for SSR/SSG use (convert dates to strings).
@@ -1,4 +1,4 @@
1
- export { B as BLOG_QUERY_KEYS, j as BlogApiContext, m as BlogApiRouter, k as BlogBackendHooks, h as BlogRouteKey, C as CreatePostInput, N as NextPreviousPostsQuerySchema, P as PostListParams, i as PostListQuerySchema, c as PostListResult, U as UpdatePostInput, l as blogBackendPlugin, f as createBlogQueryKeys, d as createPost, e as deletePost, g as getAllPosts, b as getAllTags, a as getPostBySlug, u as updatePost } from '../../../shared/stack.DiodAFAa.mjs';
1
+ export { B as BLOG_QUERY_KEYS, j as BlogApiContext, m as BlogApiRouter, k as BlogBackendHooks, h as BlogRouteKey, C as CreatePostInput, N as NextPreviousPostsQuerySchema, P as PostListParams, i as PostListQuerySchema, c as PostListResult, U as UpdatePostInput, l as blogBackendPlugin, f as createBlogQueryKeys, d as createPost, e as deletePost, g as getAllPosts, b as getAllTags, a as getPostBySlug, u as updatePost } from '../../../shared/stack.ueI-K4xy.mjs';
2
2
  import { P as Post, T as Tag, S as SerializedPost, a as SerializedTag } from '../../../shared/stack.Dsatjh0B.mjs';
3
3
  import '@tanstack/react-query';
4
4
  import '@btst/stack/plugins/client';
@@ -6,7 +6,7 @@ import '@btst/stack/plugins/api';
6
6
  import '@btst/db';
7
7
  import 'better-call';
8
8
  import 'zod';
9
- import '../../../shared/stack.CuhcFsAx.mjs';
9
+ import '../../../shared/stack.DuQOcInS.mjs';
10
10
 
11
11
  /**
12
12
  * Serialize a Tag for SSR/SSG use (convert dates to strings).
@@ -1,4 +1,4 @@
1
- export { B as BLOG_QUERY_KEYS, j as BlogApiContext, m as BlogApiRouter, k as BlogBackendHooks, h as BlogRouteKey, C as CreatePostInput, N as NextPreviousPostsQuerySchema, P as PostListParams, i as PostListQuerySchema, c as PostListResult, U as UpdatePostInput, l as blogBackendPlugin, f as createBlogQueryKeys, d as createPost, e as deletePost, g as getAllPosts, b as getAllTags, a as getPostBySlug, u as updatePost } from '../../../shared/stack.ufcExQIR.js';
1
+ export { B as BLOG_QUERY_KEYS, j as BlogApiContext, m as BlogApiRouter, k as BlogBackendHooks, h as BlogRouteKey, C as CreatePostInput, N as NextPreviousPostsQuerySchema, P as PostListParams, i as PostListQuerySchema, c as PostListResult, U as UpdatePostInput, l as blogBackendPlugin, f as createBlogQueryKeys, d as createPost, e as deletePost, g as getAllPosts, b as getAllTags, a as getPostBySlug, u as updatePost } from '../../../shared/stack.CxWEN62M.js';
2
2
  import { P as Post, T as Tag, S as SerializedPost, a as SerializedTag } from '../../../shared/stack.Dsatjh0B.js';
3
3
  import '@tanstack/react-query';
4
4
  import '@btst/stack/plugins/client';
@@ -6,7 +6,7 @@ import '@btst/stack/plugins/api';
6
6
  import '@btst/db';
7
7
  import 'better-call';
8
8
  import 'zod';
9
- import '../../../shared/stack.CuhcFsAx.js';
9
+ import '../../../shared/stack.DuQOcInS.js';
10
10
 
11
11
  /**
12
12
  * Serialize a Tag for SSR/SSG use (convert dates to strings).
@@ -1,8 +1,8 @@
1
- export { P as PostCreateInput, e as PostUpdateInput, o as UseNextPreviousPostsOptions, p as UseNextPreviousPostsResult, d as UsePostResult, b as UsePostSearchOptions, c as UsePostSearchResult, U as UsePostsOptions, a as UsePostsResult, r as UseRecentPostsOptions, s as UseRecentPostsResult, k as useCreatePost, m as useDeletePost, q as useNextPreviousPosts, g as usePost, n as usePostSearch, u as usePosts, t as useRecentPosts, h as useSuspensePost, f as useSuspensePosts, j as useSuspenseTags, i as useTags, l as useUpdatePost } from '../../../../shared/stack.DNLuzDb3.cjs';
1
+ export { P as PostCreateInput, e as PostUpdateInput, o as UseNextPreviousPostsOptions, p as UseNextPreviousPostsResult, d as UsePostResult, b as UsePostSearchOptions, c as UsePostSearchResult, U as UsePostsOptions, a as UsePostsResult, r as UseRecentPostsOptions, s as UseRecentPostsResult, k as useCreatePost, m as useDeletePost, q as useNextPreviousPosts, g as usePost, n as usePostSearch, u as usePosts, t as useRecentPosts, h as useSuspensePost, f as useSuspensePosts, j as useSuspenseTags, i as useTags, l as useUpdatePost } from '../../../../shared/stack.BvuqACtA.cjs';
2
2
  import '@tanstack/react-query';
3
3
  import '../../../../shared/stack.Dsatjh0B.cjs';
4
4
  import 'zod';
5
- import '../../../../shared/stack.CuhcFsAx.cjs';
5
+ import '../../../../shared/stack.DuQOcInS.cjs';
6
6
 
7
7
  declare function useDebounce<T>(value: T, delay?: number): T;
8
8
  declare function useThrottle<T>(value: T, wait?: number): T;
@@ -1,8 +1,8 @@
1
- export { P as PostCreateInput, e as PostUpdateInput, o as UseNextPreviousPostsOptions, p as UseNextPreviousPostsResult, d as UsePostResult, b as UsePostSearchOptions, c as UsePostSearchResult, U as UsePostsOptions, a as UsePostsResult, r as UseRecentPostsOptions, s as UseRecentPostsResult, k as useCreatePost, m as useDeletePost, q as useNextPreviousPosts, g as usePost, n as usePostSearch, u as usePosts, t as useRecentPosts, h as useSuspensePost, f as useSuspensePosts, j as useSuspenseTags, i as useTags, l as useUpdatePost } from '../../../../shared/stack.Dfc44JiE.mjs';
1
+ export { P as PostCreateInput, e as PostUpdateInput, o as UseNextPreviousPostsOptions, p as UseNextPreviousPostsResult, d as UsePostResult, b as UsePostSearchOptions, c as UsePostSearchResult, U as UsePostsOptions, a as UsePostsResult, r as UseRecentPostsOptions, s as UseRecentPostsResult, k as useCreatePost, m as useDeletePost, q as useNextPreviousPosts, g as usePost, n as usePostSearch, u as usePosts, t as useRecentPosts, h as useSuspensePost, f as useSuspensePosts, j as useSuspenseTags, i as useTags, l as useUpdatePost } from '../../../../shared/stack.Cs8R5HxD.mjs';
2
2
  import '@tanstack/react-query';
3
3
  import '../../../../shared/stack.Dsatjh0B.mjs';
4
4
  import 'zod';
5
- import '../../../../shared/stack.CuhcFsAx.mjs';
5
+ import '../../../../shared/stack.DuQOcInS.mjs';
6
6
 
7
7
  declare function useDebounce<T>(value: T, delay?: number): T;
8
8
  declare function useThrottle<T>(value: T, wait?: number): T;
@@ -1,8 +1,8 @@
1
- export { P as PostCreateInput, e as PostUpdateInput, o as UseNextPreviousPostsOptions, p as UseNextPreviousPostsResult, d as UsePostResult, b as UsePostSearchOptions, c as UsePostSearchResult, U as UsePostsOptions, a as UsePostsResult, r as UseRecentPostsOptions, s as UseRecentPostsResult, k as useCreatePost, m as useDeletePost, q as useNextPreviousPosts, g as usePost, n as usePostSearch, u as usePosts, t as useRecentPosts, h as useSuspensePost, f as useSuspensePosts, j as useSuspenseTags, i as useTags, l as useUpdatePost } from '../../../../shared/stack.BnSAhKJi.js';
1
+ export { P as PostCreateInput, e as PostUpdateInput, o as UseNextPreviousPostsOptions, p as UseNextPreviousPostsResult, d as UsePostResult, b as UsePostSearchOptions, c as UsePostSearchResult, U as UsePostsOptions, a as UsePostsResult, r as UseRecentPostsOptions, s as UseRecentPostsResult, k as useCreatePost, m as useDeletePost, q as useNextPreviousPosts, g as usePost, n as usePostSearch, u as usePosts, t as useRecentPosts, h as useSuspensePost, f as useSuspensePosts, j as useSuspenseTags, i as useTags, l as useUpdatePost } from '../../../../shared/stack.DPTRuLUH.js';
2
2
  import '@tanstack/react-query';
3
3
  import '../../../../shared/stack.Dsatjh0B.js';
4
4
  import 'zod';
5
- import '../../../../shared/stack.CuhcFsAx.js';
5
+ import '../../../../shared/stack.DuQOcInS.js';
6
6
 
7
7
  declare function useDebounce<T>(value: T, delay?: number): T;
8
8
  declare function useThrottle<T>(value: T, wait?: number): T;
@@ -3,9 +3,9 @@ import * as _btst_yar from '@btst/yar';
3
3
  import { ComponentType, ReactNode } from 'react';
4
4
  import { QueryClient } from '@tanstack/react-query';
5
5
  import { P as Post, S as SerializedPost } from '../../../shared/stack.Dsatjh0B.cjs';
6
- export { U as UsePostsOptions, a as UsePostsResult } from '../../../shared/stack.DNLuzDb3.cjs';
6
+ export { U as UsePostsOptions, a as UsePostsResult } from '../../../shared/stack.BvuqACtA.cjs';
7
7
  import 'zod';
8
- import '../../../shared/stack.CuhcFsAx.cjs';
8
+ import '../../../shared/stack.DuQOcInS.cjs';
9
9
 
10
10
  /**
11
11
  * Context passed to route hooks
@@ -390,6 +390,8 @@ declare const BLOG_LOCALIZATION: {
390
390
  BLOG_GENERIC_ERROR_MESSAGE: string;
391
391
  BLOG_PAGE_NOT_FOUND_TITLE: string;
392
392
  BLOG_PAGE_NOT_FOUND_DESCRIPTION: string;
393
+ BLOG_TAGS_SHOW_ALL: string;
394
+ BLOG_TAGS_SHOW_LESS: string;
393
395
  };
394
396
  type BlogLocalization = typeof BLOG_LOCALIZATION;
395
397
 
@@ -3,9 +3,9 @@ import * as _btst_yar from '@btst/yar';
3
3
  import { ComponentType, ReactNode } from 'react';
4
4
  import { QueryClient } from '@tanstack/react-query';
5
5
  import { P as Post, S as SerializedPost } from '../../../shared/stack.Dsatjh0B.mjs';
6
- export { U as UsePostsOptions, a as UsePostsResult } from '../../../shared/stack.Dfc44JiE.mjs';
6
+ export { U as UsePostsOptions, a as UsePostsResult } from '../../../shared/stack.Cs8R5HxD.mjs';
7
7
  import 'zod';
8
- import '../../../shared/stack.CuhcFsAx.mjs';
8
+ import '../../../shared/stack.DuQOcInS.mjs';
9
9
 
10
10
  /**
11
11
  * Context passed to route hooks
@@ -390,6 +390,8 @@ declare const BLOG_LOCALIZATION: {
390
390
  BLOG_GENERIC_ERROR_MESSAGE: string;
391
391
  BLOG_PAGE_NOT_FOUND_TITLE: string;
392
392
  BLOG_PAGE_NOT_FOUND_DESCRIPTION: string;
393
+ BLOG_TAGS_SHOW_ALL: string;
394
+ BLOG_TAGS_SHOW_LESS: string;
393
395
  };
394
396
  type BlogLocalization = typeof BLOG_LOCALIZATION;
395
397
 
@@ -3,9 +3,9 @@ import * as _btst_yar from '@btst/yar';
3
3
  import { ComponentType, ReactNode } from 'react';
4
4
  import { QueryClient } from '@tanstack/react-query';
5
5
  import { P as Post, S as SerializedPost } from '../../../shared/stack.Dsatjh0B.js';
6
- export { U as UsePostsOptions, a as UsePostsResult } from '../../../shared/stack.BnSAhKJi.js';
6
+ export { U as UsePostsOptions, a as UsePostsResult } from '../../../shared/stack.DPTRuLUH.js';
7
7
  import 'zod';
8
- import '../../../shared/stack.CuhcFsAx.js';
8
+ import '../../../shared/stack.DuQOcInS.js';
9
9
 
10
10
  /**
11
11
  * Context passed to route hooks
@@ -390,6 +390,8 @@ declare const BLOG_LOCALIZATION: {
390
390
  BLOG_GENERIC_ERROR_MESSAGE: string;
391
391
  BLOG_PAGE_NOT_FOUND_TITLE: string;
392
392
  BLOG_PAGE_NOT_FOUND_DESCRIPTION: string;
393
+ BLOG_TAGS_SHOW_ALL: string;
394
+ BLOG_TAGS_SHOW_LESS: string;
393
395
  };
394
396
  type BlogLocalization = typeof BLOG_LOCALIZATION;
395
397
 
@@ -1,9 +1,9 @@
1
1
  import '@tanstack/react-query';
2
- export { f as createBlogQueryKeys } from '../../shared/stack.CLWhMntf.cjs';
2
+ export { f as createBlogQueryKeys } from '../../shared/stack.04aMRz_W.cjs';
3
3
  import '@btst/stack/plugins/client';
4
4
  import '../../shared/stack.Dsatjh0B.cjs';
5
5
  import '@btst/stack/plugins/api';
6
6
  import '@btst/db';
7
7
  import 'better-call';
8
8
  import 'zod';
9
- import '../../shared/stack.CuhcFsAx.cjs';
9
+ import '../../shared/stack.DuQOcInS.cjs';
@@ -1,9 +1,9 @@
1
1
  import '@tanstack/react-query';
2
- export { f as createBlogQueryKeys } from '../../shared/stack.DiodAFAa.mjs';
2
+ export { f as createBlogQueryKeys } from '../../shared/stack.ueI-K4xy.mjs';
3
3
  import '@btst/stack/plugins/client';
4
4
  import '../../shared/stack.Dsatjh0B.mjs';
5
5
  import '@btst/stack/plugins/api';
6
6
  import '@btst/db';
7
7
  import 'better-call';
8
8
  import 'zod';
9
- import '../../shared/stack.CuhcFsAx.mjs';
9
+ import '../../shared/stack.DuQOcInS.mjs';
@@ -1,9 +1,9 @@
1
1
  import '@tanstack/react-query';
2
- export { f as createBlogQueryKeys } from '../../shared/stack.ufcExQIR.js';
2
+ export { f as createBlogQueryKeys } from '../../shared/stack.CxWEN62M.js';
3
3
  import '@btst/stack/plugins/client';
4
4
  import '../../shared/stack.Dsatjh0B.js';
5
5
  import '@btst/stack/plugins/api';
6
6
  import '@btst/db';
7
7
  import 'better-call';
8
8
  import 'zod';
9
- import '../../shared/stack.CuhcFsAx.js';
9
+ import '../../shared/stack.DuQOcInS.js';
@@ -1,4 +1,4 @@
1
- export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.Rtcvl8sS.cjs';
1
+ export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.B6S3cgwN.cjs';
2
2
  import { B as BoardWithColumns, S as SerializedBoardWithColumns, C as ColumnWithTasks, a as SerializedColumn, T as Task, b as SerializedTask } from '../../../shared/stack.DJaKVY7v.cjs';
3
3
  import '@btst/stack/plugins/api';
4
4
  import '@btst/db';
@@ -1,4 +1,4 @@
1
- export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.HE_IvqV5.mjs';
1
+ export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.Bzfx-_lq.mjs';
2
2
  import { B as BoardWithColumns, S as SerializedBoardWithColumns, C as ColumnWithTasks, a as SerializedColumn, T as Task, b as SerializedTask } from '../../../shared/stack.DJaKVY7v.mjs';
3
3
  import '@btst/stack/plugins/api';
4
4
  import '@btst/db';
@@ -1,4 +1,4 @@
1
- export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.D4Cea8II.js';
1
+ export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.j5SFLC1d.js';
2
2
  import { B as BoardWithColumns, S as SerializedBoardWithColumns, C as ColumnWithTasks, a as SerializedColumn, T as Task, b as SerializedTask } from '../../../shared/stack.DJaKVY7v.js';
3
3
  import '@btst/stack/plugins/api';
4
4
  import '@btst/db';
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.Rtcvl8sS.cjs';
2
+ import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.B6S3cgwN.cjs';
3
3
  import { createApiClient } from '@btst/stack/plugins/client';
4
4
  import { S as SerializedBoardWithColumns } from '../../shared/stack.DJaKVY7v.cjs';
5
5
  import '@btst/stack/plugins/api';
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.HE_IvqV5.mjs';
2
+ import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.Bzfx-_lq.mjs';
3
3
  import { createApiClient } from '@btst/stack/plugins/client';
4
4
  import { S as SerializedBoardWithColumns } from '../../shared/stack.DJaKVY7v.mjs';
5
5
  import '@btst/stack/plugins/api';
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.D4Cea8II.js';
2
+ import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.j5SFLC1d.js';
3
3
  import { createApiClient } from '@btst/stack/plugins/client';
4
4
  import { S as SerializedBoardWithColumns } from '../../shared/stack.DJaKVY7v.js';
5
5
  import '@btst/stack/plugins/api';
@@ -6,7 +6,7 @@ import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
6
6
  import { DBAdapter } from '@btst/db';
7
7
  import * as better_call from 'better-call';
8
8
  import { z } from 'zod';
9
- import { c as createPostSchema, u as updatePostSchema } from './stack.CuhcFsAx.cjs';
9
+ import { c as createPostSchema, u as updatePostSchema } from './stack.DuQOcInS.cjs';
10
10
 
11
11
  /**
12
12
  * Parameters for filtering/paginating posts.
@@ -325,11 +325,11 @@ declare const blogBackendPlugin: (hooks?: BlogBackendHooks) => _btst_stack_plugi
325
325
  slug: string;
326
326
  })[] | undefined;
327
327
  slug?: string | undefined;
328
- published?: boolean | undefined;
329
- publishedAt?: unknown;
330
328
  createdAt?: unknown;
331
329
  updatedAt?: unknown;
330
+ publishedAt?: unknown;
332
331
  image?: string | undefined;
332
+ published?: boolean | undefined;
333
333
  }, {
334
334
  title: string;
335
335
  content: string;
@@ -342,11 +342,11 @@ declare const blogBackendPlugin: (hooks?: BlogBackendHooks) => _btst_stack_plugi
342
342
  slug: string;
343
343
  })[] | undefined;
344
344
  slug?: string | undefined;
345
- published?: boolean | undefined;
346
- publishedAt?: unknown;
347
345
  createdAt?: unknown;
348
346
  updatedAt?: unknown;
347
+ publishedAt?: unknown;
349
348
  image?: string | undefined;
349
+ published?: boolean | undefined;
350
350
  }>;
351
351
  }, Post>;
352
352
  readonly updatePost: better_call.StrictEndpoint<"/posts/:id", {} & {
@@ -1,7 +1,7 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
2
  import { S as SerializedPost, a as SerializedTag } from './stack.Dsatjh0B.cjs';
3
3
  import { z } from 'zod';
4
- import { c as createPostSchema, u as updatePostSchema } from './stack.CuhcFsAx.cjs';
4
+ import { c as createPostSchema, u as updatePostSchema } from './stack.DuQOcInS.cjs';
5
5
 
6
6
  /**
7
7
  * Options for the usePosts hook
@@ -136,14 +136,14 @@ declare function useCreatePost(): _tanstack_react_query.UseMutationResult<Serial
136
136
  name: string;
137
137
  slug: string;
138
138
  })[];
139
- published: boolean;
140
139
  title: string;
141
140
  content: string;
142
141
  excerpt: string;
142
+ published: boolean;
143
143
  slug?: string | undefined;
144
- publishedAt?: Date | undefined;
145
144
  createdAt?: Date | undefined;
146
145
  updatedAt?: Date | undefined;
146
+ publishedAt?: Date | undefined;
147
147
  image?: string | undefined;
148
148
  }, unknown>;
149
149
  /** Update an existing post by id */
@@ -1,7 +1,7 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
2
  import { S as SerializedPost, a as SerializedTag } from './stack.Dsatjh0B.mjs';
3
3
  import { z } from 'zod';
4
- import { c as createPostSchema, u as updatePostSchema } from './stack.CuhcFsAx.mjs';
4
+ import { c as createPostSchema, u as updatePostSchema } from './stack.DuQOcInS.mjs';
5
5
 
6
6
  /**
7
7
  * Options for the usePosts hook
@@ -136,14 +136,14 @@ declare function useCreatePost(): _tanstack_react_query.UseMutationResult<Serial
136
136
  name: string;
137
137
  slug: string;
138
138
  })[];
139
- published: boolean;
140
139
  title: string;
141
140
  content: string;
142
141
  excerpt: string;
142
+ published: boolean;
143
143
  slug?: string | undefined;
144
- publishedAt?: Date | undefined;
145
144
  createdAt?: Date | undefined;
146
145
  updatedAt?: Date | undefined;
146
+ publishedAt?: Date | undefined;
147
147
  image?: string | undefined;
148
148
  }, unknown>;
149
149
  /** Update an existing post by id */
@@ -6,7 +6,7 @@ import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
6
6
  import { DBAdapter } from '@btst/db';
7
7
  import * as better_call from 'better-call';
8
8
  import { z } from 'zod';
9
- import { c as createPostSchema, u as updatePostSchema } from './stack.CuhcFsAx.js';
9
+ import { c as createPostSchema, u as updatePostSchema } from './stack.DuQOcInS.js';
10
10
 
11
11
  /**
12
12
  * Parameters for filtering/paginating posts.
@@ -325,11 +325,11 @@ declare const blogBackendPlugin: (hooks?: BlogBackendHooks) => _btst_stack_plugi
325
325
  slug: string;
326
326
  })[] | undefined;
327
327
  slug?: string | undefined;
328
- published?: boolean | undefined;
329
- publishedAt?: unknown;
330
328
  createdAt?: unknown;
331
329
  updatedAt?: unknown;
330
+ publishedAt?: unknown;
332
331
  image?: string | undefined;
332
+ published?: boolean | undefined;
333
333
  }, {
334
334
  title: string;
335
335
  content: string;
@@ -342,11 +342,11 @@ declare const blogBackendPlugin: (hooks?: BlogBackendHooks) => _btst_stack_plugi
342
342
  slug: string;
343
343
  })[] | undefined;
344
344
  slug?: string | undefined;
345
- published?: boolean | undefined;
346
- publishedAt?: unknown;
347
345
  createdAt?: unknown;
348
346
  updatedAt?: unknown;
347
+ publishedAt?: unknown;
349
348
  image?: string | undefined;
349
+ published?: boolean | undefined;
350
350
  }>;
351
351
  }, Post>;
352
352
  readonly updatePost: better_call.StrictEndpoint<"/posts/:id", {} & {
@@ -1,7 +1,7 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
2
  import { S as SerializedPost, a as SerializedTag } from './stack.Dsatjh0B.js';
3
3
  import { z } from 'zod';
4
- import { c as createPostSchema, u as updatePostSchema } from './stack.CuhcFsAx.js';
4
+ import { c as createPostSchema, u as updatePostSchema } from './stack.DuQOcInS.js';
5
5
 
6
6
  /**
7
7
  * Options for the usePosts hook
@@ -136,14 +136,14 @@ declare function useCreatePost(): _tanstack_react_query.UseMutationResult<Serial
136
136
  name: string;
137
137
  slug: string;
138
138
  })[];
139
- published: boolean;
140
139
  title: string;
141
140
  content: string;
142
141
  excerpt: string;
142
+ published: boolean;
143
143
  slug?: string | undefined;
144
- publishedAt?: Date | undefined;
145
144
  createdAt?: Date | undefined;
146
145
  updatedAt?: Date | undefined;
146
+ publishedAt?: Date | undefined;
147
147
  image?: string | undefined;
148
148
  }, unknown>;
149
149
  /** Update an existing post by id */
@@ -6,7 +6,7 @@ import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
6
6
  import { DBAdapter } from '@btst/db';
7
7
  import * as better_call from 'better-call';
8
8
  import { z } from 'zod';
9
- import { c as createPostSchema, u as updatePostSchema } from './stack.CuhcFsAx.mjs';
9
+ import { c as createPostSchema, u as updatePostSchema } from './stack.DuQOcInS.mjs';
10
10
 
11
11
  /**
12
12
  * Parameters for filtering/paginating posts.
@@ -325,11 +325,11 @@ declare const blogBackendPlugin: (hooks?: BlogBackendHooks) => _btst_stack_plugi
325
325
  slug: string;
326
326
  })[] | undefined;
327
327
  slug?: string | undefined;
328
- published?: boolean | undefined;
329
- publishedAt?: unknown;
330
328
  createdAt?: unknown;
331
329
  updatedAt?: unknown;
330
+ publishedAt?: unknown;
332
331
  image?: string | undefined;
332
+ published?: boolean | undefined;
333
333
  }, {
334
334
  title: string;
335
335
  content: string;
@@ -342,11 +342,11 @@ declare const blogBackendPlugin: (hooks?: BlogBackendHooks) => _btst_stack_plugi
342
342
  slug: string;
343
343
  })[] | undefined;
344
344
  slug?: string | undefined;
345
- published?: boolean | undefined;
346
- publishedAt?: unknown;
347
345
  createdAt?: unknown;
348
346
  updatedAt?: unknown;
347
+ publishedAt?: unknown;
349
348
  image?: string | undefined;
349
+ published?: boolean | undefined;
350
350
  }>;
351
351
  }, Post>;
352
352
  readonly updatePost: better_call.StrictEndpoint<"/posts/:id", {} & {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@btst/stack",
3
- "version": "2.11.7",
3
+ "version": "2.11.8",
4
4
  "description": "A composable, plugin-based library for building full-stack applications.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { usePluginOverrides, useBasePath } from "@btst/stack/context";
3
+ import { usePluginOverrides } from "@btst/stack/context";
4
4
  import { formatDate } from "date-fns";
5
5
  import {
6
6
  useSuspensePost,
@@ -12,11 +12,10 @@ import { MarkdownContent } from "../shared/markdown-content";
12
12
  import { PageHeader } from "../shared/page-header";
13
13
  import { PageWrapper } from "../shared/page-wrapper";
14
14
  import type { BlogPluginOverrides } from "../../overrides";
15
- import { DefaultImage, DefaultLink } from "../shared/defaults";
15
+ import { DefaultImage } from "../shared/defaults";
16
16
  import { BLOG_LOCALIZATION } from "../../localization";
17
17
  import { PostNavigation } from "../shared/post-navigation";
18
18
  import { RecentPostsCarousel } from "../shared/recent-posts-carousel";
19
- import { Badge } from "@workspace/ui/components/badge";
20
19
  import { useRouteLifecycle } from "@workspace/ui/hooks/use-route-lifecycle";
21
20
  import { OnThisPage, OnThisPageSelect } from "../shared/on-this-page";
22
21
  import type { SerializedPost } from "../../../types";
@@ -24,6 +23,7 @@ import { useRegisterPageAIContext } from "@btst/stack/plugins/ai-chat/client/con
24
23
  import { WhenVisible } from "@workspace/ui/components/when-visible";
25
24
  import { PostNavigationSkeleton } from "../loading/post-navigation-skeleton";
26
25
  import { RecentPostsCarouselSkeleton } from "../loading/recent-posts-carousel-skeleton";
26
+ import { CollapsibleTagList } from "../shared/collapsible-tag-list";
27
27
 
28
28
  // Internal component with actual page content
29
29
  export function PostPage({ slug }: { slug: string }) {
@@ -151,29 +151,12 @@ export function PostPage({ slug }: { slug: string }) {
151
151
  }
152
152
 
153
153
  function PostHeaderTop({ post }: { post: SerializedPost }) {
154
- const { Link } = usePluginOverrides<
155
- BlogPluginOverrides,
156
- Partial<BlogPluginOverrides>
157
- >("blog", {
158
- Link: DefaultLink,
159
- });
160
- const basePath = useBasePath();
161
154
  return (
162
155
  <div className="flex flex-row items-center justify-center gap-2 flex-wrap mt-8">
163
156
  <span className="font-light text-muted-foreground text-sm">
164
157
  {formatDate(post.createdAt, "MMMM d, yyyy")}
165
158
  </span>
166
- {post.tags && post.tags.length > 0 && (
167
- <>
168
- {post.tags.map((tag) => (
169
- <Link key={tag.id} href={`${basePath}/blog/tag/${tag.slug}`}>
170
- <Badge variant="secondary" className="text-xs">
171
- {tag.name}
172
- </Badge>
173
- </Link>
174
- ))}
175
- </>
176
- )}
159
+ <CollapsibleTagList tags={post.tags ?? []} />
177
160
  </div>
178
161
  );
179
162
  }
@@ -0,0 +1,76 @@
1
+ "use client";
2
+
3
+ import { usePluginOverrides, useBasePath } from "@btst/stack/context";
4
+ import type { BlogPluginOverrides } from "../../overrides";
5
+ import { DefaultLink } from "./defaults";
6
+ import { Badge } from "@workspace/ui/components/badge";
7
+ import { BLOG_LOCALIZATION } from "../../localization";
8
+ import { ChevronDown, ChevronUp } from "lucide-react";
9
+ import { useState } from "react";
10
+ import type { SerializedTag } from "../../../types";
11
+
12
+ const MAX_VISIBLE_TAGS = 15;
13
+
14
+ interface CollapsibleTagListProps {
15
+ tags: SerializedTag[];
16
+ maxVisible?: number;
17
+ }
18
+
19
+ export function CollapsibleTagList({
20
+ tags,
21
+ maxVisible = MAX_VISIBLE_TAGS,
22
+ }: CollapsibleTagListProps) {
23
+ const { Link, localization } = usePluginOverrides<
24
+ BlogPluginOverrides,
25
+ Partial<BlogPluginOverrides>
26
+ >("blog", {
27
+ Link: DefaultLink,
28
+ localization: BLOG_LOCALIZATION,
29
+ });
30
+ const basePath = useBasePath();
31
+ const [showAll, setShowAll] = useState(false);
32
+
33
+ if (!tags || tags.length === 0) {
34
+ return null;
35
+ }
36
+
37
+ const hasMore = tags.length > maxVisible;
38
+ const visibleTags = showAll || !hasMore ? tags : tags.slice(0, maxVisible);
39
+
40
+ return (
41
+ <>
42
+ {visibleTags.map((tag) => (
43
+ <Link key={tag.id} href={`${basePath}/blog/tag/${tag.slug}`}>
44
+ <Badge variant="secondary" className="text-xs">
45
+ {tag.name}
46
+ </Badge>
47
+ </Link>
48
+ ))}
49
+ {hasMore && (
50
+ <Badge asChild variant="secondary" className="text-xs cursor-pointer">
51
+ <button
52
+ type="button"
53
+ onClick={() => setShowAll((prev) => !prev)}
54
+ aria-expanded={showAll}
55
+ aria-label={
56
+ showAll
57
+ ? localization.BLOG_TAGS_SHOW_LESS
58
+ : localization.BLOG_TAGS_SHOW_ALL
59
+ }
60
+ title={
61
+ showAll
62
+ ? localization.BLOG_TAGS_SHOW_LESS
63
+ : localization.BLOG_TAGS_SHOW_ALL
64
+ }
65
+ >
66
+ {showAll ? (
67
+ <ChevronUp aria-hidden="true" />
68
+ ) : (
69
+ <ChevronDown aria-hidden="true" />
70
+ )}
71
+ </button>
72
+ </Badge>
73
+ )}
74
+ </>
75
+ );
76
+ }
@@ -1,20 +1,10 @@
1
1
  "use client";
2
2
 
3
- import { usePluginOverrides, useBasePath } from "@btst/stack/context";
4
- import type { BlogPluginOverrides } from "../../overrides";
5
- import { DefaultLink } from "./defaults";
6
- import { Badge } from "@workspace/ui/components/badge";
7
3
  import { useSuspenseTags } from "../../hooks/blog-hooks";
4
+ import { CollapsibleTagList } from "./collapsible-tag-list";
8
5
 
9
6
  export function TagsList() {
10
7
  const { tags } = useSuspenseTags();
11
- const { Link } = usePluginOverrides<
12
- BlogPluginOverrides,
13
- Partial<BlogPluginOverrides>
14
- >("blog", {
15
- Link: DefaultLink,
16
- });
17
- const basePath = useBasePath();
18
8
 
19
9
  if (!tags || tags.length === 0) {
20
10
  return null;
@@ -22,13 +12,7 @@ export function TagsList() {
22
12
 
23
13
  return (
24
14
  <div className="flex flex-wrap gap-2 justify-center">
25
- {tags.map((tag) => (
26
- <Link key={tag.id} href={`${basePath}/blog/tag/${tag.slug}`}>
27
- <Badge variant="secondary" className="text-xs">
28
- {tag.name}
29
- </Badge>
30
- </Link>
31
- ))}
15
+ <CollapsibleTagList tags={tags} />
32
16
  </div>
33
17
  );
34
18
  }
@@ -4,4 +4,6 @@ export const BLOG_COMMON = {
4
4
  BLOG_PAGE_NOT_FOUND_TITLE: "Not Found",
5
5
  BLOG_PAGE_NOT_FOUND_DESCRIPTION:
6
6
  "The page you are looking for does not exist.",
7
+ BLOG_TAGS_SHOW_ALL: "Show all tags",
8
+ BLOG_TAGS_SHOW_LESS: "Show fewer tags",
7
9
  };
@@ -7,12 +7,12 @@ import { QueryClient } from '@tanstack/react-query';
7
7
 
8
8
  declare const createBoardSchema: z.ZodObject<{
9
9
  description: z.ZodOptional<z.ZodString>;
10
- name: z.ZodString;
11
- createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
12
- updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
13
10
  slug: z.ZodOptional<z.ZodString>;
14
11
  ownerId: z.ZodOptional<z.ZodString>;
15
12
  organizationId: z.ZodOptional<z.ZodString>;
13
+ createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
14
+ updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
15
+ name: z.ZodString;
16
16
  }, z.core.$strip>;
17
17
  declare const updateBoardSchema: z.ZodObject<{
18
18
  createdAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
@@ -331,19 +331,19 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
331
331
  body: better_call.StandardSchemaV1<{
332
332
  name: string;
333
333
  description?: string | undefined;
334
- createdAt?: unknown;
335
- updatedAt?: unknown;
336
334
  slug?: string | undefined;
337
335
  ownerId?: string | undefined;
338
336
  organizationId?: string | undefined;
337
+ createdAt?: unknown;
338
+ updatedAt?: unknown;
339
339
  }, {
340
340
  name: string;
341
341
  description?: string | undefined;
342
- createdAt?: unknown;
343
- updatedAt?: unknown;
344
342
  slug?: string | undefined;
345
343
  ownerId?: string | undefined;
346
344
  organizationId?: string | undefined;
345
+ createdAt?: unknown;
346
+ updatedAt?: unknown;
347
347
  }>;
348
348
  }, {
349
349
  columns: ColumnWithTasks[];
@@ -360,20 +360,20 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
360
360
  method: "PUT";
361
361
  body: better_call.StandardSchemaV1<{
362
362
  description?: string | undefined;
363
- name?: string | undefined;
364
- createdAt?: unknown;
365
- updatedAt?: unknown;
366
363
  slug?: string | undefined;
367
364
  ownerId?: string | undefined;
368
365
  organizationId?: string | undefined;
369
- }, {
370
- description?: string | undefined;
371
- name?: string | undefined;
372
366
  createdAt?: unknown;
373
367
  updatedAt?: unknown;
368
+ name?: string | undefined;
369
+ }, {
370
+ description?: string | undefined;
374
371
  slug?: string | undefined;
375
372
  ownerId?: string | undefined;
376
373
  organizationId?: string | undefined;
374
+ createdAt?: unknown;
375
+ updatedAt?: unknown;
376
+ name?: string | undefined;
377
377
  }>;
378
378
  }, Board>;
379
379
  readonly deleteBoard: better_call.StrictEndpoint<"/boards/:id", {} & {
@@ -7,12 +7,12 @@ import { QueryClient } from '@tanstack/react-query';
7
7
 
8
8
  declare const createBoardSchema: z.ZodObject<{
9
9
  description: z.ZodOptional<z.ZodString>;
10
- name: z.ZodString;
11
- createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
12
- updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
13
10
  slug: z.ZodOptional<z.ZodString>;
14
11
  ownerId: z.ZodOptional<z.ZodString>;
15
12
  organizationId: z.ZodOptional<z.ZodString>;
13
+ createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
14
+ updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
15
+ name: z.ZodString;
16
16
  }, z.core.$strip>;
17
17
  declare const updateBoardSchema: z.ZodObject<{
18
18
  createdAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
@@ -331,19 +331,19 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
331
331
  body: better_call.StandardSchemaV1<{
332
332
  name: string;
333
333
  description?: string | undefined;
334
- createdAt?: unknown;
335
- updatedAt?: unknown;
336
334
  slug?: string | undefined;
337
335
  ownerId?: string | undefined;
338
336
  organizationId?: string | undefined;
337
+ createdAt?: unknown;
338
+ updatedAt?: unknown;
339
339
  }, {
340
340
  name: string;
341
341
  description?: string | undefined;
342
- createdAt?: unknown;
343
- updatedAt?: unknown;
344
342
  slug?: string | undefined;
345
343
  ownerId?: string | undefined;
346
344
  organizationId?: string | undefined;
345
+ createdAt?: unknown;
346
+ updatedAt?: unknown;
347
347
  }>;
348
348
  }, {
349
349
  columns: ColumnWithTasks[];
@@ -360,20 +360,20 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
360
360
  method: "PUT";
361
361
  body: better_call.StandardSchemaV1<{
362
362
  description?: string | undefined;
363
- name?: string | undefined;
364
- createdAt?: unknown;
365
- updatedAt?: unknown;
366
363
  slug?: string | undefined;
367
364
  ownerId?: string | undefined;
368
365
  organizationId?: string | undefined;
369
- }, {
370
- description?: string | undefined;
371
- name?: string | undefined;
372
366
  createdAt?: unknown;
373
367
  updatedAt?: unknown;
368
+ name?: string | undefined;
369
+ }, {
370
+ description?: string | undefined;
374
371
  slug?: string | undefined;
375
372
  ownerId?: string | undefined;
376
373
  organizationId?: string | undefined;
374
+ createdAt?: unknown;
375
+ updatedAt?: unknown;
376
+ name?: string | undefined;
377
377
  }>;
378
378
  }, Board>;
379
379
  readonly deleteBoard: better_call.StrictEndpoint<"/boards/:id", {} & {
@@ -8,15 +8,15 @@ declare const createPostSchema: z.ZodObject<{
8
8
  name: z.ZodString;
9
9
  slug: z.ZodString;
10
10
  }, z.core.$strip>]>>>>;
11
+ title: z.ZodString;
11
12
  slug: z.ZodOptional<z.ZodString>;
12
- published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
13
- publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
14
13
  createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
15
14
  updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
16
- title: z.ZodString;
15
+ publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
17
16
  content: z.ZodString;
18
17
  excerpt: z.ZodString;
19
18
  image: z.ZodOptional<z.ZodString>;
19
+ published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
20
20
  }, z.core.$strip>;
21
21
  declare const updatePostSchema: z.ZodObject<{
22
22
  publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
@@ -8,15 +8,15 @@ declare const createPostSchema: z.ZodObject<{
8
8
  name: z.ZodString;
9
9
  slug: z.ZodString;
10
10
  }, z.core.$strip>]>>>>;
11
+ title: z.ZodString;
11
12
  slug: z.ZodOptional<z.ZodString>;
12
- published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
13
- publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
14
13
  createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
15
14
  updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
16
- title: z.ZodString;
15
+ publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
17
16
  content: z.ZodString;
18
17
  excerpt: z.ZodString;
19
18
  image: z.ZodOptional<z.ZodString>;
19
+ published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
20
20
  }, z.core.$strip>;
21
21
  declare const updatePostSchema: z.ZodObject<{
22
22
  publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
@@ -8,15 +8,15 @@ declare const createPostSchema: z.ZodObject<{
8
8
  name: z.ZodString;
9
9
  slug: z.ZodString;
10
10
  }, z.core.$strip>]>>>>;
11
+ title: z.ZodString;
11
12
  slug: z.ZodOptional<z.ZodString>;
12
- published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
13
- publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
14
13
  createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
15
14
  updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
16
- title: z.ZodString;
15
+ publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
17
16
  content: z.ZodString;
18
17
  excerpt: z.ZodString;
19
18
  image: z.ZodOptional<z.ZodString>;
19
+ published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
20
20
  }, z.core.$strip>;
21
21
  declare const updatePostSchema: z.ZodObject<{
22
22
  publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
@@ -7,12 +7,12 @@ import { QueryClient } from '@tanstack/react-query';
7
7
 
8
8
  declare const createBoardSchema: z.ZodObject<{
9
9
  description: z.ZodOptional<z.ZodString>;
10
- name: z.ZodString;
11
- createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
12
- updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
13
10
  slug: z.ZodOptional<z.ZodString>;
14
11
  ownerId: z.ZodOptional<z.ZodString>;
15
12
  organizationId: z.ZodOptional<z.ZodString>;
13
+ createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
14
+ updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
15
+ name: z.ZodString;
16
16
  }, z.core.$strip>;
17
17
  declare const updateBoardSchema: z.ZodObject<{
18
18
  createdAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
@@ -331,19 +331,19 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
331
331
  body: better_call.StandardSchemaV1<{
332
332
  name: string;
333
333
  description?: string | undefined;
334
- createdAt?: unknown;
335
- updatedAt?: unknown;
336
334
  slug?: string | undefined;
337
335
  ownerId?: string | undefined;
338
336
  organizationId?: string | undefined;
337
+ createdAt?: unknown;
338
+ updatedAt?: unknown;
339
339
  }, {
340
340
  name: string;
341
341
  description?: string | undefined;
342
- createdAt?: unknown;
343
- updatedAt?: unknown;
344
342
  slug?: string | undefined;
345
343
  ownerId?: string | undefined;
346
344
  organizationId?: string | undefined;
345
+ createdAt?: unknown;
346
+ updatedAt?: unknown;
347
347
  }>;
348
348
  }, {
349
349
  columns: ColumnWithTasks[];
@@ -360,20 +360,20 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
360
360
  method: "PUT";
361
361
  body: better_call.StandardSchemaV1<{
362
362
  description?: string | undefined;
363
- name?: string | undefined;
364
- createdAt?: unknown;
365
- updatedAt?: unknown;
366
363
  slug?: string | undefined;
367
364
  ownerId?: string | undefined;
368
365
  organizationId?: string | undefined;
369
- }, {
370
- description?: string | undefined;
371
- name?: string | undefined;
372
366
  createdAt?: unknown;
373
367
  updatedAt?: unknown;
368
+ name?: string | undefined;
369
+ }, {
370
+ description?: string | undefined;
374
371
  slug?: string | undefined;
375
372
  ownerId?: string | undefined;
376
373
  organizationId?: string | undefined;
374
+ createdAt?: unknown;
375
+ updatedAt?: unknown;
376
+ name?: string | undefined;
377
377
  }>;
378
378
  }, Board>;
379
379
  readonly deleteBoard: better_call.StrictEndpoint<"/boards/:id", {} & {