@umodeapporg/ui 0.2.0 → 0.4.0

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.
Files changed (65) hide show
  1. package/README.md +78 -0
  2. package/dist/assets/umode-ui.css +148 -0
  3. package/dist/components/Form/ControlledSelect.js +1 -1
  4. package/dist/components/Form/ControlledTabs.js +4 -4
  5. package/dist/components/Form/ControlledTabs.js.map +1 -1
  6. package/dist/components/Form/ControlledViewToggle.js +2 -2
  7. package/dist/components/Form/ControlledViewToggle.js.map +1 -1
  8. package/dist/components/Navigation/ControlledBreadcrumb.js +3 -2
  9. package/dist/components/Navigation/ControlledBreadcrumb.js.map +1 -1
  10. package/dist/components/Navigation/PageTitle.js +3 -6
  11. package/dist/components/Navigation/PageTitle.js.map +1 -1
  12. package/dist/components/Navigation/ReactRouterNavigationAdapter.d.ts +7 -0
  13. package/dist/components/Navigation/ReactRouterNavigationAdapter.js +26 -0
  14. package/dist/components/Navigation/ReactRouterNavigationAdapter.js.map +1 -0
  15. package/dist/components/Navigation/UiNavigationContext.d.ts +38 -0
  16. package/dist/components/Navigation/UiNavigationContext.js +43 -0
  17. package/dist/components/Navigation/UiNavigationContext.js.map +1 -0
  18. package/dist/components/Search/filters/useFilters.js +2 -2
  19. package/dist/components/Search/filters/useFilters.js.map +1 -1
  20. package/dist/components/Shell/AppHeader.d.ts +19 -0
  21. package/dist/components/Shell/AppHeader.js +64 -0
  22. package/dist/components/Shell/AppHeader.js.map +1 -0
  23. package/dist/components/Shell/AppShell.d.ts +20 -0
  24. package/dist/components/Shell/AppShell.js +100 -0
  25. package/dist/components/Shell/AppShell.js.map +1 -0
  26. package/dist/components/Shell/AppSidebar.d.ts +15 -0
  27. package/dist/components/Shell/AppSidebar.js +63 -0
  28. package/dist/components/Shell/AppSidebar.js.map +1 -0
  29. package/dist/components/Shell/LanguageToggle.d.ts +8 -0
  30. package/dist/components/Shell/LanguageToggle.js +59 -0
  31. package/dist/components/Shell/LanguageToggle.js.map +1 -0
  32. package/dist/components/Shell/SidebarMenu.d.ts +24 -0
  33. package/dist/components/Shell/SidebarMenu.js +204 -0
  34. package/dist/components/Shell/SidebarMenu.js.map +1 -0
  35. package/dist/components/Shell/ThemeToggle.d.ts +11 -0
  36. package/dist/components/Shell/ThemeToggle.js +55 -0
  37. package/dist/components/Shell/ThemeToggle.js.map +1 -0
  38. package/dist/components/Shell/headerControlStyles.d.ts +10 -0
  39. package/dist/components/Shell/headerControlStyles.js +11 -0
  40. package/dist/components/Shell/headerControlStyles.js.map +1 -0
  41. package/dist/components/Shell/useSidebarState.d.ts +14 -0
  42. package/dist/components/Shell/useSidebarState.js +106 -0
  43. package/dist/components/Shell/useSidebarState.js.map +1 -0
  44. package/dist/components/UI/BaseDataCard.js +3 -2
  45. package/dist/components/UI/BaseDataCard.js.map +1 -1
  46. package/dist/components/UI/DataTable/DataTable.js +1 -1
  47. package/dist/components/UI/DataTable/DataTableBulkEditDialog.js +1 -1
  48. package/dist/components/UI/DataTable/DataTableFilters.js +1 -1
  49. package/dist/components/UI/DataTable/DataTableToolbar.js +1 -1
  50. package/dist/components/UI/DataTable/applyDataTableFilters.js +1 -1
  51. package/dist/components/UI/UserMenu.d.ts +48 -0
  52. package/dist/components/UI/UserMenu.js +196 -0
  53. package/dist/components/UI/UserMenu.js.map +1 -0
  54. package/dist/index.d.ts +6 -0
  55. package/dist/index.js +47 -34
  56. package/dist/index.js.map +1 -1
  57. package/dist/locales/en/ui.json.d.ts +28 -0
  58. package/dist/locales/en/ui.json.js +12 -0
  59. package/dist/locales/en/ui.json.js.map +1 -1
  60. package/dist/locales/index.d.ts +56 -0
  61. package/dist/locales/pt/ui.json.d.ts +28 -0
  62. package/dist/locales/pt/ui.json.js +12 -0
  63. package/dist/locales/pt/ui.json.js.map +1 -1
  64. package/package.json +6 -3
  65. package/src/assets/styles/base.css +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"BaseDataCard.js","sources":["../../../src/components/UI/BaseDataCard.tsx"],"sourcesContent":["import { useRef, useState } from 'react';\nimport * as React from 'react';\nimport classNames from 'classnames';\nimport { Link } from 'react-router-dom';\n\nimport ControlledTooltip from '@/components/UI/ControlledTooltip';\nimport { MaterialSymbol, SymbolCodepoints } from '@/components/UI/MaterialSymbol';\nimport { uiLogger } from '@/helpers/uiLogger';\n\nimport ControlledButton from '../Form/ControlledButton';\nimport SkeletonLoading from '../UI/SkeletonLoading';\n\nimport CustomCard from './CustomCard';\ninterface IBaseDataCardProps extends React.HTMLAttributes<HTMLDivElement> {\n title?: string;\n smallTitle?: boolean;\n titleIcon?: SymbolCodepoints | null;\n titleClass?: string;\n cardIcon?: SymbolCodepoints;\n iconTooltip?: string;\n iconColor?: string;\n iconSize?: number;\n itsClickable?: boolean;\n actionIcon?: SymbolCodepoints;\n actionHref?: string;\n actionButton?: () => void;\n onAction?: () => void;\n actionButtonLabel?: string;\n showActionButton?: boolean;\n useScroll?: boolean;\n loading?: boolean;\n onSecondarySlot?: React.ReactNode;\n infoTooltip?: string;\n}\n\nconst BaseDataCard: React.FC<IBaseDataCardProps> = ({\n title,\n smallTitle,\n titleIcon,\n titleClass,\n cardIcon,\n iconTooltip,\n itsClickable = false,\n actionIcon = 'edit',\n actionHref,\n className,\n actionButton,\n actionButtonLabel,\n showActionButton = false,\n onAction,\n useScroll = false,\n loading = false,\n children,\n onSecondarySlot,\n infoTooltip,\n}) => {\n const [isArrowUpward, setIsArrowUpward] = useState(false);\n const cardRef = useRef<HTMLDivElement>(null);\n\n const handleActionClick = () => {\n const newArrowUpwardState = !isArrowUpward;\n setIsArrowUpward(newArrowUpwardState);\n if (actionButton) {\n actionButton();\n }\n if (!newArrowUpwardState && cardRef.current && useScroll) {\n setTimeout(() => {\n uiLogger.debug('Scrolling into view');\n cardRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }, 1);\n }\n };\n\n return (\n <CustomCard\n className={classNames('overflow-y-hidden p-5 transition-colors', {\n [`${className}`]: !!className,\n 'h-[30rem]': useScroll,\n ['hover:transition-custom hover:ease-custom cursor-pointer hover:bg-success-soft hover:duration-slow']:\n itsClickable,\n })}\n customRef={cardRef}\n >\n <div className=\"flex h-full flex-col justify-between\">\n <div className=\"mb-3 flex items-center justify-between\">\n <div className=\"flex w-full items-center justify-between\">\n {loading ? (\n <SkeletonLoading className=\"!h-4\" />\n ) : (\n <div className=\"flex items-center gap-x-1.5\">\n {titleIcon &&\n (iconTooltip ? (\n <ControlledTooltip content={iconTooltip} className=\"max-w-80\">\n <MaterialSymbol\n icon={titleIcon}\n size={smallTitle ? 18 : 20}\n color=\"rgb(var(--color-foreground-subtle))\"\n className=\"!hidden desktop:!block\"\n />\n </ControlledTooltip>\n ) : (\n <MaterialSymbol\n icon={titleIcon}\n size={smallTitle ? 18 : 20}\n color=\"rgb(var(--color-foreground-subtle))\"\n className=\"!hidden desktop:!block\"\n />\n ))}\n\n {title && (\n <span\n className={classNames(\n 'font-semibold text-foreground',\n {\n 'text-xs': smallTitle,\n 'text-lg': !smallTitle,\n },\n titleClass,\n )}\n >\n {title}\n </span>\n )}\n\n {infoTooltip && (\n <ControlledTooltip content={infoTooltip} className=\"max-w-80\">\n <MaterialSymbol\n icon=\"info\"\n size={smallTitle ? 16 : 18}\n color=\"rgb(var(--color-foreground-subtle))\"\n className=\"ml-1 cursor-help\"\n />\n </ControlledTooltip>\n )}\n </div>\n )}\n </div>\n\n <div>\n {loading ? (\n <SkeletonLoading type=\"circle\" className=\"ml-3\" />\n ) : (\n <div className=\"flex items-center space-x-2\">\n {actionHref && (\n <Link to={actionHref}>\n <ControlledButton\n defaultHtmlButton\n onClick={onAction}\n className=\"flex size-9 items-center justify-center rounded-full transition-colors hover:bg-muted\"\n >\n <MaterialSymbol color=\"rgb(var(--color-primary))\" icon={actionIcon} />\n </ControlledButton>\n </Link>\n )}\n\n {onAction && (\n <ControlledButton\n defaultHtmlButton\n onClick={onAction}\n className=\"flex size-9 items-center justify-center rounded-full transition-colors hover:bg-muted\"\n >\n <MaterialSymbol color=\"rgb(var(--color-primary))\" icon={actionIcon} />\n </ControlledButton>\n )}\n\n {onSecondarySlot && <>{onSecondarySlot}</>}\n\n {cardIcon && <MaterialSymbol icon={cardIcon} size={25} color=\"rgb(var(--color-primary))\" />}\n </div>\n )}\n </div>\n </div>\n\n <div\n className={classNames('m-auto', {\n 'w-[90%]': useScroll,\n 'w-full': !useScroll,\n })}\n >\n {children}\n </div>\n </div>\n\n {showActionButton && actionButtonLabel && (\n <div className=\"flex h-20 w-full items-center justify-center rounded-md bg-gradient-to-t from-surface to-transparent\">\n <ControlledButton\n className=\"flex w-full max-w-full items-center justify-center gap-x-3 rounded-full px-4 py-2 text-sm font-semibold capitalize text-white tablet:w-60\"\n onClick={handleActionClick}\n >\n <MaterialSymbol\n icon=\"arrow_downward\"\n size={20}\n color=\"white\"\n className={classNames('transition-transform duration-slow', {\n 'rotate-180': isArrowUpward,\n })}\n />\n\n {actionButtonLabel}\n </ControlledButton>\n </div>\n )}\n </CustomCard>\n );\n};\n\nexport default BaseDataCard;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"BaseDataCard.js","sources":["../../../src/components/UI/BaseDataCard.tsx"],"sourcesContent":["import { useRef, useState } from 'react';\nimport * as React from 'react';\nimport classNames from 'classnames';\n\nimport { useUiNavigation } from '@/components/Navigation/UiNavigationContext';\nimport ControlledTooltip from '@/components/UI/ControlledTooltip';\nimport { MaterialSymbol, SymbolCodepoints } from '@/components/UI/MaterialSymbol';\nimport { uiLogger } from '@/helpers/uiLogger';\n\nimport ControlledButton from '../Form/ControlledButton';\nimport SkeletonLoading from '../UI/SkeletonLoading';\n\nimport CustomCard from './CustomCard';\ninterface IBaseDataCardProps extends React.HTMLAttributes<HTMLDivElement> {\n title?: string;\n smallTitle?: boolean;\n titleIcon?: SymbolCodepoints | null;\n titleClass?: string;\n cardIcon?: SymbolCodepoints;\n iconTooltip?: string;\n iconColor?: string;\n iconSize?: number;\n itsClickable?: boolean;\n actionIcon?: SymbolCodepoints;\n actionHref?: string;\n actionButton?: () => void;\n onAction?: () => void;\n actionButtonLabel?: string;\n showActionButton?: boolean;\n useScroll?: boolean;\n loading?: boolean;\n onSecondarySlot?: React.ReactNode;\n infoTooltip?: string;\n}\n\nconst BaseDataCard: React.FC<IBaseDataCardProps> = ({\n title,\n smallTitle,\n titleIcon,\n titleClass,\n cardIcon,\n iconTooltip,\n itsClickable = false,\n actionIcon = 'edit',\n actionHref,\n className,\n actionButton,\n actionButtonLabel,\n showActionButton = false,\n onAction,\n useScroll = false,\n loading = false,\n children,\n onSecondarySlot,\n infoTooltip,\n}) => {\n const { Link: NavigationLink } = useUiNavigation();\n const [isArrowUpward, setIsArrowUpward] = useState(false);\n const cardRef = useRef<HTMLDivElement>(null);\n\n const handleActionClick = () => {\n const newArrowUpwardState = !isArrowUpward;\n setIsArrowUpward(newArrowUpwardState);\n if (actionButton) {\n actionButton();\n }\n if (!newArrowUpwardState && cardRef.current && useScroll) {\n setTimeout(() => {\n uiLogger.debug('Scrolling into view');\n cardRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }, 1);\n }\n };\n\n return (\n <CustomCard\n className={classNames('overflow-y-hidden p-5 transition-colors', {\n [`${className}`]: !!className,\n 'h-[30rem]': useScroll,\n ['hover:transition-custom hover:ease-custom cursor-pointer hover:bg-success-soft hover:duration-slow']:\n itsClickable,\n })}\n customRef={cardRef}\n >\n <div className=\"flex h-full flex-col justify-between\">\n <div className=\"mb-3 flex items-center justify-between\">\n <div className=\"flex w-full items-center justify-between\">\n {loading ? (\n <SkeletonLoading className=\"!h-4\" />\n ) : (\n <div className=\"flex items-center gap-x-1.5\">\n {titleIcon &&\n (iconTooltip ? (\n <ControlledTooltip content={iconTooltip} className=\"max-w-80\">\n <MaterialSymbol\n icon={titleIcon}\n size={smallTitle ? 18 : 20}\n color=\"rgb(var(--color-foreground-subtle))\"\n className=\"!hidden desktop:!block\"\n />\n </ControlledTooltip>\n ) : (\n <MaterialSymbol\n icon={titleIcon}\n size={smallTitle ? 18 : 20}\n color=\"rgb(var(--color-foreground-subtle))\"\n className=\"!hidden desktop:!block\"\n />\n ))}\n\n {title && (\n <span\n className={classNames(\n 'font-semibold text-foreground',\n {\n 'text-xs': smallTitle,\n 'text-lg': !smallTitle,\n },\n titleClass,\n )}\n >\n {title}\n </span>\n )}\n\n {infoTooltip && (\n <ControlledTooltip content={infoTooltip} className=\"max-w-80\">\n <MaterialSymbol\n icon=\"info\"\n size={smallTitle ? 16 : 18}\n color=\"rgb(var(--color-foreground-subtle))\"\n className=\"ml-1 cursor-help\"\n />\n </ControlledTooltip>\n )}\n </div>\n )}\n </div>\n\n <div>\n {loading ? (\n <SkeletonLoading type=\"circle\" className=\"ml-3\" />\n ) : (\n <div className=\"flex items-center space-x-2\">\n {actionHref && (\n <NavigationLink to={actionHref}>\n <ControlledButton\n defaultHtmlButton\n onClick={onAction}\n className=\"flex size-9 items-center justify-center rounded-full transition-colors hover:bg-muted\"\n >\n <MaterialSymbol color=\"rgb(var(--color-primary))\" icon={actionIcon} />\n </ControlledButton>\n </NavigationLink>\n )}\n\n {onAction && (\n <ControlledButton\n defaultHtmlButton\n onClick={onAction}\n className=\"flex size-9 items-center justify-center rounded-full transition-colors hover:bg-muted\"\n >\n <MaterialSymbol color=\"rgb(var(--color-primary))\" icon={actionIcon} />\n </ControlledButton>\n )}\n\n {onSecondarySlot && <>{onSecondarySlot}</>}\n\n {cardIcon && <MaterialSymbol icon={cardIcon} size={25} color=\"rgb(var(--color-primary))\" />}\n </div>\n )}\n </div>\n </div>\n\n <div\n className={classNames('m-auto', {\n 'w-[90%]': useScroll,\n 'w-full': !useScroll,\n })}\n >\n {children}\n </div>\n </div>\n\n {showActionButton && actionButtonLabel && (\n <div className=\"flex h-20 w-full items-center justify-center rounded-md bg-gradient-to-t from-surface to-transparent\">\n <ControlledButton\n className=\"flex w-full max-w-full items-center justify-center gap-x-3 rounded-full px-4 py-2 text-sm font-semibold capitalize text-white tablet:w-60\"\n onClick={handleActionClick}\n >\n <MaterialSymbol\n icon=\"arrow_downward\"\n size={20}\n color=\"white\"\n className={classNames('transition-transform duration-slow', {\n 'rotate-180': isArrowUpward,\n })}\n />\n\n {actionButtonLabel}\n </ControlledButton>\n </div>\n )}\n </CustomCard>\n );\n};\n\nexport default BaseDataCard;\n"],"names":[],"mappings":"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"}
@@ -27,7 +27,7 @@ import "../NoDataFound/index.js";
27
27
  import "../../Search/filters/FiltersButton.js";
28
28
  import "../../../helpers/utilityHelpers.js";
29
29
  import "../../Form/ControlledDialog.js";
30
- import "react-router-dom";
30
+ import "../../Navigation/UiNavigationContext.js";
31
31
  import { useBreakpoint } from "../../../hooks/useBreakpoint.js";
32
32
  import GridProvider from "./grid/GridProvider.js";
33
33
  import { useGridFillApply } from "./grid/useGridFillApply.js";
@@ -24,7 +24,7 @@ import NoDataFound from "../NoDataFound/index.js";
24
24
  import "../../Search/filters/FiltersButton.js";
25
25
  import "../../../helpers/utilityHelpers.js";
26
26
  import "../ControlledPopover.js";
27
- import "react-router-dom";
27
+ import "../../Navigation/UiNavigationContext.js";
28
28
  import UnifiedSearchBar from "../../Search/UnifiedSearchBar.js";
29
29
  const resolveDefaultRowLabel = (row, columns) => {
30
30
  const label = (columns ?? []).filter((column) => column.type !== "actions" && !!column.accessor).map((column) => column.accessor?.(row)).find((value) => typeof value === "string" || typeof value === "number");
@@ -24,7 +24,7 @@ import "../NoDataFound/index.js";
24
24
  import "../../Search/filters/FiltersButton.js";
25
25
  import "../../../helpers/utilityHelpers.js";
26
26
  import FiltersPanel from "../../Search/filters/FiltersPanel.js";
27
- import "react-router-dom";
27
+ import "../../Navigation/UiNavigationContext.js";
28
28
  const DataTableFilters = ({
29
29
  filters,
30
30
  values,
@@ -26,7 +26,7 @@ import SkeletonLoading from "../SkeletonLoading.js";
26
26
  import "../../Search/filters/FiltersButton.js";
27
27
  import "../../../helpers/utilityHelpers.js";
28
28
  import "../../Form/ControlledDialog.js";
29
- import "react-router-dom";
29
+ import "../../Navigation/UiNavigationContext.js";
30
30
  import UnifiedSearchBar from "../../Search/UnifiedSearchBar.js";
31
31
  import DataTableSegmentedTabs from "./DataTableSegmentedTabs.js";
32
32
  const DataTableToolbar = ({
@@ -25,7 +25,7 @@ import "../NoDataFound/index.js";
25
25
  import "../../Search/filters/FiltersButton.js";
26
26
  import "../../../helpers/utilityHelpers.js";
27
27
  import "../../Form/ControlledDialog.js";
28
- import "react-router-dom";
28
+ import "../../Navigation/UiNavigationContext.js";
29
29
  const isFieldActive = (field, values) => !isFilterValueEmpty(field, values?.[field.key]);
30
30
  const applyDataTableFilters = (rows, filters, values) => {
31
31
  if (!filters) return rows;
@@ -0,0 +1,48 @@
1
+ export interface IUserMenuAccount {
2
+ id: string;
3
+ name: string;
4
+ logoUrl?: string;
5
+ }
6
+ export interface IUserMenuItem {
7
+ key: string;
8
+ label: string;
9
+ /** Internal route, rendered through the navigation port's Link. */
10
+ to?: string;
11
+ onClick?: () => void;
12
+ tone?: 'default' | 'danger';
13
+ }
14
+ interface IUserMenuProps {
15
+ userName?: string;
16
+ userEmail?: string;
17
+ /** The active account/tenant shown in the trigger, beside the user identity. */
18
+ accountName?: string;
19
+ accountLogoUrl?: string;
20
+ /** Role chip in the trigger; omitted when empty. */
21
+ roleLabel?: string;
22
+ /** Account switcher list; omit (undefined) to hide the whole section. */
23
+ accounts?: Array<IUserMenuAccount>;
24
+ activeAccountId?: string;
25
+ /** Account being switched to; disables the list and shows its spinner. */
26
+ switchingAccountId?: string | null;
27
+ loadingAccounts?: boolean;
28
+ onSwitchAccount?: (accountId: string) => void;
29
+ /** Fired when the popover opens/closes, e.g. to lazily fetch the accounts. */
30
+ onOpenChange?: (open: boolean) => void;
31
+ open: boolean;
32
+ /** Extra rows in the footer (profile, settings...), before the logout row. */
33
+ menuItems?: Array<IUserMenuItem>;
34
+ onLogout?: () => void;
35
+ logoutLabel?: string;
36
+ /** Renders only the identity summary, with no popover (e.g. admin mode). */
37
+ readOnly?: boolean;
38
+ className?: string;
39
+ }
40
+ /**
41
+ * The uMode account menu: identity summary as the trigger, account switcher (with search past
42
+ * five entries), custom rows and logout in a popover. Everything app-shaped (who the user is,
43
+ * what switching does, where profile lives) arrives as props, so any host renders the same
44
+ * surface the dashboard does.
45
+ */
46
+ declare const UserMenu: React.FC<IUserMenuProps>;
47
+ export default UserMenu;
48
+ export type { IUserMenuProps };
@@ -0,0 +1,196 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { useState, useEffect } from "react";
3
+ import classNames from "classnames";
4
+ import { useTranslation } from "react-i18next";
5
+ import ControlledButton from "../Form/ControlledButton.js";
6
+ import ControlledImage from "../Form/ControlledImage/index.js";
7
+ import { useUiNavigation } from "../Navigation/UiNavigationContext.js";
8
+ import UnifiedSearchBar from "../Search/UnifiedSearchBar.js";
9
+ import OutlinedChip from "./Chips/OutlinedChip.js";
10
+ import { ControlledPopoverRoot, ControlledPopoverHandler, ControlledPopoverContent } from "./ControlledPopover.js";
11
+ import LoadingSpinner from "./LoadingSpinner.js";
12
+ import { MaterialSymbol } from "./MaterialSymbol/index.js";
13
+ import NoDataFound from "./NoDataFound/index.js";
14
+ import { getUserAvatarLetters } from "../../helpers/stringHelpers.js";
15
+ const SEARCH_THRESHOLD = 5;
16
+ const AccountRow = ({ account, isActive, switchingAccountId, onSwitchAccount }) => /* @__PURE__ */ jsxs(
17
+ ControlledButton,
18
+ {
19
+ defaultHtmlButton: true,
20
+ type: "button",
21
+ disabled: !!switchingAccountId,
22
+ onClick: () => onSwitchAccount?.(account.id),
23
+ className: classNames("flex w-full items-center gap-x-3 rounded-lg px-2 py-2.5 transition-colors", {
24
+ "bg-brand-soft": isActive,
25
+ "hover:bg-muted": !isActive,
26
+ "disabled:cursor-not-allowed disabled:opacity-60": !!switchingAccountId
27
+ }),
28
+ children: [
29
+ account.logoUrl ? /* @__PURE__ */ jsx(
30
+ ControlledImage,
31
+ {
32
+ src: account.logoUrl,
33
+ className: "size-8 shrink-0 rounded-full border border-brand-border bg-surface object-cover"
34
+ }
35
+ ) : /* @__PURE__ */ jsx("div", { className: "flex size-8 shrink-0 items-center justify-center rounded-full bg-brand-hover text-xs font-bold text-brand-fg", children: getUserAvatarLetters(account.name) }),
36
+ /* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-1 flex-col items-start", children: /* @__PURE__ */ jsx("span", { className: "w-full truncate text-left text-sm text-foreground", children: account.name }) }),
37
+ switchingAccountId === account.id && /* @__PURE__ */ jsx(LoadingSpinner, { size: 4, color: "foreground-faint" }),
38
+ isActive && !switchingAccountId && /* @__PURE__ */ jsx(MaterialSymbol, { icon: "check", size: 18, color: "rgb(var(--color-primary))" })
39
+ ]
40
+ }
41
+ );
42
+ const UserMenu = ({
43
+ userName,
44
+ userEmail,
45
+ accountName,
46
+ accountLogoUrl,
47
+ roleLabel,
48
+ accounts,
49
+ activeAccountId,
50
+ switchingAccountId,
51
+ loadingAccounts = false,
52
+ onSwitchAccount,
53
+ onOpenChange,
54
+ open,
55
+ menuItems,
56
+ onLogout,
57
+ logoutLabel,
58
+ readOnly = false,
59
+ className
60
+ }) => {
61
+ const { t } = useTranslation("ui");
62
+ const { Link: NavigationLink } = useUiNavigation();
63
+ const userInitials = userName ? getUserAvatarLetters(userName) : "??";
64
+ const showAccounts = Array.isArray(accounts);
65
+ const safeAccounts = accounts ?? [];
66
+ const [filtered, setFiltered] = useState(safeAccounts);
67
+ useEffect(() => {
68
+ setFiltered(accounts ?? []);
69
+ }, [accounts, open]);
70
+ const accountSummary = /* @__PURE__ */ jsxs(Fragment, { children: [
71
+ /* @__PURE__ */ jsx("div", { className: "flex size-10 shrink-0 items-center justify-center rounded-full bg-gradient-to-tl from-brand to-brand", children: accountLogoUrl && /* @__PURE__ */ jsx(ControlledImage, { src: accountLogoUrl, className: "size-9 rounded-full" }) }),
72
+ /* @__PURE__ */ jsxs("div", { className: "hidden min-w-0 flex-1 flex-col items-start gap-y-0.5 tablet:flex", children: [
73
+ /* @__PURE__ */ jsx("span", { className: "w-full truncate text-left text-sm font-semibold text-foreground", children: userName }),
74
+ /* @__PURE__ */ jsxs("div", { className: "flex w-full items-center justify-between gap-x-2", children: [
75
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-left text-xs text-foreground-subtle", children: accountName }),
76
+ roleLabel && /* @__PURE__ */ jsx(
77
+ OutlinedChip,
78
+ {
79
+ label: roleLabel,
80
+ chipIcon: "verified_user",
81
+ truncate: true,
82
+ tooltip: roleLabel,
83
+ className: "max-w-[15rem] shrink-0 whitespace-nowrap border border-brand-border bg-brand-soft text-brand-emphasis"
84
+ }
85
+ )
86
+ ] })
87
+ ] })
88
+ ] });
89
+ if (readOnly) {
90
+ return /* @__PURE__ */ jsx("div", { className: classNames("flex min-w-0 items-center gap-x-2.5 px-2.5 py-1.5 tablet:min-w-[300px]", className), children: accountSummary });
91
+ }
92
+ const footerRow = (item) => {
93
+ const rowClass = classNames(
94
+ "rounded-lg px-2 py-2.5 text-left text-sm transition-colors",
95
+ item.tone === "danger" ? "text-danger-emphasis hover:bg-danger-soft" : "text-foreground-muted hover:bg-muted"
96
+ );
97
+ if (item.to) {
98
+ return /* @__PURE__ */ jsx(NavigationLink, { to: item.to, onClick: () => onOpenChange?.(false), className: rowClass, children: item.label }, item.key);
99
+ }
100
+ return /* @__PURE__ */ jsx(
101
+ ControlledButton,
102
+ {
103
+ defaultHtmlButton: true,
104
+ type: "button",
105
+ onClick: () => {
106
+ onOpenChange?.(false);
107
+ item.onClick?.();
108
+ },
109
+ className: classNames("cursor-pointer", rowClass),
110
+ children: item.label
111
+ },
112
+ item.key
113
+ );
114
+ };
115
+ return /* @__PURE__ */ jsxs(ControlledPopoverRoot, { placement: "bottom-end", open, handler: (next) => onOpenChange?.(next), children: [
116
+ /* @__PURE__ */ jsx(ControlledPopoverHandler, { children: /* @__PURE__ */ jsxs(
117
+ ControlledButton,
118
+ {
119
+ defaultHtmlButton: true,
120
+ type: "button",
121
+ className: classNames(
122
+ "flex min-w-0 cursor-pointer items-center gap-x-2.5 px-2.5 py-1.5 tablet:min-w-[300px]",
123
+ className
124
+ ),
125
+ children: [
126
+ accountSummary,
127
+ /* @__PURE__ */ jsx(
128
+ MaterialSymbol,
129
+ {
130
+ icon: open ? "expand_less" : "expand_more",
131
+ size: 20,
132
+ color: "rgb(var(--color-foreground-subtle))"
133
+ }
134
+ )
135
+ ]
136
+ }
137
+ ) }),
138
+ /* @__PURE__ */ jsxs(ControlledPopoverContent, { className: "z-[9999] w-72 max-w-[calc(100vw-1.5rem)] rounded-xl border border-border p-0 shadow-xl", children: [
139
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-x-3 px-5 pb-4 pt-5", children: [
140
+ /* @__PURE__ */ jsx("div", { className: "flex size-11 shrink-0 items-center justify-center rounded-full bg-gradient-to-tl from-brand to-brand text-sm font-bold text-white", children: userInitials }),
141
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col overflow-hidden", children: [
142
+ /* @__PURE__ */ jsx("span", { className: "truncate text-sm font-semibold text-foreground", children: userName || t("userMenu.loading") }),
143
+ /* @__PURE__ */ jsx("span", { className: "truncate text-xs text-foreground-faint", children: userEmail || "" })
144
+ ] })
145
+ ] }),
146
+ /* @__PURE__ */ jsx("hr", { className: "border-border-subtle" }),
147
+ showAccounts && /* @__PURE__ */ jsxs(Fragment, { children: [
148
+ /* @__PURE__ */ jsx("div", { className: "px-5 pb-2 pt-4", children: /* @__PURE__ */ jsx("span", { className: "text-xxs font-semibold uppercase tracking-wider text-foreground-faint", children: t("userMenu.yourAccounts") }) }),
149
+ safeAccounts.length > SEARCH_THRESHOLD && /* @__PURE__ */ jsx("div", { className: "px-3 pb-2", children: /* @__PURE__ */ jsx(
150
+ UnifiedSearchBar,
151
+ {
152
+ mode: "default",
153
+ searchableItems: safeAccounts,
154
+ searchKeys: ["name"],
155
+ setFilteredItems: setFiltered,
156
+ label: t("userMenu.searchAccount"),
157
+ debounceTime: 300,
158
+ minSearchLength: 1,
159
+ containerClassName: "relative flex gap-x-2"
160
+ }
161
+ ) }),
162
+ /* @__PURE__ */ jsx("div", { className: "max-h-48 overflow-y-auto px-3 pb-2", children: loadingAccounts ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-4", children: /* @__PURE__ */ jsx(LoadingSpinner, { size: 5, color: "foreground-faint" }) }) : filtered.length === 0 ? /* @__PURE__ */ jsx(NoDataFound, { compact: true, message: t("userMenu.noAccounts") }) : filtered.map((account) => /* @__PURE__ */ jsx(
163
+ AccountRow,
164
+ {
165
+ account,
166
+ isActive: account.id === activeAccountId,
167
+ switchingAccountId,
168
+ onSwitchAccount
169
+ },
170
+ account.id
171
+ )) }),
172
+ /* @__PURE__ */ jsx("hr", { className: "border-border-subtle" })
173
+ ] }),
174
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col px-3 py-2", children: [
175
+ (menuItems ?? []).map(footerRow),
176
+ onLogout && /* @__PURE__ */ jsx(
177
+ ControlledButton,
178
+ {
179
+ defaultHtmlButton: true,
180
+ type: "button",
181
+ onClick: () => {
182
+ onOpenChange?.(false);
183
+ onLogout();
184
+ },
185
+ className: "cursor-pointer rounded-lg px-2 py-2.5 text-left text-sm text-danger-emphasis transition-colors hover:bg-danger-soft",
186
+ children: logoutLabel || t("userMenu.logout")
187
+ }
188
+ )
189
+ ] })
190
+ ] })
191
+ ] });
192
+ };
193
+ export {
194
+ UserMenu as default
195
+ };
196
+ //# sourceMappingURL=UserMenu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UserMenu.js","sources":["../../../src/components/UI/UserMenu.tsx"],"sourcesContent":["import { ReactNode, useEffect, useState } from 'react';\nimport classNames from 'classnames';\nimport { useTranslation } from 'react-i18next';\n\nimport ControlledButton from '@/components/Form/ControlledButton';\nimport ControlledImage from '@/components/Form/ControlledImage';\nimport { useUiNavigation } from '@/components/Navigation/UiNavigationContext';\nimport UnifiedSearchBar from '@/components/Search/UnifiedSearchBar';\nimport OutlinedChip from '@/components/UI/Chips/OutlinedChip';\nimport {\n ControlledPopoverContent,\n ControlledPopoverHandler,\n ControlledPopoverRoot,\n} from '@/components/UI/ControlledPopover';\nimport LoadingSpinner from '@/components/UI/LoadingSpinner';\nimport { MaterialSymbol } from '@/components/UI/MaterialSymbol';\nimport NoDataFound from '@/components/UI/NoDataFound';\nimport { getUserAvatarLetters } from '@/helpers/stringHelpers';\n\nconst SEARCH_THRESHOLD = 5;\n\nexport interface IUserMenuAccount {\n id: string;\n name: string;\n logoUrl?: string;\n}\n\nexport interface IUserMenuItem {\n key: string;\n label: string;\n /** Internal route, rendered through the navigation port's Link. */\n to?: string;\n onClick?: () => void;\n tone?: 'default' | 'danger';\n}\n\ninterface IUserMenuProps {\n userName?: string;\n userEmail?: string;\n /** The active account/tenant shown in the trigger, beside the user identity. */\n accountName?: string;\n accountLogoUrl?: string;\n /** Role chip in the trigger; omitted when empty. */\n roleLabel?: string;\n /** Account switcher list; omit (undefined) to hide the whole section. */\n accounts?: Array<IUserMenuAccount>;\n activeAccountId?: string;\n /** Account being switched to; disables the list and shows its spinner. */\n switchingAccountId?: string | null;\n loadingAccounts?: boolean;\n onSwitchAccount?: (accountId: string) => void;\n /** Fired when the popover opens/closes, e.g. to lazily fetch the accounts. */\n onOpenChange?: (open: boolean) => void;\n open: boolean;\n /** Extra rows in the footer (profile, settings...), before the logout row. */\n menuItems?: Array<IUserMenuItem>;\n onLogout?: () => void;\n logoutLabel?: string;\n /** Renders only the identity summary, with no popover (e.g. admin mode). */\n readOnly?: boolean;\n className?: string;\n}\n\nconst AccountRow: React.FC<{\n account: IUserMenuAccount;\n isActive: boolean;\n switchingAccountId?: string | null;\n onSwitchAccount?: (accountId: string) => void;\n}> = ({ account, isActive, switchingAccountId, onSwitchAccount }) => (\n <ControlledButton\n defaultHtmlButton\n type=\"button\"\n disabled={!!switchingAccountId}\n onClick={() => onSwitchAccount?.(account.id)}\n className={classNames('flex w-full items-center gap-x-3 rounded-lg px-2 py-2.5 transition-colors', {\n 'bg-brand-soft': isActive,\n 'hover:bg-muted': !isActive,\n 'disabled:cursor-not-allowed disabled:opacity-60': !!switchingAccountId,\n })}\n >\n {account.logoUrl ? (\n <ControlledImage\n src={account.logoUrl}\n className=\"size-8 shrink-0 rounded-full border border-brand-border bg-surface object-cover\"\n />\n ) : (\n <div className=\"flex size-8 shrink-0 items-center justify-center rounded-full bg-brand-hover text-xs font-bold text-brand-fg\">\n {getUserAvatarLetters(account.name)}\n </div>\n )}\n\n <div className=\"flex min-w-0 flex-1 flex-col items-start\">\n <span className=\"w-full truncate text-left text-sm text-foreground\">{account.name}</span>\n </div>\n\n {switchingAccountId === account.id && <LoadingSpinner size={4} color=\"foreground-faint\" />}\n {isActive && !switchingAccountId && <MaterialSymbol icon=\"check\" size={18} color=\"rgb(var(--color-primary))\" />}\n </ControlledButton>\n);\n\n/**\n * The uMode account menu: identity summary as the trigger, account switcher (with search past\n * five entries), custom rows and logout in a popover. Everything app-shaped (who the user is,\n * what switching does, where profile lives) arrives as props, so any host renders the same\n * surface the dashboard does.\n */\nconst UserMenu: React.FC<IUserMenuProps> = ({\n userName,\n userEmail,\n accountName,\n accountLogoUrl,\n roleLabel,\n accounts,\n activeAccountId,\n switchingAccountId,\n loadingAccounts = false,\n onSwitchAccount,\n onOpenChange,\n open,\n menuItems,\n onLogout,\n logoutLabel,\n readOnly = false,\n className,\n}) => {\n const { t } = useTranslation('ui');\n const { Link: NavigationLink } = useUiNavigation();\n\n const userInitials = userName ? getUserAvatarLetters(userName) : '??';\n const showAccounts = Array.isArray(accounts);\n const safeAccounts = accounts ?? [];\n\n const [filtered, setFiltered] = useState<Array<IUserMenuAccount>>(safeAccounts);\n\n useEffect(() => {\n setFiltered(accounts ?? []);\n }, [accounts, open]);\n\n const accountSummary = (\n <>\n <div className=\"flex size-10 shrink-0 items-center justify-center rounded-full bg-gradient-to-tl from-brand to-brand\">\n {accountLogoUrl && <ControlledImage src={accountLogoUrl} className=\"size-9 rounded-full\" />}\n </div>\n {/* Below the tablet edge the header only has room for the avatar; the same identity is\n one tap away inside the popover, so nothing is lost. */}\n <div className=\"hidden min-w-0 flex-1 flex-col items-start gap-y-0.5 tablet:flex\">\n <span className=\"w-full truncate text-left text-sm font-semibold text-foreground\">{userName}</span>\n <div className=\"flex w-full items-center justify-between gap-x-2\">\n <span className=\"min-w-0 flex-1 truncate text-left text-xs text-foreground-subtle\">{accountName}</span>\n {roleLabel && (\n <OutlinedChip\n label={roleLabel}\n chipIcon=\"verified_user\"\n truncate\n tooltip={roleLabel}\n className=\"max-w-[15rem] shrink-0 whitespace-nowrap border border-brand-border bg-brand-soft text-brand-emphasis\"\n />\n )}\n </div>\n </div>\n </>\n );\n\n if (readOnly) {\n return (\n <div className={classNames('flex min-w-0 items-center gap-x-2.5 px-2.5 py-1.5 tablet:min-w-[300px]', className)}>\n {accountSummary}\n </div>\n );\n }\n\n const footerRow = (item: IUserMenuItem): ReactNode => {\n const rowClass = classNames(\n 'rounded-lg px-2 py-2.5 text-left text-sm transition-colors',\n item.tone === 'danger' ? 'text-danger-emphasis hover:bg-danger-soft' : 'text-foreground-muted hover:bg-muted',\n );\n\n if (item.to) {\n return (\n <NavigationLink key={item.key} to={item.to} onClick={() => onOpenChange?.(false)} className={rowClass}>\n {item.label}\n </NavigationLink>\n );\n }\n return (\n <ControlledButton\n defaultHtmlButton\n key={item.key}\n type=\"button\"\n onClick={() => {\n onOpenChange?.(false);\n item.onClick?.();\n }}\n className={classNames('cursor-pointer', rowClass)}\n >\n {item.label}\n </ControlledButton>\n );\n };\n\n return (\n <ControlledPopoverRoot placement=\"bottom-end\" open={open} handler={(next) => onOpenChange?.(next)}>\n <ControlledPopoverHandler>\n <ControlledButton\n defaultHtmlButton\n type=\"button\"\n className={classNames(\n 'flex min-w-0 cursor-pointer items-center gap-x-2.5 px-2.5 py-1.5 tablet:min-w-[300px]',\n className,\n )}\n >\n {accountSummary}\n <MaterialSymbol\n icon={open ? 'expand_less' : 'expand_more'}\n size={20}\n color=\"rgb(var(--color-foreground-subtle))\"\n />\n </ControlledButton>\n </ControlledPopoverHandler>\n\n <ControlledPopoverContent className=\"z-[9999] w-72 max-w-[calc(100vw-1.5rem)] rounded-xl border border-border p-0 shadow-xl\">\n <div className=\"flex items-center gap-x-3 px-5 pb-4 pt-5\">\n <div className=\"flex size-11 shrink-0 items-center justify-center rounded-full bg-gradient-to-tl from-brand to-brand text-sm font-bold text-white\">\n {userInitials}\n </div>\n <div className=\"flex min-w-0 flex-1 flex-col overflow-hidden\">\n <span className=\"truncate text-sm font-semibold text-foreground\">{userName || t('userMenu.loading')}</span>\n <span className=\"truncate text-xs text-foreground-faint\">{userEmail || ''}</span>\n </div>\n </div>\n\n <hr className=\"border-border-subtle\" />\n\n {showAccounts && (\n <>\n <div className=\"px-5 pb-2 pt-4\">\n <span className=\"text-xxs font-semibold uppercase tracking-wider text-foreground-faint\">\n {t('userMenu.yourAccounts')}\n </span>\n </div>\n\n {safeAccounts.length > SEARCH_THRESHOLD && (\n <div className=\"px-3 pb-2\">\n <UnifiedSearchBar\n mode=\"default\"\n searchableItems={safeAccounts}\n searchKeys={['name']}\n setFilteredItems={setFiltered}\n label={t('userMenu.searchAccount')}\n debounceTime={300}\n minSearchLength={1}\n containerClassName=\"relative flex gap-x-2\"\n />\n </div>\n )}\n\n <div className=\"max-h-48 overflow-y-auto px-3 pb-2\">\n {loadingAccounts ? (\n <div className=\"flex items-center justify-center py-4\">\n <LoadingSpinner size={5} color=\"foreground-faint\" />\n </div>\n ) : filtered.length === 0 ? (\n <NoDataFound compact message={t('userMenu.noAccounts')} />\n ) : (\n filtered.map((account) => (\n <AccountRow\n key={account.id}\n account={account}\n isActive={account.id === activeAccountId}\n switchingAccountId={switchingAccountId}\n onSwitchAccount={onSwitchAccount}\n />\n ))\n )}\n </div>\n\n <hr className=\"border-border-subtle\" />\n </>\n )}\n\n <div className=\"flex flex-col px-3 py-2\">\n {(menuItems ?? []).map(footerRow)}\n\n {onLogout && (\n <ControlledButton\n defaultHtmlButton\n type=\"button\"\n onClick={() => {\n onOpenChange?.(false);\n onLogout();\n }}\n className=\"cursor-pointer rounded-lg px-2 py-2.5 text-left text-sm text-danger-emphasis transition-colors hover:bg-danger-soft\"\n >\n {logoutLabel || t('userMenu.logout')}\n </ControlledButton>\n )}\n </div>\n </ControlledPopoverContent>\n </ControlledPopoverRoot>\n );\n};\n\nexport default UserMenu;\nexport type { IUserMenuProps };\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAmBA,MAAM,mBAAmB;AA4CzB,MAAM,aAKD,CAAC,EAAE,SAAS,UAAU,oBAAoB,sBAC7C;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,mBAAiB;AAAA,IACjB,MAAK;AAAA,IACL,UAAU,CAAC,CAAC;AAAA,IACZ,SAAS,MAAM,kBAAkB,QAAQ,EAAE;AAAA,IAC3C,WAAW,WAAW,6EAA6E;AAAA,MACjG,iBAAiB;AAAA,MACjB,kBAAkB,CAAC;AAAA,MACnB,mDAAmD,CAAC,CAAC;AAAA,IAAA,CACtD;AAAA,IAEA,UAAA;AAAA,MAAA,QAAQ,UACP;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAK,QAAQ;AAAA,UACb,WAAU;AAAA,QAAA;AAAA,MAAA,wBAGX,OAAA,EAAI,WAAU,gHACZ,UAAA,qBAAqB,QAAQ,IAAI,GACpC;AAAA,MAGF,oBAAC,OAAA,EAAI,WAAU,4CACb,UAAA,oBAAC,UAAK,WAAU,qDAAqD,UAAA,QAAQ,KAAA,CAAK,EAAA,CACpF;AAAA,MAEC,uBAAuB,QAAQ,MAAM,oBAAC,kBAAe,MAAM,GAAG,OAAM,oBAAmB;AAAA,MACvF,YAAY,CAAC,sBAAsB,oBAAC,gBAAA,EAAe,MAAK,SAAQ,MAAM,IAAI,OAAM,4BAAA,CAA4B;AAAA,IAAA;AAAA,EAAA;AAC/G;AASF,MAAM,WAAqC,CAAC;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AACF,MAAM;AACJ,QAAM,EAAE,EAAA,IAAM,eAAe,IAAI;AACjC,QAAM,EAAE,MAAM,eAAA,IAAmB,gBAAA;AAEjC,QAAM,eAAe,WAAW,qBAAqB,QAAQ,IAAI;AACjE,QAAM,eAAe,MAAM,QAAQ,QAAQ;AAC3C,QAAM,eAAe,YAAY,CAAA;AAEjC,QAAM,CAAC,UAAU,WAAW,IAAI,SAAkC,YAAY;AAE9E,YAAU,MAAM;AACd,gBAAY,YAAY,EAAE;AAAA,EAC5B,GAAG,CAAC,UAAU,IAAI,CAAC;AAEnB,QAAM,iBACJ,qBAAA,UAAA,EACE,UAAA;AAAA,IAAA,oBAAC,OAAA,EAAI,WAAU,wGACZ,UAAA,kBAAkB,oBAAC,mBAAgB,KAAK,gBAAgB,WAAU,sBAAA,CAAsB,EAAA,CAC3F;AAAA,IAGA,qBAAC,OAAA,EAAI,WAAU,oEACb,UAAA;AAAA,MAAA,oBAAC,QAAA,EAAK,WAAU,mEAAmE,UAAA,UAAS;AAAA,MAC5F,qBAAC,OAAA,EAAI,WAAU,oDACb,UAAA;AAAA,QAAA,oBAAC,QAAA,EAAK,WAAU,oEAAoE,UAAA,aAAY;AAAA,QAC/F,aACC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,YACP,UAAS;AAAA,YACT,UAAQ;AAAA,YACR,SAAS;AAAA,YACT,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MACZ,EAAA,CAEJ;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAGF,MAAI,UAAU;AACZ,+BACG,OAAA,EAAI,WAAW,WAAW,0EAA0E,SAAS,GAC3G,UAAA,gBACH;AAAA,EAEJ;AAEA,QAAM,YAAY,CAAC,SAAmC;AACpD,UAAM,WAAW;AAAA,MACf;AAAA,MACA,KAAK,SAAS,WAAW,8CAA8C;AAAA,IAAA;AAGzE,QAAI,KAAK,IAAI;AACX,aACE,oBAAC,gBAAA,EAA8B,IAAI,KAAK,IAAI,SAAS,MAAM,eAAe,KAAK,GAAG,WAAW,UAC1F,UAAA,KAAK,MAAA,GADa,KAAK,GAE1B;AAAA,IAEJ;AACA,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,mBAAiB;AAAA,QAEjB,MAAK;AAAA,QACL,SAAS,MAAM;AACb,yBAAe,KAAK;AACpB,eAAK,UAAA;AAAA,QACP;AAAA,QACA,WAAW,WAAW,kBAAkB,QAAQ;AAAA,QAE/C,UAAA,KAAK;AAAA,MAAA;AAAA,MARD,KAAK;AAAA,IAAA;AAAA,EAWhB;AAEA,SACE,qBAAC,uBAAA,EAAsB,WAAU,cAAa,MAAY,SAAS,CAAC,SAAS,eAAe,IAAI,GAC9F,UAAA;AAAA,IAAA,oBAAC,0BAAA,EACC,UAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,mBAAiB;AAAA,QACjB,MAAK;AAAA,QACL,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QAAA;AAAA,QAGD,UAAA;AAAA,UAAA;AAAA,UACD;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAM,OAAO,gBAAgB;AAAA,cAC7B,MAAM;AAAA,cACN,OAAM;AAAA,YAAA;AAAA,UAAA;AAAA,QACR;AAAA,MAAA;AAAA,IAAA,GAEJ;AAAA,IAEA,qBAAC,0BAAA,EAAyB,WAAU,0FAClC,UAAA;AAAA,MAAA,qBAAC,OAAA,EAAI,WAAU,4CACb,UAAA;AAAA,QAAA,oBAAC,OAAA,EAAI,WAAU,qIACZ,UAAA,cACH;AAAA,QACA,qBAAC,OAAA,EAAI,WAAU,gDACb,UAAA;AAAA,UAAA,oBAAC,UAAK,WAAU,kDAAkD,UAAA,YAAY,EAAE,kBAAkB,GAAE;AAAA,UACpG,oBAAC,QAAA,EAAK,WAAU,0CAA0C,uBAAa,GAAA,CAAG;AAAA,QAAA,EAAA,CAC5E;AAAA,MAAA,GACF;AAAA,MAEA,oBAAC,MAAA,EAAG,WAAU,uBAAA,CAAuB;AAAA,MAEpC,gBACC,qBAAA,UAAA,EACE,UAAA;AAAA,QAAA,oBAAC,OAAA,EAAI,WAAU,kBACb,UAAA,oBAAC,QAAA,EAAK,WAAU,yEACb,UAAA,EAAE,uBAAuB,EAAA,CAC5B,GACF;AAAA,QAEC,aAAa,SAAS,oBACrB,oBAAC,OAAA,EAAI,WAAU,aACb,UAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,iBAAiB;AAAA,YACjB,YAAY,CAAC,MAAM;AAAA,YACnB,kBAAkB;AAAA,YAClB,OAAO,EAAE,wBAAwB;AAAA,YACjC,cAAc;AAAA,YACd,iBAAiB;AAAA,YACjB,oBAAmB;AAAA,UAAA;AAAA,QAAA,GAEvB;AAAA,QAGF,oBAAC,OAAA,EAAI,WAAU,sCACZ,4BACC,oBAAC,OAAA,EAAI,WAAU,yCACb,UAAA,oBAAC,gBAAA,EAAe,MAAM,GAAG,OAAM,mBAAA,CAAmB,EAAA,CACpD,IACE,SAAS,WAAW,IACtB,oBAAC,aAAA,EAAY,SAAO,MAAC,SAAS,EAAE,qBAAqB,EAAA,CAAG,IAExD,SAAS,IAAI,CAAC,YACZ;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC;AAAA,YACA,UAAU,QAAQ,OAAO;AAAA,YACzB;AAAA,YACA;AAAA,UAAA;AAAA,UAJK,QAAQ;AAAA,QAAA,CAMhB,GAEL;AAAA,QAEA,oBAAC,MAAA,EAAG,WAAU,uBAAA,CAAuB;AAAA,MAAA,GACvC;AAAA,MAGF,qBAAC,OAAA,EAAI,WAAU,2BACX,UAAA;AAAA,SAAA,aAAa,CAAA,GAAI,IAAI,SAAS;AAAA,QAE/B,YACC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,mBAAiB;AAAA,YACjB,MAAK;AAAA,YACL,SAAS,MAAM;AACb,6BAAe,KAAK;AACpB,uBAAA;AAAA,YACF;AAAA,YACA,WAAU;AAAA,YAET,UAAA,eAAe,EAAE,iBAAiB;AAAA,UAAA;AAAA,QAAA;AAAA,MACrC,EAAA,CAEJ;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;"}
package/dist/index.d.ts CHANGED
@@ -14,7 +14,12 @@ export { default as ControlledBreadcrumb } from './components/Navigation/Control
14
14
  export { default as ErrorPage } from './components/Navigation/ErrorPage';
