@silicajs/components 0.1.0 → 0.1.2
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/google-icon.d.ts +7 -0
- package/dist/google-icon.js +46 -0
- package/dist/google-icon.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/not-found.js +7 -1
- package/dist/not-found.js.map +1 -1
- package/dist/sign-in-shell.d.ts +14 -0
- package/dist/sign-in-shell.js +50 -0
- package/dist/sign-in-shell.js.map +1 -0
- package/dist/user-menu.d.ts +2 -3
- package/dist/user-menu.js +118 -19
- package/dist/user-menu.js.map +1 -1
- package/package.json +15 -5
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
function GoogleIcon({ className }) {
|
|
3
|
+
return /* @__PURE__ */ jsxs(
|
|
4
|
+
"svg",
|
|
5
|
+
{
|
|
6
|
+
className,
|
|
7
|
+
viewBox: "0 0 24 24",
|
|
8
|
+
"aria-hidden": "true",
|
|
9
|
+
focusable: "false",
|
|
10
|
+
children: [
|
|
11
|
+
/* @__PURE__ */ jsx(
|
|
12
|
+
"path",
|
|
13
|
+
{
|
|
14
|
+
d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z",
|
|
15
|
+
fill: "#4285F4"
|
|
16
|
+
}
|
|
17
|
+
),
|
|
18
|
+
/* @__PURE__ */ jsx(
|
|
19
|
+
"path",
|
|
20
|
+
{
|
|
21
|
+
d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z",
|
|
22
|
+
fill: "#34A853"
|
|
23
|
+
}
|
|
24
|
+
),
|
|
25
|
+
/* @__PURE__ */ jsx(
|
|
26
|
+
"path",
|
|
27
|
+
{
|
|
28
|
+
d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z",
|
|
29
|
+
fill: "#FBBC05"
|
|
30
|
+
}
|
|
31
|
+
),
|
|
32
|
+
/* @__PURE__ */ jsx(
|
|
33
|
+
"path",
|
|
34
|
+
{
|
|
35
|
+
d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z",
|
|
36
|
+
fill: "#EA4335"
|
|
37
|
+
}
|
|
38
|
+
)
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
export {
|
|
44
|
+
GoogleIcon
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=google-icon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/google-icon.tsx"],"sourcesContent":["export function GoogleIcon({ className }: { className?: string }) {\n return (\n <svg\n className={className}\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path\n d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z\"\n fill=\"#4285F4\"\n />\n <path\n d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"\n fill=\"#34A853\"\n />\n <path\n d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\"\n fill=\"#FBBC05\"\n />\n <path\n d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"\n fill=\"#EA4335\"\n />\n </svg>\n );\n}\n"],"mappings":"AAEI,SAME,KANF;AAFG,SAAS,WAAW,EAAE,UAAU,GAA2B;AAChE,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,SAAQ;AAAA,MACR,eAAY;AAAA,MACZ,WAAU;AAAA,MAEV;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,GAAE;AAAA,YACF,MAAK;AAAA;AAAA,QACP;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export { Backlinks, BacklinksProps } from './backlinks.js';
|
|
2
2
|
export { Breadcrumbs, BreadcrumbsProps } from './breadcrumbs.js';
|
|
3
3
|
export { DarkModeToggle, DarkModeToggleProps } from './dark-mode-toggle.js';
|
|
4
|
+
export { GoogleIcon } from './google-icon.js';
|
|
4
5
|
export { NotAllowed, NotAllowedProps } from './not-allowed.js';
|
|
6
|
+
export { SignInShell, SignInShellProps } from './sign-in-shell.js';
|
|
5
7
|
export { NotFound, NotFoundProps } from './not-found.js';
|
|
6
8
|
export { PageProperties, PagePropertiesProps } from './page-properties.js';
|
|
7
9
|
export { SearchPalette, SearchPaletteProps, SearchTrigger, SearchTriggerProps } from './search.js';
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,9 @@ import { Breadcrumbs } from "./breadcrumbs.js";
|
|
|
3
3
|
import {
|
|
4
4
|
DarkModeToggle
|
|
5
5
|
} from "./dark-mode-toggle.js";
|
|
6
|
+
import { GoogleIcon } from "./google-icon.js";
|
|
6
7
|
import { NotAllowed } from "./not-allowed.js";
|
|
8
|
+
import { SignInShell } from "./sign-in-shell.js";
|
|
7
9
|
import { NotFound } from "./not-found.js";
|
|
8
10
|
import { PageProperties } from "./page-properties.js";
|
|
9
11
|
import {
|
|
@@ -26,11 +28,13 @@ export {
|
|
|
26
28
|
Backlinks,
|
|
27
29
|
Breadcrumbs,
|
|
28
30
|
DarkModeToggle,
|
|
31
|
+
GoogleIcon,
|
|
29
32
|
NotAllowed,
|
|
30
33
|
NotFound,
|
|
31
34
|
PageProperties,
|
|
32
35
|
SearchPalette,
|
|
33
36
|
SearchTrigger,
|
|
37
|
+
SignInShell,
|
|
34
38
|
SilicaLink,
|
|
35
39
|
SilicaRoutingProvider,
|
|
36
40
|
TableOfContents,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { Backlinks, type BacklinksProps } from \"./backlinks.js\";\nexport { Breadcrumbs, type BreadcrumbsProps } from \"./breadcrumbs.js\";\nexport {\n DarkModeToggle,\n type DarkModeToggleProps,\n} from \"./dark-mode-toggle.js\";\nexport { NotAllowed, type NotAllowedProps } from \"./not-allowed.js\";\nexport { NotFound, type NotFoundProps } from \"./not-found.js\";\nexport { PageProperties, type PagePropertiesProps } from \"./page-properties.js\";\nexport {\n SearchPalette,\n SearchTrigger,\n type SearchPaletteProps,\n type SearchTriggerProps,\n} from \"./search.js\";\nexport {\n SilicaLink,\n SilicaRoutingProvider,\n useSilicaRouting,\n type SilicaLinkComponent,\n type SilicaLinkProps,\n type SilicaRoutingContextValue,\n type SilicaRoutingProviderProps,\n} from \"./routing.js\";\nexport {\n TableOfContents,\n type TableOfContentsProps,\n} from \"./table-of-contents.js\";\nexport { TagsList, type TagsListProps } from \"./tags-list.js\";\nexport { UserMenu, type UserMenuProps } from \"./user-menu.js\";\nexport { VaultTree, type VaultTreeProps } from \"./vault-tree.js\";\nexport { breadcrumbSegmentHref, prettySegment, slugToHref } from \"./slug.js\";\n"],"mappings":"AAAA,SAAS,iBAAsC;AAC/C,SAAS,mBAA0C;AACnD;AAAA,EACE;AAAA,OAEK;AACP,SAAS,kBAAwC;AACjD,SAAS,gBAAoC;AAC7C,SAAS,sBAAgD;AACzD;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAKK;AACP;AAAA,EACE;AAAA,OAEK;AACP,SAAS,gBAAoC;AAC7C,SAAS,gBAAoC;AAC7C,SAAS,iBAAsC;AAC/C,SAAS,uBAAuB,eAAe,kBAAkB;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { Backlinks, type BacklinksProps } from \"./backlinks.js\";\nexport { Breadcrumbs, type BreadcrumbsProps } from \"./breadcrumbs.js\";\nexport {\n DarkModeToggle,\n type DarkModeToggleProps,\n} from \"./dark-mode-toggle.js\";\nexport { GoogleIcon } from \"./google-icon.js\";\nexport { NotAllowed, type NotAllowedProps } from \"./not-allowed.js\";\nexport { SignInShell, type SignInShellProps } from \"./sign-in-shell.js\";\nexport { NotFound, type NotFoundProps } from \"./not-found.js\";\nexport { PageProperties, type PagePropertiesProps } from \"./page-properties.js\";\nexport {\n SearchPalette,\n SearchTrigger,\n type SearchPaletteProps,\n type SearchTriggerProps,\n} from \"./search.js\";\nexport {\n SilicaLink,\n SilicaRoutingProvider,\n useSilicaRouting,\n type SilicaLinkComponent,\n type SilicaLinkProps,\n type SilicaRoutingContextValue,\n type SilicaRoutingProviderProps,\n} from \"./routing.js\";\nexport {\n TableOfContents,\n type TableOfContentsProps,\n} from \"./table-of-contents.js\";\nexport { TagsList, type TagsListProps } from \"./tags-list.js\";\nexport { UserMenu, type UserMenuProps } from \"./user-menu.js\";\nexport { VaultTree, type VaultTreeProps } from \"./vault-tree.js\";\nexport { breadcrumbSegmentHref, prettySegment, slugToHref } from \"./slug.js\";\n"],"mappings":"AAAA,SAAS,iBAAsC;AAC/C,SAAS,mBAA0C;AACnD;AAAA,EACE;AAAA,OAEK;AACP,SAAS,kBAAkB;AAC3B,SAAS,kBAAwC;AACjD,SAAS,mBAA0C;AACnD,SAAS,gBAAoC;AAC7C,SAAS,sBAAgD;AACzD;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAKK;AACP;AAAA,EACE;AAAA,OAEK;AACP,SAAS,gBAAoC;AAC7C,SAAS,gBAAoC;AAC7C,SAAS,iBAAsC;AAC/C,SAAS,uBAAuB,eAAe,kBAAkB;","names":[]}
|
package/dist/not-found.js
CHANGED
|
@@ -18,7 +18,13 @@ function NotFound({
|
|
|
18
18
|
/* @__PURE__ */ jsx(CardTitle, { className: "text-lg", children: title }),
|
|
19
19
|
/* @__PURE__ */ jsx(CardDescription, { children: description })
|
|
20
20
|
] }),
|
|
21
|
-
/* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsx(
|
|
21
|
+
/* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsx(
|
|
22
|
+
Button,
|
|
23
|
+
{
|
|
24
|
+
variant: "outline",
|
|
25
|
+
render: /* @__PURE__ */ jsx("a", { href: cta.href, children: cta.label })
|
|
26
|
+
}
|
|
27
|
+
) })
|
|
22
28
|
] }) });
|
|
23
29
|
}
|
|
24
30
|
export {
|
package/dist/not-found.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/not-found.tsx"],"sourcesContent":["import { Button } from \"@silicajs/ui/components/button\";\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@silicajs/ui/components/card\";\n\nexport type NotFoundProps = {\n title?: string;\n description?: string;\n cta?: { href: string; label: string };\n className?: string;\n};\n\nexport function NotFound({\n title = \"Page not found\",\n description = \"The requested note does not exist or is not published.\",\n cta = { href: \"/\", label: \"Return home\" },\n className,\n}: NotFoundProps) {\n return (\n <main className={className} data-slot=\"not-found\">\n <Card className=\"mx-auto max-w-md\">\n <CardHeader>\n <CardTitle className=\"text-lg\">{title}</CardTitle>\n <CardDescription>{description}</CardDescription>\n </CardHeader>\n <CardContent>\n <Button
|
|
1
|
+
{"version":3,"sources":["../src/not-found.tsx"],"sourcesContent":["import { Button } from \"@silicajs/ui/components/button\";\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@silicajs/ui/components/card\";\n\nexport type NotFoundProps = {\n title?: string;\n description?: string;\n cta?: { href: string; label: string };\n className?: string;\n};\n\nexport function NotFound({\n title = \"Page not found\",\n description = \"The requested note does not exist or is not published.\",\n cta = { href: \"/\", label: \"Return home\" },\n className,\n}: NotFoundProps) {\n return (\n <main className={className} data-slot=\"not-found\">\n <Card className=\"mx-auto max-w-md\">\n <CardHeader>\n <CardTitle className=\"text-lg\">{title}</CardTitle>\n <CardDescription>{description}</CardDescription>\n </CardHeader>\n <CardContent>\n <Button\n variant=\"outline\"\n render={<a href={cta.href}>{cta.label}</a>}\n />\n </CardContent>\n </Card>\n </main>\n );\n}\n"],"mappings":"AAyBQ,SACE,KADF;AAzBR,SAAS,cAAc;AACvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AASA,SAAS,SAAS;AAAA,EACvB,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,MAAM,EAAE,MAAM,KAAK,OAAO,cAAc;AAAA,EACxC;AACF,GAAkB;AAChB,SACE,oBAAC,UAAK,WAAsB,aAAU,aACpC,+BAAC,QAAK,WAAU,oBACd;AAAA,yBAAC,cACC;AAAA,0BAAC,aAAU,WAAU,WAAW,iBAAM;AAAA,MACtC,oBAAC,mBAAiB,uBAAY;AAAA,OAChC;AAAA,IACA,oBAAC,eACC;AAAA,MAAC;AAAA;AAAA,QACC,SAAQ;AAAA,QACR,QAAQ,oBAAC,OAAE,MAAM,IAAI,MAAO,cAAI,OAAM;AAAA;AAAA,IACxC,GACF;AAAA,KACF,GACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
type SignInShellProps = {
|
|
5
|
+
title: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
logo?: string;
|
|
8
|
+
headline?: string;
|
|
9
|
+
subheadline?: string;
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
};
|
|
12
|
+
declare function SignInShell({ title, description, logo, headline, subheadline, children, }: SignInShellProps): react_jsx_runtime.JSX.Element;
|
|
13
|
+
|
|
14
|
+
export { SignInShell, type SignInShellProps };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { BookOpen } from "lucide-react";
|
|
3
|
+
import {
|
|
4
|
+
Card,
|
|
5
|
+
CardContent,
|
|
6
|
+
CardDescription,
|
|
7
|
+
CardHeader,
|
|
8
|
+
CardTitle
|
|
9
|
+
} from "@silicajs/ui/components/card";
|
|
10
|
+
function SignInShell({
|
|
11
|
+
title,
|
|
12
|
+
description,
|
|
13
|
+
logo,
|
|
14
|
+
headline = "Sign in required",
|
|
15
|
+
subheadline,
|
|
16
|
+
children
|
|
17
|
+
}) {
|
|
18
|
+
const hint = subheadline ?? (description ? `${description} is private. Sign in with Google to access it.` : "This site is private. Sign in with Google to continue.");
|
|
19
|
+
return /* @__PURE__ */ jsxs(
|
|
20
|
+
"main",
|
|
21
|
+
{
|
|
22
|
+
className: "flex min-h-svh flex-col items-center justify-center gap-6 bg-muted/40 p-6 md:p-10",
|
|
23
|
+
"data-slot": "sign-in",
|
|
24
|
+
children: [
|
|
25
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
26
|
+
logo ? /* @__PURE__ */ jsx(
|
|
27
|
+
"img",
|
|
28
|
+
{
|
|
29
|
+
src: logo,
|
|
30
|
+
alt: "",
|
|
31
|
+
className: "size-8 shrink-0 rounded-md object-contain"
|
|
32
|
+
}
|
|
33
|
+
) : /* @__PURE__ */ jsx("span", { className: "flex size-8 shrink-0 items-center justify-center rounded-md border border-border bg-background text-foreground", children: /* @__PURE__ */ jsx(BookOpen, { className: "size-4", "aria-hidden": "true" }) }),
|
|
34
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold tracking-tight text-foreground", children: title })
|
|
35
|
+
] }),
|
|
36
|
+
/* @__PURE__ */ jsxs(Card, { className: "w-full max-w-sm shadow-sm", children: [
|
|
37
|
+
/* @__PURE__ */ jsxs(CardHeader, { className: "text-center", children: [
|
|
38
|
+
/* @__PURE__ */ jsx(CardTitle, { className: "text-xl tracking-tight", children: headline }),
|
|
39
|
+
/* @__PURE__ */ jsx(CardDescription, { children: hint })
|
|
40
|
+
] }),
|
|
41
|
+
/* @__PURE__ */ jsx(CardContent, { className: "flex flex-col gap-4", children })
|
|
42
|
+
] })
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
SignInShell
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=sign-in-shell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sign-in-shell.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { BookOpen } from \"lucide-react\";\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n} from \"@silicajs/ui/components/card\";\n\nexport type SignInShellProps = {\n title: string;\n description?: string;\n logo?: string;\n headline?: string;\n subheadline?: string;\n children: ReactNode;\n};\n\nexport function SignInShell({\n title,\n description,\n logo,\n headline = \"Sign in required\",\n subheadline,\n children,\n}: SignInShellProps) {\n const hint =\n subheadline ??\n (description\n ? `${description} is private. Sign in with Google to access it.`\n : \"This site is private. Sign in with Google to continue.\");\n\n return (\n <main\n className=\"flex min-h-svh flex-col items-center justify-center gap-6 bg-muted/40 p-6 md:p-10\"\n data-slot=\"sign-in\"\n >\n <div className=\"flex items-center gap-2\">\n {logo ? (\n <img\n src={logo}\n alt=\"\"\n className=\"size-8 shrink-0 rounded-md object-contain\"\n />\n ) : (\n <span className=\"flex size-8 shrink-0 items-center justify-center rounded-md border border-border bg-background text-foreground\">\n <BookOpen className=\"size-4\" aria-hidden=\"true\" />\n </span>\n )}\n <span className=\"text-sm font-semibold tracking-tight text-foreground\">\n {title}\n </span>\n </div>\n\n <Card className=\"w-full max-w-sm shadow-sm\">\n <CardHeader className=\"text-center\">\n <CardTitle className=\"text-xl tracking-tight\">{headline}</CardTitle>\n <CardDescription>{hint}</CardDescription>\n </CardHeader>\n <CardContent className=\"flex flex-col gap-4\">{children}</CardContent>\n </Card>\n </main>\n );\n}\n"],"mappings":"AAsCM,SAEI,KAFJ;AArCN,SAAS,gBAAgB;AACzB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAWA,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,OACJ,gBACC,cACG,GAAG,WAAW,mDACd;AAEN,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,aAAU;AAAA,MAEV;AAAA,6BAAC,SAAI,WAAU,2BACZ;AAAA,iBACC;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL,KAAI;AAAA,cACJ,WAAU;AAAA;AAAA,UACZ,IAEA,oBAAC,UAAK,WAAU,kHACd,8BAAC,YAAS,WAAU,UAAS,eAAY,QAAO,GAClD;AAAA,UAEF,oBAAC,UAAK,WAAU,wDACb,iBACH;AAAA,WACF;AAAA,QAEA,qBAAC,QAAK,WAAU,6BACd;AAAA,+BAAC,cAAW,WAAU,eACpB;AAAA,gCAAC,aAAU,WAAU,0BAA0B,oBAAS;AAAA,YACxD,oBAAC,mBAAiB,gBAAK;AAAA,aACzB;AAAA,UACA,oBAAC,eAAY,WAAU,uBAAuB,UAAS;AAAA,WACzD;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
package/dist/user-menu.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
|
|
3
3
|
type UserMenuProps = {
|
|
4
|
-
|
|
5
|
-
className?: string;
|
|
4
|
+
logo?: string;
|
|
6
5
|
};
|
|
7
|
-
declare function UserMenu({
|
|
6
|
+
declare function UserMenu({ logo }: UserMenuProps): react_jsx_runtime.JSX.Element;
|
|
8
7
|
|
|
9
8
|
export { UserMenu, type UserMenuProps };
|
package/dist/user-menu.js
CHANGED
|
@@ -1,40 +1,139 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { EllipsisVertical, LogOut } from "lucide-react";
|
|
5
|
+
import {
|
|
6
|
+
Avatar,
|
|
7
|
+
AvatarFallback,
|
|
8
|
+
AvatarImage
|
|
9
|
+
} from "@silicajs/ui/components/avatar";
|
|
5
10
|
import {
|
|
6
11
|
DropdownMenu,
|
|
7
12
|
DropdownMenuContent,
|
|
13
|
+
DropdownMenuGroup,
|
|
8
14
|
DropdownMenuItem,
|
|
9
|
-
DropdownMenuLabel,
|
|
10
15
|
DropdownMenuSeparator,
|
|
11
16
|
DropdownMenuTrigger
|
|
12
17
|
} from "@silicajs/ui/components/dropdown-menu";
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
import {
|
|
19
|
+
SidebarMenu,
|
|
20
|
+
SidebarMenuButton,
|
|
21
|
+
SidebarMenuItem,
|
|
22
|
+
useSidebar
|
|
23
|
+
} from "@silicajs/ui/components/sidebar";
|
|
24
|
+
function UserMenu({ logo }) {
|
|
25
|
+
const { isMobile } = useSidebar();
|
|
26
|
+
const [user, setUser] = useState(null);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
let cancelled = false;
|
|
29
|
+
void fetch("/api/auth/get-session", { credentials: "include" }).then((response) => response.ok ? response.json() : null).then((data) => {
|
|
30
|
+
if (cancelled || !data?.user) return;
|
|
31
|
+
setUser({
|
|
32
|
+
name: data.user.name ?? data.user.email ?? "Account",
|
|
33
|
+
email: data.user.email ?? "",
|
|
34
|
+
image: data.user.image ?? void 0
|
|
35
|
+
});
|
|
36
|
+
}).catch(() => {
|
|
37
|
+
});
|
|
38
|
+
return () => {
|
|
39
|
+
cancelled = true;
|
|
40
|
+
};
|
|
41
|
+
}, []);
|
|
42
|
+
const displayName = user?.name ?? "Account";
|
|
43
|
+
const displayEmail = user?.email ?? "";
|
|
44
|
+
const avatarSrc = user?.image ?? logo;
|
|
45
|
+
const initials = getInitials(user?.name, user?.email);
|
|
46
|
+
return /* @__PURE__ */ jsx(SidebarMenu, { children: /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
47
|
+
/* @__PURE__ */ jsxs(
|
|
16
48
|
DropdownMenuTrigger,
|
|
17
49
|
{
|
|
18
50
|
render: /* @__PURE__ */ jsx(
|
|
19
|
-
|
|
51
|
+
SidebarMenuButton,
|
|
20
52
|
{
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
size: "icon-sm",
|
|
24
|
-
"aria-label": "User menu",
|
|
25
|
-
className,
|
|
26
|
-
children: /* @__PURE__ */ jsx(UserIcon, { "aria-hidden": "true" })
|
|
53
|
+
size: "lg",
|
|
54
|
+
className: "data-open:bg-sidebar-accent data-open:text-sidebar-accent-foreground"
|
|
27
55
|
}
|
|
28
|
-
)
|
|
56
|
+
),
|
|
57
|
+
children: [
|
|
58
|
+
/* @__PURE__ */ jsx(UserAvatar, { src: avatarSrc, alt: displayName, initials }),
|
|
59
|
+
/* @__PURE__ */ jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [
|
|
60
|
+
/* @__PURE__ */ jsx("span", { className: "truncate font-medium", children: displayName }),
|
|
61
|
+
displayEmail ? /* @__PURE__ */ jsx("span", { className: "truncate text-xs text-muted-foreground", children: displayEmail }) : null
|
|
62
|
+
] }),
|
|
63
|
+
/* @__PURE__ */ jsx(EllipsisVertical, { className: "ml-auto size-4 shrink-0 text-muted-foreground" })
|
|
64
|
+
]
|
|
29
65
|
}
|
|
30
66
|
),
|
|
31
|
-
/* @__PURE__ */ jsxs(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
67
|
+
/* @__PURE__ */ jsxs(
|
|
68
|
+
DropdownMenuContent,
|
|
69
|
+
{
|
|
70
|
+
className: "min-w-56 rounded-lg",
|
|
71
|
+
side: isMobile ? "bottom" : "right",
|
|
72
|
+
align: "end",
|
|
73
|
+
sideOffset: 4,
|
|
74
|
+
children: [
|
|
75
|
+
/* @__PURE__ */ jsx("div", { className: "px-1 py-1.5 font-normal", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-left text-sm", children: [
|
|
76
|
+
/* @__PURE__ */ jsx(
|
|
77
|
+
UserAvatar,
|
|
78
|
+
{
|
|
79
|
+
src: avatarSrc,
|
|
80
|
+
alt: displayName,
|
|
81
|
+
initials
|
|
82
|
+
}
|
|
83
|
+
),
|
|
84
|
+
/* @__PURE__ */ jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [
|
|
85
|
+
/* @__PURE__ */ jsx("span", { className: "truncate font-medium", children: displayName }),
|
|
86
|
+
displayEmail ? /* @__PURE__ */ jsx("span", { className: "truncate text-xs text-muted-foreground", children: displayEmail }) : null
|
|
87
|
+
] })
|
|
88
|
+
] }) }),
|
|
89
|
+
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
90
|
+
/* @__PURE__ */ jsx(DropdownMenuGroup, { children: /* @__PURE__ */ jsxs(
|
|
91
|
+
DropdownMenuItem,
|
|
92
|
+
{
|
|
93
|
+
variant: "destructive",
|
|
94
|
+
onClick: () => {
|
|
95
|
+
void signOut();
|
|
96
|
+
},
|
|
97
|
+
children: [
|
|
98
|
+
/* @__PURE__ */ jsx(LogOut, {}),
|
|
99
|
+
"Sign out"
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
) })
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
)
|
|
106
|
+
] }) }) });
|
|
107
|
+
}
|
|
108
|
+
function UserAvatar({
|
|
109
|
+
src,
|
|
110
|
+
alt,
|
|
111
|
+
initials
|
|
112
|
+
}) {
|
|
113
|
+
return /* @__PURE__ */ jsxs(Avatar, { className: "size-8", children: [
|
|
114
|
+
src ? /* @__PURE__ */ jsx(AvatarImage, { src, alt }) : null,
|
|
115
|
+
/* @__PURE__ */ jsx(AvatarFallback, { className: "text-xs", children: initials })
|
|
36
116
|
] });
|
|
37
117
|
}
|
|
118
|
+
function getInitials(name, email) {
|
|
119
|
+
const trimmedName = name?.trim();
|
|
120
|
+
if (trimmedName) {
|
|
121
|
+
const parts = trimmedName.split(/\s+/).filter(Boolean);
|
|
122
|
+
if (parts.length >= 2) {
|
|
123
|
+
return `${parts[0]?.[0] ?? ""}${parts[1]?.[0] ?? ""}`.toUpperCase();
|
|
124
|
+
}
|
|
125
|
+
return trimmedName.slice(0, 2).toUpperCase();
|
|
126
|
+
}
|
|
127
|
+
if (email) return email.slice(0, 2).toUpperCase();
|
|
128
|
+
return "??";
|
|
129
|
+
}
|
|
130
|
+
async function signOut() {
|
|
131
|
+
await fetch("/api/auth/sign-out", {
|
|
132
|
+
method: "POST",
|
|
133
|
+
credentials: "include"
|
|
134
|
+
});
|
|
135
|
+
window.location.assign("/sign-in");
|
|
136
|
+
}
|
|
38
137
|
export {
|
|
39
138
|
UserMenu
|
|
40
139
|
};
|
package/dist/user-menu.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/user-menu.tsx"],"sourcesContent":["\"use client\";\n\nimport {
|
|
1
|
+
{"version":3,"sources":["../src/user-menu.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { EllipsisVertical, LogOut } from \"lucide-react\";\n\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from \"@silicajs/ui/components/avatar\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@silicajs/ui/components/dropdown-menu\";\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from \"@silicajs/ui/components/sidebar\";\n\nexport type UserMenuProps = {\n logo?: string;\n};\n\ntype SessionUser = {\n name?: string | null;\n email?: string | null;\n image?: string | null;\n};\n\ntype SessionResponse = {\n user?: SessionUser;\n};\n\nexport function UserMenu({ logo }: UserMenuProps) {\n const { isMobile } = useSidebar();\n const [user, setUser] = useState<SessionUser | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n void fetch(\"/api/auth/get-session\", { credentials: \"include\" })\n .then((response) => (response.ok ? response.json() : null))\n .then((data: SessionResponse | null) => {\n if (cancelled || !data?.user) return;\n setUser({\n name: data.user.name ?? data.user.email ?? \"Account\",\n email: data.user.email ?? \"\",\n image: data.user.image ?? undefined,\n });\n })\n .catch(() => {});\n\n return () => {\n cancelled = true;\n };\n }, []);\n\n const displayName = user?.name ?? \"Account\";\n const displayEmail = user?.email ?? \"\";\n const avatarSrc = user?.image ?? logo;\n const initials = getInitials(user?.name, user?.email);\n\n return (\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger\n render={\n <SidebarMenuButton\n size=\"lg\"\n className=\"data-open:bg-sidebar-accent data-open:text-sidebar-accent-foreground\"\n />\n }\n >\n <UserAvatar src={avatarSrc} alt={displayName} initials={initials} />\n <div className=\"grid flex-1 text-left text-sm leading-tight\">\n <span className=\"truncate font-medium\">{displayName}</span>\n {displayEmail ? (\n <span className=\"truncate text-xs text-muted-foreground\">\n {displayEmail}\n </span>\n ) : null}\n </div>\n <EllipsisVertical className=\"ml-auto size-4 shrink-0 text-muted-foreground\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent\n className=\"min-w-56 rounded-lg\"\n side={isMobile ? \"bottom\" : \"right\"}\n align=\"end\"\n sideOffset={4}\n >\n <div className=\"px-1 py-1.5 font-normal\">\n <div className=\"flex items-center gap-2 text-left text-sm\">\n <UserAvatar\n src={avatarSrc}\n alt={displayName}\n initials={initials}\n />\n <div className=\"grid flex-1 text-left text-sm leading-tight\">\n <span className=\"truncate font-medium\">{displayName}</span>\n {displayEmail ? (\n <span className=\"truncate text-xs text-muted-foreground\">\n {displayEmail}\n </span>\n ) : null}\n </div>\n </div>\n </div>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem\n variant=\"destructive\"\n onClick={() => {\n void signOut();\n }}\n >\n <LogOut />\n Sign out\n </DropdownMenuItem>\n </DropdownMenuGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n );\n}\n\nfunction UserAvatar({\n src,\n alt,\n initials,\n}: {\n src?: string;\n alt: string;\n initials: string;\n}) {\n return (\n <Avatar className=\"size-8\">\n {src ? <AvatarImage src={src} alt={alt} /> : null}\n <AvatarFallback className=\"text-xs\">{initials}</AvatarFallback>\n </Avatar>\n );\n}\n\nfunction getInitials(name?: string | null, email?: string | null): string {\n const trimmedName = name?.trim();\n if (trimmedName) {\n const parts = trimmedName.split(/\\s+/).filter(Boolean);\n if (parts.length >= 2) {\n return `${parts[0]?.[0] ?? \"\"}${parts[1]?.[0] ?? \"\"}`.toUpperCase();\n }\n return trimmedName.slice(0, 2).toUpperCase();\n }\n if (email) return email.slice(0, 2).toUpperCase();\n return \"??\";\n}\n\nasync function signOut(): Promise<void> {\n await fetch(\"/api/auth/sign-out\", {\n method: \"POST\",\n credentials: \"include\",\n });\n window.location.assign(\"/sign-in\");\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@silicajs/components",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Silica-aware, framework-agnostic React composables built on @silicajs/ui.",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
6
7
|
"license": "MIT",
|
|
7
8
|
"publishConfig": {
|
|
8
9
|
"access": "public"
|
|
@@ -27,10 +28,10 @@
|
|
|
27
28
|
"test": "vitest run --passWithNoTests"
|
|
28
29
|
},
|
|
29
30
|
"dependencies": {
|
|
30
|
-
"@silicajs/core": "^0.1.
|
|
31
|
+
"@silicajs/core": "^0.1.1",
|
|
31
32
|
"@silicajs/remark-obsidian": "^0.1.0",
|
|
32
|
-
"@silicajs/ui": "^0.1.
|
|
33
|
-
"lucide-react": "^1.
|
|
33
|
+
"@silicajs/ui": "^0.1.2",
|
|
34
|
+
"lucide-react": "^1.17.0"
|
|
34
35
|
},
|
|
35
36
|
"peerDependencies": {
|
|
36
37
|
"react": "^19.2.0",
|
|
@@ -40,7 +41,16 @@
|
|
|
40
41
|
"@types/react": "^19.2.10",
|
|
41
42
|
"@types/react-dom": "^19.2.3",
|
|
42
43
|
"react": "^19.2.6",
|
|
43
|
-
"react-dom": "^19.2.
|
|
44
|
+
"react-dom": "^19.2.7",
|
|
44
45
|
"tsup": "^8.5.1"
|
|
46
|
+
},
|
|
47
|
+
"homepage": "https://github.com/agdevhq/silica/tree/main/packages/components#readme",
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "git+https://github.com/agdevhq/silica.git",
|
|
51
|
+
"directory": "packages/components"
|
|
52
|
+
},
|
|
53
|
+
"bugs": {
|
|
54
|
+
"url": "https://github.com/agdevhq/silica/issues"
|
|
45
55
|
}
|
|
46
56
|
}
|