@opencosmos/ui 1.3.3 → 1.3.5
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/index.d.mts +8 -4
- package/dist/index.d.ts +8 -4
- package/dist/index.js +39 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +39 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/layout/AppSidebar.tsx +55 -6
package/dist/index.d.mts
CHANGED
|
@@ -2441,8 +2441,10 @@ interface AppSidebarProviderProps {
|
|
|
2441
2441
|
children: React__default.ReactNode;
|
|
2442
2442
|
/** Initial open state used on server and first render @default true */
|
|
2443
2443
|
defaultOpen?: boolean;
|
|
2444
|
+
/** localStorage key for persisting open state. Use unique keys per page to avoid cross-page state bleed. @default 'appsidebar:state' */
|
|
2445
|
+
storageKey?: string;
|
|
2444
2446
|
}
|
|
2445
|
-
declare function AppSidebarProvider({ children, defaultOpen }: AppSidebarProviderProps): react_jsx_runtime.JSX.Element;
|
|
2447
|
+
declare function AppSidebarProvider({ children, defaultOpen, storageKey }: AppSidebarProviderProps): react_jsx_runtime.JSX.Element;
|
|
2446
2448
|
declare function AppSidebarInset({ children, className, }: {
|
|
2447
2449
|
children: React__default.ReactNode;
|
|
2448
2450
|
className?: string;
|
|
@@ -2459,16 +2461,18 @@ interface AppSidebarProps {
|
|
|
2459
2461
|
logo?: React__default.ReactNode;
|
|
2460
2462
|
/** Wordmark shown next to the logo when expanded */
|
|
2461
2463
|
title?: string;
|
|
2462
|
-
/** Navigation items */
|
|
2464
|
+
/** Navigation items rendered at the top (below the header) */
|
|
2463
2465
|
items?: AppSidebarNavItem[];
|
|
2464
|
-
/**
|
|
2466
|
+
/** Navigation items rendered at the bottom (above the footer) */
|
|
2467
|
+
bottomItems?: AppSidebarNavItem[];
|
|
2468
|
+
/** Body slot — rendered in the flex-1 mid-section (e.g. conversation history). Only visible when expanded. */
|
|
2465
2469
|
children?: React__default.ReactNode;
|
|
2466
2470
|
/** Footer slot — auth section, user avatar, sign-in prompt, etc. */
|
|
2467
2471
|
footer?: React__default.ReactNode;
|
|
2468
2472
|
/** Additional className for the <aside> */
|
|
2469
2473
|
className?: string;
|
|
2470
2474
|
}
|
|
2471
|
-
declare function AppSidebar({ logo, title, items, children, footer, className, }: AppSidebarProps): react_jsx_runtime.JSX.Element;
|
|
2475
|
+
declare function AppSidebar({ logo, title, items, bottomItems, children, footer, className, }: AppSidebarProps): react_jsx_runtime.JSX.Element;
|
|
2472
2476
|
|
|
2473
2477
|
interface StackProps extends React__default.HTMLAttributes<HTMLDivElement> {
|
|
2474
2478
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -2441,8 +2441,10 @@ interface AppSidebarProviderProps {
|
|
|
2441
2441
|
children: React__default.ReactNode;
|
|
2442
2442
|
/** Initial open state used on server and first render @default true */
|
|
2443
2443
|
defaultOpen?: boolean;
|
|
2444
|
+
/** localStorage key for persisting open state. Use unique keys per page to avoid cross-page state bleed. @default 'appsidebar:state' */
|
|
2445
|
+
storageKey?: string;
|
|
2444
2446
|
}
|
|
2445
|
-
declare function AppSidebarProvider({ children, defaultOpen }: AppSidebarProviderProps): react_jsx_runtime.JSX.Element;
|
|
2447
|
+
declare function AppSidebarProvider({ children, defaultOpen, storageKey }: AppSidebarProviderProps): react_jsx_runtime.JSX.Element;
|
|
2446
2448
|
declare function AppSidebarInset({ children, className, }: {
|
|
2447
2449
|
children: React__default.ReactNode;
|
|
2448
2450
|
className?: string;
|
|
@@ -2459,16 +2461,18 @@ interface AppSidebarProps {
|
|
|
2459
2461
|
logo?: React__default.ReactNode;
|
|
2460
2462
|
/** Wordmark shown next to the logo when expanded */
|
|
2461
2463
|
title?: string;
|
|
2462
|
-
/** Navigation items */
|
|
2464
|
+
/** Navigation items rendered at the top (below the header) */
|
|
2463
2465
|
items?: AppSidebarNavItem[];
|
|
2464
|
-
/**
|
|
2466
|
+
/** Navigation items rendered at the bottom (above the footer) */
|
|
2467
|
+
bottomItems?: AppSidebarNavItem[];
|
|
2468
|
+
/** Body slot — rendered in the flex-1 mid-section (e.g. conversation history). Only visible when expanded. */
|
|
2465
2469
|
children?: React__default.ReactNode;
|
|
2466
2470
|
/** Footer slot — auth section, user avatar, sign-in prompt, etc. */
|
|
2467
2471
|
footer?: React__default.ReactNode;
|
|
2468
2472
|
/** Additional className for the <aside> */
|
|
2469
2473
|
className?: string;
|
|
2470
2474
|
}
|
|
2471
|
-
declare function AppSidebar({ logo, title, items, children, footer, className, }: AppSidebarProps): react_jsx_runtime.JSX.Element;
|
|
2475
|
+
declare function AppSidebar({ logo, title, items, bottomItems, children, footer, className, }: AppSidebarProps): react_jsx_runtime.JSX.Element;
|
|
2472
2476
|
|
|
2473
2477
|
interface StackProps extends React__default.HTMLAttributes<HTMLDivElement> {
|
|
2474
2478
|
/**
|
package/dist/index.js
CHANGED
|
@@ -11073,13 +11073,13 @@ var DEFAULT_CONTEXT = {
|
|
|
11073
11073
|
function useAppSidebar() {
|
|
11074
11074
|
return (0, import_react19.useContext)(AppSidebarContext) ?? DEFAULT_CONTEXT;
|
|
11075
11075
|
}
|
|
11076
|
-
function AppSidebarProvider({ children, defaultOpen = true }) {
|
|
11076
|
+
function AppSidebarProvider({ children, defaultOpen = true, storageKey = STORAGE_KEY }) {
|
|
11077
11077
|
const [isOpen, setIsOpen] = (0, import_react19.useState)(defaultOpen);
|
|
11078
11078
|
(0, import_react19.useEffect)(() => {
|
|
11079
|
-
const stored = localStorage.getItem(
|
|
11079
|
+
const stored = localStorage.getItem(storageKey);
|
|
11080
11080
|
if (stored !== null) setIsOpen(stored === "true");
|
|
11081
|
-
}, []);
|
|
11082
|
-
const persist3 = (value) => localStorage.setItem(
|
|
11081
|
+
}, [storageKey]);
|
|
11082
|
+
const persist3 = (value) => localStorage.setItem(storageKey, String(value));
|
|
11083
11083
|
const toggle = () => setIsOpen((prev) => {
|
|
11084
11084
|
const next = !prev;
|
|
11085
11085
|
persist3(next);
|
|
@@ -11118,6 +11118,7 @@ function AppSidebar({
|
|
|
11118
11118
|
logo,
|
|
11119
11119
|
title,
|
|
11120
11120
|
items = [],
|
|
11121
|
+
bottomItems = [],
|
|
11121
11122
|
children,
|
|
11122
11123
|
footer,
|
|
11123
11124
|
className
|
|
@@ -11232,6 +11233,40 @@ function AppSidebar({
|
|
|
11232
11233
|
children
|
|
11233
11234
|
}
|
|
11234
11235
|
),
|
|
11236
|
+
bottomItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("nav", { className: "px-2 py-2 space-y-1 shrink-0 border-t border-foreground/8", "aria-label": "Bottom navigation", children: bottomItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(
|
|
11237
|
+
"a",
|
|
11238
|
+
{
|
|
11239
|
+
href: item.href,
|
|
11240
|
+
target: item.external ? "_blank" : void 0,
|
|
11241
|
+
rel: item.external ? "noopener noreferrer" : void 0,
|
|
11242
|
+
title: !isOpen ? item.label : void 0,
|
|
11243
|
+
"aria-label": !isOpen ? item.label : void 0,
|
|
11244
|
+
className: cn(
|
|
11245
|
+
"flex items-center rounded-lg transition-colors duration-150",
|
|
11246
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus)]",
|
|
11247
|
+
isOpen ? "gap-3 px-3 py-3" : "justify-center w-9 h-9 mx-auto",
|
|
11248
|
+
item.active ? "bg-foreground/8 text-foreground font-medium" : "text-[var(--color-text-secondary)] hover:bg-foreground/5 hover:text-[var(--color-text-primary)]"
|
|
11249
|
+
),
|
|
11250
|
+
children: [
|
|
11251
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { className: "shrink-0 flex items-center justify-center w-4 h-4", children: item.icon }),
|
|
11252
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
11253
|
+
"span",
|
|
11254
|
+
{
|
|
11255
|
+
className: "text-sm whitespace-nowrap",
|
|
11256
|
+
style: {
|
|
11257
|
+
opacity: isOpen ? 1 : 0,
|
|
11258
|
+
width: isOpen ? "auto" : 0,
|
|
11259
|
+
overflow: "hidden",
|
|
11260
|
+
pointerEvents: isOpen ? "auto" : "none",
|
|
11261
|
+
transition: shouldAnimate ? `opacity ${Math.round(duration * 0.55)}ms ease-out` : "none"
|
|
11262
|
+
},
|
|
11263
|
+
children: item.label
|
|
11264
|
+
}
|
|
11265
|
+
)
|
|
11266
|
+
]
|
|
11267
|
+
},
|
|
11268
|
+
item.label
|
|
11269
|
+
)) }),
|
|
11235
11270
|
footer && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
11236
11271
|
"div",
|
|
11237
11272
|
{
|