@btst/stack 3.1.2 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/README.md +2 -2
  2. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-input.cjs +112 -103
  3. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-input.mjs +112 -103
  4. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-interface.cjs +5 -2
  5. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-interface.mjs +5 -2
  6. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-layout.cjs +99 -88
  7. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-layout.mjs +99 -88
  8. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-message.cjs +12 -3
  9. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-message.mjs +12 -3
  10. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-sidebar.cjs +6 -2
  11. package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-sidebar.mjs +6 -2
  12. package/dist/packages/stack/src/plugins/ai-chat/client/hooks/chat-hooks.cjs +5 -5
  13. package/dist/packages/stack/src/plugins/ai-chat/client/hooks/chat-hooks.mjs +5 -5
  14. package/dist/packages/stack/src/plugins/blog/client/components/shared/page-wrapper.cjs +3 -2
  15. package/dist/packages/stack/src/plugins/blog/client/components/shared/page-wrapper.mjs +3 -2
  16. package/dist/packages/stack/src/plugins/blog/client/components/shared/post-card.cjs +81 -52
  17. package/dist/packages/stack/src/plugins/blog/client/components/shared/post-card.mjs +82 -53
  18. package/dist/packages/stack/src/plugins/blog/client/components/shared/posts-list.cjs +3 -2
  19. package/dist/packages/stack/src/plugins/blog/client/components/shared/posts-list.mjs +3 -2
  20. package/dist/packages/stack/src/plugins/cms/client/components/pages/content-list-page.internal.cjs +95 -75
  21. package/dist/packages/stack/src/plugins/cms/client/components/pages/content-list-page.internal.mjs +95 -75
  22. package/dist/packages/stack/src/plugins/cms/client/components/pages/dashboard-page.internal.cjs +16 -3
  23. package/dist/packages/stack/src/plugins/cms/client/components/pages/dashboard-page.internal.mjs +16 -3
  24. package/dist/packages/stack/src/plugins/cms/client/components/shared/page-wrapper.cjs +3 -2
  25. package/dist/packages/stack/src/plugins/cms/client/components/shared/page-wrapper.mjs +3 -2
  26. package/dist/packages/stack/src/plugins/cms/utils.cjs +6 -2
  27. package/dist/packages/stack/src/plugins/cms/utils.mjs +6 -3
  28. package/dist/packages/stack/src/plugins/form-builder/client/components/forms/form-renderer.cjs +14 -8
  29. package/dist/packages/stack/src/plugins/form-builder/client/components/forms/form-renderer.mjs +14 -8
  30. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/form-list-page.internal.cjs +94 -87
  31. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/form-list-page.internal.mjs +94 -87
  32. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/submissions-page.internal.cjs +81 -74
  33. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/submissions-page.internal.mjs +81 -74
  34. package/dist/packages/stack/src/plugins/form-builder/client/components/shared/page-wrapper.cjs +3 -2
  35. package/dist/packages/stack/src/plugins/form-builder/client/components/shared/page-wrapper.mjs +3 -2
  36. package/dist/packages/stack/src/plugins/form-builder/client/components/shared/pagination.cjs +25 -16
  37. package/dist/packages/stack/src/plugins/form-builder/client/components/shared/pagination.mjs +25 -16
  38. package/dist/packages/stack/src/plugins/form-builder/utils.cjs +6 -2
  39. package/dist/packages/stack/src/plugins/form-builder/utils.mjs +6 -3
  40. package/dist/packages/stack/src/plugins/kanban/api/getters.cjs +7 -5
  41. package/dist/packages/stack/src/plugins/kanban/api/getters.mjs +7 -5
  42. package/dist/packages/stack/src/plugins/media/client/hooks/use-media.cjs +10 -8
  43. package/dist/packages/stack/src/plugins/media/client/hooks/use-media.mjs +10 -8
  44. package/dist/plugins/ai-chat/client/components/index.d.cts +1 -1
  45. package/dist/plugins/ai-chat/client/components/index.d.mts +1 -1
  46. package/dist/plugins/ai-chat/client/components/index.d.ts +1 -1
  47. package/dist/plugins/ai-chat/client/index.d.cts +2 -2
  48. package/dist/plugins/ai-chat/client/index.d.mts +2 -2
  49. package/dist/plugins/ai-chat/client/index.d.ts +2 -2
  50. package/dist/plugins/blog/api/index.d.cts +2 -2
  51. package/dist/plugins/blog/api/index.d.mts +2 -2
  52. package/dist/plugins/blog/api/index.d.ts +2 -2
  53. package/dist/plugins/blog/client/hooks/index.d.cts +2 -2
  54. package/dist/plugins/blog/client/hooks/index.d.mts +2 -2
  55. package/dist/plugins/blog/client/hooks/index.d.ts +2 -2
  56. package/dist/plugins/blog/client/index.d.cts +20 -2
  57. package/dist/plugins/blog/client/index.d.mts +20 -2
  58. package/dist/plugins/blog/client/index.d.ts +20 -2
  59. package/dist/plugins/blog/query-keys.d.cts +2 -2
  60. package/dist/plugins/blog/query-keys.d.mts +2 -2
  61. package/dist/plugins/blog/query-keys.d.ts +2 -2
  62. package/dist/plugins/cms/api/index.d.cts +1 -1
  63. package/dist/plugins/cms/api/index.d.mts +1 -1
  64. package/dist/plugins/cms/api/index.d.ts +1 -1
  65. package/dist/plugins/cms/client/index.d.cts +18 -0
  66. package/dist/plugins/cms/client/index.d.mts +18 -0
  67. package/dist/plugins/cms/client/index.d.ts +18 -0
  68. package/dist/plugins/cms/query-keys.d.cts +1 -1
  69. package/dist/plugins/cms/query-keys.d.mts +1 -1
  70. package/dist/plugins/cms/query-keys.d.ts +1 -1
  71. package/dist/plugins/form-builder/client/index.d.cts +16 -0
  72. package/dist/plugins/form-builder/client/index.d.mts +16 -0
  73. package/dist/plugins/form-builder/client/index.d.ts +16 -0
  74. package/dist/plugins/ui-builder/client/hooks/index.d.cts +1 -1
  75. package/dist/plugins/ui-builder/client/hooks/index.d.mts +1 -1
  76. package/dist/plugins/ui-builder/client/hooks/index.d.ts +1 -1
  77. package/dist/plugins/ui-builder/client/index.d.cts +1 -1
  78. package/dist/plugins/ui-builder/client/index.d.mts +1 -1
  79. package/dist/plugins/ui-builder/client/index.d.ts +1 -1
  80. package/dist/plugins/ui-builder/query-keys.d.cts +1 -1
  81. package/dist/plugins/ui-builder/query-keys.d.mts +1 -1
  82. package/dist/plugins/ui-builder/query-keys.d.ts +1 -1
  83. package/dist/shared/{stack.BTStHVTy.d.cts → stack.BGzgFx3R.d.cts} +5 -5
  84. package/dist/shared/{stack.CtrnoQgH.d.cts → stack.BOZRaVpu.d.cts} +35 -35
  85. package/dist/shared/{stack.94kN3pEK.d.mts → stack.CjCSDfWy.d.mts} +5 -5
  86. package/dist/shared/{stack.lPKwd_v0.d.ts → stack.DlBoNqYu.d.ts} +35 -35
  87. package/dist/shared/{stack.DfrRYOIl.d.ts → stack.Dpg_JjIo.d.ts} +5 -5
  88. package/dist/shared/{stack.BggTHKlo.d.mts → stack.Dvy7FmaA.d.mts} +35 -35
  89. package/dist/shared/{stack.5_zzCejP.d.cts → stack.rVF0f509.d.cts} +20 -0
  90. package/dist/shared/{stack.5_zzCejP.d.mts → stack.rVF0f509.d.mts} +20 -0
  91. package/dist/shared/{stack.5_zzCejP.d.ts → stack.rVF0f509.d.ts} +20 -0
  92. package/package.json +11 -7
  93. package/src/__tests__/package-metadata.test.ts +4 -4
  94. package/src/plugins/ai-chat/__tests__/classnames-overrides.test.tsx +248 -0
  95. package/src/plugins/ai-chat/__tests__/hooks.test.tsx +70 -54
  96. package/src/plugins/ai-chat/client/components/chat-input.tsx +6 -1
  97. package/src/plugins/ai-chat/client/components/chat-interface.tsx +3 -0
  98. package/src/plugins/ai-chat/client/components/chat-layout.tsx +9 -2
  99. package/src/plugins/ai-chat/client/components/chat-message.tsx +13 -5
  100. package/src/plugins/ai-chat/client/components/chat-sidebar.tsx +6 -2
  101. package/src/plugins/ai-chat/client/hooks/chat-hooks.tsx +6 -9
  102. package/src/plugins/ai-chat/client/overrides.ts +21 -0
  103. package/src/plugins/blog/__tests__/classnames-overrides.test.tsx +206 -0
  104. package/src/plugins/blog/client/components/shared/page-wrapper.tsx +3 -2
  105. package/src/plugins/blog/client/components/shared/post-card.tsx +32 -12
  106. package/src/plugins/blog/client/components/shared/posts-list.tsx +3 -2
  107. package/src/plugins/blog/client/overrides.ts +18 -0
  108. package/src/plugins/cms/__tests__/classnames-overrides.test.tsx +200 -0
  109. package/src/plugins/cms/client/components/pages/content-list-page.internal.tsx +17 -4
  110. package/src/plugins/cms/client/components/pages/dashboard-page.internal.tsx +14 -3
  111. package/src/plugins/cms/client/components/shared/page-wrapper.tsx +3 -2
  112. package/src/plugins/cms/client/overrides.ts +19 -0
  113. package/src/plugins/form-builder/__tests__/classnames-overrides.test.tsx +312 -0
  114. package/src/plugins/form-builder/client/components/forms/form-renderer.tsx +14 -9
  115. package/src/plugins/form-builder/client/components/pages/form-list-page.internal.tsx +9 -5
  116. package/src/plugins/form-builder/client/components/pages/submissions-page.internal.tsx +9 -5
  117. package/src/plugins/form-builder/client/components/shared/page-wrapper.tsx +3 -2
  118. package/src/plugins/form-builder/client/components/shared/pagination.tsx +7 -1
  119. package/src/plugins/form-builder/client/overrides.ts +17 -0
  120. package/src/plugins/kanban/__tests__/getters.test.ts +14 -1
  121. package/src/plugins/kanban/api/getters.ts +9 -7
  122. package/src/plugins/kanban/types.ts +4 -6
  123. package/src/plugins/media/client/hooks/use-media.tsx +7 -8
  124. package/dist/shared/{stack.lsbdKRj7.d.mts → stack.B8PG21zX.d.mts} +16 -16
  125. package/dist/shared/{stack.CKc_Bais.d.cts → stack.Csi-4Mgz.d.cts} +7 -7
  126. package/dist/shared/{stack.CKc_Bais.d.mts → stack.Csi-4Mgz.d.mts} +7 -7
  127. package/dist/shared/{stack.CKc_Bais.d.ts → stack.Csi-4Mgz.d.ts} +7 -7
  128. package/dist/shared/{stack.BMlTZnZp.d.ts → stack.CyalJ0j6.d.ts} +16 -16
  129. package/dist/shared/{stack.BV0uNV4f.d.cts → stack.D6Pg-ufX.d.cts} +16 -16
