@haroonwaves/blog-kit-react 0.0.4 → 0.0.6

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.
package/dist/index.cjs CHANGED
@@ -43,25 +43,39 @@ var import_react_markdown = __toESM(require("react-markdown"), 1);
43
43
  var import_remark_gfm = __toESM(require("remark-gfm"), 1);
44
44
  var import_rehype_prism_plus = __toESM(require("rehype-prism-plus"), 1);
45
45
  var import_rehype_raw = __toESM(require("rehype-raw"), 1);
46
+
47
+ // src/components/Badge.tsx
46
48
  var import_jsx_runtime = require("react/jsx-runtime");
47
- function BlogRenderer({ content, className = "", components }) {
49
+ function Badge({ children, className }) {
50
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
51
+ "span",
52
+ {
53
+ className: `inline-flex items-center rounded-full border border-transparent bg-orange-100 px-2.5 py-0.5 text-xs font-semibold text-orange-500 ${className}`,
54
+ children
55
+ }
56
+ );
57
+ }
58
+
59
+ // src/components/MarkdownRenderer.tsx
60
+ var import_jsx_runtime2 = require("react/jsx-runtime");
61
+ function BlogRenderer({ content, metadata, className = "", components }) {
48
62
  const defaultComponents = {
49
- h1: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", { className: "text-4xl font-bold mb-4 mt-8 text-gray-800", ...props }),
50
- h2: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-3xl font-bold mb-3 mt-6 text-gray-800", ...props }),
51
- h3: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "text-2xl font-semibold mb-2 mt-4 text-gray-800", ...props }),
52
- h4: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h4", { className: "text-xl font-semibold mb-2 mt-4 text-gray-800", ...props }),
53
- h5: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h5", { className: "text-lg font-semibold mb-2 mt-3 text-gray-800", ...props }),
54
- h6: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h6", { className: "text-base font-semibold mb-2 mt-3 text-gray-800", ...props }),
55
- p: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mb-4 leading-7 text-gray-600", ...props }),
56
- ul: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { className: "mb-4 ml-6 list-disc text-gray-600", ...props }),
57
- ol: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "mb-4 ml-6 list-decimal text-gray-600", ...props }),
58
- li: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { className: "mb-2", ...props }),
63
+ h1: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h1", { className: "text-4xl font-bold mb-4 mt-8 text-gray-800", ...props }),
64
+ h2: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { className: "text-3xl font-bold mb-3 mt-6 text-gray-800", ...props }),
65
+ h3: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { className: "text-2xl font-semibold mb-2 mt-4 text-gray-800", ...props }),
66
+ h4: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h4", { className: "text-xl font-semibold mb-2 mt-4 text-gray-800", ...props }),
67
+ h5: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h5", { className: "text-lg font-semibold mb-2 mt-3 text-gray-800", ...props }),
68
+ h6: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h6", { className: "text-base font-semibold mb-2 mt-3 text-gray-800", ...props }),
69
+ p: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "mb-4 leading-7 text-gray-600", ...props }),
70
+ ul: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ul", { className: "mb-4 ml-6 list-disc text-gray-600", ...props }),
71
+ ol: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ol", { className: "mb-4 ml-6 list-decimal text-gray-600", ...props }),
72
+ li: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("li", { className: "mb-2", ...props }),
59
73
  code: ({ className: codeClassName, children, ...props }) => {
60
74
  const isInline = !codeClassName;
61
- return isInline ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { className: "px-1.5 py-0.5 bg-gray-100 rounded text-sm text-red-600", ...props, children }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { className: codeClassName, ...props, children });
75
+ return isInline ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("code", { className: "px-1.5 py-0.5 bg-gray-100 rounded text-sm text-red-600", ...props, children }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("code", { className: codeClassName, ...props, children });
62
76
  },
63
77
  pre: ({ className: preClassName, children, ...props }) => {
64
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
78
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
65
79
  "pre",
66
80
  {
67
81
  className: `mb-4 rounded-lg overflow-x-auto [&>code]:block [&>code]:p-4 ${preClassName || ""}`,
@@ -70,44 +84,58 @@ function BlogRenderer({ content, className = "", components }) {
70
84
  }
71
85
  );
72
86
  },
73
- blockquote: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
87
+ blockquote: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
74
88
  "blockquote",
75
89
  {
76
90
  className: "border-l-4 border-blue-500 pl-4 italic my-4 text-gray-600",
77
91
  ...props
78
92
  }
79
93
  ),
