@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.
@@ -0,0 +1,1748 @@
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-native/src/Box.tsx
943
+ var import_react_native = require("react-native");
944
+ var import_jsx_runtime6 = require("react/jsx-runtime");
945
+ var Box = ({
946
+ children,
947
+ onPress,
948
+ onLayout,
949
+ onMoveShouldSetResponder,
950
+ onResponderGrant,
951
+ onResponderMove,
952
+ onResponderRelease,
953
+ onResponderTerminate,
954
+ backgroundColor,
955
+ borderColor,
956
+ borderWidth,
957
+ borderBottomWidth,
958
+ borderBottomColor,
959
+ borderTopWidth,
960
+ borderTopColor,
961
+ borderLeftWidth,
962
+ borderLeftColor,
963
+ borderRightWidth,
964
+ borderRightColor,
965
+ borderRadius,
966
+ borderStyle,
967
+ height,
968
+ padding,
969
+ paddingHorizontal,
970
+ paddingVertical,
971
+ margin,
972
+ marginTop,
973
+ marginBottom,
974
+ marginLeft,
975
+ marginRight,
976
+ flexDirection,
977
+ alignItems,
978
+ justifyContent,
979
+ position,
980
+ top,
981
+ bottom,
982
+ left,
983
+ right,
984
+ width,
985
+ minWidth,
986
+ minHeight,
987
+ maxWidth,
988
+ maxHeight,
989
+ flex,
990
+ overflow,
991
+ zIndex,
992
+ hoverStyle,
993
+ pressStyle,
994
+ style,
995
+ "data-testid": dataTestId,
996
+ testID,
997
+ as,
998
+ src,
999
+ alt,
1000
+ ...rest
1001
+ }) => {
1002
+ const getContainerStyle = (pressed) => ({
1003
+ backgroundColor: pressed && pressStyle?.backgroundColor ? pressStyle.backgroundColor : backgroundColor,
1004
+ borderColor,
1005
+ borderWidth,
1006
+ borderBottomWidth,
1007
+ borderBottomColor,
1008
+ borderTopWidth,
1009
+ borderTopColor,
1010
+ borderLeftWidth,
1011
+ borderLeftColor,
1012
+ borderRightWidth,
1013
+ borderRightColor,
1014
+ borderRadius,
1015
+ borderStyle,
1016
+ overflow,
1017
+ zIndex,
1018
+ height,
1019
+ width,
1020
+ minWidth,
1021
+ minHeight,
1022
+ maxWidth,
1023
+ maxHeight,
1024
+ padding,
1025
+ paddingHorizontal,
1026
+ paddingVertical,
1027
+ margin,
1028
+ marginTop,
1029
+ marginBottom,
1030
+ marginLeft,
1031
+ marginRight,
1032
+ flexDirection,
1033
+ alignItems,
1034
+ justifyContent,
1035
+ position,
1036
+ top,
1037
+ bottom,
1038
+ left,
1039
+ right,
1040
+ flex,
1041
+ ...style
1042
+ });
1043
+ const finalTestID = dataTestId || testID;
1044
+ const {
1045
+ role,
1046
+ tabIndex,
1047
+ onKeyDown,
1048
+ onKeyUp,
1049
+ "aria-label": _ariaLabel,
1050
+ "aria-labelledby": _ariaLabelledBy,
1051
+ "aria-current": _ariaCurrent,
1052
+ "aria-disabled": _ariaDisabled,
1053
+ "aria-live": _ariaLive,
1054
+ className,
1055
+ "data-testid": _dataTestId,
1056
+ ...nativeRest
1057
+ } = rest;
1058
+ if (as === "img" && src) {
1059
+ const imageStyle = {
1060
+ width,
1061
+ height,
1062
+ borderRadius,
1063
+ position,
1064
+ top,
1065
+ bottom,
1066
+ left,
1067
+ right,
1068
+ ...style
1069
+ };
1070
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1071
+ import_react_native.Image,
1072
+ {
1073
+ source: { uri: src },
1074
+ style: imageStyle,
1075
+ testID: finalTestID,
1076
+ resizeMode: "cover",
1077
+ ...nativeRest
1078
+ }
1079
+ );
1080
+ }
1081
+ if (onPress) {
1082
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1083
+ import_react_native.Pressable,
1084
+ {
1085
+ onPress,
1086
+ onLayout,
1087
+ onMoveShouldSetResponder,
1088
+ onResponderGrant,
1089
+ onResponderMove,
1090
+ onResponderRelease,
1091
+ onResponderTerminate,
1092
+ style: ({ pressed }) => getContainerStyle(pressed),
1093
+ testID: finalTestID,
1094
+ ...nativeRest,
1095
+ children
1096
+ }
1097
+ );
1098
+ }
1099
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1100
+ import_react_native.View,
1101
+ {
1102
+ style: getContainerStyle(),
1103
+ testID: finalTestID,
1104
+ onLayout,
1105
+ onMoveShouldSetResponder,
1106
+ onResponderGrant,
1107
+ onResponderMove,
1108
+ onResponderRelease,
1109
+ onResponderTerminate,
1110
+ ...nativeRest,
1111
+ children
1112
+ }
1113
+ );
1114
+ };
1115
+
1116
+ // src/SidebarFooter.tsx
1117
+ var import_xui_core4 = require("@xsolla/xui-core");
1118
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1119
+ var SidebarFooter = ({
1120
+ children
1121
+ }) => {
1122
+ const { theme } = (0, import_xui_core4.useResolvedTheme)();
1123
+ const sizing = theme.sizing.sidebar();
1124
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1125
+ Box,
1126
+ {
1127
+ flexDirection: "row",
1128
+ alignItems: "flex-end",
1129
+ justifyContent: "space-between",
1130
+ padding: sizing.padding,
1131
+ borderTopWidth: 1,
1132
+ borderTopColor: theme.colors.border.secondary,
1133
+ flexShrink: 0,
1134
+ children
1135
+ }
1136
+ );
1137
+ };
1138
+
1139
+ // src/SidebarTrigger.tsx
1140
+ var import_styled_components4 = __toESM(require("styled-components"));
1141
+ var import_xui_core5 = require("@xsolla/xui-core");
1142
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1143
+ var ToggleButton = import_styled_components4.default.button`
1144
+ display: flex;
1145
+ width: ${(p) => p.$size}px;
1146
+ height: ${(p) => p.$size}px;
1147
+ align-items: center;
1148
+ justify-content: center;
1149
+ border: 1px solid ${(p) => p.$borderColor};
1150
+ border-radius: ${(p) => p.$radius}px;
1151
+ background: transparent;
1152
+ backdrop-filter: blur(30px);
1153
+ cursor: pointer;
1154
+ color: ${(p) => p.$color};
1155
+ padding: 0;
1156
+ font: inherit;
1157
+
1158
+ &:hover {
1159
+ background: ${(p) => p.$hoverBg};
1160
+ }
1161
+
1162
+ &:focus-visible {
1163
+ outline: ${(p) => p.$focusOutlineWidth}px solid ${(p) => p.$focusOutline};
1164
+ outline-offset: 2px;
1165
+ }
1166
+
1167
+ svg {
1168
+ width: ${(p) => p.$iconSize}px;
1169
+ height: ${(p) => p.$iconSize}px;
1170
+ }
1171
+ `;
1172
+ var SidebarTrigger = () => {
1173
+ const { collapsed, onCollapsedChange } = useSidebar();
1174
+ const { theme } = (0, import_xui_core5.useResolvedTheme)();
1175
+ const sizing = theme.sizing.sidebar();
1176
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1177
+ ToggleButton,
1178
+ {
1179
+ type: "button",
1180
+ onClick: () => onCollapsedChange(!collapsed),
1181
+ "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
1182
+ "aria-pressed": collapsed,
1183
+ $size: sizing.itemHeight,
1184
+ $radius: sizing.radius,
1185
+ $iconSize: sizing.iconSize,
1186
+ $borderColor: theme.colors.border.secondary,
1187
+ $hoverBg: theme.colors.overlay.mono,
1188
+ $color: theme.colors.content.tertiary,
1189
+ $focusOutline: theme.colors.border.brand,
1190
+ $focusOutlineWidth: sizing.focusOutlineWidth,
1191
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(HideSidebarIcon, { flipped: collapsed })
1192
+ }
1193
+ );
1194
+ };
1195
+
1196
+ // src/SidebarGroup.tsx
1197
+ var import_xui_core6 = require("@xsolla/xui-core");
1198
+ var import_xui_typography2 = require("@xsolla/xui-typography");
1199
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1200
+ var SidebarGroup = ({
1201
+ label,
1202
+ dataId,
1203
+ children
1204
+ }) => {
1205
+ const { theme } = (0, import_xui_core6.useResolvedTheme)();
1206
+ const sizing = theme.sizing.sidebar();
1207
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1208
+ Box,
1209
+ {
1210
+ flexDirection: "column",
1211
+ "data-id": dataId,
1212
+ role: label ? "group" : void 0,
1213
+ "aria-label": label,
1214
+ children: [
1215
+ label && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1216
+ Box,
1217
+ {
1218
+ flexDirection: "row",
1219
+ alignItems: "center",
1220
+ height: sizing.sectionLabelHeight,
1221
+ paddingHorizontal: sizing.padding,
1222
+ marginTop: sizing.padding,
1223
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_xui_typography2.Typography, { variant: "bodyXs", color: "secondary", children: label })
1224
+ }
1225
+ ),
1226
+ children
1227
+ ]
1228
+ }
1229
+ );
1230
+ };
1231
+
1232
+ // src/SidebarMenu.tsx
1233
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1234
+ var SidebarMenu = ({
1235
+ children
1236
+ }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Box, { flexDirection: "column", alignItems: "stretch", children });
1237
+
1238
+ // src/SidebarMenuItem.tsx
1239
+ var import_styled_components5 = __toESM(require("styled-components"));
1240
+ var import_xui_core7 = require("@xsolla/xui-core");
1241
+ var import_xui_typography3 = require("@xsolla/xui-typography");
1242
+ var import_xui_tooltip = require("@xsolla/xui-tooltip");
1243
+ var import_xui_icons_base2 = require("@xsolla/xui-icons-base");
1244
+
1245
+ // src/constants.ts
1246
+ var ITEM_BASE_CLASS = "xui-sb-item";
1247
+ var ITEM_ACTIVE_CLASS = "xui-sb-item--active";
1248
+
1249
+ // src/SidebarMenuItem.tsx
1250
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1251
+ var TOOLTIP_TRUNCATE_LENGTH = 20;
1252
+ var ItemWrapper = import_styled_components5.default.div`
1253
+ display: contents;
1254
+
1255
+ & > .${ITEM_BASE_CLASS} {
1256
+ display: flex;
1257
+ height: ${(p) => p.$multiLine ? "auto" : `${p.$itemHeight}px`};
1258
+ max-height: ${(p) => p.$multiLine ? "none" : `${p.$itemHeight}px`};
1259
+ width: 100%;
1260
+ box-sizing: border-box;
1261
+ align-items: ${(p) => p.$multiLine ? "flex-start" : "center"};
1262
+ gap: 8px;
1263
+ padding: 0 ${(p) => p.$padding}px;
1264
+ border-radius: ${(p) => p.$radius}px;
1265
+ color: ${(p) => p.$colorIdle};
1266
+ cursor: pointer;
1267
+ font-size: 14px;
1268
+ font-weight: 500;
1269
+ line-height: 18px;
1270
+ overflow: hidden;
1271
+ transition:
1272
+ background-color 0.15s ease-in-out,
1273
+ color 0.15s ease-in-out;
1274
+ white-space: ${(p) => p.$multiLine ? "normal" : "nowrap"};
1275
+ text-align: left;
1276
+ text-decoration: none;
1277
+ }
1278
+
1279
+ & > .${ITEM_BASE_CLASS}:hover {
1280
+ background-color: ${(p) => p.$hoverBg};
1281
+ }
1282
+
1283
+ & > .${ITEM_BASE_CLASS}:focus-visible {
1284
+ outline: ${(p) => p.$focusOutlineWidth}px solid ${(p) => p.$focusOutline};
1285
+ outline-offset: -${(p) => p.$focusOutlineWidth}px;
1286
+ }
1287
+
1288
+ & > .${ITEM_ACTIVE_CLASS} {
1289
+ background-color: ${(p) => p.$activeBg};
1290
+ outline: 1px solid ${(p) => p.$activeOutline};
1291
+ outline-offset: -1px;
1292
+ color: ${(p) => p.$colorActive};
1293
+ font-weight: 500;
1294
+ }
1295
+ `;
1296
+ var IconBox = import_styled_components5.default.div`
1297
+ display: flex;
1298
+ width: ${(p) => p.$size}px;
1299
+ height: ${(p) => p.$size}px;
1300
+ flex-shrink: 0;
1301
+ align-items: center;
1302
+ justify-content: center;
1303
+ color: inherit;
1304
+
1305
+ svg {
1306
+ width: ${(p) => p.$pin ? "12px" : `${p.$size}px`};
1307
+ height: ${(p) => p.$pin ? "12px" : `${p.$size}px`};
1308
+ }
1309
+ `;
1310
+ var LabelBox = import_styled_components5.default.span`
1311
+ display: flex;
1312
+ flex: 1;
1313
+ gap: 4px;
1314
+ height: 20px;
1315
+ align-items: center;
1316
+ min-width: 0;
1317
+ overflow: hidden;
1318
+ text-overflow: ellipsis;
1319
+ `;
1320
+ var BadgeDot = import_styled_components5.default.span`
1321
+ width: ${(p) => p.$size}px;
1322
+ height: ${(p) => p.$size}px;
1323
+ flex-shrink: 0;
1324
+ background: ${(p) => p.$color};
1325
+ border-radius: 999px;
1326
+ `;
1327
+ var BetaTag = import_styled_components5.default.span`
1328
+ padding: 2px 6px;
1329
+ border-radius: ${(p) => p.$radius}px;
1330
+ background: ${(p) => p.$bg};
1331
+ color: ${(p) => p.$color};
1332
+ font-size: 11px;
1333
+ font-weight: 500;
1334
+ line-height: 14px;
1335
+ flex-shrink: 0;
1336
+ `;
1337
+ var ExternalIconBox = import_styled_components5.default.span`
1338
+ display: flex;
1339
+ width: ${(p) => p.$size}px;
1340
+ height: ${(p) => p.$size}px;
1341
+ flex-shrink: 0;
1342
+ align-items: center;
1343
+ justify-content: center;
1344
+ margin-left: auto;
1345
+ color: ${(p) => p.$color};
1346
+ `;
1347
+ var SidebarMenuItem = ({
1348
+ to,
1349
+ label,
1350
+ icon,
1351
+ exact,
1352
+ external,
1353
+ hasExternalIcon,
1354
+ target,
1355
+ onClick,
1356
+ dataId,
1357
+ isActive,
1358
+ isPinned,
1359
+ showBadge,
1360
+ hasTooltip,
1361
+ beta,
1362
+ multiLine,
1363
+ extra,
1364
+ isNested = false
1365
+ }) => {
1366
+ const { LinkComponent } = useSidebar();
1367
+ const { theme } = (0, import_xui_core7.useResolvedTheme)();
1368
+ const sizing = theme.sizing.sidebar();
1369
+ const shouldTruncate = Boolean(hasTooltip) && typeof label === "string" && label.length > TOOLTIP_TRUNCATE_LENGTH;
1370
+ 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;
1371
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1372
+ ItemWrapper,
1373
+ {
1374
+ $itemHeight: sizing.itemHeight,
1375
+ $iconSize: sizing.iconSize,
1376
+ $padding: sizing.padding,
1377
+ $radius: sizing.radius,
1378
+ $colorIdle: theme.colors.content.tertiary,
1379
+ $colorActive: theme.colors.content.primary,
1380
+ $hoverBg: theme.colors.overlay.mono,
1381
+ $activeBg: theme.colors.overlay.mono,
1382
+ $activeOutline: theme.colors.border.secondary,
1383
+ $focusOutline: theme.colors.border.brand,
1384
+ $focusOutlineWidth: sizing.focusOutlineWidth,
1385
+ $multiLine: multiLine,
1386
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1387
+ LinkComponent,
1388
+ {
1389
+ to,
1390
+ exact,
1391
+ external,
1392
+ target,
1393
+ onClick,
1394
+ isActive,
1395
+ className: ITEM_BASE_CLASS,
1396
+ activeClassName: ITEM_ACTIVE_CLASS,
1397
+ dataId,
1398
+ children: [
1399
+ icon && !isNested && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(IconBox, { $size: sizing.iconSize, $pin: isPinned, children: icon }),
1400
+ extra,
1401
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(LabelBox, { children: [
1402
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1403
+ import_xui_typography3.Typography,
1404
+ {
1405
+ variant: isNested ? "bodySm" : "bodySmAccent",
1406
+ color: "inherit",
1407
+ noWrap: !multiLine,
1408
+ children: displayLabel
1409
+ }
1410
+ ),
1411
+ showBadge && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1412
+ BadgeDot,
1413
+ {
1414
+ $size: sizing.itemBadgeSize,
1415
+ $color: theme.colors.background.alert.primary
1416
+ }
1417
+ )
1418
+ ] }),
1419
+ beta && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1420
+ BetaTag,
1421
+ {
1422
+ $bg: theme.colors.overlay.mono,
1423
+ $color: theme.colors.content.tertiary,
1424
+ $radius: sizing.radius,
1425
+ children: "Beta"
1426
+ }
1427
+ ),
1428
+ external && hasExternalIcon && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1429
+ ExternalIconBox,
1430
+ {
1431
+ $size: sizing.externalIconSize,
1432
+ $color: theme.colors.content.secondary,
1433
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_xui_icons_base2.OpenIn, { size: 18, variant: "line" })
1434
+ }
1435
+ )
1436
+ ]
1437
+ }
1438
+ )
1439
+ }
1440
+ );
1441
+ };
1442
+
1443
+ // src/SidebarMenuCollapsible.tsx
1444
+ var import_react3 = require("react");
1445
+ var import_styled_components6 = __toESM(require("styled-components"));
1446
+ var import_xui_core8 = require("@xsolla/xui-core");
1447
+ var import_xui_typography4 = require("@xsolla/xui-typography");
1448
+ var import_xui_icons_base3 = require("@xsolla/xui-icons-base");
1449
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1450
+ var HeaderButton = import_styled_components6.default.button`
1451
+ display: flex;
1452
+ height: ${(p) => p.$itemHeight}px;
1453
+ width: 100%;
1454
+ box-sizing: border-box;
1455
+ align-items: center;
1456
+ gap: 8px;
1457
+ padding: 0 ${(p) => p.$padding}px;
1458
+ border: 0;
1459
+ border-radius: ${(p) => p.$radius}px;
1460
+ background: transparent;
1461
+ color: ${(p) => p.$color};
1462
+ cursor: pointer;
1463
+ font-size: 14px;
1464
+ font-weight: 500;
1465
+ line-height: 18px;
1466
+ font-family: inherit;
1467
+ text-align: left;
1468
+ white-space: nowrap;
1469
+ overflow: hidden;
1470
+ transition:
1471
+ background-color 0.15s ease-in-out,
1472
+ color 0.15s ease-in-out;
1473
+
1474
+ &:hover {
1475
+ background-color: ${(p) => p.$hoverBg};
1476
+ }
1477
+
1478
+ &:focus-visible {
1479
+ outline: ${(p) => p.$focusOutlineWidth}px solid ${(p) => p.$focusOutline};
1480
+ outline-offset: -${(p) => p.$focusOutlineWidth}px;
1481
+ }
1482
+ `;
1483
+ var ExpandRegion = import_styled_components6.default.div`
1484
+ display: grid;
1485
+ grid-template-rows: ${(p) => p.$expanded ? "1fr" : "0fr"};
1486
+ transition: ${(p) => p.$transition};
1487
+
1488
+ & > div {
1489
+ overflow: hidden;
1490
+ }
1491
+
1492
+ & .${ITEM_BASE_CLASS} {
1493
+ position: relative;
1494
+ padding: 0 ${(p) => p.$padding}px 0 ${(p) => p.$nestedPaddingLeft}px;
1495
+ font-weight: 400;
1496
+
1497
+ &::before {
1498
+ content: "";
1499
+ position: absolute;
1500
+ left: ${(p) => p.$railLeft}px;
1501
+ top: 0;
1502
+ bottom: 0;
1503
+ width: 1px;
1504
+ background: ${(p) => p.$railColor};
1505
+ transform: translateX(-50%);
1506
+ }
1507
+ }
1508
+
1509
+ & .${ITEM_ACTIVE_CLASS} {
1510
+ font-weight: 500;
1511
+ color: ${(p) => p.$colorActive};
1512
+ background-color: ${(p) => p.$activeBg};
1513
+ outline: 1px solid ${(p) => p.$activeOutline};
1514
+ outline-offset: -1px;
1515
+ }
1516
+ `;
1517
+ var IconBox2 = import_styled_components6.default.div`
1518
+ display: flex;
1519
+ width: ${(p) => p.$size}px;
1520
+ height: ${(p) => p.$size}px;
1521
+ flex-shrink: 0;
1522
+ align-items: center;
1523
+ justify-content: center;
1524
+ color: inherit;
1525
+
1526
+ svg {
1527
+ width: ${(p) => p.$size}px;
1528
+ height: ${(p) => p.$size}px;
1529
+ }
1530
+ `;
1531
+ var LabelBox2 = import_styled_components6.default.span`
1532
+ display: flex;
1533
+ flex: 1;
1534
+ gap: 4px;
1535
+ height: 20px;
1536
+ align-items: center;
1537
+ min-width: 0;
1538
+ overflow: hidden;
1539
+ text-overflow: ellipsis;
1540
+ `;
1541
+ var ChevronBox = import_styled_components6.default.span`
1542
+ display: flex;
1543
+ width: ${(p) => p.$size}px;
1544
+ height: ${(p) => p.$size}px;
1545
+ flex-shrink: 0;
1546
+ align-items: center;
1547
+ justify-content: center;
1548
+ margin-left: auto;
1549
+ color: inherit;
1550
+
1551
+ svg {
1552
+ width: ${(p) => p.$size}px;
1553
+ height: ${(p) => p.$size}px;
1554
+ }
1555
+ `;
1556
+ var computeRouteMatch = (pathname, matchPaths) => {
1557
+ if (matchPaths.length === 0) {
1558
+ return false;
1559
+ }
1560
+ const pathWithoutMerchant = pathname.replace(/^\/\d+/, "");
1561
+ return matchPaths.some((p) => {
1562
+ if (p === "/") return pathWithoutMerchant === "/";
1563
+ return pathWithoutMerchant === p || pathWithoutMerchant.startsWith(`${p}/`);
1564
+ });
1565
+ };
1566
+ var SidebarMenuCollapsible = ({
1567
+ icon,
1568
+ label,
1569
+ dataId,
1570
+ matchPaths = [],
1571
+ children
1572
+ }) => {
1573
+ const { pathname, expandedId, onExpandedIdChange } = useSidebar();
1574
+ const { theme } = (0, import_xui_core8.useResolvedTheme)();
1575
+ const sizing = theme.sizing.sidebar();
1576
+ const idRef = (0, import_react3.useRef)();
1577
+ if (!idRef.current) {
1578
+ idRef.current = dataId || `sb-collapsible-${Math.random().toString(36).slice(2, 10)}`;
1579
+ }
1580
+ const collapsibleId = idRef.current;
1581
+ const contentId = `sidebar-collapsible-${collapsibleId}`;
1582
+ const matchKey = matchPaths.join("|");
1583
+ const isRouteMatch = (0, import_react3.useMemo)(
1584
+ () => computeRouteMatch(pathname, matchPaths),
1585
+ [pathname, matchKey, matchPaths]
1586
+ );
1587
+ const prevMatchRef = (0, import_react3.useRef)(isRouteMatch);
1588
+ (0, import_react3.useEffect)(() => {
1589
+ if (prevMatchRef.current !== isRouteMatch) {
1590
+ prevMatchRef.current = isRouteMatch;
1591
+ if (isRouteMatch) {
1592
+ onExpandedIdChange(collapsibleId);
1593
+ }
1594
+ }
1595
+ }, [isRouteMatch, collapsibleId, onExpandedIdChange]);
1596
+ const mountRef = (0, import_react3.useRef)(true);
1597
+ (0, import_react3.useEffect)(() => {
1598
+ if (mountRef.current && isRouteMatch) {
1599
+ onExpandedIdChange(collapsibleId);
1600
+ mountRef.current = false;
1601
+ }
1602
+ }, [isRouteMatch, collapsibleId, onExpandedIdChange]);
1603
+ const isExpanded = expandedId === collapsibleId;
1604
+ const handleToggle = () => {
1605
+ onExpandedIdChange(isExpanded ? null : collapsibleId);
1606
+ };
1607
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1608
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
1609
+ HeaderButton,
1610
+ {
1611
+ type: "button",
1612
+ onClick: handleToggle,
1613
+ "data-id": dataId,
1614
+ "aria-expanded": isExpanded,
1615
+ "aria-controls": contentId,
1616
+ $itemHeight: sizing.itemHeight,
1617
+ $padding: sizing.padding,
1618
+ $radius: sizing.radius,
1619
+ $color: theme.colors.content.tertiary,
1620
+ $hoverBg: theme.colors.control.mono.secondary.bgHover,
1621
+ $focusOutline: theme.colors.border.brand,
1622
+ $focusOutlineWidth: sizing.focusOutlineWidth,
1623
+ children: [
1624
+ icon && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconBox2, { $size: sizing.iconSize, children: icon }),
1625
+ /* @__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 }) }),
1626
+ /* @__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" }) })
1627
+ ]
1628
+ }
1629
+ ),
1630
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1631
+ ExpandRegion,
1632
+ {
1633
+ id: contentId,
1634
+ role: "region",
1635
+ $expanded: isExpanded,
1636
+ $transition: sizing.transitionRows,
1637
+ $padding: sizing.padding,
1638
+ $nestedPaddingLeft: sizing.nestedItemPaddingLeft,
1639
+ $railLeft: sizing.nestedItemRailLeft,
1640
+ $railColor: theme.colors.border.secondary,
1641
+ $colorActive: theme.colors.content.primary,
1642
+ $activeBg: theme.colors.overlay.mono,
1643
+ $activeOutline: theme.colors.border.secondary,
1644
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { children })
1645
+ }
1646
+ )
1647
+ ] });
1648
+ };
1649
+
1650
+ // src/SidebarMenuSub.tsx
1651
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1652
+ var SidebarMenuSub = ({
1653
+ children
1654
+ }) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_jsx_runtime13.Fragment, { children });
1655
+
1656
+ // src/SidebarChatButton.tsx
1657
+ var import_styled_components7 = __toESM(require("styled-components"));
1658
+ var import_xui_core9 = require("@xsolla/xui-core");
1659
+ var import_xui_typography5 = require("@xsolla/xui-typography");
1660
+ var import_xui_icons_base4 = require("@xsolla/xui-icons-base");
1661
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1662
+ var ChatButton = import_styled_components7.default.button`
1663
+ display: flex;
1664
+ height: ${(p) => p.$height}px;
1665
+ align-items: center;
1666
+ gap: 8px;
1667
+ padding: 0 ${(p) => p.$padding}px;
1668
+ border: 1px solid ${(p) => p.$border};
1669
+ border-radius: ${(p) => p.$radius}px;
1670
+ background: ${(p) => p.$bg};
1671
+ color: ${(p) => p.$color};
1672
+ cursor: pointer;
1673
+ font: inherit;
1674
+ position: relative;
1675
+
1676
+ &:hover {
1677
+ opacity: 0.9;
1678
+ }
1679
+
1680
+ &:focus-visible {
1681
+ outline: ${(p) => p.$focusOutlineWidth}px solid ${(p) => p.$focusOutline};
1682
+ outline-offset: 2px;
1683
+ }
1684
+
1685
+ svg {
1686
+ width: 16px;
1687
+ height: 16px;
1688
+ }
1689
+ `;
1690
+ var Badge = import_styled_components7.default.span`
1691
+ position: absolute;
1692
+ top: -2px;
1693
+ right: -2px;
1694
+ width: ${(p) => p.$size}px;
1695
+ height: ${(p) => p.$size}px;
1696
+ background: ${(p) => p.$color};
1697
+ border-radius: 999px;
1698
+ `;
1699
+ var SidebarChatButton = ({
1700
+ onClick,
1701
+ badge
1702
+ }) => {
1703
+ const { theme } = (0, import_xui_core9.useResolvedTheme)();
1704
+ const sizing = theme.sizing.sidebar();
1705
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1706
+ ChatButton,
1707
+ {
1708
+ onClick,
1709
+ type: "button",
1710
+ $height: sizing.itemHeight,
1711
+ $padding: sizing.padding,
1712
+ $radius: sizing.radius,
1713
+ $bg: theme.colors.control.brand.primary.bg,
1714
+ $border: theme.colors.control.brand.primary.border,
1715
+ $color: theme.colors.content.static.dark,
1716
+ $focusOutline: theme.colors.border.brand,
1717
+ $focusOutlineWidth: sizing.focusOutlineWidth,
1718
+ children: [
1719
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_xui_icons_base4.ChatTwoMessages, { size: 16, variant: "line" }),
1720
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_xui_typography5.Typography, { variant: "bodySmAccent", color: "inherit", children: "Chat" }),
1721
+ badge && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1722
+ Badge,
1723
+ {
1724
+ $size: sizing.chatBadgeSize,
1725
+ $color: theme.colors.background.alert.primary
1726
+ }
1727
+ )
1728
+ ]
1729
+ }
1730
+ );
1731
+ };
1732
+ // Annotate the CommonJS export names for ESM import in node:
1733
+ 0 && (module.exports = {
1734
+ Sidebar,
1735
+ SidebarChatButton,
1736
+ SidebarCollapsed,
1737
+ SidebarContent,
1738
+ SidebarFooter,
1739
+ SidebarGroup,
1740
+ SidebarMenu,
1741
+ SidebarMenuCollapsible,
1742
+ SidebarMenuItem,
1743
+ SidebarMenuSub,
1744
+ SidebarProvider,
1745
+ SidebarTrigger,
1746
+ useSidebar
1747
+ });
1748
+ //# sourceMappingURL=index.js.map