@@ -9,6 +9,7 @@ const formatPostDate = require('./format-post-date.cjs');
9
9
  const LucideIcons = require('lucide-react');
10
10
  const constants = require('../../constants.cjs');
11
11
  const defaults = require('./defaults.cjs');
12
+ const utils = require('../../../utils.cjs');
12
13
 
13
14
  const GRADIENT_PALETTES = [
14
15
  {
@@ -208,7 +209,7 @@ function getGradientFromTitle(title) {
208
209
  }
209
210
  function PostCard({ post }) {
210
211
  const t = context.useTranslate();
211
- const { localization } = context.usePluginOverrides(constants.BLOG_PLUGIN_ID, {});
212
+ const { localization, classNames } = context.usePluginOverrides(constants.BLOG_PLUGIN_ID, {});
212
213
  const { router } = context.useStack();
213
214
  const Link = router?.Link ?? defaults.DefaultLink;
214
215
  const Image = router?.Image ?? defaults.DefaultImage;
@@ -217,59 +218,87 @@ function PostCard({ post }) {
217
218
  const timestamp = post.publishedAt || post.createdAt;
218
219
  const postDate = formatPostDate.formatPostDate(timestamp);
219
220
  const gradient = post.image ? null : getGradientFromTitle(post.title);
220
- return /* @__PURE__ */ jsxRuntime.jsxs(card.Card, { className: "group relative flex h-full flex-col gap-4 pt-0! pb-4! transition-shadow duration-200 hover:shadow-lg", children: [
221
- /* @__PURE__ */ jsxRuntime.jsx(
222
- Link,
223
- {
224
- href: blogPath,
225
- className: "relative block h-48 w-full overflow-hidden rounded-t-xl bg-muted",
226
- "aria-label": post.title,
227
- children: post.image ? /* @__PURE__ */ jsxRuntime.jsx(
228
- Image,
221
+ const tags = post.tags?.map((tag) => /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { variant: "secondary", className: "text-xs", children: tag.name }, tag.id));
222
+ return /* @__PURE__ */ jsxRuntime.jsxs(
223
+ card.Card,
224
+ {
225
+ className: utils.cn(
226
+ "group relative flex h-full flex-col gap-4 pt-0! pb-4! transition-shadow duration-200 hover:shadow-lg",
227
+ classNames?.postCard
228
+ ),
229
+ children: [
230
+ /* @__PURE__ */ jsxRuntime.jsx(
231
+ Link,
229
232
  {
230
- src: post.image,
231
- alt: post.title,
232
- className: "h-full w-full object-cover transition-transform duration-200 group-hover:scale-105",
233
- width: 500,
234
- height: 300
233
+ href: blogPath,
234
+ className: "relative block h-48 w-full overflow-hidden rounded-t-xl bg-muted",
235
+ "aria-label": post.title,
236
+ children: post.image ? /* @__PURE__ */ jsxRuntime.jsx(
237
+ Image,
238
+ {
239
+ src: post.image,
240
+ alt: post.title,
241
+ className: "h-full w-full object-cover transition-transform duration-200 group-hover:scale-105",
242
+ width: 500,
243
+ height: 300
244
+ }
245
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative h-full w-full overflow-hidden transition-transform duration-200 group-hover:scale-105", children: [
246
+ /* @__PURE__ */ jsxRuntime.jsx(
247
+ "div",
248
+ {
249
+ className: `absolute inset-0 bg-linear-to-br ${gradient.from} ${gradient.via} ${gradient.to}`
250
+ }
251
+ ),
252
+ /* @__PURE__ */ jsxRuntime.jsx(
253
+ "div",
254
+ {
255
+ className: `absolute inset-0 bg-linear-to-tr ${gradient.overlay} via-transparent to-transparent`
256
+ }
257
+ ),
258
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative z-10 flex h-full w-full items-center justify-center p-6", children: /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-center text-xl font-bold leading-tight text-white drop-shadow-lg line-clamp-3", children: post.title }) })
259
+ ] })
235
260
  }
236
- ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative h-full w-full overflow-hidden transition-transform duration-200 group-hover:scale-105", children: [
237
- /* @__PURE__ */ jsxRuntime.jsx(
238
- "div",
239
- {
240
- className: `absolute inset-0 bg-linear-to-br ${gradient.from} ${gradient.via} ${gradient.to}`
241
- }
242
- ),
243
- /* @__PURE__ */ jsxRuntime.jsx(
244
- "div",
245
- {
246
- className: `absolute inset-0 bg-linear-to-tr ${gradient.overlay} via-transparent to-transparent`
247
- }
248
- ),
249
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative z-10 flex h-full w-full items-center justify-center p-6", children: /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-center text-xl font-bold leading-tight text-white drop-shadow-lg line-clamp-3", children: post.title }) })
250
- ] })
251
- }
252
- ),
253
- !post.published && /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { variant: "destructive", className: "absolute top-2 left-2 text-xs", children: localization?.BLOG_CARD_DRAFT_BADGE ?? t("blog.card.draftBadge", "Draft") }),
254
- /* @__PURE__ */ jsxRuntime.jsxs(
255
- Link,
256
- {
257
- href: blogPath,
258
- "aria-label": `${post.title}`,
259
- className: "block focus:outline-none focus-visible:ring-2 focus-visible:ring-ring/50 grow",
260
- children: [
261
- /* @__PURE__ */ jsxRuntime.jsx(card.CardHeader, { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(card.CardTitle, { className: "line-clamp-3 text-lg leading-tight transition-colors group-hover:underline", children: post.title }) }),
262
- /* @__PURE__ */ jsxRuntime.jsx(card.CardContent, { className: "flex flex-1 flex-col gap-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
263
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-muted-foreground text-xs", children: [
264
- /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.CalendarIcon, { className: "h-3 w-3" }),
265
- /* @__PURE__ */ jsxRuntime.jsx("time", { dateTime: timestamp, children: postDate })
266
- ] }),
267
- post.tags && post.tags.length > 0 && post.tags.map((tag) => /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { variant: "secondary", className: "text-xs", children: tag.name }, tag.id))
268
- ] }) })
269
- ]
270
- }
271
- )
272
- ] });
261
+ ),
262
+ !post.published && /* @__PURE__ */ jsxRuntime.jsx(badge.Badge, { variant: "destructive", className: "absolute top-2 left-2 text-xs", children: localization?.BLOG_CARD_DRAFT_BADGE ?? t("blog.card.draftBadge", "Draft") }),
263
+ /* @__PURE__ */ jsxRuntime.jsxs(
264
+ Link,
265
+ {
266
+ href: blogPath,
267
+ "aria-label": `${post.title}`,
268
+ className: "block focus:outline-none focus-visible:ring-2 focus-visible:ring-ring/50 grow",
269
+ children: [
270
+ /* @__PURE__ */ jsxRuntime.jsx(card.CardHeader, { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
271
+ card.CardTitle,
272
+ {
273
+ className: utils.cn(
274
+ "line-clamp-3 text-lg leading-tight transition-colors group-hover:underline",
275
+ classNames?.postTitle
276
+ ),
277
+ children: post.title
278
+ }
279
+ ) }),
280
+ /* @__PURE__ */ jsxRuntime.jsx(card.CardContent, { className: "flex flex-1 flex-col gap-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
281
+ /* @__PURE__ */ jsxRuntime.jsxs(
282
+ "div",
283
+ {
284
+ className: utils.cn(
285
+ "flex items-center gap-2 text-muted-foreground text-xs",
286
+ classNames?.postMeta
287
+ ),
288
+ children: [
289
+ /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.CalendarIcon, { className: "h-3 w-3" }),
290
+ /* @__PURE__ */ jsxRuntime.jsx("time", { dateTime: timestamp, children: postDate })
291
+ ]
292
+ }
293
+ ),
294
+ classNames?.tagsList ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: utils.cn("flex flex-wrap gap-2", classNames.tagsList), children: tags }) : tags
295
+ ] }) })
296
+ ]
297
+ }
298
+ )
299
+ ]
300
+ }
301
+ );
273
302
  }
