@codebit-programando-solucoes/codebit-web-antd 1.1.44 → 1.1.46

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.
@@ -17,7 +17,7 @@ export interface LoggedMainContainerProps {
17
17
  * - Role‑based menu filtering
18
18
  * - User logout functionality
19
19
  * - Application version display
20
- * - Header user-profile avatar/dropdown (see `UserMenu`), built from the `userMenuItems` config function
20
+ * - A `headerExtra` slot occupying the header's entire right-hand side — the host app composes its own theme toggle, user menu, etc. there (see `ThemeToggle`, `UserMenu`)
21
21
  *
22
22
  * This component must be used within a `CodebitConfigProvider` and `CodebitThemeContext` context to access configuration such as menu items, user data, and theme settings.
23
23
  *
@@ -62,21 +62,20 @@ export interface CodebitConfigContextType {
62
62
  /** Function that returns menu items configuration for items displayed above the logout button in the bottom menu. */
63
63
  bottomMenuItems?: (user?: LoggedUser) => MenuItem[];
64
64
  /**
65
- * Function that returns menu items configuration for the header user-menu dropdown (opened by clicking the user avatar next to the theme toggle). Takes an optional
66
- * `LoggedUser` object as parameter and returns an array of `MenuItem` objects. Clicks on these items invoke `onMenuClick` with the item's key, but — unlike
67
- * `menuItems`/`bottomMenuItems` — never trigger the built-in navigation/logout behavior; the host application is fully responsible for reacting to the click (e.g. opening a
68
- * modal).
65
+ * Renders the entire right-hand side of the header (where the theme toggle and user menu used to be hardcoded). Receives the current `LoggedUser` and returns whatever the host
66
+ * application wants there — typically `<ThemeToggle />`, a `<UserMenu />` built from its own items/click handling, and any app-specific controls, composed together. The
67
+ * library no longer assembles this area itself; `ThemeToggle` and `UserMenu` remain exported so the host app can reuse them.
69
68
  */
70
- userMenuItems?: (user?: LoggedUser) => MenuItem[];
69
+ headerExtra?: (user?: LoggedUser) => React.ReactNode;
71
70
  /**
72
- * Function invoked when a menu item is clicked. Receives the item's key.
73
- *
74
- * For clicks originating from `menuItems`/`bottomMenuItems` (sidebar navigation), the return value controls the built-in behavior:
71
+ * Function invoked when a menu item is clicked. Receives the item's key. Only covers `menuItems`/`bottomMenuItems` (sidebar navigation) clicks — the return value controls the
72
+ * built-in behavior:
75
73
  *
76
74
  * - Returning **`false`** cancels the internal action (navigation or logout).
77
75
  * - Returning **`true`** (or any other truthy value) lets the internal processing continue as usual.
78
76
  *
79
- * For clicks originating from `userMenuItems` (header user-menu dropdown), there is no built-in action to cancel — the return value is ignored for these clicks.
77
+ * Clicks inside `headerExtra`'s content (e.g. a `UserMenu` composed there) are entirely the host application's responsibility — they don't go through this callback unless the
78
+ * host app chooses to wire it up that way itself.
80
79
  */
81
80
  onMenuClick?: (key: string) => boolean;
82
81
  }
@@ -97,24 +96,19 @@ export interface CodebitConfigProviderProps {
97
96
  secondarySidebarWidth?: number;
98
97
  /** Function that returns bottom‑menu items. */
99
98
  bottomMenuItems?: (user?: LoggedUser) => MenuItem[];
100
- /**
101
- * Function that returns items for the header user-menu dropdown (e.g. a "Minhas preferências" entry). Clicks on these items invoke `onMenuClick` but never trigger the
102
- * built-in navigation/logout behavior — the host application is fully responsible for reacting to the click (e.g. opening a modal).
103
- */
104
- userMenuItems?: (user?: LoggedUser) => MenuItem[];
99
+ /** Renders the entire right-hand side of the header. See {@link CodebitConfigContextType.headerExtra} — same contract, this is just the prop the host app passes in. */
100
+ headerExtra?: (user?: LoggedUser) => React.ReactNode;
105
101
  /** Function to handle user logout. */
106
102
  doLogout: () => Promise<void>;
107
103
  /** Function to check login status and return user data. */
108
104
  checkLogin: () => Promise<any | null>;
109
105
  /**
110
- * Callback executed when a menu item is clicked. Receives the item's key.
111
- *
112
- * For `menuItems`/`bottomMenuItems` clicks (sidebar navigation):
106
+ * Callback executed when a menu item is clicked. Receives the item's key. Only covers `menuItems`/`bottomMenuItems` (sidebar navigation) clicks:
113
107
  *
114
108
  * - Return **`false`** to **prevent** the default internal handling (navigation, logout, etc.).
115
109
  * - Return **`true`** (or any truthy value) to allow the default processing to proceed.
116
110
  *
117
- * For `userMenuItems` clicks (header user-menu dropdown), the return value is ignored — there is no default action to prevent.
111
+ * Clicks inside `headerExtra`'s content are not routed through this callback automatically — wire that up yourself if you want to reuse the same handler.
118
112
  */
119
113
  onMenuClick?: (key: string) => boolean;
120
114
  }
@@ -49,4 +49,6 @@ type CodebitThemeProviderProps = {
49
49
  forcedTheme?: 'dark' | 'light' | null;
50
50
  /** Optional color overrides. Any color/shade not provided falls back to Codebit's current default palette. */
51
51
  colors?: CodebitThemeColors;
52
+ /** Optional font-family override applied to antd's `token.fontFamily`. When unset, antd's default font stack is used (unchanged from current behavior). */
53
+ fontFamily?: string;
52
54
  } & ConfigProviderProps;
package/dist/index.cjs CHANGED
@@ -620,7 +620,7 @@ var __webpack_exports__ = {};
620
620
  const codebit_web_namespaceObject = require("@codebit-programando-solucoes/codebit-web");
621
621
  const logger = new codebit_web_namespaceObject.Logger('CodebitConfigContext');
622
622
  const CodebitConfigContext = /*#__PURE__*/ (0, external_react_.createContext)(null);
623
- function CodebitConfigProvider({ children, menuItems, version = '1.0', showVersion = ()=>true, secondarySidebar, secondarySidebarWidth = 280, bottomMenuItems, userMenuItems, doLogout, checkLogin, onMenuClick }) {
623
+ function CodebitConfigProvider({ children, menuItems, version = '1.0', showVersion = ()=>true, secondarySidebar, secondarySidebarWidth = 280, bottomMenuItems, headerExtra, doLogout, checkLogin, onMenuClick }) {
624
624
  const [isLogged, setIsLogged] = (0, external_react_.useState)(null);
625
625
  const [user, setUser] = (0, external_react_.useState)(null);
626
626
  const logout = async ()=>{
@@ -665,7 +665,7 @@ var __webpack_exports__ = {};
665
665
  secondarySidebar,
666
666
  secondarySidebarWidth,
667
667
  bottomMenuItems,
668
- userMenuItems,
668
+ headerExtra,
669
669
  onMenuClick
670
670
  }), [
671
671
  menuItems,
@@ -676,7 +676,7 @@ var __webpack_exports__ = {};
676
676
  secondarySidebar,
677
677
  secondarySidebarWidth,
678
678
  bottomMenuItems,
679
- userMenuItems,
679
+ headerExtra,
680
680
  onMenuClick
681
681
  ]);
682
682
  return /*#__PURE__*/ (0, jsx_runtime.jsx)(CodebitConfigContext.Provider, {
@@ -692,7 +692,7 @@ var __webpack_exports__ = {};
692
692
  secondarySidebar: external_prop_types_default().func,
693
693
  secondarySidebarWidth: external_prop_types_default().number,
694
694
  bottomMenuItems: external_prop_types_default().func,
695
- userMenuItems: external_prop_types_default().func,
695
+ headerExtra: external_prop_types_default().func,
696
696
  doLogout: external_prop_types_default().func.isRequired,
697
697
  checkLogin: external_prop_types_default().func.isRequired,
698
698
  onMenuClick: external_prop_types_default().func
@@ -720,7 +720,7 @@ var __webpack_exports__ = {};
720
720
  dark: '#1a1a1a'
721
721
  }
722
722
  };
723
- const CodebitThemeProvider = ({ children, storeThemeInLocalStorage = true, containerId = 'root', forcedTheme = null, colors = {}, ...props })=>{
723
+ const CodebitThemeProvider = ({ children, storeThemeInLocalStorage = true, containerId = 'root', forcedTheme = null, colors = {}, fontFamily, ...props })=>{
724
724
  const hasLoaded = (0, external_react_.useRef)(false);
725
725
  const [isDarkMode, setIsDarkMode] = (0, external_react_.useState)(()=>{
726
726
  if (forcedTheme) return 'dark' === forcedTheme;
@@ -808,7 +808,10 @@ var __webpack_exports__ = {};
808
808
  token: {
809
809
  colorPrimary: resolvedColors.primary[isDarkMode ? 'dark' : 'light'],
810
810
  colorInfo: resolvedColors.primary[isDarkMode ? 'dark' : 'light'],
811
- colorLink: resolvedColors.primary[isDarkMode ? 'dark' : 'light']
811
+ colorLink: resolvedColors.primary[isDarkMode ? 'dark' : 'light'],
812
+ ...fontFamily ? {
813
+ fontFamily
814
+ } : {}
812
815
  },
813
816
  components: {
814
817
  Menu: {
@@ -872,23 +875,28 @@ var __webpack_exports__ = {};
872
875
  light: external_prop_types_default().string,
873
876
  dark: external_prop_types_default().string
874
877
  })
875
- })
878
+ }),
879
+ fontFamily: external_prop_types_default().string
876
880
  };
