@olwiba/ui 0.0.33 → 0.0.35
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.ts +5 -1
- package/dist/index.js +23 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/app/AppShell.tsx +37 -5
- package/src/components/ThemeSwitchMinimal.tsx +6 -1
package/package.json
CHANGED
package/src/app/AppShell.tsx
CHANGED
|
@@ -87,6 +87,10 @@ export interface AppShellProps {
|
|
|
87
87
|
user?: AppShellUser;
|
|
88
88
|
/** Text shown in the top header bar */
|
|
89
89
|
pageTitle?: string;
|
|
90
|
+
/** Slot rendered at the start of the top header bar, after the sidebar trigger. */
|
|
91
|
+
headerStart?: ReactNode;
|
|
92
|
+
/** Slot rendered at the end of the top header bar. */
|
|
93
|
+
headerEnd?: ReactNode;
|
|
90
94
|
/** Override link rendering for SPA navigation. Defaults to a native <a>. */
|
|
91
95
|
renderLink?: AppShellRenderLink;
|
|
92
96
|
children?: ReactNode;
|
|
@@ -203,18 +207,26 @@ function ShellSidebar({
|
|
|
203
207
|
side: 'left' | 'right';
|
|
204
208
|
sidebarPosition: 'viewport' | 'contained';
|
|
205
209
|
}) {
|
|
210
|
+
const fallbackLogo = typeof brand.name === 'string' ? brand.name.slice(0, 1).toUpperCase() : null;
|
|
211
|
+
|
|
206
212
|
return (
|
|
207
213
|
<Sidebar side={side} collapsible={collapsible} sidebarPosition={sidebarPosition}>
|
|
208
214
|
<SidebarHeader>
|
|
209
215
|
<SidebarMenu>
|
|
210
216
|
<SidebarMenuItem>
|
|
211
|
-
<SidebarMenuButton asChild className="data-[slot=sidebar-menu-button]:!p-1.5">
|
|
217
|
+
<SidebarMenuButton asChild tooltip={typeof brand.name === 'string' ? brand.name : undefined} className="data-[slot=sidebar-menu-button]:!p-1.5">
|
|
212
218
|
{renderLink({
|
|
213
219
|
href: brand.href ?? '#',
|
|
214
220
|
children: (
|
|
215
221
|
<>
|
|
216
|
-
{brand.logo
|
|
217
|
-
|
|
222
|
+
{brand.logo ?? (
|
|
223
|
+
<span className="flex size-4 shrink-0 items-center justify-center text-sm font-semibold">
|
|
224
|
+
{fallbackLogo}
|
|
225
|
+
</span>
|
|
226
|
+
)}
|
|
227
|
+
<span className="min-w-0 truncate text-base font-semibold group-data-[collapsible=icon]:hidden">
|
|
228
|
+
{brand.name}
|
|
229
|
+
</span>
|
|
218
230
|
</>
|
|
219
231
|
),
|
|
220
232
|
})}
|
|
@@ -287,13 +299,31 @@ function ShellSidebar({
|
|
|
287
299
|
);
|
|
288
300
|
}
|
|
289
301
|
|
|
290
|
-
function ShellHeader({
|
|
302
|
+
function ShellHeader({
|
|
303
|
+
pageTitle,
|
|
304
|
+
headerStart,
|
|
305
|
+
headerEnd,
|
|
306
|
+
}: {
|
|
307
|
+
pageTitle: string;
|
|
308
|
+
headerStart?: ReactNode;
|
|
309
|
+
headerEnd?: ReactNode;
|
|
310
|
+
}) {
|
|
291
311
|
return (
|
|
292
312
|
<header className="flex h-12 shrink-0 items-center gap-2 border-b transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-12">
|
|
293
313
|
<div className="flex w-full items-center gap-1 px-4 lg:gap-2 lg:px-6">
|
|
294
314
|
<SidebarTrigger className="-ml-1" />
|
|
315
|
+
{headerStart && (
|
|
316
|
+
<div className="flex items-center gap-1">
|
|
317
|
+
{headerStart}
|
|
318
|
+
</div>
|
|
319
|
+
)}
|
|
295
320
|
<Separator orientation="vertical" className="mx-2 data-[orientation=vertical]:h-4" />
|
|
296
321
|
<h1 className="text-base font-medium">{pageTitle}</h1>
|
|
322
|
+
{headerEnd && (
|
|
323
|
+
<div className="ml-auto flex items-center gap-1">
|
|
324
|
+
{headerEnd}
|
|
325
|
+
</div>
|
|
326
|
+
)}
|
|
297
327
|
</div>
|
|
298
328
|
</header>
|
|
299
329
|
);
|
|
@@ -323,6 +353,8 @@ export function AppShell({
|
|
|
323
353
|
action,
|
|
324
354
|
user = defaultUser,
|
|
325
355
|
pageTitle = 'Dashboard',
|
|
356
|
+
headerStart,
|
|
357
|
+
headerEnd,
|
|
326
358
|
renderLink = defaultRenderLink,
|
|
327
359
|
collapsible = 'icon',
|
|
328
360
|
sidebarPosition = 'viewport',
|
|
@@ -347,7 +379,7 @@ export function AppShell({
|
|
|
347
379
|
sidebarPosition={sidebarPosition}
|
|
348
380
|
/>
|
|
349
381
|
<SidebarInset className={isContained ? undefined : 'overflow-y-auto'}>
|
|
350
|
-
<ShellHeader pageTitle={pageTitle} />
|
|
382
|
+
<ShellHeader pageTitle={pageTitle} headerStart={headerStart} headerEnd={headerEnd} />
|
|
351
383
|
{children}
|
|
352
384
|
</SidebarInset>
|
|
353
385
|
</SidebarProvider>
|
|
@@ -22,7 +22,12 @@ export function ThemeSwitchMinimal() {
|
|
|
22
22
|
|
|
23
23
|
return (
|
|
24
24
|
<Button variant="ghost" size="icon" onClick={toggle} className="size-8" aria-label="Toggle theme">
|
|
25
|
-
|
|
25
|
+
<span
|
|
26
|
+
key={theme}
|
|
27
|
+
className="inline-flex size-4 items-center justify-center animate-in fade-in zoom-in-75 spin-in-90 duration-200 motion-reduce:animate-none"
|
|
28
|
+
>
|
|
29
|
+
{theme === 'dark' ? <Sun className="size-4" /> : <Moon className="size-4" />}
|
|
30
|
+
</span>
|
|
26
31
|
</Button>
|
|
27
32
|
);
|
|
28
33
|
}
|