274
303
 
275
304
  exports.PostCard = PostCard;
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
3
  import { Badge } from '../../../../../../../ui/src/components/badge.mjs';
4
4
  import { Card, CardHeader, CardTitle, CardContent } from '../../../../../../../ui/src/components/card.mjs';
5
5
  import { useTranslate, usePluginOverrides, useStack, useBasePath } from '@btst/stack/context';
@@ -7,6 +7,7 @@ import { formatPostDate } from './format-post-date.mjs';
7
7
  import { CalendarIcon } from 'lucide-react';
8
8
  import { BLOG_PLUGIN_ID } from '../../constants.mjs';
9
9
  import { DefaultLink, DefaultImage } from './defaults.mjs';
10
+ import { cn } from '../../../utils.mjs';
10
11
 
11
12
  const GRADIENT_PALETTES = [
12
13
  {
@@ -206,7 +207,7 @@ function getGradientFromTitle(title) {
206
207
  }
207
208
  function PostCard({ post }) {
208
209
  const t = useTranslate();
209
- const { localization } = usePluginOverrides(BLOG_PLUGIN_ID, {});
210
+ const { localization, classNames } = usePluginOverrides(BLOG_PLUGIN_ID, {});
210
211
  const { router } = useStack();
211
212
  const Link = router?.Link ?? DefaultLink;
212
213
  const Image = router?.Image ?? DefaultImage;
@@ -215,59 +216,87 @@ function PostCard({ post }) {
215
216
  const timestamp = post.publishedAt || post.createdAt;
216
217
  const postDate = formatPostDate(timestamp);
217
218
  const gradient = post.image ? null : getGradientFromTitle(post.title);
218
- return /* @__PURE__ */ jsxs(Card, { className: "group relative flex h-full flex-col gap-4 pt-0! pb-4! transition-shadow duration-200 hover:shadow-lg", children: [
219
- /* @__PURE__ */ jsx(
220
- Link,
221
- {
222
- href: blogPath,
223
- className: "relative block h-48 w-full overflow-hidden rounded-t-xl bg-muted",
224
- "aria-label": post.title,
225
- children: post.image ? /* @__PURE__ */ jsx(
226
- Image,
219
+ const tags = post.tags?.map((tag) => /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs", children: tag.name }, tag.id));
220
+ return /* @__PURE__ */ jsxs(
221
+ Card,
222
+ {
223
+ className: cn(
224
+ "group relative flex h-full flex-col gap-4 pt-0! pb-4! transition-shadow duration-200 hover:shadow-lg",
225
+ classNames?.postCard
226
+ ),
227
+ children: [
228
+ /* @__PURE__ */ jsx(
229
+ Link,
227
230
  {
228
- src: post.image,
229
- alt: post.title,
230
- className: "h-full w-full object-cover transition-transform duration-200 group-hover:scale-105",
231
- width: 500,
232
- height: 300
231
+ href: blogPath,
232
+ className: "relative block h-48 w-full overflow-hidden rounded-t-xl bg-muted",
233
+ "aria-label": post.title,
234
+ children: post.image ? /* @__PURE__ */ jsx(
235
+ Image,
236
+ {
237
+ src: post.image,
238
+ alt: post.title,
239
+ className: "h-full w-full object-cover transition-transform duration-200 group-hover:scale-105",
240
+ width: 500,
241
+ height: 300
242
+ }
243
+ ) : /* @__PURE__ */ jsxs("div", { className: "relative h-full w-full overflow-hidden transition-transform duration-200 group-hover:scale-105", children: [
244
+ /* @__PURE__ */ jsx(
245
+ "div",
246
+ {
247
+ className: `absolute inset-0 bg-linear-to-br ${gradient.from} ${gradient.via} ${gradient.to}`
248
+ }
249
+ ),
250
+ /* @__PURE__ */ jsx(
251
+ "div",
252
+ {
253
+ className: `absolute inset-0 bg-linear-to-tr ${gradient.overlay} via-transparent to-transparent`
254
+ }
255
+ ),
256
+ /* @__PURE__ */ jsx("div", { className: "relative z-10 flex h-full w-full items-center justify-center p-6", children: /* @__PURE__ */ jsx("h3", { className: "text-center text-xl font-bold leading-tight text-white drop-shadow-lg line-clamp-3", children: post.title }) })
257
+ ] })
233
258
  }
234
- ) : /* @__PURE__ */ jsxs("div", { className: "relative h-full w-full overflow-hidden transition-transform duration-200 group-hover:scale-105", children: [
235
- /* @__PURE__ */ jsx(
236
- "div",
237
- {
238
- className: `absolute inset-0 bg-linear-to-br ${gradient.from} ${gradient.via} ${gradient.to}`
239
- }
240
- ),
241
- /* @__PURE__ */ jsx(
242
- "div",
243
- {
244
- className: `absolute inset-0 bg-linear-to-tr ${gradient.overlay} via-transparent to-transparent`
245
- }
246
- ),
247
- /* @__PURE__ */ jsx("div", { className: "relative z-10 flex h-full w-full items-center justify-center p-6", children: /* @__PURE__ */ jsx("h3", { className: "text-center text-xl font-bold leading-tight text-white drop-shadow-lg line-clamp-3", children: post.title }) })
248
- ] })
249
- }
250
- ),
251
- !post.published && /* @__PURE__ */ jsx(Badge, { variant: "destructive", className: "absolute top-2 left-2 text-xs", children: localization?.BLOG_CARD_DRAFT_BADGE ?? t("blog.card.draftBadge", "Draft") }),
252
- /* @__PURE__ */ jsxs(
253
- Link,
254
- {
255
- href: blogPath,
256
- "aria-label": `${post.title}`,
257
- className: "block focus:outline-none focus-visible:ring-2 focus-visible:ring-ring/50 grow",
258
- children: [
259
- /* @__PURE__ */ jsx(CardHeader, { className: "flex-1", children: /* @__PURE__ */ jsx(CardTitle, { className: "line-clamp-3 text-lg leading-tight transition-colors group-hover:underline", children: post.title }) }),
260
- /* @__PURE__ */ jsx(CardContent, { className: "flex flex-1 flex-col gap-2", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
261
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-muted-foreground text-xs", children: [
262
- /* @__PURE__ */ jsx(CalendarIcon, { className: "h-3 w-3" }),
263
- /* @__PURE__ */ jsx("time", { dateTime: timestamp, children: postDate })
264
- ] }),
265
- post.tags && post.tags.length > 0 && post.tags.map((tag) => /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs", children: tag.name }, tag.id))
266
- ] }) })
267
- ]
268
- }
269
- )
270
- ] });
259
+ ),
260
+ !post.published && /* @__PURE__ */ jsx(Badge, { variant: "destructive", className: "absolute top-2 left-2 text-xs", children: localization?.BLOG_CARD_DRAFT_BADGE ?? t("blog.card.draftBadge", "Draft") }),
261
+ /* @__PURE__ */ jsxs(
262
+ Link,
263
+ {
264
+ href: blogPath,
265
+ "aria-label": `${post.title}`,
266
+ className: "block focus:outline-none focus-visible:ring-2 focus-visible:ring-ring/50 grow",
267
+ children: [
268
+ /* @__PURE__ */ jsx(CardHeader, { className: "flex-1", children: /* @__PURE__ */ jsx(
269
+ CardTitle,
270
+ {
271
+ className: cn(
272
+ "line-clamp-3 text-lg leading-tight transition-colors group-hover:underline",
273
+ classNames?.postTitle
274
+ ),
275
+ children: post.title
276
+ }
277
+ ) }),
278
+ /* @__PURE__ */ jsx(CardContent, { className: "flex flex-1 flex-col gap-2", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
279
+ /* @__PURE__ */ jsxs(
280
+ "div",
281
+ {
282
+ className: cn(
283
+ "flex items-center gap-2 text-muted-foreground text-xs",
284
+ classNames?.postMeta
285
+ ),
286
+ children: [
287
+ /* @__PURE__ */ jsx(CalendarIcon, { className: "h-3 w-3" }),
288
+ /* @__PURE__ */ jsx("time", { dateTime: timestamp, children: postDate })
289
+ ]
290
+ }
291
+ ),
292
+ classNames?.tagsList ? /* @__PURE__ */ jsx("div", { className: cn("flex flex-wrap gap-2", classNames.tagsList), children: tags }) : tags
293
+ ] }) })
294
+ ]
295
+ }
296
+ )
297
+ ]
298
+ }
299
+ );
271
300
  }