15
15
  export { default as PageTitle } from './components/Navigation/PageTitle';
16
16
  export * from './components/Navigation/PageTitleNavigationContext';
17
+ export * from './components/Navigation/UiNavigationContext';
17
18
  export { default as UnifiedSearchBar } from './components/Search/UnifiedSearchBar';
19
+ export { default as AppShell } from './components/Shell/AppShell';
20
+ export { default as ShellLanguageToggle } from './components/Shell/LanguageToggle';
21
+ export * from './components/Shell/SidebarMenu';
22
+ export { default as ShellThemeToggle } from './components/Shell/ThemeToggle';
18
23
  export * from './components/UI/access/UiAccessContext';
19
24
  export { default as BaseDataCard } from './components/UI/BaseDataCard';
20
25
  export { default as OutlinedChip } from './components/UI/Chips/OutlinedChip';
@@ -34,6 +39,7 @@ export { default as LoadingSpinner } from './components/UI/LoadingSpinner';
34
39
  export * from './components/UI/MaterialSymbol/index';
35
40
  export { default as NoDataFound } from './components/UI/NoDataFound/index';
36
41
  export { default as SkeletonLoading } from './components/UI/SkeletonLoading';
42
+ export { default as UserMenu } from './components/UI/UserMenu';
37
43
  export * from './helpers/composeRefs';
