@brutalcomponent/react
Version:
Brutalist React components
268 lines (266 loc) • 11.2 kB
JavaScript
import { FilterControls } from '../../chunk-BDCXITH3.mjs';
import '../../chunk-YLIM27QY.mjs';
import '../../chunk-E2BWEC67.mjs';
import { Icon } from '../../chunk-QB4EPFXT.mjs';
import '../../chunk-KMHX64YN.mjs';
import '../../chunk-7QJK2SK5.mjs';
import React2 from 'react';
import { clsx } from 'clsx';
import { FaArrowLeft, FaCalendarAlt, FaEye, FaClock, FaUtensils, FaGlobe } from 'react-icons/fa';
/**
* @brutalcomponent/react
* (c) David Heffler (https://dvh.sh)
* Licensed under MIT
*/
var blogSortOptions = [
{ value: "newest", label: "Sort: Newest" },
{ value: "oldest", label: "Sort: Oldest" },
{ value: "most-views", label: "Sort: Popular" }
];
var BlogFilters = (props) => {
return /* @__PURE__ */ React2.createElement(FilterControls, { ...props, sortOptions: blogSortOptions });
};
var PostHeader = ({
title,
date,
views,
readingTime,
backHref = "/blog",
backLabel = "Back to all posts",
isCooking = false,
origin,
type,
cookingTime,
className
}) => {
return /* @__PURE__ */ React2.createElement(
"div",
{
className: clsx(
"mb-12 bg-brutal-gray-100 p-6 shadow-brutal transform -skew-x-2",
"border-4 border-brutal-black",
className
)
},
/* @__PURE__ */ React2.createElement("div", { className: "transform skew-x-2" }, /* @__PURE__ */ React2.createElement("div", { className: "flex flex-col md:flex-row justify-between items-start md:items-center mb-6" }, /* @__PURE__ */ React2.createElement(
"a",
{
href: backHref,
className: "inline-flex items-center text-brutal-pink hover:text-brutal-peach transition-colors duration-200 mb-4 md:mb-0 group"
},
/* @__PURE__ */ React2.createElement(
Icon,
{
icon: FaArrowLeft,
size: "sm",
className: "mr-2 animate-pulse group-hover:translate-x-[-4px] transition-transform"
}
),
/* @__PURE__ */ React2.createElement("span", { className: "uppercase tracking-wide font-bold" }, backLabel)
), /* @__PURE__ */ React2.createElement("div", { className: "flex items-center flex-wrap gap-2 sm:gap-4 text-brutal-gray-600 text-xs font-mono" }, /* @__PURE__ */ React2.createElement("div", { className: "flex items-center" }, /* @__PURE__ */ React2.createElement(Icon, { icon: FaCalendarAlt, size: "xs", className: "mr-1" }), /* @__PURE__ */ React2.createElement("time", { dateTime: date }, new Date(date).toLocaleDateString())), views !== void 0 && /* @__PURE__ */ React2.createElement("div", { className: "flex items-center" }, /* @__PURE__ */ React2.createElement(Icon, { icon: FaEye, size: "xs", className: "mr-1" }), /* @__PURE__ */ React2.createElement("span", null, views, " views")), readingTime && /* @__PURE__ */ React2.createElement("div", { className: "flex items-center" }, /* @__PURE__ */ React2.createElement(Icon, { icon: FaClock, size: "xs", className: "mr-1" }), /* @__PURE__ */ React2.createElement("span", null, readingTime, " min read")), cookingTime && /* @__PURE__ */ React2.createElement("div", { className: "flex items-center" }, /* @__PURE__ */ React2.createElement(Icon, { icon: FaUtensils, size: "xs", className: "mr-1" }), /* @__PURE__ */ React2.createElement("span", null, cookingTime)), origin && /* @__PURE__ */ React2.createElement("div", { className: "flex items-center" }, /* @__PURE__ */ React2.createElement(Icon, { icon: FaGlobe, size: "xs", className: "mr-1" }), /* @__PURE__ */ React2.createElement("span", null, origin)), type && /* @__PURE__ */ React2.createElement("div", { className: "flex items-center" }, /* @__PURE__ */ React2.createElement(Icon, { icon: FaUtensils, size: "xs", className: "mr-1" }), /* @__PURE__ */ React2.createElement("span", null, type)))), /* @__PURE__ */ React2.createElement("h1", { className: "text-4xl md:text-5xl font-black text-brutal-black uppercase tracking-wide leading-tight transform hover:skew-x-2 transition-transform duration-300" }, title))
);
};
var PostContent = ({
children,
className
}) => {
return /* @__PURE__ */ React2.createElement(
"div",
{
className: clsx(
"prose prose-lg max-w-none",
// Headings
"prose-headings:font-black prose-headings:uppercase prose-headings:tracking-wider",
"prose-h1:text-4xl prose-h1:text-brutal-black prose-h1:transform prose-h1:-skew-x-2",
"prose-h2:text-3xl prose-h2:text-brutal-black",
"prose-h3:text-2xl prose-h3:text-brutal-black",
"prose-h4:text-xl prose-h4:text-brutal-black",
// Paragraphs
"prose-p:text-brutal-gray-700 prose-p:font-mono prose-p:leading-relaxed",
// Links
"prose-a:text-brutal-pink prose-a:no-underline prose-a:font-bold",
"prose-a:border-b-2 prose-a:border-brutal-pink",
"prose-a:hover:text-brutal-peach prose-a:hover:border-brutal-peach",
"prose-a:transition-colors",
// Lists
"prose-ul:list-none prose-ul:space-y-2",
"prose-ul:pl-0",
"prose-li:text-brutal-gray-700 prose-li:font-mono",
'prose-li:before:content-["\u2192"] prose-li:before:text-brutal-pink',
"prose-li:before:font-black prose-li:before:mr-2",
"prose-ol:list-decimal prose-ol:list-inside",
// Blockquotes
"prose-blockquote:border-l-4 prose-blockquote:border-brutal-pink",
"prose-blockquote:bg-brutal-gray-100 prose-blockquote:py-2",
"prose-blockquote:pl-4 prose-blockquote:not-italic",
// Code
"prose-code:bg-brutal-gray-200 prose-code:text-brutal-black",
"prose-code:px-2 prose-code:py-1 prose-code:rounded-none",
"prose-code:before:content-none prose-code:after:content-none",
"prose-pre:bg-brutal-black prose-pre:text-brutal-white",
"prose-pre:border-4 prose-pre:border-brutal-black",
"prose-pre:shadow-brutal",
// Tables
"prose-table:border-4 prose-table:border-brutal-black",
"prose-thead:bg-brutal-black prose-thead:text-brutal-white",
"prose-th:font-black prose-th:uppercase prose-th:tracking-wider",
"prose-th:p-3",
"prose-td:border-2 prose-td:border-brutal-black prose-td:p-3",
// Images
"prose-img:border-4 prose-img:border-brutal-black",
"prose-img:shadow-brutal",
// Strong
"prose-strong:font-black prose-strong:text-brutal-pink",
// HR
"prose-hr:border-brutal-black prose-hr:border-2",
className
)
},
children
);
};
var MDXComponents = {
h1: (props) => /* @__PURE__ */ React2.createElement(
"h1",
{
className: "text-4xl font-black mb-6 text-brutal-black uppercase tracking-wide transform -skew-x-2",
...props
}
),
h2: (props) => /* @__PURE__ */ React2.createElement(
"h2",
{
className: "text-3xl font-bold mb-4 text-brutal-black uppercase tracking-wide",
...props
}
),
h3: (props) => /* @__PURE__ */ React2.createElement("h3", { className: "text-2xl font-semibold mb-3 text-brutal-black", ...props }),
h4: (props) => /* @__PURE__ */ React2.createElement("h4", { className: "text-xl font-semibold mb-2 text-brutal-black", ...props }),
p: (props) => /* @__PURE__ */ React2.createElement(
"p",
{
className: "mb-6 text-brutal-gray-700 font-mono leading-relaxed",
...props
}
),
a: (props) => /* @__PURE__ */ React2.createElement(
"a",
{
className: "text-brutal-pink hover:text-brutal-peach transition-colors duration-200 border-b-2 border-brutal-pink hover:border-brutal-peach font-bold",
...props
}
),
ul: (props) => /* @__PURE__ */ React2.createElement("ul", { className: "list-none space-y-2 mb-6", ...props }),
ol: (props) => /* @__PURE__ */ React2.createElement("ol", { className: "list-decimal list-inside mb-6 space-y-2", ...props }),
li: (props) => /* @__PURE__ */ React2.createElement("li", { className: "text-brutal-gray-700 font-mono flex items-start" }, /* @__PURE__ */ React2.createElement("span", { className: "text-brutal-pink font-black mr-2" }, "\u2192"), /* @__PURE__ */ React2.createElement("span", null, props.children)),
blockquote: (props) => /* @__PURE__ */ React2.createElement(
"blockquote",
{
className: "border-l-4 border-brutal-pink pl-4 italic mb-6 text-brutal-gray-700 font-mono bg-brutal-gray-100 py-2",
...props
}
),
code: (props) => /* @__PURE__ */ React2.createElement(
"code",
{
className: "bg-brutal-gray-200 text-brutal-black px-2 py-1 font-mono text-sm",
...props
}
),
pre: (props) => /* @__PURE__ */ React2.createElement(
"pre",
{
className: "bg-brutal-black text-brutal-white p-4 mb-6 overflow-x-auto border-4 border-brutal-black shadow-brutal",
...props
}
)
};
var LicenseInfo = ({
type = "CC BY-NC-SA 4.0",
className
}) => {
const licenseUrls = {
"CC BY-NC-SA 4.0": "https://creativecommons.org/licenses/by-nc-sa/4.0/",
"CC BY 4.0": "https://creativecommons.org/licenses/by/4.0/",
"CC BY-SA 4.0": "https://creativecommons.org/licenses/by-sa/4.0/",
"CC BY-NC 4.0": "https://creativecommons.org/licenses/by-nc/4.0/"
};
return /* @__PURE__ */ React2.createElement(
"div",
{
className: clsx(
"mt-12 p-4 bg-brutal-gray-100 border-t-4 border-brutal-black transform skew-x-2",
className
)
},
/* @__PURE__ */ React2.createElement("p", { className: "text-sm text-brutal-gray-600 font-mono" }, "This work is licensed under", " ", /* @__PURE__ */ React2.createElement(
"a",
{
href: licenseUrls[type],
target: "_blank",
rel: "noopener noreferrer",
className: "text-brutal-pink hover:text-brutal-peach transition-colors duration-200 uppercase tracking-wide font-bold"
},
type
))
);
};
/**
* @file src/modules/blog/BlogFilters/BlogFilters.tsx
* @author David (https://dvh.sh)
* @license MIT
*
* @created Fri Sep 12 2025
* @updated Fri Sep 12 2025
*
* @description
* A specific implementation of FilterControls for blog posts.
* @client This component requires client-side JavaScript
*/
/**
* @file src/modules/blog/PostHeader/PostHeader.tsx
* @author David (https://dvh.sh)
* @license MIT
*
* @created Thu Sep 11 2025
* @updated Fri Sep 12 2025
*
* @description
* Header section for blog posts with metadata
*/
/**
* @file src/modules/blog/PostContent/PostContent.tsx
* @author David (https://dvh.sh)
* @license MIT
*
* @created Thu Sep 11 2025
* @updated Fri Sep 12 2025
*
* @description
* Container for blog post content with brutal MDX styles
*/
/**
* @file src/modules/blog/LicenseInfo/LicenseInfo.tsx
* @author David (https://dvh.sh)
* @license MIT
*
* @created Thu Sep 11 2025
* @updated Fri Sep 12 2025
*
* @description
* Display Creative Commons license information
*/
/**
* @file src/modules/blog/index.ts
* @author David (https://dvh.sh)
* @license MIT
*
* @created Thu Sep 11 2025
* @updated Fri Sep 12 2025
*
* @description
*
*/
export { BlogFilters, LicenseInfo, MDXComponents, PostContent, PostHeader };
//# sourceMappingURL=index.mjs.map
//# sourceMappingURL=index.mjs.map