@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.
- package/README.md +78 -0
- package/dist/assets/umode-ui.css +148 -0
- package/dist/components/Form/ControlledSelect.js +1 -1
- package/dist/components/Form/ControlledTabs.js +4 -4
- package/dist/components/Form/ControlledTabs.js.map +1 -1
- package/dist/components/Form/ControlledViewToggle.js +2 -2
- package/dist/components/Form/ControlledViewToggle.js.map +1 -1
- package/dist/components/Navigation/ControlledBreadcrumb.js +3 -2
- package/dist/components/Navigation/ControlledBreadcrumb.js.map +1 -1
- package/dist/components/Navigation/PageTitle.js +3 -6
- package/dist/components/Navigation/PageTitle.js.map +1 -1
- package/dist/components/Navigation/ReactRouterNavigationAdapter.d.ts +7 -0
- package/dist/components/Navigation/ReactRouterNavigationAdapter.js +26 -0
- package/dist/components/Navigation/ReactRouterNavigationAdapter.js.map +1 -0
- package/dist/components/Navigation/UiNavigationContext.d.ts +38 -0
- package/dist/components/Navigation/UiNavigationContext.js +43 -0
- package/dist/components/Navigation/UiNavigationContext.js.map +1 -0
- package/dist/components/Search/filters/useFilters.js +2 -2
- package/dist/components/Search/filters/useFilters.js.map +1 -1
- package/dist/components/Shell/AppHeader.d.ts +19 -0
- package/dist/components/Shell/AppHeader.js +64 -0
- package/dist/components/Shell/AppHeader.js.map +1 -0
- package/dist/components/Shell/AppShell.d.ts +20 -0
- package/dist/components/Shell/AppShell.js +100 -0
- package/dist/components/Shell/AppShell.js.map +1 -0
- package/dist/components/Shell/AppSidebar.d.ts +15 -0
- package/dist/components/Shell/AppSidebar.js +63 -0
- package/dist/components/Shell/AppSidebar.js.map +1 -0
- package/dist/components/Shell/LanguageToggle.d.ts +8 -0
- package/dist/components/Shell/LanguageToggle.js +59 -0
- package/dist/components/Shell/LanguageToggle.js.map +1 -0
- package/dist/components/Shell/SidebarMenu.d.ts +24 -0
- package/dist/components/Shell/SidebarMenu.js +204 -0
- package/dist/components/Shell/SidebarMenu.js.map +1 -0
- package/dist/components/Shell/ThemeToggle.d.ts +11 -0
- package/dist/components/Shell/ThemeToggle.js +55 -0
- package/dist/components/Shell/ThemeToggle.js.map +1 -0
- package/dist/components/Shell/headerControlStyles.d.ts +10 -0
- package/dist/components/Shell/headerControlStyles.js +11 -0
- package/dist/components/Shell/headerControlStyles.js.map +1 -0
- package/dist/components/Shell/useSidebarState.d.ts +14 -0
- package/dist/components/Shell/useSidebarState.js +106 -0
- package/dist/components/Shell/useSidebarState.js.map +1 -0
- package/dist/components/UI/BaseDataCard.js +3 -2
- package/dist/components/UI/BaseDataCard.js.map +1 -1
- package/dist/components/UI/DataTable/DataTable.js +1 -1
- package/dist/components/UI/DataTable/DataTableBulkEditDialog.js +1 -1
- package/dist/components/UI/DataTable/DataTableFilters.js +1 -1
- package/dist/components/UI/DataTable/DataTableToolbar.js +1 -1
- package/dist/components/UI/DataTable/applyDataTableFilters.js +1 -1
- package/dist/components/UI/UserMenu.d.ts +48 -0
- package/dist/components/UI/UserMenu.js +196 -0
- package/dist/components/UI/UserMenu.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +47 -34
- package/dist/index.js.map +1 -1
- package/dist/locales/en/ui.json.d.ts +28 -0
- package/dist/locales/en/ui.json.js +12 -0
- package/dist/locales/en/ui.json.js.map +1 -1
- package/dist/locales/index.d.ts +56 -0
- package/dist/locales/pt/ui.json.d.ts +28 -0
- package/dist/locales/pt/ui.json.js +12 -0
- package/dist/locales/pt/ui.json.js.map +1 -1
- package/package.json +6 -3
- 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":";;;;;;;;;;AAmCA,MAAM,eAA6C,CAAC;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,mBAAmB;AAAA,EACnB;AAAA,EACA,YAAY;AAAA,EACZ,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,EAAE,MAAM,eAAA,IAAmB,gBAAA;AACjC,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,KAAK;AACxD,QAAM,UAAU,OAAuB,IAAI;AAE3C,QAAM,oBAAoB,MAAM;AAC9B,UAAM,sBAAsB,CAAC;AAC7B,qBAAiB,mBAAmB;AACpC,QAAI,cAAc;AAChB,mBAAA;AAAA,IACF;AACA,QAAI,CAAC,uBAAuB,QAAQ,WAAW,WAAW;AACxD,iBAAW,MAAM;AACf,iBAAS,MAAM,qBAAqB;AACpC,gBAAQ,SAAS,eAAe,EAAE,UAAU,UAAU,OAAO,SAAS;AAAA,MACxE,GAAG,CAAC;AAAA,IACN;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,WAAW,2CAA2C;AAAA,QAC/D,CAAC,GAAG,SAAS,EAAE,GAAG,CAAC,CAAC;AAAA,QACpB,aAAa;AAAA,QACb,CAAC,oGAAoG,GACnG;AAAA,MAAA,CACH;AAAA,MACD,WAAW;AAAA,MAEX,UAAA;AAAA,QAAA,qBAAC,OAAA,EAAI,WAAU,wCACb,UAAA;AAAA,UAAA,qBAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,YAAA,oBAAC,OAAA,EAAI,WAAU,4CACZ,UAAA,UACC,oBAAC,iBAAA,EAAgB,WAAU,OAAA,CAAO,IAElC,qBAAC,OAAA,EAAI,WAAU,+BACZ,UAAA;AAAA,cAAA,cACE,cACC,oBAAC,mBAAA,EAAkB,SAAS,aAAa,WAAU,YACjD,UAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAM;AAAA,kBACN,MAAM,aAAa,KAAK;AAAA,kBACxB,OAAM;AAAA,kBACN,WAAU;AAAA,gBAAA;AAAA,cAAA,GAEd,IAEA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAM;AAAA,kBACN,MAAM,aAAa,KAAK;AAAA,kBACxB,OAAM;AAAA,kBACN,WAAU;AAAA,gBAAA;AAAA,cAAA;AAAA,cAIf,SACC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAW;AAAA,oBACT;AAAA,oBACA;AAAA,sBACE,WAAW;AAAA,sBACX,WAAW,CAAC;AAAA,oBAAA;AAAA,oBAEd;AAAA,kBAAA;AAAA,kBAGD,UAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,cAIJ,eACC,oBAAC,mBAAA,EAAkB,SAAS,aAAa,WAAU,YACjD,UAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,MAAM,aAAa,KAAK;AAAA,kBACxB,OAAM;AAAA,kBACN,WAAU;AAAA,gBAAA;AAAA,cAAA,EACZ,CACF;AAAA,YAAA,EAAA,CAEJ,EAAA,CAEJ;AAAA,YAEA,oBAAC,OAAA,EACE,UAAA,UACC,oBAAC,iBAAA,EAAgB,MAAK,UAAS,WAAU,OAAA,CAAO,IAEhD,qBAAC,OAAA,EAAI,WAAU,+BACZ,UAAA;AAAA,cAAA,cACC,oBAAC,gBAAA,EAAe,IAAI,YAClB,UAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,mBAAiB;AAAA,kBACjB,SAAS;AAAA,kBACT,WAAU;AAAA,kBAEV,UAAA,oBAAC,gBAAA,EAAe,OAAM,6BAA4B,MAAM,WAAA,CAAY;AAAA,gBAAA;AAAA,cAAA,GAExE;AAAA,cAGD,YACC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,mBAAiB;AAAA,kBACjB,SAAS;AAAA,kBACT,WAAU;AAAA,kBAEV,UAAA,oBAAC,gBAAA,EAAe,OAAM,6BAA4B,MAAM,WAAA,CAAY;AAAA,gBAAA;AAAA,cAAA;AAAA,cAIvE,mDAAsB,UAAA,gBAAA,CAAgB;AAAA,cAEtC,gCAAa,gBAAA,EAAe,MAAM,UAAU,MAAM,IAAI,OAAM,4BAAA,CAA4B;AAAA,YAAA,EAAA,CAC3F,EAAA,CAEJ;AAAA,UAAA,GACF;AAAA,UAEA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAW,WAAW,UAAU;AAAA,gBAC9B,WAAW;AAAA,gBACX,UAAU,CAAC;AAAA,cAAA,CACZ;AAAA,cAEA;AAAA,YAAA;AAAA,UAAA;AAAA,QACH,GACF;AAAA,QAEC,oBAAoB,qBACnB,oBAAC,OAAA,EAAI,WAAU,wGACb,UAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,SAAS;AAAA,YAET,UAAA;AAAA,cAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,MAAM;AAAA,kBACN,OAAM;AAAA,kBACN,WAAW,WAAW,sCAAsC;AAAA,oBAC1D,cAAc;AAAA,kBAAA,CACf;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGF;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA,EACH,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAIR;"}
|
|
@@ -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 "
|
|
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 "
|
|
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 "
|
|
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 "
|
|
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 "
|
|
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":"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"}
|
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
|
|
20
|
-
import { default as
|
|
21
|
-
import { default as
|
|
22
|
-
import { default as
|
|
23
|
-
import { default as
|
|
24
|
-
import { default as
|
|
25
|
-
import { default as
|
|
26
|
-
import { default as
|
|
27
|
-
import { default as
|
|
28
|
-
import { default as
|
|
29
|
-
import { default as
|
|
30
|
-
import { default as
|
|
31
|
-
import { default as
|
|
32
|
-
import { default as
|
|
33
|
-
import { default as
|
|
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
|
|
36
|
-
import { default as
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
73
|
+
default26 as ControlledMenu,
|
|
74
|
+
default27 as ControlledPopover,
|
|
75
|
+
default28 as ControlledProgress,
|
|
69
76
|
default8 as ControlledRadio,
|
|
70
77
|
ControlledSelect,
|
|
71
|
-
|
|
78
|
+
default29 as ControlledSlider,
|
|
72
79
|
default9 as ControlledSwitch,
|
|
73
80
|
default10 as ControlledTabs,
|
|
74
81
|
default11 as ControlledTextarea,
|
|
75
|
-
|
|
82
|
+
default30 as ControlledTooltip,
|
|
76
83
|
default12 as ControlledViewToggle,
|
|
77
|
-
|
|
78
|
-
|
|
84
|
+
default31 as CustomBadge,
|
|
85
|
+
default32 as CustomCard,
|
|
79
86
|
default14 as ErrorPage,
|
|
80
|
-
|
|
81
|
-
|
|
87
|
+
default33 as InformationCard,
|
|
88
|
+
default34 as LoadingSpinner,
|
|
82
89
|
MOTION_OFFSET_PX,
|
|
83
90
|
MaterialSymbol,
|
|
84
|
-
|
|
85
|
-
|
|
91
|
+
default35 as NoDataFound,
|
|
92
|
+
default21 as OutlinedChip,
|
|
86
93
|
default15 as PageTitle,
|
|
87
94
|
PageTitleNavigationProvider,
|
|
88
|
-
|
|
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",
|