mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-03 16:16:59 +00:00
feat: draw the rail's add app button in the page skeleton
This commit is contained in:
@@ -44,6 +44,7 @@
|
||||
@custom-variant boot-no-calendar (&:where([data-boot-rail]:not([data-boot-rail~="calendar"]) *));
|
||||
@custom-variant boot-no-contacts (&:where([data-boot-rail]:not([data-boot-rail~="contacts"]) *));
|
||||
@custom-variant boot-no-files (&:where([data-boot-rail]:not([data-boot-rail~="files"]) *));
|
||||
@custom-variant boot-rail-add-app (&:where([data-boot-rail~="add-app"] *));
|
||||
@custom-variant boot-rail-admin (&:where([data-boot-rail~="admin"] *));
|
||||
@custom-variant boot-rail-a11y (&:where([data-boot-rail~="a11y"] *));
|
||||
@custom-variant boot-rail-quota (&:where([data-boot-rail~="quota"] *));
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
Keyboard,
|
||||
Mail,
|
||||
Menu,
|
||||
Plus,
|
||||
Settings,
|
||||
Shield,
|
||||
Users,
|
||||
@@ -66,6 +67,9 @@ export function RailSkeleton({ active, className }: { active?: RailApp; classNam
|
||||
<Icon className={cn("w-[18px] h-[18px] flex-shrink-0", active === id && "text-primary")} />
|
||||
</span>
|
||||
))}
|
||||
<span className={cn(item(false), "hidden boot-rail-add-app:flex")}>
|
||||
<Plus className="w-[18px] h-[18px] flex-shrink-0" />
|
||||
</span>
|
||||
</div>
|
||||
<div className="mt-auto flex flex-col items-center gap-2 pb-3 px-1 text-muted-foreground">
|
||||
<span className={cn(footerItem, "hidden boot-rail-admin:flex")}>
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
"use client";
|
||||
|
||||
import { useTranslations } from "next-intl";
|
||||
import type { RailLabels } from "./shell";
|
||||
|
||||
/**
|
||||
* The few strings a page skeleton shows: the status message and the phone
|
||||
* bottom bar's labels. For the gates of client pages, which have the message
|
||||
* catalog; the skeleton components themselves stay free of next-intl.
|
||||
*/
|
||||
export function useSkeletonLabels(): { label: string; labels: RailLabels } {
|
||||
const t = useTranslations();
|
||||
return {
|
||||
label: t("common.loading"),
|
||||
labels: {
|
||||
mail: t("sidebar.mail"),
|
||||
calendar: t("sidebar.calendar"),
|
||||
contacts: t("sidebar.contacts"),
|
||||
files: t("sidebar.files"),
|
||||
settings: t("sidebar.settings"),
|
||||
admin: t("sidebar.admin"),
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -357,13 +357,14 @@ export function NavigationRail({
|
||||
if (!client) return;
|
||||
const items: RailHint[] = [];
|
||||
for (const item of navItems) if (item.id !== 'mail' && !item.hidden) items.push(item.id as RailHint);
|
||||
if (sidebarAppsEnabled && onManageApps) items.push('add-app');
|
||||
if (isStalwartAdmin) items.push('admin');
|
||||
if (showAccessibilityButton) items.push('a11y');
|
||||
if (quotaShown) items.push('quota');
|
||||
writeRailHints(items);
|
||||
// navItems is rebuilt every render; its inputs are listed instead.
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [client, supportsCalendar, calendarEnabled, supportsContacts, contactsEnabled, supportsFiles, filesEnabled, isStalwartAdmin, showAccessibilityButton, quotaShown]);
|
||||
}, [client, supportsCalendar, calendarEnabled, supportsContacts, contactsEnabled, supportsFiles, filesEnabled, sidebarAppsEnabled, !!onManageApps, isStalwartAdmin, showAccessibilityButton, quotaShown]);
|
||||
|
||||
const getIsActive = (href: string, itemId: string) => {
|
||||
if (activeAppId) return false;
|
||||
|
||||
@@ -6,7 +6,7 @@ import { BOOT_HINTS_KEY } from './keys';
|
||||
* admin rights, quota), which nothing else keeps across a reload. The boot
|
||||
* script turns it into `data-boot-rail` (lib/boot-skeleton/boot-script.ts).
|
||||
*/
|
||||
export type RailHint = 'calendar' | 'contacts' | 'files' | 'admin' | 'a11y' | 'quota';
|
||||
export type RailHint = 'calendar' | 'contacts' | 'files' | 'add-app' | 'admin' | 'a11y' | 'quota';
|
||||
|
||||
let lastWritten: string | null = null;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user