Skip to content

Commit 6ad3de5

Browse files
chore: update shadcn registry [skip ci]
1 parent e7c3052 commit 6ad3de5

1 file changed

Lines changed: 8 additions & 2 deletions

File tree

packages/stack/registry/btst-blog.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@
190190
{
191191
"path": "btst/blog/client/components/pages/post-page.internal.tsx",
192192
"type": "registry:component",
193-
"content": "\"use client\";\n\nimport { usePluginOverrides, useBasePath } from \"@btst/stack/context\";\nimport { formatDate } from \"date-fns\";\nimport {\n\tuseSuspensePost,\n\tuseNextPreviousPosts,\n\tuseRecentPosts,\n} from \"@btst/stack/plugins/blog/client/hooks\";\nimport { EmptyList } from \"../shared/empty-list\";\nimport { MarkdownContent } from \"../shared/markdown-content\";\nimport { PageHeader } from \"../shared/page-header\";\nimport { PageWrapper } from \"../shared/page-wrapper\";\nimport type { BlogPluginOverrides } from \"../../overrides\";\nimport { DefaultImage, DefaultLink } from \"../shared/defaults\";\nimport { BLOG_LOCALIZATION } from \"../../localization\";\nimport { PostNavigation } from \"../shared/post-navigation\";\nimport { RecentPostsCarousel } from \"../shared/recent-posts-carousel\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { useRouteLifecycle } from \"@/hooks/use-route-lifecycle\";\nimport { OnThisPage, OnThisPageSelect } from \"../shared/on-this-page\";\nimport type { SerializedPost } from \"../../../types\";\nimport { useRegisterPageAIContext } from \"@btst/stack/plugins/ai-chat/client/context\";\nimport { WhenVisible } from \"@/components/ui/when-visible\";\nimport { PostNavigationSkeleton } from \"../loading/post-navigation-skeleton\";\nimport { RecentPostsCarouselSkeleton } from \"../loading/recent-posts-carousel-skeleton\";\nimport { ChevronDown, ChevronUp } from \"lucide-react\";\nimport { useState } from \"react\";\n\nconst MAX_VISIBLE_POST_TAGS = 15;\n\n// Internal component with actual page content\nexport function PostPage({ slug }: { slug: string }) {\n\tconst overrides = usePluginOverrides<\n\t\tBlogPluginOverrides,\n\t\tPartial<BlogPluginOverrides>\n\t>(\"blog\", {\n\t\tImage: DefaultImage,\n\t\tlocalization: BLOG_LOCALIZATION,\n\t});\n\tconst { Image, localization } = overrides;\n\n\t// Call lifecycle hooks\n\tuseRouteLifecycle({\n\t\trouteName: \"post\",\n\t\tcontext: {\n\t\t\tpath: `/blog/${slug}`,\n\t\t\tparams: { slug },\n\t\t\tisSSR: typeof window === \"undefined\",\n\t\t},\n\t\toverrides,\n\t\tbeforeRenderHook: (overrides, context) => {\n\t\t\tif (overrides.onBeforePostPageRendered) {\n\t\t\t\treturn overrides.onBeforePostPageRendered(slug, context);\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\t});\n\n\tconst { post } = useSuspensePost(slug ?? \"\");\n\n\tconst { previousPost, nextPost } = useNextPreviousPosts(\n\t\tpost?.createdAt ?? new Date(),\n\t\t{\n\t\t\tenabled: !!post,\n\t\t},\n\t);\n\n\tconst { recentPosts } = useRecentPosts({\n\t\tlimit: 5,\n\t\texcludeSlug: slug,\n\t\tenabled: !!post,\n\t});\n\n\t// Register page AI context so the chat can summarize and discuss this post\n\tuseRegisterPageAIContext(\n\t\tpost\n\t\t\t? {\n\t\t\t\t\trouteName: \"blog-post\",\n\t\t\t\t\tpageDescription:\n\t\t\t\t\t\t`Blog post: \"${post.title}\"\\nAuthor: ${post.authorId ?? \"Unknown\"}\\n\\n${post.content ?? \"\"}`.slice(\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t16000,\n\t\t\t\t\t\t),\n\t\t\t\t\tsuggestions: [\n\t\t\t\t\t\t\"Summarize this post\",\n\t\t\t\t\t\t\"What are the key takeaways?\",\n\t\t\t\t\t\t\"Explain this in simpler terms\",\n\t\t\t\t\t],\n\t\t\t\t}\n\t\t\t: null,\n\t);\n\n\tif (!slug || !post) {\n\t\treturn (\n\t\t\t<PageWrapper>\n\t\t\t\t<EmptyList message={localization.BLOG_PAGE_NOT_FOUND_DESCRIPTION} />\n\t\t\t</PageWrapper>\n\t\t);\n\t}\n\n\treturn (\n\t\t<PageWrapper className=\"gap-0 px-4 lg:px-2 py-0 pb-18\" testId=\"post-page\">\n\t\t\t<div className=\"flex items-start w-full\">\n\t\t\t\t<div className=\"w-44 shrink-0 hidden xl:flex mr-auto\" />\n\t\t\t\t<div className=\"flex flex-col items-center flex-1 mx-auto w-full max-w-4xl min-w-0\">\n\t\t\t\t\t<OnThisPageSelect markdown={post.content} />\n\n\t\t\t\t\t<PageHeader\n\t\t\t\t\t\ttitle={post.title}\n\t\t\t\t\t\tdescription={post.excerpt}\n\t\t\t\t\t\tchildrenTop={<PostHeaderTop post={post} />}\n\t\t\t\t\t/>\n\n\t\t\t\t\t{post.image && (\n\t\t\t\t\t\t<div className=\"flex flex-col gap-2 my-6 aspect-video w-full relative\">\n\t\t\t\t\t\t\t<Image\n\t\t\t\t\t\t\t\tsrc={post.image}\n\t\t\t\t\t\t\t\talt={post.title}\n\t\t\t\t\t\t\t\tclassName=\"object-cover transition-transform duration-200\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<div className=\"w-full px-3\">\n\t\t\t\t\t\t<MarkdownContent markdown={post.content} />\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div className=\"flex flex-col gap-4 w-full\">\n\t\t\t\t\t\t<WhenVisible\n\t\t\t\t\t\t\trootMargin=\"200px\"\n\t\t\t\t\t\t\tfallback={<PostNavigationSkeleton />}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<PostNavigation previousPost={previousPost} nextPost={nextPost} />\n\t\t\t\t\t\t</WhenVisible>\n\n\t\t\t\t\t\t<WhenVisible\n\t\t\t\t\t\t\trootMargin=\"200px\"\n\t\t\t\t\t\t\tfallback={<RecentPostsCarouselSkeleton />}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<RecentPostsCarousel posts={recentPosts} />\n\t\t\t\t\t\t</WhenVisible>\n\n\t\t\t\t\t\t{overrides.postBottomSlot && (\n\t\t\t\t\t\t\t<div data-testid=\"post-bottom-slot\">\n\t\t\t\t\t\t\t\t{overrides.postBottomSlot(post)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<OnThisPage markdown={post.content} />\n\t\t\t</div>\n\t\t</PageWrapper>\n\t);\n}\n\nfunction PostHeaderTop({ post }: { post: SerializedPost }) {\n\tconst { Link, localization } = usePluginOverrides<\n\t\tBlogPluginOverrides,\n\t\tPartial<BlogPluginOverrides>\n\t>(\"blog\", {\n\t\tLink: DefaultLink,\n\t\tlocalization: BLOG_LOCALIZATION,\n\t});\n\tconst basePath = useBasePath();\n\tconst [showAll, setShowAll] = useState(false);\n\n\tconst allTags = post.tags ?? [];\n\tconst hasMore = allTags.length > MAX_VISIBLE_POST_TAGS;\n\tconst visibleTags =\n\t\tshowAll || !hasMore ? allTags : allTags.slice(0, MAX_VISIBLE_POST_TAGS);\n\n\treturn (\n\t\t<div className=\"flex flex-row items-center justify-center gap-2 flex-wrap mt-8\">\n\t\t\t<span className=\"font-light text-muted-foreground text-sm\">\n\t\t\t\t{formatDate(post.createdAt, \"MMMM d, yyyy\")}\n\t\t\t</span>\n\t\t\t{visibleTags.map((tag) => (\n\t\t\t\t<Link key={tag.id} href={`${basePath}/blog/tag/${tag.slug}`}>\n\t\t\t\t\t<Badge variant=\"secondary\" className=\"text-xs\">\n\t\t\t\t\t\t{tag.name}\n\t\t\t\t\t</Badge>\n\t\t\t\t</Link>\n\t\t\t))}\n\t\t\t{hasMore && (\n\t\t\t\t<Badge asChild variant=\"secondary\" className=\"text-xs cursor-pointer\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={() => setShowAll((prev) => !prev)}\n\t\t\t\t\t\taria-expanded={showAll}\n\t\t\t\t\t\taria-label={\n\t\t\t\t\t\t\tshowAll\n\t\t\t\t\t\t\t\t? localization.BLOG_TAGS_SHOW_LESS\n\t\t\t\t\t\t\t\t: localization.BLOG_TAGS_SHOW_ALL\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttitle={\n\t\t\t\t\t\t\tshowAll\n\t\t\t\t\t\t\t\t? localization.BLOG_TAGS_SHOW_LESS\n\t\t\t\t\t\t\t\t: localization.BLOG_TAGS_SHOW_ALL\n\t\t\t\t\t\t}\n\t\t\t\t\t>\n\t\t\t\t\t\t{showAll ? (\n\t\t\t\t\t\t\t<ChevronUp aria-hidden=\"true\" />\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<ChevronDown aria-hidden=\"true\" />\n\t\t\t\t\t\t)}\n\t\t\t\t\t</button>\n\t\t\t\t</Badge>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n",
193+
"content": "\"use client\";\n\nimport { usePluginOverrides } from \"@btst/stack/context\";\nimport { formatDate } from \"date-fns\";\nimport {\n\tuseSuspensePost,\n\tuseNextPreviousPosts,\n\tuseRecentPosts,\n} from \"@btst/stack/plugins/blog/client/hooks\";\nimport { EmptyList } from \"../shared/empty-list\";\nimport { MarkdownContent } from \"../shared/markdown-content\";\nimport { PageHeader } from \"../shared/page-header\";\nimport { PageWrapper } from \"../shared/page-wrapper\";\nimport type { BlogPluginOverrides } from \"../../overrides\";\nimport { DefaultImage } from \"../shared/defaults\";\nimport { BLOG_LOCALIZATION } from \"../../localization\";\nimport { PostNavigation } from \"../shared/post-navigation\";\nimport { RecentPostsCarousel } from \"../shared/recent-posts-carousel\";\nimport { useRouteLifecycle } from \"@/hooks/use-route-lifecycle\";\nimport { OnThisPage, OnThisPageSelect } from \"../shared/on-this-page\";\nimport type { SerializedPost } from \"../../../types\";\nimport { useRegisterPageAIContext } from \"@btst/stack/plugins/ai-chat/client/context\";\nimport { WhenVisible } from \"@/components/ui/when-visible\";\nimport { PostNavigationSkeleton } from \"../loading/post-navigation-skeleton\";\nimport { RecentPostsCarouselSkeleton } from \"../loading/recent-posts-carousel-skeleton\";\nimport { CollapsibleTagList } from \"../shared/collapsible-tag-list\";\n\n// Internal component with actual page content\nexport function PostPage({ slug }: { slug: string }) {\n\tconst overrides = usePluginOverrides<\n\t\tBlogPluginOverrides,\n\t\tPartial<BlogPluginOverrides>\n\t>(\"blog\", {\n\t\tImage: DefaultImage,\n\t\tlocalization: BLOG_LOCALIZATION,\n\t});\n\tconst { Image, localization } = overrides;\n\n\t// Call lifecycle hooks\n\tuseRouteLifecycle({\n\t\trouteName: \"post\",\n\t\tcontext: {\n\t\t\tpath: `/blog/${slug}`,\n\t\t\tparams: { slug },\n\t\t\tisSSR: typeof window === \"undefined\",\n\t\t},\n\t\toverrides,\n\t\tbeforeRenderHook: (overrides, context) => {\n\t\t\tif (overrides.onBeforePostPageRendered) {\n\t\t\t\treturn overrides.onBeforePostPageRendered(slug, context);\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\t});\n\n\tconst { post } = useSuspensePost(slug ?? \"\");\n\n\tconst { previousPost, nextPost } = useNextPreviousPosts(\n\t\tpost?.createdAt ?? new Date(),\n\t\t{\n\t\t\tenabled: !!post,\n\t\t},\n\t);\n\n\tconst { recentPosts } = useRecentPosts({\n\t\tlimit: 5,\n\t\texcludeSlug: slug,\n\t\tenabled: !!post,\n\t});\n\n\t// Register page AI context so the chat can summarize and discuss this post\n\tuseRegisterPageAIContext(\n\t\tpost\n\t\t\t? {\n\t\t\t\t\trouteName: \"blog-post\",\n\t\t\t\t\tpageDescription:\n\t\t\t\t\t\t`Blog post: \"${post.title}\"\\nAuthor: ${post.authorId ?? \"Unknown\"}\\n\\n${post.content ?? \"\"}`.slice(\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t16000,\n\t\t\t\t\t\t),\n\t\t\t\t\tsuggestions: [\n\t\t\t\t\t\t\"Summarize this post\",\n\t\t\t\t\t\t\"What are the key takeaways?\",\n\t\t\t\t\t\t\"Explain this in simpler terms\",\n\t\t\t\t\t],\n\t\t\t\t}\n\t\t\t: null,\n\t);\n\n\tif (!slug || !post) {\n\t\treturn (\n\t\t\t<PageWrapper>\n\t\t\t\t<EmptyList message={localization.BLOG_PAGE_NOT_FOUND_DESCRIPTION} />\n\t\t\t</PageWrapper>\n\t\t);\n\t}\n\n\treturn (\n\t\t<PageWrapper className=\"gap-0 px-4 lg:px-2 py-0 pb-18\" testId=\"post-page\">\n\t\t\t<div className=\"flex items-start w-full\">\n\t\t\t\t<div className=\"w-44 shrink-0 hidden xl:flex mr-auto\" />\n\t\t\t\t<div className=\"flex flex-col items-center flex-1 mx-auto w-full max-w-4xl min-w-0\">\n\t\t\t\t\t<OnThisPageSelect markdown={post.content} />\n\n\t\t\t\t\t<PageHeader\n\t\t\t\t\t\ttitle={post.title}\n\t\t\t\t\t\tdescription={post.excerpt}\n\t\t\t\t\t\tchildrenTop={<PostHeaderTop post={post} />}\n\t\t\t\t\t/>\n\n\t\t\t\t\t{post.image && (\n\t\t\t\t\t\t<div className=\"flex flex-col gap-2 my-6 aspect-video w-full relative\">\n\t\t\t\t\t\t\t<Image\n\t\t\t\t\t\t\t\tsrc={post.image}\n\t\t\t\t\t\t\t\talt={post.title}\n\t\t\t\t\t\t\t\tclassName=\"object-cover transition-transform duration-200\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<div className=\"w-full px-3\">\n\t\t\t\t\t\t<MarkdownContent markdown={post.content} />\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div className=\"flex flex-col gap-4 w-full\">\n\t\t\t\t\t\t<WhenVisible\n\t\t\t\t\t\t\trootMargin=\"200px\"\n\t\t\t\t\t\t\tfallback={<PostNavigationSkeleton />}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<PostNavigation previousPost={previousPost} nextPost={nextPost} />\n\t\t\t\t\t\t</WhenVisible>\n\n\t\t\t\t\t\t<WhenVisible\n\t\t\t\t\t\t\trootMargin=\"200px\"\n\t\t\t\t\t\t\tfallback={<RecentPostsCarouselSkeleton />}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<RecentPostsCarousel posts={recentPosts} />\n\t\t\t\t\t\t</WhenVisible>\n\n\t\t\t\t\t\t{overrides.postBottomSlot && (\n\t\t\t\t\t\t\t<div data-testid=\"post-bottom-slot\">\n\t\t\t\t\t\t\t\t{overrides.postBottomSlot(post)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<OnThisPage markdown={post.content} />\n\t\t\t</div>\n\t\t</PageWrapper>\n\t);\n}\n\nfunction PostHeaderTop({ post }: { post: SerializedPost }) {\n\treturn (\n\t\t<div className=\"flex flex-row items-center justify-center gap-2 flex-wrap mt-8\">\n\t\t\t<span className=\"font-light text-muted-foreground text-sm\">\n\t\t\t\t{formatDate(post.createdAt, \"MMMM d, yyyy\")}\n\t\t\t</span>\n\t\t\t<CollapsibleTagList tags={post.tags ?? []} />\n\t\t</div>\n\t);\n}\n",
194194
"target": "src/components/btst/blog/client/components/pages/post-page.internal.tsx"
195195
},
196196
{
@@ -211,6 +211,12 @@
211211
"content": "\"use client\";\n\nimport { lazy } from \"react\";\nimport { usePluginOverrides } from \"@btst/stack/context\";\nimport type { BlogPluginOverrides } from \"../../overrides\";\nimport { ComposedRoute } from \"@btst/stack/client/components\";\nimport { DefaultError } from \"../shared/default-error\";\nimport { PostsLoading } from \"../loading\";\nimport { NotFoundPage } from \"./404-page\";\n\n// Lazy load the internal component with actual page content\nconst TagPage = lazy(() =>\n\timport(\"./tag-page.internal\").then((m) => ({ default: m.TagPage })),\n);\n\n// Exported wrapped component with error and loading boundaries\nexport function TagPageComponent({ tagSlug }: { tagSlug: string }) {\n\tconst { onRouteError } = usePluginOverrides<BlogPluginOverrides>(\"blog\");\n\treturn (\n\t\t<ComposedRoute\n\t\t\tpath={`/blog/tag/${tagSlug}`}\n\t\t\tPageComponent={TagPage}\n\t\t\tErrorComponent={DefaultError}\n\t\t\tLoadingComponent={PostsLoading}\n\t\t\tNotFoundComponent={NotFoundPage}\n\t\t\tprops={{ tagSlug }}\n\t\t\tonError={(error) => {\n\t\t\t\tif (onRouteError) {\n\t\t\t\t\tonRouteError(\"tag\", error, {\n\t\t\t\t\t\tpath: `/blog/tag/${tagSlug}`,\n\t\t\t\t\t\tisSSR: typeof window === \"undefined\",\n\t\t\t\t\t\ttagSlug,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}}\n\t\t/>\n\t);\n}\n",
212212
"target": "src/components/btst/blog/client/components/pages/tag-page.tsx"
213213
},
214+
{
215+
"path": "btst/blog/client/components/shared/collapsible-tag-list.tsx",
216+
"type": "registry:component",
217+
"content": "\"use client\";\n\nimport { usePluginOverrides, useBasePath } from \"@btst/stack/context\";\nimport type { BlogPluginOverrides } from \"../../overrides\";\nimport { DefaultLink } from \"./defaults\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { BLOG_LOCALIZATION } from \"../../localization\";\nimport { ChevronDown, ChevronUp } from \"lucide-react\";\nimport { useState } from \"react\";\nimport type { SerializedTag } from \"../../../types\";\n\nconst MAX_VISIBLE_TAGS = 15;\n\ninterface CollapsibleTagListProps {\n\ttags: SerializedTag[];\n\tmaxVisible?: number;\n}\n\nexport function CollapsibleTagList({\n\ttags,\n\tmaxVisible = MAX_VISIBLE_TAGS,\n}: CollapsibleTagListProps) {\n\tconst { Link, localization } = usePluginOverrides<\n\t\tBlogPluginOverrides,\n\t\tPartial<BlogPluginOverrides>\n\t>(\"blog\", {\n\t\tLink: DefaultLink,\n\t\tlocalization: BLOG_LOCALIZATION,\n\t});\n\tconst basePath = useBasePath();\n\tconst [showAll, setShowAll] = useState(false);\n\n\tif (!tags || tags.length === 0) {\n\t\treturn null;\n\t}\n\n\tconst hasMore = tags.length > maxVisible;\n\tconst visibleTags = showAll || !hasMore ? tags : tags.slice(0, maxVisible);\n\n\treturn (\n\t\t<>\n\t\t\t{visibleTags.map((tag) => (\n\t\t\t\t<Link key={tag.id} href={`${basePath}/blog/tag/${tag.slug}`}>\n\t\t\t\t\t<Badge variant=\"secondary\" className=\"text-xs\">\n\t\t\t\t\t\t{tag.name}\n\t\t\t\t\t</Badge>\n\t\t\t\t</Link>\n\t\t\t))}\n\t\t\t{hasMore && (\n\t\t\t\t<Badge asChild variant=\"secondary\" className=\"text-xs cursor-pointer\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={() => setShowAll((prev) => !prev)}\n\t\t\t\t\t\taria-expanded={showAll}\n\t\t\t\t\t\taria-label={\n\t\t\t\t\t\t\tshowAll\n\t\t\t\t\t\t\t\t? localization.BLOG_TAGS_SHOW_LESS\n\t\t\t\t\t\t\t\t: localization.BLOG_TAGS_SHOW_ALL\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttitle={\n\t\t\t\t\t\t\tshowAll\n\t\t\t\t\t\t\t\t? localization.BLOG_TAGS_SHOW_LESS\n\t\t\t\t\t\t\t\t: localization.BLOG_TAGS_SHOW_ALL\n\t\t\t\t\t\t}\n\t\t\t\t\t>\n\t\t\t\t\t\t{showAll ? (\n\t\t\t\t\t\t\t<ChevronUp aria-hidden=\"true\" />\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<ChevronDown aria-hidden=\"true\" />\n\t\t\t\t\t\t)}\n\t\t\t\t\t</button>\n\t\t\t\t</Badge>\n\t\t\t)}\n\t\t</>\n\t);\n}\n",
218+
"target": "src/components/btst/blog/client/components/shared/collapsible-tag-list.tsx"
219+
},
214220
{
215221
"path": "btst/blog/client/components/shared/default-error.tsx",
216222
"type": "registry:component",
@@ -310,7 +316,7 @@
310316
{
311317
"path": "btst/blog/client/components/shared/tags-list.tsx",
312318
"type": "registry:component",
313-
"content": "\"use client\";\n\nimport { usePluginOverrides, useBasePath } from \"@btst/stack/context\";\nimport type { BlogPluginOverrides } from \"../../overrides\";\nimport { DefaultLink } from \"./defaults\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { useSuspenseTags } from \"@btst/stack/plugins/blog/client/hooks\";\nimport { BLOG_LOCALIZATION } from \"../../localization\";\nimport { ChevronDown, ChevronUp } from \"lucide-react\";\nimport { useState } from \"react\";\n\nconst MAX_VISIBLE_TAGS = 15;\n\nexport function TagsList() {\n\tconst { tags } = useSuspenseTags();\n\tconst { Link, localization } = usePluginOverrides<\n\t\tBlogPluginOverrides,\n\t\tPartial<BlogPluginOverrides>\n\t>(\"blog\", {\n\t\tLink: DefaultLink,\n\t\tlocalization: BLOG_LOCALIZATION,\n\t});\n\tconst basePath = useBasePath();\n\tconst [showAll, setShowAll] = useState(false);\n\n\tif (!tags || tags.length === 0) {\n\t\treturn null;\n\t}\n\n\tconst hasMore = tags.length > MAX_VISIBLE_TAGS;\n\tconst visibleTags =\n\t\tshowAll || !hasMore ? tags : tags.slice(0, MAX_VISIBLE_TAGS);\n\n\treturn (\n\t\t<div className=\"flex flex-wrap gap-2 justify-center\">\n\t\t\t{visibleTags.map((tag) => (\n\t\t\t\t<Link key={tag.id} href={`${basePath}/blog/tag/${tag.slug}`}>\n\t\t\t\t\t<Badge variant=\"secondary\" className=\"text-xs\">\n\t\t\t\t\t\t{tag.name}\n\t\t\t\t\t</Badge>\n\t\t\t\t</Link>\n\t\t\t))}\n\t\t\t{hasMore && (\n\t\t\t\t<Badge asChild variant=\"secondary\" className=\"text-xs cursor-pointer\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={() => setShowAll((prev) => !prev)}\n\t\t\t\t\t\taria-expanded={showAll}\n\t\t\t\t\t\taria-label={\n\t\t\t\t\t\t\tshowAll\n\t\t\t\t\t\t\t\t? localization.BLOG_TAGS_SHOW_LESS\n\t\t\t\t\t\t\t\t: localization.BLOG_TAGS_SHOW_ALL\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttitle={\n\t\t\t\t\t\t\tshowAll\n\t\t\t\t\t\t\t\t? localization.BLOG_TAGS_SHOW_LESS\n\t\t\t\t\t\t\t\t: localization.BLOG_TAGS_SHOW_ALL\n\t\t\t\t\t\t}\n\t\t\t\t\t>\n\t\t\t\t\t\t{showAll ? (\n\t\t\t\t\t\t\t<ChevronUp aria-hidden=\"true\" />\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<ChevronDown aria-hidden=\"true\" />\n\t\t\t\t\t\t)}\n\t\t\t\t\t</button>\n\t\t\t\t</Badge>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n",
319+
"content": "\"use client\";\n\nimport { useSuspenseTags } from \"@btst/stack/plugins/blog/client/hooks\";\nimport { CollapsibleTagList } from \"./collapsible-tag-list\";\n\nexport function TagsList() {\n\tconst { tags } = useSuspenseTags();\n\n\tif (!tags || tags.length === 0) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<div className=\"flex flex-wrap gap-2 justify-center\">\n\t\t\t<CollapsibleTagList tags={tags} />\n\t\t</div>\n\t);\n}\n",
314320
"target": "src/components/btst/blog/client/components/shared/tags-list.tsx"
315321
},
316322
{

0 commit comments

Comments
 (0)