877
- const ThemeToggle = ()=>{
878
- const config = (0, external_react_.useContext)(CodebitThemeContext);
879
- if (!config) throw new Error('ThemeToggle must be used within CodebitThemeContext');
880
- (0, external_react_.useEffect)(()=>{
881
- document.documentElement.style.colorScheme = config.isDarkMode ? 'dark' : 'light';
882
- }, [
883
- config.isDarkMode
884
- ]);
885
- return /*#__PURE__*/ (0, jsx_runtime.jsx)(external_antd_namespaceObject.Switch, {
886
- theme: config.isDarkMode ? 'dark' : 'light',
887
- checked: config.isDarkMode,
888
- onChange: (value)=>config.setIsDarkMode(value),
889
- checkedChildren: /*#__PURE__*/ (0, jsx_runtime.jsx)(icons_namespaceObject.MoonOutlined, {}),
890
- unCheckedChildren: /*#__PURE__*/ (0, jsx_runtime.jsx)(icons_namespaceObject.SunOutlined, {})
891
- });
881
+ const LoggedMainContainer_module = {
882
+ layout: "layout-mL5o6I",
883
+ drawer: "drawer-oj0mJX",
884
+ drawerBody: "drawerBody-YtAN37",
885
+ drawerFlex: "drawerFlex-AGTAax",
886
+ sider: "sider-BDy1Bs",
887
+ siderLayout: "siderLayout-C8H0uI",
888
+ secondarySidebar: "secondarySidebar-P6J_Xn",
889
+ menu: "menu-KMvPt7",
890
+ menuContainer: "menuContainer-ahnhBu",
891
+ menuLabel: "menuLabel-csBJTc",
892
+ menuDescription: "menuDescription-d6BFBO",
893
+ menuSpacer: "menuSpacer-RIB3II",
894
+ versionMenu: "versionMenu-NM4uyG",
895
+ bottomMenu: "bottomMenu-VtOktS",
896
+ header: "header-vgc67L",
897
+ mobile: "mobile-mKGxb5",
898
+ headerSpace: "headerSpace-Fd_iha",
899
+ content: "content-OZHp2h"
892
900
  };
893
901
  const external_react_i18next_namespaceObject = require("react-i18next");
894
902
  const external_i18next_namespaceObject = require("i18next");
@@ -912,157 +920,7 @@ var __webpack_exports__ = {};
912
920
  const useCodebitWebAntdTranslation = ()=>(0, external_react_i18next_namespaceObject.useTranslation)('codebitWebAntd', {
913
921
  i18n: i18n
914
922
  });
915
- const UserMenu_module = {
916
- trigger: "trigger-tlcps4",
917
- avatar: "avatar-Tmnqa_",
918
- caret: "caret-OWS8_0",
919
- panel: "panel-GCcfCo",
920
- userInfo: "userInfo-fDuDn1",
921
- userName: "userName-sIs1iq",
922
- userSubtitle: "userSubtitle-Fflhaw",
923
- divider: "divider-JJjJVy",
924
- menu: "menu-cuORr_"
925
- };
926
- const OPEN_KEYS = new Set([
927
- 'Enter',
928
- ' '
929
- ]);
930
- const { Text } = external_antd_namespaceObject.Typography;
931
- function getInitials(name) {
932
- const parts = name?.trim().split(/\s+/).filter(Boolean) ?? [];
933
- if (0 === parts.length) return '';
934
- const first = [
935
- ...parts[0]
936
- ];
937
- if (1 === parts.length) return first.slice(0, 2).join('').toUpperCase();
938
- const last = [
939
- ...parts.at(-1)
940
- ];
941
- return `${first[0]}${last[0]}`.toUpperCase();
942
- }
943
- function UserMenuPanel({ user, items, onItemClick }) {
944
- return /*#__PURE__*/ (0, jsx_runtime.jsxs)("div", {
945
- className: UserMenu_module.panel,
946
- children: [
947
- /*#__PURE__*/ (0, jsx_runtime.jsxs)("div", {
948
- className: UserMenu_module.userInfo,
949
- children: [
950
- /*#__PURE__*/ (0, jsx_runtime.jsx)(Text, {
951
- className: UserMenu_module.userName,
952
- strong: true,
953
- children: user?.name
954
- }),
955
- user?.subtitle && /*#__PURE__*/ (0, jsx_runtime.jsx)(Text, {
956
- className: UserMenu_module.userSubtitle,
957
- type: 'secondary',
958
- children: user.subtitle
959
- })
960
- ]
961
- }),
962
- /*#__PURE__*/ (0, jsx_runtime.jsx)(external_antd_namespaceObject.Divider, {
963
- className: UserMenu_module.divider
964
- }),
965
- /*#__PURE__*/ (0, jsx_runtime.jsx)(external_antd_namespaceObject.Menu, {
966
- className: UserMenu_module.menu,
967
- items: items,
968
- onClick: ({ key })=>onItemClick?.(key)
969
- })
970
- ]
971
- });
972
- }
973
- UserMenuPanel.propTypes = {
974
- user: external_prop_types_default().shape({
975
- name: external_prop_types_default().string,
976
- subtitle: external_prop_types_default().string
977
- }),
978
- items: external_prop_types_default().arrayOf(external_prop_types_default().object).isRequired,
979
- onItemClick: external_prop_types_default().func
980
- };
981
- function createPopupRender(user, items, onItemClick) {
982
- return ()=>/*#__PURE__*/ (0, jsx_runtime.jsx)(UserMenuPanel, {
983
- user: user,
984
- items: items,
985
- onItemClick: onItemClick
986
- });
987
- }
988
- function UserMenu({ user, items = [], onItemClick, caretIcon = /*#__PURE__*/ (0, jsx_runtime.jsx)(icons_namespaceObject.DownOutlined, {}) }) {
989
- const { t } = useCodebitWebAntdTranslation();
990
- const [open, setOpen] = (0, external_react_.useState)(false);
991
- const initials = getInitials(user?.name);
992
- const handleItemClick = (key)=>{
993
- setOpen(false);
994
- onItemClick?.(key);
995
- };
996
- const avatar = /*#__PURE__*/ (0, jsx_runtime.jsx)(external_antd_namespaceObject.Avatar, {
997
- className: UserMenu_module.avatar,
998
- children: initials || /*#__PURE__*/ (0, jsx_runtime.jsx)(icons_namespaceObject.UserOutlined, {})
999
- });
1000
- if (!items.length) return avatar;
1001
- return /*#__PURE__*/ (0, jsx_runtime.jsx)(external_antd_namespaceObject.Dropdown, {
1002
- trigger: [
1003
- 'click'
1004
- ],
1005
- open: open,
1006
- onOpenChange: setOpen,
1007
- placement: 'bottomRight',
1008
- popupRender: createPopupRender(user, items, handleItemClick),
1009
- children: /*#__PURE__*/ (0, jsx_runtime.jsxs)(external_antd_namespaceObject.Space, {
1010
- className: UserMenu_module.trigger,
1011
- role: 'button',
1012
- tabIndex: 0,
1013
- "aria-haspopup": 'menu',
1014
- "aria-expanded": open,
1015
- "aria-label": t('UserMenu.openMenu'),
1016
- onKeyDown: (event)=>{
1017
- if (!OPEN_KEYS.has(event.key)) return;
1018
- event.preventDefault();
1019
- setOpen((wasOpen)=>!wasOpen);
1020
- },
1021
- children: [
1022
- avatar,
1023
- /*#__PURE__*/ (0, jsx_runtime.jsx)("span", {
1024
- className: UserMenu_module.caret,
1025
- children: caretIcon
1026
- })
1027
- ]
1028
- })
1029
- });
1030
- }
1031
- UserMenu.propTypes = {
1032
- user: external_prop_types_default().shape({
1033
- name: external_prop_types_default().string,
1034
- email: external_prop_types_default().string,
1035
- id: external_prop_types_default().string,
1036
- roles: external_prop_types_default().arrayOf(external_prop_types_default().string),
1037
- subtitle: external_prop_types_default().string
1038
- }),
1039
- items: external_prop_types_default().arrayOf(external_prop_types_default().object),
1040
- onItemClick: external_prop_types_default().func,
1041
- caretIcon: external_prop_types_default().node
1042
- };
1043
- const LoggedMainContainer_module = {
1044
- layout: "layout-mL5o6I",
1045
- drawer: "drawer-oj0mJX",
1046
- drawerBody: "drawerBody-YtAN37",
1047
- drawerFlex: "drawerFlex-AGTAax",
1048
- sider: "sider-BDy1Bs",
1049
- siderLayout: "siderLayout-C8H0uI",
1050
- secondarySidebar: "secondarySidebar-P6J_Xn",
1051
- menu: "menu-KMvPt7",
1052
- menuContainer: "menuContainer-ahnhBu",
1053
- menuLabel: "menuLabel-csBJTc",
1054
- menuDescription: "menuDescription-d6BFBO",
1055
- menuSpacer: "menuSpacer-RIB3II",
1056
- versionMenu: "versionMenu-NM4uyG",
1057
- bottomMenu: "bottomMenu-VtOktS",
1058
- header: "header-vgc67L",
1059
- mobile: "mobile-mKGxb5",
1060
- headerSpace: "headerSpace-Fd_iha",
1061
- headerDivider: "headerDivider-yfEwNN",
1062
- content: "content-OZHp2h"
1063
- };
1064
923
  const { Header, Sider, Content } = external_antd_namespaceObject.Layout;
1065
- const { Text: LoggedMainContainer_Text } = external_antd_namespaceObject.Typography;
1066
924
  const MENU_KEY_APP_LOGOUT = 'app-logout';
1067
925
  function filterMenuItemsByRole(items, user) {
1068
926
  return items.filter((item)=>{
@@ -1082,7 +940,7 @@ var __webpack_exports__ = {};
1082
940
  const navigate = (0, external_react_router_namespaceObject.useNavigate)();
1083
941
  const location = (0, external_react_router_namespaceObject.useLocation)();
1084
942
  if (!configCodebit || !configTheme) throw new Error('LoggedContainer must be used within CodebitConfigProvider and CodebitThemeContext');
1085
- const { logout, user, menuItems, version, showVersion, secondarySidebar, secondarySidebarWidth = 280, bottomMenuItems, userMenuItems, onMenuClick } = configCodebit;
943
+ const { logout, user, menuItems, version, showVersion, secondarySidebar, secondarySidebarWidth = 280, bottomMenuItems, headerExtra, onMenuClick } = configCodebit;
1086
944
  const { isDarkMode } = configTheme;
1087
945
  const theme = isDarkMode ? 'dark' : 'light';
1088
946
  const allMenuItems = (0, external_react_.useMemo)(()=>[
@@ -1104,13 +962,6 @@ var __webpack_exports__ = {};
1104
962
  bottomMenuItems,
1105
963
  user
1106
964
  ]);
1107
- const filteredUserMenuItems = (0, external_react_.useMemo)(()=>{
1108
- if (!userMenuItems) return [];
1109
- return filterMenuItemsByRole(userMenuItems(user), user);
1110
- }, [
1111
- userMenuItems,
1112
- user
1113
- ]);
1114
965
  const memoizedBottomMenuItems = (0, external_react_.useMemo)(()=>[
1115
966
  ...filteredBottomMenuItems,
1116
967
  {
@@ -1162,11 +1013,6 @@ var __webpack_exports__ = {};
1162
1013
  isMobile,
1163
1014
  setDrawerVisible
1164
1015
  ]);
1165
- const handleUserMenuItemClick = (0, external_react_.useCallback)((key)=>{
1166
- onMenuClick?.(key);
1167
- }, [
1168
- onMenuClick
1169
- ]);
1170
1016
  const primaryMenu = (0, external_react_.useMemo)(()=>/*#__PURE__*/ (0, jsx_runtime.jsx)(external_antd_namespaceObject.Menu, {
1171
1017
  theme: theme,
1172
1018
  mode: 'inline',
@@ -1298,19 +1144,7 @@ var __webpack_exports__ = {};
1298
1144
  icon: /*#__PURE__*/ (0, jsx_runtime.jsx)(icons_namespaceObject.WechatOutlined, {}),
1299
1145
  onClick: ()=>setSecondarySidebarDrawerVisible(true)
1300
1146
  }),
1301
- !isMobile && /*#__PURE__*/ (0, jsx_runtime.jsx)(LoggedMainContainer_Text, {
1302
- children: t('LoggedMainContainer.theme')
1303
- }),
1304
- /*#__PURE__*/ (0, jsx_runtime.jsx)(ThemeToggle, {}),
1305
- /*#__PURE__*/ (0, jsx_runtime.jsx)(external_antd_namespaceObject.Divider, {
1306
- type: 'vertical',
1307
- className: LoggedMainContainer_module.headerDivider
1308
- }),
1309
- /*#__PURE__*/ (0, jsx_runtime.jsx)(UserMenu, {
1310
- user: user,
1311
- items: filteredUserMenuItems,
1312
- onItemClick: handleUserMenuItemClick
1313
- })
1147
+ headerExtra?.(user)
1314
1148
  ]
1315
1149
  })
1316
1150
  ]
@@ -1327,6 +1161,150 @@ var __webpack_exports__ = {};
1327
1161
  LoggedMainContainer.propTypes = {
1328
1162
  children: external_prop_types_default().node.isRequired
1329
1163
  };
1164
+ const ThemeToggle = ()=>{
1165
+ const config = (0, external_react_.useContext)(CodebitThemeContext);
1166
+ if (!config) throw new Error('ThemeToggle must be used within CodebitThemeContext');
1167
+ (0, external_react_.useEffect)(()=>{
1168
+ document.documentElement.style.colorScheme = config.isDarkMode ? 'dark' : 'light';
1169
+ }, [
1170
+ config.isDarkMode
1171
+ ]);
1172
+ return /*#__PURE__*/ (0, jsx_runtime.jsx)(external_antd_namespaceObject.Switch, {
1173
+ theme: config.isDarkMode ? 'dark' : 'light',
1174
+ checked: config.isDarkMode,
1175
+ onChange: (value)=>config.setIsDarkMode(value),
1176
+ checkedChildren: /*#__PURE__*/ (0, jsx_runtime.jsx)(icons_namespaceObject.MoonOutlined, {}),
1177
+ unCheckedChildren: /*#__PURE__*/ (0, jsx_runtime.jsx)(icons_namespaceObject.SunOutlined, {})
1178
+ });
1179
+ };
1180
+ const UserMenu_module = {
1181
+ trigger: "trigger-tlcps4",
1182
+ avatar: "avatar-Tmnqa_",
1183
+ caret: "caret-OWS8_0",
1184
+ panel: "panel-GCcfCo",
1185
+ userInfo: "userInfo-fDuDn1",
1186
+ userName: "userName-sIs1iq",
1187
+ userSubtitle: "userSubtitle-Fflhaw",
1188
+ divider: "divider-JJjJVy",
1189
+ menu: "menu-cuORr_"
1190
+ };
1191
+ const OPEN_KEYS = new Set([
1192
+ 'Enter',
1193
+ ' '
1194
+ ]);
1195
+ const { Text } = external_antd_namespaceObject.Typography;
1196
+ function getInitials(name) {
1197
+ const parts = name?.trim().split(/\s+/).filter(Boolean) ?? [];
1198
+ if (0 === parts.length) return '';
1199
+ const first = [
1200
+ ...parts[0]
1201
+ ];
1202
+ if (1 === parts.length) return first.slice(0, 2).join('').toUpperCase();
1203
+ const last = [
1204
+ ...parts.at(-1)
1205
+ ];
1206
+ return `${first[0]}${last[0]}`.toUpperCase();
1207
+ }
1208
+ function UserMenuPanel({ user, items, onItemClick }) {
1209
+ return /*#__PURE__*/ (0, jsx_runtime.jsxs)("div", {
1210
+ className: UserMenu_module.panel,
1211
+ children: [
1212
+ /*#__PURE__*/ (0, jsx_runtime.jsxs)("div", {
1213
+ className: UserMenu_module.userInfo,
1214
+ children: [
1215
+ /*#__PURE__*/ (0, jsx_runtime.jsx)(Text, {
1216
+ className: UserMenu_module.userName,
1217
+ strong: true,
1218
+ children: user?.name
1219
+ }),
1220
+ user?.subtitle && /*#__PURE__*/ (0, jsx_runtime.jsx)(Text, {
1221
+ className: UserMenu_module.userSubtitle,
1222
+ type: 'secondary',
1223
+ children: user.subtitle
1224
+ })
1225
+ ]
1226
+ }),
1227
+ /*#__PURE__*/ (0, jsx_runtime.jsx)(external_antd_namespaceObject.Divider, {
1228
+ className: UserMenu_module.divider
1229
+ }),
1230
+ /*#__PURE__*/ (0, jsx_runtime.jsx)(external_antd_namespaceObject.Menu, {
1231
+ className: UserMenu_module.menu,
1232
+ items: items,
1233
+ onClick: ({ key })=>onItemClick?.(key)
1234
+ })
1235
+ ]
1236
+ });
1237
+ }
1238
+ UserMenuPanel.propTypes = {
1239
+ user: external_prop_types_default().shape({
1240
+ name: external_prop_types_default().string,
1241
+ subtitle: external_prop_types_default().string
1242
+ }),
1243
+ items: external_prop_types_default().arrayOf(external_prop_types_default().object).isRequired,
1244
+ onItemClick: external_prop_types_default().func
1245
+ };
1246
+ function createPopupRender(user, items, onItemClick) {
1247
+ return ()=>/*#__PURE__*/ (0, jsx_runtime.jsx)(UserMenuPanel, {
1248
+ user: user,
1249
+ items: items,
1250
+ onItemClick: onItemClick
1251
+ });
1252
+ }
1253
+ function UserMenu({ user, items = [], onItemClick, caretIcon = /*#__PURE__*/ (0, jsx_runtime.jsx)(icons_namespaceObject.DownOutlined, {}) }) {
1254
+ const { t } = useCodebitWebAntdTranslation();
1255
+ const [open, setOpen] = (0, external_react_.useState)(false);
1256
+ const initials = getInitials(user?.name);
1257
+ const handleItemClick = (key)=>{
1258
+ setOpen(false);
1259
+ onItemClick?.(key);
1260
+ };
1261
+ const avatar = /*#__PURE__*/ (0, jsx_runtime.jsx)(external_antd_namespaceObject.Avatar, {
1262
+ className: UserMenu_module.avatar,
1263
+ children: initials || /*#__PURE__*/ (0, jsx_runtime.jsx)(icons_namespaceObject.UserOutlined, {})
1264
+ });
1265
+ if (!items.length) return avatar;
1266
+ return /*#__PURE__*/ (0, jsx_runtime.jsx)(external_antd_namespaceObject.Dropdown, {
1267
+ trigger: [
1268
+ 'click'
1269
+ ],
1270
+ open: open,
1271
+ onOpenChange: setOpen,
1272
+ placement: 'bottomRight',
1273
+ popupRender: createPopupRender(user, items, handleItemClick),
1274
+ children: /*#__PURE__*/ (0, jsx_runtime.jsxs)(external_antd_namespaceObject.Space, {
1275
+ className: UserMenu_module.trigger,
1276
+ role: 'button',
1277
+ tabIndex: 0,
1278
+ "aria-haspopup": 'menu',
1279
+ "aria-expanded": open,
1280
+ "aria-label": t('UserMenu.openMenu'),
1281
+ onKeyDown: (event)=>{
1282
+ if (!OPEN_KEYS.has(event.key)) return;
1283
+ event.preventDefault();
1284
+ setOpen((wasOpen)=>!wasOpen);
1285
+ },
1286
+ children: [
1287
+ avatar,
1288
+ /*#__PURE__*/ (0, jsx_runtime.jsx)("span", {
1289
+ className: UserMenu_module.caret,
1290
+ children: caretIcon
1291
+ })
1292
+ ]
1293
+ })
1294
+ });
1295
+ }
1296
+ UserMenu.propTypes = {
1297
+ user: external_prop_types_default().shape({
1298
+ name: external_prop_types_default().string,
1299
+ email: external_prop_types_default().string,
1300
+ id: external_prop_types_default().string,
1301
+ roles: external_prop_types_default().arrayOf(external_prop_types_default().string),
1302
+ subtitle: external_prop_types_default().string
1303
+ }),
1304
+ items: external_prop_types_default().arrayOf(external_prop_types_default().object),
1305
+ onItemClick: external_prop_types_default().func,
1306
+ caretIcon: external_prop_types_default().node
1307
+ };
1330
1308
  function useErrorMessage() {
1331
1309
  const { t } = useCodebitWebAntdTranslation();
1332
1310
  const getErrorMessage = (error)=>{
package/dist/index.css CHANGED
@@ -13,61 +13,6 @@ html.dark-theme {
13
13
  height: 100dvh !important;
14
14
  }
15
15
 
16
- .trigger-tlcps4 {
17
- cursor: pointer;
18
- }
19
-
20
- .avatar-Tmnqa_ {
21
- background: var(--antd-color-primary);
22
- flex-shrink: 0;
23
- }
24
-
25
- .caret-OWS8_0 {
26
- color: var(--antd-color-text-secondary);
27
- font-size: var(--antd-font-size-xs);
28
- }
29
-
30
- .panel-GCcfCo {
31
- background: var(--antd-color-bg-elevated);
32
- border: 1px solid var(--antd-color-border-secondary);
33
- border-radius: var(--antd-border-radius-lg);
34
- min-width: 200px;
35
- max-width: 280px;
36
- box-shadow: var(--antd-shadow-lg);
37
- flex-direction: column;
38
- display: flex;
39
- overflow: hidden;
40
- }
41
-
42
- .userInfo-fDuDn1 {
43
- padding: var(--antd-padding-xs) var(--antd-padding-sm);
44
- gap: var(--antd-margin-xxs);
45
- flex-direction: column;
46
- display: flex;
47
- }
48
-
49
- .userName-sIs1iq {
50
- text-overflow: ellipsis;
51
- white-space: nowrap;
52
- overflow: hidden;
53
- }
54
-
55
- .userSubtitle-Fflhaw {
56
- font-size: var(--antd-font-size-sm);
57
- text-overflow: ellipsis;
58
- white-space: nowrap;
59
- overflow: hidden;
60
- }
61
-
62
- .divider-JJjJVy {
63
- margin: 0;
64
- }
65
-
66
- .menu-cuORr_ {
67
- background: none;
68
- border-inline-end: none;
69
- }
70
-
71
16
  .layout-mL5o6I {
72
17
  height: 100vh;
73
18
  position: fixed;
@@ -174,17 +119,66 @@ html.dark-theme {
174
119
  gap: var(--antd-margin-xs);
175
120
  }
176
121
 
177
- .headerDivider-yfEwNN {
178
- height: var(--antd-control-height-sm);
179
- border-color: var(--antd-color-split);
180
- margin: 0;
181
- }
182
-
183
122
  .content-OZHp2h {
184
123
  padding: var(--antd-padding-xxs) var(--antd-padding) var(--antd-padding) var(--antd-padding);
185
124
  position: relative;
186
125
  }
187
126
 
127
+ .trigger-tlcps4 {
128
+ cursor: pointer;
129
+ }
130
+
131
+ .avatar-Tmnqa_ {
132
+ background: var(--antd-color-primary);
133
+ flex-shrink: 0;
134
+ }
135
+
136
+ .caret-OWS8_0 {
137
+ color: var(--antd-color-text-secondary);
138
+ font-size: var(--antd-font-size-xs);
139
+ }
140
+
141
+ .panel-GCcfCo {
142
+ background: var(--antd-color-bg-elevated);
143
+ border: 1px solid var(--antd-color-border-secondary);
144
+ border-radius: var(--antd-border-radius-lg);
145
+ min-width: 200px;
146
+ max-width: 280px;
147
+ box-shadow: var(--antd-shadow-lg);
148
+ flex-direction: column;
149
+ display: flex;
150
+ overflow: hidden;
151
+ }
152
+
153
+ .userInfo-fDuDn1 {
154
+ padding: var(--antd-padding-xs) var(--antd-padding-sm);
155
+ gap: var(--antd-margin-xxs);
156
+ flex-direction: column;
157
+ display: flex;
158
+ }
159
+
160
+ .userName-sIs1iq {
161
+ text-overflow: ellipsis;
162
+ white-space: nowrap;
163
+ overflow: hidden;
164
+ }
165
+
166
+ .userSubtitle-Fflhaw {
167
+ font-size: var(--antd-font-size-sm);
168
+ text-overflow: ellipsis;
169
+ white-space: nowrap;
170
+ overflow: hidden;
171
+ }
172
+
173
+ .divider-JJjJVy {
174
+ margin: 0;
175
+ }
176
+
177
+ .menu-cuORr_ {
178
+ background: none;
179
+ border-inline-end: none;
180
+ }
181
+
188
182
  .listCard-ISftFd {
189
183
  width: 100%;
190
184
  height: 100%;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codebit-programando-solucoes/codebit-web-antd",
3
- "version": "1.1.44",
3
+ "version": "1.1.46",
4
4
  "main": "./dist/index.cjs",
5
5
  "type": "module",
6
6
  "types": "./src/index.d.ts",