@codebit-programando-solucoes/codebit-web-antd 1.1.49 → 1.1.51
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/dist/components/UserMenu.d.ts +9 -0
- package/dist/index.cjs +78 -11
- package/dist/index.css +51 -5
- package/package.json +1 -1
|
@@ -11,12 +11,21 @@ export interface UserMenuProps {
|
|
|
11
11
|
onItemClick?: (key: string) => void;
|
|
12
12
|
/** Icon shown next to the avatar to indicate the dropdown affordance. Defaults to `<DownOutlined />`. */
|
|
13
13
|
caretIcon?: ReactNode;
|
|
14
|
+
/**
|
|
15
|
+
* How items carrying `children` are rendered. `'submenu'` keeps Ant Design's sideways flyout; `'group'` renders them inline, inside the panel's own scroll container; `'auto'`
|
|
16
|
+
* (the default) picks `'group'` on touch devices, where a flyout has neither the horizontal room nor a reliable hover to open on. A `disabled` parent always stays a submenu,
|
|
17
|
+
* since that is what keeps its children unreachable.
|
|
18
|
+
*/
|
|
19
|
+
nestedItemsMode?: 'auto' | 'group' | 'submenu';
|
|
14
20
|
}
|
|
15
21
|
|
|
16
22
|
/**
|
|
17
23
|
* Header user-profile control. Renders the current user's avatar and, when `items` is non-empty, a dropdown showing the user's name/subtitle followed by the given menu items (e.g.
|
|
18
24
|
* a "Minhas preferências" entry supplied by the host application).
|
|
19
25
|
*
|
|
26
|
+
* The dropdown is given a real height budget: the popup is measured against the room left under the trigger when it opens, and the item list becomes the one scrolling region
|
|
27
|
+
* inside it, so a long menu stays fully reachable on a phone instead of running off the bottom of the screen.
|
|
28
|
+
*
|
|
20
29
|
* @param props - Component props
|
|
21
30
|
* @returns React.JSX.Element - Avatar, optionally wrapped in a Dropdown
|
|
22
31
|
* @component
|
package/dist/index.cjs
CHANGED
|
@@ -779,6 +779,7 @@ var __webpack_exports__ = {};
|
|
|
779
779
|
document.documentElement.classList.remove('dark-theme');
|
|
780
780
|
target.classList.remove('dark-theme');
|
|
781
781
|
}
|
|
782
|
+
document.documentElement.style.colorScheme = isDarkMode ? 'dark' : 'light';
|
|
782
783
|
document.documentElement.style.setProperty('--color-primary', resolvedColors.primary[isDarkMode ? 'dark' : 'light']);
|
|
783
784
|
}, [
|
|
784
785
|
isDarkMode,
|
|
@@ -1169,11 +1170,6 @@ var __webpack_exports__ = {};
|
|
|
1169
1170
|
const ThemeToggle = ()=>{
|
|
1170
1171
|
const config = (0, external_react_.useContext)(CodebitThemeContext);
|
|
1171
1172
|
if (!config) throw new Error('ThemeToggle must be used within CodebitThemeContext');
|
|
1172
|
-
(0, external_react_.useEffect)(()=>{
|
|
1173
|
-
document.documentElement.style.colorScheme = config.isDarkMode ? 'dark' : 'light';
|
|
1174
|
-
}, [
|
|
1175
|
-
config.isDarkMode
|
|
1176
|
-
]);
|
|
1177
1173
|
return /*#__PURE__*/ (0, jsx_runtime.jsx)(external_antd_namespaceObject.Switch, {
|
|
1178
1174
|
theme: config.isDarkMode ? 'dark' : 'light',
|
|
1179
1175
|
checked: config.isDarkMode,
|
|
@@ -1186,17 +1182,23 @@ var __webpack_exports__ = {};
|
|
|
1186
1182
|
trigger: "trigger-tlcps4",
|
|
1187
1183
|
avatar: "avatar-Tmnqa_",
|
|
1188
1184
|
caret: "caret-OWS8_0",
|
|
1185
|
+
popupRoot: "popupRoot-MxWPmX",
|
|
1189
1186
|
panel: "panel-GCcfCo",
|
|
1187
|
+
divider: "divider-JJjJVy",
|
|
1190
1188
|
userInfo: "userInfo-fDuDn1",
|
|
1191
1189
|
userName: "userName-sIs1iq",
|
|
1192
1190
|
userSubtitle: "userSubtitle-Fflhaw",
|
|
1193
|
-
divider: "divider-JJjJVy",
|
|
1194
1191
|
menu: "menu-cuORr_"
|
|
1195
1192
|
};
|
|
1196
1193
|
const OPEN_KEYS = new Set([
|
|
1197
1194
|
'Enter',
|
|
1198
1195
|
' '
|
|
1199
1196
|
]);
|
|
1197
|
+
const COARSE_POINTER_QUERY = '(pointer: coarse)';
|
|
1198
|
+
const TRIGGER_TO_POPUP_OFFSET = 4;
|
|
1199
|
+
const VIEWPORT_GUTTER = 8;
|
|
1200
|
+
const MIN_POPUP_HEIGHT = 160;
|
|
1201
|
+
const MAX_HEIGHT_VAR = '--codebit-user-menu-max-height';
|
|
1200
1202
|
const { Text } = external_antd_namespaceObject.Typography;
|
|
1201
1203
|
function getInitials(name) {
|
|
1202
1204
|
const parts = name?.trim().split(/\s+/).filter(Boolean) ?? [];
|
|
@@ -1210,6 +1212,23 @@ var __webpack_exports__ = {};
|
|
|
1210
1212
|
];
|
|
1211
1213
|
return `${first[0]}${last[0]}`.toUpperCase();
|
|
1212
1214
|
}
|
|
1215
|
+
function computeMaxHeight(trigger) {
|
|
1216
|
+
if (!trigger) return null;
|
|
1217
|
+
const viewportHeight = Math.min(document.documentElement.clientHeight, globalThis.visualViewport?.height ?? 1 / 0);
|
|
1218
|
+
return Math.max(MIN_POPUP_HEIGHT, viewportHeight - trigger.getBoundingClientRect().bottom - TRIGGER_TO_POPUP_OFFSET - VIEWPORT_GUTTER);
|
|
1219
|
+
}
|
|
1220
|
+
function toGroupItems(items) {
|
|
1221
|
+
return items.map((item)=>{
|
|
1222
|
+
if (!item || 'object' != typeof item) return item;
|
|
1223
|
+
if (!item.children || item.disabled) return item;
|
|
1224
|
+
return {
|
|
1225
|
+
key: item.key,
|
|
1226
|
+
label: item.label,
|
|
1227
|
+
type: 'group',
|
|
1228
|
+
children: toGroupItems(item.children)
|
|
1229
|
+
};
|
|
1230
|
+
});
|
|
1231
|
+
}
|
|
1213
1232
|
function UserMenuPanel({ user, items, onItemClick }) {
|
|
1214
1233
|
return /*#__PURE__*/ (0, jsx_runtime.jsxs)("div", {
|
|
1215
1234
|
className: UserMenu_module.panel,
|
|
@@ -1255,10 +1274,48 @@ var __webpack_exports__ = {};
|
|
|
1255
1274
|
onItemClick: onItemClick
|
|
1256
1275
|
});
|
|
1257
1276
|
}
|
|
1258
|
-
function UserMenu({ user, items = [], onItemClick, caretIcon = /*#__PURE__*/ (0, jsx_runtime.jsx)(icons_namespaceObject.DownOutlined, {}) }) {
|
|
1277
|
+
function UserMenu({ user, items = [], onItemClick, caretIcon = /*#__PURE__*/ (0, jsx_runtime.jsx)(icons_namespaceObject.DownOutlined, {}), nestedItemsMode = 'auto' }) {
|
|
1259
1278
|
const { t } = useCodebitWebAntdTranslation();
|
|
1260
1279
|
const [open, setOpen] = (0, external_react_.useState)(false);
|
|
1280
|
+
const [maxHeight, setMaxHeight] = (0, external_react_.useState)(null);
|
|
1281
|
+
const [coarsePointer, setCoarsePointer] = (0, external_react_.useState)(false);
|
|
1282
|
+
const triggerRef = (0, external_react_.useRef)(null);
|
|
1261
1283
|
const initials = getInitials(user?.name);
|
|
1284
|
+
(0, external_react_.useEffect)(()=>{
|
|
1285
|
+
const pointerQuery = globalThis.matchMedia?.(COARSE_POINTER_QUERY);
|
|
1286
|
+
if (!pointerQuery) return;
|
|
1287
|
+
const syncPointer = (event)=>setCoarsePointer(event.matches);
|
|
1288
|
+
setCoarsePointer(pointerQuery.matches);
|
|
1289
|
+
pointerQuery.addEventListener('change', syncPointer);
|
|
1290
|
+
return ()=>pointerQuery.removeEventListener('change', syncPointer);
|
|
1291
|
+
}, []);
|
|
1292
|
+
(0, external_react_.useEffect)(()=>{
|
|
1293
|
+
if (!open) return;
|
|
1294
|
+
const remeasure = ()=>setMaxHeight(computeMaxHeight(triggerRef.current));
|
|
1295
|
+
const visualViewport = globalThis.visualViewport;
|
|
1296
|
+
globalThis.addEventListener('resize', remeasure);
|
|
1297
|
+
globalThis.addEventListener('orientationchange', remeasure);
|
|
1298
|
+
visualViewport?.addEventListener('resize', remeasure);
|
|
1299
|
+
return ()=>{
|
|
1300
|
+
globalThis.removeEventListener('resize', remeasure);
|
|
1301
|
+
globalThis.removeEventListener('orientationchange', remeasure);
|
|
1302
|
+
visualViewport?.removeEventListener('resize', remeasure);
|
|
1303
|
+
};
|
|
1304
|
+
}, [
|
|
1305
|
+
open
|
|
1306
|
+
]);
|
|
1307
|
+
const resolvedItems = (0, external_react_.useMemo)(()=>{
|
|
1308
|
+
const asGroups = 'group' === nestedItemsMode || 'auto' === nestedItemsMode && coarsePointer;
|
|
1309
|
+
return asGroups ? toGroupItems(items) : items;
|
|
1310
|
+
}, [
|
|
1311
|
+
items,
|
|
1312
|
+
nestedItemsMode,
|
|
1313
|
+
coarsePointer
|
|
1314
|
+
]);
|
|
1315
|
+
const handleOpenChange = (nextOpen)=>{
|
|
1316
|
+
if (nextOpen) setMaxHeight(computeMaxHeight(triggerRef.current));
|
|
1317
|
+
setOpen(nextOpen);
|
|
1318
|
+
};
|
|
1262
1319
|
const handleItemClick = (key)=>{
|
|
1263
1320
|
setOpen(false);
|
|
1264
1321
|
onItemClick?.(key);
|
|
@@ -1273,10 +1330,15 @@ var __webpack_exports__ = {};
|
|
|
1273
1330
|
'click'
|
|
1274
1331
|
],
|
|
1275
1332
|
open: open,
|
|
1276
|
-
onOpenChange:
|
|
1333
|
+
onOpenChange: handleOpenChange,
|
|
1277
1334
|
placement: 'bottomRight',
|
|
1278
|
-
|
|
1335
|
+
rootClassName: UserMenu_module.popupRoot,
|
|
1336
|
+
overlayStyle: null === maxHeight ? void 0 : {
|
|
1337
|
+
[MAX_HEIGHT_VAR]: `${maxHeight}px`
|
|
1338
|
+
},
|
|
1339
|
+
popupRender: createPopupRender(user, resolvedItems, handleItemClick),
|
|
1279
1340
|
children: /*#__PURE__*/ (0, jsx_runtime.jsxs)(external_antd_namespaceObject.Space, {
|
|
1341
|
+
ref: triggerRef,
|
|
1280
1342
|
className: UserMenu_module.trigger,
|
|
1281
1343
|
role: 'button',
|
|
1282
1344
|
tabIndex: 0,
|
|
@@ -1286,7 +1348,7 @@ var __webpack_exports__ = {};
|
|
|
1286
1348
|
onKeyDown: (event)=>{
|
|
1287
1349
|
if (!OPEN_KEYS.has(event.key)) return;
|
|
1288
1350
|
event.preventDefault();
|
|
1289
|
-
|
|
1351
|
+
handleOpenChange(!open);
|
|
1290
1352
|
},
|
|
1291
1353
|
children: [
|
|
1292
1354
|
avatar,
|
|
@@ -1308,7 +1370,12 @@ var __webpack_exports__ = {};
|
|
|
1308
1370
|
}),
|
|
1309
1371
|
items: external_prop_types_default().arrayOf(external_prop_types_default().object),
|
|
1310
1372
|
onItemClick: external_prop_types_default().func,
|
|
1311
|
-
caretIcon: external_prop_types_default().node
|
|
1373
|
+
caretIcon: external_prop_types_default().node,
|
|
1374
|
+
nestedItemsMode: external_prop_types_default().oneOf([
|
|
1375
|
+
'auto',
|
|
1376
|
+
'group',
|
|
1377
|
+
'submenu'
|
|
1378
|
+
])
|
|
1312
1379
|
};
|
|
1313
1380
|
function useErrorMessage() {
|
|
1314
1381
|
const { t } = useCodebitWebAntdTranslation();
|
package/dist/index.css
CHANGED
|
@@ -112,6 +112,16 @@ html.dark-theme {
|
|
|
112
112
|
height: var(--antd-control-height-lg);
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
.header-vgc67L .ant-space {
|
|
116
|
+
height: 100%;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.header-vgc67L .ant-space .ant-space-item {
|
|
120
|
+
vertical-align: middle;
|
|
121
|
+
height: 100%;
|
|
122
|
+
display: inline-flex;
|
|
123
|
+
}
|
|
124
|
+
|
|
115
125
|
.secondarySidebarTrigger-dD6WGB {
|
|
116
126
|
margin-right: var(--antd-padding-xs);
|
|
117
127
|
}
|
|
@@ -130,7 +140,7 @@ html.dark-theme {
|
|
|
130
140
|
}
|
|
131
141
|
|
|
132
142
|
.content-OZHp2h {
|
|
133
|
-
padding: var(--antd-padding-
|
|
143
|
+
padding: 0 var(--antd-padding-xs) var(--antd-padding-xs) var(--antd-padding-xs);
|
|
134
144
|
position: relative;
|
|
135
145
|
}
|
|
136
146
|
|
|
@@ -148,6 +158,10 @@ html.dark-theme {
|
|
|
148
158
|
font-size: var(--antd-font-size-xs);
|
|
149
159
|
}
|
|
150
160
|
|
|
161
|
+
.popupRoot-MxWPmX.ant-dropdown {
|
|
162
|
+
max-height: calc(var(--codebit-user-menu-max-height, calc(100vh - var(--antd-control-height-lg, 40px) - var(--antd-margin-xxs, 4px) - var(--antd-margin-xs, 8px))) - env(safe-area-inset-bottom, 0px));
|
|
163
|
+
}
|
|
164
|
+
|
|
151
165
|
.panel-GCcfCo {
|
|
152
166
|
background: var(--antd-color-bg-elevated);
|
|
153
167
|
border: 1px solid var(--antd-color-border-secondary);
|
|
@@ -155,15 +169,22 @@ html.dark-theme {
|
|
|
155
169
|
min-width: 200px;
|
|
156
170
|
max-width: 280px;
|
|
157
171
|
box-shadow: var(--antd-shadow-lg);
|
|
172
|
+
max-height: calc(var(--codebit-user-menu-max-height, calc(100vh - var(--antd-control-height-lg, 40px) - var(--antd-margin-xxs, 4px) - var(--antd-margin-xs, 8px))) - env(safe-area-inset-bottom, 0px));
|
|
158
173
|
flex-direction: column;
|
|
159
174
|
display: flex;
|
|
160
175
|
overflow: hidden;
|
|
161
176
|
}
|
|
162
177
|
|
|
178
|
+
.panel-GCcfCo > .divider-JJjJVy {
|
|
179
|
+
flex-shrink: 0;
|
|
180
|
+
margin: 0;
|
|
181
|
+
}
|
|
182
|
+
|
|
163
183
|
.userInfo-fDuDn1 {
|
|
164
184
|
padding: var(--antd-padding-xs) var(--antd-padding-sm);
|
|
165
185
|
gap: var(--antd-margin-xxs);
|
|
166
186
|
flex-direction: column;
|
|
187
|
+
flex-shrink: 0;
|
|
167
188
|
display: flex;
|
|
168
189
|
}
|
|
169
190
|
|
|
@@ -180,13 +201,13 @@ html.dark-theme {
|
|
|
180
201
|
overflow: hidden;
|
|
181
202
|
}
|
|
182
203
|
|
|
183
|
-
.divider-JJjJVy {
|
|
184
|
-
margin: 0;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
204
|
.menu-cuORr_ {
|
|
205
|
+
overscroll-behavior: contain;
|
|
188
206
|
background: none;
|
|
189
207
|
border-inline-end: none;
|
|
208
|
+
flex: 0 auto;
|
|
209
|
+
min-height: 0;
|
|
210
|
+
overflow-y: auto;
|
|
190
211
|
}
|
|
191
212
|
|
|
192
213
|
.menu-cuORr_ .ant-dropdown-menu-title-content {
|
|
@@ -196,6 +217,31 @@ html.dark-theme {
|
|
|
196
217
|
overflow: hidden;
|
|
197
218
|
}
|
|
198
219
|
|
|
220
|
+
.menu-cuORr_ .ant-dropdown-menu-item-group-title {
|
|
221
|
+
text-overflow: ellipsis;
|
|
222
|
+
white-space: nowrap;
|
|
223
|
+
overflow: hidden;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
@media (width <= 480px) {
|
|
227
|
+
.panel-GCcfCo {
|
|
228
|
+
max-width: min(360px, 100vw - var(--antd-margin-xs, 8px) - var(--antd-margin, 16px));
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
@media (pointer: coarse) {
|
|
233
|
+
.menu-cuORr_ .ant-dropdown-menu-item, .menu-cuORr_ .ant-dropdown-menu-submenu-title {
|
|
234
|
+
min-height: 44px;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.trigger-tlcps4 {
|
|
238
|
+
min-height: var(--antd-control-height-lg, 40px);
|
|
239
|
+
padding-inline: var(--antd-padding-xxs, 4px);
|
|
240
|
+
margin-inline: calc(var(--antd-padding-xxs, 4px) * -1);
|
|
241
|
+
align-items: center;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
199
245
|
.listCard-ISftFd {
|
|
200
246
|
width: 100%;
|
|
201
247
|
height: 100%;
|