ultisuite-client/lib/mail-chrome-classes.ts
R3D347HR4Y 5304790ed5
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
feat(auth): enhance session management and identity provider settings
- Added SessionGuard component to manage session expiration and online status.
- Updated AuthProvider to streamline session fetching and handling.
- Introduced IdentityProvidersSection for managing OAuth, SAML, and LDAP identity providers.
- Implemented identity provider guides for easier configuration.
- Enhanced mail settings with infinite scroll option for improved user experience.
- Updated global styles and layout components for better consistency across the application.
2026-06-09 09:36:46 +02:00

335 lines
15 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { cn } from "@/lib/utils"
/** Menu déroulant / contextuel Gmail (portail Radix → tokens shadcn). */
export const MAIL_MENU_SURFACE_CLASS = cn(
"min-w-[220px] rounded-lg border border-border bg-popover p-0 py-1 text-popover-foreground shadow-lg",
"[&_[data-slot=dropdown-menu-item]]:gap-3 [&_[data-slot=dropdown-menu-item]]:rounded-none",
"[&_[data-slot=dropdown-menu-item]]:px-3 [&_[data-slot=dropdown-menu-item]]:py-2 [&_[data-slot=dropdown-menu-item]]:text-sm",
"[&_[data-slot=dropdown-menu-item]]:focus:bg-accent [&_[data-slot=dropdown-menu-item]]:focus:text-accent-foreground",
"[&_[data-slot=dropdown-menu-sub-trigger]]:gap-3 [&_[data-slot=dropdown-menu-sub-trigger]]:rounded-none",
"[&_[data-slot=dropdown-menu-sub-trigger]]:px-3 [&_[data-slot=dropdown-menu-sub-trigger]]:py-2",
"[&_[data-slot=dropdown-menu-sub-trigger]]:text-sm",
"[&_[data-slot=dropdown-menu-sub-trigger]]:focus:bg-accent",
"[&_[data-slot=dropdown-menu-sub-trigger]]:data-[state=open]:bg-accent",
"[&_[data-slot=dropdown-menu-sub-content]]:min-w-[200px]",
"[&_[data-slot=dropdown-menu-sub-content]]:rounded-lg",
"[&_[data-slot=dropdown-menu-sub-content]]:border [&_[data-slot=dropdown-menu-sub-content]]:border-border",
"[&_[data-slot=dropdown-menu-sub-content]]:bg-popover",
"[&_[data-slot=dropdown-menu-sub-content]]:p-0 [&_[data-slot=dropdown-menu-sub-content]]:py-1",
"[&_[data-slot=dropdown-menu-sub-content]]:shadow-lg",
"[&_[data-slot=dropdown-menu-separator]]:mx-0 [&_[data-slot=dropdown-menu-separator]]:my-1",
"[&_[data-slot=dropdown-menu-separator]]:bg-border",
"[&_[data-slot=context-menu-item]]:focus:bg-accent [&_[data-slot=context-menu-item]]:focus:text-accent-foreground",
"[&_[data-slot=context-menu-sub-trigger]]:focus:bg-accent",
"[&_[data-slot=context-menu-sub-content]]:border-border [&_[data-slot=context-menu-sub-content]]:bg-popover"
)
export const MAIL_MENU_SURFACE_WIDE_CLASS = cn(
MAIL_MENU_SURFACE_CLASS,
"min-w-[280px]"
)
export const MAIL_SIDEBAR_MENU_SURFACE_CLASS = cn(
"min-w-[240px] border-border bg-popover p-0 py-1.5 text-popover-foreground shadow-md",
"[&_[data-slot=dropdown-menu-label]]:text-muted-foreground",
"[&_[data-slot=dropdown-menu-item]]:text-popover-foreground",
"[&_[data-slot=dropdown-menu-item]]:focus:bg-accent [&_[data-slot=dropdown-menu-item]]:focus:text-accent-foreground",
"[&_[data-slot=dropdown-menu-sub-trigger]]:text-popover-foreground",
"[&_[data-slot=dropdown-menu-sub-trigger]]:focus:bg-accent",
"[&_[data-slot=dropdown-menu-sub-trigger]]:data-[state=open]:bg-accent",
"[&_[data-slot=context-menu-label]]:text-muted-foreground",
"[&_[data-slot=context-menu-item]]:text-popover-foreground",
"[&_[data-slot=context-menu-item]]:focus:bg-accent [&_[data-slot=context-menu-item]]:focus:text-accent-foreground",
"[&_[data-slot=context-menu-sub-trigger]]:text-popover-foreground",
"[&_[data-slot=context-menu-sub-trigger]]:focus:bg-accent",
"[&_[data-slot=context-menu-sub-trigger]]:data-[state=open]:bg-accent"
)
export const MAIL_SIDEBAR_MENU_ITEM_CLASS = cn(
"mx-1 flex cursor-pointer items-center justify-between gap-3 px-3 py-2 text-sm text-popover-foreground",
"focus:bg-accent focus:text-accent-foreground"
)
export const MAIL_SIDEBAR_MENU_SUB_TRIGGER_CLASS = cn(
"mx-1 cursor-pointer rounded-sm px-2 py-2 text-popover-foreground",
"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent"
)
export const MAIL_SIDEBAR_MENU_PLAIN_ITEM_CLASS = cn(
"mx-1 cursor-pointer px-3 py-2 text-sm text-popover-foreground focus:bg-accent focus:text-accent-foreground"
)
export const MAIL_SIDEBAR_MENU_SEPARATOR_CLASS = "my-1.5 bg-border"
export const MAIL_SIDEBAR_COLOR_SWATCH_RING_CLASS =
"border-border bg-mail-surface ring-offset-background hover:ring-muted-foreground focus-visible:ring-ring"
export const MAIL_SIDEBAR_COLOR_PICKER_CLASS = cn(
"min-w-[180px] border-border bg-popover p-2 text-popover-foreground shadow-md"
)
export const MAIL_ICON_BTN =
"text-muted-foreground hover:bg-accent hover:text-accent-foreground"
/** Panneaux header (favoris, comptes) — gris mail, pas le noir `popover`. */
export const MAIL_HEADER_DROPDOWN_CLASS = cn(
"border border-border bg-mail-surface-elevated text-foreground shadow-xl",
)
export const MAIL_TOOLBAR_ICON_BTN = cn(
"h-9 w-9 shrink-0 text-muted-foreground hover:bg-accent hover:text-accent-foreground"
)
/** Onglets catégorie boîte — libellés / icônes blancs en dark ; le soulignement garde la couleur daccent. */
export const MAIL_INBOX_CATEGORY_TAB_CONTENT_DARK_CLASS = "dark:!text-white"
export const MAIL_PREVIEW_SCROLL_CLASS =
"min-h-0 flex-1 overflow-y-auto overflow-x-hidden overscroll-y-contain outline-none max-sm:pb-16 " +
"[scrollbar-color:color-mix(in_srgb,var(--muted-foreground)_55%,transparent)_transparent] [scrollbar-width:auto] " +
"[&::-webkit-scrollbar]:w-2.5 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-muted-foreground/45"
export const MAIL_REPLY_BAR_CLASS =
"bg-gradient-to-b from-transparent via-mail-surface/90 to-mail-surface pt-3"
export const MAIL_REPLY_BUTTON_CLASS = cn(
"inline-flex shrink-0 items-center gap-2 whitespace-nowrap rounded-full border border-border",
"bg-mail-surface px-6 py-2.5 text-sm font-medium text-foreground shadow-sm",
"transition-shadow hover:bg-accent hover:shadow-md"
)
export const MAIL_INVITATION_CARD_CLASS = cn(
"mx-6 mb-4 rounded-xl border border-border bg-mail-invitation px-4 py-3 shadow-sm"
)
export const MAIL_MESSAGE_HOVER_CLASS = "hover:bg-accent/60"
export const MAIL_COMPOSE_TITLEBAR_CLASS = cn(
"flex h-10 shrink-0 cursor-pointer items-center rounded-t-lg bg-muted px-3",
"dark:bg-[#2d2e30]"
)
export const MAIL_COMPOSE_POPOVER_CLASS = cn(
"border-border bg-popover p-3 text-popover-foreground shadow-lg"
)
export const MAIL_COMPOSE_MENU_SELECTED_CLASS = "bg-accent text-accent-foreground"
export const MAIL_COMPOSE_TOOLBAR_BTN = cn(
"flex h-7 w-7 items-center justify-center rounded text-muted-foreground transition-colors",
"hover:bg-accent hover:text-accent-foreground disabled:opacity-40"
)
export const MAIL_COMPOSE_TOOLBAR_BTN_ACTIVE = "bg-accent text-foreground"
export const MAIL_COMPOSE_TOOLBAR_SEP = "mx-0.5 h-5 w-px bg-border"
export const MAIL_COMPOSE_BOTTOM_ICON_BTN = cn(
"flex h-8 w-8 items-center justify-center rounded-full text-muted-foreground transition-colors",
"hover:bg-accent hover:text-accent-foreground"
)
export const MAIL_COMPOSE_BOTTOM_ICON_BTN_ACTIVE = "bg-accent text-foreground"
export const MAIL_COMPOSE_PRIMARY_SEND_BTN = cn(
"inline-flex h-9 items-center bg-primary text-primary-foreground",
"hover:bg-primary/90 hover:shadow-md transition-all"
)
export const MAIL_COMPOSE_RECIPIENT_DIVIDER = "ml-3 border-b border-border"
export const MAIL_COMPOSE_SUGGESTION_SELECTED = "bg-primary/10"
export const MAIL_COMPOSE_SUGGESTION_HOVER = "hover:bg-accent"
export const MAIL_COMPOSE_CONTACT_PILL_CLASS = cn(
"inline-flex items-center gap-1 rounded-full bg-muted py-0.5 pl-0.5 pr-2 text-sm text-foreground",
"hover:bg-accent transition-colors"
)
export const MAIL_COMPOSE_DROP_ZONE_CLASS = cn(
"absolute inset-0 z-50 flex items-center justify-center rounded-lg border-2 border-dashed border-primary",
"bg-primary/5"
)
/** Bouton pilule xs (barres flottantes liste / lecture). */
export const XS_FLOATING_CONTROL_BTN = cn(
"pointer-events-auto size-9 shrink-0 rounded-full border border-border",
"bg-mail-surface/80 text-muted-foreground shadow-md backdrop-blur",
"hover:bg-accent hover:text-accent-foreground"
)
/** Barre overlay xs : pas de fond opaque, contrôles flottants seulement. */
export const XS_FLOATING_CHROME_BAR =
"pointer-events-none absolute inset-x-0 top-0 z-20 flex items-center gap-2 px-3 pt-2 sm:hidden"
export const MAIL_TOOLTIP_CONTENT_CLASS =
"border border-border bg-popover text-popover-foreground shadow-md"
/** En-tête sujet : pas de fond propre (aligné sur le panneau). */
export const MAIL_PREVIEW_SUBJECT_HEADER_CLASS = ""
export const MAIL_TOAST_SURFACE_CLASS = cn(
"relative box-border w-full max-w-full overflow-hidden rounded-xl border border-border",
"bg-mail-surface text-foreground shadow-md ring-1 ring-primary/15"
)
/** Liste — barre doutils (sélection, pagination, refresh). */
export const MAIL_LIST_TOOLBAR_CLASS = "flex shrink-0 items-center gap-0.5 border-b border-border px-2"
export const MAIL_LIST_TOOLBAR_BTN = MAIL_TOOLBAR_ICON_BTN
/** Ligne liste — cases à cocher. */
export const MAIL_LIST_ROW_CHECKBOX_CLASS = cn(
"size-4 min-h-4 min-w-4 shrink-0 border-[1.5px] border-mail-row-checkbox-border bg-transparent shadow-none",
"dark:bg-transparent focus-visible:ring-mail-row-checkbox-border/30",
"data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground"
)
export const MAIL_LIST_ROW_CHECKBOX_CIRCULAR_CLASS = cn(
MAIL_LIST_ROW_CHECKBOX_CLASS,
"rounded-full"
)
export const MAIL_LIST_ROW_CHECKBOX_SQUARE_CLASS = cn(
MAIL_LIST_ROW_CHECKBOX_CLASS,
"rounded-[2.5px]"
)
export const MAIL_LIST_ROW_DIVIDER_CLASS = "divide-y divide-mail-list-divider"
/** Recherche — champ et panneau avancé. */
export const MAIL_SEARCH_INPUT_WRAP_CLASS = cn(
"relative flex min-w-0 flex-1 items-center rounded-full border border-border",
"bg-mail-surface-elevated shadow-sm transition-shadow focus-within:shadow-md"
)
/** Séparateurs recherche (header, bandeau chips) — bordure lisible en dark. */
export const MAIL_SEARCH_SECTION_DIVIDER_CLASS = "border-mail-border"
/** Chip filtre recherche — inactif. */
export const MAIL_SEARCH_CHIP_INACTIVE_CLASS = cn(
"border-mail-list-chip-border bg-mail-list-chip-muted text-mail-list-chip-text"
)
/** Champs recherche avancée — même fond/bordure que les pickers (label, select). */
export const MAIL_SEARCH_FIELD_CLASS = cn(
"rounded-md border border-solid !border-mail-border bg-mail-surface-muted text-foreground shadow-none",
"focus-visible:!border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
"dark:!border-mail-border dark:!bg-mail-surface-muted"
)
/** Cases à cocher recherche avancée — bordure lisible en dark. */
export const MAIL_SEARCH_CHECKBOX_CLASS = cn(
"size-4 border-[1.5px] border-mail-row-checkbox-border bg-mail-surface-muted shadow-none",
"dark:bg-mail-surface-muted",
"data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
"data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground"
)
/** Fond vitré suggestions recherche (desktop + mobile). */
export const MAIL_SEARCH_SUGGESTIONS_SURFACE_CLASS = cn(
"bg-mail-surface-elevated/80 backdrop-blur-xl backdrop-saturate-150",
"supports-[backdrop-filter]:bg-mail-surface-elevated/65"
)
/** Suggestions recherche (desktop) — panneau déroulant vitré. */
export const MAIL_SEARCH_SUGGESTIONS_DROPDOWN_CLASS = cn(
"absolute left-0 right-0 top-full z-50 mt-1 overflow-hidden rounded-lg border text-foreground shadow-lg",
MAIL_SEARCH_SECTION_DIVIDER_CLASS,
MAIL_SEARCH_SUGGESTIONS_SURFACE_CLASS
)
export const MAIL_SEARCH_ADVANCED_PANEL_CLASS = cn(
"absolute left-0 top-full z-50 mt-1 max-h-[80vh] overflow-y-auto rounded-lg border",
MAIL_SEARCH_SECTION_DIVIDER_CLASS,
"bg-mail-surface-elevated text-foreground shadow-lg",
"data-mail-search-advanced",
"sm:min-w-[34rem] sm:max-w-[min(42rem,calc(100vw-5rem))]",
"md:min-w-[38rem]",
"lg:right-0 lg:min-w-0 lg:max-w-none"
)
/** Recherche mobile (xs) — plein écran, gris mail en dark (pas `bg-background`). */
export const MAIL_MOBILE_SEARCH_SHEET_CLASS = cn(
"z-[101] flex h-[100dvh] max-h-[100dvh] w-full flex-col gap-0 rounded-none border-0",
"bg-mail-surface text-foreground p-0 shadow-xl",
"duration-300 ease-out",
"data-[state=open]:animate-in data-[state=closed]:animate-out",
"data-[state=open]:slide-in-from-bottom data-[state=closed]:slide-out-to-bottom",
"pb-[env(safe-area-inset-bottom)]",
"data-mail-mobile-search"
)
/** Sidebar — xs only (flou sur le canvas). sm+ stays transparent with NO backdrop-filter
* so descendant sticky rows can use their own backdrop-filter freely. */
export const MAIL_SIDEBAR_PANEL_SURFACE_CLASS = cn(
"max-sm:bg-app-canvas/80 max-sm:backdrop-blur-xl max-sm:backdrop-saturate-150 max-sm:supports-[backdrop-filter]:bg-app-canvas/65",
"sm:bg-transparent"
)
/** Sidebar — frosted strips (Sortbot, section headers, open folder branches). */
export const MAIL_SIDEBAR_BLUR_SURFACE_CLASS = "mail-sidebar-blur-surface"
/** Sidebar — overlay mobile/touch : classe CSS dédiée (pas bg-* Tailwind). */
export const MAIL_SIDEBAR_PANEL_SURFACE_MOBILE_CLASS = "mail-sidebar-overlay-panel"
export const MAIL_SIDEBAR_OVERFLOW_BTN_CLASS = cn(
"flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-full text-muted-foreground",
"outline-none hover:bg-accent/80 focus-visible:ring-2 focus-visible:ring-ring/50"
)
export function mailNavRowClass(opts: {
isSelected: boolean
isOver?: boolean
rowHoverHeld?: boolean
hasUnread?: boolean
extra?: string
}) {
return cn(
"transition-colors",
opts.isSelected
? "bg-mail-nav-selected text-mail-nav-selected font-medium"
: opts.isOver
? "bg-mail-nav-drop text-foreground"
: opts.rowHoverHeld
? "bg-mail-nav-hover text-foreground"
: opts.hasUnread
? "text-foreground hover:bg-mail-nav-hover"
: "text-muted-foreground hover:bg-mail-nav-hover",
opts.extra
)
}
/** Inset autour de la card centrale (réglages mail, aligné drive/mail). */
export const MAIL_SETTINGS_MAIN_INSET_CLASS =
"flex min-h-0 min-w-0 flex-1 flex-col px-1 pb-1 max-sm:px-0 max-sm:pb-0"
/** Card blanche du contenu central des réglages mail. */
export const MAIL_SETTINGS_MAIN_CARD_CLASS =
"flex min-h-0 flex-1 flex-col overflow-hidden rounded-2xl bg-mail-surface shadow-sm max-sm:rounded-none max-sm:shadow-none"
/** Liste d'onglets des pages réglages (libellés, automatisations…). */
export const MAIL_SETTINGS_TABS_LIST_CLASS = cn(
"flex h-auto w-fit max-w-full flex-wrap gap-1.5",
"[&_[data-slot=tabs-trigger]]:flex-none",
)
/** Card interne des pages réglages mail (alignée contacts). */
export const MAIL_SETTINGS_CARD_CLASS = cn(
"mail-settings-card rounded-lg border border-mail-border bg-mail-surface shadow-sm",
"dark:bg-mail-surface-elevated dark:shadow-[0_1px_4px_rgba(0,0,0,0.35)]",
)
/** Masonry 2 colonnes pour sections réglages (affichage, signatures…) en lg+. */
export const MAIL_SETTINGS_PAGE_MASONRY_CLASS = "lg:columns-2 lg:gap-5"
export const MAIL_SETTINGS_PAGE_MASONRY_ITEM_CLASS =
"lg:mb-5 lg:break-inside-avoid"
/** Bloc empilé → card en masonry (variant page affichage). */
export const MAIL_SETTINGS_PAGE_MASONRY_SECTION_CLASS = cn(
"mail-settings-masonry-section border-border px-0 py-5",
"lg:mb-5 lg:break-inside-avoid lg:rounded-xl lg:border lg:border-mail-border lg:bg-mail-surface lg:px-5 lg:py-5 lg:shadow-sm",
"dark:lg:bg-mail-surface-elevated dark:lg:shadow-[0_1px_4px_rgba(0,0,0,0.35)]",
)