@haroonwaves/blog-kit-react 0.0.4 → 0.0.5
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 +85 -57
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +85 -57
- 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,42 +84,56 @@ 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
|
blog,
|
|
111
139
|
basePath = "/blog",
|
|
@@ -116,19 +144,19 @@ function BlogCard({
|
|
|
116
144
|
showDate = true
|
|
117
145
|
}) {
|
|
118
146
|
const href = `${basePath}/${blog.slug}`;
|
|
119
|
-
const defaultLink = (href2, children) => /* @__PURE__ */ (0,
|
|
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 && blog.category && /* @__PURE__ */ (0,
|
|
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 && blog.category && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Badge, { children: blog.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: blog.readingTime }),
|
|
158
|
+
showReadingTime && showDate && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "\u2022" }),
|
|
159
|
+
showDate && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("time", { dateTime: blog.date, children: new Date(blog.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: blog.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: blog.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,7 +178,7 @@ 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
|
blogs,
|
|
156
184
|
basePath = "/blog",
|
|
@@ -160,9 +188,9 @@ function BlogList({
|
|
|
160
188
|
cardProps
|
|
161
189
|
}) {
|
|
162
190
|
if (blogs.length === 0) {
|
|
163
|
-
return /* @__PURE__ */ (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: blogs.map((blog) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
166
194
|
BlogCard,
|
|
167
195
|
{
|
|
168
196
|
blog,
|
|
@@ -175,12 +203,12 @@ function BlogList({
|
|
|
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
|
@@ -22,10 +22,11 @@ interface BlogConfig {
|
|
|
22
22
|
|
|
23
23
|
interface BlogRendererProps {
|
|
24
24
|
content: string;
|
|
25
|
+
metadata: BlogMeta;
|
|
25
26
|
className?: string;
|
|
26
27
|
components?: Record<string, react__default.ComponentType<any>>;
|
|
27
28
|
}
|
|
28
|
-
declare function BlogRenderer({ content, className, components }: BlogRendererProps): react_jsx_runtime.JSX.Element;
|
|
29
|
+
declare function BlogRenderer({ content, metadata, className, components }: BlogRendererProps): react_jsx_runtime.JSX.Element;
|
|
29
30
|
|
|
30
31
|
interface BlogCardProps {
|
|
31
32
|
blog: BlogMeta;
|
package/dist/index.d.ts
CHANGED
|
@@ -22,10 +22,11 @@ interface BlogConfig {
|
|
|
22
22
|
|
|
23
23
|
interface BlogRendererProps {
|
|
24
24
|
content: string;
|
|
25
|
+
metadata: BlogMeta;
|
|
25
26
|
className?: string;
|
|
26
27
|
components?: Record<string, react__default.ComponentType<any>>;
|
|
27
28
|
}
|
|
28
|
-
declare function BlogRenderer({ content, className, components }: BlogRendererProps): react_jsx_runtime.JSX.Element;
|
|
29
|
+
declare function BlogRenderer({ content, metadata, className, components }: BlogRendererProps): react_jsx_runtime.JSX.Element;
|
|
29
30
|
|
|
30
31
|
interface BlogCardProps {
|
|
31
32
|
blog: BlogMeta;
|
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,42 +44,56 @@ 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
|
blog,
|
|
71
99
|
basePath = "/blog",
|
|
@@ -76,19 +104,19 @@ function BlogCard({
|
|
|
76
104
|
showDate = true
|
|
77
105
|
}) {
|
|
78
106
|
const href = `${basePath}/${blog.slug}`;
|
|
79
|
-
const defaultLink = (href2, children) => /* @__PURE__ */
|
|
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 && blog.category && /* @__PURE__ */
|
|
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 && blog.category && /* @__PURE__ */ jsx3(Badge, { children: blog.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: blog.readingTime }),
|
|
118
|
+
showReadingTime && showDate && /* @__PURE__ */ jsx3("span", { children: "\u2022" }),
|
|
119
|
+
showDate && /* @__PURE__ */ jsx3("time", { dateTime: blog.date, children: new Date(blog.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: blog.title })
|
|
101
129
|
),
|
|
102
|
-
/* @__PURE__ */
|
|
130
|
+
/* @__PURE__ */ jsx3("p", { className: "text-sm text-gray-500 leading-6 mb-4", children: blog.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,7 +138,7 @@ 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
|
blogs,
|
|
116
144
|
basePath = "/blog",
|
|
@@ -120,9 +148,9 @@ function BlogList({
|
|
|
120
148
|
cardProps
|
|
121
149
|
}) {
|
|
122
150
|
if (blogs.length === 0) {
|
|
123
|
-
return /* @__PURE__ */
|
|
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: blogs.map((blog) => /* @__PURE__ */ jsx4(
|
|
126
154
|
BlogCard,
|
|
127
155
|
{
|
|
128
156
|
blog,
|
|
@@ -135,12 +163,12 @@ function BlogList({
|
|
|
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
|
|