@sybilion/uilib 1.2.5 → 1.2.8
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/assets/standalone-global.css +12 -11
- package/dist/esm/components/ui/AppHeader/AppHeader.styl.js +1 -1
- package/dist/esm/components/ui/Logo/Logo.js +7 -2
- package/dist/esm/components/ui/Logo/Logo.styl.js +1 -1
- package/dist/esm/components/ui/NavUserHeader/NavUserHeader.js +4 -2
- package/dist/esm/components/ui/Sidebar/Sidebar.styl.js +1 -1
- package/dist/esm/components/widgets/SybilionAppHeader/SybilionAppHeader.js +4 -2
- package/dist/esm/components/widgets/SybilionAppHeader/SybilionAppHeader.styl.js +2 -2
- package/dist/esm/docs/contexts/theme-context.js +14 -0
- package/dist/esm/docs/lib/theme.js +23 -0
- package/dist/esm/types/src/components/ui/Logo/Logo.d.ts +5 -0
- package/dist/esm/types/src/components/ui/NavUserHeader/NavUserHeader.d.ts +1 -1
- package/dist/esm/types/src/components/ui/NavUserHeader/NavUserHeader.types.d.ts +0 -4
- package/dist/esm/types/src/components/widgets/SybilionAppHeader/SybilionAppHeader.d.ts +7 -1
- package/dist/esm/types/src/docs/contexts/theme-context.d.ts +1 -0
- package/dist/esm/types/src/docs/pages/StandaloneAppLayoutPage/StandaloneAppLayoutPage.constants.d.ts +7 -0
- package/docs/standalone-apps.md +111 -12
- package/package.json +3 -2
- package/src/assets/logo.svg +3 -0
- package/src/components/ui/AppHeader/AppHeader.styl +5 -0
- package/src/components/ui/Logo/Logo.styl +2 -0
- package/src/components/ui/Logo/Logo.tsx +12 -1
- package/src/components/ui/NavUserHeader/NavUserHeader.tsx +15 -17
- package/src/components/ui/NavUserHeader/NavUserHeader.types.ts +0 -4
- package/src/components/ui/Sidebar/Sidebar.styl +1 -1
- package/src/components/widgets/SybilionAppHeader/SybilionAppHeader.styl +46 -0
- package/src/components/widgets/SybilionAppHeader/SybilionAppHeader.styl.d.ts +3 -0
- package/src/components/widgets/SybilionAppHeader/SybilionAppHeader.tsx +23 -0
- package/src/docs/config/webpack.config.js +4 -3
- package/src/docs/contexts/theme-context.tsx +14 -1
- package/src/docs/pages/NavUserHeaderPage.tsx +1 -20
- package/src/docs/pages/StandaloneAppLayoutPage/StandaloneAppLayoutPage.constants.ts +444 -0
- package/src/docs/pages/{StandaloneAppLayoutPage.styl → StandaloneAppLayoutPage/StandaloneAppLayoutPage.styl} +11 -21
- package/src/docs/pages/{StandaloneAppLayoutPage.styl.d.ts → StandaloneAppLayoutPage/StandaloneAppLayoutPage.styl.d.ts} +1 -0
- package/src/docs/pages/{StandaloneAppLayoutPage.tsx → StandaloneAppLayoutPage/StandaloneAppLayoutPage.tsx} +18 -116
- package/src/docs/registry.ts +2 -1
- /package/dist/esm/types/src/docs/pages/{StandaloneAppLayoutPage.d.ts → StandaloneAppLayoutPage/StandaloneAppLayoutPage.d.ts} +0 -0
|
@@ -125,17 +125,18 @@
|
|
|
125
125
|
--font-family-heading: 'KMR Apparat', sans-serif;
|
|
126
126
|
--font-family-body: 'Manrope', sans-serif;
|
|
127
127
|
|
|
128
|
-
|
|
129
|
-
--brand-color
|
|
130
|
-
--brand-color-
|
|
131
|
-
--brand-color-
|
|
132
|
-
--brand-color-
|
|
133
|
-
--brand-color-
|
|
134
|
-
--brand-color-
|
|
135
|
-
--brand-color-
|
|
136
|
-
--brand-color-
|
|
137
|
-
--brand-color-
|
|
138
|
-
--brand-color-
|
|
128
|
+
/* Same mapping as sybilion-client/assets/globals.css (app variables) */
|
|
129
|
+
--brand-color: var(--sb-cyan-400);
|
|
130
|
+
--brand-color-50: var(--sb-cyan-50);
|
|
131
|
+
--brand-color-100: var(--sb-cyan-100);
|
|
132
|
+
--brand-color-200: var(--sb-cyan-200);
|
|
133
|
+
--brand-color-300: var(--sb-cyan-300);
|
|
134
|
+
--brand-color-400: var(--sb-cyan-400);
|
|
135
|
+
--brand-color-500: var(--sb-cyan-500);
|
|
136
|
+
--brand-color-600: var(--sb-cyan-600);
|
|
137
|
+
--brand-color-700: var(--sb-cyan-700);
|
|
138
|
+
--brand-color-800: var(--sb-cyan-800);
|
|
139
|
+
--brand-color-900: var(--sb-cyan-900);
|
|
139
140
|
--header-height: 94px;
|
|
140
141
|
--page-x-padding: var(--p-16);
|
|
141
142
|
--page-y-padding: var(--p-12);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import styleInject from 'style-inject';
|
|
2
2
|
|
|
3
|
-
var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.AppHeader_root__SdbDv{align-items:center;align-self:flex-end;background-color:var(--color-background);display:flex;max-width:calc(100vw - var(--sidebar-width) - var(--p-3));min-height:var(--header-height);width:100%}.AppHeader_content__kyxem{align-items:center;display:flex;gap:2rem;justify-content:flex-end;padding:0 var(--p-9);width:100%}.AppHeader_logo__v31FX{align-items:center;color:var(--color-foreground);display:flex;font-size:1.5rem;font-weight:400;gap:.5rem;text-decoration:none;white-space:nowrap}.AppHeader_logo__v31FX svg{display:inline-flex;height:32px;transition:transform .1s ease-in-out;width:auto}.AppHeader_logo__v31FX:hover svg{transform:scale(1.05)}.AppHeader_nav__ahN1p{align-items:center;display:flex;flex:1;gap:1.5rem;justify-content:center}@media (max-width:units(768px,\"px\")){.AppHeader_nav__ahN1p{display:none}}.AppHeader_navLink__z43jY{color:var(--color-muted-foreground);font-size:.875rem;font-weight:400;text-decoration:none;transition:color .2s ease}.AppHeader_navLink__z43jY:hover{color:var(--color-foreground)}.AppHeader_actions__QuxEF{align-items:center;display:flex;gap:var(--p-4);margin-right:var(--p-2)}@media (max-width:units(768px,\"px\")){.AppHeader_actions__QuxEF{gap:var(--p-1)}}.AppHeader_pageHeaderActionsAnchor__qzQMs{align-items:center;display:flex;flex-shrink:0;gap:var(--p-4)}";
|
|
3
|
+
var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.AppHeader_root__SdbDv{align-items:center;align-self:flex-end;background-color:var(--color-background);display:flex;max-width:calc(100vw - var(--sidebar-width) - var(--p-3));min-height:var(--header-height);width:100%}@media (min-width:768px){[data-slot=sidebar-wrapper][data-state=collapsed] .AppHeader_root__SdbDv{max-width:100%;padding-left:200px}}.AppHeader_content__kyxem{align-items:center;display:flex;gap:2rem;justify-content:flex-end;padding:0 var(--p-9);width:100%}.AppHeader_logo__v31FX{align-items:center;color:var(--color-foreground);display:flex;font-size:1.5rem;font-weight:400;gap:.5rem;text-decoration:none;white-space:nowrap}.AppHeader_logo__v31FX svg{display:inline-flex;height:32px;transition:transform .1s ease-in-out;width:auto}.AppHeader_logo__v31FX:hover svg{transform:scale(1.05)}.AppHeader_nav__ahN1p{align-items:center;display:flex;flex:1;gap:1.5rem;justify-content:center}@media (max-width:units(768px,\"px\")){.AppHeader_nav__ahN1p{display:none}}.AppHeader_navLink__z43jY{color:var(--color-muted-foreground);font-size:.875rem;font-weight:400;text-decoration:none;transition:color .2s ease}.AppHeader_navLink__z43jY:hover{color:var(--color-foreground)}.AppHeader_actions__QuxEF{align-items:center;display:flex;gap:var(--p-4);margin-right:var(--p-2)}@media (max-width:units(768px,\"px\")){.AppHeader_actions__QuxEF{gap:var(--p-1)}}.AppHeader_pageHeaderActionsAnchor__qzQMs{align-items:center;display:flex;flex-shrink:0;gap:var(--p-4)}";
|
|
4
4
|
var S = {"root":"AppHeader_root__SdbDv","content":"AppHeader_content__kyxem","logo":"AppHeader_logo__v31FX","nav":"AppHeader_nav__ahN1p","navLink":"AppHeader_navLink__z43jY","actions":"AppHeader_actions__QuxEF","pageHeaderActionsAnchor":"AppHeader_pageHeaderActionsAnchor__qzQMs"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
@@ -2,8 +2,13 @@ import { jsxs, jsx } from 'react/jsx-runtime';
|
|
|
2
2
|
import cn from 'classnames';
|
|
3
3
|
import S from './Logo.styl.js';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Public URL for the Sybilion logo in standalone apps. Copy `@sybilion/uilib/logo.svg`
|
|
7
|
+
* to `public/logo.svg` (see standalone-apps guide). Same path as the favicon `<link href>`.
|
|
8
|
+
*/
|
|
9
|
+
const SYBILION_STANDALONE_LOGO_PUBLIC_URL = '/logo.svg';
|
|
5
10
|
function Logo({ showText = true, size = 'md', className, ...props }) {
|
|
6
|
-
return (jsxs("div", { className: cn(S.root, S[size], className), ...props, children: [jsx("img", { src:
|
|
11
|
+
return (jsxs("div", { className: cn(S.root, S[size], className), ...props, children: [jsx("img", { src: SYBILION_STANDALONE_LOGO_PUBLIC_URL, alt: showText ? '' : 'Sybilion', className: S.icon, ...(showText ? { 'aria-hidden': true } : {}) }), showText && jsx("span", { className: S.text, children: "Sybilion" })] }));
|
|
7
12
|
}
|
|
8
13
|
|
|
9
|
-
export { Logo };
|
|
14
|
+
export { Logo, SYBILION_STANDALONE_LOGO_PUBLIC_URL };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import styleInject from 'style-inject';
|
|
2
2
|
|
|
3
|
-
var css_248z = ".Logo_root__-IFVw{align-items:center;color:var(--color-foreground);display:flex;gap:8px}.Logo_icon__cE1BI{height:24px;width:auto}.Logo_text__YpU3U{font-family:var(--font-family-heading);line-height:48px}.Logo_sm__p25D- .Logo_icon__cE1BI{height:18px}.Logo_sm__p25D- .Logo_text__YpU3U{font-size:var(--text-lg);line-height:36px}.Logo_md__1Y9mG .Logo_icon__cE1BI{height:24px}.Logo_md__1Y9mG .Logo_text__YpU3U{font-size:var(--text-2xl);line-height:48px}.Logo_lg__V9Yy2 .Logo_icon__cE1BI{height:32px}.Logo_lg__V9Yy2 .Logo_text__YpU3U{font-size:var(--text-3xl);line-height:56px}";
|
|
3
|
+
var css_248z = ".Logo_root__-IFVw{align-items:center;color:var(--color-foreground);display:flex;gap:8px}.Logo_icon__cE1BI{display:block;flex-shrink:0;height:24px;width:auto}.Logo_text__YpU3U{font-family:var(--font-family-heading);line-height:48px}.Logo_sm__p25D- .Logo_icon__cE1BI{height:18px}.Logo_sm__p25D- .Logo_text__YpU3U{font-size:var(--text-lg);line-height:36px}.Logo_md__1Y9mG .Logo_icon__cE1BI{height:24px}.Logo_md__1Y9mG .Logo_text__YpU3U{font-size:var(--text-2xl);line-height:48px}.Logo_lg__V9Yy2 .Logo_icon__cE1BI{height:32px}.Logo_lg__V9Yy2 .Logo_text__YpU3U{font-size:var(--text-3xl);line-height:56px}";
|
|
4
4
|
var S = {"root":"Logo_root__-IFVw","icon":"Logo_icon__cE1BI","text":"Logo_text__YpU3U","sm":"Logo_sm__p25D-","md":"Logo_md__1Y9mG","lg":"Logo_lg__V9Yy2"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import cn from 'classnames';
|
|
3
|
+
import { useTheme } from '../../../docs/contexts/theme-context.js';
|
|
3
4
|
import { UserCircleIcon, SunIcon, MoonIcon, SignOutIcon } from '@phosphor-icons/react';
|
|
4
5
|
import { ChevronDownIcon } from 'lucide-react';
|
|
5
6
|
import { Avatar } from '../Avatar/Avatar.js';
|
|
@@ -8,7 +9,8 @@ import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLab
|
|
|
8
9
|
import { Image } from '../Image/Image.js';
|
|
9
10
|
import S from './NavUserHeader.styl.js';
|
|
10
11
|
|
|
11
|
-
function NavUserHeader({ variant = 'default', isLoading = false, isAuthenticated, user = null, menuItems,
|
|
12
|
+
function NavUserHeader({ variant = 'default', isLoading = false, isAuthenticated, user = null, menuItems, onLogout, signInSlot, onSignInClick, }) {
|
|
13
|
+
const { toggleTheme, theme } = useTheme();
|
|
12
14
|
const authenticated = isAuthenticated ?? true;
|
|
13
15
|
const avatarUrl = user?.avatar ?? '';
|
|
14
16
|
const userName = user?.name ?? '';
|
|
@@ -22,7 +24,7 @@ function NavUserHeader({ variant = 'default', isLoading = false, isAuthenticated
|
|
|
22
24
|
}
|
|
23
25
|
return (jsxs(Button, { variant: "ghost", size: "sm", className: S.loginButton, type: "button", onClick: onSignInClick, children: [jsx(UserCircleIcon, { className: S.iconLg }), jsx("span", { children: "Log in" })] }));
|
|
24
26
|
}
|
|
25
|
-
return (jsxs(DropdownMenu, { children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsxs(Button, { variant: "ghost", size: "sm", className: cn(S.userButton, variant === 'compact' && S.compact), children: [jsx(Avatar, { className: S.avatar, children: jsx(Image, { url: avatarUrl, alt: userName, fallback: jsx("div", { className: S.avatarFallback }) }) }), variant === 'default' && (jsxs(Fragment, { children: [jsxs("div", { className: S.userInfo, children: [jsx("span", { className: `${S.userName} ph-no-capture`, children: userName }), jsx("span", { className: S.userEmail, children: userEmail })] }), jsx(ChevronDownIcon, { className: S.iconSm })] }))] }) }), jsxs(DropdownMenuContent, { className: S.dropdownContent, align: "end", elevation: "md", children: [jsx(DropdownMenuLabel, { className: S.userLabel, children: jsxs("div", { className: S.userLabelContent, children: [jsx(Avatar, { className: S.avatar, children: jsx(Image, { url: avatarUrl, alt: userName, fallback: jsx("div", { className: S.avatarFallback }) }) }), jsxs("div", { className: S.userDetails, children: [jsx("span", { className: `${S.userDetailName} ph-no-capture`, children: userName }), jsx("span", { className: S.userDetailEmail, children: userEmail })] })] }) }), jsx(DropdownMenuSeparator, {}), jsxs(DropdownMenuGroup, { children: [menuItems,
|
|
27
|
+
return (jsxs(DropdownMenu, { children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsxs(Button, { variant: "ghost", size: "sm", className: cn(S.userButton, variant === 'compact' && S.compact), children: [jsx(Avatar, { className: S.avatar, children: jsx(Image, { url: avatarUrl, alt: userName, fallback: jsx("div", { className: S.avatarFallback }) }) }), variant === 'default' && (jsxs(Fragment, { children: [jsxs("div", { className: S.userInfo, children: [jsx("span", { className: `${S.userName} ph-no-capture`, children: userName }), jsx("span", { className: S.userEmail, children: userEmail })] }), jsx(ChevronDownIcon, { className: S.iconSm })] }))] }) }), jsxs(DropdownMenuContent, { className: S.dropdownContent, align: "end", elevation: "md", children: [jsx(DropdownMenuLabel, { className: S.userLabel, children: jsxs("div", { className: S.userLabelContent, children: [jsx(Avatar, { className: S.avatar, children: jsx(Image, { url: avatarUrl, alt: userName, fallback: jsx("div", { className: S.avatarFallback }) }) }), jsxs("div", { className: S.userDetails, children: [jsx("span", { className: `${S.userDetailName} ph-no-capture`, children: userName }), jsx("span", { className: S.userDetailEmail, children: userEmail })] })] }) }), jsx(DropdownMenuSeparator, {}), jsxs(DropdownMenuGroup, { children: [menuItems, jsx(DropdownMenuItem, { onSelect: toggleTheme, children: theme === 'dark' ? (jsxs(Fragment, { children: [jsx(SunIcon, {}), "Light theme"] })) : (jsxs(Fragment, { children: [jsx(MoonIcon, {}), "Dark theme"] })) })] }), jsx(DropdownMenuSeparator, {}), jsxs(DropdownMenuItem, { variant: "destructive", onSelect: () => onLogout(), children: [jsx(SignOutIcon, {}), "Log out"] })] })] }));
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
export { NavUserHeader };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import styleInject from 'style-inject';
|
|
2
2
|
|
|
3
|
-
var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.Sidebar_sidebarWrapper__DGm4P{align-items:stretch;display:flex;flex-direction:row;--welcome-alert-height:44px;height:calc(100% - 44px);height:calc(100% - var(--welcome-alert-height));min-height:0;width:100%}.Sidebar_sidebarWrapper__DGm4P #page-sidebar-actions{min-height:100%}@media (max-width:768px){.Sidebar_sidebarWrapper__DGm4P{flex-direction:column;height:100dvh;max-height:100dvh}}.Sidebar_sidebarMainShell__pSWDC{display:flex;flex:1;flex-direction:column;min-height:0;min-width:0}.Sidebar_chatPanelMount__1Zctx{background:var(--background);border-left:1px solid var(--border);flex:0 0 0px;flex:0 0 var(--chat-panel-width,0px);min-height:0;min-width:0;overflow:hidden;width:0;width:var(--chat-panel-width,0)}@media (max-width:768px){.Sidebar_chatPanelMount__1Zctx{border-left:none;border-top:1px solid var(--border);flex:0 0 0px;flex:0 0 var(--chat-panel-height,0px);height:0;height:var(--chat-panel-height,0);transition:flex-basis .2s ease,height .2s ease;width:100%}}.Sidebar_sidebar__0vqNZ{height:0;position:fixed;--top-offset:-10px;--gap-top:calc(var(--header-height) + var(--top-offset));align-self:flex-start;color:var(--sidebar-foreground);display:none;flex-direction:column;top:var(--gap-top);width:var(--sidebar-width)}@media (min-width:768px){.Sidebar_sidebar__0vqNZ[data-state=expanded]{display:flex;height:calc(100vh - var(--gap-top));min-height:0}}.Sidebar_sidebar__0vqNZ[data-collapsible=offcanvas]{overflow:hidden;padding:0;width:0}.Sidebar_sidebarTrigger__ipx2C{cursor:pointer;height:var(--p-5);width:var(--p-5)}.Sidebar_sidebarTrigger__ipx2C svg{height:20px;width:20px}.Sidebar_sidebarRail__uvSpl{position:absolute;inset-y:0;display:hidden;transition:all ease-out;width:1rem;z-index:20}.Sidebar_sidebarRail__uvSpl:hover:after{background-color:var(--sidebar-border)}.Sidebar_sidebarRail__uvSpl[data-side=left]{right:-1rem}.Sidebar_sidebarRail__uvSpl[data-side=right]{left:0}.Sidebar_sidebarRail__uvSpl:after{content:\"\";position:absolute;inset-y:0;left:50%;width:2px}@media (min-width:640px){.Sidebar_sidebarRail__uvSpl{display:flex}}.Sidebar_sidebarRail__uvSpl[data-side=left]{cursor:w-resize}.Sidebar_sidebarRail__uvSpl[data-side=left][data-state=collapsed],.Sidebar_sidebarRail__uvSpl[data-side=right]{cursor:e-resize}.Sidebar_sidebarRail__uvSpl[data-side=right][data-state=collapsed]{cursor:w-resize}.Sidebar_sidebarRail__uvSpl[data-collapsible=offcanvas]{transform:translateX(0)}.Sidebar_sidebarRail__uvSpl[data-collapsible=offcanvas]:hover{background-color:var(--sidebar)}.Sidebar_sidebarRail__uvSpl[data-collapsible=offcanvas]:after{left:100%}.Sidebar_sidebarRail__uvSpl[data-side=left][data-collapsible=offcanvas]{right:-.5rem}.Sidebar_sidebarRail__uvSpl[data-side=right][data-collapsible=offcanvas]{left:-.5rem}.Sidebar_sidebarResizeHandle__kuD6t{background-color:transparent;background-color:var(--page-color);border-radius:2.5px;height:calc(100vh + 200px);opacity:0;position:absolute;top:-200px;touch-action:none;transition:opacity .15s ease-out;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:5px;z-index:30}.Sidebar_sidebarResizeHandle__kuD6t:before{content:\"\";cursor:col-resize;height:100%;position:absolute;right:0;width:30px}.Sidebar_sidebarResizeHandle__kuD6t[data-side=left]{right:2px}.Sidebar_sidebarResizeHandle__kuD6t[data-side=right]{left:0}.Sidebar_sidebarResizeHandle__kuD6t:hover{opacity:1}.Sidebar_sidebarResizeHandle__kuD6t:active{opacity:0}.Sidebar_fullHeightResizer__jZXnw .Sidebar_sidebarResizeHandle__kuD6t{height:calc(100vh - var(--gap-top)*-1);top:-80px}.Sidebar_sidebarInput__ujQLX{background-color:var(--background);box-shadow:none;height:2rem;width:100%}.Sidebar_sidebarFooter__V3O-l,.Sidebar_sidebarHeader__X33ii{display:flex;flex-direction:column;gap:0;padding:0}.Sidebar_sidebarSeparator__oUkYG{background-color:var(--sidebar-border);margin-left:0;margin-right:0;width:auto}.Sidebar_sidebarContent__Ywe1o{display:flex;flex:1;flex-direction:column;gap:var(--p-16);height:100vh;max-height:100vh;min-height:0;overflow:auto;position:absolute;width:100%}@media (min-width:768px){.Sidebar_sidebarContent__Ywe1o{height:calc(100vh - var(--gap-top))}}.Sidebar_sidebarContent__Ywe1o[data-collapsible=icon]{overflow:hidden}.Sidebar_sidebarGroup__7Mhg2{display:flex;flex-direction:column;min-width:0;padding:40px 0 0;position:relative;width:100%}.Sidebar_sidebarGroupAction__OhVZq{align-items:center;aspect-ratio:1;border-radius:.375rem;color:var(--sidebar-foreground);display:flex;justify-content:center;outline:none;padding:0;position:absolute;right:.75rem;top:.875rem;transition:transform;width:1.25rem}.Sidebar_sidebarGroupAction__OhVZq:hover{background-color:var(--sidebar-accent);color:var(--sidebar-accent-foreground)}.Sidebar_sidebarGroupAction__OhVZq:focus-visible{box-shadow:0 0 0 2px var(--sidebar-ring)}.Sidebar_sidebarGroupAction__OhVZq>svg{flex-shrink:0;height:1rem;width:1rem}.Sidebar_sidebarGroupAction__OhVZq:after{content:\"\";inset:-.5rem;position:absolute}@media (min-width:768px){.Sidebar_sidebarGroupAction__OhVZq:after{display:none}}.Sidebar_sidebarGroupAction__OhVZq[data-collapsible=icon]{display:none}.Sidebar_sidebarMenu__hYXIo{display:flex;flex-direction:column;gap:var(--p-4);list-style:none;min-width:0;padding:0 var(--p-11) var(--p-10) var(--p-8);width:100%}@media (max-width:768px){.Sidebar_sidebarMenu__hYXIo{padding-right:var(--p-8)}}.Sidebar_sidebarMenuItem__CRhM8{cursor:pointer;position:relative}.Sidebar_sidebarMenuBadge__ttvCR{align-items:center;border-radius:.375rem;color:var(--sidebar-foreground);display:flex;font-size:.75rem;font-weight:500;height:1.25rem;justify-content:center;min-width:1.25rem;padding-left:.25rem;padding-right:.25rem;pointer-events:none;position:absolute;right:.25rem;-webkit-user-select:none;-moz-user-select:none;user-select:none}.Sidebar_sidebarMenuBadge__ttvCR[data-size=sm]{top:.25rem}.Sidebar_sidebarMenuBadge__ttvCR[data-size=md]{top:.375rem}.Sidebar_sidebarMenuBadge__ttvCR[data-size=lg]{top:.625rem}.Sidebar_sidebarMenuBadge__ttvCR[data-collapsible=icon]{display:none}.Sidebar_sidebarMenuSkeleton__u2KoI{align-items:center;border-radius:.375rem;display:flex;gap:.5rem;height:2rem;padding-left:.5rem;padding-right:.5rem}.Sidebar_sidebarMenuSkeletonIcon__-1tvv{border-radius:.375rem;height:1rem;width:1rem}.Sidebar_sidebarMenuSkeletonText__dWzWo{flex:1;height:1rem;max-width:var(--skeleton-width)}.Sidebar_sidebarMenuSub__gh8Rn{border-color:var(--sidebar-border);border-left:none;display:flex;flex-direction:column;gap:var(--p-2);list-style:none;margin-left:0;margin-right:0;min-width:0;padding:0;padding-top:var(--p-1);position:relative;transform:translateX(1px)}.Sidebar_sidebarMenuSub__gh8Rn:before{background:var(--sidebar-border);bottom:26px;content:\"\";left:var(--p-5);pointer-events:none;position:absolute;top:0;width:1px}.Sidebar_sidebarMenuSub__gh8Rn[data-collapsible=icon]{display:none}.Sidebar_sidebarMenuSubItem__fTHJa{margin-left:var(--p-6);position:relative}.Sidebar_sidebarMenuSubItem__fTHJa:before{border-bottom:1px solid var(--sidebar-border);border-bottom-left-radius:var(--p-2);border-left:1px solid var(--sidebar-border);bottom:0;content:\"\";height:var(--p-3);left:calc(var(--p-1)*-1);position:absolute;top:var(--p-2);width:var(--p-3)}.Sidebar_sidebarMenuSubItem__fTHJa a:hover{text-decoration:none}.Sidebar_sheetContentSidebar__cM2h2{color:var(--sidebar-foreground);padding:0;width:var(--sidebar-width)}.Sidebar_sheetContentSidebar__cM2h2>button{display:none}@media (max-width:768px){.Sidebar_sheetContentSidebar__cM2h2{z-index:100}}.Sidebar_sheetSidebarInner__U-SMQ{background-color:var(--sidebar);display:flex;flex-direction:column;height:100%;width:100%}.Sidebar_sidebarNone__crRsF{color:var(--sidebar-foreground);display:flex;flex-direction:column;height:100%;width:var(--sidebar-width)}.Sidebar_variant-floating__-qvkJ{padding:.5rem}.Sidebar_variant-floating__-qvkJ[data-collapsible=icon],.Sidebar_variant-inset__oTfrV[data-collapsible=icon]{width:calc(var(--sidebar-width-icon) + 1rem + 2px)}.Sidebar_variant-sidebar__fAe77[data-collapsible=icon]{width:var(--sidebar-width-icon)}.Sidebar_variant-sidebar__fAe77[data-side=left]{border-right:1px solid #e5e7eb}.Sidebar_variant-sidebar__fAe77[data-side=right]{border-left:1px solid #e5e7eb}.Sidebar_sidebarMenuButton__vIEh->span,.Sidebar_sidebarMenuSubButton__c9flh>span{min-width:0;text-transform:capitalize}.Sidebar_sidebarMenuButton__vIEh->span:first-child,.Sidebar_sidebarMenuSubButton__c9flh>span:first-child{flex-grow:1}.Sidebar_sidebarMenuButton__vIEh-{align-items:center;border-radius:var(--p-3);color:var(--sidebar-foreground);cursor:pointer;display:flex;font-size:.875rem;gap:var(--p-2);justify-content:flex-start;outline:none;overflow:hidden;padding:var(--p-6) var(--p-3);text-align:left;text-decoration:none;transition:all;width:100%}.Sidebar_sidebarMenuButton__vIEh-:visited{color:var(--sidebar-foreground)}.Sidebar_sidebarMenuButton__vIEh-:hover{text-decoration:none}.Sidebar_sidebarMenuSubItem__fTHJa:active .Sidebar_sidebarMenuButton__vIEh-,.Sidebar_sidebarMenuSubItem__fTHJa:hover .Sidebar_sidebarMenuButton__vIEh-,.Sidebar_sidebarMenuSubItem__fTHJa[data-state=open] .Sidebar_sidebarMenuButton__vIEh-{background-color:var(--sidebar-accent);color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuButton__vIEh-:focus-visible{box-shadow:0 0 0 2px var(--sidebar-ring)}.Sidebar_sidebarMenuButton__vIEh-:disabled,.Sidebar_sidebarMenuButton__vIEh-[aria-disabled=true]{opacity:.5;pointer-events:none}.Sidebar_sidebarMenuButton__vIEh-[data-active=true]{background-color:var(--sidebar-accent);color:var(--sidebar-accent-foreground);font-weight:500}.Sidebar_sidebarMenuButton__vIEh-[data-collapsible=icon]{height:2rem!important;padding:.5rem!important;width:2rem!important}.Sidebar_sidebarMenuButton__vIEh->span{flex-grow:1;line-height:20px;overflow:hidden;white-space:nowrap}.Sidebar_sidebarMenuButton__vIEh->svg{flex-shrink:0;height:var(--p-5);width:var(--p-5)}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_size-sm__7aIbu{font-size:.75rem;height:1.75rem}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_size-md__rcjmO{font-size:.875rem;height:var(--p-12)}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_size-lg__1k76S{font-size:.875rem;height:3rem}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_size-lg__1k76S[data-collapsible=icon]{padding:0!important}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_variant-outline__UmtAz{background-color:var(--background);box-shadow:0 0 0 1px var(--sidebar-border)}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_variant-outline__UmtAz:hover{background-color:var(--sidebar-accent);box-shadow:0 0 0 1px var(--sidebar-accent);color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuButtonCta__dQAhv{display:flex;justify-content:flex-start;text-align:left;width:100%}.Sidebar_sidebarMenuButtonCta__dQAhv>svg{flex-shrink:0;height:var(--p-5);width:var(--p-5)}.Sidebar_sidebarMenuAction__mFZa1{align-items:center;aspect-ratio:1;border-radius:.375rem;color:var(--sidebar-foreground);cursor:pointer;display:flex;justify-content:center;opacity:0;outline:none;padding:0;position:absolute;right:var(--p-2);top:var(--p-2);transition:transform;width:1.25rem}.Sidebar_sidebarMenuAction__mFZa1:before{background-image:linear-gradient(to left,var(--sidebar-accent) 70%,transparent 100%);content:\"\";height:100%;pointer-events:none;position:absolute;right:0;transition:opacity .2s ease-in-out;width:calc(100% + var(--p-4))}.Sidebar_sidebarMenuSubItem__fTHJa:hover .Sidebar_sidebarMenuAction__mFZa1{opacity:1}.Sidebar_sidebarMenuAction__mFZa1:focus-visible{box-shadow:0 0 0 2px var(--sidebar-ring)}.Sidebar_sidebarMenuAction__mFZa1>svg{flex-shrink:0;height:1rem;opacity:.5;pointer-events:none;transition:opacity .2s ease-in-out;width:1rem;z-index:1}.Sidebar_sidebarMenuAction__mFZa1:hover>svg{opacity:1}.Sidebar_sidebarMenuAction__mFZa1:after{content:\"\";inset:-.5rem;position:absolute}@media (min-width:768px){.Sidebar_sidebarMenuAction__mFZa1:after{display:none}}.Sidebar_sidebarMenuAction__mFZa1[data-size=sm]{top:.25rem}.Sidebar_sidebarMenuAction__mFZa1[data-size=md]{top:.375rem}.Sidebar_sidebarMenuAction__mFZa1[data-size=lg]{top:.625rem}.Sidebar_sidebarMenuAction__mFZa1[data-collapsible=icon]{display:none}.Sidebar_sidebarMenuAction__mFZa1.Sidebar_showOnHover__itXsA[data-active=true]{color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuAction__mFZa1.Sidebar_showOnHover__itXsA[data-state=open]{opacity:1}@media (min-width:768px){.Sidebar_sidebarMenuAction__mFZa1.Sidebar_showOnHover__itXsA{opacity:0}.Sidebar_sidebarMenuAction__mFZa1.Sidebar_showOnHover__itXsA:focus-within,.Sidebar_sidebarMenuAction__mFZa1.Sidebar_showOnHover__itXsA:hover{opacity:1}}.Sidebar_sidebarMenuSubButton__c9flh{align-items:center;border-radius:var(--p-3);color:var(--sidebar-foreground);cursor:pointer;display:flex;gap:var(--p-1);height:var(--p-9);margin-left:var(--p-3);min-width:0;outline:none;overflow:hidden;padding:var(--p-1) var(--p-2);text-decoration:none;transform:translateX(-1px)}.Sidebar_sidebarMenuSubButton__c9flh:visited{color:var(--sidebar-foreground)}.Sidebar_sidebarMenuSubButton__c9flh:hover{text-decoration:none}.Sidebar_sidebarMenuSubItem__fTHJa:active .Sidebar_sidebarMenuSubButton__c9flh,.Sidebar_sidebarMenuSubItem__fTHJa:hover .Sidebar_sidebarMenuSubButton__c9flh{background-color:var(--sidebar-accent);color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuSubButton__c9flh:focus-visible{box-shadow:0 0 0 2px var(--sidebar-ring)}.Sidebar_sidebarMenuSubButton__c9flh:disabled,.Sidebar_sidebarMenuSubButton__c9flh[aria-disabled=true]{opacity:.5;pointer-events:none}.Sidebar_sidebarMenuSubButton__c9flh[data-active=true]{background-color:var(--sidebar-accent);color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuSubButton__c9flh[data-active=true]:visited{color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuSubButton__c9flh[data-collapsible=icon]{display:none}.Sidebar_sidebarMenuSubButton__c9flh>span:first-child{overflow:hidden;white-space:nowrap}.Sidebar_sidebarMenuSubButton__c9flh>svg{color:var(--sidebar-accent-foreground);flex-shrink:0;height:1rem;width:1rem}.Sidebar_sidebarMenuSubButton__c9flh.Sidebar_size-sm__7aIbu{font-size:.75rem}.Sidebar_sidebarMenuSubButton__c9flh.Sidebar_size-md__rcjmO{font-size:.875rem}.Sidebar_sidebarMenuSubButton__c9flh.Sidebar_size-lg__1k76S{font-size:1rem}::view-transition-old(sidebar-container),::view-transition-old(sidebar-gap){animation-duration:.2s;animation-name:Sidebar_sidebarVtOld__hlKqn;animation-timing-function:ease-out;transform:translateZ(0)}::view-transition-new(sidebar-container),::view-transition-new(sidebar-gap){animation-duration:.2s;animation-name:Sidebar_sidebarVtNew__FFhYU;animation-timing-function:ease-out;transform:translateZ(0)}@keyframes Sidebar_sidebarVtOld__hlKqn{0%{opacity:1}to{opacity:0}}@keyframes Sidebar_sidebarVtNew__FFhYU{0%{opacity:0}to{opacity:1}}";
|
|
3
|
+
var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.Sidebar_sidebarWrapper__DGm4P{align-items:stretch;display:flex;flex-direction:row;--welcome-alert-height:44px;height:calc(100% - 44px);height:calc(100% - var(--welcome-alert-height));min-height:0;width:100%}.Sidebar_sidebarWrapper__DGm4P #page-sidebar-actions{min-height:100%}@media (max-width:768px){.Sidebar_sidebarWrapper__DGm4P{flex-direction:column;height:100dvh;max-height:100dvh}}.Sidebar_sidebarMainShell__pSWDC{display:flex;flex:1;flex-direction:column;min-height:0;min-width:0}.Sidebar_chatPanelMount__1Zctx{background:var(--background);border-left:1px solid var(--border);flex:0 0 0px;flex:0 0 var(--chat-panel-width,0px);min-height:0;min-width:0;overflow:hidden;width:0;width:var(--chat-panel-width,0)}@media (max-width:768px){.Sidebar_chatPanelMount__1Zctx{border-left:none;border-top:1px solid var(--border);flex:0 0 0px;flex:0 0 var(--chat-panel-height,0px);height:0;height:var(--chat-panel-height,0);transition:flex-basis .2s ease,height .2s ease;width:100%}}.Sidebar_sidebar__0vqNZ{height:0;position:fixed;--top-offset:-10px;--gap-top:calc(var(--header-height) + var(--top-offset));align-self:flex-start;color:var(--sidebar-foreground);display:none;flex-direction:column;top:var(--gap-top);width:var(--sidebar-width)}@media (min-width:768px){.Sidebar_sidebar__0vqNZ[data-state=expanded]{display:flex;height:calc(100% - var(--gap-top));min-height:0}}.Sidebar_sidebar__0vqNZ[data-collapsible=offcanvas]{overflow:hidden;padding:0;width:0}.Sidebar_sidebarTrigger__ipx2C{cursor:pointer;height:var(--p-5);width:var(--p-5)}.Sidebar_sidebarTrigger__ipx2C svg{height:20px;width:20px}.Sidebar_sidebarRail__uvSpl{position:absolute;inset-y:0;display:hidden;transition:all ease-out;width:1rem;z-index:20}.Sidebar_sidebarRail__uvSpl:hover:after{background-color:var(--sidebar-border)}.Sidebar_sidebarRail__uvSpl[data-side=left]{right:-1rem}.Sidebar_sidebarRail__uvSpl[data-side=right]{left:0}.Sidebar_sidebarRail__uvSpl:after{content:\"\";position:absolute;inset-y:0;left:50%;width:2px}@media (min-width:640px){.Sidebar_sidebarRail__uvSpl{display:flex}}.Sidebar_sidebarRail__uvSpl[data-side=left]{cursor:w-resize}.Sidebar_sidebarRail__uvSpl[data-side=left][data-state=collapsed],.Sidebar_sidebarRail__uvSpl[data-side=right]{cursor:e-resize}.Sidebar_sidebarRail__uvSpl[data-side=right][data-state=collapsed]{cursor:w-resize}.Sidebar_sidebarRail__uvSpl[data-collapsible=offcanvas]{transform:translateX(0)}.Sidebar_sidebarRail__uvSpl[data-collapsible=offcanvas]:hover{background-color:var(--sidebar)}.Sidebar_sidebarRail__uvSpl[data-collapsible=offcanvas]:after{left:100%}.Sidebar_sidebarRail__uvSpl[data-side=left][data-collapsible=offcanvas]{right:-.5rem}.Sidebar_sidebarRail__uvSpl[data-side=right][data-collapsible=offcanvas]{left:-.5rem}.Sidebar_sidebarResizeHandle__kuD6t{background-color:transparent;background-color:var(--page-color);border-radius:2.5px;height:calc(100vh + 200px);opacity:0;position:absolute;top:-200px;touch-action:none;transition:opacity .15s ease-out;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:5px;z-index:30}.Sidebar_sidebarResizeHandle__kuD6t:before{content:\"\";cursor:col-resize;height:100%;position:absolute;right:0;width:30px}.Sidebar_sidebarResizeHandle__kuD6t[data-side=left]{right:2px}.Sidebar_sidebarResizeHandle__kuD6t[data-side=right]{left:0}.Sidebar_sidebarResizeHandle__kuD6t:hover{opacity:1}.Sidebar_sidebarResizeHandle__kuD6t:active{opacity:0}.Sidebar_fullHeightResizer__jZXnw .Sidebar_sidebarResizeHandle__kuD6t{height:calc(100vh - var(--gap-top)*-1);top:-80px}.Sidebar_sidebarInput__ujQLX{background-color:var(--background);box-shadow:none;height:2rem;width:100%}.Sidebar_sidebarFooter__V3O-l,.Sidebar_sidebarHeader__X33ii{display:flex;flex-direction:column;gap:0;padding:0}.Sidebar_sidebarSeparator__oUkYG{background-color:var(--sidebar-border);margin-left:0;margin-right:0;width:auto}.Sidebar_sidebarContent__Ywe1o{display:flex;flex:1;flex-direction:column;gap:var(--p-16);height:100vh;max-height:100vh;min-height:0;overflow:auto;position:absolute;width:100%}@media (min-width:768px){.Sidebar_sidebarContent__Ywe1o{height:calc(100vh - var(--gap-top))}}.Sidebar_sidebarContent__Ywe1o[data-collapsible=icon]{overflow:hidden}.Sidebar_sidebarGroup__7Mhg2{display:flex;flex-direction:column;min-width:0;padding:40px 0 0;position:relative;width:100%}.Sidebar_sidebarGroupAction__OhVZq{align-items:center;aspect-ratio:1;border-radius:.375rem;color:var(--sidebar-foreground);display:flex;justify-content:center;outline:none;padding:0;position:absolute;right:.75rem;top:.875rem;transition:transform;width:1.25rem}.Sidebar_sidebarGroupAction__OhVZq:hover{background-color:var(--sidebar-accent);color:var(--sidebar-accent-foreground)}.Sidebar_sidebarGroupAction__OhVZq:focus-visible{box-shadow:0 0 0 2px var(--sidebar-ring)}.Sidebar_sidebarGroupAction__OhVZq>svg{flex-shrink:0;height:1rem;width:1rem}.Sidebar_sidebarGroupAction__OhVZq:after{content:\"\";inset:-.5rem;position:absolute}@media (min-width:768px){.Sidebar_sidebarGroupAction__OhVZq:after{display:none}}.Sidebar_sidebarGroupAction__OhVZq[data-collapsible=icon]{display:none}.Sidebar_sidebarMenu__hYXIo{display:flex;flex-direction:column;gap:var(--p-4);list-style:none;min-width:0;padding:0 var(--p-11) var(--p-10) var(--p-8);width:100%}@media (max-width:768px){.Sidebar_sidebarMenu__hYXIo{padding-right:var(--p-8)}}.Sidebar_sidebarMenuItem__CRhM8{cursor:pointer;position:relative}.Sidebar_sidebarMenuBadge__ttvCR{align-items:center;border-radius:.375rem;color:var(--sidebar-foreground);display:flex;font-size:.75rem;font-weight:500;height:1.25rem;justify-content:center;min-width:1.25rem;padding-left:.25rem;padding-right:.25rem;pointer-events:none;position:absolute;right:.25rem;-webkit-user-select:none;-moz-user-select:none;user-select:none}.Sidebar_sidebarMenuBadge__ttvCR[data-size=sm]{top:.25rem}.Sidebar_sidebarMenuBadge__ttvCR[data-size=md]{top:.375rem}.Sidebar_sidebarMenuBadge__ttvCR[data-size=lg]{top:.625rem}.Sidebar_sidebarMenuBadge__ttvCR[data-collapsible=icon]{display:none}.Sidebar_sidebarMenuSkeleton__u2KoI{align-items:center;border-radius:.375rem;display:flex;gap:.5rem;height:2rem;padding-left:.5rem;padding-right:.5rem}.Sidebar_sidebarMenuSkeletonIcon__-1tvv{border-radius:.375rem;height:1rem;width:1rem}.Sidebar_sidebarMenuSkeletonText__dWzWo{flex:1;height:1rem;max-width:var(--skeleton-width)}.Sidebar_sidebarMenuSub__gh8Rn{border-color:var(--sidebar-border);border-left:none;display:flex;flex-direction:column;gap:var(--p-2);list-style:none;margin-left:0;margin-right:0;min-width:0;padding:0;padding-top:var(--p-1);position:relative;transform:translateX(1px)}.Sidebar_sidebarMenuSub__gh8Rn:before{background:var(--sidebar-border);bottom:26px;content:\"\";left:var(--p-5);pointer-events:none;position:absolute;top:0;width:1px}.Sidebar_sidebarMenuSub__gh8Rn[data-collapsible=icon]{display:none}.Sidebar_sidebarMenuSubItem__fTHJa{margin-left:var(--p-6);position:relative}.Sidebar_sidebarMenuSubItem__fTHJa:before{border-bottom:1px solid var(--sidebar-border);border-bottom-left-radius:var(--p-2);border-left:1px solid var(--sidebar-border);bottom:0;content:\"\";height:var(--p-3);left:calc(var(--p-1)*-1);position:absolute;top:var(--p-2);width:var(--p-3)}.Sidebar_sidebarMenuSubItem__fTHJa a:hover{text-decoration:none}.Sidebar_sheetContentSidebar__cM2h2{color:var(--sidebar-foreground);padding:0;width:var(--sidebar-width)}.Sidebar_sheetContentSidebar__cM2h2>button{display:none}@media (max-width:768px){.Sidebar_sheetContentSidebar__cM2h2{z-index:100}}.Sidebar_sheetSidebarInner__U-SMQ{background-color:var(--sidebar);display:flex;flex-direction:column;height:100%;width:100%}.Sidebar_sidebarNone__crRsF{color:var(--sidebar-foreground);display:flex;flex-direction:column;height:100%;width:var(--sidebar-width)}.Sidebar_variant-floating__-qvkJ{padding:.5rem}.Sidebar_variant-floating__-qvkJ[data-collapsible=icon],.Sidebar_variant-inset__oTfrV[data-collapsible=icon]{width:calc(var(--sidebar-width-icon) + 1rem + 2px)}.Sidebar_variant-sidebar__fAe77[data-collapsible=icon]{width:var(--sidebar-width-icon)}.Sidebar_variant-sidebar__fAe77[data-side=left]{border-right:1px solid #e5e7eb}.Sidebar_variant-sidebar__fAe77[data-side=right]{border-left:1px solid #e5e7eb}.Sidebar_sidebarMenuButton__vIEh->span,.Sidebar_sidebarMenuSubButton__c9flh>span{min-width:0;text-transform:capitalize}.Sidebar_sidebarMenuButton__vIEh->span:first-child,.Sidebar_sidebarMenuSubButton__c9flh>span:first-child{flex-grow:1}.Sidebar_sidebarMenuButton__vIEh-{align-items:center;border-radius:var(--p-3);color:var(--sidebar-foreground);cursor:pointer;display:flex;font-size:.875rem;gap:var(--p-2);justify-content:flex-start;outline:none;overflow:hidden;padding:var(--p-6) var(--p-3);text-align:left;text-decoration:none;transition:all;width:100%}.Sidebar_sidebarMenuButton__vIEh-:visited{color:var(--sidebar-foreground)}.Sidebar_sidebarMenuButton__vIEh-:hover{text-decoration:none}.Sidebar_sidebarMenuSubItem__fTHJa:active .Sidebar_sidebarMenuButton__vIEh-,.Sidebar_sidebarMenuSubItem__fTHJa:hover .Sidebar_sidebarMenuButton__vIEh-,.Sidebar_sidebarMenuSubItem__fTHJa[data-state=open] .Sidebar_sidebarMenuButton__vIEh-{background-color:var(--sidebar-accent);color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuButton__vIEh-:focus-visible{box-shadow:0 0 0 2px var(--sidebar-ring)}.Sidebar_sidebarMenuButton__vIEh-:disabled,.Sidebar_sidebarMenuButton__vIEh-[aria-disabled=true]{opacity:.5;pointer-events:none}.Sidebar_sidebarMenuButton__vIEh-[data-active=true]{background-color:var(--sidebar-accent);color:var(--sidebar-accent-foreground);font-weight:500}.Sidebar_sidebarMenuButton__vIEh-[data-collapsible=icon]{height:2rem!important;padding:.5rem!important;width:2rem!important}.Sidebar_sidebarMenuButton__vIEh->span{flex-grow:1;line-height:20px;overflow:hidden;white-space:nowrap}.Sidebar_sidebarMenuButton__vIEh->svg{flex-shrink:0;height:var(--p-5);width:var(--p-5)}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_size-sm__7aIbu{font-size:.75rem;height:1.75rem}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_size-md__rcjmO{font-size:.875rem;height:var(--p-12)}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_size-lg__1k76S{font-size:.875rem;height:3rem}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_size-lg__1k76S[data-collapsible=icon]{padding:0!important}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_variant-outline__UmtAz{background-color:var(--background);box-shadow:0 0 0 1px var(--sidebar-border)}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_variant-outline__UmtAz:hover{background-color:var(--sidebar-accent);box-shadow:0 0 0 1px var(--sidebar-accent);color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuButtonCta__dQAhv{display:flex;justify-content:flex-start;text-align:left;width:100%}.Sidebar_sidebarMenuButtonCta__dQAhv>svg{flex-shrink:0;height:var(--p-5);width:var(--p-5)}.Sidebar_sidebarMenuAction__mFZa1{align-items:center;aspect-ratio:1;border-radius:.375rem;color:var(--sidebar-foreground);cursor:pointer;display:flex;justify-content:center;opacity:0;outline:none;padding:0;position:absolute;right:var(--p-2);top:var(--p-2);transition:transform;width:1.25rem}.Sidebar_sidebarMenuAction__mFZa1:before{background-image:linear-gradient(to left,var(--sidebar-accent) 70%,transparent 100%);content:\"\";height:100%;pointer-events:none;position:absolute;right:0;transition:opacity .2s ease-in-out;width:calc(100% + var(--p-4))}.Sidebar_sidebarMenuSubItem__fTHJa:hover .Sidebar_sidebarMenuAction__mFZa1{opacity:1}.Sidebar_sidebarMenuAction__mFZa1:focus-visible{box-shadow:0 0 0 2px var(--sidebar-ring)}.Sidebar_sidebarMenuAction__mFZa1>svg{flex-shrink:0;height:1rem;opacity:.5;pointer-events:none;transition:opacity .2s ease-in-out;width:1rem;z-index:1}.Sidebar_sidebarMenuAction__mFZa1:hover>svg{opacity:1}.Sidebar_sidebarMenuAction__mFZa1:after{content:\"\";inset:-.5rem;position:absolute}@media (min-width:768px){.Sidebar_sidebarMenuAction__mFZa1:after{display:none}}.Sidebar_sidebarMenuAction__mFZa1[data-size=sm]{top:.25rem}.Sidebar_sidebarMenuAction__mFZa1[data-size=md]{top:.375rem}.Sidebar_sidebarMenuAction__mFZa1[data-size=lg]{top:.625rem}.Sidebar_sidebarMenuAction__mFZa1[data-collapsible=icon]{display:none}.Sidebar_sidebarMenuAction__mFZa1.Sidebar_showOnHover__itXsA[data-active=true]{color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuAction__mFZa1.Sidebar_showOnHover__itXsA[data-state=open]{opacity:1}@media (min-width:768px){.Sidebar_sidebarMenuAction__mFZa1.Sidebar_showOnHover__itXsA{opacity:0}.Sidebar_sidebarMenuAction__mFZa1.Sidebar_showOnHover__itXsA:focus-within,.Sidebar_sidebarMenuAction__mFZa1.Sidebar_showOnHover__itXsA:hover{opacity:1}}.Sidebar_sidebarMenuSubButton__c9flh{align-items:center;border-radius:var(--p-3);color:var(--sidebar-foreground);cursor:pointer;display:flex;gap:var(--p-1);height:var(--p-9);margin-left:var(--p-3);min-width:0;outline:none;overflow:hidden;padding:var(--p-1) var(--p-2);text-decoration:none;transform:translateX(-1px)}.Sidebar_sidebarMenuSubButton__c9flh:visited{color:var(--sidebar-foreground)}.Sidebar_sidebarMenuSubButton__c9flh:hover{text-decoration:none}.Sidebar_sidebarMenuSubItem__fTHJa:active .Sidebar_sidebarMenuSubButton__c9flh,.Sidebar_sidebarMenuSubItem__fTHJa:hover .Sidebar_sidebarMenuSubButton__c9flh{background-color:var(--sidebar-accent);color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuSubButton__c9flh:focus-visible{box-shadow:0 0 0 2px var(--sidebar-ring)}.Sidebar_sidebarMenuSubButton__c9flh:disabled,.Sidebar_sidebarMenuSubButton__c9flh[aria-disabled=true]{opacity:.5;pointer-events:none}.Sidebar_sidebarMenuSubButton__c9flh[data-active=true]{background-color:var(--sidebar-accent);color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuSubButton__c9flh[data-active=true]:visited{color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuSubButton__c9flh[data-collapsible=icon]{display:none}.Sidebar_sidebarMenuSubButton__c9flh>span:first-child{overflow:hidden;white-space:nowrap}.Sidebar_sidebarMenuSubButton__c9flh>svg{color:var(--sidebar-accent-foreground);flex-shrink:0;height:1rem;width:1rem}.Sidebar_sidebarMenuSubButton__c9flh.Sidebar_size-sm__7aIbu{font-size:.75rem}.Sidebar_sidebarMenuSubButton__c9flh.Sidebar_size-md__rcjmO{font-size:.875rem}.Sidebar_sidebarMenuSubButton__c9flh.Sidebar_size-lg__1k76S{font-size:1rem}::view-transition-old(sidebar-container),::view-transition-old(sidebar-gap){animation-duration:.2s;animation-name:Sidebar_sidebarVtOld__hlKqn;animation-timing-function:ease-out;transform:translateZ(0)}::view-transition-new(sidebar-container),::view-transition-new(sidebar-gap){animation-duration:.2s;animation-name:Sidebar_sidebarVtNew__FFhYU;animation-timing-function:ease-out;transform:translateZ(0)}@keyframes Sidebar_sidebarVtOld__hlKqn{0%{opacity:1}to{opacity:0}}@keyframes Sidebar_sidebarVtNew__FFhYU{0%{opacity:0}to{opacity:1}}";
|
|
4
4
|
var SidebarStem = {"sidebarWrapper":"Sidebar_sidebarWrapper__DGm4P","sidebarMainShell":"Sidebar_sidebarMainShell__pSWDC","chatPanelMount":"Sidebar_chatPanelMount__1Zctx","sidebar":"Sidebar_sidebar__0vqNZ","sidebarTrigger":"Sidebar_sidebarTrigger__ipx2C","sidebarRail":"Sidebar_sidebarRail__uvSpl","sidebarResizeHandle":"Sidebar_sidebarResizeHandle__kuD6t","fullHeightResizer":"Sidebar_fullHeightResizer__jZXnw","sidebarInput":"Sidebar_sidebarInput__ujQLX","sidebarHeader":"Sidebar_sidebarHeader__X33ii","sidebarFooter":"Sidebar_sidebarFooter__V3O-l","sidebarSeparator":"Sidebar_sidebarSeparator__oUkYG","sidebarContent":"Sidebar_sidebarContent__Ywe1o","sidebarGroup":"Sidebar_sidebarGroup__7Mhg2","sidebarGroupAction":"Sidebar_sidebarGroupAction__OhVZq","sidebarMenu":"Sidebar_sidebarMenu__hYXIo","sidebarMenuItem":"Sidebar_sidebarMenuItem__CRhM8","sidebarMenuBadge":"Sidebar_sidebarMenuBadge__ttvCR","sidebarMenuSkeleton":"Sidebar_sidebarMenuSkeleton__u2KoI","sidebarMenuSkeletonIcon":"Sidebar_sidebarMenuSkeletonIcon__-1tvv","sidebarMenuSkeletonText":"Sidebar_sidebarMenuSkeletonText__dWzWo","sidebarMenuSub":"Sidebar_sidebarMenuSub__gh8Rn","sidebarMenuSubItem":"Sidebar_sidebarMenuSubItem__fTHJa","sheetContentSidebar":"Sidebar_sheetContentSidebar__cM2h2","sheetSidebarInner":"Sidebar_sheetSidebarInner__U-SMQ","sidebarNone":"Sidebar_sidebarNone__crRsF","variant-floating":"Sidebar_variant-floating__-qvkJ","variant-inset":"Sidebar_variant-inset__oTfrV","variant-sidebar":"Sidebar_variant-sidebar__fAe77","sidebarMenuButton":"Sidebar_sidebarMenuButton__vIEh-","sidebarMenuSubButton":"Sidebar_sidebarMenuSubButton__c9flh","size-sm":"Sidebar_size-sm__7aIbu","size-md":"Sidebar_size-md__rcjmO","size-lg":"Sidebar_size-lg__1k76S","variant-outline":"Sidebar_variant-outline__UmtAz","sidebarMenuButtonCta":"Sidebar_sidebarMenuButtonCta__dQAhv","sidebarMenuAction":"Sidebar_sidebarMenuAction__mFZa1","showOnHover":"Sidebar_showOnHover__itXsA","sidebarVtOld":"Sidebar_sidebarVtOld__hlKqn","sidebarVtNew":"Sidebar_sidebarVtNew__FFhYU"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import cn from 'classnames';
|
|
3
|
+
import { Link } from 'react-router-dom';
|
|
3
4
|
import { AppHeaderPortal } from '../../ui/AppHeader/AppHeader.js';
|
|
4
5
|
import { PAGE_HEADER_ACTIONS_ID } from '../../ui/AppHeader/appChromeAnchors.js';
|
|
5
6
|
import { Gap } from '../../ui/Gap/Gap.js';
|
|
7
|
+
import { Logo } from '../../ui/Logo/Logo.js';
|
|
6
8
|
import { NavUserHeader } from '../../ui/NavUserHeader/NavUserHeader.js';
|
|
7
9
|
import { WorkspaceAppSwitcher } from '../../ui/WorkspaceAppSwitcher/WorkspaceAppSwitcher.js';
|
|
8
10
|
import '@phosphor-icons/react';
|
|
9
11
|
import 'lucide-react';
|
|
10
12
|
import S from './SybilionAppHeader.styl.js';
|
|
11
13
|
|
|
12
|
-
function SybilionAppHeader({ pageHeaderId, actionsAnchorId = PAGE_HEADER_ACTIONS_ID, actionsAnchorClassName, pathname, onNavigate, authenticated, defaultApps, appsStorageKey, ...navUserHeaderProps }) {
|
|
13
|
-
return (jsxs(AppHeaderPortal, { pageHeaderId: pageHeaderId, children: [jsx(WorkspaceAppSwitcher, { pathname: pathname, onNavigate: onNavigate, authenticated: authenticated, defaultApps: defaultApps, appsStorageKey: appsStorageKey }), jsx(Gap, {}), jsx("div", { id: actionsAnchorId, className: cn(S.actionsAnchor, actionsAnchorClassName), children: jsx(NavUserHeader, { ...navUserHeaderProps }) })] }));
|
|
14
|
+
function SybilionAppHeader({ pageHeaderId, actionsAnchorId = PAGE_HEADER_ACTIONS_ID, actionsAnchorClassName, pathname, onNavigate, authenticated, defaultApps, appsStorageKey, logo, logoAreaClassName, welcomeBannerOffset, ...navUserHeaderProps }) {
|
|
15
|
+
return (jsxs(AppHeaderPortal, { pageHeaderId: pageHeaderId, children: [jsx("div", { className: cn(S.logoArea, welcomeBannerOffset && S.logoAreaWithBanner, logoAreaClassName), children: jsx(Link, { to: "/", className: S.logoLink, children: logo ?? jsx(Logo, { size: "md", "aria-hidden": true }) }) }), jsx(WorkspaceAppSwitcher, { pathname: pathname, onNavigate: onNavigate, authenticated: authenticated, defaultApps: defaultApps, appsStorageKey: appsStorageKey }), jsx(Gap, {}), jsx("div", { id: actionsAnchorId, className: cn(S.actionsAnchor, actionsAnchorClassName), children: jsx(NavUserHeader, { ...navUserHeaderProps }) })] }));
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
export { SybilionAppHeader };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import styleInject from 'style-inject';
|
|
2
2
|
|
|
3
|
-
var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.SybilionAppHeader_actionsAnchor__ress2{align-items:center;display:flex;flex-shrink:0;gap:var(--p-4)}";
|
|
4
|
-
var S = {"actionsAnchor":"SybilionAppHeader_actionsAnchor__ress2"};
|
|
3
|
+
var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.SybilionAppHeader_actionsAnchor__ress2{align-items:center;display:flex;flex-shrink:0;gap:var(--p-4)}.SybilionAppHeader_logoArea__3HAhG{align-items:center;display:flex;gap:var(--p-2);left:40px;position:absolute;top:22px;z-index:10}@media (max-width:768px){.SybilionAppHeader_logoArea__3HAhG{left:32px}}@media (min-width:768px){[data-slot=sidebar-wrapper][data-state=expanded] .SybilionAppHeader_logoArea__3HAhG{position:fixed}}.SybilionAppHeader_logoAreaWithBanner__7Iy78{top:22px;top:calc(22px + var(--welcome-banner-height, 0px))}@media (min-width:768px){[data-slot=sidebar-wrapper][data-state=collapsed] .SybilionAppHeader_logoAreaWithBanner__7Iy78{top:22px}}.SybilionAppHeader_logoLink__bH-KX{align-items:center;color:var(--color-foreground);display:flex;font-size:1.5rem;font-weight:400;gap:.5rem;text-decoration:none;white-space:nowrap;width:-moz-fit-content;width:fit-content}.SybilionAppHeader_logoLink__bH-KX svg{display:inline-flex;flex-shrink:0;height:32px;transition:transform .1s ease-in-out;width:auto}.SybilionAppHeader_logoLink__bH-KX:hover svg{transform:scale(1.05)}";
|
|
4
|
+
var S = {"actionsAnchor":"SybilionAppHeader_actionsAnchor__ress2","logoArea":"SybilionAppHeader_logoArea__3HAhG","logoAreaWithBanner":"SybilionAppHeader_logoAreaWithBanner__7Iy78","logoLink":"SybilionAppHeader_logoLink__bH-KX"};
|
|
5
5
|
styleInject(css_248z);
|
|
6
6
|
|
|
7
7
|
export { S as default };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import 'react/jsx-runtime';
|
|
2
|
+
import { createContext, useContext } from 'react';
|
|
3
|
+
import '@homecode/ui';
|
|
4
|
+
import '../lib/theme.js';
|
|
5
|
+
|
|
6
|
+
const ThemeContext = createContext({
|
|
7
|
+
theme: 'light',
|
|
8
|
+
isDarkMode: false,
|
|
9
|
+
setTheme: () => { },
|
|
10
|
+
toggleTheme: () => { },
|
|
11
|
+
});
|
|
12
|
+
const useTheme = () => useContext(ThemeContext);
|
|
13
|
+
|
|
14
|
+
export { useTheme };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ThemeHelpers, ThemeDefaults } from '@homecode/ui';
|
|
2
|
+
|
|
3
|
+
const { colors, getColors, getConfig } = ThemeDefaults;
|
|
4
|
+
getColors();
|
|
5
|
+
getConfig();
|
|
6
|
+
({
|
|
7
|
+
light: {
|
|
8
|
+
...ThemeHelpers.colorsConfigToVars({
|
|
9
|
+
...getColors({
|
|
10
|
+
accent: colors.dark,
|
|
11
|
+
decent: colors.light,
|
|
12
|
+
}),
|
|
13
|
+
}),
|
|
14
|
+
},
|
|
15
|
+
dark: {
|
|
16
|
+
...ThemeHelpers.colorsConfigToVars({
|
|
17
|
+
...getColors({
|
|
18
|
+
accent: colors.light,
|
|
19
|
+
decent: colors.dark,
|
|
20
|
+
}),
|
|
21
|
+
}),
|
|
22
|
+
},
|
|
23
|
+
});
|
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
import type { LogoProps } from './Logo.types';
|
|
2
|
+
/**
|
|
3
|
+
* Public URL for the Sybilion logo in standalone apps. Copy `@sybilion/uilib/logo.svg`
|
|
4
|
+
* to `public/logo.svg` (see standalone-apps guide). Same path as the favicon `<link href>`.
|
|
5
|
+
*/
|
|
6
|
+
export declare const SYBILION_STANDALONE_LOGO_PUBLIC_URL: "/logo.svg";
|
|
2
7
|
export declare function Logo({ showText, size, className, ...props }: LogoProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { NavUserHeaderProps } from './NavUserHeader.types';
|
|
2
|
-
export declare function NavUserHeader({ variant, isLoading, isAuthenticated, user, menuItems,
|
|
2
|
+
export declare function NavUserHeader({ variant, isLoading, isAuthenticated, user, menuItems, onLogout, signInSlot, onSignInClick, }: NavUserHeaderProps): string | number | bigint | true | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode>> | import("react/jsx-runtime").JSX.Element;
|
|
@@ -14,10 +14,6 @@ export type NavUserHeaderProps = {
|
|
|
14
14
|
user?: NavUserHeaderUser | null;
|
|
15
15
|
/** Rows inside the menu above theme toggle and logout. Use `DropdownMenuItem` nodes. */
|
|
16
16
|
menuItems?: ReactNode;
|
|
17
|
-
/** Current theme drives the toggle row label/icons. */
|
|
18
|
-
theme: 'light' | 'dark';
|
|
19
|
-
/** When set, renders the light/dark theme menu row. */
|
|
20
|
-
onThemeToggle?: () => void;
|
|
21
17
|
onLogout: () => void;
|
|
22
18
|
/** Replaces default “Log in” control when signed out. */
|
|
23
19
|
signInSlot?: ReactNode;
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
1
2
|
import type { NavUserHeaderProps } from '#uilib/components/ui/NavUserHeader';
|
|
2
3
|
import { type WorkspaceAppSwitcherProps } from '#uilib/components/ui/WorkspaceAppSwitcher';
|
|
3
4
|
export type SybilionAppHeaderProps = WorkspaceAppSwitcherProps & NavUserHeaderProps & {
|
|
4
5
|
pageHeaderId?: string;
|
|
5
6
|
actionsAnchorId?: string;
|
|
6
7
|
actionsAnchorClassName?: string;
|
|
8
|
+
/** Branded markup; omit for default lucide tile + «Sybilion». */
|
|
9
|
+
logo?: ReactNode;
|
|
10
|
+
logoAreaClassName?: string;
|
|
11
|
+
/** Applies vertical offset when a welcome banner consumes top space (CSS `--welcome-banner-height` on shell). */
|
|
12
|
+
welcomeBannerOffset?: boolean;
|
|
7
13
|
};
|
|
8
|
-
export declare function SybilionAppHeader({ pageHeaderId, actionsAnchorId, actionsAnchorClassName, pathname, onNavigate, authenticated, defaultApps, appsStorageKey, ...navUserHeaderProps }: SybilionAppHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export declare function SybilionAppHeader({ pageHeaderId, actionsAnchorId, actionsAnchorClassName, pathname, onNavigate, authenticated, defaultApps, appsStorageKey, logo, logoAreaClassName, welcomeBannerOffset, ...navUserHeaderProps }: SybilionAppHeaderProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/esm/types/src/docs/pages/StandaloneAppLayoutPage/StandaloneAppLayoutPage.constants.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { WorkspaceAppEntry } from '#uilib/components/ui/WorkspaceAppSwitcher';
|
|
2
|
+
import { SidebarDatasetsItemsGroupedDataset } from '#uilib/components/widgets/SidebarDatasetsItemsGrouped';
|
|
3
|
+
export declare const MOCK_DATASETS: SidebarDatasetsItemsGroupedDataset[];
|
|
4
|
+
export type PreviewPanel = 'home' | 'datasets';
|
|
5
|
+
export declare const TEST_HEADER_ID = "test-header-id";
|
|
6
|
+
export declare const DOCS_WORKSPACE_APPS_LS_KEY = "uilib.docs.workspaceApps";
|
|
7
|
+
export declare const DOCS_PREVIEW_APPS: WorkspaceAppEntry[];
|
package/docs/standalone-apps.md
CHANGED
|
@@ -15,12 +15,48 @@ yarn add react react-dom react-router-dom @auth0/auth0-react @sybilion/uilib @sy
|
|
|
15
15
|
yarn add -D vite @vitejs/plugin-react
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
**React ecosystem versions (avoid collisions):** declare **`react`**, **`react-dom`**, **`react-router-dom`**, and **`@auth0/auth0-react`** as **direct** dependencies and align them with **`@sybilion/uilib`**, not arbitrary latest majors.
|
|
19
|
+
|
|
20
|
+
1. After installing uilib, open **`node_modules/@sybilion/uilib/package.json`** (or this repo’s root **`package.json`** at the release you pin).
|
|
21
|
+
2. **`peerDependencies`** — satisfy these ranges in your app (`react` / `react-dom`, `react-router-dom`, `@auth0/auth0-react`, and **`vite`** when you use the Vite helpers).
|
|
22
|
+
3. **`devDependencies`** — for **`react`**, **`react-dom`**, and **`react-router-dom`**, prefer **the same versions uilib lists there** (what its docs build and tests run against). Re-read this file whenever you bump **`@sybilion/uilib`** so your app does not drift to another React major while uilib does not.
|
|
23
|
+
|
|
24
|
+
Mismatched or duplicated React (two copies in the bundle) causes **invalid hook call** / subtle runtime bugs — and specifically causes **Radix UI interactive widgets** (dropdowns, dialogs, tooltips) to **silently fail** (context broken across the module boundary). If Yarn/npm hoists a second React, fix upstream ranges or use **`resolutions`** (Yarn) / **`overrides`** (npm) so the tree resolves to **one** `react` / `react-dom` pair matching (3). Also add `dedupe` + `@radix-ui/` alias in `vite.config.ts` (see **Local dev: Vite API proxy**).
|
|
25
|
+
|
|
26
|
+
**Current required versions (as of uilib 1.2.x):** `react` / `react-dom` **`^19`**, `@types/react` / `@types/react-dom` **`^19`**. Add resolutions so nested copies stay aligned:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"resolutions": {
|
|
31
|
+
"@types/react": "^19",
|
|
32
|
+
"@types/react-dom": "^19"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
18
37
|
Import tokens/fonts once (typically `src/main.tsx`):
|
|
19
38
|
|
|
20
39
|
```ts
|
|
21
40
|
import '@sybilion/uilib/standalone-global.css';
|
|
22
41
|
```
|
|
23
42
|
|
|
43
|
+
### Branding (header logo + optional tab icon)
|
|
44
|
+
|
|
45
|
+
**Header:** **`SybilionAppHeader`** includes **`Logo`** from **`@sybilion/uilib`**. **`Logo`** uses **`SYBILION_STANDALONE_LOGO_PUBLIC_URL`** (**`'/logo.svg'`**). Vite serves that from **`public/logo.svg`**. Copy the published file once:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
mkdir -p public && cp node_modules/@sybilion/uilib/logo.svg public/logo.svg
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
That asset is **`src/assets/logo.svg`** in the package (**cyan** glyph). The **uilib docs** repo uses **`assets/logo.svg`** (**purple**) for its own site only—not what **`./logo.svg`** publishes.
|
|
52
|
+
|
|
53
|
+
**Browser tab (optional):** The favicon (tiny icon next to the tab title) and the document title come from **`index.html`**, not from React. **`Logo`** does not set them. To replace Vite’s default tab icon with the package logo, add **`href="/logo.svg"`** — same as **`SYBILION_STANDALONE_LOGO_PUBLIC_URL`** from **`@sybilion/uilib`** — plus **`<title>`** in **`index.html`** `<head>`:
|
|
54
|
+
|
|
55
|
+
```html
|
|
56
|
+
<link rel="icon" href="/logo.svg" type="image/svg+xml" />
|
|
57
|
+
<title>Your app name</title>
|
|
58
|
+
```
|
|
59
|
+
|
|
24
60
|
Mount the tree with `ReactDOM.createRoot` → `App` (wrap with `StrictMode` if you want).
|
|
25
61
|
|
|
26
62
|
### `package.json` scripts (required)
|
|
@@ -99,16 +135,39 @@ Package README: [`@sybilion/sdk`](https://www.npmjs.com/package/@sybilion/sdk)
|
|
|
99
135
|
|
|
100
136
|
## Local dev: Vite API proxy
|
|
101
137
|
|
|
102
|
-
Avoid browser CORS in development by serving the SPA from Vite and proxying **`/api`** to the real API.
|
|
138
|
+
Avoid browser CORS in development by serving the SPA from Vite and proxying **`/api`** to the real API.
|
|
139
|
+
|
|
140
|
+
**Reference `vite.config.ts` (minimal standalone Sybilion SPA):** merge your own `plugins` / options into this shape; keep `resolve.dedupe` and the `@radix-ui/` alias unless you know the dependency tree dedupes React and Radix correctly on its own.
|
|
141
|
+
|
|
142
|
+
- **`sybilionStandaloneViteDev`** (`@sybilion/uilib/vite-standalone-dev`) — reads **`PORT`** (defaults **3000** if unset or invalid) for **`server`** and **`preview`** bind; sets **`proxy['/api']`** → **`VITE_SYBILION_API_BASE_URL`** with `changeOrigin` and `secure: true`. Pass Vite’s **`mode`** so env (including `VITE_*`) and proxy target resolve the same way as `vite` / `vite build`.
|
|
143
|
+
- **`defineConfig(({ mode }) => …)`** — callback form gives `mode` per command (`development` / `production` / …); forward it into `sybilionStandaloneViteDev`.
|
|
144
|
+
- **`plugins: [react()]`** — add other plugins (e.g. SVGR) in the same array.
|
|
145
|
+
- **`resolve.dedupe`** — force one physical copy of `react`, `react-dom`, `react-router`, and `react-router-dom`. If the app and `@sybilion/uilib` resolve different copies, React context and router state break (`Invalid hook call`, blank subtree, Radix menus that never open). `react-router` is listed because it is a shared transitive dependency of the router packages and can duplicate independently.
|
|
146
|
+
- **`resolve.alias` for `@radix-ui/*`** — uilib’s published bundle uses bare `@radix-ui/react-*` imports. Yarn/npm can still place those packages under `node_modules/@sybilion/uilib/node_modules/@radix-ui/…`, so Vite may bundle two Radix trees and split React context across them. The regex alias rewrites every `@radix-ui/…` import to **`./node_modules/@radix-ui/`** (project root). **`path.resolve(… ) + '/'`** is required so subpaths like `@radix-ui/react-dialog` resolve under that folder.
|
|
147
|
+
- **`path`** — Node built-in `node:path`; only used at config evaluation time.
|
|
103
148
|
|
|
104
149
|
```ts
|
|
150
|
+
// vite.config.ts — reference config for a standalone app using @sybilion/uilib + proxy.
|
|
105
151
|
import { sybilionStandaloneViteDev } from '@sybilion/uilib/vite-standalone-dev';
|
|
106
152
|
import react from '@vitejs/plugin-react';
|
|
153
|
+
import path from 'node:path';
|
|
107
154
|
import { defineConfig } from 'vite';
|
|
108
155
|
|
|
156
|
+
// Pass `mode` into sybilionStandaloneViteDev so proxy + VITE_* match the active Vite command.
|
|
109
157
|
export default defineConfig(({ mode }) => ({
|
|
110
158
|
...sybilionStandaloneViteDev({ mode }),
|
|
111
159
|
plugins: [react()],
|
|
160
|
+
resolve: {
|
|
161
|
+
// One copy of React + Router across app and uilib (avoids invalid hook call / dead Radix UI).
|
|
162
|
+
dedupe: ['react', 'react-dom', 'react-router', 'react-router-dom'],
|
|
163
|
+
alias: [
|
|
164
|
+
{
|
|
165
|
+
find: /^@radix-ui\//,
|
|
166
|
+
// Pin all Radix imports to the app’s root node_modules; trailing slash keeps subpaths working.
|
|
167
|
+
replacement: path.resolve('./node_modules/@radix-ui/') + '/',
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
},
|
|
112
171
|
}));
|
|
113
172
|
```
|
|
114
173
|
|
|
@@ -169,6 +228,44 @@ export function AppProviders({ children }: { children: ReactNode }) {
|
|
|
169
228
|
|
|
170
229
|
**Hooks:** `useSybilionAuth()`, `useSybilionApiFetch()` (or `createSybilionApiFetch` / `sybilionApiFetch` helpers).
|
|
171
230
|
|
|
231
|
+
### Loading the user profile for `SybilionAppHeader`
|
|
232
|
+
|
|
233
|
+
`useSybilionAuth()` gives you `isAuthenticated` / `logout` but **not** a user object. Fetch it once with `sybilionSdk.auth.getMe()` after authentication. The response shape is:
|
|
234
|
+
|
|
235
|
+
```ts
|
|
236
|
+
// GET /api/v1/users/me → { data: { user: BackendUser }, message, status }
|
|
237
|
+
// BackendUser includes `picture` (profile image URL from the API). Do not read deprecated `avatar` on the wire.
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**Agents:** import **`MeResponse`** (and rely on **`BackendUser`** inside it) from `@sybilion/sdk`. Profile image on the API is **`picture` only**; `NavUserHeader` / `SybilionAppHeader` still expect the prop key **`avatar`**—map with `avatar: u.picture ?? ''`. No `UserProfile` intersections, no `u.avatar` fallback, no manual `res as { data?: … }` once `getMe()` is typed.
|
|
241
|
+
|
|
242
|
+
`NavUserHeader` (used inside `SybilionAppHeader`) accepts `user: { name, email, avatar? }`.
|
|
243
|
+
|
|
244
|
+
```ts
|
|
245
|
+
import type { MeResponse } from '@sybilion/sdk';
|
|
246
|
+
|
|
247
|
+
useEffect(() => {
|
|
248
|
+
if (!isAuthenticated) {
|
|
249
|
+
setUser(null);
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
sybilionSdk.auth
|
|
253
|
+
.getMe()
|
|
254
|
+
.then((res: MeResponse) => {
|
|
255
|
+
const u = res.data?.user;
|
|
256
|
+
if (u)
|
|
257
|
+
setUser({
|
|
258
|
+
name: u.name,
|
|
259
|
+
email: u.email,
|
|
260
|
+
avatar: u.picture ?? '',
|
|
261
|
+
});
|
|
262
|
+
})
|
|
263
|
+
.catch(() => undefined);
|
|
264
|
+
}, [isAuthenticated]);
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Pass `user` (or `null` while loading with `isLoading` on `NavUserHeader`) and `isAuthenticated` to `SybilionAppHeader`.
|
|
268
|
+
|
|
172
269
|
## 4. Layout (AppShell)
|
|
173
270
|
|
|
174
271
|
With §2 `sybilionSdk` and §3 `AppProviders` / `SybilionAuthProvider` defined, compose routing + shell so Auth0 callbacks and JWT-backed hooks wrap the whole UI.
|
|
@@ -275,7 +372,7 @@ export function AppLayout({ children }: { children: ReactNode }) {
|
|
|
275
372
|
}
|
|
276
373
|
```
|
|
277
374
|
|
|
278
|
-
Wire **`authenticated`**, **`user`** / **`isAuthenticated`**, **`theme`** / **`onLogout`**, **`menuItems`**, and **`defaultApps`** / **`appsStorageKey`** to real auth and workspace config (`useSybilionAuth`, §3). **`NavUserHeader`** behavior reference: `src/docs/pages/NavUserHeaderPage.tsx` (slug `nav-user-header`). Full shell preview: `src/docs/pages/StandaloneAppLayoutPage
|
|
375
|
+
Wire **`authenticated`**, **`user`** / **`isAuthenticated`**, **`theme`** / **`onLogout`**, **`menuItems`**, and **`defaultApps`** / **`appsStorageKey`** to real auth and workspace config (`useSybilionAuth`, §3). **`NavUserHeader`** behavior reference: `src/docs/pages/NavUserHeaderPage.tsx` (slug `nav-user-header`). Full shell preview: `src/docs/pages/StandaloneAppLayoutPage` (slug **`standalone-app-layout`**).
|
|
279
376
|
|
|
280
377
|
#### Sidebar (`AppSidebar.tsx`)
|
|
281
378
|
|
|
@@ -391,16 +488,18 @@ Composition: `PageScroll` → `AppShell` → `AppSidebar` → `AppShellMainConte
|
|
|
391
488
|
|
|
392
489
|
### Greenfield checklist (agents)
|
|
393
490
|
|
|
394
|
-
| Step | Deliverable
|
|
395
|
-
| ------------------ |
|
|
396
|
-
|
|
|
397
|
-
|
|
|
398
|
-
|
|
|
399
|
-
|
|
|
400
|
-
|
|
|
401
|
-
|
|
|
402
|
-
|
|
|
403
|
-
|
|
|
491
|
+
| Step | Deliverable |
|
|
492
|
+
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
493
|
+
| React / router | **`react`**, **`react-dom`**, **`react-router-dom`**, **`@auth0/auth0-react`** (and **`vite`** if applicable) aligned with **`@sybilion/uilib`** **`package.json`** — §1 _React ecosystem versions_. |
|
|
494
|
+
| Env files | **`.env.example`** (committed) + **`.env`** locally; **`PORT=3000`** recommended for Auth0 test tenant; **`VITE_*`** as in §1 table. |
|
|
495
|
+
| Scripts | **`package.json`** includes mandatory **`dev`** (e.g. `"vite"`); optional **`build`**, **`preview`**. |
|
|
496
|
+
| Vite proxy | **`vite.config.ts`** spreads **`sybilionStandaloneViteDev({ mode })`**; SDK **`baseUrl`** empty in dev (§2). |
|
|
497
|
+
| Files | `src/libs/sybilion-sdk.ts`, `AppProviders.tsx`, `AppLayout.tsx`, `AppSidebar.tsx`, `App.tsx`, `main.tsx`, route pages under e.g. `src/pages/`. |
|
|
498
|
+
| Branding | **`public/logo.svg`** for **`Logo`** / **`SybilionAppHeader`**: `cp node_modules/@sybilion/uilib/logo.svg public/logo.svg`. **`index.html`**: `<title>`; optional **`<link rel="icon">`** for tab icon (§1 _Branding_). |
|
|
499
|
+
| Pages + UI | **§4 Route page body** (mandatory stack) + **Discovering** (barrel-first; bespoke markup only when no export fits). |
|
|
500
|
+
| Auth0 | SPA callback / logout URLs + allowed web origins → **`http://localhost:<PORT>`** for local dev and deploy URLs (and previews). |
|
|
501
|
+
| API | **Dev:** proxy handles API traffic (no browser CORS to API). **Prod:** Sybilion backend **CORS** → your deploy `Origin`, unless API is same-origin. |
|
|
502
|
+
| Go (if applicable) | Server proxies **`/api`** to Sybilion; SPA dev **`baseUrl`** stays `''` when same-origin. |
|
|
404
503
|
|
|
405
504
|
### Glossary (high-use pieces)
|
|
406
505
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sybilion/uilib",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.8",
|
|
4
4
|
"description": "Sybilion Design System — React UI components (Webpack + Stylus)",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
"types": "./dist/standalone/vite-sybilion-standalone-dev.d.ts",
|
|
36
36
|
"import": "./dist/standalone/vite-sybilion-standalone-dev.js",
|
|
37
37
|
"default": "./dist/standalone/vite-sybilion-standalone-dev.js"
|
|
38
|
-
}
|
|
38
|
+
},
|
|
39
|
+
"./logo.svg": "./src/assets/logo.svg"
|
|
39
40
|
},
|
|
40
41
|
"files": [
|
|
41
42
|
"assets",
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
|
2
|
+
<path fill="#59f0ff" d="M13.43 24.023h-2.836v-2.836h2.836zm-2.835-2.844H5.63v-2.74h4.965Zm10.527-2.74h-2.726v2.74h-4.965v-2.74h4.952v-4.965h2.74zm-15.5 0h-2.74v-4.965h2.74ZM2.87 13.462H.034v-2.836H2.87Zm21.096 0H21.13v-2.836h2.836zM5.617 10.635h-2.74V5.669h2.74zm15.505 0h-2.74V5.669h2.74zM10.588 2.927v2.74H5.623v-2.74Zm2.842 0h4.96v2.74h-4.966v-2.74h-2.83V.09h2.836z" style="stroke-width:.13252" />
|
|
3
|
+
</svg>
|
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|
min-height var(--header-height)
|
|
10
10
|
background-color var(--color-background)
|
|
11
11
|
|
|
12
|
+
@media (min-width MOBILE)
|
|
13
|
+
:global([data-slot='sidebar-wrapper'][data-state='collapsed']) &
|
|
14
|
+
padding-left 200px
|
|
15
|
+
max-width 100%
|
|
16
|
+
|
|
12
17
|
.content
|
|
13
18
|
display flex
|
|
14
19
|
align-items center
|
|
@@ -3,6 +3,12 @@ import cn from 'classnames';
|
|
|
3
3
|
import S from './Logo.styl';
|
|
4
4
|
import type { LogoProps } from './Logo.types';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Public URL for the Sybilion logo in standalone apps. Copy `@sybilion/uilib/logo.svg`
|
|
8
|
+
* to `public/logo.svg` (see standalone-apps guide). Same path as the favicon `<link href>`.
|
|
9
|
+
*/
|
|
10
|
+
export const SYBILION_STANDALONE_LOGO_PUBLIC_URL = '/logo.svg' as const;
|
|
11
|
+
|
|
6
12
|
export function Logo({
|
|
7
13
|
showText = true,
|
|
8
14
|
size = 'md',
|
|
@@ -11,7 +17,12 @@ export function Logo({
|
|
|
11
17
|
}: LogoProps) {
|
|
12
18
|
return (
|
|
13
19
|
<div className={cn(S.root, S[size], className)} {...props}>
|
|
14
|
-
<img
|
|
20
|
+
<img
|
|
21
|
+
src={SYBILION_STANDALONE_LOGO_PUBLIC_URL}
|
|
22
|
+
alt={showText ? '' : 'Sybilion'}
|
|
23
|
+
className={S.icon}
|
|
24
|
+
{...(showText ? { 'aria-hidden': true } : {})}
|
|
25
|
+
/>
|
|
15
26
|
{showText && <span className={S.text}>Sybilion</span>}
|
|
16
27
|
</div>
|
|
17
28
|
);
|