80
- a: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { className: "text-blue-600 hover:text-blue-800 underline", ...props }),
81
- strong: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { className: "font-semibold text-gray-800", ...props }),
82
- em: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("em", { className: "italic", ...props }),
83
- del: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("del", { className: "line-through text-gray-500", ...props }),
84
- hr: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { className: "my-8 border-gray-300", ...props }),
85
- br: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", { ...props }),
86
- img: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { className: "max-w-full h-auto rounded-lg my-4", ...props }),
87
- table: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "overflow-x-auto my-4", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("table", { className: "min-w-full border border-gray-300 rounded", ...props }) }),
88
- thead: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { className: "bg-gray-50", ...props }),
89
- tbody: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { ...props }),
90
- tr: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tr", { className: "border-b border-gray-300", ...props }),
91
- th: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "px-4 py-2 text-left font-semibold border border-gray-300", ...props }),
92
- td: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "px-4 py-2 border border-gray-300", ...props }),
93
- input: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { className: "mr-2", type: "checkbox", disabled: true, ...props })
94
+ a: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { className: "text-blue-600 hover:text-blue-800 underline", ...props }),
95
+ strong: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { className: "font-semibold text-gray-800", ...props }),
96
+ em: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("em", { className: "italic", ...props }),
97
+ del: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("del", { className: "line-through text-gray-500", ...props }),
98
+ hr: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("hr", { className: "my-8 border-gray-300", ...props }),
99
+ br: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("br", { ...props }),
100
+ img: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("img", { className: "max-w-full h-auto rounded-lg my-4", ...props }),
101
+ table: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "overflow-x-auto my-4", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("table", { className: "min-w-full border border-gray-300 rounded", ...props }) }),
102
+ thead: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("thead", { className: "bg-gray-50", ...props }),
103
+ tbody: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tbody", { ...props }),
104
+ tr: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tr", { className: "border-b border-gray-300", ...props }),
105
+ th: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("th", { className: "px-4 py-2 text-left font-semibold border border-gray-300", ...props }),
106
+ td: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { className: "px-4 py-2 border border-gray-300", ...props }),
107
+ input: ({ ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("input", { className: "mr-2", type: "checkbox", disabled: true, ...props })
94
108
  };
95
109
  const mergedComponents = { ...defaultComponents, ...components };
96
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `prose prose-slate max-w-none ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
97
- import_react_markdown.default,
98
- {
99
- remarkPlugins: [import_remark_gfm.default],
100
- rehypePlugins: [import_rehype_raw.default, import_rehype_prism_plus.default],
101
- components: mergedComponents,
102
- children: content
103
- }
104
- ) });
110
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
111
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center gap-3 mb-4", children: [
112
+ metadata.category && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Badge, { children: metadata.category }),
113
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center gap-2 text-sm text-gray-500", children: [
114
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: metadata.readingTime }),
115
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u2022" }),
116
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("time", { dateTime: metadata.date, children: new Date(metadata.date).toLocaleDateString("en-US", {
117
+ year: "numeric",
118
+ month: "long",
119
+ day: "numeric"
120
+ }) })
121
+ ] })
122
+ ] }),
123
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: `prose prose-slate max-w-none ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
124
+ import_react_markdown.default,
125
+ {
126
+ remarkPlugins: [import_remark_gfm.default],
127
+ rehypePlugins: [import_rehype_raw.default, import_rehype_prism_plus.default],
128
+ components: mergedComponents,
129
+ children: content
130
+ }
131
+ ) })
132
+ ] });
105
133
  }
106
134
 
107
135
  // src/components/BlogCard.tsx
