@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 +91 -63
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +91 -63
- package/package.json +1 -1
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
|
|
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,
|
|
50
|
-
h2: ({ ...props }) => /* @__PURE__ */ (0,
|
|
51
|
-
h3: ({ ...props }) => /* @__PURE__ */ (0,
|
|
52
|
-
h4: ({ ...props }) => /* @__PURE__ */ (0,
|
|
53
|
-
h5: ({ ...props }) => /* @__PURE__ */ (0,
|
|
54
|
-
h6: ({ ...props }) => /* @__PURE__ */ (0,
|
|
55
|
-
p: ({ ...props }) => /* @__PURE__ */ (0,
|
|
56
|
-
ul: ({ ...props }) => /* @__PURE__ */ (0,
|
|
57
|
-
ol: ({ ...props }) => /* @__PURE__ */ (0,
|
|
58
|
-
li: ({ ...props }) => /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
81
|
-
strong: ({ ...props }) => /* @__PURE__ */ (0,
|
|
82
|
-
em: ({ ...props }) => /* @__PURE__ */ (0,
|
|
83
|
-
del: ({ ...props }) => /* @__PURE__ */ (0,
|
|
84
|
-
hr: ({ ...props }) => /* @__PURE__ */ (0,
|
|
85
|
-
br: ({ ...props }) => /* @__PURE__ */ (0,
|
|
86
|
-
img: ({ ...props }) => /* @__PURE__ */ (0,
|
|
87
|
-
table: ({ ...props }) => /* @__PURE__ */ (0,
|
|
88
|
-
thead: ({ ...props }) => /* @__PURE__ */ (0,
|
|
89
|
-
tbody: ({ ...props }) => /* @__PURE__ */ (0,
|
|
90
|
-
tr: ({ ...props }) => /* @__PURE__ */ (0,
|
|
91
|
-
th: ({ ...props }) => /* @__PURE__ */ (0,
|
|
92
|
-
td: ({ ...props }) => /* @__PURE__ */ (0,
|
|
93
|
-
input: ({ ...props }) => /* @__PURE__ */ (0,
|
|
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,
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
|
136
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
109
137
|
function BlogCard({
|
|
110
|
-
|
|
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}/${
|
|
119
|
-
const defaultLink = (href2, children) => /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
127
|
-
showCategory &&
|
|
128
|
-
(showReadingTime || showDate) && /* @__PURE__ */ (0,
|
|
129
|
-
showReadingTime && /* @__PURE__ */ (0,
|
|
130
|
-
showReadingTime && showDate && /* @__PURE__ */ (0,
|
|
131
|
-
showDate && /* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
181
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
154
182
|
function BlogList({
|
|
155
|
-
|
|
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 (
|
|
163
|
-
return /* @__PURE__ */ (0,
|
|
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,
|
|
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
|
-
|
|
196
|
+
metadata: meta,
|
|
169
197
|
basePath,
|
|
170
198
|
renderLink,
|
|
171
199
|
...cardProps
|
|
172
200
|
},
|
|
173
|
-
|
|
201
|
+
meta.slug
|
|
174
202
|
)) });
|
|
175
203
|
}
|
|
176
204
|
|
|
177
205
|
// src/components/BlogPlaceholder.tsx
|
|
178
|
-
var
|
|
206
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
179
207
|
function BlogPlaceholder({ count = 3, className = "" }) {
|
|
180
|
-
return /* @__PURE__ */ (0,
|
|
181
|
-
/* @__PURE__ */ (0,
|
|
182
|
-
/* @__PURE__ */ (0,
|
|
183
|
-
/* @__PURE__ */ (0,
|
|
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
|
-
|
|
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({
|
|
39
|
+
declare function BlogCard({ metadata, basePath, renderLink, className, showCategory, showReadingTime, showDate, }: BlogCardProps): react_jsx_runtime.JSX.Element;
|
|
40
40
|
|
|
41
41
|
interface BlogListProps {
|
|
42
|
-
|
|
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({
|
|
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
|
-
|
|
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({
|
|
39
|
+
declare function BlogCard({ metadata, basePath, renderLink, className, showCategory, showReadingTime, showDate, }: BlogCardProps): react_jsx_runtime.JSX.Element;
|
|
40
40
|
|
|
41
41
|
interface BlogListProps {
|
|
42
|
-
|
|
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({
|
|
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
|
|
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__ */
|
|
10
|
-
h2: ({ ...props }) => /* @__PURE__ */
|
|
11
|
-
h3: ({ ...props }) => /* @__PURE__ */
|
|
12
|
-
h4: ({ ...props }) => /* @__PURE__ */
|
|
13
|
-
h5: ({ ...props }) => /* @__PURE__ */
|
|
14
|
-
h6: ({ ...props }) => /* @__PURE__ */
|
|
15
|
-
p: ({ ...props }) => /* @__PURE__ */
|
|
16
|
-
ul: ({ ...props }) => /* @__PURE__ */
|
|
17
|
-
ol: ({ ...props }) => /* @__PURE__ */
|
|
18
|
-
li: ({ ...props }) => /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
41
|
-
strong: ({ ...props }) => /* @__PURE__ */
|
|
42
|
-
em: ({ ...props }) => /* @__PURE__ */
|
|
43
|
-
del: ({ ...props }) => /* @__PURE__ */
|
|
44
|
-
hr: ({ ...props }) => /* @__PURE__ */
|
|
45
|
-
br: ({ ...props }) => /* @__PURE__ */
|
|
46
|
-
img: ({ ...props }) => /* @__PURE__ */
|
|
47
|
-
table: ({ ...props }) => /* @__PURE__ */
|
|
48
|
-
thead: ({ ...props }) => /* @__PURE__ */
|
|
49
|
-
tbody: ({ ...props }) => /* @__PURE__ */
|
|
50
|
-
tr: ({ ...props }) => /* @__PURE__ */
|
|
51
|
-
th: ({ ...props }) => /* @__PURE__ */
|
|
52
|
-
td: ({ ...props }) => /* @__PURE__ */
|
|
53
|
-
input: ({ ...props }) => /* @__PURE__ */
|
|
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__ */
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
|
96
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
69
97
|
function BlogCard({
|
|
70
|
-
|
|
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}/${
|
|
79
|
-
const defaultLink = (href2, children) => /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
87
|
-
showCategory &&
|
|
88
|
-
(showReadingTime || showDate) && /* @__PURE__ */
|
|
89
|
-
showReadingTime && /* @__PURE__ */
|
|
90
|
-
showReadingTime && showDate && /* @__PURE__ */
|
|
91
|
-
showDate && /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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
|
|
141
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
114
142
|
function BlogList({
|
|
115
|
-
|
|
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 (
|
|
123
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
153
|
+
return /* @__PURE__ */ jsx4("div", { className: `space-y-6 ${className}`, children: metadata.map((meta) => /* @__PURE__ */ jsx4(
|
|
126
154
|
BlogCard,
|
|
127
155
|
{
|
|
128
|
-
|
|
156
|
+
metadata: meta,
|
|
129
157
|
basePath,
|
|
130
158
|
renderLink,
|
|
131
159
|
...cardProps
|
|
132
160
|
},
|
|
133
|
-
|
|
161
|
+
meta.slug
|
|
134
162
|
)) });
|
|
135
163
|
}
|
|
136
164
|
|
|
137
165
|
// src/components/BlogPlaceholder.tsx
|
|
138
|
-
import { jsx as
|
|
166
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
139
167
|
function BlogPlaceholder({ count = 3, className = "" }) {
|
|
140
|
-
return /* @__PURE__ */
|
|
141
|
-
/* @__PURE__ */
|
|
142
|
-
/* @__PURE__ */
|
|
143
|
-
/* @__PURE__ */
|
|
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
|
|