singularity-components 0.1.195 → 0.1.197
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/components/blocks/badges/category-badge.d.ts +11 -0
- package/dist/components/blocks/badges/category-badge.js +34 -0
- package/dist/components/blocks/badges/category-badge.js.map +1 -0
- package/dist/components/blocks/cards/blogpost-card.d.ts +3 -1
- package/dist/components/blocks/cards/blogpost-card.js +10 -5
- package/dist/components/blocks/cards/blogpost-card.js.map +1 -1
- package/dist/components/blocks/directory/author-card.d.ts +10 -0
- package/dist/components/blocks/directory/author-card.js +50 -0
- package/dist/components/blocks/directory/author-card.js.map +1 -0
- package/dist/components/blocks/directory/category-card.d.ts +10 -0
- package/dist/components/blocks/directory/category-card.js +27 -0
- package/dist/components/blocks/directory/category-card.js.map +1 -0
- package/dist/components/blocks/extras/extras-hub-card.d.ts +16 -0
- package/dist/components/blocks/extras/extras-hub-card.js +22 -0
- package/dist/components/blocks/extras/extras-hub-card.js.map +1 -0
- package/dist/components/blocks/gallery/image-gallery.d.ts +14 -0
- package/dist/components/blocks/gallery/image-gallery.js +211 -0
- package/dist/components/blocks/gallery/image-gallery.js.map +1 -0
- package/dist/components/blocks/index.d.ts +11 -0
- package/dist/components/blocks/index.js +10 -0
- package/dist/components/blocks/index.js.map +1 -1
- package/dist/components/blocks/loading/loading-skeletons.d.ts +15 -0
- package/dist/components/blocks/loading/loading-skeletons.js +78 -0
- package/dist/components/blocks/loading/loading-skeletons.js.map +1 -0
- package/dist/components/blocks/login/login.js +76 -47
- package/dist/components/blocks/login/login.js.map +1 -1
- package/dist/components/blocks/marketing/page-hero.d.ts +13 -0
- package/dist/components/blocks/marketing/page-hero.js +37 -0
- package/dist/components/blocks/marketing/page-hero.js.map +1 -0
- package/dist/components/blocks/marketing/stats-grid.d.ts +16 -0
- package/dist/components/blocks/marketing/stats-grid.js +30 -0
- package/dist/components/blocks/marketing/stats-grid.js.map +1 -0
- package/dist/components/blocks/marketing/timeline.d.ts +17 -0
- package/dist/components/blocks/marketing/timeline.js +46 -0
- package/dist/components/blocks/marketing/timeline.js.map +1 -0
- package/dist/components/blocks/marketing/values-grid.d.ts +16 -0
- package/dist/components/blocks/marketing/values-grid.js +29 -0
- package/dist/components/blocks/marketing/values-grid.js.map +1 -0
- package/dist/components/blocks/post-list/post-list-with-filters.js +4 -4
- package/dist/components/blocks/post-list/post-list-with-filters.js.map +1 -1
- package/dist/components/index.d.ts +28 -1
- package/dist/components/pages/about/about-page.d.ts +5 -0
- package/dist/components/pages/about/about-page.js +161 -0
- package/dist/components/pages/about/about-page.js.map +1 -0
- package/dist/components/pages/admin/admin-page.js +160 -103
- package/dist/components/pages/admin/admin-page.js.map +1 -1
- package/dist/components/pages/author/author-page.d.ts +8 -0
- package/dist/components/pages/author/author-page.js +107 -0
- package/dist/components/pages/author/author-page.js.map +1 -0
- package/dist/components/pages/authors/authors-page.d.ts +5 -0
- package/dist/components/pages/authors/authors-page.js +25 -0
- package/dist/components/pages/authors/authors-page.js.map +1 -0
- package/dist/components/pages/blogpost/blogpost.d.ts +4 -1
- package/dist/components/pages/blogpost/blogpost.js +110 -62
- package/dist/components/pages/blogpost/blogpost.js.map +1 -1
- package/dist/components/pages/categories/categories-page.d.ts +5 -0
- package/dist/components/pages/categories/categories-page.js +33 -0
- package/dist/components/pages/categories/categories-page.js.map +1 -0
- package/dist/components/pages/category/category-page.js +4 -2
- package/dist/components/pages/category/category-page.js.map +1 -1
- package/dist/components/pages/chat/chat-page.js +4 -4
- package/dist/components/pages/chat/chat-page.js.map +1 -1
- package/dist/components/pages/contact/contact-page.d.ts +5 -0
- package/dist/components/pages/contact/contact-page.js +180 -0
- package/dist/components/pages/contact/contact-page.js.map +1 -0
- package/dist/components/pages/content-blocks/content-blocks-page.d.ts +5 -0
- package/dist/components/pages/content-blocks/content-blocks-page.js +87 -0
- package/dist/components/pages/content-blocks/content-blocks-page.js.map +1 -0
- package/dist/components/pages/extras/extras-hub-page.d.ts +10 -0
- package/dist/components/pages/extras/extras-hub-page.js +110 -0
- package/dist/components/pages/extras/extras-hub-page.js.map +1 -0
- package/dist/components/pages/index.d.ts +14 -0
- package/dist/components/pages/index.js +12 -0
- package/dist/components/pages/index.js.map +1 -1
- package/dist/components/pages/maintenance/maintenance-page.js +1 -1
- package/dist/components/pages/maintenance/maintenance-page.js.map +1 -1
- package/dist/components/pages/membership/membership-page.d.ts +5 -0
- package/dist/components/pages/membership/membership-page.js +131 -0
- package/dist/components/pages/membership/membership-page.js.map +1 -0
- package/dist/components/pages/mosaic/mosaic-page.d.ts +5 -0
- package/dist/components/pages/mosaic/mosaic-page.js +81 -0
- package/dist/components/pages/mosaic/mosaic-page.js.map +1 -0
- package/dist/components/pages/newsletter/newsletter-page.d.ts +5 -0
- package/dist/components/pages/newsletter/newsletter-page.js +165 -0
- package/dist/components/pages/newsletter/newsletter-page.js.map +1 -0
- package/dist/components/pages/not-found/not-found.js +2 -2
- package/dist/components/pages/not-found/not-found.js.map +1 -1
- package/dist/components/pages/privacy/privacy-page.js +2 -2
- package/dist/components/pages/privacy/privacy-page.js.map +1 -1
- package/dist/components/pages/resources/resources-page.d.ts +5 -0
- package/dist/components/pages/resources/resources-page.js +24 -0
- package/dist/components/pages/resources/resources-page.js.map +1 -0
- package/dist/components/pages/startpage/startpage.js +6 -4
- package/dist/components/pages/startpage/startpage.js.map +1 -1
- package/dist/components/pages/terms/terms-page.js +2 -2
- package/dist/components/pages/terms/terms-page.js.map +1 -1
- package/dist/components/primitives/accordion/accordion.js +14 -16
- package/dist/components/primitives/accordion/accordion.js.map +1 -1
- package/dist/components/primitives/badge/badge.js +1 -1
- package/dist/components/primitives/badge/badge.js.map +1 -1
- package/dist/components/primitives/buttons/button.d.ts +2 -2
- package/dist/components/primitives/buttons/icon-button.d.ts +1 -1
- package/dist/components/primitives/collapsible/collapsible.js +4 -1
- package/dist/components/primitives/collapsible/collapsible.js.map +1 -1
- package/dist/components/primitives/dropdown-menu/dropdown-menu.js +6 -1
- package/dist/components/primitives/dropdown-menu/dropdown-menu.js.map +1 -1
- package/dist/components/primitives/forms/checkbox.js +1 -1
- package/dist/components/primitives/forms/checkbox.js.map +1 -1
- package/dist/components/primitives/forms/field.d.ts +4 -2
- package/dist/components/primitives/forms/field.js +4 -2
- package/dist/components/primitives/forms/field.js.map +1 -1
- package/dist/components/primitives/forms/form-control.d.ts +28 -0
- package/dist/components/primitives/forms/form-control.js +40 -0
- package/dist/components/primitives/forms/form-control.js.map +1 -0
- package/dist/components/primitives/forms/form.d.ts +12 -0
- package/dist/components/primitives/forms/form.js +30 -0
- package/dist/components/primitives/forms/form.js.map +1 -0
- package/dist/components/primitives/forms/select.js +12 -12
- package/dist/components/primitives/forms/select.js.map +1 -1
- package/dist/components/primitives/icon/icon.d.ts +3 -2
- package/dist/components/primitives/icon/icon.js +2 -1
- package/dist/components/primitives/icon/icon.js.map +1 -1
- package/dist/components/primitives/index.d.ts +4 -0
- package/dist/components/primitives/index.js +3 -0
- package/dist/components/primitives/index.js.map +1 -1
- package/dist/components/primitives/layout/layout.d.ts +1 -1
- package/dist/components/primitives/link/link.d.ts +2 -2
- package/dist/components/primitives/sheet/sheet.js +1 -1
- package/dist/components/primitives/sheet/sheet.js.map +1 -1
- package/dist/components/primitives/stack/stack.d.ts +2 -2
- package/dist/components/primitives/text/internal/text-element.d.ts +8 -2
- package/dist/components/primitives/text/internal/text-element.js +3 -0
- package/dist/components/primitives/text/internal/text-element.js.map +1 -1
- package/dist/components/primitives/text/text-code.d.ts +1 -1
- package/dist/components/templates/form/form.d.ts +2 -2
- package/dist/components/templates/form/form.js +133 -87
- package/dist/components/templates/form/form.js.map +1 -1
- package/dist/components/templates/hero/hero.js +1 -0
- package/dist/components/templates/hero/hero.js.map +1 -1
- package/dist/components/templates/index.d.ts +1 -0
- package/dist/components/templates/index.js +1 -0
- package/dist/components/templates/index.js.map +1 -1
- package/dist/components/templates/loading-screen/loading-screen.d.ts +10 -0
- package/dist/components/templates/loading-screen/loading-screen.js +39 -0
- package/dist/components/templates/loading-screen/loading-screen.js.map +1 -0
- package/dist/css/variables.css +6 -3
- package/dist/css/variables.css.map +1 -1
- package/dist/data/posts.d.ts +5 -0
- package/dist/data/posts.js +41 -8
- package/dist/data/posts.js.map +1 -1
- package/dist/index.d.ts +28 -1
- package/dist/lib/forms/field-props.d.ts +60 -0
- package/dist/lib/forms/field-props.js +60 -0
- package/dist/lib/forms/field-props.js.map +1 -0
- package/dist/lib/forms/index.d.ts +11 -0
- package/dist/lib/forms/index.js +3 -0
- package/dist/lib/forms/index.js.map +1 -0
- package/dist/lib/forms/tanstack-field.d.ts +71 -0
- package/dist/lib/forms/tanstack-field.js +121 -0
- package/dist/lib/forms/tanstack-field.js.map +1 -0
- package/dist/lib/index.d.ts +11 -0
- package/dist/lib/index.js +1 -0
- package/dist/lib/index.js.map +1 -1
- package/dist/main.css +393 -90
- package/dist/main.css.map +1 -1
- package/package.json +30 -23
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
type Props = {
|
|
4
|
+
category: string;
|
|
5
|
+
clickable?: boolean;
|
|
6
|
+
className?: string;
|
|
7
|
+
};
|
|
8
|
+
/** Badge for post categories, optionally linking to a category page. */
|
|
9
|
+
declare function CategoryBadge({ category, clickable, className, }: Props): React.JSX.Element;
|
|
10
|
+
|
|
11
|
+
export { CategoryBadge as default };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Badge } from "../../primitives/badge/badge.js";
|
|
3
|
+
import { Link } from "../../primitives/link/link.js";
|
|
4
|
+
import { cn } from "../../../utils/index.js";
|
|
5
|
+
function CategoryBadge({
|
|
6
|
+
category,
|
|
7
|
+
clickable = false,
|
|
8
|
+
className
|
|
9
|
+
}) {
|
|
10
|
+
if (clickable) {
|
|
11
|
+
return /* @__PURE__ */ jsx(
|
|
12
|
+
Link,
|
|
13
|
+
{
|
|
14
|
+
to: `/category/${encodeURIComponent(category)}`,
|
|
15
|
+
variant: "no-decoration",
|
|
16
|
+
className: cn("sg:inline-flex", className),
|
|
17
|
+
onClick: (e) => e.stopPropagation(),
|
|
18
|
+
children: /* @__PURE__ */ jsx(
|
|
19
|
+
Badge,
|
|
20
|
+
{
|
|
21
|
+
variant: "secondary",
|
|
22
|
+
className: "sg:cursor-pointer sg:hover:bg-primary sg:hover:text-primary-foreground sg:transition-colors",
|
|
23
|
+
children: category
|
|
24
|
+
}
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
return /* @__PURE__ */ jsx(Badge, { variant: "secondary", className, children: category });
|
|
30
|
+
}
|
|
31
|
+
export {
|
|
32
|
+
CategoryBadge as default
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=category-badge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/blocks/badges/category-badge.tsx"],"sourcesContent":["import { Badge } from \"../../primitives/badge/badge\";\r\nimport { Link } from \"../../primitives/link/link\";\r\nimport { cn } from \"../../../utils/index\";\r\n\r\ntype Props = {\r\n\tcategory: string;\r\n\tclickable?: boolean;\r\n\tclassName?: string;\r\n};\r\n\r\n/** Badge for post categories, optionally linking to a category page. */\r\nexport default function CategoryBadge({\r\n\tcategory,\r\n\tclickable = false,\r\n\tclassName,\r\n}: Props) {\r\n\tif (clickable) {\r\n\t\treturn (\r\n\t\t\t<Link\r\n\t\t\t\tto={`/category/${encodeURIComponent(category)}`}\r\n\t\t\t\tvariant=\"no-decoration\"\r\n\t\t\t\tclassName={cn(\"sg:inline-flex\", className)}\r\n\t\t\t\tonClick={(e: React.MouseEvent) => e.stopPropagation()}\r\n\t\t\t>\r\n\t\t\t\t<Badge\r\n\t\t\t\t\tvariant=\"secondary\"\r\n\t\t\t\t\tclassName=\"sg:cursor-pointer sg:hover:bg-primary sg:hover:text-primary-foreground sg:transition-colors\"\r\n\t\t\t\t>\r\n\t\t\t\t\t{category}\r\n\t\t\t\t</Badge>\r\n\t\t\t</Link>\r\n\t\t);\r\n\t}\r\n\r\n\treturn (\r\n\t\t<Badge variant=\"secondary\" className={className}>\r\n\t\t\t{category}\r\n\t\t</Badge>\r\n\t);\r\n}\r\n"],"mappings":"AAwBI;AAxBJ,SAAS,aAAa;AACtB,SAAS,YAAY;AACrB,SAAS,UAAU;AASJ,SAAR,cAA+B;AAAA,EACrC;AAAA,EACA,YAAY;AAAA,EACZ;AACD,GAAU;AACT,MAAI,WAAW;AACd,WACC;AAAA,MAAC;AAAA;AAAA,QACA,IAAI,aAAa,mBAAmB,QAAQ,CAAC;AAAA,QAC7C,SAAQ;AAAA,QACR,WAAW,GAAG,kBAAkB,SAAS;AAAA,QACzC,SAAS,CAAC,MAAwB,EAAE,gBAAgB;AAAA,QAEpD;AAAA,UAAC;AAAA;AAAA,YACA,SAAQ;AAAA,YACR,WAAU;AAAA,YAET;AAAA;AAAA,QACF;AAAA;AAAA,IACD;AAAA,EAEF;AAEA,SACC,oBAAC,SAAM,SAAQ,aAAY,WACzB,oBACF;AAEF;","names":[]}
|
|
@@ -2,12 +2,14 @@ import * as React from 'react';
|
|
|
2
2
|
|
|
3
3
|
interface Props {
|
|
4
4
|
id: number;
|
|
5
|
+
slug?: string;
|
|
5
6
|
image: string;
|
|
6
7
|
categories: string[];
|
|
7
8
|
date: string;
|
|
8
9
|
title: string;
|
|
9
10
|
excerpt: string;
|
|
11
|
+
clickableCategories?: boolean;
|
|
10
12
|
}
|
|
11
|
-
declare function BlogPostCard({ id, image, title, categories, date, excerpt, }: Props): React.JSX.Element;
|
|
13
|
+
declare function BlogPostCard({ id, slug, image, title, categories, date, excerpt, clickableCategories, }: Props): React.JSX.Element;
|
|
12
14
|
|
|
13
15
|
export { BlogPostCard as default };
|
|
@@ -7,22 +7,25 @@ import {
|
|
|
7
7
|
Text,
|
|
8
8
|
TextSpan,
|
|
9
9
|
Badges,
|
|
10
|
-
Badge,
|
|
11
10
|
Icon,
|
|
12
11
|
UiImage
|
|
13
12
|
} from "../../primitives/index.js";
|
|
13
|
+
import CategoryBadge from "../badges/category-badge.js";
|
|
14
14
|
function BlogPostCard({
|
|
15
15
|
id,
|
|
16
|
+
slug,
|
|
16
17
|
image,
|
|
17
18
|
title,
|
|
18
19
|
categories,
|
|
19
20
|
date,
|
|
20
|
-
excerpt
|
|
21
|
+
excerpt,
|
|
22
|
+
clickableCategories = false
|
|
21
23
|
}) {
|
|
24
|
+
const postPath = slug ? `/posts/${slug}` : `/posts/${id}`;
|
|
22
25
|
return /* @__PURE__ */ jsx(
|
|
23
26
|
Link,
|
|
24
27
|
{
|
|
25
|
-
to:
|
|
28
|
+
to: postPath,
|
|
26
29
|
variant: "no-decoration",
|
|
27
30
|
className: "sg:group sg:block sg:h-full",
|
|
28
31
|
children: /* @__PURE__ */ jsxs(Card, { className: "sg:overflow-hidden sg:transition-shadow sg:hover:shadow-lg sg:h-full sg:flex sg:flex-col", children: [
|
|
@@ -35,8 +38,10 @@ function BlogPostCard({
|
|
|
35
38
|
loading: "lazy"
|
|
36
39
|
}
|
|
37
40
|
) }),
|
|
38
|
-
/* @__PURE__ */ jsxs(CardContent, { className: "sg:p-5 sg:flex sg:flex-col sg:grow", children: [
|
|
39
|
-
categories && categories.length > 0 && /* @__PURE__ */ jsx(Badges, { className: "sg:mb-2", children: categories.map(
|
|
41
|
+
/* @__PURE__ */ jsxs(CardContent, { className: "sg:p-5 sg:flex sg:flex-col sg:grow sg:text-card-foreground", children: [
|
|
42
|
+
categories && categories.length > 0 && /* @__PURE__ */ jsx(Badges, { className: "sg:mb-2", children: categories.map(
|
|
43
|
+
(cat) => clickableCategories ? /* @__PURE__ */ jsx(CategoryBadge, { category: cat, clickable: true }, cat) : /* @__PURE__ */ jsx(CategoryBadge, { category: cat }, cat)
|
|
44
|
+
) }),
|
|
40
45
|
/* @__PURE__ */ jsx(TextTime, { size: "xs", foreground: "muted-foreground", children: date }),
|
|
41
46
|
/* @__PURE__ */ jsx(
|
|
42
47
|
Heading,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/components/blocks/cards/blogpost-card.tsx"],"sourcesContent":["import { Card, CardContent } from \"./card\";\r\nimport { Link } from \"../../primitives/link/link\";\r\nimport {\r\n TextTime,\r\n Heading,\r\n Text,\r\n TextSpan,\r\n Badges,\r\n
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/blocks/cards/blogpost-card.tsx"],"sourcesContent":["import { Card, CardContent } from \"./card\";\r\nimport { Link } from \"../../primitives/link/link\";\r\nimport {\r\n TextTime,\r\n Heading,\r\n Text,\r\n TextSpan,\r\n Badges,\r\n Icon,\r\n UiImage,\r\n} from \"../../primitives/index\";\r\nimport CategoryBadge from \"../badges/category-badge\";\r\n\r\ninterface Props {\r\n id: number;\r\n slug?: string;\r\n image: string;\r\n categories: string[];\r\n date: string;\r\n title: string;\r\n excerpt: string;\r\n clickableCategories?: boolean;\r\n}\r\n\r\nexport default function BlogPostCard({\r\n id,\r\n slug,\r\n image,\r\n title,\r\n categories,\r\n date,\r\n excerpt,\r\n clickableCategories = false,\r\n}: Props) {\r\n const postPath = slug ? `/posts/${slug}` : `/posts/${id}`;\r\n\r\n return (\r\n <Link\r\n to={postPath}\r\n variant=\"no-decoration\"\r\n className=\"sg:group sg:block sg:h-full\"\r\n >\r\n <Card className=\"sg:overflow-hidden sg:transition-shadow sg:hover:shadow-lg sg:h-full sg:flex sg:flex-col\">\r\n <div className=\"sg:aspect-16/10 sg:overflow-hidden\">\r\n <UiImage\r\n src={image}\r\n alt={title}\r\n className=\"sg:h-full sg:w-full sg:object-cover sg:transition-transform sg:duration-300 sg:group-hover:scale-105\"\r\n loading=\"lazy\"\r\n />\r\n </div>\r\n <CardContent className=\"sg:p-5 sg:flex sg:flex-col sg:grow sg:text-card-foreground\">\r\n {categories && categories.length > 0 && (\r\n <Badges className=\"sg:mb-2\">\r\n {categories.map((cat) =>\r\n clickableCategories ? (\r\n <CategoryBadge key={cat} category={cat} clickable />\r\n ) : (\r\n <CategoryBadge key={cat} category={cat} />\r\n ),\r\n )}\r\n </Badges>\r\n )}\r\n <TextTime size=\"xs\" foreground=\"muted-foreground\">\r\n {date}\r\n </TextTime>\r\n <Heading\r\n variant=\"h6\"\r\n as=\"h3\"\r\n className=\"sg:mt-1 sg:group-hover:text-primary sg:transition-colors\"\r\n >\r\n {title}\r\n </Heading>\r\n <Text\r\n size=\"sm\"\r\n foreground=\"muted-foreground\"\r\n className=\"sg:mt-2 sg:line-clamp-2\"\r\n >\r\n {excerpt}\r\n </Text>\r\n <TextSpan\r\n size=\"sm\"\r\n foreground=\"primary\"\r\n className=\"sg:mt-auto sg:pt-3 sg:inline-flex sg:items-center sg:gap-1\"\r\n >\r\n Read more <Icon icon=\"ArrowRight\" size=\"xs\" />\r\n </TextSpan>\r\n </CardContent>\r\n </Card>\r\n </Link>\r\n );\r\n}\r\n"],"mappings":"AA4CU,cAoCA,YApCA;AA5CV,SAAS,MAAM,mBAAmB;AAClC,SAAS,YAAY;AACrB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,OAAO,mBAAmB;AAaX,SAAR,aAA8B;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,sBAAsB;AACxB,GAAU;AACR,QAAM,WAAW,OAAO,UAAU,IAAI,KAAK,UAAU,EAAE;AAEvD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,IAAI;AAAA,MACJ,SAAQ;AAAA,MACR,WAAU;AAAA,MAEV,+BAAC,QAAK,WAAU,4FACd;AAAA,4BAAC,SAAI,WAAU,sCACb;AAAA,UAAC;AAAA;AAAA,YACC,KAAK;AAAA,YACL,KAAK;AAAA,YACL,WAAU;AAAA,YACV,SAAQ;AAAA;AAAA,QACV,GACF;AAAA,QACA,qBAAC,eAAY,WAAU,8DACpB;AAAA,wBAAc,WAAW,SAAS,KACjC,oBAAC,UAAO,WAAU,WACf,qBAAW;AAAA,YAAI,CAAC,QACf,sBACE,oBAAC,iBAAwB,UAAU,KAAK,WAAS,QAA7B,GAA8B,IAElD,oBAAC,iBAAwB,UAAU,OAAf,GAAoB;AAAA,UAE5C,GACF;AAAA,UAEF,oBAAC,YAAS,MAAK,MAAK,YAAW,oBAC5B,gBACH;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,SAAQ;AAAA,cACR,IAAG;AAAA,cACH,WAAU;AAAA,cAET;AAAA;AAAA,UACH;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,YAAW;AAAA,cACX,WAAU;AAAA,cAET;AAAA;AAAA,UACH;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,YAAW;AAAA,cACX,WAAU;AAAA,cACX;AAAA;AAAA,gBACW,oBAAC,QAAK,MAAK,cAAa,MAAK,MAAK;AAAA;AAAA;AAAA,UAC9C;AAAA,WACF;AAAA,SACF;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Author } from '../../../data/authors.js';
|
|
3
|
+
|
|
4
|
+
type Props = {
|
|
5
|
+
author: Author;
|
|
6
|
+
};
|
|
7
|
+
/** Author list card linking to author profile page. */
|
|
8
|
+
declare function AuthorCard({ author }: Props): React.JSX.Element;
|
|
9
|
+
|
|
10
|
+
export { AuthorCard };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { posts } from "../../../data/posts.js";
|
|
3
|
+
import {
|
|
4
|
+
Avatar,
|
|
5
|
+
AvatarFallback,
|
|
6
|
+
AvatarImage
|
|
7
|
+
} from "../../primitives/avatar/avatar.js";
|
|
8
|
+
import { Card, CardContent, CardTitle, CardDescription } from "../cards/card.js";
|
|
9
|
+
import CategoryBadge from "../badges/category-badge.js";
|
|
10
|
+
import { Badge } from "../../primitives/badge/badge.js";
|
|
11
|
+
import { Link } from "../../primitives/link/link.js";
|
|
12
|
+
import { Text } from "../../primitives/index.js";
|
|
13
|
+
function AuthorCard({ author }) {
|
|
14
|
+
const postCount = posts.filter((p) => p.author === author.name).length;
|
|
15
|
+
return /* @__PURE__ */ jsx(
|
|
16
|
+
Link,
|
|
17
|
+
{
|
|
18
|
+
to: `/extras/authors/${author.slug}`,
|
|
19
|
+
variant: "no-decoration",
|
|
20
|
+
className: "sg:group sg:block",
|
|
21
|
+
children: /* @__PURE__ */ jsx(Card, { className: "sg:transition-shadow sg:hover:shadow-lg sg:hover:border-primary/40", children: /* @__PURE__ */ jsx(CardContent, { className: "sg:p-6", children: /* @__PURE__ */ jsxs("div", { className: "sg:flex sg:items-start sg:gap-4", children: [
|
|
22
|
+
/* @__PURE__ */ jsxs(Avatar, { className: "sg:h-14 sg:w-14 sg:shrink-0", children: [
|
|
23
|
+
/* @__PURE__ */ jsx(AvatarImage, { src: author.avatar, alt: author.name }),
|
|
24
|
+
/* @__PURE__ */ jsx(AvatarFallback, { children: author.name.split(" ").map((n) => n[0]).join("") })
|
|
25
|
+
] }),
|
|
26
|
+
/* @__PURE__ */ jsxs("div", { className: "sg:flex-1 sg:min-w-0", children: [
|
|
27
|
+
/* @__PURE__ */ jsx(CardTitle, { className: "sg:text-xl sg:group-hover:text-primary sg:transition-colors", children: author.name }),
|
|
28
|
+
/* @__PURE__ */ jsxs(Text, { size: "sm", foreground: "muted-foreground", className: "sg:mt-0.5", children: [
|
|
29
|
+
author.role,
|
|
30
|
+
" \xB7 ",
|
|
31
|
+
author.location
|
|
32
|
+
] }),
|
|
33
|
+
/* @__PURE__ */ jsx(CardDescription, { className: "sg:mt-2 sg:line-clamp-2", children: author.bio }),
|
|
34
|
+
/* @__PURE__ */ jsxs("div", { className: "sg:flex sg:items-center sg:gap-2 sg:mt-3 sg:flex-wrap", children: [
|
|
35
|
+
/* @__PURE__ */ jsxs(Badge, { variant: "secondary", children: [
|
|
36
|
+
postCount,
|
|
37
|
+
" post",
|
|
38
|
+
postCount !== 1 ? "s" : ""
|
|
39
|
+
] }),
|
|
40
|
+
author.interests.slice(0, 3).map((interest) => /* @__PURE__ */ jsx(CategoryBadge, { category: interest }, interest))
|
|
41
|
+
] })
|
|
42
|
+
] })
|
|
43
|
+
] }) }) })
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
AuthorCard
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=author-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/blocks/directory/author-card.tsx"],"sourcesContent":["import type { Author } from \"../../../data/authors\";\r\nimport { posts } from \"../../../data/posts\";\r\nimport {\r\n\tAvatar,\r\n\tAvatarFallback,\r\n\tAvatarImage,\r\n} from \"../../primitives/avatar/avatar\";\r\nimport { Card, CardContent, CardTitle, CardDescription } from \"../cards/card\";\r\nimport CategoryBadge from \"../badges/category-badge\";\r\nimport { Badge } from \"../../primitives/badge/badge\";\r\nimport { Link } from \"../../primitives/link/link\";\r\nimport { Text } from \"../../primitives/index\";\r\n\r\ntype Props = {\r\n\tauthor: Author;\r\n};\r\n\r\n/** Author list card linking to author profile page. */\r\nexport function AuthorCard({ author }: Props) {\r\n\tconst postCount = posts.filter((p) => p.author === author.name).length;\r\n\r\n\treturn (\r\n\t\t<Link\r\n\t\t\tto={`/extras/authors/${author.slug}`}\r\n\t\t\tvariant=\"no-decoration\"\r\n\t\t\tclassName=\"sg:group sg:block\"\r\n\t\t>\r\n\t\t\t<Card className=\"sg:transition-shadow sg:hover:shadow-lg sg:hover:border-primary/40\">\r\n\t\t\t\t<CardContent className=\"sg:p-6\">\r\n\t\t\t\t\t<div className=\"sg:flex sg:items-start sg:gap-4\">\r\n\t\t\t\t\t\t<Avatar className=\"sg:h-14 sg:w-14 sg:shrink-0\">\r\n\t\t\t\t\t\t\t<AvatarImage src={author.avatar} alt={author.name} />\r\n\t\t\t\t\t\t\t<AvatarFallback>\r\n\t\t\t\t\t\t\t\t{author.name\r\n\t\t\t\t\t\t\t\t\t.split(\" \")\r\n\t\t\t\t\t\t\t\t\t.map((n) => n[0])\r\n\t\t\t\t\t\t\t\t\t.join(\"\")}\r\n\t\t\t\t\t\t\t</AvatarFallback>\r\n\t\t\t\t\t\t</Avatar>\r\n\t\t\t\t\t\t<div className=\"sg:flex-1 sg:min-w-0\">\r\n\t\t\t\t\t\t\t<CardTitle className=\"sg:text-xl sg:group-hover:text-primary sg:transition-colors\">\r\n\t\t\t\t\t\t\t\t{author.name}\r\n\t\t\t\t\t\t\t</CardTitle>\r\n\t\t\t\t\t\t\t<Text size=\"sm\" foreground=\"muted-foreground\" className=\"sg:mt-0.5\">\r\n\t\t\t\t\t\t\t\t{author.role} · {author.location}\r\n\t\t\t\t\t\t\t</Text>\r\n\t\t\t\t\t\t\t<CardDescription className=\"sg:mt-2 sg:line-clamp-2\">\r\n\t\t\t\t\t\t\t\t{author.bio}\r\n\t\t\t\t\t\t\t</CardDescription>\r\n\t\t\t\t\t\t\t<div className=\"sg:flex sg:items-center sg:gap-2 sg:mt-3 sg:flex-wrap\">\r\n\t\t\t\t\t\t\t\t<Badge variant=\"secondary\">\r\n\t\t\t\t\t\t\t\t\t{postCount} post{postCount !== 1 ? \"s\" : \"\"}\r\n\t\t\t\t\t\t\t\t</Badge>\r\n\t\t\t\t\t\t\t\t{author.interests.slice(0, 3).map((interest) => (\r\n\t\t\t\t\t\t\t\t\t<CategoryBadge key={interest} category={interest} />\r\n\t\t\t\t\t\t\t\t))}\r\n\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</CardContent>\r\n\t\t\t</Card>\r\n\t\t</Link>\r\n\t);\r\n}\r\n"],"mappings":"AA8BM,SACC,KADD;AA7BN,SAAS,aAAa;AACtB;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,MAAM,aAAa,WAAW,uBAAuB;AAC9D,OAAO,mBAAmB;AAC1B,SAAS,aAAa;AACtB,SAAS,YAAY;AACrB,SAAS,YAAY;AAOd,SAAS,WAAW,EAAE,OAAO,GAAU;AAC7C,QAAM,YAAY,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO,IAAI,EAAE;AAEhE,SACC;AAAA,IAAC;AAAA;AAAA,MACA,IAAI,mBAAmB,OAAO,IAAI;AAAA,MAClC,SAAQ;AAAA,MACR,WAAU;AAAA,MAEV,8BAAC,QAAK,WAAU,sEACf,8BAAC,eAAY,WAAU,UACtB,+BAAC,SAAI,WAAU,mCACd;AAAA,6BAAC,UAAO,WAAU,+BACjB;AAAA,8BAAC,eAAY,KAAK,OAAO,QAAQ,KAAK,OAAO,MAAM;AAAA,UACnD,oBAAC,kBACC,iBAAO,KACN,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,EACf,KAAK,EAAE,GACV;AAAA,WACD;AAAA,QACA,qBAAC,SAAI,WAAU,wBACd;AAAA,8BAAC,aAAU,WAAU,+DACnB,iBAAO,MACT;AAAA,UACA,qBAAC,QAAK,MAAK,MAAK,YAAW,oBAAmB,WAAU,aACtD;AAAA,mBAAO;AAAA,YAAK;AAAA,YAAI,OAAO;AAAA,aACzB;AAAA,UACA,oBAAC,mBAAgB,WAAU,2BACzB,iBAAO,KACT;AAAA,UACA,qBAAC,SAAI,WAAU,yDACd;AAAA,iCAAC,SAAM,SAAQ,aACb;AAAA;AAAA,cAAU;AAAA,cAAM,cAAc,IAAI,MAAM;AAAA,eAC1C;AAAA,YACC,OAAO,UAAU,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,aAClC,oBAAC,iBAA6B,UAAU,YAApB,QAA8B,CAClD;AAAA,aACF;AAAA,WACD;AAAA,SACD,GACD,GACD;AAAA;AAAA,EACD;AAEF;","names":[]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Card, CardContent, CardTitle, CardDescription } from "../cards/card.js";
|
|
3
|
+
import { Badge } from "../../primitives/badge/badge.js";
|
|
4
|
+
import { Link } from "../../primitives/link/link.js";
|
|
5
|
+
import { Stack } from "../../primitives/stack/stack.js";
|
|
6
|
+
function CategoryCard({ name, count }) {
|
|
7
|
+
return /* @__PURE__ */ jsx(
|
|
8
|
+
Link,
|
|
9
|
+
{
|
|
10
|
+
to: `/category/${encodeURIComponent(name)}`,
|
|
11
|
+
variant: "no-decoration",
|
|
12
|
+
className: "sg:group sg:block",
|
|
13
|
+
children: /* @__PURE__ */ jsx(Card, { className: "sg:transition-shadow sg:hover:shadow-lg sg:hover:border-primary/40", children: /* @__PURE__ */ jsx(CardContent, { className: "sg:p-6", children: /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
14
|
+
/* @__PURE__ */ jsx(CardTitle, { className: "sg:text-xl sg:group-hover:text-primary sg:transition-colors", children: name }),
|
|
15
|
+
/* @__PURE__ */ jsx(CardDescription, { children: /* @__PURE__ */ jsxs(Badge, { variant: "secondary", children: [
|
|
16
|
+
count,
|
|
17
|
+
" post",
|
|
18
|
+
count !== 1 ? "s" : ""
|
|
19
|
+
] }) })
|
|
20
|
+
] }) }) })
|
|
21
|
+
}
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
CategoryCard
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=category-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/blocks/directory/category-card.tsx"],"sourcesContent":["import { Card, CardContent, CardTitle, CardDescription } from \"../cards/card\";\r\nimport { Badge } from \"../../primitives/badge/badge\";\r\nimport { Link } from \"../../primitives/link/link\";\r\nimport { Stack } from \"../../primitives/stack/stack\";\r\n\r\ntype Props = {\r\n\tname: string;\r\n\tcount: number;\r\n};\r\n\r\n/** Category index card linking to category page. */\r\nexport function CategoryCard({ name, count }: Props) {\r\n\treturn (\r\n\t\t<Link\r\n\t\t\tto={`/category/${encodeURIComponent(name)}`}\r\n\t\t\tvariant=\"no-decoration\"\r\n\t\t\tclassName=\"sg:group sg:block\"\r\n\t\t>\r\n\t\t\t<Card className=\"sg:transition-shadow sg:hover:shadow-lg sg:hover:border-primary/40\">\r\n\t\t\t\t<CardContent className=\"sg:p-6\">\r\n\t\t\t\t\t<Stack gap={2}>\r\n\t\t\t\t\t\t<CardTitle className=\"sg:text-xl sg:group-hover:text-primary sg:transition-colors\">\r\n\t\t\t\t\t\t\t{name}\r\n\t\t\t\t\t\t</CardTitle>\r\n\t\t\t\t\t\t<CardDescription>\r\n\t\t\t\t\t\t\t<Badge variant=\"secondary\">\r\n\t\t\t\t\t\t\t\t{count} post{count !== 1 ? \"s\" : \"\"}\r\n\t\t\t\t\t\t\t</Badge>\r\n\t\t\t\t\t\t</CardDescription>\r\n\t\t\t\t\t</Stack>\r\n\t\t\t\t</CardContent>\r\n\t\t\t</Card>\r\n\t\t</Link>\r\n\t);\r\n}\r\n"],"mappings":"AAqBM,cAIC,YAJD;AArBN,SAAS,MAAM,aAAa,WAAW,uBAAuB;AAC9D,SAAS,aAAa;AACtB,SAAS,YAAY;AACrB,SAAS,aAAa;AAQf,SAAS,aAAa,EAAE,MAAM,MAAM,GAAU;AACpD,SACC;AAAA,IAAC;AAAA;AAAA,MACA,IAAI,aAAa,mBAAmB,IAAI,CAAC;AAAA,MACzC,SAAQ;AAAA,MACR,WAAU;AAAA,MAEV,8BAAC,QAAK,WAAU,sEACf,8BAAC,eAAY,WAAU,UACtB,+BAAC,SAAM,KAAK,GACX;AAAA,4BAAC,aAAU,WAAU,+DACnB,gBACF;AAAA,QACA,oBAAC,mBACA,+BAAC,SAAM,SAAQ,aACb;AAAA;AAAA,UAAM;AAAA,UAAM,UAAU,IAAI,MAAM;AAAA,WAClC,GACD;AAAA,SACD,GACD,GACD;AAAA;AAAA,EACD;AAEF;","names":[]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { icons } from 'lucide-react';
|
|
3
|
+
|
|
4
|
+
type ExtrasHubItem = {
|
|
5
|
+
title: string;
|
|
6
|
+
description: string;
|
|
7
|
+
to: string;
|
|
8
|
+
icon: keyof typeof icons;
|
|
9
|
+
};
|
|
10
|
+
type Props = {
|
|
11
|
+
item: ExtrasHubItem;
|
|
12
|
+
};
|
|
13
|
+
/** Linked card for the extras hub index page. */
|
|
14
|
+
declare function ExtrasHubCard({ item }: Props): React.JSX.Element;
|
|
15
|
+
|
|
16
|
+
export { ExtrasHubCard, type ExtrasHubItem };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Card, CardContent, CardTitle, CardDescription } from "../cards/card.js";
|
|
3
|
+
import { Icon } from "../../primitives/icon/icon.js";
|
|
4
|
+
import { Link } from "../../primitives/link/link.js";
|
|
5
|
+
import { Stack } from "../../primitives/stack/stack.js";
|
|
6
|
+
function ExtrasHubCard({ item }) {
|
|
7
|
+
return /* @__PURE__ */ jsx(Link, { to: item.to, variant: "no-decoration", className: "sg:group sg:block", children: /* @__PURE__ */ jsx(Card, { className: "sg:transition-shadow sg:hover:shadow-lg sg:hover:border-primary/40", children: /* @__PURE__ */ jsx(CardContent, { className: "sg:p-6", children: /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
|
|
8
|
+
/* @__PURE__ */ jsx(
|
|
9
|
+
Icon,
|
|
10
|
+
{
|
|
11
|
+
icon: item.icon,
|
|
12
|
+
className: "sg:h-6 sg:w-6 sg:text-primary"
|
|
13
|
+
}
|
|
14
|
+
),
|
|
15
|
+
/* @__PURE__ */ jsx(CardTitle, { className: "sg:group-hover:text-primary sg:transition-colors", children: item.title }),
|
|
16
|
+
/* @__PURE__ */ jsx(CardDescription, { children: item.description })
|
|
17
|
+
] }) }) }) });
|
|
18
|
+
}
|
|
19
|
+
export {
|
|
20
|
+
ExtrasHubCard
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=extras-hub-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/blocks/extras/extras-hub-card.tsx"],"sourcesContent":["import type { icons } from \"lucide-react\";\r\nimport { Card, CardContent, CardTitle, CardDescription } from \"../cards/card\";\r\nimport { Icon } from \"../../primitives/icon/icon\";\r\nimport { Link } from \"../../primitives/link/link\";\r\nimport { Stack } from \"../../primitives/stack/stack\";\r\n\r\nexport type ExtrasHubItem = {\r\n\ttitle: string;\r\n\tdescription: string;\r\n\tto: string;\r\n\ticon: keyof typeof icons;\r\n};\r\n\r\ntype Props = {\r\n\titem: ExtrasHubItem;\r\n};\r\n\r\n/** Linked card for the extras hub index page. */\r\nexport function ExtrasHubCard({ item }: Props) {\r\n\treturn (\r\n\t\t<Link to={item.to} variant=\"no-decoration\" className=\"sg:group sg:block\">\r\n\t\t\t<Card className=\"sg:transition-shadow sg:hover:shadow-lg sg:hover:border-primary/40\">\r\n\t\t\t\t<CardContent className=\"sg:p-6\">\r\n\t\t\t\t\t<Stack gap={2}>\r\n\t\t\t\t\t\t<Icon\r\n\t\t\t\t\t\t\ticon={item.icon}\r\n\t\t\t\t\t\t\tclassName=\"sg:h-6 sg:w-6 sg:text-primary\"\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t<CardTitle className=\"sg:group-hover:text-primary sg:transition-colors\">\r\n\t\t\t\t\t\t\t{item.title}\r\n\t\t\t\t\t\t</CardTitle>\r\n\t\t\t\t\t\t<CardDescription>{item.description}</CardDescription>\r\n\t\t\t\t\t</Stack>\r\n\t\t\t\t</CardContent>\r\n\t\t\t</Card>\r\n\t\t</Link>\r\n\t);\r\n}\r\n"],"mappings":"AAuBK,SACC,KADD;AAtBL,SAAS,MAAM,aAAa,WAAW,uBAAuB;AAC9D,SAAS,YAAY;AACrB,SAAS,YAAY;AACrB,SAAS,aAAa;AAcf,SAAS,cAAc,EAAE,KAAK,GAAU;AAC9C,SACC,oBAAC,QAAK,IAAI,KAAK,IAAI,SAAQ,iBAAgB,WAAU,qBACpD,8BAAC,QAAK,WAAU,sEACf,8BAAC,eAAY,WAAU,UACtB,+BAAC,SAAM,KAAK,GACX;AAAA;AAAA,MAAC;AAAA;AAAA,QACA,MAAM,KAAK;AAAA,QACX,WAAU;AAAA;AAAA,IACX;AAAA,IACA,oBAAC,aAAU,WAAU,oDACnB,eAAK,OACP;AAAA,IACA,oBAAC,mBAAiB,eAAK,aAAY;AAAA,KACpC,GACD,GACD,GACD;AAEF;","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
type GalleryImage = {
|
|
4
|
+
src: string;
|
|
5
|
+
alt?: string;
|
|
6
|
+
};
|
|
7
|
+
type Props = {
|
|
8
|
+
images: GalleryImage[];
|
|
9
|
+
className?: string;
|
|
10
|
+
};
|
|
11
|
+
/** Multi-image viewer with single, carousel, and grid modes plus lightbox. */
|
|
12
|
+
declare function ImageGallery({ images, className }: Props): React.JSX.Element | null;
|
|
13
|
+
|
|
14
|
+
export { type GalleryImage, ImageGallery as default };
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { IconButton, Text, UiImage } from "../../primitives/index.js";
|
|
5
|
+
import {
|
|
6
|
+
Sheet,
|
|
7
|
+
SheetContent,
|
|
8
|
+
SheetTitle
|
|
9
|
+
} from "../../primitives/sheet/sheet.js";
|
|
10
|
+
import { cn } from "../../../utils/index.js";
|
|
11
|
+
function gridCols(count) {
|
|
12
|
+
if (count <= 2) return "sg:grid-cols-1 sm:sg:grid-cols-2";
|
|
13
|
+
if (count <= 4) return "sg:grid-cols-2 sm:sg:grid-cols-2 md:sg:grid-cols-4";
|
|
14
|
+
if (count <= 6) return "sg:grid-cols-2 sm:sg:grid-cols-3";
|
|
15
|
+
return "sg:grid-cols-2 sm:sg:grid-cols-3 md:sg:grid-cols-4";
|
|
16
|
+
}
|
|
17
|
+
function ImageGallery({ images, className }) {
|
|
18
|
+
const [viewMode, setViewMode] = useState(
|
|
19
|
+
images.length <= 1 ? "single" : "grid"
|
|
20
|
+
);
|
|
21
|
+
const [currentIndex, setCurrentIndex] = useState(0);
|
|
22
|
+
const [lightboxOpen, setLightboxOpen] = useState(false);
|
|
23
|
+
const [lightboxIndex, setLightboxIndex] = useState(0);
|
|
24
|
+
if (!images.length) return null;
|
|
25
|
+
const prev = () => setCurrentIndex((i) => (i - 1 + images.length) % images.length);
|
|
26
|
+
const next = () => setCurrentIndex((i) => (i + 1) % images.length);
|
|
27
|
+
const openLightbox = (index) => {
|
|
28
|
+
setLightboxIndex(index);
|
|
29
|
+
setLightboxOpen(true);
|
|
30
|
+
};
|
|
31
|
+
const modes = [
|
|
32
|
+
{ value: "single", icon: "Image", label: "Single image" },
|
|
33
|
+
{ value: "carousel", icon: "Images", label: "Carousel" },
|
|
34
|
+
{ value: "grid", icon: "Grid2x2", label: "Grid" }
|
|
35
|
+
];
|
|
36
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("sg:space-y-4", className), children: [
|
|
37
|
+
images.length > 1 && /* @__PURE__ */ jsxs("div", { className: "sg:flex sg:items-center sg:justify-between", children: [
|
|
38
|
+
/* @__PURE__ */ jsxs(Text, { size: "sm", foreground: "muted-foreground", children: [
|
|
39
|
+
images.length,
|
|
40
|
+
" image",
|
|
41
|
+
images.length !== 1 ? "s" : ""
|
|
42
|
+
] }),
|
|
43
|
+
/* @__PURE__ */ jsx("div", { className: "sg:flex sg:gap-1", children: modes.map((mode) => /* @__PURE__ */ jsx(
|
|
44
|
+
IconButton,
|
|
45
|
+
{
|
|
46
|
+
icon: mode.icon,
|
|
47
|
+
variant: viewMode === mode.value ? "default" : "outline",
|
|
48
|
+
size: "sm",
|
|
49
|
+
"aria-label": mode.label,
|
|
50
|
+
"aria-pressed": viewMode === mode.value,
|
|
51
|
+
onClick: () => setViewMode(mode.value)
|
|
52
|
+
},
|
|
53
|
+
mode.value
|
|
54
|
+
)) })
|
|
55
|
+
] }),
|
|
56
|
+
viewMode === "single" && /* @__PURE__ */ jsx(
|
|
57
|
+
"button",
|
|
58
|
+
{
|
|
59
|
+
type: "button",
|
|
60
|
+
className: "sg:w-full sg:rounded-lg sg:overflow-hidden sg:cursor-pointer sg:border-0 sg:p-0 sg:bg-transparent",
|
|
61
|
+
onClick: () => openLightbox(currentIndex),
|
|
62
|
+
children: /* @__PURE__ */ jsx(
|
|
63
|
+
UiImage,
|
|
64
|
+
{
|
|
65
|
+
src: images[currentIndex].src,
|
|
66
|
+
alt: images[currentIndex].alt || "Gallery image",
|
|
67
|
+
className: "sg:w-full sg:h-56 sm:sg:h-72 md:sg:h-96 sg:object-cover",
|
|
68
|
+
loading: "lazy"
|
|
69
|
+
}
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
),
|
|
73
|
+
viewMode === "carousel" && /* @__PURE__ */ jsxs("div", { className: "sg:relative sg:rounded-lg sg:overflow-hidden sg:group", children: [
|
|
74
|
+
/* @__PURE__ */ jsx(
|
|
75
|
+
"button",
|
|
76
|
+
{
|
|
77
|
+
type: "button",
|
|
78
|
+
className: "sg:w-full sg:border-0 sg:p-0 sg:bg-transparent sg:cursor-pointer",
|
|
79
|
+
onClick: () => openLightbox(currentIndex),
|
|
80
|
+
children: /* @__PURE__ */ jsx(
|
|
81
|
+
UiImage,
|
|
82
|
+
{
|
|
83
|
+
src: images[currentIndex].src,
|
|
84
|
+
alt: images[currentIndex].alt || "Gallery image",
|
|
85
|
+
className: "sg:w-full sg:h-56 sm:sg:h-72 md:sg:h-96 sg:object-cover",
|
|
86
|
+
loading: "lazy"
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
),
|
|
91
|
+
images.length > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
92
|
+
/* @__PURE__ */ jsx(
|
|
93
|
+
IconButton,
|
|
94
|
+
{
|
|
95
|
+
variant: "secondary",
|
|
96
|
+
size: "sm",
|
|
97
|
+
className: "sg:absolute sg:left-3 sg:top-1/2 sg:-translate-y-1/2 sg:opacity-0 sg:group-hover:opacity-100 sg:transition-opacity sg:h-10 sg:w-10 sg:rounded-full sg:shadow-lg",
|
|
98
|
+
onClick: prev,
|
|
99
|
+
icon: "ChevronLeft",
|
|
100
|
+
"aria-label": "Previous image"
|
|
101
|
+
}
|
|
102
|
+
),
|
|
103
|
+
/* @__PURE__ */ jsx(
|
|
104
|
+
IconButton,
|
|
105
|
+
{
|
|
106
|
+
variant: "secondary",
|
|
107
|
+
size: "sm",
|
|
108
|
+
className: "sg:absolute sg:right-3 sg:top-1/2 sg:-translate-y-1/2 sg:opacity-0 sg:group-hover:opacity-100 sg:transition-opacity sg:h-10 sg:w-10 sg:rounded-full sg:shadow-lg",
|
|
109
|
+
onClick: next,
|
|
110
|
+
icon: "ChevronRight",
|
|
111
|
+
"aria-label": "Next image"
|
|
112
|
+
}
|
|
113
|
+
),
|
|
114
|
+
/* @__PURE__ */ jsx("div", { className: "sg:absolute sg:bottom-3 sg:left-1/2 sg:-translate-x-1/2 sg:flex sg:items-center sg:gap-1.5 sg:bg-black/40 sg:backdrop-blur-sm sg:rounded-full sg:px-3 sg:py-1.5", children: images.map((_, i) => /* @__PURE__ */ jsx(
|
|
115
|
+
"button",
|
|
116
|
+
{
|
|
117
|
+
type: "button",
|
|
118
|
+
onClick: () => setCurrentIndex(i),
|
|
119
|
+
className: cn(
|
|
120
|
+
"sg:h-2 sg:rounded-full sg:transition-all sg:border-0 sg:p-0",
|
|
121
|
+
i === currentIndex ? "sg:w-6 sg:bg-white" : "sg:w-2 sg:bg-white/50 hover:sg:bg-white/75"
|
|
122
|
+
),
|
|
123
|
+
"aria-label": `Go to image ${i + 1}`
|
|
124
|
+
},
|
|
125
|
+
i
|
|
126
|
+
)) })
|
|
127
|
+
] })
|
|
128
|
+
] }),
|
|
129
|
+
viewMode === "grid" && /* @__PURE__ */ jsx("div", { className: cn("sg:grid sg:gap-2 sm:sg:gap-3", gridCols(images.length)), children: images.map((img, i) => /* @__PURE__ */ jsx(
|
|
130
|
+
"button",
|
|
131
|
+
{
|
|
132
|
+
type: "button",
|
|
133
|
+
className: "sg:rounded-lg sg:overflow-hidden sg:cursor-pointer sg:group/img sg:border-0 sg:p-0 sg:bg-transparent",
|
|
134
|
+
onClick: () => openLightbox(i),
|
|
135
|
+
children: /* @__PURE__ */ jsx(
|
|
136
|
+
UiImage,
|
|
137
|
+
{
|
|
138
|
+
src: img.src,
|
|
139
|
+
alt: img.alt || `Gallery image ${i + 1}`,
|
|
140
|
+
className: "sg:w-full sg:aspect-4/3 sg:object-cover sg:transition-transform sg:duration-300 sg:group-hover/img:scale-105",
|
|
141
|
+
loading: "lazy"
|
|
142
|
+
}
|
|
143
|
+
)
|
|
144
|
+
},
|
|
145
|
+
i
|
|
146
|
+
)) }),
|
|
147
|
+
/* @__PURE__ */ jsx(Sheet, { open: lightboxOpen, onOpenChange: setLightboxOpen, children: /* @__PURE__ */ jsxs(
|
|
148
|
+
SheetContent,
|
|
149
|
+
{
|
|
150
|
+
side: "bottom",
|
|
151
|
+
className: "sg:max-h-[95vh] sg:overflow-y-auto sg:border-0 sg:p-2 sg:bg-background/95 sg:backdrop-blur-sm",
|
|
152
|
+
children: [
|
|
153
|
+
/* @__PURE__ */ jsx(SheetTitle, { className: "sg:sr-only", children: "Image lightbox" }),
|
|
154
|
+
/* @__PURE__ */ jsxs("div", { className: "sg:relative sg:mx-auto sg:max-w-4xl", children: [
|
|
155
|
+
/* @__PURE__ */ jsx(
|
|
156
|
+
UiImage,
|
|
157
|
+
{
|
|
158
|
+
src: images[lightboxIndex].src,
|
|
159
|
+
alt: images[lightboxIndex].alt || "Gallery image",
|
|
160
|
+
className: "sg:w-full sg:max-h-[80vh] sg:object-contain sg:rounded-md"
|
|
161
|
+
}
|
|
162
|
+
),
|
|
163
|
+
images.length > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
164
|
+
/* @__PURE__ */ jsx(
|
|
165
|
+
IconButton,
|
|
166
|
+
{
|
|
167
|
+
variant: "secondary",
|
|
168
|
+
size: "sm",
|
|
169
|
+
className: "sg:absolute sg:left-2 sg:top-1/2 sg:-translate-y-1/2 sg:h-10 sg:w-10 sg:rounded-full sg:shadow-lg",
|
|
170
|
+
onClick: () => setLightboxIndex(
|
|
171
|
+
(i) => (i - 1 + images.length) % images.length
|
|
172
|
+
),
|
|
173
|
+
icon: "ChevronLeft",
|
|
174
|
+
"aria-label": "Previous image"
|
|
175
|
+
}
|
|
176
|
+
),
|
|
177
|
+
/* @__PURE__ */ jsx(
|
|
178
|
+
IconButton,
|
|
179
|
+
{
|
|
180
|
+
variant: "secondary",
|
|
181
|
+
size: "sm",
|
|
182
|
+
className: "sg:absolute sg:right-2 sg:top-1/2 sg:-translate-y-1/2 sg:h-10 sg:w-10 sg:rounded-full sg:shadow-lg",
|
|
183
|
+
onClick: () => setLightboxIndex((i) => (i + 1) % images.length),
|
|
184
|
+
icon: "ChevronRight",
|
|
185
|
+
"aria-label": "Next image"
|
|
186
|
+
}
|
|
187
|
+
),
|
|
188
|
+
/* @__PURE__ */ jsx("div", { className: "sg:absolute sg:bottom-3 sg:left-1/2 sg:-translate-x-1/2 sg:flex sg:gap-1.5", children: images.map((_, i) => /* @__PURE__ */ jsx(
|
|
189
|
+
"button",
|
|
190
|
+
{
|
|
191
|
+
type: "button",
|
|
192
|
+
onClick: () => setLightboxIndex(i),
|
|
193
|
+
className: cn(
|
|
194
|
+
"sg:h-2 sg:rounded-full sg:transition-all sg:border-0 sg:p-0",
|
|
195
|
+
i === lightboxIndex ? "sg:w-6 sg:bg-primary" : "sg:w-2 sg:bg-muted-foreground/40 hover:sg:bg-muted-foreground/60"
|
|
196
|
+
),
|
|
197
|
+
"aria-label": `Go to image ${i + 1}`
|
|
198
|
+
},
|
|
199
|
+
i
|
|
200
|
+
)) })
|
|
201
|
+
] })
|
|
202
|
+
] })
|
|
203
|
+
]
|
|
204
|
+
}
|
|
205
|
+
) })
|
|
206
|
+
] });
|
|
207
|
+
}
|
|
208
|
+
export {
|
|
209
|
+
ImageGallery as default
|
|
210
|
+
};
|
|
211
|
+
//# sourceMappingURL=image-gallery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/blocks/gallery/image-gallery.tsx"],"sourcesContent":["\"use client\";\r\n\r\nimport { useState } from \"react\";\r\nimport { IconButton, Text, UiImage } from \"../../primitives/index\";\r\nimport {\r\n\tSheet,\r\n\tSheetContent,\r\n\tSheetTitle,\r\n} from \"../../primitives/sheet/sheet\";\r\nimport { cn } from \"../../../utils/index\";\r\n\r\ntype ViewMode = \"single\" | \"carousel\" | \"grid\";\r\n\r\nexport type GalleryImage = { src: string; alt?: string };\r\n\r\ntype Props = {\r\n\timages: GalleryImage[];\r\n\tclassName?: string;\r\n};\r\n\r\nfunction gridCols(count: number) {\r\n\tif (count <= 2) return \"sg:grid-cols-1 sm:sg:grid-cols-2\";\r\n\tif (count <= 4) return \"sg:grid-cols-2 sm:sg:grid-cols-2 md:sg:grid-cols-4\";\r\n\tif (count <= 6) return \"sg:grid-cols-2 sm:sg:grid-cols-3\";\r\n\treturn \"sg:grid-cols-2 sm:sg:grid-cols-3 md:sg:grid-cols-4\";\r\n}\r\n\r\n/** Multi-image viewer with single, carousel, and grid modes plus lightbox. */\r\nexport default function ImageGallery({ images, className }: Props) {\r\n\tconst [viewMode, setViewMode] = useState<ViewMode>(\r\n\t\timages.length <= 1 ? \"single\" : \"grid\",\r\n\t);\r\n\tconst [currentIndex, setCurrentIndex] = useState(0);\r\n\tconst [lightboxOpen, setLightboxOpen] = useState(false);\r\n\tconst [lightboxIndex, setLightboxIndex] = useState(0);\r\n\r\n\tif (!images.length) return null;\r\n\r\n\tconst prev = () =>\r\n\t\tsetCurrentIndex((i) => (i - 1 + images.length) % images.length);\r\n\tconst next = () => setCurrentIndex((i) => (i + 1) % images.length);\r\n\r\n\tconst openLightbox = (index: number) => {\r\n\t\tsetLightboxIndex(index);\r\n\t\tsetLightboxOpen(true);\r\n\t};\r\n\r\n\tconst modes: { value: ViewMode; icon: \"Image\" | \"Images\" | \"Grid2x2\"; label: string }[] =\r\n\t\t[\r\n\t\t\t{ value: \"single\", icon: \"Image\", label: \"Single image\" },\r\n\t\t\t{ value: \"carousel\", icon: \"Images\", label: \"Carousel\" },\r\n\t\t\t{ value: \"grid\", icon: \"Grid2x2\", label: \"Grid\" },\r\n\t\t];\r\n\r\n\treturn (\r\n\t\t<div className={cn(\"sg:space-y-4\", className)}>\r\n\t\t\t{images.length > 1 && (\r\n\t\t\t\t<div className=\"sg:flex sg:items-center sg:justify-between\">\r\n\t\t\t\t\t<Text size=\"sm\" foreground=\"muted-foreground\">\r\n\t\t\t\t\t\t{images.length} image{images.length !== 1 ? \"s\" : \"\"}\r\n\t\t\t\t\t</Text>\r\n\t\t\t\t\t<div className=\"sg:flex sg:gap-1\">\r\n\t\t\t\t\t\t{modes.map((mode) => (\r\n\t\t\t\t\t\t\t<IconButton\r\n\t\t\t\t\t\t\t\tkey={mode.value}\r\n\t\t\t\t\t\t\t\ticon={mode.icon}\r\n\t\t\t\t\t\t\t\tvariant={viewMode === mode.value ? \"default\" : \"outline\"}\r\n\t\t\t\t\t\t\t\tsize=\"sm\"\r\n\t\t\t\t\t\t\t\taria-label={mode.label}\r\n\t\t\t\t\t\t\t\taria-pressed={viewMode === mode.value}\r\n\t\t\t\t\t\t\t\tonClick={() => setViewMode(mode.value)}\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t))}\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\t)}\r\n\r\n\t\t\t{viewMode === \"single\" && (\r\n\t\t\t\t<button\r\n\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\tclassName=\"sg:w-full sg:rounded-lg sg:overflow-hidden sg:cursor-pointer sg:border-0 sg:p-0 sg:bg-transparent\"\r\n\t\t\t\t\tonClick={() => openLightbox(currentIndex)}\r\n\t\t\t\t>\r\n\t\t\t\t\t<UiImage\r\n\t\t\t\t\t\tsrc={images[currentIndex].src}\r\n\t\t\t\t\t\talt={images[currentIndex].alt || \"Gallery image\"}\r\n\t\t\t\t\t\tclassName=\"sg:w-full sg:h-56 sm:sg:h-72 md:sg:h-96 sg:object-cover\"\r\n\t\t\t\t\t\tloading=\"lazy\"\r\n\t\t\t\t\t/>\r\n\t\t\t\t</button>\r\n\t\t\t)}\r\n\r\n\t\t\t{viewMode === \"carousel\" && (\r\n\t\t\t\t<div className=\"sg:relative sg:rounded-lg sg:overflow-hidden sg:group\">\r\n\t\t\t\t\t<button\r\n\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\tclassName=\"sg:w-full sg:border-0 sg:p-0 sg:bg-transparent sg:cursor-pointer\"\r\n\t\t\t\t\t\tonClick={() => openLightbox(currentIndex)}\r\n\t\t\t\t\t>\r\n\t\t\t\t\t\t<UiImage\r\n\t\t\t\t\t\t\tsrc={images[currentIndex].src}\r\n\t\t\t\t\t\t\talt={images[currentIndex].alt || \"Gallery image\"}\r\n\t\t\t\t\t\t\tclassName=\"sg:w-full sg:h-56 sm:sg:h-72 md:sg:h-96 sg:object-cover\"\r\n\t\t\t\t\t\t\tloading=\"lazy\"\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</button>\r\n\t\t\t\t\t{images.length > 1 && (\r\n\t\t\t\t\t\t<>\r\n\t\t\t\t\t\t\t<IconButton\r\n\t\t\t\t\t\t\t\tvariant=\"secondary\"\r\n\t\t\t\t\t\t\t\tsize=\"sm\"\r\n\t\t\t\t\t\t\t\tclassName=\"sg:absolute sg:left-3 sg:top-1/2 sg:-translate-y-1/2 sg:opacity-0 sg:group-hover:opacity-100 sg:transition-opacity sg:h-10 sg:w-10 sg:rounded-full sg:shadow-lg\"\r\n\t\t\t\t\t\t\t\tonClick={prev}\r\n\t\t\t\t\t\t\t\ticon=\"ChevronLeft\"\r\n\t\t\t\t\t\t\t\taria-label=\"Previous image\"\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t<IconButton\r\n\t\t\t\t\t\t\t\tvariant=\"secondary\"\r\n\t\t\t\t\t\t\t\tsize=\"sm\"\r\n\t\t\t\t\t\t\t\tclassName=\"sg:absolute sg:right-3 sg:top-1/2 sg:-translate-y-1/2 sg:opacity-0 sg:group-hover:opacity-100 sg:transition-opacity sg:h-10 sg:w-10 sg:rounded-full sg:shadow-lg\"\r\n\t\t\t\t\t\t\t\tonClick={next}\r\n\t\t\t\t\t\t\t\ticon=\"ChevronRight\"\r\n\t\t\t\t\t\t\t\taria-label=\"Next image\"\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t<div className=\"sg:absolute sg:bottom-3 sg:left-1/2 sg:-translate-x-1/2 sg:flex sg:items-center sg:gap-1.5 sg:bg-black/40 sg:backdrop-blur-sm sg:rounded-full sg:px-3 sg:py-1.5\">\r\n\t\t\t\t\t\t\t\t{images.map((_, i) => (\r\n\t\t\t\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\t\t\t\tkey={i}\r\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\t\t\t\tonClick={() => setCurrentIndex(i)}\r\n\t\t\t\t\t\t\t\t\t\tclassName={cn(\r\n\t\t\t\t\t\t\t\t\t\t\t\"sg:h-2 sg:rounded-full sg:transition-all sg:border-0 sg:p-0\",\r\n\t\t\t\t\t\t\t\t\t\t\ti === currentIndex\r\n\t\t\t\t\t\t\t\t\t\t\t\t? \"sg:w-6 sg:bg-white\"\r\n\t\t\t\t\t\t\t\t\t\t\t\t: \"sg:w-2 sg:bg-white/50 hover:sg:bg-white/75\",\r\n\t\t\t\t\t\t\t\t\t\t)}\r\n\t\t\t\t\t\t\t\t\t\taria-label={`Go to image ${i + 1}`}\r\n\t\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t\t))}\r\n\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t</>\r\n\t\t\t\t\t)}\r\n\t\t\t\t</div>\r\n\t\t\t)}\r\n\r\n\t\t\t{viewMode === \"grid\" && (\r\n\t\t\t\t<div className={cn(\"sg:grid sg:gap-2 sm:sg:gap-3\", gridCols(images.length))}>\r\n\t\t\t\t\t{images.map((img, i) => (\r\n\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\tkey={i}\r\n\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\tclassName=\"sg:rounded-lg sg:overflow-hidden sg:cursor-pointer sg:group/img sg:border-0 sg:p-0 sg:bg-transparent\"\r\n\t\t\t\t\t\t\tonClick={() => openLightbox(i)}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t<UiImage\r\n\t\t\t\t\t\t\t\tsrc={img.src}\r\n\t\t\t\t\t\t\t\talt={img.alt || `Gallery image ${i + 1}`}\r\n\t\t\t\t\t\t\t\tclassName=\"sg:w-full sg:aspect-4/3 sg:object-cover sg:transition-transform sg:duration-300 sg:group-hover/img:scale-105\"\r\n\t\t\t\t\t\t\t\tloading=\"lazy\"\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t</button>\r\n\t\t\t\t\t))}\r\n\t\t\t\t</div>\r\n\t\t\t)}\r\n\r\n\t\t\t<Sheet open={lightboxOpen} onOpenChange={setLightboxOpen}>\r\n\t\t\t\t<SheetContent\r\n\t\t\t\t\tside=\"bottom\"\r\n\t\t\t\t\tclassName=\"sg:max-h-[95vh] sg:overflow-y-auto sg:border-0 sg:p-2 sg:bg-background/95 sg:backdrop-blur-sm\"\r\n\t\t\t\t>\r\n\t\t\t\t\t<SheetTitle className=\"sg:sr-only\">Image lightbox</SheetTitle>\r\n\t\t\t\t\t<div className=\"sg:relative sg:mx-auto sg:max-w-4xl\">\r\n\t\t\t\t\t\t<UiImage\r\n\t\t\t\t\t\t\tsrc={images[lightboxIndex].src}\r\n\t\t\t\t\t\t\talt={images[lightboxIndex].alt || \"Gallery image\"}\r\n\t\t\t\t\t\t\tclassName=\"sg:w-full sg:max-h-[80vh] sg:object-contain sg:rounded-md\"\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t{images.length > 1 && (\r\n\t\t\t\t\t\t\t<>\r\n\t\t\t\t\t\t\t\t<IconButton\r\n\t\t\t\t\t\t\t\t\tvariant=\"secondary\"\r\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\r\n\t\t\t\t\t\t\t\t\tclassName=\"sg:absolute sg:left-2 sg:top-1/2 sg:-translate-y-1/2 sg:h-10 sg:w-10 sg:rounded-full sg:shadow-lg\"\r\n\t\t\t\t\t\t\t\t\tonClick={() =>\r\n\t\t\t\t\t\t\t\t\t\tsetLightboxIndex(\r\n\t\t\t\t\t\t\t\t\t\t\t(i) => (i - 1 + images.length) % images.length,\r\n\t\t\t\t\t\t\t\t\t\t)\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\ticon=\"ChevronLeft\"\r\n\t\t\t\t\t\t\t\t\taria-label=\"Previous image\"\r\n\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t\t<IconButton\r\n\t\t\t\t\t\t\t\t\tvariant=\"secondary\"\r\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\r\n\t\t\t\t\t\t\t\t\tclassName=\"sg:absolute sg:right-2 sg:top-1/2 sg:-translate-y-1/2 sg:h-10 sg:w-10 sg:rounded-full sg:shadow-lg\"\r\n\t\t\t\t\t\t\t\t\tonClick={() =>\r\n\t\t\t\t\t\t\t\t\t\tsetLightboxIndex((i) => (i + 1) % images.length)\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\ticon=\"ChevronRight\"\r\n\t\t\t\t\t\t\t\t\taria-label=\"Next image\"\r\n\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t\t<div className=\"sg:absolute sg:bottom-3 sg:left-1/2 sg:-translate-x-1/2 sg:flex sg:gap-1.5\">\r\n\t\t\t\t\t\t\t\t\t{images.map((_, i) => (\r\n\t\t\t\t\t\t\t\t\t\t<button\r\n\t\t\t\t\t\t\t\t\t\t\tkey={i}\r\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\r\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => setLightboxIndex(i)}\r\n\t\t\t\t\t\t\t\t\t\t\tclassName={cn(\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"sg:h-2 sg:rounded-full sg:transition-all sg:border-0 sg:p-0\",\r\n\t\t\t\t\t\t\t\t\t\t\t\ti === lightboxIndex\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t? \"sg:w-6 sg:bg-primary\"\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t: \"sg:w-2 sg:bg-muted-foreground/40 hover:sg:bg-muted-foreground/60\",\r\n\t\t\t\t\t\t\t\t\t\t\t)}\r\n\t\t\t\t\t\t\t\t\t\t\taria-label={`Go to image ${i + 1}`}\r\n\t\t\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t\t\t))}\r\n\t\t\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t\t</>\r\n\t\t\t\t\t\t)}\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</SheetContent>\r\n\t\t\t</Sheet>\r\n\t\t</div>\r\n\t);\r\n}\r\n"],"mappings":"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","names":[]}
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
export { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './cards/card.js';
|
|
2
|
+
export { AuthorCard } from './directory/author-card.js';
|
|
3
|
+
export { CategoryCard } from './directory/category-card.js';
|
|
4
|
+
export { ExtrasHubCard, ExtrasHubItem } from './extras/extras-hub-card.js';
|
|
5
|
+
export { GalleryImage } from './gallery/image-gallery.js';
|
|
6
|
+
export { CommentSkeleton, PostCardSkeleton, PostListRowSkeleton, PostListSkeleton, SinglePostSkeleton } from './loading/loading-skeletons.js';
|
|
2
7
|
export { Login, LoginCredentials, LoginProps } from './login/login.js';
|
|
8
|
+
export { PageHero } from './marketing/page-hero.js';
|
|
9
|
+
export { StatItem, StatsGrid } from './marketing/stats-grid.js';
|
|
10
|
+
export { Timeline, TimelineItem } from './marketing/timeline.js';
|
|
11
|
+
export { ValueItem, ValuesGrid } from './marketing/values-grid.js';
|
|
3
12
|
export { PostListWithFilters } from './post-list/post-list-with-filters.js';
|
|
4
13
|
import 'react';
|
|
14
|
+
import '../../data/authors.js';
|
|
15
|
+
import 'lucide-react';
|
|
5
16
|
import '../../data/posts.js';
|
|
@@ -1,6 +1,16 @@
|
|
|
1
|
+
export * from "./badges/category-badge.js";
|
|
1
2
|
export * from "./cards/blogpost-card.js";
|
|
2
3
|
export * from "./cards/card.js";
|
|
4
|
+
export * from "./directory/author-card.js";
|
|
5
|
+
export * from "./directory/category-card.js";
|
|
3
6
|
export * from "./empty-state/EmptyState.js";
|
|
7
|
+
export * from "./extras/extras-hub-card.js";
|
|
8
|
+
export * from "./gallery/image-gallery.js";
|
|
9
|
+
export * from "./loading/loading-skeletons.js";
|
|
4
10
|
export * from "./login/login.js";
|
|
11
|
+
export * from "./marketing/page-hero.js";
|
|
12
|
+
export * from "./marketing/stats-grid.js";
|
|
13
|
+
export * from "./marketing/timeline.js";
|
|
14
|
+
export * from "./marketing/values-grid.js";
|
|
5
15
|
export * from "./post-list/post-list-with-filters.js";
|
|
6
16
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/blocks/index.ts"],"sourcesContent":["/**\n * Blocks index\n *\n * Please keep exports sorted alphabetically by path!\n */\n\nexport * from \"./cards/blogpost-card\";\nexport * from \"./cards/card\";\nexport * from \"./empty-state/EmptyState\";\nexport * from \"./login/login\";\nexport * from \"./post-list/post-list-with-filters\";\n"],"mappings":"AAMA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/blocks/index.ts"],"sourcesContent":["/**\n * Blocks index\n *\n * Please keep exports sorted alphabetically by path!\n */\n\nexport * from \"./badges/category-badge\";\nexport * from \"./cards/blogpost-card\";\nexport * from \"./cards/card\";\nexport * from \"./directory/author-card\";\nexport * from \"./directory/category-card\";\nexport * from \"./empty-state/EmptyState\";\nexport * from \"./extras/extras-hub-card\";\nexport * from \"./gallery/image-gallery\";\nexport * from \"./loading/loading-skeletons\";\nexport * from \"./login/login\";\nexport * from \"./marketing/page-hero\";\nexport * from \"./marketing/stats-grid\";\nexport * from \"./marketing/timeline\";\nexport * from \"./marketing/values-grid\";\nexport * from \"./post-list/post-list-with-filters\";\n"],"mappings":"AAMA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
declare function PostCardSkeleton(): React.JSX.Element;
|
|
4
|
+
declare function PostListSkeleton({ count }: {
|
|
5
|
+
count?: number;
|
|
6
|
+
}): React.JSX.Element;
|
|
7
|
+
declare function PostListRowSkeleton({ count }: {
|
|
8
|
+
count?: number;
|
|
9
|
+
}): React.JSX.Element;
|
|
10
|
+
declare function CommentSkeleton({ count }: {
|
|
11
|
+
count?: number;
|
|
12
|
+
}): React.JSX.Element;
|
|
13
|
+
declare function SinglePostSkeleton(): React.JSX.Element;
|
|
14
|
+
|
|
15
|
+
export { CommentSkeleton, PostCardSkeleton, PostListRowSkeleton, PostListSkeleton, SinglePostSkeleton };
|