108
- var import_jsx_runtime2 = require("react/jsx-runtime");
136
+ var import_jsx_runtime3 = require("react/jsx-runtime");
109
137
  function BlogCard({
110
- blog,
138
+ metadata,
111
139
  basePath = "/blog",
112
140
  renderLink,
113
141
  className = "",
@@ -115,20 +143,20 @@ function BlogCard({
115
143
  showReadingTime = true,
116
144
  showDate = true
117
145
  }) {
118
- const href = `${basePath}/${blog.slug}`;
119
- const defaultLink = (href2, children) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { href: href2, children });
146
+ const href = `${basePath}/${metadata.slug}`;
147
+ const defaultLink = (href2, children) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("a", { href: href2, children });
120
148
  const Link = renderLink || defaultLink;
121
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
149
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
122
150
  "article",
123
151
  {
124
152
  className: `bg-white rounded-lg border border-gray-200 hover:border-gray-300 p-6 transition-colors ${className}`,
125
153
  children: [
126
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "flex items-center justify-between mb-3", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center gap-3", children: [
127
- showCategory && blog.category && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "inline-flex items-center rounded-full border border-transparent bg-orange-100 px-2.5 py-0.5 text-xs font-semibold text-orange-500", children: blog.category }),
128
- (showReadingTime || showDate) && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center gap-2 text-sm text-gray-500", children: [
129
- showReadingTime && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: blog.readingTime }),
130
- showReadingTime && showDate && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "\u2022" }),
131
- showDate && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("time", { dateTime: blog.date, children: new Date(blog.date).toLocaleDateString("en-US", {
154
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "flex items-center justify-between mb-3", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-3", children: [
155
+ showCategory && metadata.category && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Badge, { children: metadata.category }),
156
+ (showReadingTime || showDate) && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-2 text-sm text-gray-500", children: [
157
+ showReadingTime && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: metadata.readingTime }),
158
+ showReadingTime && showDate && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "\u2022" }),
159
+ showDate && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("time", { dateTime: metadata.date, children: new Date(metadata.date).toLocaleDateString("en-US", {
132
160
  year: "numeric",
133
161
  month: "long",
134
162
  day: "numeric"
@@ -137,12 +165,12 @@ function BlogCard({
137
165
  ] }) }),
138
166
  Link(
139
167
  href,
140
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { className: "font-semibold text-xl text-gray-700 mb-2 hover:underline transition-colors", children: blog.title })
168
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "font-semibold text-xl text-gray-700 mb-2 hover:underline transition-colors", children: metadata.title })
141
169
  ),
142
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-sm text-gray-500 leading-6 mb-4", children: blog.description }),
170
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-sm text-gray-500 leading-6 mb-4", children: metadata.description }),
143
171
  Link(
144
172
  href,
145
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "inline-flex items-center text-blue-600 hover:text-blue-700 font-medium text-sm", children: "Read more \u2192" })
173
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "inline-flex items-center text-blue-600 hover:text-blue-700 font-medium text-sm", children: "Read more \u2192" })
146
174
  )
147
175
  ]
148
176
  }
@@ -150,37 +178,37 @@ function BlogCard({
150
178
  }
151
179
 
152
180
  // src/components/BlogList.tsx
153
- var import_jsx_runtime3 = require("react/jsx-runtime");
181
+ var import_jsx_runtime4 = require("react/jsx-runtime");
154
182
  function BlogList({
155
- blogs,
183
+ metadata,
156
184
  basePath = "/blog",
157
185
  renderLink,
158
186
  className = "",
159
187
  emptyMessage = "No blog posts found.",
160
188
  cardProps
161
189
  }) {
162
- if (blogs.length === 0) {
163
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: `text-center text-gray-500 py-12 ${className}`, children: emptyMessage });
190
+ if (metadata.length === 0) {
191
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: `text-center text-gray-500 py-12 ${className}`, children: emptyMessage });
164
192
  }
165
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: `space-y-6 ${className}`, children: blogs.map((blog) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
193
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: `space-y-6 ${className}`, children: metadata.map((meta) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
166
194
  BlogCard,
167
195
  {
168
- blog,
196
+ metadata: meta,
169
197
  basePath,
170
198
  renderLink,
171
199
  ...cardProps
172
200
  },
173
- blog.slug
201
+ meta.slug
174
202
  )) });
175
203
  }
176
204
 
177
205
  // src/components/BlogPlaceholder.tsx
178
- var import_jsx_runtime4 = require("react/jsx-runtime");
206
+ var import_jsx_runtime5 = require("react/jsx-runtime");
179
207
  function BlogPlaceholder({ count = 3, className = "" }) {
180
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: `space-y-6 ${className}`, children: Array.from({ length: count }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "bg-white rounded-lg border border-gray-200 p-6 animate-pulse", children: [
181
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "h-4 bg-gray-200 rounded mb-3" }),
182
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "h-6 bg-gray-200 rounded mb-2" }),
183
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "h-4 bg-gray-200 rounded w-3/4" })
208
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: `space-y-6 ${className}`, children: Array.from({ length: count }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "bg-white rounded-lg border border-gray-200 p-6 animate-pulse", children: [
209
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "h-4 bg-gray-200 rounded mb-3" }),
210
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "h-6 bg-gray-200 rounded mb-2" }),
211
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "h-4 bg-gray-200 rounded w-3/4" })
184
212
  ] }, i)) });
185
213
  }
186
214
 
