@xsolla/xui-b2b-sidebar 0.147.1

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/web/index.js ADDED
@@ -0,0 +1,1820 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.tsx
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ Sidebar: () => Sidebar,
34
+ SidebarChatButton: () => SidebarChatButton,
35
+ SidebarCollapsed: () => SidebarCollapsed,
36
+ SidebarContent: () => SidebarContent,
37
+ SidebarFooter: () => SidebarFooter,
38
+ SidebarGroup: () => SidebarGroup,
39
+ SidebarMenu: () => SidebarMenu,
40
+ SidebarMenuCollapsible: () => SidebarMenuCollapsible,
41
+ SidebarMenuItem: () => SidebarMenuItem,
42
+ SidebarMenuSub: () => SidebarMenuSub,
43
+ SidebarProvider: () => SidebarProvider,
44
+ SidebarTrigger: () => SidebarTrigger,
45
+ useSidebar: () => useSidebar
46
+ });
47
+ module.exports = __toCommonJS(index_exports);
48
+
49
+ // src/Sidebar.tsx
50
+ var import_styled_components2 = __toESM(require("styled-components"));
51
+ var import_xui_core2 = require("@xsolla/xui-core");
52
+
53
+ // src/SidebarContext.tsx
54
+ var import_react = require("react");
55
+ var import_jsx_runtime = require("react/jsx-runtime");
56
+ var DefaultLink = ({
57
+ to,
58
+ external,
59
+ target,
60
+ className,
61
+ children,
62
+ dataId,
63
+ onClick
64
+ }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
65
+ "a",
66
+ {
67
+ href: to,
68
+ className,
69
+ target: external ? target ?? "_blank" : target ?? void 0,
70
+ rel: external ? "noopener noreferrer" : void 0,
71
+ "data-id": dataId,
72
+ onClick,
73
+ children
74
+ }
75
+ );
76
+ var SidebarContext = (0, import_react.createContext)({
77
+ collapsed: false,
78
+ onCollapsedChange: () => {
79
+ },
80
+ pathname: "",
81
+ LinkComponent: DefaultLink,
82
+ expandedId: null,
83
+ onExpandedIdChange: () => {
84
+ }
85
+ });
86
+ var SidebarProvider = ({
87
+ collapsed: collapsedProp,
88
+ onCollapsedChange,
89
+ pathname = "",
90
+ linkComponent,
91
+ children
92
+ }) => {
93
+ const [internalCollapsed, setInternalCollapsed] = (0, import_react.useState)(false);
94
+ const [expandedId, setExpandedId] = (0, import_react.useState)(null);
95
+ const collapsed = collapsedProp ?? internalCollapsed;
96
+ const handleCollapsedChange = (0, import_react.useCallback)(
97
+ (next) => {
98
+ if (collapsedProp === void 0) setInternalCollapsed(next);
99
+ onCollapsedChange?.(next);
100
+ },
101
+ [collapsedProp, onCollapsedChange]
102
+ );
103
+ const onExpandedIdChange = (0, import_react.useCallback)((id) => {
104
+ setExpandedId(id);
105
+ }, []);
106
+ const value = (0, import_react.useMemo)(
107
+ () => ({
108
+ collapsed,
109
+ onCollapsedChange: handleCollapsedChange,
110
+ pathname,
111
+ LinkComponent: linkComponent || DefaultLink,
112
+ expandedId,
113
+ onExpandedIdChange
114
+ }),
115
+ [
116
+ collapsed,
117
+ handleCollapsedChange,
118
+ pathname,
119
+ linkComponent,
120
+ expandedId,
121
+ onExpandedIdChange
122
+ ]
123
+ );
124
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarContext.Provider, { value, children });
125
+ };
126
+ var useSidebar = () => (0, import_react.useContext)(SidebarContext);
127
+
128
+ // src/SidebarCollapsed.tsx
129
+ var import_react2 = require("react");
130
+ var import_react_dom = require("react-dom");
131
+ var import_styled_components = __toESM(require("styled-components"));
132
+ var import_xui_core = require("@xsolla/xui-core");
133
+ var import_xui_typography = require("@xsolla/xui-typography");
134
+ var import_xui_icons_base = require("@xsolla/xui-icons-base");
135
+
136
+ // src/HideSidebarIcon.tsx
137
+ var import_jsx_runtime2 = require("react/jsx-runtime");
138
+ var HideSidebarIcon = ({
139
+ flipped
140
+ }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
141
+ "svg",
142
+ {
143
+ width: "18",
144
+ height: "18",
145
+ viewBox: "0 0 18 18",
146
+ fill: "none",
147
+ xmlns: "http://www.w3.org/2000/svg",
148
+ "aria-hidden": "true",
149
+ focusable: "false",
150
+ style: flipped ? { transform: "rotate(180deg)" } : void 0,
151
+ children: [
152
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
153
+ "path",
154
+ {
155
+ d: "M10.1519 3.75L10.9674 4.60262L7.33825 8.39704H15.75V9.60296H7.33825L10.9674 13.3974L10.1519 14.25L5.33446 9.21318C5.22185 9.09544 5.22185 8.90456 5.33446 8.78682L10.1519 3.75Z",
156
+ fill: "currentColor"
157
+ }
158
+ ),
159
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M2.25 3.75H3.75V15H2.25V3.75Z", fill: "currentColor" })
160
+ ]
161
+ }
162
+ );
163
+
164
+ // src/SidebarCollapsed.tsx
165
+ var import_jsx_runtime3 = require("react/jsx-runtime");
166
+ var POPOVER_GAP_PX = 12;
167
+ var POPOVER_VIEWPORT_PADDING_PX = 8;
168
+ var POPOVER_CLOSE_DELAY_MS = 150;
169
+ var POPOVER_ITEM_BASE_CLASS = "xui-sb-popover-item";
170
+ var POPOVER_ITEM_ACTIVE_CLASS = "xui-sb-popover-item--active";
171
+ var Outer = import_styled_components.default.div`
172
+ display: flex;
173
+ width: ${(p) => p.$width}px;
174
+ height: 100%;
175
+ max-height: 100%;
176
+ box-sizing: border-box;
177
+ flex-direction: column;
178
+ flex-shrink: 0;
179
+ overflow: hidden;
180
+ background: ${(p) => p.$bg};
181
+ border-radius: ${(p) => p.$radius}px;
182
+
183
+ a {
184
+ text-decoration: none;
185
+ }
186
+ `;
187
+ var MainScroll = import_styled_components.default.div`
188
+ display: flex;
189
+ flex: 1;
190
+ flex-direction: column;
191
+ align-items: center;
192
+ padding: ${(p) => p.$padding}px 0;
193
+ min-height: 0;
194
+ overflow-y: auto;
195
+
196
+ &::-webkit-scrollbar {
197
+ width: 0;
198
+ }
199
+ `;
200
+ var IconBtn = import_styled_components.default.button`
201
+ display: flex;
202
+ width: ${(p) => p.$size}px;
203
+ height: ${(p) => p.$size}px;
204
+ align-items: center;
205
+ justify-content: center;
206
+ border: 0;
207
+ border-radius: ${(p) => p.$radius}px;
208
+ background: ${(p) => p.$active ? p.$hoverBg : "transparent"};
209
+ color: ${(p) => p.$active ? p.$hoverColor : p.$color};
210
+ cursor: pointer;
211
+ padding: 0;
212
+ font: inherit;
213
+ transition:
214
+ background-color 0.15s ease-in-out,
215
+ color 0.15s ease-in-out;
216
+
217
+ ${(p) => p.$active && `
218
+ background-color: ${p.$activeBg};
219
+ outline: 1px solid ${p.$activeOutline};
220
+ outline-offset: -1px;
221
+ `}
222
+
223
+ &:hover {
224
+ background-color: ${(p) => p.$hoverBg};
225
+ color: ${(p) => p.$hoverColor};
226
+ }
227
+
228
+ &:focus-visible {
229
+ outline: ${(p) => p.$focusOutlineWidth}px solid ${(p) => p.$focusOutline};
230
+ outline-offset: -${(p) => p.$focusOutlineWidth}px;
231
+ }
232
+
233
+ & > span {
234
+ display: flex;
235
+ width: ${(p) => p.$iconSize}px;
236
+ height: ${(p) => p.$iconSize}px;
237
+ align-items: center;
238
+ justify-content: center;
239
+
240
+ svg {
241
+ width: ${(p) => p.$iconSize}px;
242
+ height: ${(p) => p.$iconSize}px;
243
+ }
244
+ }
245
+ `;
246
+ var Spacer = import_styled_components.default.div`
247
+ height: 16px;
248
+ flex-shrink: 0;
249
+ `;
250
+ var FixedBottom = import_styled_components.default.div`
251
+ display: flex;
252
+ flex-direction: column;
253
+ align-items: center;
254
+ padding: ${(p) => p.$padding}px 0;
255
+ flex-shrink: 0;
256
+ `;
257
+ var Footer = import_styled_components.default.div`
258
+ display: flex;
259
+ flex-direction: column;
260
+ align-items: center;
261
+ gap: 4px;
262
+ padding: ${(p) => p.$padding}px 0;
263
+ border-top: 1px solid ${(p) => p.$borderColor};
264
+ flex-shrink: 0;
265
+ `;
266
+ var CollapsedChat = import_styled_components.default.button`
267
+ display: flex;
268
+ width: ${(p) => p.$size}px;
269
+ height: ${(p) => p.$size}px;
270
+ align-items: center;
271
+ justify-content: center;
272
+ border: 1px solid ${(p) => p.$border};
273
+ border-radius: ${(p) => p.$radius}px;
274
+ background: ${(p) => p.$bg};
275
+ color: ${(p) => p.$color};
276
+ cursor: pointer;
277
+ position: relative;
278
+ padding: 0;
279
+ font: inherit;
280
+
281
+ &:hover {
282
+ opacity: 0.9;
283
+ }
284
+
285
+ &:focus-visible {
286
+ outline: ${(p) => p.$focusOutlineWidth}px solid ${(p) => p.$focusOutline};
287
+ outline-offset: 2px;
288
+ }
289
+
290
+ svg {
291
+ width: 16px;
292
+ height: 16px;
293
+ }
294
+ `;
295
+ var CollapsedToggle = import_styled_components.default.button`
296
+ display: flex;
297
+ width: ${(p) => p.$size}px;
298
+ height: ${(p) => p.$size}px;
299
+ align-items: center;
300
+ justify-content: center;
301
+ border: 1px solid ${(p) => p.$borderColor};
302
+ border-radius: ${(p) => p.$radius}px;
303
+ background: transparent;
304
+ cursor: pointer;
305
+ color: ${(p) => p.$color};
306
+ padding: 0;
307
+ font: inherit;
308
+
309
+ &:hover {
310
+ background: ${(p) => p.$hoverBg};
311
+ }
312
+
313
+ &:focus-visible {
314
+ outline: ${(p) => p.$focusOutlineWidth}px solid ${(p) => p.$focusOutline};
315
+ outline-offset: 2px;
316
+ }
317
+
318
+ svg {
319
+ width: ${(p) => p.$iconSize}px;
320
+ height: ${(p) => p.$iconSize}px;
321
+ }
322
+ `;
323
+ var ChatBadge = import_styled_components.default.span`
324
+ position: absolute;
325
+ top: -2px;
326
+ right: -2px;
327
+ width: ${(p) => p.$size}px;
328
+ height: ${(p) => p.$size}px;
329
+ background: ${(p) => p.$color};
330
+ border-radius: 999px;
331
+ `;
332
+ var PopoverContainer = import_styled_components.default.div`
333
+ position: fixed;
334
+ z-index: ${(p) => p.$zIndex};
335
+ min-width: ${(p) => p.$minWidth}px;
336
+ max-width: ${(p) => p.$maxWidth}px;
337
+ `;
338
+ var PopoverInner = import_styled_components.default.div`
339
+ min-height: ${(p) => p.$itemHeight}px;
340
+ padding: ${(p) => p.$padding}px;
341
+ background: ${(p) => p.$bg};
342
+ border-radius: ${(p) => p.$radius}px;
343
+ display: flex;
344
+ flex-direction: column;
345
+ gap: 6px;
346
+ box-shadow: ${(p) => p.$shadow};
347
+ `;
348
+ var PopoverTitle = import_styled_components.default.div`
349
+ display: flex;
350
+ height: 20px;
351
+ align-items: center;
352
+ padding: 0 ${(p) => p.$padding}px;
353
+ overflow: hidden;
354
+ `;
355
+ var PopoverDivider = import_styled_components.default.div`
356
+ height: 1px;
357
+ align-self: stretch;
358
+ background: ${(p) => p.$color};
359
+ `;
360
+ var PopoverItems = import_styled_components.default.div`
361
+ display: flex;
362
+ flex-direction: column;
363
+
364
+ & > .${POPOVER_ITEM_BASE_CLASS} {
365
+ display: flex;
366
+ max-height: ${(p) => p.$itemHeight}px;
367
+ align-items: center;
368
+ padding: 12px ${(p) => p.$padding}px;
369
+ border-radius: ${(p) => p.$radius}px;
370
+ color: ${(p) => p.$colorIdle};
371
+ font-weight: 400;
372
+ cursor: pointer;
373
+ transition: background-color 0.15s ease-in-out;
374
+ text-decoration: none;
375
+ }
376
+
377
+ & > .${POPOVER_ITEM_BASE_CLASS}:hover {
378
+ background-color: ${(p) => p.$hoverBg};
379
+ }
380
+
381
+ & > .${POPOVER_ITEM_BASE_CLASS}:focus-visible {
382
+ outline: ${(p) => p.$focusOutlineWidth}px solid ${(p) => p.$focusOutline};
383
+ outline-offset: -${(p) => p.$focusOutlineWidth}px;
384
+ }
385
+
386
+ & > .${POPOVER_ITEM_ACTIVE_CLASS} {
387
+ background-color: ${(p) => p.$activeBg};
388
+ color: ${(p) => p.$colorActive};
389
+ outline: 1px solid ${(p) => p.$activeOutline};
390
+ outline-offset: -1px;
391
+ font-weight: 500;
392
+ }
393
+ `;
394
+ var SinglePopoverPanel = import_styled_components.default.div`
395
+ padding: 4px;
396
+ background: ${(p) => p.$bg};
397
+ border-radius: ${(p) => p.$radius}px;
398
+ display: inline-flex;
399
+ flex-direction: column;
400
+ box-shadow: ${(p) => p.$shadow};
401
+ `;
402
+ var SingleLinkWrap = import_styled_components.default.div`
403
+ display: contents;
404
+
405
+ & > a,
406
+ & > * {
407
+ display: inline-flex;
408
+ max-height: ${(p) => p.$itemHeight}px;
409
+ align-items: center;
410
+ padding: 0 ${(p) => p.$padding}px;
411
+ border-radius: ${(p) => p.$radius}px;
412
+ color: ${(p) => p.$color};
413
+ cursor: pointer;
414
+ font-size: 14px;
415
+ font-weight: 400;
416
+ line-height: 18px;
417
+ white-space: nowrap;
418
+ text-decoration: none;
419
+ }
420
+ `;
421
+ var isChildActive = (item, pathname) => {
422
+ if (!item.children || !pathname) {
423
+ return false;
424
+ }
425
+ const pathWithoutMerchant = pathname.replace(/^\/\d+/, "");
426
+ return item.children.some((child) => {
427
+ if (typeof child.to !== "string") {
428
+ return false;
429
+ }
430
+ return child.exact ? pathWithoutMerchant === child.to : pathWithoutMerchant === child.to || pathWithoutMerchant.startsWith(`${child.to}/`);
431
+ });
432
+ };
433
+ var CollapsedIconItem = ({ item, onPopoverOpen, onPopoverClose, pathname, sizing, colors }) => {
434
+ const ref = (0, import_react2.useRef)(null);
435
+ const hasChildren = Boolean(item.children && item.children.length > 0);
436
+ const isActive = hasChildren && isChildActive(item, pathname);
437
+ const openPopover = (0, import_react2.useCallback)(() => {
438
+ if (ref.current) {
439
+ onPopoverOpen(item, ref.current.getBoundingClientRect());
440
+ }
441
+ }, [item, onPopoverOpen]);
442
+ const isSimpleActive = !hasChildren && (() => {
443
+ if (!item.to || !pathname) {
444
+ return false;
445
+ }
446
+ const pathWithoutMerchant = pathname.replace(/^\/\d+/, "");
447
+ return item.exact ? pathWithoutMerchant === item.to : pathWithoutMerchant === item.to || pathWithoutMerchant.startsWith(`${item.to}/`);
448
+ })();
449
+ const handleKeyDown = (e) => {
450
+ if (e.key === "Enter" || e.key === " ") {
451
+ e.preventDefault();
452
+ openPopover();
453
+ } else if (e.key === "Escape") {
454
+ onPopoverClose();
455
+ }
456
+ };
457
+ if (!item.icon) {
458
+ return null;
459
+ }
460
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
461
+ IconBtn,
462
+ {
463
+ ref,
464
+ type: "button",
465
+ onMouseEnter: openPopover,
466
+ onMouseLeave: onPopoverClose,
467
+ onFocus: openPopover,
468
+ onBlur: onPopoverClose,
469
+ onKeyDown: handleKeyDown,
470
+ "data-id": item.dataId,
471
+ "aria-haspopup": hasChildren ? "menu" : "false",
472
+ $size: sizing.itemHeight,
473
+ $radius: sizing.radius,
474
+ $iconSize: sizing.iconSize,
475
+ $color: colors.content.tertiary,
476
+ $hoverBg: colors.overlay.mono,
477
+ $hoverColor: colors.content.primary,
478
+ $activeBg: colors.overlay.mono,
479
+ $activeOutline: colors.border.secondary,
480
+ $focusOutline: colors.border.brand,
481
+ $focusOutlineWidth: sizing.focusOutlineWidth,
482
+ $active: isActive || isSimpleActive,
483
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: item.icon })
484
+ }
485
+ );
486
+ };
487
+ var CollapsedPopover = ({
488
+ item,
489
+ triggerRect,
490
+ onClose,
491
+ onMouseEnter,
492
+ onMouseLeave,
493
+ sizing,
494
+ colors
495
+ }) => {
496
+ const { LinkComponent } = useSidebar();
497
+ const popoverRef = (0, import_react2.useRef)(null);
498
+ const hasChildren = Boolean(item.children && item.children.length > 0);
499
+ const [position, setPosition] = (0, import_react2.useState)({
500
+ top: triggerRect.top,
501
+ left: triggerRect.right + POPOVER_GAP_PX
502
+ });
503
+ (0, import_react2.useLayoutEffect)(() => {
504
+ if (!popoverRef.current) {
505
+ return;
506
+ }
507
+ const rect = popoverRef.current.getBoundingClientRect();
508
+ const triggerCenterY = triggerRect.top + triggerRect.height / 2;
509
+ const idealTop = hasChildren ? triggerRect.top : triggerCenterY - rect.height / 2;
510
+ const maxTop = Math.max(
511
+ POPOVER_VIEWPORT_PADDING_PX,
512
+ window.innerHeight - rect.height - POPOVER_VIEWPORT_PADDING_PX
513
+ );
514
+ const top = Math.max(
515
+ POPOVER_VIEWPORT_PADDING_PX,
516
+ Math.min(idealTop, maxTop)
517
+ );
518
+ const left = Math.min(
519
+ triggerRect.right + POPOVER_GAP_PX,
520
+ window.innerWidth - rect.width - POPOVER_VIEWPORT_PADDING_PX
521
+ );
522
+ if (top !== position.top || left !== position.left) {
523
+ setPosition({ top, left });
524
+ }
525
+ }, [
526
+ triggerRect.top,
527
+ triggerRect.right,
528
+ triggerRect.height,
529
+ hasChildren,
530
+ item.dataId,
531
+ position.top,
532
+ position.left
533
+ ]);
534
+ if (!hasChildren) {
535
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
536
+ PopoverContainer,
537
+ {
538
+ ref: popoverRef,
539
+ style: { top: position.top, left: position.left, minWidth: "auto" },
540
+ onMouseEnter,
541
+ onMouseLeave,
542
+ $minWidth: 0,
543
+ $maxWidth: sizing.popoverMaxWidth,
544
+ $zIndex: sizing.popoverZIndex,
545
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
546
+ SinglePopoverPanel,
547
+ {
548
+ $padding: sizing.padding,
549
+ $itemHeight: sizing.itemHeight,
550
+ $radius: sizing.radius,
551
+ $bg: colors.layer.float,
552
+ $shadow: sizing.popoverShadow,
553
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
554
+ SingleLinkWrap,
555
+ {
556
+ $itemHeight: sizing.itemHeight,
557
+ $padding: sizing.padding,
558
+ $radius: sizing.radius,
559
+ $color: colors.content.primary,
560
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
561
+ LinkComponent,
562
+ {
563
+ to: item.to,
564
+ exact: item.exact,
565
+ external: item.external,
566
+ target: item.target,
567
+ dataId: item.dataId,
568
+ onClick: onClose,
569
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_xui_typography.Typography, { variant: "bodySm", color: "primary", children: item.label })
570
+ }
571
+ )
572
+ }
573
+ )
574
+ }
575
+ )
576
+ }
577
+ );
578
+ }
579
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
580
+ PopoverContainer,
581
+ {
582
+ ref: popoverRef,
583
+ role: "menu",
584
+ style: { top: position.top, left: position.left },
585
+ onMouseEnter,
586
+ onMouseLeave,
587
+ $minWidth: sizing.popoverMinWidth,
588
+ $maxWidth: sizing.popoverMaxWidth,
589
+ $zIndex: sizing.popoverZIndex,
590
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
591
+ PopoverInner,
592
+ {
593
+ $itemHeight: sizing.itemHeight,
594
+ $padding: sizing.padding,
595
+ $radius: sizing.radius,
596
+ $bg: colors.layer.float,
597
+ $shadow: sizing.popoverShadow,
598
+ children: [
599
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PopoverTitle, { $padding: sizing.padding, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_xui_typography.Typography, { variant: "bodyXs", color: "primary", children: item.label }) }),
600
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PopoverDivider, { $color: colors.border.secondary }),
601
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
602
+ PopoverItems,
603
+ {
604
+ $itemHeight: sizing.itemHeight,
605
+ $padding: sizing.padding,
606
+ $radius: sizing.radius,
607
+ $colorIdle: colors.content.tertiary,
608
+ $colorActive: colors.content.primary,
609
+ $hoverBg: colors.overlay.mono,
610
+ $activeBg: colors.overlay.mono,
611
+ $activeOutline: colors.border.secondary,
612
+ $focusOutline: colors.border.brand,
613
+ $focusOutlineWidth: sizing.focusOutlineWidth,
614
+ children: (item.children || []).map((child, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
615
+ LinkComponent,
616
+ {
617
+ to: child.to,
618
+ exact: child.exact,
619
+ external: child.external,
620
+ target: child.target,
621
+ className: POPOVER_ITEM_BASE_CLASS,
622
+ activeClassName: POPOVER_ITEM_ACTIVE_CLASS,
623
+ dataId: child.dataId,
624
+ onClick: onClose,
625
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_xui_typography.Typography, { variant: "bodySm", color: "inherit", children: child.label })
626
+ },
627
+ child.dataId || (typeof child.to === "string" ? child.to : `child-${i}`)
628
+ ))
629
+ }
630
+ )
631
+ ]
632
+ }
633
+ )
634
+ }
635
+ );
636
+ };
637
+ var SidebarCollapsed = ({
638
+ items,
639
+ toolItems = [],
640
+ bottomItems = [],
641
+ onToggleCollapse,
642
+ onChatClick,
643
+ showChat = true,
644
+ chatBadge = false
645
+ }) => {
646
+ const { pathname } = useSidebar();
647
+ const { theme } = (0, import_xui_core.useResolvedTheme)();
648
+ const sizing = theme.sizing.sidebar();
649
+ const colors = theme.colors;
650
+ const [popover, setPopover] = (0, import_react2.useState)(null);
651
+ const closeTimerRef = (0, import_react2.useRef)(null);
652
+ const cancelCloseTimer = (0, import_react2.useCallback)(() => {
653
+ if (closeTimerRef.current) {
654
+ clearTimeout(closeTimerRef.current);
655
+ closeTimerRef.current = null;
656
+ }
657
+ }, []);
658
+ const startCloseTimer = (0, import_react2.useCallback)(() => {
659
+ cancelCloseTimer();
660
+ closeTimerRef.current = setTimeout(() => {
661
+ setPopover(null);
662
+ }, POPOVER_CLOSE_DELAY_MS);
663
+ }, [cancelCloseTimer]);
664
+ (0, import_react2.useEffect)(() => () => cancelCloseTimer(), [cancelCloseTimer]);
665
+ const handlePopoverOpen = (0, import_react2.useCallback)(
666
+ (item, rect) => {
667
+ cancelCloseTimer();
668
+ setPopover({ item, triggerRect: rect });
669
+ },
670
+ [cancelCloseTimer]
671
+ );
672
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
673
+ Outer,
674
+ {
675
+ $width: sizing.widthCollapsed,
676
+ $radius: sizing.radius,
677
+ $bg: colors.background.secondary,
678
+ children: [
679
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(MainScroll, { $padding: sizing.padding, children: [
680
+ items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
681
+ CollapsedIconItem,
682
+ {
683
+ item,
684
+ onPopoverOpen: handlePopoverOpen,
685
+ onPopoverClose: startCloseTimer,
686
+ pathname,
687
+ sizing,
688
+ colors
689
+ },
690
+ item.dataId || `item-${i}`
691
+ )),
692
+ toolItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
693
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Spacer, {}),
694
+ toolItems.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
695
+ CollapsedIconItem,
696
+ {
697
+ item,
698
+ onPopoverOpen: handlePopoverOpen,
699
+ onPopoverClose: startCloseTimer,
700
+ pathname,
701
+ sizing,
702
+ colors
703
+ },
704
+ item.dataId || `tool-${i}`
705
+ ))
706
+ ] })
707
+ ] }),
708
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
709
+ FixedBottom,
710
+ {
711
+ $padding: sizing.padding,
712
+ $borderColor: colors.border.secondary,
713
+ children: bottomItems.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
714
+ CollapsedIconItem,
715
+ {
716
+ item,
717
+ onPopoverOpen: handlePopoverOpen,
718
+ onPopoverClose: startCloseTimer,
719
+ pathname,
720
+ sizing,
721
+ colors
722
+ },
723
+ item.dataId || `bottom-${i}`
724
+ ))
725
+ }
726
+ ),
727
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Footer, { $padding: sizing.padding, $borderColor: colors.border.secondary, children: [
728
+ showChat && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
729
+ CollapsedChat,
730
+ {
731
+ onClick: onChatClick,
732
+ type: "button",
733
+ "aria-label": "Open chat",
734
+ $size: sizing.itemHeight,
735
+ $radius: sizing.radius,
736
+ $bg: colors.control.brand.primary.bg,
737
+ $border: colors.control.brand.primary.border,
738
+ $color: colors.content.static.dark,
739
+ $focusOutline: colors.border.brand,
740
+ $focusOutlineWidth: sizing.focusOutlineWidth,
741
+ children: [
742
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_xui_icons_base.ChatTwoMessages, { size: 16, variant: "line" }),
743
+ chatBadge && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
744
+ ChatBadge,
745
+ {
746
+ $size: sizing.chatBadgeSize,
747
+ $color: colors.background.alert.primary
748
+ }
749
+ )
750
+ ]
751
+ }
752
+ ),
753
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
754
+ CollapsedToggle,
755
+ {
756
+ onClick: onToggleCollapse,
757
+ type: "button",
758
+ "aria-label": "Expand sidebar",
759
+ "aria-pressed": true,
760
+ $size: sizing.itemHeight,
761
+ $radius: sizing.radius,
762
+ $iconSize: sizing.iconSize,
763
+ $borderColor: colors.border.secondary,
764
+ $hoverBg: colors.overlay.mono,
765
+ $color: colors.content.tertiary,
766
+ $focusOutline: colors.border.brand,
767
+ $focusOutlineWidth: sizing.focusOutlineWidth,
768
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(HideSidebarIcon, { flipped: true })
769
+ }
770
+ )
771
+ ] }),
772
+ popover && typeof document !== "undefined" && (0, import_react_dom.createPortal)(
773
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
774
+ CollapsedPopover,
775
+ {
776
+ item: popover.item,
777
+ triggerRect: popover.triggerRect,
778
+ onClose: () => setPopover(null),
779
+ onMouseEnter: cancelCloseTimer,
780
+ onMouseLeave: startCloseTimer,
781
+ sizing,
782
+ colors
783
+ }
784
+ ),
785
+ document.body
786
+ )
787
+ ]
788
+ }
789
+ );
790
+ };
791
+
792
+ // src/Sidebar.tsx
793
+ var import_jsx_runtime4 = require("react/jsx-runtime");
794
+ var Outer2 = import_styled_components2.default.div`
795
+ width: ${(p) => p.$width}px;
796
+ height: 100%;
797
+ max-height: 100%;
798
+ flex-shrink: 0;
799
+ position: relative;
800
+ overflow: hidden;
801
+ border-radius: ${(p) => p.$radius}px;
802
+ background: ${(p) => p.$bg};
803
+ transition: width ${(p) => p.$transition};
804
+
805
+ a {
806
+ text-decoration: none;
807
+ }
808
+ `;
809
+ var ExpandedPane = import_styled_components2.default.div`
810
+ position: absolute;
811
+ top: 0;
812
+ left: 0;
813
+ width: ${(p) => p.$width}px;
814
+ height: 100%;
815
+ display: flex;
816
+ flex-direction: column;
817
+ overflow: hidden;
818
+ opacity: ${(p) => p.$hidden ? 0 : 1};
819
+ pointer-events: ${(p) => p.$hidden ? "none" : "auto"};
820
+ transition: ${(p) => p.$hidden ? p.$fadeOut : p.$fadeIn};
821
+ `;
822
+ var CollapsedPane = import_styled_components2.default.div`
823
+ position: absolute;
824
+ top: 0;
825
+ left: 0;
826
+ width: ${(p) => p.$width}px;
827
+ height: 100%;
828
+ opacity: ${(p) => p.$hidden ? 0 : 1};
829
+ pointer-events: ${(p) => p.$hidden ? "none" : "auto"};
830
+ transition: ${(p) => p.$hidden ? p.$fadeOut : p.$fadeIn};
831
+
832
+ & > div {
833
+ background: transparent;
834
+ border-radius: 0;
835
+ }
836
+ `;
837
+ var Sidebar = ({
838
+ collapsedItems = [],
839
+ collapsedToolItems = [],
840
+ collapsedBottomItems = [],
841
+ showChat = true,
842
+ onChatClick,
843
+ chatBadge = false,
844
+ children
845
+ }) => {
846
+ const { collapsed, onCollapsedChange } = useSidebar();
847
+ const { theme } = (0, import_xui_core2.useResolvedTheme)();
848
+ const sizing = theme.sizing.sidebar();
849
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
850
+ Outer2,
851
+ {
852
+ role: "navigation",
853
+ "aria-label": "Sidebar navigation",
854
+ $expanded: sizing.widthExpanded,
855
+ $collapsed: sizing.widthCollapsed,
856
+ $width: collapsed ? sizing.widthCollapsed : sizing.widthExpanded,
857
+ $radius: sizing.radius,
858
+ $bg: theme.colors.background.secondary,
859
+ $transition: sizing.transitionWidth,
860
+ children: [
861
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
862
+ ExpandedPane,
863
+ {
864
+ "aria-hidden": collapsed,
865
+ $width: sizing.widthExpanded,
866
+ $hidden: collapsed,
867
+ $fadeIn: sizing.transitionFadeIn,
868
+ $fadeOut: sizing.transitionFadeOut,
869
+ children
870
+ }
871
+ ),
872
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
873
+ CollapsedPane,
874
+ {
875
+ "aria-hidden": !collapsed,
876
+ $width: sizing.widthCollapsed,
877
+ $hidden: !collapsed,
878
+ $fadeIn: sizing.transitionFadeIn,
879
+ $fadeOut: sizing.transitionFadeOut,
880
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
881
+ SidebarCollapsed,
882
+ {
883
+ items: collapsedItems,
884
+ toolItems: collapsedToolItems,
885
+ bottomItems: collapsedBottomItems,
886
+ onToggleCollapse: () => onCollapsedChange(!collapsed),
887
+ showChat,
888
+ onChatClick,
889
+ chatBadge
890
+ }
891
+ )
892
+ }
893
+ )
894
+ ]
895
+ }
896
+ );
897
+ };
898
+
899
+ // src/SidebarContent.tsx
900
+ var import_styled_components3 = __toESM(require("styled-components"));
901
+ var import_xui_core3 = require("@xsolla/xui-core");
902
+ var import_jsx_runtime5 = require("react/jsx-runtime");
903
+ var ScrollableArea = import_styled_components3.default.div`
904
+ flex: 1;
905
+ display: flex;
906
+ flex-direction: column;
907
+ padding: ${(p) => p.$padding}px;
908
+ padding-bottom: 0;
909
+ overflow: hidden auto;
910
+ min-height: 0;
911
+
912
+ &::-webkit-scrollbar {
913
+ width: 4px;
914
+ }
915
+ &::-webkit-scrollbar-track {
916
+ background: none;
917
+ }
918
+ &::-webkit-scrollbar-thumb {
919
+ background-color: ${(p) => p.$thumbColor};
920
+ border-radius: 2px;
921
+ visibility: hidden;
922
+ }
923
+ &:hover::-webkit-scrollbar-thumb {
924
+ visibility: visible;
925
+ }
926
+ `;
927
+ var SidebarContent = ({
928
+ children
929
+ }) => {
930
+ const { theme } = (0, import_xui_core3.useResolvedTheme)();
931
+ const sizing = theme.sizing.sidebar();
932
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
933
+ ScrollableArea,
934
+ {
935
+ $padding: sizing.padding,
936
+ $thumbColor: theme.colors.content.tertiary,
937
+ children
938
+ }
939
+ );
940
+ };
941
+
942
+ // ../../foundation/primitives-web/src/Box.tsx
943
+ var import_react4 = __toESM(require("react"));
944
+ var import_styled_components4 = __toESM(require("styled-components"));
945
+
946
+ // ../../foundation/primitives-web/src/filterDOMProps.ts
947
+ var import_react3 = __toESM(require("react"));
948
+
949
+ // ../../../node_modules/@emotion/memoize/dist/memoize.esm.js
950
+ function memoize(fn) {
951
+ var cache = {};
952
+ return function(arg) {
953
+ if (cache[arg] === void 0) cache[arg] = fn(arg);
954
+ return cache[arg];
955
+ };
956
+ }
957
+ var memoize_esm_default = memoize;
958
+
959
+ // ../../../node_modules/@emotion/is-prop-valid/dist/is-prop-valid.esm.js
960
+ var reactPropsRegex = /^((children|dangerouslySetInnerHTML|key|ref|autoFocus|defaultValue|defaultChecked|innerHTML|suppressContentEditableWarning|suppressHydrationWarning|valueLink|accept|acceptCharset|accessKey|action|allow|allowUserMedia|allowPaymentRequest|allowFullScreen|allowTransparency|alt|async|autoComplete|autoPlay|capture|cellPadding|cellSpacing|challenge|charSet|checked|cite|classID|className|cols|colSpan|content|contentEditable|contextMenu|controls|controlsList|coords|crossOrigin|data|dateTime|decoding|default|defer|dir|disabled|disablePictureInPicture|download|draggable|encType|form|formAction|formEncType|formMethod|formNoValidate|formTarget|frameBorder|headers|height|hidden|high|href|hrefLang|htmlFor|httpEquiv|id|inputMode|integrity|is|keyParams|keyType|kind|label|lang|list|loading|loop|low|marginHeight|marginWidth|max|maxLength|media|mediaGroup|method|min|minLength|multiple|muted|name|nonce|noValidate|open|optimum|pattern|placeholder|playsInline|poster|preload|profile|radioGroup|readOnly|referrerPolicy|rel|required|reversed|role|rows|rowSpan|sandbox|scope|scoped|scrolling|seamless|selected|shape|size|sizes|slot|span|spellCheck|src|srcDoc|srcLang|srcSet|start|step|style|summary|tabIndex|target|title|type|useMap|value|width|wmode|wrap|about|datatype|inlist|prefix|property|resource|typeof|vocab|autoCapitalize|autoCorrect|autoSave|color|inert|itemProp|itemScope|itemType|itemID|itemRef|on|results|security|unselectable|accentHeight|accumulate|additive|alignmentBaseline|allowReorder|alphabetic|amplitude|arabicForm|ascent|attributeName|attributeType|autoReverse|azimuth|baseFrequency|baselineShift|baseProfile|bbox|begin|bias|by|calcMode|capHeight|clip|clipPathUnits|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|colorProfile|colorRendering|contentScriptType|contentStyleType|cursor|cx|cy|d|decelerate|descent|diffuseConstant|direction|display|divisor|dominantBaseline|dur|dx|dy|edgeMode|elevation|enableBackground|end|exponent|externalResourcesRequired|fill|fillOpacity|fillRule|filter|filterRes|filterUnits|floodColor|floodOpacity|focusable|fontFamily|fontSize|fontSizeAdjust|fontStretch|fontStyle|fontVariant|fontWeight|format|from|fr|fx|fy|g1|g2|glyphName|glyphOrientationHorizontal|glyphOrientationVertical|glyphRef|gradientTransform|gradientUnits|hanging|horizAdvX|horizOriginX|ideographic|imageRendering|in|in2|intercept|k|k1|k2|k3|k4|kernelMatrix|kernelUnitLength|kerning|keyPoints|keySplines|keyTimes|lengthAdjust|letterSpacing|lightingColor|limitingConeAngle|local|markerEnd|markerMid|markerStart|markerHeight|markerUnits|markerWidth|mask|maskContentUnits|maskUnits|mathematical|mode|numOctaves|offset|opacity|operator|order|orient|orientation|origin|overflow|overlinePosition|overlineThickness|panose1|paintOrder|pathLength|patternContentUnits|patternTransform|patternUnits|pointerEvents|points|pointsAtX|pointsAtY|pointsAtZ|preserveAlpha|preserveAspectRatio|primitiveUnits|r|radius|refX|refY|renderingIntent|repeatCount|repeatDur|requiredExtensions|requiredFeatures|restart|result|rotate|rx|ry|scale|seed|shapeRendering|slope|spacing|specularConstant|specularExponent|speed|spreadMethod|startOffset|stdDeviation|stemh|stemv|stitchTiles|stopColor|stopOpacity|strikethroughPosition|strikethroughThickness|string|stroke|strokeDasharray|strokeDashoffset|strokeLinecap|strokeLinejoin|strokeMiterlimit|strokeOpacity|strokeWidth|surfaceScale|systemLanguage|tableValues|targetX|targetY|textAnchor|textDecoration|textRendering|textLength|to|transform|u1|u2|underlinePosition|underlineThickness|unicode|unicodeBidi|unicodeRange|unitsPerEm|vAlphabetic|vHanging|vIdeographic|vMathematical|values|vectorEffect|version|vertAdvY|vertOriginX|vertOriginY|viewBox|viewTarget|visibility|widths|wordSpacing|writingMode|x|xHeight|x1|x2|xChannelSelector|xlinkActuate|xlinkArcrole|xlinkHref|xlinkRole|xlinkShow|xlinkTitle|xlinkType|xmlBase|xmlns|xmlnsXlink|xmlLang|xmlSpace|y|y1|y2|yChannelSelector|z|zoomAndPan|for|class|autofocus)|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/;
961
+ var index = memoize_esm_default(
962
+ function(prop) {
963
+ return reactPropsRegex.test(prop) || prop.charCodeAt(0) === 111 && prop.charCodeAt(1) === 110 && prop.charCodeAt(2) < 91;
964
+ }
965
+ /* Z+1 */
966
+ );
967
+ var is_prop_valid_esm_default = index;
968
+
969
+ // ../../foundation/primitives-web/src/filterDOMProps.ts
970
+ var ADDITIONAL_BLOCKED_PROPS = /* @__PURE__ */ new Set([
971
+ // RN-only event handlers (pass isPropValid's on* pattern)
972
+ "onPress",
973
+ "onChangeText",
974
+ "onLayout",
975
+ "onMoveShouldSetResponder",
976
+ "onResponderGrant",
977
+ "onResponderMove",
978
+ "onResponderRelease",
979
+ "onResponderTerminate",
980
+ // SVG attributes that pass isPropValid
981
+ "strokeWidth",
982
+ // CSS properties that pass isPropValid but are used as component props
983
+ "overflow",
984
+ "cursor",
985
+ "fontSize",
986
+ "fontWeight",
987
+ "fontFamily",
988
+ "textDecoration"
989
+ ]);
990
+ function shouldForwardProp(key) {
991
+ if (ADDITIONAL_BLOCKED_PROPS.has(key)) return false;
992
+ return is_prop_valid_esm_default(key);
993
+ }
994
+ function createFilteredElement(defaultTag) {
995
+ const Component = import_react3.default.forwardRef(
996
+ ({ children, elementType, ...props }, ref) => {
997
+ const Tag = elementType || defaultTag;
998
+ const htmlProps = {};
999
+ for (const key of Object.keys(props)) {
1000
+ if (shouldForwardProp(key)) {
1001
+ htmlProps[key] = props[key];
1002
+ }
1003
+ }
1004
+ return import_react3.default.createElement(
1005
+ Tag,
1006
+ { ref, ...htmlProps },
1007
+ children
1008
+ );
1009
+ }
1010
+ );
1011
+ Component.displayName = `Filtered(${defaultTag})`;
1012
+ return Component;
1013
+ }
1014
+
1015
+ // ../../foundation/primitives-web/src/Box.tsx
1016
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1017
+ var FilteredDiv = createFilteredElement("div");
1018
+ var StyledBox = (0, import_styled_components4.default)(FilteredDiv)`
1019
+ display: flex;
1020
+ box-sizing: border-box;
1021
+ background-color: ${(props) => props.backgroundColor || "transparent"};
1022
+ border-color: ${(props) => props.borderColor || "transparent"};
1023
+ border-width: ${(props) => typeof props.borderWidth === "number" ? `${props.borderWidth}px` : props.borderWidth || 0};
1024
+
1025
+ ${(props) => props.borderBottomWidth !== void 0 && `
1026
+ border-bottom-width: ${typeof props.borderBottomWidth === "number" ? `${props.borderBottomWidth}px` : props.borderBottomWidth};
1027
+ border-bottom-color: ${props.borderBottomColor || props.borderColor || "transparent"};
1028
+ border-bottom-style: solid;
1029
+ `}
1030
+ ${(props) => props.borderTopWidth !== void 0 && `
1031
+ border-top-width: ${typeof props.borderTopWidth === "number" ? `${props.borderTopWidth}px` : props.borderTopWidth};
1032
+ border-top-color: ${props.borderTopColor || props.borderColor || "transparent"};
1033
+ border-top-style: solid;
1034
+ `}
1035
+ ${(props) => props.borderLeftWidth !== void 0 && `
1036
+ border-left-width: ${typeof props.borderLeftWidth === "number" ? `${props.borderLeftWidth}px` : props.borderLeftWidth};
1037
+ border-left-color: ${props.borderLeftColor || props.borderColor || "transparent"};
1038
+ border-left-style: solid;
1039
+ `}
1040
+ ${(props) => props.borderRightWidth !== void 0 && `
1041
+ border-right-width: ${typeof props.borderRightWidth === "number" ? `${props.borderRightWidth}px` : props.borderRightWidth};
1042
+ border-right-color: ${props.borderRightColor || props.borderColor || "transparent"};
1043
+ border-right-style: solid;
1044
+ `}
1045
+
1046
+ border-style: ${(props) => props.borderStyle || (props.borderWidth || props.borderBottomWidth || props.borderTopWidth || props.borderLeftWidth || props.borderRightWidth ? "solid" : "none")};
1047
+ border-radius: ${(props) => typeof props.borderRadius === "number" ? `${props.borderRadius}px` : props.borderRadius || 0};
1048
+ height: ${(props) => typeof props.height === "number" ? `${props.height}px` : props.height || "auto"};
1049
+ width: ${(props) => typeof props.width === "number" ? `${props.width}px` : props.width || "auto"};
1050
+ min-width: ${(props) => typeof props.minWidth === "number" ? `${props.minWidth}px` : props.minWidth || "auto"};
1051
+ min-height: ${(props) => typeof props.minHeight === "number" ? `${props.minHeight}px` : props.minHeight || "auto"};
1052
+ max-width: ${(props) => typeof props.maxWidth === "number" ? `${props.maxWidth}px` : props.maxWidth || "none"};
1053
+ max-height: ${(props) => typeof props.maxHeight === "number" ? `${props.maxHeight}px` : props.maxHeight || "none"};
1054
+
1055
+ padding: ${(props) => typeof props.padding === "number" ? `${props.padding}px` : props.padding || 0};
1056
+ ${(props) => props.paddingHorizontal && `
1057
+ padding-left: ${typeof props.paddingHorizontal === "number" ? `${props.paddingHorizontal}px` : props.paddingHorizontal};
1058
+ padding-right: ${typeof props.paddingHorizontal === "number" ? `${props.paddingHorizontal}px` : props.paddingHorizontal};
1059
+ `}
1060
+ ${(props) => props.paddingVertical && `
1061
+ padding-top: ${typeof props.paddingVertical === "number" ? `${props.paddingVertical}px` : props.paddingVertical};
1062
+ padding-bottom: ${typeof props.paddingVertical === "number" ? `${props.paddingVertical}px` : props.paddingVertical};
1063
+ `}
1064
+ ${(props) => props.paddingTop !== void 0 && `padding-top: ${typeof props.paddingTop === "number" ? `${props.paddingTop}px` : props.paddingTop};`}
1065
+ ${(props) => props.paddingBottom !== void 0 && `padding-bottom: ${typeof props.paddingBottom === "number" ? `${props.paddingBottom}px` : props.paddingBottom};`}
1066
+ ${(props) => props.paddingLeft !== void 0 && `padding-left: ${typeof props.paddingLeft === "number" ? `${props.paddingLeft}px` : props.paddingLeft};`}
1067
+ ${(props) => props.paddingRight !== void 0 && `padding-right: ${typeof props.paddingRight === "number" ? `${props.paddingRight}px` : props.paddingRight};`}
1068
+
1069
+ margin: ${(props) => typeof props.margin === "number" ? `${props.margin}px` : props.margin || 0};
1070
+ ${(props) => props.marginTop !== void 0 && `margin-top: ${typeof props.marginTop === "number" ? `${props.marginTop}px` : props.marginTop};`}
1071
+ ${(props) => props.marginBottom !== void 0 && `margin-bottom: ${typeof props.marginBottom === "number" ? `${props.marginBottom}px` : props.marginBottom};`}
1072
+ ${(props) => props.marginLeft !== void 0 && `margin-left: ${typeof props.marginLeft === "number" ? `${props.marginLeft}px` : props.marginLeft};`}
1073
+ ${(props) => props.marginRight !== void 0 && `margin-right: ${typeof props.marginRight === "number" ? `${props.marginRight}px` : props.marginRight};`}
1074
+
1075
+ flex-direction: ${(props) => props.flexDirection || "column"};
1076
+ flex-wrap: ${(props) => props.flexWrap || "nowrap"};
1077
+ align-items: ${(props) => props.alignItems || "stretch"};
1078
+ justify-content: ${(props) => props.justifyContent || "flex-start"};
1079
+ cursor: ${(props) => props.cursor ? props.cursor : props.onClick || props.onPress ? "pointer" : "inherit"};
1080
+ position: ${(props) => props.position || "static"};
1081
+ top: ${(props) => typeof props.top === "number" ? `${props.top}px` : props.top};
1082
+ bottom: ${(props) => typeof props.bottom === "number" ? `${props.bottom}px` : props.bottom};
1083
+ left: ${(props) => typeof props.left === "number" ? `${props.left}px` : props.left};
1084
+ right: ${(props) => typeof props.right === "number" ? `${props.right}px` : props.right};
1085
+ flex: ${(props) => props.flex};
1086
+ flex-shrink: ${(props) => props.flexShrink ?? 1};
1087
+ gap: ${(props) => typeof props.gap === "number" ? `${props.gap}px` : props.gap || 0};
1088
+ align-self: ${(props) => props.alignSelf || "auto"};
1089
+ overflow: ${(props) => props.overflow || "visible"};
1090
+ overflow-x: ${(props) => props.overflowX || "visible"};
1091
+ overflow-y: ${(props) => props.overflowY || "visible"};
1092
+ z-index: ${(props) => props.zIndex};
1093
+ opacity: ${(props) => props.disabled ? 0.5 : 1};
1094
+ pointer-events: ${(props) => props.disabled ? "none" : "auto"};
1095
+
1096
+ &:hover {
1097
+ ${(props) => props.hoverStyle?.backgroundColor && `background-color: ${props.hoverStyle.backgroundColor};`}
1098
+ ${(props) => props.hoverStyle?.borderColor && `border-color: ${props.hoverStyle.borderColor};`}
1099
+ }
1100
+
1101
+ &:active {
1102
+ ${(props) => props.pressStyle?.backgroundColor && `background-color: ${props.pressStyle.backgroundColor};`}
1103
+ }
1104
+ `;
1105
+ var Box = import_react4.default.forwardRef(
1106
+ ({
1107
+ children,
1108
+ onPress,
1109
+ onKeyDown,
1110
+ onKeyUp,
1111
+ role,
1112
+ "aria-label": ariaLabel,
1113
+ "aria-labelledby": ariaLabelledBy,
1114
+ "aria-current": ariaCurrent,
1115
+ "aria-disabled": ariaDisabled,
1116
+ "aria-live": ariaLive,
1117
+ "aria-busy": ariaBusy,
1118
+ "aria-describedby": ariaDescribedBy,
1119
+ "aria-expanded": ariaExpanded,
1120
+ "aria-haspopup": ariaHasPopup,
1121
+ "aria-pressed": ariaPressed,
1122
+ "aria-controls": ariaControls,
1123
+ tabIndex,
1124
+ as,
1125
+ src,
1126
+ alt,
1127
+ type,
1128
+ disabled,
1129
+ id,
1130
+ testID,
1131
+ "data-testid": dataTestId,
1132
+ ...props
1133
+ }, ref) => {
1134
+ if (as === "img" && src) {
1135
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1136
+ "img",
1137
+ {
1138
+ src,
1139
+ alt: alt || "",
1140
+ style: {
1141
+ display: "block",
1142
+ objectFit: "cover",
1143
+ width: typeof props.width === "number" ? `${props.width}px` : props.width,
1144
+ height: typeof props.height === "number" ? `${props.height}px` : props.height,
1145
+ borderRadius: typeof props.borderRadius === "number" ? `${props.borderRadius}px` : props.borderRadius,
1146
+ position: props.position,
1147
+ top: typeof props.top === "number" ? `${props.top}px` : props.top,
1148
+ left: typeof props.left === "number" ? `${props.left}px` : props.left,
1149
+ right: typeof props.right === "number" ? `${props.right}px` : props.right,
1150
+ bottom: typeof props.bottom === "number" ? `${props.bottom}px` : props.bottom
1151
+ }
1152
+ }
1153
+ );
1154
+ }
1155
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1156
+ StyledBox,
1157
+ {
1158
+ ref,
1159
+ elementType: as,
1160
+ id,
1161
+ type: as === "button" ? type || "button" : void 0,
1162
+ disabled: as === "button" ? disabled : void 0,
1163
+ onClick: onPress,
1164
+ onKeyDown,
1165
+ onKeyUp,
1166
+ role,
1167
+ "aria-label": ariaLabel,
1168
+ "aria-labelledby": ariaLabelledBy,
1169
+ "aria-current": ariaCurrent,
1170
+ "aria-disabled": ariaDisabled,
1171
+ "aria-busy": ariaBusy,
1172
+ "aria-describedby": ariaDescribedBy,
1173
+ "aria-expanded": ariaExpanded,
1174
+ "aria-haspopup": ariaHasPopup,
1175
+ "aria-pressed": ariaPressed,
1176
+ "aria-controls": ariaControls,
1177
+ "aria-live": ariaLive,
1178
+ tabIndex: tabIndex !== void 0 ? tabIndex : void 0,
1179
+ "data-testid": dataTestId || testID,
1180
+ ...props,
1181
+ children
1182
+ }
1183
+ );
1184
+ }
1185
+ );
1186
+ Box.displayName = "Box";
1187
+
1188
+ // src/SidebarFooter.tsx
1189
+ var import_xui_core4 = require("@xsolla/xui-core");
1190
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1191
+ var SidebarFooter = ({
1192
+ children
1193
+ }) => {
1194
+ const { theme } = (0, import_xui_core4.useResolvedTheme)();
1195
+ const sizing = theme.sizing.sidebar();
1196
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1197
+ Box,
1198
+ {
1199
+ flexDirection: "row",
1200
+ alignItems: "flex-end",
1201
+ justifyContent: "space-between",
1202
+ padding: sizing.padding,
1203
+ borderTopWidth: 1,
1204
+ borderTopColor: theme.colors.border.secondary,
1205
+ flexShrink: 0,
1206
+ children
1207
+ }
1208
+ );
1209
+ };
1210
+
1211
+ // src/SidebarTrigger.tsx
1212
+ var import_styled_components5 = __toESM(require("styled-components"));
1213
+ var import_xui_core5 = require("@xsolla/xui-core");
1214
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1215
+ var ToggleButton = import_styled_components5.default.button`
1216
+ display: flex;
1217
+ width: ${(p) => p.$size}px;
1218
+ height: ${(p) => p.$size}px;
1219
+ align-items: center;
1220
+ justify-content: center;
1221
+ border: 1px solid ${(p) => p.$borderColor};
1222
+ border-radius: ${(p) => p.$radius}px;
1223
+ background: transparent;
1224
+ backdrop-filter: blur(30px);
1225
+ cursor: pointer;
1226
+ color: ${(p) => p.$color};
1227
+ padding: 0;
1228
+ font: inherit;
1229
+
1230
+ &:hover {
1231
+ background: ${(p) => p.$hoverBg};
1232
+ }
1233
+
1234
+ &:focus-visible {
1235
+ outline: ${(p) => p.$focusOutlineWidth}px solid ${(p) => p.$focusOutline};
1236
+ outline-offset: 2px;
1237
+ }
1238
+
1239
+ svg {
1240
+ width: ${(p) => p.$iconSize}px;
1241
+ height: ${(p) => p.$iconSize}px;
1242
+ }
1243
+ `;
1244
+ var SidebarTrigger = () => {
1245
+ const { collapsed, onCollapsedChange } = useSidebar();
1246
+ const { theme } = (0, import_xui_core5.useResolvedTheme)();
1247
+ const sizing = theme.sizing.sidebar();
1248
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1249
+ ToggleButton,
1250
+ {
1251
+ type: "button",
1252
+ onClick: () => onCollapsedChange(!collapsed),
1253
+ "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
1254
+ "aria-pressed": collapsed,
1255
+ $size: sizing.itemHeight,
1256
+ $radius: sizing.radius,
1257
+ $iconSize: sizing.iconSize,
1258
+ $borderColor: theme.colors.border.secondary,
1259
+ $hoverBg: theme.colors.overlay.mono,
1260
+ $color: theme.colors.content.tertiary,
1261
+ $focusOutline: theme.colors.border.brand,
1262
+ $focusOutlineWidth: sizing.focusOutlineWidth,
1263
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(HideSidebarIcon, { flipped: collapsed })
1264
+ }
1265
+ );
1266
+ };
1267
+
1268
+ // src/SidebarGroup.tsx
1269
+ var import_xui_core6 = require("@xsolla/xui-core");
1270
+ var import_xui_typography2 = require("@xsolla/xui-typography");
1271
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1272
+ var SidebarGroup = ({
1273
+ label,
1274
+ dataId,
1275
+ children
1276
+ }) => {
1277
+ const { theme } = (0, import_xui_core6.useResolvedTheme)();
1278
+ const sizing = theme.sizing.sidebar();
1279
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1280
+ Box,
1281
+ {
1282
+ flexDirection: "column",
1283
+ "data-id": dataId,
1284
+ role: label ? "group" : void 0,
1285
+ "aria-label": label,
1286
+ children: [
1287
+ label && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1288
+ Box,
1289
+ {
1290
+ flexDirection: "row",
1291
+ alignItems: "center",
1292
+ height: sizing.sectionLabelHeight,
1293
+ paddingHorizontal: sizing.padding,
1294
+ marginTop: sizing.padding,
1295
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_xui_typography2.Typography, { variant: "bodyXs", color: "secondary", children: label })
1296
+ }
1297
+ ),
1298
+ children
1299
+ ]
1300
+ }
1301
+ );
1302
+ };
1303
+
1304
+ // src/SidebarMenu.tsx
1305
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1306
+ var SidebarMenu = ({
1307
+ children
1308
+ }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Box, { flexDirection: "column", alignItems: "stretch", children });
1309
+
1310
+ // src/SidebarMenuItem.tsx
1311
+ var import_styled_components6 = __toESM(require("styled-components"));
1312
+ var import_xui_core7 = require("@xsolla/xui-core");
1313
+ var import_xui_typography3 = require("@xsolla/xui-typography");
1314
+ var import_xui_tooltip = require("@xsolla/xui-tooltip");
1315
+ var import_xui_icons_base2 = require("@xsolla/xui-icons-base");
1316
+
1317
+ // src/constants.ts
1318
+ var ITEM_BASE_CLASS = "xui-sb-item";
1319
+ var ITEM_ACTIVE_CLASS = "xui-sb-item--active";
1320
+
1321
+ // src/SidebarMenuItem.tsx
1322
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1323
+ var TOOLTIP_TRUNCATE_LENGTH = 20;
1324
+ var ItemWrapper = import_styled_components6.default.div`
1325
+ display: contents;
1326
+
1327
+ & > .${ITEM_BASE_CLASS} {
1328
+ display: flex;
1329
+ height: ${(p) => p.$multiLine ? "auto" : `${p.$itemHeight}px`};
1330
+ max-height: ${(p) => p.$multiLine ? "none" : `${p.$itemHeight}px`};
1331
+ width: 100%;
1332
+ box-sizing: border-box;
1333
+ align-items: ${(p) => p.$multiLine ? "flex-start" : "center"};
1334
+ gap: 8px;
1335
+ padding: 0 ${(p) => p.$padding}px;
1336
+ border-radius: ${(p) => p.$radius}px;
1337
+ color: ${(p) => p.$colorIdle};
1338
+ cursor: pointer;
1339
+ font-size: 14px;
1340
+ font-weight: 500;
1341
+ line-height: 18px;
1342
+ overflow: hidden;
1343
+ transition:
1344
+ background-color 0.15s ease-in-out,
1345
+ color 0.15s ease-in-out;
1346
+ white-space: ${(p) => p.$multiLine ? "normal" : "nowrap"};
1347
+ text-align: left;
1348
+ text-decoration: none;
1349
+ }
1350
+
1351
+ & > .${ITEM_BASE_CLASS}:hover {
1352
+ background-color: ${(p) => p.$hoverBg};
1353
+ }
1354
+
1355
+ & > .${ITEM_BASE_CLASS}:focus-visible {
1356
+ outline: ${(p) => p.$focusOutlineWidth}px solid ${(p) => p.$focusOutline};
1357
+ outline-offset: -${(p) => p.$focusOutlineWidth}px;
1358
+ }
1359
+
1360
+ & > .${ITEM_ACTIVE_CLASS} {
1361
+ background-color: ${(p) => p.$activeBg};
1362
+ outline: 1px solid ${(p) => p.$activeOutline};
1363
+ outline-offset: -1px;
1364
+ color: ${(p) => p.$colorActive};
1365
+ font-weight: 500;
1366
+ }
1367
+ `;
1368
+ var IconBox = import_styled_components6.default.div`
1369
+ display: flex;
1370
+ width: ${(p) => p.$size}px;
1371
+ height: ${(p) => p.$size}px;
1372
+ flex-shrink: 0;
1373
+ align-items: center;
1374
+ justify-content: center;
1375
+ color: inherit;
1376
+
1377
+ svg {
1378
+ width: ${(p) => p.$pin ? "12px" : `${p.$size}px`};
1379
+ height: ${(p) => p.$pin ? "12px" : `${p.$size}px`};
1380
+ }
1381
+ `;
1382
+ var LabelBox = import_styled_components6.default.span`
1383
+ display: flex;
1384
+ flex: 1;
1385
+ gap: 4px;
1386
+ height: 20px;
1387
+ align-items: center;
1388
+ min-width: 0;
1389
+ overflow: hidden;
1390
+ text-overflow: ellipsis;
1391
+ `;
1392
+ var BadgeDot = import_styled_components6.default.span`
1393
+ width: ${(p) => p.$size}px;
1394
+ height: ${(p) => p.$size}px;
1395
+ flex-shrink: 0;
1396
+ background: ${(p) => p.$color};
1397
+ border-radius: 999px;
1398
+ `;
1399
+ var BetaTag = import_styled_components6.default.span`
1400
+ padding: 2px 6px;
1401
+ border-radius: ${(p) => p.$radius}px;
1402
+ background: ${(p) => p.$bg};
1403
+ color: ${(p) => p.$color};
1404
+ font-size: 11px;
1405
+ font-weight: 500;
1406
+ line-height: 14px;
1407
+ flex-shrink: 0;
1408
+ `;
1409
+ var ExternalIconBox = import_styled_components6.default.span`
1410
+ display: flex;
1411
+ width: ${(p) => p.$size}px;
1412
+ height: ${(p) => p.$size}px;
1413
+ flex-shrink: 0;
1414
+ align-items: center;
1415
+ justify-content: center;
1416
+ margin-left: auto;
1417
+ color: ${(p) => p.$color};
1418
+ `;
1419
+ var SidebarMenuItem = ({
1420
+ to,
1421
+ label,
1422
+ icon,
1423
+ exact,
1424
+ external,
1425
+ hasExternalIcon,
1426
+ target,
1427
+ onClick,
1428
+ dataId,
1429
+ isActive,
1430
+ isPinned,
1431
+ showBadge,
1432
+ hasTooltip,
1433
+ beta,
1434
+ multiLine,
1435
+ extra,
1436
+ isNested = false
1437
+ }) => {
1438
+ const { LinkComponent } = useSidebar();
1439
+ const { theme } = (0, import_xui_core7.useResolvedTheme)();
1440
+ const sizing = theme.sizing.sidebar();
1441
+ const shouldTruncate = Boolean(hasTooltip) && typeof label === "string" && label.length > TOOLTIP_TRUNCATE_LENGTH;
1442
+ const displayLabel = shouldTruncate ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_xui_tooltip.Tooltip, { content: label, placement: "right", size: "md", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: `${label.slice(0, TOOLTIP_TRUNCATE_LENGTH)}\u2026` }) }) : label;
1443
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1444
+ ItemWrapper,
1445
+ {
1446
+ $itemHeight: sizing.itemHeight,
1447
+ $iconSize: sizing.iconSize,
1448
+ $padding: sizing.padding,
1449
+ $radius: sizing.radius,
1450
+ $colorIdle: theme.colors.content.tertiary,
1451
+ $colorActive: theme.colors.content.primary,
1452
+ $hoverBg: theme.colors.overlay.mono,
1453
+ $activeBg: theme.colors.overlay.mono,
1454
+ $activeOutline: theme.colors.border.secondary,
1455
+ $focusOutline: theme.colors.border.brand,
1456
+ $focusOutlineWidth: sizing.focusOutlineWidth,
1457
+ $multiLine: multiLine,
1458
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1459
+ LinkComponent,
1460
+ {
1461
+ to,
1462
+ exact,
1463
+ external,
1464
+ target,
1465
+ onClick,
1466
+ isActive,
1467
+ className: ITEM_BASE_CLASS,
1468
+ activeClassName: ITEM_ACTIVE_CLASS,
1469
+ dataId,
1470
+ children: [
1471
+ icon && !isNested && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(IconBox, { $size: sizing.iconSize, $pin: isPinned, children: icon }),
1472
+ extra,
1473
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(LabelBox, { children: [
1474
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1475
+ import_xui_typography3.Typography,
1476
+ {
1477
+ variant: isNested ? "bodySm" : "bodySmAccent",
1478
+ color: "inherit",
1479
+ noWrap: !multiLine,
1480
+ children: displayLabel
1481
+ }
1482
+ ),
1483
+ showBadge && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1484
+ BadgeDot,
1485
+ {
1486
+ $size: sizing.itemBadgeSize,
1487
+ $color: theme.colors.background.alert.primary
1488
+ }
1489
+ )
1490
+ ] }),
1491
+ beta && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1492
+ BetaTag,
1493
+ {
1494
+ $bg: theme.colors.overlay.mono,
1495
+ $color: theme.colors.content.tertiary,
1496
+ $radius: sizing.radius,
1497
+ children: "Beta"
1498
+ }
1499
+ ),
1500
+ external && hasExternalIcon && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1501
+ ExternalIconBox,
1502
+ {
1503
+ $size: sizing.externalIconSize,
1504
+ $color: theme.colors.content.secondary,
1505
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_xui_icons_base2.OpenIn, { size: 18, variant: "line" })
1506
+ }
1507
+ )
1508
+ ]
1509
+ }
1510
+ )
1511
+ }
1512
+ );
1513
+ };
1514
+
1515
+ // src/SidebarMenuCollapsible.tsx
1516
+ var import_react5 = require("react");
1517
+ var import_styled_components7 = __toESM(require("styled-components"));
1518
+ var import_xui_core8 = require("@xsolla/xui-core");
1519
+ var import_xui_typography4 = require("@xsolla/xui-typography");
1520
+ var import_xui_icons_base3 = require("@xsolla/xui-icons-base");
1521
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1522
+ var HeaderButton = import_styled_components7.default.button`
1523
+ display: flex;
1524
+ height: ${(p) => p.$itemHeight}px;
1525
+ width: 100%;
1526
+ box-sizing: border-box;
1527
+ align-items: center;
1528
+ gap: 8px;
1529
+ padding: 0 ${(p) => p.$padding}px;
1530
+ border: 0;
1531
+ border-radius: ${(p) => p.$radius}px;
1532
+ background: transparent;
1533
+ color: ${(p) => p.$color};
1534
+ cursor: pointer;
1535
+ font-size: 14px;
1536
+ font-weight: 500;
1537
+ line-height: 18px;
1538
+ font-family: inherit;
1539
+ text-align: left;
1540
+ white-space: nowrap;
1541
+ overflow: hidden;
1542
+ transition:
1543
+ background-color 0.15s ease-in-out,
1544
+ color 0.15s ease-in-out;
1545
+
1546
+ &:hover {
1547
+ background-color: ${(p) => p.$hoverBg};
1548
+ }
1549
+
1550
+ &:focus-visible {
1551
+ outline: ${(p) => p.$focusOutlineWidth}px solid ${(p) => p.$focusOutline};
1552
+ outline-offset: -${(p) => p.$focusOutlineWidth}px;
1553
+ }
1554
+ `;
1555
+ var ExpandRegion = import_styled_components7.default.div`
1556
+ display: grid;
1557
+ grid-template-rows: ${(p) => p.$expanded ? "1fr" : "0fr"};
1558
+ transition: ${(p) => p.$transition};
1559
+
1560
+ & > div {
1561
+ overflow: hidden;
1562
+ }
1563
+
1564
+ & .${ITEM_BASE_CLASS} {
1565
+ position: relative;
1566
+ padding: 0 ${(p) => p.$padding}px 0 ${(p) => p.$nestedPaddingLeft}px;
1567
+ font-weight: 400;
1568
+
1569
+ &::before {
1570
+ content: "";
1571
+ position: absolute;
1572
+ left: ${(p) => p.$railLeft}px;
1573
+ top: 0;
1574
+ bottom: 0;
1575
+ width: 1px;
1576
+ background: ${(p) => p.$railColor};
1577
+ transform: translateX(-50%);
1578
+ }
1579
+ }
1580
+
1581
+ & .${ITEM_ACTIVE_CLASS} {
1582
+ font-weight: 500;
1583
+ color: ${(p) => p.$colorActive};
1584
+ background-color: ${(p) => p.$activeBg};
1585
+ outline: 1px solid ${(p) => p.$activeOutline};
1586
+ outline-offset: -1px;
1587
+ }
1588
+ `;
1589
+ var IconBox2 = import_styled_components7.default.div`
1590
+ display: flex;
1591
+ width: ${(p) => p.$size}px;
1592
+ height: ${(p) => p.$size}px;
1593
+ flex-shrink: 0;
1594
+ align-items: center;
1595
+ justify-content: center;
1596
+ color: inherit;
1597
+
1598
+ svg {
1599
+ width: ${(p) => p.$size}px;
1600
+ height: ${(p) => p.$size}px;
1601
+ }
1602
+ `;
1603
+ var LabelBox2 = import_styled_components7.default.span`
1604
+ display: flex;
1605
+ flex: 1;
1606
+ gap: 4px;
1607
+ height: 20px;
1608
+ align-items: center;
1609
+ min-width: 0;
1610
+ overflow: hidden;
1611
+ text-overflow: ellipsis;
1612
+ `;
1613
+ var ChevronBox = import_styled_components7.default.span`
1614
+ display: flex;
1615
+ width: ${(p) => p.$size}px;
1616
+ height: ${(p) => p.$size}px;
1617
+ flex-shrink: 0;
1618
+ align-items: center;
1619
+ justify-content: center;
1620
+ margin-left: auto;
1621
+ color: inherit;
1622
+
1623
+ svg {
1624
+ width: ${(p) => p.$size}px;
1625
+ height: ${(p) => p.$size}px;
1626
+ }
1627
+ `;
1628
+ var computeRouteMatch = (pathname, matchPaths) => {
1629
+ if (matchPaths.length === 0) {
1630
+ return false;
1631
+ }
1632
+ const pathWithoutMerchant = pathname.replace(/^\/\d+/, "");
1633
+ return matchPaths.some((p) => {
1634
+ if (p === "/") return pathWithoutMerchant === "/";
1635
+ return pathWithoutMerchant === p || pathWithoutMerchant.startsWith(`${p}/`);
1636
+ });
1637
+ };
1638
+ var SidebarMenuCollapsible = ({
1639
+ icon,
1640
+ label,
1641
+ dataId,
1642
+ matchPaths = [],
1643
+ children
1644
+ }) => {
1645
+ const { pathname, expandedId, onExpandedIdChange } = useSidebar();
1646
+ const { theme } = (0, import_xui_core8.useResolvedTheme)();
1647
+ const sizing = theme.sizing.sidebar();
1648
+ const idRef = (0, import_react5.useRef)();
1649
+ if (!idRef.current) {
1650
+ idRef.current = dataId || `sb-collapsible-${Math.random().toString(36).slice(2, 10)}`;
1651
+ }
1652
+ const collapsibleId = idRef.current;
1653
+ const contentId = `sidebar-collapsible-${collapsibleId}`;
1654
+ const matchKey = matchPaths.join("|");
1655
+ const isRouteMatch = (0, import_react5.useMemo)(
1656
+ () => computeRouteMatch(pathname, matchPaths),
1657
+ [pathname, matchKey, matchPaths]
1658
+ );
1659
+ const prevMatchRef = (0, import_react5.useRef)(isRouteMatch);
1660
+ (0, import_react5.useEffect)(() => {
1661
+ if (prevMatchRef.current !== isRouteMatch) {
1662
+ prevMatchRef.current = isRouteMatch;
1663
+ if (isRouteMatch) {
1664
+ onExpandedIdChange(collapsibleId);
1665
+ }
1666
+ }
1667
+ }, [isRouteMatch, collapsibleId, onExpandedIdChange]);
1668
+ const mountRef = (0, import_react5.useRef)(true);
1669
+ (0, import_react5.useEffect)(() => {
1670
+ if (mountRef.current && isRouteMatch) {
1671
+ onExpandedIdChange(collapsibleId);
1672
+ mountRef.current = false;
1673
+ }
1674
+ }, [isRouteMatch, collapsibleId, onExpandedIdChange]);
1675
+ const isExpanded = expandedId === collapsibleId;
1676
+ const handleToggle = () => {
1677
+ onExpandedIdChange(isExpanded ? null : collapsibleId);
1678
+ };
1679
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1680
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1681
+ HeaderButton,
1682
+ {
1683
+ type: "button",
1684
+ onClick: handleToggle,
1685
+ "data-id": dataId,
1686
+ "aria-expanded": isExpanded,
1687
+ "aria-controls": contentId,
1688
+ $itemHeight: sizing.itemHeight,
1689
+ $padding: sizing.padding,
1690
+ $radius: sizing.radius,
1691
+ $color: theme.colors.content.tertiary,
1692
+ $hoverBg: theme.colors.control.mono.secondary.bgHover,
1693
+ $focusOutline: theme.colors.border.brand,
1694
+ $focusOutlineWidth: sizing.focusOutlineWidth,
1695
+ children: [
1696
+ icon && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconBox2, { $size: sizing.iconSize, children: icon }),
1697
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(LabelBox2, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_xui_typography4.Typography, { variant: "bodySmAccent", color: "inherit", noWrap: true, children: label }) }),
1698
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChevronBox, { $size: sizing.chevronSize, children: isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_xui_icons_base3.ChevronUp, { size: 14, variant: "solid" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_xui_icons_base3.ChevronRight, { size: 14, variant: "solid" }) })
1699
+ ]
1700
+ }
1701
+ ),
1702
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1703
+ ExpandRegion,
1704
+ {
1705
+ id: contentId,
1706
+ role: "region",
1707
+ $expanded: isExpanded,
1708
+ $transition: sizing.transitionRows,
1709
+ $padding: sizing.padding,
1710
+ $nestedPaddingLeft: sizing.nestedItemPaddingLeft,
1711
+ $railLeft: sizing.nestedItemRailLeft,
1712
+ $railColor: theme.colors.border.secondary,
1713
+ $colorActive: theme.colors.content.primary,
1714
+ $activeBg: theme.colors.overlay.mono,
1715
+ $activeOutline: theme.colors.border.secondary,
1716
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { children })
1717
+ }
1718
+ )
1719
+ ] });
1720
+ };
1721
+
1722
+ // src/SidebarMenuSub.tsx
1723
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1724
+ var SidebarMenuSub = ({
1725
+ children
1726
+ }) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_jsx_runtime13.Fragment, { children });
1727
+
1728
+ // src/SidebarChatButton.tsx
1729
+ var import_styled_components8 = __toESM(require("styled-components"));
1730
+ var import_xui_core9 = require("@xsolla/xui-core");
1731
+ var import_xui_typography5 = require("@xsolla/xui-typography");
1732
+ var import_xui_icons_base4 = require("@xsolla/xui-icons-base");
1733
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1734
+ var ChatButton = import_styled_components8.default.button`
1735
+ display: flex;
1736
+ height: ${(p) => p.$height}px;
1737
+ align-items: center;
1738
+ gap: 8px;
1739
+ padding: 0 ${(p) => p.$padding}px;
1740
+ border: 1px solid ${(p) => p.$border};
1741
+ border-radius: ${(p) => p.$radius}px;
1742
+ background: ${(p) => p.$bg};
1743
+ color: ${(p) => p.$color};
1744
+ cursor: pointer;
1745
+ font: inherit;
1746
+ position: relative;
1747
+
1748
+ &:hover {
1749
+ opacity: 0.9;
1750
+ }
1751
+
1752
+ &:focus-visible {
1753
+ outline: ${(p) => p.$focusOutlineWidth}px solid ${(p) => p.$focusOutline};
1754
+ outline-offset: 2px;
1755
+ }
1756
+
1757
+ svg {
1758
+ width: 16px;
1759
+ height: 16px;
1760
+ }
1761
+ `;
1762
+ var Badge = import_styled_components8.default.span`
1763
+ position: absolute;
1764
+ top: -2px;
1765
+ right: -2px;
1766
+ width: ${(p) => p.$size}px;
1767
+ height: ${(p) => p.$size}px;
1768
+ background: ${(p) => p.$color};
1769
+ border-radius: 999px;
1770
+ `;
1771
+ var SidebarChatButton = ({
1772
+ onClick,
1773
+ badge
1774
+ }) => {
1775
+ const { theme } = (0, import_xui_core9.useResolvedTheme)();
1776
+ const sizing = theme.sizing.sidebar();
1777
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1778
+ ChatButton,
1779
+ {
1780
+ onClick,
1781
+ type: "button",
1782
+ $height: sizing.itemHeight,
1783
+ $padding: sizing.padding,
1784
+ $radius: sizing.radius,
1785
+ $bg: theme.colors.control.brand.primary.bg,
1786
+ $border: theme.colors.control.brand.primary.border,
1787
+ $color: theme.colors.content.static.dark,
1788
+ $focusOutline: theme.colors.border.brand,
1789
+ $focusOutlineWidth: sizing.focusOutlineWidth,
1790
+ children: [
1791
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_xui_icons_base4.ChatTwoMessages, { size: 16, variant: "line" }),
1792
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_xui_typography5.Typography, { variant: "bodySmAccent", color: "inherit", children: "Chat" }),
1793
+ badge && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1794
+ Badge,
1795
+ {
1796
+ $size: sizing.chatBadgeSize,
1797
+ $color: theme.colors.background.alert.primary
1798
+ }
1799
+ )
1800
+ ]
1801
+ }
1802
+ );
1803
+ };
1804
+ // Annotate the CommonJS export names for ESM import in node:
1805
+ 0 && (module.exports = {
1806
+ Sidebar,
1807
+ SidebarChatButton,
1808
+ SidebarCollapsed,
1809
+ SidebarContent,
1810
+ SidebarFooter,
1811
+ SidebarGroup,
1812
+ SidebarMenu,
1813
+ SidebarMenuCollapsible,
1814
+ SidebarMenuItem,
1815
+ SidebarMenuSub,
1816
+ SidebarProvider,
1817
+ SidebarTrigger,
1818
+ useSidebar
1819
+ });
1820
+ //# sourceMappingURL=index.js.map