singularity-components 0.1.151 → 0.1.193
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/README.md +29 -12
- package/dist/components/blocks/cards/blogpost-card.d.ts +9 -4
- package/dist/components/blocks/cards/blogpost-card.js +37 -23
- package/dist/components/blocks/cards/blogpost-card.js.map +1 -1
- package/dist/components/blocks/cards/card.js +1 -1
- package/dist/components/blocks/cards/card.js.map +1 -1
- package/dist/components/blocks/empty-state/EmptyState.d.ts +15 -0
- package/dist/components/blocks/empty-state/EmptyState.js +36 -0
- package/dist/components/blocks/empty-state/EmptyState.js.map +1 -0
- package/dist/components/blocks/index.d.ts +2 -0
- package/dist/components/blocks/index.js +4 -2
- package/dist/components/blocks/index.js.map +1 -1
- package/dist/components/blocks/post-list/post-filters.d.ts +19 -0
- package/dist/components/blocks/post-list/post-filters.js +99 -0
- package/dist/components/blocks/post-list/post-filters.js.map +1 -0
- package/dist/components/blocks/post-list/post-list-with-filters.d.ts +19 -0
- package/dist/components/blocks/post-list/post-list-with-filters.js +439 -0
- package/dist/components/blocks/post-list/post-list-with-filters.js.map +1 -0
- package/dist/components/index.d.ts +42 -12
- package/dist/components/index.js +5 -6
- package/dist/components/index.js.map +1 -1
- package/dist/components/pages/admin/admin-page.d.ts +8 -0
- package/dist/components/pages/admin/admin-page.js +299 -0
- package/dist/components/pages/admin/admin-page.js.map +1 -0
- package/dist/components/pages/blogpost/blogpost.js +440 -0
- package/dist/components/pages/blogpost/blogpost.js.map +1 -0
- package/dist/components/pages/category/category-page.d.ts +8 -0
- package/dist/components/pages/category/category-page.js +69 -0
- package/dist/components/pages/category/category-page.js.map +1 -0
- package/dist/components/pages/chat/chat-page.d.ts +5 -0
- package/dist/components/pages/chat/chat-page.js +209 -0
- package/dist/components/pages/chat/chat-page.js.map +1 -0
- package/dist/components/pages/index.d.ts +11 -0
- package/dist/components/pages/index.js +11 -0
- package/dist/components/pages/index.js.map +1 -0
- package/dist/components/pages/login/login-page.d.ts +19 -0
- package/dist/components/pages/login/login-page.js +108 -0
- package/dist/components/pages/login/login-page.js.map +1 -0
- package/dist/components/pages/maintenance/maintenance-page.d.ts +5 -0
- package/dist/components/pages/maintenance/maintenance-page.js +50 -0
- package/dist/components/pages/maintenance/maintenance-page.js.map +1 -0
- package/dist/components/pages/not-found/not-found.d.ts +10 -0
- package/dist/components/pages/not-found/not-found.js +64 -0
- package/dist/components/pages/not-found/not-found.js.map +1 -0
- package/dist/components/pages/privacy/privacy-page.d.ts +15 -0
- package/dist/components/pages/privacy/privacy-page.js +98 -0
- package/dist/components/pages/privacy/privacy-page.js.map +1 -0
- package/dist/components/pages/search/search-page.d.ts +5 -0
- package/dist/components/pages/search/search-page.js +18 -0
- package/dist/components/pages/search/search-page.js.map +1 -0
- package/dist/components/pages/startpage/startpage.js +50 -0
- package/dist/components/pages/startpage/startpage.js.map +1 -0
- package/dist/components/pages/terms/terms-page.d.ts +15 -0
- package/dist/components/pages/terms/terms-page.js +98 -0
- package/dist/components/pages/terms/terms-page.js.map +1 -0
- package/dist/components/primitives/accordion/accordion.js +1 -1
- package/dist/components/primitives/accordion/accordion.js.map +1 -1
- package/dist/components/primitives/alert/alert.js +1 -1
- package/dist/components/primitives/alert/alert.js.map +1 -1
- package/dist/components/primitives/avatar/avatar.d.ts +14 -0
- package/dist/components/primitives/avatar/avatar.js +103 -0
- package/dist/components/primitives/avatar/avatar.js.map +1 -0
- package/dist/components/primitives/badge/badge.d.ts +1 -1
- package/dist/components/primitives/badge/badge.js +5 -5
- package/dist/components/primitives/badge/badge.js.map +1 -1
- package/dist/components/primitives/badge/badges.js +1 -1
- package/dist/components/primitives/badge/badges.js.map +1 -1
- package/dist/components/primitives/{button → buttons}/button.d.ts +8 -7
- package/dist/components/primitives/{button → buttons}/button.js +19 -14
- package/dist/components/primitives/buttons/button.js.map +1 -0
- package/dist/components/primitives/buttons/icon-button.d.ts +33 -0
- package/dist/components/primitives/buttons/icon-button.js +61 -0
- package/dist/components/primitives/buttons/icon-button.js.map +1 -0
- package/dist/components/primitives/{link → buttons}/link-button.d.ts +7 -4
- package/dist/components/primitives/buttons/link-button.js +35 -0
- package/dist/components/primitives/buttons/link-button.js.map +1 -0
- package/dist/components/primitives/collapsible/collapsible.d.ts +9 -0
- package/dist/components/primitives/collapsible/collapsible.js +53 -0
- package/dist/components/primitives/collapsible/collapsible.js.map +1 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu.d.ts +30 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu.js +164 -0
- package/dist/components/primitives/dropdown-menu/dropdown-menu.js.map +1 -0
- package/dist/components/primitives/forms/checkbox.d.ts +6 -0
- package/dist/components/primitives/forms/checkbox.js +30 -0
- package/dist/components/primitives/forms/checkbox.js.map +1 -0
- package/dist/components/primitives/forms/field.d.ts +29 -0
- package/dist/components/primitives/forms/field.js +218 -0
- package/dist/components/primitives/forms/field.js.map +1 -0
- package/dist/components/primitives/forms/input.d.ts +6 -0
- package/dist/components/primitives/forms/input.js +22 -0
- package/dist/components/primitives/forms/input.js.map +1 -0
- package/dist/components/primitives/forms/select.d.ts +22 -0
- package/dist/components/primitives/forms/select.js +169 -0
- package/dist/components/primitives/forms/select.js.map +1 -0
- package/dist/components/primitives/forms/textarea.d.ts +6 -0
- package/dist/components/primitives/forms/textarea.js +20 -0
- package/dist/components/primitives/forms/textarea.js.map +1 -0
- package/dist/components/primitives/icon/icon.d.ts +9 -2
- package/dist/components/primitives/icon/icon.js +10 -3
- package/dist/components/primitives/icon/icon.js.map +1 -1
- package/dist/components/primitives/index.d.ts +23 -7
- package/dist/components/primitives/index.js +31 -20
- package/dist/components/primitives/index.js.map +1 -1
- package/dist/components/primitives/label/label.d.ts +6 -0
- package/dist/components/primitives/label/label.js +22 -0
- package/dist/components/primitives/label/label.js.map +1 -0
- package/dist/components/primitives/layout/layout.d.ts +6 -3
- package/dist/components/primitives/layout/layout.js +28 -11
- package/dist/components/primitives/layout/layout.js.map +1 -1
- package/dist/components/primitives/link/link.d.ts +11 -5
- package/dist/components/primitives/link/link.js +38 -11
- package/dist/components/primitives/link/link.js.map +1 -1
- package/dist/components/primitives/separator/separator.js +1 -1
- package/dist/components/primitives/separator/separator.js.map +1 -1
- package/dist/components/primitives/sheet/sheet.d.ts +29 -0
- package/dist/components/primitives/sheet/sheet.js +117 -0
- package/dist/components/primitives/sheet/sheet.js.map +1 -0
- package/dist/components/primitives/skeleton/skeleton.js +1 -1
- package/dist/components/primitives/skeleton/skeleton.js.map +1 -1
- package/dist/components/primitives/sonner/sonner.d.ts +7 -0
- package/dist/components/primitives/sonner/sonner.js +42 -0
- package/dist/components/primitives/sonner/sonner.js.map +1 -0
- package/dist/components/primitives/sonner/use-toast.d.ts +24 -0
- package/dist/components/primitives/sonner/use-toast.js +21 -0
- package/dist/components/primitives/sonner/use-toast.js.map +1 -0
- package/dist/components/primitives/spinner/spinner.js +1 -1
- package/dist/components/primitives/spinner/spinner.js.map +1 -1
- package/dist/components/primitives/stack/stack.d.ts +3 -0
- package/dist/components/primitives/stack/stack.js +34 -4
- package/dist/components/primitives/stack/stack.js.map +1 -1
- package/dist/components/primitives/text/{text-heading.d.ts → heading.d.ts} +5 -5
- package/dist/components/primitives/text/{text-heading.js → heading.js} +11 -11
- package/dist/components/primitives/text/heading.js.map +1 -0
- package/dist/components/primitives/text/internal/text-element.d.ts +7 -3
- package/dist/components/primitives/text/internal/text-element.js +4 -2
- package/dist/components/primitives/text/internal/text-element.js.map +1 -1
- package/dist/components/primitives/text/text-code.d.ts +26 -0
- package/dist/components/primitives/text/text-code.js +44 -0
- package/dist/components/primitives/text/text-code.js.map +1 -0
- package/dist/components/primitives/text/text-div.js +2 -2
- package/dist/components/primitives/text/text-div.js.map +1 -1
- package/dist/components/primitives/text/text-span.js +2 -2
- package/dist/components/primitives/text/text-span.js.map +1 -1
- package/dist/components/primitives/text/text-time.js +2 -2
- package/dist/components/primitives/text/text-time.js.map +1 -1
- package/dist/components/primitives/text/{text-paragraph.d.ts → text.d.ts} +4 -4
- package/dist/components/primitives/text/{text-paragraph.js → text.js} +11 -11
- package/dist/components/primitives/text/text.js.map +1 -0
- package/dist/components/primitives/{ui-image.d.ts → ui-image/ui-image.d.ts} +1 -1
- package/dist/components/primitives/{ui-image.js → ui-image/ui-image.js} +3 -3
- package/dist/components/primitives/ui-image/ui-image.js.map +1 -0
- package/dist/components/primitives/ui-link/ui-link.d.ts +8 -0
- package/dist/components/primitives/ui-link/ui-link.js +19 -0
- package/dist/components/primitives/ui-link/ui-link.js.map +1 -0
- package/dist/components/providers/LinkContext.d.ts +1 -1
- package/dist/components/providers/LinkContext.js +1 -1
- package/dist/components/providers/LinkContext.js.map +1 -1
- package/dist/components/providers/SingularityContext.d.ts +4 -1
- package/dist/components/providers/SingularityContext.js +7 -3
- package/dist/components/providers/SingularityContext.js.map +1 -1
- package/dist/components/providers/auth-provider.d.ts +15 -0
- package/dist/components/providers/auth-provider.js +30 -0
- package/dist/components/providers/auth-provider.js.map +1 -0
- package/dist/components/providers/index.d.ts +3 -0
- package/dist/components/providers/index.js +5 -3
- package/dist/components/providers/index.js.map +1 -1
- package/dist/components/providers/theme-provider.d.ts +27 -0
- package/dist/components/providers/theme-provider.js +75 -0
- package/dist/components/providers/theme-provider.js.map +1 -0
- package/dist/components/templates/container/container.d.ts +20 -0
- package/dist/components/templates/container/container.js +58 -0
- package/dist/components/templates/container/container.js.map +1 -0
- package/dist/components/templates/footer/footer.d.ts +5 -0
- package/dist/components/templates/footer/footer.js +12 -0
- package/dist/components/templates/footer/footer.js.map +1 -0
- package/dist/components/templates/form/form.d.ts +5 -0
- package/dist/components/templates/form/form.js +141 -0
- package/dist/components/templates/form/form.js.map +1 -0
- package/dist/components/templates/hero/hero.d.ts +18 -0
- package/dist/components/{sections → templates}/hero/hero.js +52 -22
- package/dist/components/templates/hero/hero.js.map +1 -0
- package/dist/components/templates/index.d.ts +4 -2
- package/dist/components/templates/index.js +4 -2
- package/dist/components/templates/index.js.map +1 -1
- package/dist/components/templates/navigation/header.d.ts +19 -0
- package/dist/components/templates/navigation/header.js +222 -0
- package/dist/components/templates/navigation/header.js.map +1 -0
- package/dist/components/templates/navigation/index.d.ts +3 -0
- package/dist/components/templates/navigation/index.js +2 -0
- package/dist/components/templates/navigation/index.js.map +1 -0
- package/dist/css/variables.css +2 -2
- package/dist/css/variables.css.map +1 -1
- package/dist/data/authors.d.ts +12 -0
- package/dist/data/authors.js +33 -0
- package/dist/data/authors.js.map +1 -0
- package/dist/data/posts.d.ts +5 -3
- package/dist/data/posts.js +66 -47
- package/dist/data/posts.js.map +1 -1
- package/dist/index.d.ts +42 -12
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/helpers/index.js +1 -1
- package/dist/lib/helpers/index.js.map +1 -1
- package/dist/lib/index.js +2 -2
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/types.d.ts +4 -8
- package/dist/main.css +1528 -85
- package/dist/main.css.map +1 -1
- package/dist/{utils.js → utils/index.js} +1 -1
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/index.test.js +37 -0
- package/dist/utils/index.test.js.map +1 -0
- package/package.json +69 -44
- package/dist/components/primitives/button/button.js.map +0 -1
- package/dist/components/primitives/link/link-button.js +0 -21
- package/dist/components/primitives/link/link-button.js.map +0 -1
- package/dist/components/primitives/text/text-heading.js.map +0 -1
- package/dist/components/primitives/text/text-paragraph.js.map +0 -1
- package/dist/components/primitives/ui-image.js.map +0 -1
- package/dist/components/primitives/ui-link.d.ts +0 -8
- package/dist/components/primitives/ui-link.js +0 -16
- package/dist/components/primitives/ui-link.js.map +0 -1
- package/dist/components/sections/body/body.d.ts +0 -19
- package/dist/components/sections/body/body.js +0 -49
- package/dist/components/sections/body/body.js.map +0 -1
- package/dist/components/sections/footer/footer.d.ts +0 -12
- package/dist/components/sections/footer/footer.js +0 -59
- package/dist/components/sections/footer/footer.js.map +0 -1
- package/dist/components/sections/hero/hero.d.ts +0 -6
- package/dist/components/sections/hero/hero.js.map +0 -1
- package/dist/components/sections/index.d.ts +0 -3
- package/dist/components/sections/index.js +0 -4
- package/dist/components/sections/index.js.map +0 -1
- package/dist/components/templates/blogpost/blogpost.js +0 -173
- package/dist/components/templates/blogpost/blogpost.js.map +0 -1
- package/dist/components/templates/startpage/startpage.js +0 -48
- package/dist/components/templates/startpage/startpage.js.map +0 -1
- package/dist/components/units/index.js +0 -1
- package/dist/components/units/index.js.map +0 -1
- package/dist/utils.js.map +0 -1
- /package/dist/components/{templates → pages}/blogpost/blogpost.d.ts +0 -0
- /package/dist/components/{templates → pages}/startpage/startpage.d.ts +0 -0
- /package/dist/{utils.d.ts → utils/index.d.ts} +0 -0
- /package/dist/{components/units/index.d.ts → utils/index.test.d.ts} +0 -0
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useMemo } from "react";
|
|
4
|
+
import { motion, AnimatePresence } from "framer-motion";
|
|
5
|
+
import BlogPostCard from "../cards/blogpost-card.js";
|
|
6
|
+
import EmptyState from "../empty-state/EmptyState.js";
|
|
7
|
+
import { Input } from "../../primitives/forms/input.js";
|
|
8
|
+
import { Button } from "../../primitives/buttons/button.js";
|
|
9
|
+
import { Badge } from "../../primitives/badge/badge.js";
|
|
10
|
+
import { Link } from "../../primitives/link/link.js";
|
|
11
|
+
import { Icon } from "../../primitives/icon/icon.js";
|
|
12
|
+
import {
|
|
13
|
+
Heading,
|
|
14
|
+
IconButton,
|
|
15
|
+
Text,
|
|
16
|
+
TextSpan,
|
|
17
|
+
TextTime,
|
|
18
|
+
UiImage
|
|
19
|
+
} from "../../primitives/index.js";
|
|
20
|
+
import {
|
|
21
|
+
Select,
|
|
22
|
+
SelectContent,
|
|
23
|
+
SelectItem,
|
|
24
|
+
SelectTrigger,
|
|
25
|
+
SelectValue
|
|
26
|
+
} from "../../primitives/forms/select.js";
|
|
27
|
+
import { FilterControls } from "./post-filters.js";
|
|
28
|
+
import { cn } from "../../../utils/index.js";
|
|
29
|
+
const PAGE_SIZE = 6;
|
|
30
|
+
function PostListWithFilters({
|
|
31
|
+
posts: sourcePosts,
|
|
32
|
+
hideSearch = false,
|
|
33
|
+
hideAuthorFilter = false,
|
|
34
|
+
filterMode = "sidebar",
|
|
35
|
+
defaultLoadMode = "load-more"
|
|
36
|
+
}) {
|
|
37
|
+
const [query, setQuery] = useState("");
|
|
38
|
+
const [selectedCategories, setSelectedCategories] = useState([]);
|
|
39
|
+
const [selectedAuthors, setSelectedAuthors] = useState([]);
|
|
40
|
+
const [sortBy, setSortBy] = useState("newest");
|
|
41
|
+
const [loadMode, setLoadMode] = useState(defaultLoadMode);
|
|
42
|
+
const [viewMode, setViewMode] = useState("grid");
|
|
43
|
+
const [currentPage, setCurrentPage] = useState(1);
|
|
44
|
+
const [loadMoreCount, setLoadMoreCount] = useState(PAGE_SIZE);
|
|
45
|
+
const [isFiltersOpen, setIsFiltersOpen] = useState(false);
|
|
46
|
+
const allCategories = useMemo(
|
|
47
|
+
() => Array.from(new Set(sourcePosts.flatMap((p) => p.categories))).sort(),
|
|
48
|
+
[sourcePosts]
|
|
49
|
+
);
|
|
50
|
+
const allAuthors = useMemo(
|
|
51
|
+
() => Array.from(new Set(sourcePosts.map((p) => p.author))).sort(),
|
|
52
|
+
[sourcePosts]
|
|
53
|
+
);
|
|
54
|
+
const resetPaging = () => {
|
|
55
|
+
setCurrentPage(1);
|
|
56
|
+
setLoadMoreCount(PAGE_SIZE);
|
|
57
|
+
};
|
|
58
|
+
const toggleCategory = (cat) => {
|
|
59
|
+
setSelectedCategories(
|
|
60
|
+
(prev) => prev.includes(cat) ? prev.filter((c) => c !== cat) : [...prev, cat]
|
|
61
|
+
);
|
|
62
|
+
resetPaging();
|
|
63
|
+
};
|
|
64
|
+
const toggleAuthor = (author) => {
|
|
65
|
+
setSelectedAuthors(
|
|
66
|
+
(prev) => prev.includes(author) ? prev.filter((a) => a !== author) : [...prev, author]
|
|
67
|
+
);
|
|
68
|
+
resetPaging();
|
|
69
|
+
};
|
|
70
|
+
const clearFilters = () => {
|
|
71
|
+
setSelectedCategories([]);
|
|
72
|
+
setSelectedAuthors([]);
|
|
73
|
+
setQuery("");
|
|
74
|
+
resetPaging();
|
|
75
|
+
};
|
|
76
|
+
const activeCount = selectedCategories.length + selectedAuthors.length;
|
|
77
|
+
const filtered = useMemo(() => {
|
|
78
|
+
let result = [...sourcePosts];
|
|
79
|
+
if (selectedCategories.length > 0) {
|
|
80
|
+
result = result.filter(
|
|
81
|
+
(p) => selectedCategories.some((cat) => p.categories?.includes(cat))
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
if (selectedAuthors.length > 0) {
|
|
85
|
+
result = result.filter(
|
|
86
|
+
(p) => p.author && selectedAuthors.includes(p.author)
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
if (query.trim()) {
|
|
90
|
+
const q = query.toLowerCase();
|
|
91
|
+
result = result.filter(
|
|
92
|
+
(p) => p.title.toLowerCase().includes(q) || p.excerpt.toLowerCase().includes(q) || p.author.toLowerCase().includes(q) || p.categories?.some((c) => c.toLowerCase().includes(q))
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
result.sort((a, b) => {
|
|
96
|
+
switch (sortBy) {
|
|
97
|
+
case "newest":
|
|
98
|
+
return new Date(b.date).getTime() - new Date(a.date).getTime();
|
|
99
|
+
case "oldest":
|
|
100
|
+
return new Date(a.date).getTime() - new Date(b.date).getTime();
|
|
101
|
+
case "a-z":
|
|
102
|
+
return a.title.localeCompare(b.title);
|
|
103
|
+
case "z-a":
|
|
104
|
+
return b.title.localeCompare(a.title);
|
|
105
|
+
default:
|
|
106
|
+
return 0;
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
return result;
|
|
110
|
+
}, [query, selectedCategories, selectedAuthors, sortBy, sourcePosts]);
|
|
111
|
+
const totalPages = Math.ceil(filtered.length / PAGE_SIZE);
|
|
112
|
+
const displayed = loadMode === "pagination" ? filtered.slice((currentPage - 1) * PAGE_SIZE, currentPage * PAGE_SIZE) : filtered.slice(0, loadMoreCount);
|
|
113
|
+
const hasMore = loadMode === "load-more" && loadMoreCount < filtered.length;
|
|
114
|
+
const filterProps = {
|
|
115
|
+
categories: allCategories,
|
|
116
|
+
authors: allAuthors,
|
|
117
|
+
selectedCategories,
|
|
118
|
+
selectedAuthors,
|
|
119
|
+
toggleCategory,
|
|
120
|
+
toggleAuthor,
|
|
121
|
+
clearFilters,
|
|
122
|
+
activeCount,
|
|
123
|
+
sortBy,
|
|
124
|
+
setSortBy,
|
|
125
|
+
hideAuthorFilter
|
|
126
|
+
};
|
|
127
|
+
return /* @__PURE__ */ jsxs("div", { className: "sg:w-full", children: [
|
|
128
|
+
!hideSearch && /* @__PURE__ */ jsxs("div", { className: "sg:relative sg:mb-8 sg:max-w-lg", children: [
|
|
129
|
+
/* @__PURE__ */ jsx("div", { className: "sg:absolute sg:left-3 sg:top-1/2 sg:-translate-y-1/2 sg:pointer-events-none", children: /* @__PURE__ */ jsx(Icon, { icon: "Search", size: "xs", color: "muted-foreground" }) }),
|
|
130
|
+
/* @__PURE__ */ jsx(
|
|
131
|
+
Input,
|
|
132
|
+
{
|
|
133
|
+
placeholder: "Search posts...",
|
|
134
|
+
value: query,
|
|
135
|
+
onChange: (e) => {
|
|
136
|
+
setQuery(e.target.value);
|
|
137
|
+
resetPaging();
|
|
138
|
+
},
|
|
139
|
+
className: "sg:pl-9"
|
|
140
|
+
}
|
|
141
|
+
)
|
|
142
|
+
] }),
|
|
143
|
+
/* @__PURE__ */ jsxs("div", { className: "sg:flex sg:flex-wrap sg:items-center sg:gap-3 sg:mb-6", children: [
|
|
144
|
+
/* @__PURE__ */ jsxs(
|
|
145
|
+
Button,
|
|
146
|
+
{
|
|
147
|
+
variant: "outline",
|
|
148
|
+
size: "sm",
|
|
149
|
+
className: cn(
|
|
150
|
+
"sg:relative",
|
|
151
|
+
filterMode === "sidebar" && "sg:md:hidden"
|
|
152
|
+
),
|
|
153
|
+
onClick: () => setIsFiltersOpen(!isFiltersOpen),
|
|
154
|
+
iconStart: "ListFilter",
|
|
155
|
+
children: [
|
|
156
|
+
"Filters",
|
|
157
|
+
activeCount > 0 && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
|
|
158
|
+
TextSpan,
|
|
159
|
+
{
|
|
160
|
+
size: "xs",
|
|
161
|
+
foreground: "primary-foreground",
|
|
162
|
+
className: "sg:absolute sg:-top-1.5 sg:-right-1.5 sg:h-4 sg:w-4 sg:rounded-full sg:bg-primary sg:flex sg:items-center sg:justify-center",
|
|
163
|
+
children: activeCount
|
|
164
|
+
}
|
|
165
|
+
) })
|
|
166
|
+
]
|
|
167
|
+
}
|
|
168
|
+
),
|
|
169
|
+
/* @__PURE__ */ jsx("div", { className: "sg:flex-1" }),
|
|
170
|
+
/* @__PURE__ */ jsxs("div", { className: "sg:flex sg:gap-1 sg:bg-muted/50 sg:p-1 sg:rounded-lg sg:border", children: [
|
|
171
|
+
/* @__PURE__ */ jsx(
|
|
172
|
+
Button,
|
|
173
|
+
{
|
|
174
|
+
variant: viewMode === "grid" ? "secondary" : "ghost",
|
|
175
|
+
size: "sm",
|
|
176
|
+
onClick: () => setViewMode("grid"),
|
|
177
|
+
"aria-label": "Grid view",
|
|
178
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: "LayoutGrid", size: "xs" })
|
|
179
|
+
}
|
|
180
|
+
),
|
|
181
|
+
/* @__PURE__ */ jsx(
|
|
182
|
+
Button,
|
|
183
|
+
{
|
|
184
|
+
variant: viewMode === "list" ? "secondary" : "ghost",
|
|
185
|
+
size: "sm",
|
|
186
|
+
onClick: () => setViewMode("list"),
|
|
187
|
+
"aria-label": "List view",
|
|
188
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: "List", size: "xs" })
|
|
189
|
+
}
|
|
190
|
+
)
|
|
191
|
+
] })
|
|
192
|
+
] }),
|
|
193
|
+
/* @__PURE__ */ jsx(AnimatePresence, { children: isFiltersOpen && /* @__PURE__ */ jsxs(
|
|
194
|
+
motion.div,
|
|
195
|
+
{
|
|
196
|
+
initial: { height: 0, opacity: 0 },
|
|
197
|
+
animate: { height: "auto", opacity: 1 },
|
|
198
|
+
exit: { height: 0, opacity: 0 },
|
|
199
|
+
className: "sg:overflow-hidden sg:border sg:rounded-xl sg:p-6 sg:bg-card sg:mb-8 sg:shadow-sm",
|
|
200
|
+
children: [
|
|
201
|
+
/* @__PURE__ */ jsxs("div", { className: "sg:flex sg:justify-between sg:items-center sg:mb-6", children: [
|
|
202
|
+
/* @__PURE__ */ jsx(Heading, { variant: "h4", children: "Filters" }),
|
|
203
|
+
/* @__PURE__ */ jsx(
|
|
204
|
+
IconButton,
|
|
205
|
+
{
|
|
206
|
+
variant: "ghost",
|
|
207
|
+
icon: "X",
|
|
208
|
+
size: "sm",
|
|
209
|
+
"aria-label": "Close filters",
|
|
210
|
+
onClick: () => setIsFiltersOpen(false)
|
|
211
|
+
}
|
|
212
|
+
)
|
|
213
|
+
] }),
|
|
214
|
+
/* @__PURE__ */ jsx(FilterControls, { ...filterProps })
|
|
215
|
+
]
|
|
216
|
+
}
|
|
217
|
+
) }),
|
|
218
|
+
/* @__PURE__ */ jsxs("div", { className: "sg:flex sg:gap-8", children: [
|
|
219
|
+
filterMode === "sidebar" && /* @__PURE__ */ jsx("aside", { className: "sg:hidden sg:md:block sg:w-64 sg:shrink-0", children: /* @__PURE__ */ jsx("div", { className: "sg:sticky sg:top-24 sg:space-y-8", children: /* @__PURE__ */ jsx(FilterControls, { ...filterProps }) }) }),
|
|
220
|
+
/* @__PURE__ */ jsxs("div", { className: "sg:flex-1 sg:min-w-0", children: [
|
|
221
|
+
activeCount > 0 && /* @__PURE__ */ jsxs(
|
|
222
|
+
"div",
|
|
223
|
+
{
|
|
224
|
+
className: cn(
|
|
225
|
+
"sg:flex sg:flex-wrap sg:items-center sg:gap-2 sg:mb-6",
|
|
226
|
+
filterMode === "sidebar" && "sg:md:hidden"
|
|
227
|
+
),
|
|
228
|
+
children: [
|
|
229
|
+
selectedCategories.map((cat) => /* @__PURE__ */ jsxs(
|
|
230
|
+
Badge,
|
|
231
|
+
{
|
|
232
|
+
variant: "default",
|
|
233
|
+
className: "sg:cursor-pointer sg:pr-1",
|
|
234
|
+
onClick: () => toggleCategory(cat),
|
|
235
|
+
children: [
|
|
236
|
+
cat,
|
|
237
|
+
" ",
|
|
238
|
+
/* @__PURE__ */ jsx(Icon, { icon: "X", size: "xs", className: "sg:ml-1" })
|
|
239
|
+
]
|
|
240
|
+
},
|
|
241
|
+
cat
|
|
242
|
+
)),
|
|
243
|
+
!hideAuthorFilter && selectedAuthors.map((author) => /* @__PURE__ */ jsxs(
|
|
244
|
+
Badge,
|
|
245
|
+
{
|
|
246
|
+
variant: "default",
|
|
247
|
+
className: "sg:cursor-pointer sg:pr-1",
|
|
248
|
+
onClick: () => toggleAuthor(author),
|
|
249
|
+
children: [
|
|
250
|
+
author,
|
|
251
|
+
" ",
|
|
252
|
+
/* @__PURE__ */ jsx(Icon, { icon: "X", size: "xs", className: "sg:ml-1" })
|
|
253
|
+
]
|
|
254
|
+
},
|
|
255
|
+
author
|
|
256
|
+
))
|
|
257
|
+
]
|
|
258
|
+
}
|
|
259
|
+
),
|
|
260
|
+
/* @__PURE__ */ jsxs("div", { className: "sg:flex sg:flex-wrap sg:gap-2 sg:items-center sg:justify-between sg:mb-6", children: [
|
|
261
|
+
/* @__PURE__ */ jsxs(Text, { size: "sm", foreground: "muted-foreground", children: [
|
|
262
|
+
"Showing ",
|
|
263
|
+
/* @__PURE__ */ jsx(TextSpan, { fontweight: "medium", children: filtered.length }),
|
|
264
|
+
" ",
|
|
265
|
+
"result",
|
|
266
|
+
filtered.length !== 1 ? "s" : ""
|
|
267
|
+
] }),
|
|
268
|
+
/* @__PURE__ */ jsxs("div", { className: "sg:flex sg:items-center sg:gap-2 sg:flex-wrap", children: [
|
|
269
|
+
/* @__PURE__ */ jsx(
|
|
270
|
+
Text,
|
|
271
|
+
{
|
|
272
|
+
id: "loadmode_dropdown",
|
|
273
|
+
size: "xs",
|
|
274
|
+
foreground: "muted-foreground",
|
|
275
|
+
children: "Load mode:"
|
|
276
|
+
}
|
|
277
|
+
),
|
|
278
|
+
/* @__PURE__ */ jsxs(
|
|
279
|
+
Select,
|
|
280
|
+
{
|
|
281
|
+
value: loadMode,
|
|
282
|
+
onValueChange: (v) => setLoadMode(v),
|
|
283
|
+
children: [
|
|
284
|
+
/* @__PURE__ */ jsx(
|
|
285
|
+
SelectTrigger,
|
|
286
|
+
{
|
|
287
|
+
className: "sg:h-8 sg:w-32 sg:text-[12px]",
|
|
288
|
+
"aria-labelledby": "loadmode_dropdown",
|
|
289
|
+
children: /* @__PURE__ */ jsx(SelectValue, {})
|
|
290
|
+
}
|
|
291
|
+
),
|
|
292
|
+
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
293
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "load-more", children: "Load more" }),
|
|
294
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "pagination", children: "Pagination" })
|
|
295
|
+
] })
|
|
296
|
+
]
|
|
297
|
+
}
|
|
298
|
+
)
|
|
299
|
+
] })
|
|
300
|
+
] }),
|
|
301
|
+
filtered.length === 0 ? /* @__PURE__ */ jsx(
|
|
302
|
+
EmptyState,
|
|
303
|
+
{
|
|
304
|
+
icon: "Search",
|
|
305
|
+
title: "No posts found",
|
|
306
|
+
description: query.trim() ? `No results for "${query}". Try different keywords.` : "No posts match the selected filters.",
|
|
307
|
+
actionLabel: "Clear all filters",
|
|
308
|
+
onAction: clearFilters,
|
|
309
|
+
className: "sg:bg-muted/30 sg:rounded-2xl"
|
|
310
|
+
}
|
|
311
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
312
|
+
/* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsx(
|
|
313
|
+
motion.div,
|
|
314
|
+
{
|
|
315
|
+
initial: { opacity: 0, y: 10 },
|
|
316
|
+
animate: { opacity: 1, y: 0 },
|
|
317
|
+
exit: { opacity: 0, y: -10 },
|
|
318
|
+
transition: { duration: 0.2 },
|
|
319
|
+
className: viewMode === "grid" ? "sg:grid sg:grid-cols-[repeat(auto-fill,minmax(210px,1fr))] sg:gap-8" : "sg:flex sg:flex-col sg:gap-4",
|
|
320
|
+
children: displayed.map(
|
|
321
|
+
(post) => viewMode === "grid" ? /* @__PURE__ */ jsx(
|
|
322
|
+
BlogPostCard,
|
|
323
|
+
{
|
|
324
|
+
id: post.id,
|
|
325
|
+
image: post.primaryImage,
|
|
326
|
+
categories: post.categories,
|
|
327
|
+
date: post.date,
|
|
328
|
+
title: post.title,
|
|
329
|
+
excerpt: post.excerpt
|
|
330
|
+
},
|
|
331
|
+
post.id
|
|
332
|
+
) : /* @__PURE__ */ jsxs(
|
|
333
|
+
Link,
|
|
334
|
+
{
|
|
335
|
+
to: `/posts/${post.id}`,
|
|
336
|
+
variant: "no-decoration",
|
|
337
|
+
className: "sg:group sg:flex sg:gap-5 sg:rounded-xl sg:border sg:bg-card sg:p-4 sg:hover:shadow-lg sg:hover:border-primary/20 sg:transition-all",
|
|
338
|
+
children: [
|
|
339
|
+
/* @__PURE__ */ jsx("div", { className: "sg:w-32 sg:h-32 sg:rounded-lg sg:overflow-hidden sg:shrink-0", children: /* @__PURE__ */ jsx(
|
|
340
|
+
UiImage,
|
|
341
|
+
{
|
|
342
|
+
src: post.primaryImage,
|
|
343
|
+
alt: post.title,
|
|
344
|
+
className: "sg:w-full sg:h-full sg:object-cover sg:transition-transform sg:duration-500 sg:group-hover:scale-110",
|
|
345
|
+
loading: "lazy"
|
|
346
|
+
}
|
|
347
|
+
) }),
|
|
348
|
+
/* @__PURE__ */ jsxs("div", { className: "sg:min-w-0 sg:flex sg:flex-col sg:justify-center", children: [
|
|
349
|
+
/* @__PURE__ */ jsx(
|
|
350
|
+
Heading,
|
|
351
|
+
{
|
|
352
|
+
variant: "h6",
|
|
353
|
+
as: "h5",
|
|
354
|
+
className: "sg:group-hover:text-primary sg:transition-colors sg:line-clamp-1",
|
|
355
|
+
children: post.title
|
|
356
|
+
}
|
|
357
|
+
),
|
|
358
|
+
/* @__PURE__ */ jsx(
|
|
359
|
+
Text,
|
|
360
|
+
{
|
|
361
|
+
size: "sm",
|
|
362
|
+
foreground: "muted-foreground",
|
|
363
|
+
className: "sg:line-clamp-2 sg:mt-1.5",
|
|
364
|
+
children: post.excerpt
|
|
365
|
+
}
|
|
366
|
+
),
|
|
367
|
+
/* @__PURE__ */ jsxs("div", { className: "sg:flex sg:items-center sg:gap-3 sg:mt-3 ", children: [
|
|
368
|
+
/* @__PURE__ */ jsx(TextSpan, { size: "xs", foreground: "muted-foreground", children: post.author }),
|
|
369
|
+
/* @__PURE__ */ jsx("span", { className: "sg:h-1 sg:w-1 sg:rounded-full sg:bg-border" }),
|
|
370
|
+
/* @__PURE__ */ jsx(TextTime, { size: "xs", foreground: "muted-foreground", children: new Date(post.date).toLocaleDateString(
|
|
371
|
+
void 0,
|
|
372
|
+
{
|
|
373
|
+
month: "short",
|
|
374
|
+
day: "numeric",
|
|
375
|
+
year: "numeric"
|
|
376
|
+
}
|
|
377
|
+
) })
|
|
378
|
+
] })
|
|
379
|
+
] })
|
|
380
|
+
]
|
|
381
|
+
},
|
|
382
|
+
post.id
|
|
383
|
+
)
|
|
384
|
+
)
|
|
385
|
+
},
|
|
386
|
+
`${displayed.map((p) => p.id).join(",")}-${viewMode}`
|
|
387
|
+
) }),
|
|
388
|
+
loadMode === "load-more" && hasMore && /* @__PURE__ */ jsx("div", { className: "sg:mt-12 sg:text-center", children: /* @__PURE__ */ jsx(
|
|
389
|
+
Button,
|
|
390
|
+
{
|
|
391
|
+
variant: "outline",
|
|
392
|
+
size: "lg",
|
|
393
|
+
onClick: () => setLoadMoreCount((c) => c + PAGE_SIZE),
|
|
394
|
+
children: "Load more stories"
|
|
395
|
+
}
|
|
396
|
+
) }),
|
|
397
|
+
loadMode === "pagination" && totalPages > 1 && /* @__PURE__ */ jsxs("div", { className: "sg:mt-12 sg:flex sg:items-center sg:justify-center sg:gap-2", children: [
|
|
398
|
+
/* @__PURE__ */ jsx(
|
|
399
|
+
Button,
|
|
400
|
+
{
|
|
401
|
+
variant: "outline",
|
|
402
|
+
size: "sm",
|
|
403
|
+
disabled: currentPage <= 1,
|
|
404
|
+
onClick: () => setCurrentPage((p) => p - 1),
|
|
405
|
+
children: "Previous"
|
|
406
|
+
}
|
|
407
|
+
),
|
|
408
|
+
/* @__PURE__ */ jsx("div", { className: "sg:flex sg:gap-1.5", children: Array.from({ length: totalPages }, (_, i) => i + 1).map(
|
|
409
|
+
(page) => /* @__PURE__ */ jsx(
|
|
410
|
+
Button,
|
|
411
|
+
{
|
|
412
|
+
variant: page === currentPage ? "default" : "ghost",
|
|
413
|
+
size: "sm",
|
|
414
|
+
onClick: () => setCurrentPage(page),
|
|
415
|
+
children: page
|
|
416
|
+
},
|
|
417
|
+
page
|
|
418
|
+
)
|
|
419
|
+
) }),
|
|
420
|
+
/* @__PURE__ */ jsx(
|
|
421
|
+
Button,
|
|
422
|
+
{
|
|
423
|
+
variant: "outline",
|
|
424
|
+
size: "sm",
|
|
425
|
+
disabled: currentPage >= totalPages,
|
|
426
|
+
onClick: () => setCurrentPage((p) => p + 1),
|
|
427
|
+
children: "Next"
|
|
428
|
+
}
|
|
429
|
+
)
|
|
430
|
+
] })
|
|
431
|
+
] })
|
|
432
|
+
] })
|
|
433
|
+
] })
|
|
434
|
+
] });
|
|
435
|
+
}
|
|
436
|
+
export {
|
|
437
|
+
PostListWithFilters
|
|
438
|
+
};
|
|
439
|
+
//# sourceMappingURL=post-list-with-filters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/blocks/post-list/post-list-with-filters.tsx"],"sourcesContent":["\"use client\";\nimport { useState, useMemo } from \"react\";\nimport { motion, AnimatePresence } from \"framer-motion\";\nimport type { BlogPost } from \"../../../data/posts\";\nimport BlogPostCard from \"../cards/blogpost-card\";\nimport EmptyState from \"../empty-state/EmptyState\";\nimport { Input } from \"../../primitives/forms/input\";\nimport { Button } from \"../../primitives/buttons/button\";\nimport { Badge } from \"../../primitives/badge/badge\";\nimport { Link } from \"../../primitives/link/link\";\nimport { Icon } from \"../../primitives/icon/icon\";\nimport {\n Heading,\n IconButton,\n Text,\n TextSpan,\n TextTime,\n UiImage,\n} from \"../../primitives/index\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../primitives/forms/select\";\nimport { FilterControls } from \"./post-filters\";\nimport { cn } from \"../../../utils/index\";\n\nconst PAGE_SIZE = 6;\n\ntype SortOption = \"newest\" | \"oldest\" | \"a-z\" | \"z-a\";\ntype ViewMode = \"grid\" | \"list\";\ntype LoadMode = \"pagination\" | \"load-more\";\n\ntype FilterMode = \"sidebar\" | \"drawer\";\n\ninterface PostListWithFiltersProps {\n posts: BlogPost[];\n /** Hide the search bar */\n hideSearch?: boolean;\n /** Hide the author filter badges */\n hideAuthorFilter?: boolean;\n /** \"sidebar\" = inline on desktop, sheet on mobile (default). \"drawer\" = always behind a button/sheet. */\n filterMode?: FilterMode;\n /** Default load mode. \"load-more\" (default) or \"pagination\". User can still toggle. */\n defaultLoadMode?: LoadMode;\n}\n\nexport function PostListWithFilters({\n posts: sourcePosts,\n hideSearch = false,\n hideAuthorFilter = false,\n filterMode = \"sidebar\",\n defaultLoadMode = \"load-more\",\n}: PostListWithFiltersProps) {\n const [query, setQuery] = useState(\"\");\n const [selectedCategories, setSelectedCategories] = useState<string[]>([]);\n const [selectedAuthors, setSelectedAuthors] = useState<string[]>([]);\n const [sortBy, setSortBy] = useState<SortOption>(\"newest\");\n const [loadMode, setLoadMode] = useState<LoadMode>(defaultLoadMode);\n const [viewMode, setViewMode] = useState<ViewMode>(\"grid\");\n const [currentPage, setCurrentPage] = useState(1);\n const [loadMoreCount, setLoadMoreCount] = useState(PAGE_SIZE);\n const [isFiltersOpen, setIsFiltersOpen] = useState(false);\n\n const allCategories = useMemo(\n () => Array.from(new Set(sourcePosts.flatMap((p) => p.categories))).sort(),\n [sourcePosts],\n );\n const allAuthors = useMemo(\n () => Array.from(new Set(sourcePosts.map((p) => p.author))).sort(),\n [sourcePosts],\n );\n\n const resetPaging = () => {\n setCurrentPage(1);\n setLoadMoreCount(PAGE_SIZE);\n };\n\n const toggleCategory = (cat: string) => {\n setSelectedCategories((prev) =>\n prev.includes(cat) ? prev.filter((c) => c !== cat) : [...prev, cat],\n );\n resetPaging();\n };\n\n const toggleAuthor = (author: string) => {\n setSelectedAuthors((prev) =>\n prev.includes(author)\n ? prev.filter((a) => a !== author)\n : [...prev, author],\n );\n resetPaging();\n };\n\n const clearFilters = () => {\n setSelectedCategories([]);\n setSelectedAuthors([]);\n setQuery(\"\");\n resetPaging();\n };\n\n const activeCount = selectedCategories.length + selectedAuthors.length;\n\n const filtered = useMemo(() => {\n let result = [...sourcePosts];\n\n if (selectedCategories.length > 0) {\n result = result.filter((p) =>\n selectedCategories.some((cat) => p.categories?.includes(cat)),\n );\n }\n if (selectedAuthors.length > 0) {\n result = result.filter(\n (p) => p.author && selectedAuthors.includes(p.author),\n );\n }\n if (query.trim()) {\n const q = query.toLowerCase();\n result = result.filter(\n (p) =>\n p.title.toLowerCase().includes(q) ||\n p.excerpt.toLowerCase().includes(q) ||\n p.author.toLowerCase().includes(q) ||\n p.categories?.some((c) => c.toLowerCase().includes(q)),\n );\n }\n\n result.sort((a, b) => {\n switch (sortBy) {\n case \"newest\":\n return new Date(b.date).getTime() - new Date(a.date).getTime();\n case \"oldest\":\n return new Date(a.date).getTime() - new Date(b.date).getTime();\n case \"a-z\":\n return a.title.localeCompare(b.title);\n case \"z-a\":\n return b.title.localeCompare(a.title);\n default:\n return 0;\n }\n });\n\n return result;\n }, [query, selectedCategories, selectedAuthors, sortBy, sourcePosts]);\n\n const totalPages = Math.ceil(filtered.length / PAGE_SIZE);\n const displayed =\n loadMode === \"pagination\"\n ? filtered.slice((currentPage - 1) * PAGE_SIZE, currentPage * PAGE_SIZE)\n : filtered.slice(0, loadMoreCount);\n const hasMore = loadMode === \"load-more\" && loadMoreCount < filtered.length;\n\n const filterProps = {\n categories: allCategories,\n authors: allAuthors,\n selectedCategories,\n selectedAuthors,\n toggleCategory,\n toggleAuthor,\n clearFilters,\n activeCount,\n sortBy,\n setSortBy,\n hideAuthorFilter,\n };\n\n return (\n <div className=\"sg:w-full\">\n {/* Search bar */}\n {!hideSearch && (\n <div className=\"sg:relative sg:mb-8 sg:max-w-lg\">\n <div className=\"sg:absolute sg:left-3 sg:top-1/2 sg:-translate-y-1/2 sg:pointer-events-none\">\n <Icon icon=\"Search\" size=\"xs\" color=\"muted-foreground\" />\n </div>\n <Input\n placeholder=\"Search posts...\"\n value={query}\n onChange={(e) => {\n setQuery(e.target.value);\n resetPaging();\n }}\n className=\"sg:pl-9\"\n />\n </div>\n )}\n\n {/* Toolbar */}\n <div className=\"sg:flex sg:flex-wrap sg:items-center sg:gap-3 sg:mb-6\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n className={cn(\n \"sg:relative\",\n filterMode === \"sidebar\" && \"sg:md:hidden\",\n )}\n onClick={() => setIsFiltersOpen(!isFiltersOpen)}\n iconStart=\"ListFilter\"\n >\n Filters\n {activeCount > 0 && (\n <>\n <TextSpan\n size=\"xs\"\n foreground=\"primary-foreground\"\n className=\"sg:absolute sg:-top-1.5 sg:-right-1.5 sg:h-4 sg:w-4 sg:rounded-full sg:bg-primary sg:flex sg:items-center sg:justify-center\"\n >\n {activeCount}\n </TextSpan>\n </>\n )}\n </Button>\n\n <div className=\"sg:flex-1\" />\n\n <div className=\"sg:flex sg:gap-1 sg:bg-muted/50 sg:p-1 sg:rounded-lg sg:border\">\n <Button\n variant={viewMode === \"grid\" ? \"secondary\" : \"ghost\"}\n size=\"sm\"\n onClick={() => setViewMode(\"grid\")}\n aria-label=\"Grid view\"\n >\n <Icon icon=\"LayoutGrid\" size=\"xs\" />\n </Button>\n <Button\n variant={viewMode === \"list\" ? \"secondary\" : \"ghost\"}\n size=\"sm\"\n onClick={() => setViewMode(\"list\")}\n aria-label=\"List view\"\n >\n <Icon icon=\"List\" size=\"xs\" />\n </Button>\n </div>\n </div>\n\n {/* Mobile Filters Collapsible */}\n <AnimatePresence>\n {isFiltersOpen && (\n <motion.div\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: \"auto\", opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n className=\"sg:overflow-hidden sg:border sg:rounded-xl sg:p-6 sg:bg-card sg:mb-8 sg:shadow-sm\"\n >\n <div className=\"sg:flex sg:justify-between sg:items-center sg:mb-6\">\n <Heading variant=\"h4\">Filters</Heading>\n <IconButton\n variant=\"ghost\"\n icon=\"X\"\n size=\"sm\"\n aria-label=\"Close filters\"\n onClick={() => setIsFiltersOpen(false)}\n />\n </div>\n <FilterControls {...filterProps} />\n </motion.div>\n )}\n </AnimatePresence>\n\n <div className=\"sg:flex sg:gap-8\">\n {/* Desktop sidebar filters */}\n {filterMode === \"sidebar\" && (\n <aside className=\"sg:hidden sg:md:block sg:w-64 sg:shrink-0\">\n <div className=\"sg:sticky sg:top-24 sg:space-y-8\">\n <FilterControls {...filterProps} />\n </div>\n </aside>\n )}\n\n {/* Results */}\n <div className=\"sg:flex-1 sg:min-w-0\">\n {activeCount > 0 && (\n <div\n className={cn(\n \"sg:flex sg:flex-wrap sg:items-center sg:gap-2 sg:mb-6\",\n filterMode === \"sidebar\" && \"sg:md:hidden\",\n )}\n >\n {selectedCategories.map((cat) => (\n <Badge\n key={cat}\n variant=\"default\"\n className=\"sg:cursor-pointer sg:pr-1\"\n onClick={() => toggleCategory(cat)}\n >\n {cat} <Icon icon=\"X\" size=\"xs\" className=\"sg:ml-1\" />\n </Badge>\n ))}\n {!hideAuthorFilter &&\n selectedAuthors.map((author) => (\n <Badge\n key={author}\n variant=\"default\"\n className=\"sg:cursor-pointer sg:pr-1\"\n onClick={() => toggleAuthor(author)}\n >\n {author} <Icon icon=\"X\" size=\"xs\" className=\"sg:ml-1\" />\n </Badge>\n ))}\n </div>\n )}\n\n <div className=\"sg:flex sg:flex-wrap sg:gap-2 sg:items-center sg:justify-between sg:mb-6\">\n <Text size=\"sm\" foreground=\"muted-foreground\">\n Showing <TextSpan fontweight=\"medium\">{filtered.length}</TextSpan>{\" \"}\n result{filtered.length !== 1 ? \"s\" : \"\"}\n </Text>\n <div className=\"sg:flex sg:items-center sg:gap-2 sg:flex-wrap\">\n <Text\n id=\"loadmode_dropdown\"\n size=\"xs\"\n foreground=\"muted-foreground\"\n >\n Load mode:\n </Text>\n <Select\n value={loadMode}\n onValueChange={(v) => setLoadMode(v as LoadMode)}\n >\n <SelectTrigger\n className=\"sg:h-8 sg:w-32 sg:text-[12px]\"\n aria-labelledby=\"loadmode_dropdown\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"load-more\">Load more</SelectItem>\n <SelectItem value=\"pagination\">Pagination</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {filtered.length === 0 ? (\n <EmptyState\n icon=\"Search\"\n title=\"No posts found\"\n description={\n query.trim()\n ? `No results for \"${query}\". Try different keywords.`\n : \"No posts match the selected filters.\"\n }\n actionLabel=\"Clear all filters\"\n onAction={clearFilters}\n className=\"sg:bg-muted/30 sg:rounded-2xl\"\n />\n ) : (\n <>\n <AnimatePresence mode=\"wait\">\n <motion.div\n key={`${displayed.map((p) => p.id).join(\",\")}-${viewMode}`}\n initial={{ opacity: 0, y: 10 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -10 }}\n transition={{ duration: 0.2 }}\n className={\n viewMode === \"grid\"\n ? \"sg:grid sg:grid-cols-[repeat(auto-fill,minmax(210px,1fr))] sg:gap-8\"\n : \"sg:flex sg:flex-col sg:gap-4\"\n }\n >\n {displayed.map((post) =>\n viewMode === \"grid\" ? (\n <BlogPostCard\n key={post.id}\n id={post.id}\n image={post.primaryImage}\n categories={post.categories}\n date={post.date}\n title={post.title}\n excerpt={post.excerpt}\n />\n ) : (\n <Link\n key={post.id}\n to={`/posts/${post.id}`}\n variant=\"no-decoration\"\n className=\"sg:group sg:flex sg:gap-5 sg:rounded-xl sg:border sg:bg-card sg:p-4 sg:hover:shadow-lg sg:hover:border-primary/20 sg:transition-all\"\n >\n <div className=\"sg:w-32 sg:h-32 sg:rounded-lg sg:overflow-hidden sg:shrink-0\">\n <UiImage\n src={post.primaryImage}\n alt={post.title}\n className=\"sg:w-full sg:h-full sg:object-cover sg:transition-transform sg:duration-500 sg:group-hover:scale-110\"\n loading=\"lazy\"\n />\n </div>\n <div className=\"sg:min-w-0 sg:flex sg:flex-col sg:justify-center\">\n <Heading\n variant=\"h6\"\n as=\"h5\"\n className=\"sg:group-hover:text-primary sg:transition-colors sg:line-clamp-1\"\n >\n {post.title}\n </Heading>\n <Text\n size=\"sm\"\n foreground=\"muted-foreground\"\n className=\"sg:line-clamp-2 sg:mt-1.5\"\n >\n {post.excerpt}\n </Text>\n <div className=\"sg:flex sg:items-center sg:gap-3 sg:mt-3 \">\n <TextSpan size=\"xs\" foreground=\"muted-foreground\">\n {post.author}\n </TextSpan>\n <span className=\"sg:h-1 sg:w-1 sg:rounded-full sg:bg-border\" />\n <TextTime size=\"xs\" foreground=\"muted-foreground\">\n {new Date(post.date).toLocaleDateString(\n undefined,\n {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n },\n )}\n </TextTime>\n </div>\n </div>\n </Link>\n ),\n )}\n </motion.div>\n </AnimatePresence>\n\n {loadMode === \"load-more\" && hasMore && (\n <div className=\"sg:mt-12 sg:text-center\">\n <Button\n variant=\"outline\"\n size=\"lg\"\n onClick={() => setLoadMoreCount((c) => c + PAGE_SIZE)}\n >\n Load more stories\n </Button>\n </div>\n )}\n\n {loadMode === \"pagination\" && totalPages > 1 && (\n <div className=\"sg:mt-12 sg:flex sg:items-center sg:justify-center sg:gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={currentPage <= 1}\n onClick={() => setCurrentPage((p) => p - 1)}\n >\n Previous\n </Button>\n <div className=\"sg:flex sg:gap-1.5\">\n {Array.from({ length: totalPages }, (_, i) => i + 1).map(\n (page) => (\n <Button\n key={page}\n variant={page === currentPage ? \"default\" : \"ghost\"}\n size=\"sm\"\n onClick={() => setCurrentPage(page)}\n >\n {page}\n </Button>\n ),\n )}\n </div>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={currentPage >= totalPages}\n onClick={() => setCurrentPage((p) => p + 1)}\n >\n Next\n </Button>\n </div>\n )}\n </>\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,38 +1,68 @@
|
|
|
1
|
+
export { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './blocks/cards/card.js';
|
|
2
|
+
export { PostListWithFilters } from './blocks/post-list/post-list-with-filters.js';
|
|
3
|
+
export { AdminPage, AdminPageProps } from './pages/admin/admin-page.js';
|
|
4
|
+
export { BlogPost } from './pages/blogpost/blogpost.js';
|
|
5
|
+
export { CategoryPage } from './pages/category/category-page.js';
|
|
6
|
+
export { LoginPage } from './pages/login/login-page.js';
|
|
7
|
+
export { MaintenancePage } from './pages/maintenance/maintenance-page.js';
|
|
8
|
+
export { NotFound } from './pages/not-found/not-found.js';
|
|
9
|
+
export { PrivacyPage } from './pages/privacy/privacy-page.js';
|
|
10
|
+
export { SearchPage } from './pages/search/search-page.js';
|
|
11
|
+
export { StartPage } from './pages/startpage/startpage.js';
|
|
12
|
+
export { TermsPage } from './pages/terms/terms-page.js';
|
|
1
13
|
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from './primitives/accordion/accordion.js';
|
|
2
14
|
export { Alert, AlertAction, AlertDescription, AlertTitle, alertVariants } from './primitives/alert/alert.js';
|
|
3
15
|
export { Badge, badgeVariants, badgeVariantsProps } from './primitives/badge/badge.js';
|
|
4
16
|
export { Badges, BadgesProps } from './primitives/badge/badges.js';
|
|
5
|
-
export { Button, buttonVariants, buttonVariantsProps } from './primitives/
|
|
17
|
+
export { Button, buttonVariants, buttonVariantsProps } from './primitives/buttons/button.js';
|
|
18
|
+
export { IconButton, buttonIconVariants, iconButtonVariantsProps } from './primitives/buttons/icon-button.js';
|
|
19
|
+
export { LinkButton } from './primitives/buttons/link-button.js';
|
|
20
|
+
export { Collapsible, CollapsibleContent, CollapsibleTrigger } from './primitives/collapsible/collapsible.js';
|
|
21
|
+
export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from './primitives/dropdown-menu/dropdown-menu.js';
|
|
22
|
+
export { Checkbox } from './primitives/forms/checkbox.js';
|
|
23
|
+
export { Input } from './primitives/forms/input.js';
|
|
24
|
+
export { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue } from './primitives/forms/select.js';
|
|
25
|
+
export { Textarea } from './primitives/forms/textarea.js';
|
|
6
26
|
export { Icon, iconVariants, iconVariantsProps } from './primitives/icon/icon.js';
|
|
27
|
+
export { Label } from './primitives/label/label.js';
|
|
7
28
|
export { Layout, LayoutProps, layoutVariants, layoutVariantsProps } from './primitives/layout/layout.js';
|
|
8
29
|
export { Link, linkVariants } from './primitives/link/link.js';
|
|
9
|
-
export { LinkButton } from './primitives/link/link-button.js';
|
|
10
30
|
export { Separator } from './primitives/separator/separator.js';
|
|
31
|
+
export { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger } from './primitives/sheet/sheet.js';
|
|
11
32
|
export { Skeleton } from './primitives/skeleton/skeleton.js';
|
|
33
|
+
export { Toaster } from './primitives/sonner/sonner.js';
|
|
12
34
|
export { Spinner } from './primitives/spinner/spinner.js';
|
|
13
35
|
export { Stack, StackProps, stackVariants } from './primitives/stack/stack.js';
|
|
36
|
+
export { Heading, HeadingProps, headingVariants, headingVariantsProps } from './primitives/text/heading.js';
|
|
37
|
+
export { TextCode, TextCodeProps, textCodeVariants, textCodeVariantsProps } from './primitives/text/text-code.js';
|
|
14
38
|
export { TextDiv } from './primitives/text/text-div.js';
|
|
15
|
-
export { TextHeading, TextHeadingProps, textHeadingVariants, textHeadingVariantsProps } from './primitives/text/text-heading.js';
|
|
16
|
-
export { TextParagraph, textParagraphVariants, textParagraphVariantsProps } from './primitives/text/text-paragraph.js';
|
|
17
39
|
export { TextSpan } from './primitives/text/text-span.js';
|
|
18
40
|
export { TextTime } from './primitives/text/text-time.js';
|
|
19
|
-
export {
|
|
20
|
-
export {
|
|
21
|
-
export {
|
|
22
|
-
export { Body } from './sections/body/body.js';
|
|
23
|
-
export { BlogPost } from './templates/blogpost/blogpost.js';
|
|
24
|
-
export { StartPage } from './templates/startpage/startpage.js';
|
|
41
|
+
export { Text, textVariants, textVariantsProps } from './primitives/text/text.js';
|
|
42
|
+
export { UiImage } from './primitives/ui-image/ui-image.js';
|
|
43
|
+
export { UiLink } from './primitives/ui-link/ui-link.js';
|
|
25
44
|
export { BaseImageProps, DefaultImage, ImageComponentType, ImageProvider, useImage } from './providers/ImageContext.js';
|
|
26
45
|
export { BaseLinkProps, DefaultLink, LinkComponentType, LinkProvider, useLink } from './providers/LinkContext.js';
|
|
27
46
|
export { SingularityProvider } from './providers/SingularityContext.js';
|
|
47
|
+
export { AuthProvider, useAuth } from './providers/auth-provider.js';
|
|
48
|
+
export { Theme, ThemeProvider, ThemeProviderProps, ThemeProviderState, useTheme } from './providers/theme-provider.js';
|
|
49
|
+
export { Container } from './templates/container/container.js';
|
|
50
|
+
export { Footer } from './templates/footer/footer.js';
|
|
51
|
+
export { Header, HeaderProps, NavLink } from './templates/navigation/header.js';
|
|
52
|
+
export { toast } from 'sonner';
|
|
28
53
|
import 'react/jsx-runtime';
|
|
54
|
+
import 'react';
|
|
55
|
+
import '../data/posts.js';
|
|
29
56
|
import '@base-ui/react/accordion';
|
|
30
57
|
import 'class-variance-authority/types';
|
|
31
|
-
import 'react';
|
|
32
58
|
import 'class-variance-authority';
|
|
33
59
|
import '@base-ui/react/use-render';
|
|
34
60
|
import '@base-ui/react/button';
|
|
35
61
|
import 'lucide-react';
|
|
62
|
+
import '@radix-ui/react-collapsible';
|
|
63
|
+
import '@radix-ui/react-dropdown-menu';
|
|
64
|
+
import '@base-ui/react';
|
|
36
65
|
import '@base-ui/react/separator';
|
|
37
|
-
import '
|
|
66
|
+
import '@radix-ui/react-dialog';
|
|
38
67
|
import './primitives/text/internal/text-element.js';
|
|
68
|
+
import '../lib/types.js';
|
package/dist/components/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
export * from "./
|
|
2
|
-
export * from "./
|
|
3
|
-
export * from "./
|
|
4
|
-
export * from "./
|
|
5
|
-
export * from "./templates";
|
|
6
|
-
export * from "./providers";
|
|
1
|
+
export * from "./blocks/index.js";
|
|
2
|
+
export * from "./pages/index.js";
|
|
3
|
+
export * from "./primitives/index.js";
|
|
4
|
+
export * from "./providers/index.js";
|
|
5
|
+
export * from "./templates/index.js";
|
|
7
6
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/index.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"sources":["../../src/components/index.ts"],"sourcesContent":["/**\n * Components index\n *\n * Please keep exports sorted alphabetically by path!\n */\n\nexport * from \"./blocks/index\";\nexport * from \"./pages/index\";\nexport * from \"./primitives/index\";\nexport * from \"./providers/index\";\nexport * from \"./templates/index\";\n"],"mappings":"AAMA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|