272
301
 
273
302
  export { PostCard };
@@ -7,6 +7,7 @@ const emptyList = require('./empty-list.cjs');
7
7
  const searchInput = require('./search-input.cjs');
8
8
  const constants = require('../../constants.cjs');
9
9
  const postCard = require('./post-card.cjs');
10
+ const utils = require('../../../utils.cjs');
10
11
 
11
12
  function PostsList({
12
13
  posts,
@@ -15,7 +16,7 @@ function PostsList({
15
16
  isLoadingMore
16
17
  }) {
17
18
  const t = context.useTranslate();
18
- const { localization, PostCard } = context.usePluginOverrides(constants.BLOG_PLUGIN_ID);
19
+ const { localization, PostCard, classNames } = context.usePluginOverrides(constants.BLOG_PLUGIN_ID);
19
20
  const PostCardComponent = PostCard || postCard.PostCard;
20
21
  if (posts.length === 0) {
21
22
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -35,7 +36,7 @@ function PostsList({
35
36
  }
36
37
  ) }),
37
38
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3", children: posts.map((post) => /* @__PURE__ */ jsxRuntime.jsx(PostCardComponent, { post }, post.id)) }),
38
- onLoadMore && hasMore && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(
39
+ onLoadMore && hasMore && /* @__PURE__ */ jsxRuntime.jsx("div", { className: utils.cn("flex justify-center", classNames?.pagination), children: /* @__PURE__ */ jsxRuntime.jsx(
39
40
  button.Button,
40
41
  {
41
42
  onClick: onLoadMore,
@@ -5,6 +5,7 @@ import { EmptyList } from './empty-list.mjs';
5
5
  import { SearchInput } from './search-input.mjs';
6
6
  import { BLOG_PLUGIN_ID } from '../../constants.mjs';
7
7
  import { PostCard } from './post-card.mjs';
8
+ import { cn } from '../../../utils.mjs';
8
9
 
9
10
  function PostsList({
10
11
  posts,
@@ -13,7 +14,7 @@ function PostsList({
13
14
  isLoadingMore
14
15
  }) {
15
16
  const t = useTranslate();
16
- const { localization, PostCard: PostCard$1 } = usePluginOverrides(BLOG_PLUGIN_ID);
17
+ const { localization, PostCard: PostCard$1, classNames } = usePluginOverrides(BLOG_PLUGIN_ID);
17
18
  const PostCardComponent = PostCard$1 || PostCard;
18
19
  if (posts.length === 0) {
19
20
  return /* @__PURE__ */ jsx(
@@ -33,7 +34,7 @@ function PostsList({
33
34
  }
34
35
  ) }),
35
36
  /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3", children: posts.map((post) => /* @__PURE__ */ jsx(PostCardComponent, { post }, post.id)) }),
36
- onLoadMore && hasMore && /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
37
+ onLoadMore && hasMore && /* @__PURE__ */ jsx("div", { className: cn("flex justify-center", classNames?.pagination), children: /* @__PURE__ */ jsx(
37
38
  Button,
38
39
  {
39
40
  onClick: onLoadMore,
@@ -12,6 +12,7 @@ const plugins_cms_permissions = require('../../../../../../../../plugins/cms/per
12
12
  const hooks = require('@btst/stack/client/hooks');
13
13
  const overrides = require('../../overrides.cjs');
14
14
  const constants = require('../../constants.cjs');
15
+ const utils = require('../../../utils.cjs');
15
16
  const emptyState = require('../shared/empty-state.cjs');
16
17
  const pageWrapper = require('../shared/page-wrapper.cjs');
17
18
  const useRouteLifecycle = require('../../../../../../../ui/src/hooks/use-route-lifecycle.cjs');
@@ -25,7 +26,7 @@ function ContentListPage({ typeSlug }) {
25
26
  const t = context.useTranslate();
26
27
  const notify = context.useNotify();
27
28
  const overrides$1 = context.usePluginOverrides(constants.CMS_PLUGIN_ID);
28
- const { localization } = overrides$1;
29
+ const { localization, classNames } = overrides$1;
29
30
  const { router, plugins, basePath: stackBasePath } = context.useStack();
30
31
  const navigate = router?.navigate;
31
32
  const Link = router?.Link;
@@ -207,6 +208,7 @@ function ContentListPage({ typeSlug }) {
207
208
  hasMore,
208
209
  isLoadingMore,
209
210
  localization,
211
+ classNames,
210
212
  t
211
213
  }
212
214
  )
@@ -226,89 +228,107 @@ function ContentTable({
226
228
  hasMore,
227
229
  isLoadingMore,
228
230
  localization,
231
+ classNames,
229
232
  t
230
233
  }) {
231
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border rounded-lg", children: [
232
- /* @__PURE__ */ jsxRuntime.jsxs(table.Table, { children: [
233
- /* @__PURE__ */ jsxRuntime.jsx(table.TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(table.TableRow, { children: [
234
- /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { children: localization?.CMS_LIST_COLUMN_SLUG ?? t("cms.list.columnSlug", "Slug") }),
235
- /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { children: localization?.CMS_LIST_COLUMN_CREATED ?? t("cms.list.columnCreated", "Created") }),
236
- /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { children: localization?.CMS_LIST_COLUMN_UPDATED ?? t("cms.list.columnUpdated", "Updated") }),
237
- /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { className: "w-[100px]", children: localization?.CMS_LIST_COLUMN_ACTIONS ?? t("cms.list.columnActions", "Actions") })
238
- ] }) }),
239
- /* @__PURE__ */ jsxRuntime.jsx(table.TableBody, { children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(table.TableRow, { children: [
240
- /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { className: "font-medium", children: /* @__PURE__ */ jsxRuntime.jsx(
241
- LinkComponent,
242
- {
243
- href: context.joinBasePath(basePath, `/cms/${typeSlug}/${item.id}`),
244
- className: "hover:underline",
245
- children: item.slug
246
- }
247
- ) }),
248
- /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { children: formatDate(item.createdAt) }),
249
- /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { children: formatDate(item.updatedAt) }),
250
- /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
251
- /* @__PURE__ */ jsxRuntime.jsx(
252
- context.PermissionAccess,
253
- {
254
- permission: plugins_cms_permissions.cmsPermissions.record.update({
255
- contentType: item.contentType?.slug ?? typeSlug,
256
- recordId: item.id,
257
- ...item.authorId ? { authorId: item.authorId } : {}
258
- }),
259
- children: /* @__PURE__ */ jsxRuntime.jsx(
260
- button.Button,
234
+ return /* @__PURE__ */ jsxRuntime.jsxs(
235
+ "div",
236
+ {
237
+ className: utils.cn("border rounded-lg", classNames?.table),
238
+ "data-testid": "cms-content-table",
239
+ children: [
240
+ /* @__PURE__ */ jsxRuntime.jsxs(table.Table, { children: [
241
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(table.TableRow, { children: [
242
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { children: localization?.CMS_LIST_COLUMN_SLUG ?? t("cms.list.columnSlug", "Slug") }),
243
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { children: localization?.CMS_LIST_COLUMN_CREATED ?? t("cms.list.columnCreated", "Created") }),
244
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { children: localization?.CMS_LIST_COLUMN_UPDATED ?? t("cms.list.columnUpdated", "Updated") }),
245
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableHead, { className: "w-[100px]", children: localization?.CMS_LIST_COLUMN_ACTIONS ?? t("cms.list.columnActions", "Actions") })
246
+ ] }) }),
247
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableBody, { children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(table.TableRow, { className: classNames?.tableRow, children: [
248
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { className: "font-medium", children: /* @__PURE__ */ jsxRuntime.jsx(
249
+ LinkComponent,
250
+ {
251
+ href: context.joinBasePath(basePath, `/cms/${typeSlug}/${item.id}`),
252
+ className: "hover:underline",
253
+ children: item.slug
254
+ }
255
+ ) }),
256
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { children: formatDate(item.createdAt) }),
257
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { children: formatDate(item.updatedAt) }),
258
+ /* @__PURE__ */ jsxRuntime.jsx(table.TableCell, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
259
+ /* @__PURE__ */ jsxRuntime.jsx(
260
+ context.PermissionAccess,
261
261
  {
262
- variant: "ghost",
263
- size: "icon",
264
- onClick: () => void navigate?.(
265
- context.joinBasePath(basePath, `/cms/${typeSlug}/${item.id}`)
266
- ),
267
- children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Pencil, { className: "h-4 w-4" })
262
+ permission: plugins_cms_permissions.cmsPermissions.record.update({
263
+ contentType: item.contentType?.slug ?? typeSlug,
264
+ recordId: item.id,
265
+ ...item.authorId ? { authorId: item.authorId } : {}
266
+ }),
267
+ children: /* @__PURE__ */ jsxRuntime.jsx(
268
+ button.Button,
269
+ {
270
+ variant: "ghost",
271
+ size: "icon",
272
+ onClick: () => void navigate?.(
273
+ context.joinBasePath(basePath, `/cms/${typeSlug}/${item.id}`)
274
+ ),
275
+ children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Pencil, { className: "h-4 w-4" })
276
+ }
277
+ )
278
+ }
279
+ ),
280
+ /* @__PURE__ */ jsxRuntime.jsx(
281
+ context.PermissionAccess,
282
+ {
283
+ permission: plugins_cms_permissions.cmsPermissions.record.delete({
284
+ contentType: item.contentType?.slug ?? typeSlug,
285
+ recordId: item.id,
286
+ ...item.authorId ? { authorId: item.authorId } : {}
287
+ }),
288
+ children: /* @__PURE__ */ jsxRuntime.jsx(
289
+ button.Button,
290
+ {
291
+ variant: "ghost",
292
+ size: "icon",
293
+ onClick: () => onDelete(item.id),
294
+ disabled: isDeleting,
295
+ children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Trash2, { className: "h-4 w-4 text-destructive" })
296
+ }
297
+ )
268
298
  }
269
299
  )
270
- }
271
- ),
272
- /* @__PURE__ */ jsxRuntime.jsx(
273
- context.PermissionAccess,
274
- {
275
- permission: plugins_cms_permissions.cmsPermissions.record.delete({
276
- contentType: item.contentType?.slug ?? typeSlug,
277
- recordId: item.id,
278
- ...item.authorId ? { authorId: item.authorId } : {}
279
- }),
280
- children: /* @__PURE__ */ jsxRuntime.jsx(
300
+ ] }) })
301
+ ] }, item.id)) })
302
+ ] }),
303
+ /* @__PURE__ */ jsxRuntime.jsxs(
304
+ "div",
305
+ {
306
+ className: utils.cn(
307
+ "flex items-center justify-between px-4 py-3 border-t",
308
+ classNames?.pagination
309
+ ),
310
+ "data-testid": "cms-content-pagination",
311
+ children: [
312
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: (localization?.CMS_LIST_PAGINATION_SHOWING ?? t("cms.list.paginationShowing", "Showing {from}-{to} of {total}")).replace("{from}", "1").replace("{to}", String(items.length)).replace("{total}", String(total)) }),
313
+ hasMore && /* @__PURE__ */ jsxRuntime.jsxs(
281
314
  button.Button,
282
315
  {
283
- variant: "ghost",
284
- size: "icon",
285
- onClick: () => onDelete(item.id),
286
- disabled: isDeleting,
287
- children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Trash2, { className: "h-4 w-4 text-destructive" })
316
+ variant: "outline",
317
+ size: "sm",
318
+ onClick: () => loadMore(),
319
+ disabled: isLoadingMore,
320
+ children: [
321
+ isLoadingMore && /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Loader2, { className: "h-4 w-4 mr-2 animate-spin" }),
322
+ localization?.CMS_LIST_PAGINATION_NEXT ?? t("cms.list.paginationNext", "Next")
323
+ ]
288
324
  }
289
325
  )
290
- }
291
- )
292
- ] }) })
293
- ] }, item.id)) })
294
- ] }),
295
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-t", children: [
296
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: (localization?.CMS_LIST_PAGINATION_SHOWING ?? t("cms.list.paginationShowing", "Showing {from}-{to} of {total}")).replace("{from}", "1").replace("{to}", String(items.length)).replace("{total}", String(total)) }),
297
- hasMore && /* @__PURE__ */ jsxRuntime.jsxs(
298
- button.Button,
299
- {
300
- variant: "outline",
301
- size: "sm",
302
- onClick: () => loadMore(),
303
- disabled: isLoadingMore,
304
- children: [
305
- isLoadingMore && /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Loader2, { className: "h-4 w-4 mr-2 animate-spin" }),
306
- localization?.CMS_LIST_PAGINATION_NEXT ?? t("cms.list.paginationNext", "Next")
307
- ]
308
- }
309
- )
310
- ] })
311
- ] });
326
+ ]
327
+ }
328
+ )
329
+ ]
330
+ }
331
+ );
312
332
  }
313
333
 
314
334
  exports.ContentListPage = ContentListPage;