38
44
  export * from './helpers/layeredSurfaces';
39
45
  export * from './helpers/themeTokens';
package/dist/index.js CHANGED
@@ -14,26 +14,32 @@ import { default as default13 } from "./components/Navigation/ControlledBreadcru
14
14
  import { default as default14 } from "./components/Navigation/ErrorPage.js";
15
15
  import { default as default15 } from "./components/Navigation/PageTitle.js";
16
16
  import { PageTitleNavigationProvider, usePageTitleNavigation } from "./components/Navigation/PageTitleNavigationContext.js";
17
+ import { UiNavigationProvider, useUiNavigation } from "./components/Navigation/UiNavigationContext.js";
17
18
  import { default as default16 } from "./components/Search/UnifiedSearchBar.js";
19
+ import { default as default17 } from "./components/Shell/AppShell.js";
20
+ import { default as default18 } from "./components/Shell/LanguageToggle.js";
21
+ import { resolveSidebarItemId } from "./components/Shell/SidebarMenu.js";
22
+ import { default as default19 } from "./components/Shell/ThemeToggle.js";
18
23
  import { UiAccessProvider, useUiAccess } from "./components/UI/access/UiAccessContext.js";
19
- import { default as default17 } from "./components/UI/BaseDataCard.js";
20
- import { default as default18 } from "./components/UI/Chips/OutlinedChip.js";
21
- import { default as default19 } from "./components/UI/Colors.js";
22
- import { default as default20 } from "./components/UI/ColorSwatch.js";
23
- import { default as default21 } from "./components/UI/ControlledAccordion.js";
24
- import { default as default22 } from "./components/UI/ControlledCollapse.js";
25
- import { default as default23 } from "./components/UI/ControlledMenu.js";
26
- import { default as default24 } from "./components/UI/ControlledPopover.js";
27
- import { default as default25 } from "./components/UI/ControlledProgress.js";
28
- import { default as default26 } from "./components/UI/ControlledSlider.js";
29
- import { default as default27 } from "./components/UI/ControlledTooltip.js";
30
- import { default as default28 } from "./components/UI/CustomBadge.js";
31
- import { default as default29 } from "./components/UI/CustomCard.js";
32
- import { default as default30 } from "./components/UI/InformationCard.js";
33
- import { default as default31 } from "./components/UI/LoadingSpinner.js";
24
+ import { default as default20 } from "./components/UI/BaseDataCard.js";
25
+ import { default as default21 } from "./components/UI/Chips/OutlinedChip.js";
26
+ import { default as default22 } from "./components/UI/Colors.js";
27
+ import { default as default23 } from "./components/UI/ColorSwatch.js";
28
+ import { default as default24 } from "./components/UI/ControlledAccordion.js";
29
+ import { default as default25 } from "./components/UI/ControlledCollapse.js";
30
+ import { default as default26 } from "./components/UI/ControlledMenu.js";
31
+ import { default as default27 } from "./components/UI/ControlledPopover.js";
32
+ import { default as default28 } from "./components/UI/ControlledProgress.js";
33
+ import { default as default29 } from "./components/UI/ControlledSlider.js";
34
+ import { default as default30 } from "./components/UI/ControlledTooltip.js";
35
+ import { default as default31 } from "./components/UI/CustomBadge.js";
36
+ import { default as default32 } from "./components/UI/CustomCard.js";
37
+ import { default as default33 } from "./components/UI/InformationCard.js";
38
+ import { default as default34 } from "./components/UI/LoadingSpinner.js";
34
39
  import { MaterialSymbol, combineClasses } from "./components/UI/MaterialSymbol/index.js";