package/dist/index.d.cts CHANGED
@@ -13,7 +13,6 @@ interface BlogMeta {
13
13
  interface Blog {
14
14
  metadata: BlogMeta;
15
15
  content: string;
16
- readingTime: string;
17
16
  }
18
17
  interface BlogConfig {
19
18
  contentDirectory: string;
@@ -22,13 +21,14 @@ interface BlogConfig {
22
21
 
23
22
  interface BlogRendererProps {
24
23
  content: string;
24
+ metadata: BlogMeta;
25
25
  className?: string;
26
26
  components?: Record<string, react__default.ComponentType<any>>;
27
27
  }
28
- declare function BlogRenderer({ content, className, components }: BlogRendererProps): react_jsx_runtime.JSX.Element;
28
+ declare function BlogRenderer({ content, metadata, className, components }: BlogRendererProps): react_jsx_runtime.JSX.Element;
29
29
 
30
30
  interface BlogCardProps {
31
- blog: BlogMeta;
31
+ metadata: BlogMeta;
32
32
  basePath?: string;
33
33
  renderLink?: (href: string, children: react__default.ReactNode) => react__default.ReactNode;
34
34
  className?: string;
@@ -36,17 +36,17 @@ interface BlogCardProps {
36
36
  showReadingTime?: boolean;
37
37
  showDate?: boolean;
38
38
  }
39
- declare function BlogCard({ blog, basePath, renderLink, className, showCategory, showReadingTime, showDate, }: BlogCardProps): react_jsx_runtime.JSX.Element;
39
+ declare function BlogCard({ metadata, basePath, renderLink, className, showCategory, showReadingTime, showDate, }: BlogCardProps): react_jsx_runtime.JSX.Element;
40
40
 
41
41
  interface BlogListProps {
42
- blogs: BlogMeta[];
42
+ metadata: BlogMeta[];
43
43
  basePath?: string;
44
44
  renderLink?: BlogCardProps['renderLink'];
45
45
  className?: string;
46
46
  emptyMessage?: string;
47
47
  cardProps?: Omit<BlogCardProps, 'blog' | 'basePath' | 'renderLink'>;
48
48
  }
49
- declare function BlogList({ blogs, basePath, renderLink, className, emptyMessage, cardProps, }: BlogListProps): react_jsx_runtime.JSX.Element;
49
+ declare function BlogList({ metadata, basePath, renderLink, className, emptyMessage, cardProps, }: BlogListProps): react_jsx_runtime.JSX.Element;
50
50
 
51
51
  interface BlogPlaceholderProps {
52
52
  count?: number;
package/dist/index.d.ts CHANGED
@@ -13,7 +13,6 @@ interface BlogMeta {
13
13
  interface Blog {
14
14
  metadata: BlogMeta;
15
15
  content: string;
16
- readingTime: string;
17
16
  }
18
17
  interface BlogConfig {
19
18
  contentDirectory: string;
@@ -22,13 +21,14 @@ interface BlogConfig {
22
21
 
23
22
  interface BlogRendererProps {
24
23
  content: string;
24
+ metadata: BlogMeta;
25
25
  className?: string;
26
26
  components?: Record<string, react__default.ComponentType<any>>;
27
27
  }
28
- declare function BlogRenderer({ content, className, components }: BlogRendererProps): react_jsx_runtime.JSX.Element;
28
+ declare function BlogRenderer({ content, metadata, className, components }: BlogRendererProps): react_jsx_runtime.JSX.Element;
29
29
 
30
30
  interface BlogCardProps {
31
- blog: BlogMeta;
31
+ metadata: BlogMeta;
32
32
  basePath?: string;
33
33
  renderLink?: (href: string, children: react__default.ReactNode) => react__default.ReactNode;
34
34
  className?: string;
@@ -36,17 +36,17 @@ interface BlogCardProps {
36
36
  showReadingTime?: boolean;
37
37
  showDate?: boolean;
38
38
  }
39
- declare function BlogCard({ blog, basePath, renderLink, className, showCategory, showReadingTime, showDate, }: BlogCardProps): react_jsx_runtime.JSX.Element;
39
+ declare function BlogCard({ metadata, basePath, renderLink, className, showCategory, showReadingTime, showDate, }: BlogCardProps): react_jsx_runtime.JSX.Element;
40
40
 
41
41
  interface BlogListProps {
42
- blogs: BlogMeta[];
42
+ metadata: BlogMeta[];
43
43
  basePath?: string;
44
44
  renderLink?: BlogCardProps['renderLink'];
45
45
  className?: string;
46
46
  emptyMessage?: string;
47
47
  cardProps?: Omit<BlogCardProps, 'blog' | 'basePath' | 'renderLink'>;
48
48
  }
49
- declare function BlogList({ blogs, basePath, renderLink, className, emptyMessage, cardProps, }: BlogListProps): react_jsx_runtime.JSX.Element;
49
+ declare function BlogList({ metadata, basePath, renderLink, className, emptyMessage, cardProps, }: BlogListProps): react_jsx_runtime.JSX.Element;
50
50
 
51
51
  interface BlogPlaceholderProps {
52
52
  count?: number;
package/dist/index.js CHANGED
@@ -3,25 +3,39 @@ import ReactMarkdown from "react-markdown";
3
3
  import remarkGfm from "remark-gfm";
4
4
  import rehypePrismPlus from "rehype-prism-plus";
5
5
  import rehypeRaw from "rehype-raw";
6
+
7
+ // src/components/Badge.tsx
6
8
  import { jsx } from "react/jsx-runtime";
7
- function BlogRenderer({ content, className = "", components }) {
9
+ function Badge({ children, className }) {
10
+ return /* @__PURE__ */ jsx(
11
+ "span",
12
+ {
13
+ className: `inline-flex items-center rounded-full border border-transparent bg-orange-100 px-2.5 py-0.5 text-xs font-semibold text-orange-500 ${className}`,
14
+ children
15
+ }
16
+ );
17
+ }
18
+
19
+ // src/components/MarkdownRenderer.tsx
20
+ import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
21
+ function BlogRenderer({ content, metadata, className = "", components }) {
8
22
  const defaultComponents = {
9
- h1: ({ ...props }) => /* @__PURE__ */ jsx("h1", { className: "text-4xl font-bold mb-4 mt-8 text-gray-800", ...props }),
10
- h2: ({ ...props }) => /* @__PURE__ */ jsx("h2", { className: "text-3xl font-bold mb-3 mt-6 text-gray-800", ...props }),
11
- h3: ({ ...props }) => /* @__PURE__ */ jsx("h3", { className: "text-2xl font-semibold mb-2 mt-4 text-gray-800", ...props }),
12
- h4: ({ ...props }) => /* @__PURE__ */ jsx("h4", { className: "text-xl font-semibold mb-2 mt-4 text-gray-800", ...props }),
13
- h5: ({ ...props }) => /* @__PURE__ */ jsx("h5", { className: "text-lg font-semibold mb-2 mt-3 text-gray-800", ...props }),
14
- h6: ({ ...props }) => /* @__PURE__ */ jsx("h6", { className: "text-base font-semibold mb-2 mt-3 text-gray-800", ...props }),
15
- p: ({ ...props }) => /* @__PURE__ */ jsx("p", { className: "mb-4 leading-7 text-gray-600", ...props }),
16
- ul: ({ ...props }) => /* @__PURE__ */ jsx("ul", { className: "mb-4 ml-6 list-disc text-gray-600", ...props }),
17
- ol: ({ ...props }) => /* @__PURE__ */ jsx("ol", { className: "mb-4 ml-6 list-decimal text-gray-600", ...props }),
18
- li: ({ ...props }) => /* @__PURE__ */ jsx("li", { className: "mb-2", ...props }),
23
+ h1: ({ ...props }) => /* @__PURE__ */ jsx2("h1", { className: "text-4xl font-bold mb-4 mt-8 text-gray-800", ...props }),
24
+ h2: ({ ...props }) => /* @__PURE__ */ jsx2("h2", { className: "text-3xl font-bold mb-3 mt-6 text-gray-800", ...props }),
25
+ h3: ({ ...props }) => /* @__PURE__ */ jsx2("h3", { className: "text-2xl font-semibold mb-2 mt-4 text-gray-800", ...props }),
26
+ h4: ({ ...props }) => /* @__PURE__ */ jsx2("h4", { className: "text-xl font-semibold mb-2 mt-4 text-gray-800", ...props }),
27
+ h5: ({ ...props }) => /* @__PURE__ */ jsx2("h5", { className: "text-lg font-semibold mb-2 mt-3 text-gray-800", ...props }),
28
+ h6: ({ ...props }) => /* @__PURE__ */ jsx2("h6", { className: "text-base font-semibold mb-2 mt-3 text-gray-800", ...props }),
29
+ p: ({ ...props }) => /* @__PURE__ */ jsx2("p", { className: "mb-4 leading-7 text-gray-600", ...props }),
30
+ ul: ({ ...props }) => /* @__PURE__ */ jsx2("ul", { className: "mb-4 ml-6 list-disc text-gray-600", ...props }),
31
+ ol: ({ ...props }) => /* @__PURE__ */ jsx2("ol", { className: "mb-4 ml-6 list-decimal text-gray-600", ...props }),
32
+ li: ({ ...props }) => /* @__PURE__ */ jsx2("li", { className: "mb-2", ...props }),
19
33
  code: ({ className: codeClassName, children, ...props }) => {
20
34
  const isInline = !codeClassName;
21
- return isInline ? /* @__PURE__ */ jsx("code", { className: "px-1.5 py-0.5 bg-gray-100 rounded text-sm text-red-600", ...props, children }) : /* @__PURE__ */ jsx("code", { className: codeClassName, ...props, children });
35
+ return isInline ? /* @__PURE__ */ jsx2("code", { className: "px-1.5 py-0.5 bg-gray-100 rounded text-sm text-red-600", ...props, children }) : /* @__PURE__ */ jsx2("code", { className: codeClassName, ...props, children });
22
36
  },
23
37
  pre: ({ className: preClassName, children, ...props }) => {
24
- return /* @__PURE__ */ jsx(
38
+ return /* @__PURE__ */ jsx2(
25
39
  "pre",
26
40
  {
27
41
  className: `mb-4 rounded-lg overflow-x-auto [&>code]:block [&>code]:p-4 ${preClassName || ""}`,
@@ -30,44 +44,58 @@ function BlogRenderer({ content, className = "", components }) {
30
44
  }
31
45
  );
32
46
  },
33
- blockquote: ({ ...props }) => /* @__PURE__ */ jsx(
47
+ blockquote: ({ ...props }) => /* @__PURE__ */ jsx2(
34
48
  "blockquote",
35
49
  {
36
50
  className: "border-l-4 border-blue-500 pl-4 italic my-4 text-gray-600",
37
51
  ...props
38
52
  }
39
53
  ),
40
- a: ({ ...props }) => /* @__PURE__ */ jsx("a", { className: "text-blue-600 hover:text-blue-800 underline", ...props }),
41
- strong: ({ ...props }) => /* @__PURE__ */ jsx("strong", { className: "font-semibold text-gray-800", ...props }),
42
- em: ({ ...props }) => /* @__PURE__ */ jsx("em", { className: "italic", ...props }),
43
- del: ({ ...props }) => /* @__PURE__ */ jsx("del", { className: "line-through text-gray-500", ...props }),
44
- hr: ({ ...props }) => /* @__PURE__ */ jsx("hr", { className: "my-8 border-gray-300", ...props }),
45
- br: ({ ...props }) => /* @__PURE__ */ jsx("br", { ...props }),
46
- img: ({ ...props }) => /* @__PURE__ */ jsx("img", { className: "max-w-full h-auto rounded-lg my-4", ...props }),
47
- table: ({ ...props }) => /* @__PURE__ */ jsx("div", { className: "overflow-x-auto my-4", children: /* @__PURE__ */ jsx("table", { className: "min-w-full border border-gray-300 rounded", ...props }) }),
48
- thead: ({ ...props }) => /* @__PURE__ */ jsx("thead", { className: "bg-gray-50", ...props }),
49
- tbody: ({ ...props }) => /* @__PURE__ */ jsx("tbody", { ...props }),
50
- tr: ({ ...props }) => /* @__PURE__ */ jsx("tr", { className: "border-b border-gray-300", ...props }),
51
- th: ({ ...props }) => /* @__PURE__ */ jsx("th", { className: "px-4 py-2 text-left font-semibold border border-gray-300", ...props }),
52
- td: ({ ...props }) => /* @__PURE__ */ jsx("td", { className: "px-4 py-2 border border-gray-300", ...props }),
53
- input: ({ ...props }) => /* @__PURE__ */ jsx("input", { className: "mr-2", type: "checkbox", disabled: true, ...props })
54
+ a: ({ ...props }) => /* @__PURE__ */ jsx2("a", { className: "text-blue-600 hover:text-blue-800 underline", ...props }),
55
+ strong: ({ ...props }) => /* @__PURE__ */ jsx2("strong", { className: "font-semibold text-gray-800", ...props }),
56
+ em: ({ ...props }) => /* @__PURE__ */ jsx2("em", { className: "italic", ...props }),
57
+ del: ({ ...props }) => /* @__PURE__ */ jsx2("del", { className: "line-through text-gray-500", ...props }),
58
+ hr: ({ ...props }) => /* @__PURE__ */ jsx2("hr", { className: "my-8 border-gray-300", ...props }),
59
+ br: ({ ...props }) => /* @__PURE__ */ jsx2("br", { ...props }),
60
+ img: ({ ...props }) => /* @__PURE__ */ jsx2("img", { className: "max-w-full h-auto rounded-lg my-4", ...props }),
61
+ table: ({ ...props }) => /* @__PURE__ */ jsx2("div", { className: "overflow-x-auto my-4", children: /* @__PURE__ */ jsx2("table", { className: "min-w-full border border-gray-300 rounded", ...props }) }),
62
+ thead: ({ ...props }) => /* @__PURE__ */ jsx2("thead", { className: "bg-gray-50", ...props }),
63
+ tbody: ({ ...props }) => /* @__PURE__ */ jsx2("tbody", { ...props }),
64
+ tr: ({ ...props }) => /* @__PURE__ */ jsx2("tr", { className: "border-b border-gray-300", ...props }),
65
+ th: ({ ...props }) => /* @__PURE__ */ jsx2("th", { className: "px-4 py-2 text-left font-semibold border border-gray-300", ...props }),
66
+ td: ({ ...props }) => /* @__PURE__ */ jsx2("td", { className: "px-4 py-2 border border-gray-300", ...props }),
67
+ input: ({ ...props }) => /* @__PURE__ */ jsx2("input", { className: "mr-2", type: "checkbox", disabled: true, ...props })
54
68
  };
55
69
  const mergedComponents = { ...defaultComponents, ...components };
56
- return /* @__PURE__ */ jsx("div", { className: `prose prose-slate max-w-none ${className}`, children: /* @__PURE__ */ jsx(
57
- ReactMarkdown,
58
- {
59
- remarkPlugins: [remarkGfm],
60
- rehypePlugins: [rehypeRaw, rehypePrismPlus],
61
- components: mergedComponents,
62
- children: content
63
- }
64
- ) });
70
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
71
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 mb-4", children: [
72
+ metadata.category && /* @__PURE__ */ jsx2(Badge, { children: metadata.category }),
73
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-gray-500", children: [
74
+ /* @__PURE__ */ jsx2("span", { children: metadata.readingTime }),
75
+ /* @__PURE__ */ jsx2("span", { children: "\u2022" }),
76
+ /* @__PURE__ */ jsx2("time", { dateTime: metadata.date, children: new Date(metadata.date).toLocaleDateString("en-US", {
77
+ year: "numeric",
78
+ month: "long",
79
+ day: "numeric"
80
+ }) })
81
+ ] })
82
+ ] }),
83
+ /* @__PURE__ */ jsx2("div", { className: `prose prose-slate max-w-none ${className}`, children: /* @__PURE__ */ jsx2(
84
+ ReactMarkdown,
85
+ {
86
+ remarkPlugins: [remarkGfm],
87
+ rehypePlugins: [rehypeRaw, rehypePrismPlus],
88
+ components: mergedComponents,
89
+ children: content
90
+ }
91
+ ) })
92
+ ] });
65
93
  }
66
94
 
67
95
  // src/components/BlogCard.tsx
68
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
96
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
69
97
  function BlogCard({
70
- blog,
98
+ metadata,
71
99
  basePath = "/blog",
72
100
  renderLink,
73
101
  className = "",
@@ -75,20 +103,20 @@ function BlogCard({
75
103
  showReadingTime = true,
76
104
  showDate = true
77
105
  }) {
78
- const href = `${basePath}/${blog.slug}`;
79
- const defaultLink = (href2, children) => /* @__PURE__ */ jsx2("a", { href: href2, children });
106
+ const href = `${basePath}/${metadata.slug}`;
107
+ const defaultLink = (href2, children) => /* @__PURE__ */ jsx3("a", { href: href2, children });
80
108
  const Link = renderLink || defaultLink;
81
- return /* @__PURE__ */ jsxs(
109
+ return /* @__PURE__ */ jsxs2(
82
110
  "article",
83
111
  {
84
112
  className: `bg-white rounded-lg border border-gray-200 hover:border-gray-300 p-6 transition-colors ${className}`,
85
113
  children: [
86
- /* @__PURE__ */ jsx2("div", { className: "flex items-center justify-between mb-3", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
87
- showCategory && blog.category && /* @__PURE__ */ jsx2("span", { className: "inline-flex items-center rounded-full border border-transparent bg-orange-100 px-2.5 py-0.5 text-xs font-semibold text-orange-500", children: blog.category }),
88
- (showReadingTime || showDate) && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-gray-500", children: [
89
- showReadingTime && /* @__PURE__ */ jsx2("span", { children: blog.readingTime }),
90
- showReadingTime && showDate && /* @__PURE__ */ jsx2("span", { children: "\u2022" }),
91
- showDate && /* @__PURE__ */ jsx2("time", { dateTime: blog.date, children: new Date(blog.date).toLocaleDateString("en-US", {
114
+ /* @__PURE__ */ jsx3("div", { className: "flex items-center justify-between mb-3", children: /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-3", children: [
115
+ showCategory && metadata.category && /* @__PURE__ */ jsx3(Badge, { children: metadata.category }),
116
+ (showReadingTime || showDate) && /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 text-sm text-gray-500", children: [
117
+ showReadingTime && /* @__PURE__ */ jsx3("span", { children: metadata.readingTime }),
118
+ showReadingTime && showDate && /* @__PURE__ */ jsx3("span", { children: "\u2022" }),
119
+ showDate && /* @__PURE__ */ jsx3("time", { dateTime: metadata.date, children: new Date(metadata.date).toLocaleDateString("en-US", {
92
120
  year: "numeric",
93
121
  month: "long",
94
122
  day: "numeric"
@@ -97,12 +125,12 @@ function BlogCard({
97
125
  ] }) }),
98
126
  Link(
99
127
  href,
100
- /* @__PURE__ */ jsx2("h2", { className: "font-semibold text-xl text-gray-700 mb-2 hover:underline transition-colors", children: blog.title })
128
+ /* @__PURE__ */ jsx3("h2", { className: "font-semibold text-xl text-gray-700 mb-2 hover:underline transition-colors", children: metadata.title })
101
129
  ),
102
- /* @__PURE__ */ jsx2("p", { className: "text-sm text-gray-500 leading-6 mb-4", children: blog.description }),
130
+ /* @__PURE__ */ jsx3("p", { className: "text-sm text-gray-500 leading-6 mb-4", children: metadata.description }),
103
131
  Link(
104
132
  href,
105
- /* @__PURE__ */ jsx2("span", { className: "inline-flex items-center text-blue-600 hover:text-blue-700 font-medium text-sm", children: "Read more \u2192" })
133
+ /* @__PURE__ */ jsx3("span", { className: "inline-flex items-center text-blue-600 hover:text-blue-700 font-medium text-sm", children: "Read more \u2192" })
106
134
  )
107
135
  ]
108
136
  }
@@ -110,37 +138,37 @@ function BlogCard({
110
138
  }
111
139
 
112
140
  // src/components/BlogList.tsx
113
- import { jsx as jsx3 } from "react/jsx-runtime";
141
+ import { jsx as jsx4 } from "react/jsx-runtime";
114
142
  function BlogList({
115
- blogs,
143
+ metadata,
116
144
  basePath = "/blog",
117
145
  renderLink,
118
146
  className = "",
119
147
  emptyMessage = "No blog posts found.",
120
148
  cardProps
121
149
  }) {
122
- if (blogs.length === 0) {
123
- return /* @__PURE__ */ jsx3("div", { className: `text-center text-gray-500 py-12 ${className}`, children: emptyMessage });
150
+ if (metadata.length === 0) {
151
+ return /* @__PURE__ */ jsx4("div", { className: `text-center text-gray-500 py-12 ${className}`, children: emptyMessage });
124
152
  }
125
- return /* @__PURE__ */ jsx3("div", { className: `space-y-6 ${className}`, children: blogs.map((blog) => /* @__PURE__ */ jsx3(
153
+ return /* @__PURE__ */ jsx4("div", { className: `space-y-6 ${className}`, children: metadata.map((meta) => /* @__PURE__ */ jsx4(
126
154
  BlogCard,
127
155
  {
128
- blog,
156
+ metadata: meta,
129
157
  basePath,
130
158
  renderLink,
131
159
  ...cardProps
132
160
  },
133
- blog.slug
161
+ meta.slug
134
162
  )) });
135
163
  }
136
164
 
137
165
  // src/components/BlogPlaceholder.tsx
138
- import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
166
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
139
167
  function BlogPlaceholder({ count = 3, className = "" }) {
140
- return /* @__PURE__ */ jsx4("div", { className: `space-y-6 ${className}`, children: Array.from({ length: count }).map((_, i) => /* @__PURE__ */ jsxs2("div", { className: "bg-white rounded-lg border border-gray-200 p-6 animate-pulse", children: [
141
- /* @__PURE__ */ jsx4("div", { className: "h-4 bg-gray-200 rounded mb-3" }),
142
- /* @__PURE__ */ jsx4("div", { className: "h-6 bg-gray-200 rounded mb-2" }),
143
- /* @__PURE__ */ jsx4("div", { className: "h-4 bg-gray-200 rounded w-3/4" })
168
+ return /* @__PURE__ */ jsx5("div", { className: `space-y-6 ${className}`, children: Array.from({ length: count }).map((_, i) => /* @__PURE__ */ jsxs3("div", { className: "bg-white rounded-lg border border-gray-200 p-6 animate-pulse", children: [
169
+ /* @__PURE__ */ jsx5("div", { className: "h-4 bg-gray-200 rounded mb-3" }),
170
+ /* @__PURE__ */ jsx5("div", { className: "h-6 bg-gray-200 rounded mb-2" }),
171
+ /* @__PURE__ */ jsx5("div", { className: "h-4 bg-gray-200 rounded w-3/4" })
144
172
  ] }, i)) });
145
173
  }
146
174
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haroonwaves/blog-kit-react",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",