35
- import { default as default32 } from "./components/UI/NoDataFound/index.js";
36
- import { default as default33 } from "./components/UI/SkeletonLoading.js";
40
+ import { default as default35 } from "./components/UI/NoDataFound/index.js";
41
+ import { default as default36 } from "./components/UI/SkeletonLoading.js";
42
+ import { default as default37 } from "./components/UI/UserMenu.js";
37
43
  import { composeRefs } from "./helpers/composeRefs.js";
38
44
  import { isPressOnLayeredSurface } from "./helpers/layeredSurfaces.js";
39
45
  import { readThemeToken, useThemeChartTokens } from "./helpers/themeTokens.js";
@@ -50,44 +56,49 @@ import { uiLocales } from "./locales/index.js";
50
56
  import { collapseVariants, createDrawerVariants, dialogVariants, fadeVariants, floatingVariants, scrimVariants, tooltipVariants } from "./motion/motionPresets.js";
51
57
  import { MOTION_OFFSET_PX, enterTransition, exitTransition, motionDuration, motionEase } from "./motion/motionTokens.js";
52
58
  export {
59
+ default17 as AppShell,
53
60
  BREAKPOINTS,
54
- default17 as BaseDataCard,
55
- default20 as ColorSwatch,
56
- default19 as Colors,
57
- default21 as ControlledAccordion,
61
+ default20 as BaseDataCard,
62
+ default23 as ColorSwatch,
63
+ default22 as Colors,
64
+ default24 as ControlledAccordion,
58
65
  default13 as ControlledBreadcrumb,
59
66
  default2 as ControlledButton,
60
67
  default3 as ControlledCheckbox,
61
- default22 as ControlledCollapse,
68
+ default25 as ControlledCollapse,
62
69
  default4 as ControlledDialog,
63
70
  default5 as ControlledDrawer,
64
71
  default6 as ControlledImage,
65
72
  default7 as ControlledInput,
66
- default23 as ControlledMenu,
67
- default24 as ControlledPopover,
68
- default25 as ControlledProgress,
73
+ default26 as ControlledMenu,
74
+ default27 as ControlledPopover,
75
+ default28 as ControlledProgress,
69
76
  default8 as ControlledRadio,
70
77
  ControlledSelect,
71
- default26 as ControlledSlider,
78
+ default29 as ControlledSlider,
72
79
  default9 as ControlledSwitch,
73
80
  default10 as ControlledTabs,
74
81
  default11 as ControlledTextarea,
75
- default27 as ControlledTooltip,
82
+ default30 as ControlledTooltip,
76
83
  default12 as ControlledViewToggle,
77
- default28 as CustomBadge,
78
- default29 as CustomCard,
84
+ default31 as CustomBadge,
85
+ default32 as CustomCard,
79
86
  default14 as ErrorPage,
80
- default30 as InformationCard,
81
- default31 as LoadingSpinner,
87
+ default33 as InformationCard,
88
+ default34 as LoadingSpinner,
82
89
  MOTION_OFFSET_PX,
83
90
  MaterialSymbol,
84
- default32 as NoDataFound,
85
- default18 as OutlinedChip,
91
+ default35 as NoDataFound,
92
+ default21 as OutlinedChip,
86
93
  default15 as PageTitle,
87
94
  PageTitleNavigationProvider,
88
- default33 as SkeletonLoading,
95
+ default18 as ShellLanguageToggle,
96
+ default19 as ShellThemeToggle,
97
+ default36 as SkeletonLoading,
89
98
  UiAccessProvider,
99
+ UiNavigationProvider,
90
100
  default16 as UnifiedSearchBar,
101
+ default37 as UserMenu,
91
102
  collapseVariants,
92
103
  combineClasses,
93
104
  composeRefs,
@@ -104,6 +115,7 @@ export {
104
115
  motionEase,
105
116
  readThemeToken,
106
117
  readUiPreference,
118
+ resolveSidebarItemId,
107
119
  resolveUiPreferenceScopeId,
108
120
  scrimVariants,
109
121
  tooltipVariants,
@@ -120,6 +132,7 @@ export {
120
132
  useResolvedTheme,
121
133
  useThemeChartTokens,
122
134
  useUiAccess,
135
+ useUiNavigation,
123
136
  writeUiPreference
124
137
  };
125
138
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -366,6 +366,11 @@ declare const _default: {
366
366
  "requiredField": "This field is required",
367
367
  "loadingInfo": "Loading information..."
368
368
  },
369
+ "language": {
370
+ "toggle": "Language",
371
+ "pt_short": "PT",
372
+ "en_short": "EN"
373
+ },
369
374
  "noDataFound": {
370
375
  "variants": {
371
376
  "empty": "Nothing here yet",
@@ -438,6 +443,22 @@ declare const _default: {
438
443
  "description": "This is usually temporary. Try again and, if it stays like this, contact support and tell them what you were doing."
439
444
  }
440
445
  },
446
+ "sidebar": {
447
+ "home": "Home",
448
+ "logout": "Sign out",
449
+ "openSidebar": "Open sidebar",
450
+ "collapseSidebar": "Collapse sidebar",
451
+ "sections": {
452
+ "management": "Management",
453
+ "registration": "Records"
454
+ }
455
+ },
456
+ "theme": {
457
+ "toggle": "Theme",
458
+ "light": "Light theme",
459
+ "dark": "Dark theme",
460
+ "system": "Follow system"
461
+ },
441
462
  "toast": {
442
463
  "learnMore": "Learn more"
443
464
  },
@@ -459,6 +480,13 @@ declare const _default: {
459
480
  "urlLinkCell": {
460
481
  "clickToAccess": "Click to access"
461
482
  },
483
+ "userMenu": {
484
+ "loading": "Loading...",
485
+ "yourAccounts": "Your Accounts",
486
+ "searchAccount": "Search account",
487
+ "noAccounts": "No active accounts available",
488
+ "logout": "Sign out"
489
+ },
462
490
  "voiceInput": {
463
491
  "start": "Transcribe by voice",
464
492
  "stop": "Stop transcription",