- {banner &&
{banner}
}
-
- {sidebar && sidebarPosition === 'left' &&
{sidebar}
}
- {body &&
{body}
}
- {sidebar && sidebarPosition === 'right' &&
{sidebar}
}
+
+ {/* Main content area */}
+
+
+ {banner &&
{banner}
}
+
+ {sidebar && sidebarPosition === 'left' &&
{sidebar}
}
+ {body &&
{body}
}
+ {sidebar && sidebarPosition === 'right' &&
{sidebar}
}
+
diff --git a/os-league-tools-master/src/components/common/SideBar.js b/os-league-tools-master/src/components/common/SideBar.js
new file mode 100644
index 00000000..f6685c86
--- /dev/null
+++ b/os-league-tools-master/src/components/common/SideBar.js
@@ -0,0 +1,315 @@
+import React, { useRef } from 'react';
+import { Link, NavLink } from 'react-router-dom';
+import _ from 'lodash';
+import useBreakpoint, { MEDIA_QUERIES, MODE } from '../../hooks/useBreakpoint';
+import useClickListener from '../../hooks/useClickListener';
+import { useSidebar } from '../../context/SidebarContext';
+
+// Re-export NavItem from NavBar for convenience
+export { NavItem } from './NavBar';
+
+// Group NavItems by their variant (slot)
+function groupNavItemsByVariant(navItems) {
+ const groups = {};
+ for (const item of navItems) {
+ const variant = item.variant || item.props?.slot || 'primary';
+ if (groups[variant]) {
+ groups[variant].push(item);
+ } else {
+ groups[variant] = [item];
+ }
+ }
+ return groups;
+}
+
+export default function SideBar({ navItems, brandName, brandLogo }) {
+ const { isCollapsed, toggleCollapse, isDrawerOpen, closeDrawer } = useSidebar();
+ const isDesktop = useBreakpoint(MEDIA_QUERIES.LG, MODE.GREATER_OR_EQ);
+ const drawerRef = useRef(null);
+
+ useClickListener(drawerRef, closeDrawer, true);
+
+ const {
+ primary: primaryNavItems,
+ secondary: secondaryNavItems,
+ overflow: overflowNavItems,
+ } = groupNavItemsByVariant(navItems);
+
+ // Group overflow items by collapseGroup for organization
+ const overflowGroups = getCollapseGroups(overflowNavItems || []);
+
+ // Desktop sidebar
+ if (isDesktop) {
+ return (
+
+ );
+ }
+
+ // Mobile: header + drawer
+ return (
+ <>
+
+
+
+ >
+ );
+}
+
+function SideBarBrand({ logo, name, isCollapsed }) {
+ return (
+
+

+ {!isCollapsed &&
{name}}
+
+ );
+}
+
+function SideBarSection({ title, children }) {
+ return (
+
+ {title &&
{title}
}
+ {children}
+
+ );
+}
+
+function SideBarDivider() {
+ return
;
+}
+
+function SideBarLink({ item, isCollapsed, onClick }) {
+ // If item has a custom render function for sidebar, use it
+ if (item.renderSidebarFn) {
+ return item.renderSidebarFn(isCollapsed, onClick);
+ }
+
+ // If item has a standard render function, use it with modifications
+ if (item.renderFn) {
+ return item.renderFn(isCollapsed, onClick);
+ }
+
+ const icon = item.iconFont && (
+
{item.iconFont}
+ );
+ const label = !isCollapsed &&
{item.label};
+
+ // External link
+ if (item.href) {
+ return (
+
+ {icon}
+ {label}
+
+ );
+ }
+
+ // Router link
+ if (item.to) {
+ return (
+
`sidebar-nav-link ${isActive ? 'active' : ''}`}
+ to={item.to}
+ onClick={onClick}
+ title={isCollapsed ? item.label : undefined}
+ >
+ {icon}
+ {label}
+
+ );
+ }
+
+ // Button with onClick
+ if (item.onClick) {
+ return (
+
+ );
+ }
+
+ return null;
+}
+
+function MobileHeader({ logo, name }) {
+ const { openDrawer } = useSidebar();
+
+ return (
+
+
+
+
+ {name}
+
+
+ );
+}
+
+function SideBarDrawer({
+ innerRef,
+ isOpen,
+ brandLogo,
+ brandName,
+ primaryNavItems,
+ secondaryNavItems,
+ overflowGroups,
+ onClose,
+}) {
+ return (
+
+ );
+}
+
+function SideBarBackdrop({ isOpen, onClick }) {
+ return (
+
+ );
+}
+
+function getCollapseGroups(items) {
+ const groupMapping = {};
+ for (const navItem of items) {
+ const groupId = navItem.collapseGroup || -1;
+ if (groupMapping[groupId]) {
+ groupMapping[groupId].push(navItem);
+ } else {
+ groupMapping[groupId] = [navItem];
+ }
+ }
+
+ const sortedIds = Object.keys(groupMapping).sort();
+ const groups = [];
+ for (const groupId of sortedIds) {
+ const sortedGroup = _.sortBy(groupMapping[groupId], ['collapseOrder']);
+ groups.push(sortedGroup);
+ }
+ return groups;
+}
diff --git a/os-league-tools-master/src/components/nav/Character.js b/os-league-tools-master/src/components/nav/Character.js
index 50a3ceb9..a5f01af2 100644
--- a/os-league-tools-master/src/components/nav/Character.js
+++ b/os-league-tools-master/src/components/nav/Character.js
@@ -133,4 +133,89 @@ function HiscoresIcon({ isHiscoreError }) {
);
}
-export default { NavBarItem, CollapsedMenu };
+function SideBarItem({ setCharacterModalOpen, isCollapsed, onNavigate }) {
+ const [isExpanded, setExpanded] = useState(false);
+ const dispatch = useDispatch();
+ const menuRef = useRef(null);
+ const characterState = useSelector(state => state.character);
+ const activeCharacter = characterState.characters[characterState.activeCharacter];
+ const isHiscoreError = !!characterState.hiscoresCache.error;
+
+ useClickListener(menuRef, () => setExpanded(false), true);
+
+ if (!activeCharacter) {
+ return (
+
+ );
+ }
+
+ return (
+
+
+ {isExpanded && !isCollapsed && (
+
+
+
+
+ )}
+
+ );
+}
+
+export default { NavBarItem, CollapsedMenu, SideBarItem };
diff --git a/os-league-tools-master/src/components/nav/Feedback.js b/os-league-tools-master/src/components/nav/Feedback.js
index 5b4d280d..9ab1825f 100644
--- a/os-league-tools-master/src/components/nav/Feedback.js
+++ b/os-league-tools-master/src/components/nav/Feedback.js
@@ -28,4 +28,23 @@ function CollapsedMenu({ setFeedbackModalOpen }) {
);
}
-export default { NavBarItem, CollapsedMenu };
+function SideBarItem({ setFeedbackModalOpen, isCollapsed, onNavigate }) {
+ return (
+
+ );
+}
+
+export default { NavBarItem, CollapsedMenu, SideBarItem };
diff --git a/os-league-tools-master/src/components/nav/ManageData.js b/os-league-tools-master/src/components/nav/ManageData.js
index 100b36fa..c99c0686 100644
--- a/os-league-tools-master/src/components/nav/ManageData.js
+++ b/os-league-tools-master/src/components/nav/ManageData.js
@@ -81,4 +81,75 @@ function CollapsedMenu({ setManageDataModalType }) {
);
}
-export default { NavBarItem, CollapsedMenu };
+function SideBarItem({ setManageDataModalType, isCollapsed, onNavigate }) {
+ const [isExpanded, setExpanded] = useState(false);
+ const menuRef = useRef(null);
+ useClickListener(menuRef, () => setExpanded(false), true);
+
+ return (
+
+
+ {isExpanded && !isCollapsed && (
+
+
+
+
+
+ )}
+
+ );
+}
+
+export default { NavBarItem, CollapsedMenu, SideBarItem };
diff --git a/os-league-tools-master/src/context/SidebarContext.js b/os-league-tools-master/src/context/SidebarContext.js
new file mode 100644
index 00000000..1182dd0e
--- /dev/null
+++ b/os-league-tools-master/src/context/SidebarContext.js
@@ -0,0 +1,48 @@
+import React, { createContext, useContext, useState, useEffect, useMemo, useCallback } from 'react';
+
+const SidebarContext = createContext();
+
+const STORAGE_KEY = 'sidebar-collapsed';
+
+export function SidebarProvider({ children }) {
+ const [isCollapsed, setIsCollapsed] = useState(() => {
+ const stored = localStorage.getItem(STORAGE_KEY);
+ return stored === 'true';
+ });
+ const [isDrawerOpen, setIsDrawerOpen] = useState(false);
+
+ useEffect(() => {
+ localStorage.setItem(STORAGE_KEY, isCollapsed);
+ }, [isCollapsed]);
+
+ const toggleCollapse = useCallback(() => setIsCollapsed(prev => !prev), []);
+ const toggleDrawer = useCallback(() => setIsDrawerOpen(prev => !prev), []);
+ const closeDrawer = useCallback(() => setIsDrawerOpen(false), []);
+ const openDrawer = useCallback(() => setIsDrawerOpen(true), []);
+
+ const value = useMemo(
+ () => ({
+ isCollapsed,
+ setIsCollapsed,
+ isDrawerOpen,
+ setIsDrawerOpen,
+ toggleCollapse,
+ toggleDrawer,
+ closeDrawer,
+ openDrawer,
+ }),
+ [isCollapsed, isDrawerOpen, toggleCollapse, toggleDrawer, closeDrawer, openDrawer]
+ );
+
+ return
{children};
+}
+
+export function useSidebar() {
+ const context = useContext(SidebarContext);
+ if (!context) {
+ throw new Error('useSidebar must be used within a SidebarProvider');
+ }
+ return context;
+}
+
+export default SidebarContext;
diff --git a/os-league-tools-master/src/styles/compiled.css b/os-league-tools-master/src/styles/compiled.css
index 0b08b7f3..97713a87 100644
--- a/os-league-tools-master/src/styles/compiled.css
+++ b/os-league-tools-master/src/styles/compiled.css
@@ -2180,6 +2180,459 @@ select[multiple]:focus option:checked {
box-shadow: inset 0px -7px 5px -5px var(--tw-shadow-color), 3px -3px 3px -3px var(--tw-shadow-color),
-3px -3px 3px -3px var(--tw-shadow-color);
}
+/* SIDEBAR NAVIGATION */
+.sidebar-nav {
+ position: fixed;
+ left: 0px;
+ top: 0px;
+ z-index: 20;
+ height: 100%;
+ --tw-bg-opacity: 1;
+ background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
+}
+.sidebar-nav:is(.dark *) {
+ --tw-bg-opacity: 1;
+ background-color: rgb(63 63 70 / var(--tw-bg-opacity, 1));
+}
+.sidebar-nav {
+ display: flex;
+ flex-direction: column;
+ transition-property: all;
+ transition-duration: 300ms;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ --tw-border-opacity: 1;
+ border-color: rgb(209 213 219 / var(--tw-border-opacity, 1));
+}
+.sidebar-nav:is(.dark *) {
+ --tw-border-opacity: 1;
+ border-color: rgb(113 113 122 / var(--tw-border-opacity, 1));
+}
+.sidebar-nav {
+ border-right-width: 1px;
+}
+.sidebar-nav-expanded {
+ width: 16rem;
+}
+.sidebar-nav-collapsed {
+ width: 4rem;
+}
+.sidebar-nav-brand {
+ --tw-border-opacity: 1;
+ border-color: rgb(209 213 219 / var(--tw-border-opacity, 1));
+}
+.sidebar-nav-brand:is(.dark *) {
+ --tw-border-opacity: 1;
+ border-color: rgb(113 113 122 / var(--tw-border-opacity, 1));
+}
+.sidebar-nav-brand {
+ display: flex;
+ height: 4rem;
+ align-items: center;
+ border-bottom-width: 1px;
+ padding: 1rem;
+}
+.sidebar-nav-brand-logo {
+ height: 2rem;
+ width: 2rem;
+ flex-shrink: 0;
+}
+.sidebar-nav-brand-text {
+ --tw-text-opacity: 1;
+ color: rgb(0 0 0 / var(--tw-text-opacity, 1));
+}
+.sidebar-nav-brand-text:is(.dark *) {
+ --tw-text-opacity: 1;
+ color: rgb(244 244 245 / var(--tw-text-opacity, 1));
+}
+.sidebar-nav-brand-text {
+ margin-left: 0.75rem;
+ font-size: 1.125rem;
+ line-height: 1.75rem;
+ font-weight: 600;
+ text-transform: uppercase;
+ overflow: hidden;
+ white-space: nowrap;
+}
+.sidebar-nav-content {
+ flex: 1 1 0%;
+ overflow-y: auto;
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+}
+.sidebar-nav-section {
+ padding-top: 0.25rem;
+ padding-bottom: 0.25rem;
+}
+.sidebar-nav-section-header {
+ --tw-text-opacity: 1;
+ color: rgb(55 65 81 / var(--tw-text-opacity, 1));
+}
+.sidebar-nav-section-header:is(.dark *) {
+ --tw-text-opacity: 1;
+ color: rgb(161 161 170 / var(--tw-text-opacity, 1));
+}
+.sidebar-nav-section-header {
+ padding-left: 1rem;
+ padding-right: 1rem;
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+ font-size: 0.75rem;
+ line-height: 1rem;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ overflow: hidden;
+ white-space: nowrap;
+}
+.sidebar-nav-link {
+ --tw-text-opacity: 1;
+ color: rgb(0 0 0 / var(--tw-text-opacity, 1));
+}
+.sidebar-nav-link:is(.dark *) {
+ --tw-text-opacity: 1;
+ color: rgb(244 244 245 / var(--tw-text-opacity, 1));
+}
+.sidebar-nav-link {
+ display: flex;
+ align-items: center;
+ padding-left: 1rem;
+ padding-right: 1rem;
+ padding-top: 0.75rem;
+ padding-bottom: 0.75rem;
+ cursor: pointer;
+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 150ms;
+}
+.sidebar-nav-link:hover:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgb(229 231 235 / var(--tw-bg-opacity, 1));
+}
+.sidebar-nav-link:hover:hover:is(.dark *) {
+ --tw-bg-opacity: 1;
+ background-color: rgb(39 39 42 / var(--tw-bg-opacity, 1));
+}
+.sidebar-nav-link.active {
+ --tw-bg-opacity: 1;
+ background-color: rgb(229 231 235 / var(--tw-bg-opacity, 1));
+}
+.sidebar-nav-link.active:is(.dark *) {
+ --tw-bg-opacity: 1;
+ background-color: rgb(70 70 78 / var(--tw-bg-opacity, 1));
+}
+.theme-tl-dark .sidebar-nav-link.active {
+ --tw-text-opacity: 1;
+ color: rgb(164 206 39 / var(--tw-text-opacity, 1));
+}
+.theme-tl-light .sidebar-nav-link.active {
+ --tw-text-opacity: 1;
+ color: rgb(100 144 68 / var(--tw-text-opacity, 1));
+}
+.theme-tb-dark .sidebar-nav-link.active {
+ --tw-text-opacity: 1;
+ color: rgb(229 217 147 / var(--tw-text-opacity, 1));
+}
+.theme-tb-light .sidebar-nav-link.active {
+ --tw-text-opacity: 1;
+ color: rgb(99 66 40 / var(--tw-text-opacity, 1));
+}
+.theme-sl-dark .sidebar-nav-link.active {
+ --tw-text-opacity: 1;
+ color: rgb(19 213 145 / var(--tw-text-opacity, 1));
+}
+.theme-sl-light .sidebar-nav-link.active {
+ --tw-text-opacity: 1;
+ color: rgb(0 128 118 / var(--tw-text-opacity, 1));
+}
+.theme-tr-dark .sidebar-nav-link.active {
+ --tw-text-opacity: 1;
+ color: rgb(220 139 54 / var(--tw-text-opacity, 1));
+}
+.theme-tr-light .sidebar-nav-link.active {
+ --tw-text-opacity: 1;
+ color: rgb(180 74 30 / var(--tw-text-opacity, 1));
+}
+.theme-re-dark .sidebar-nav-link.active {
+ --tw-text-opacity: 1;
+ color: rgb(32 195 254 / var(--tw-text-opacity, 1));
+}
+.theme-re-light .sidebar-nav-link.active {
+ --tw-text-opacity: 1;
+ color: rgb(3 79 146 / var(--tw-text-opacity, 1));
+}
+.theme-mono-dark .sidebar-nav-link.active {
+ --tw-text-opacity: 1;
+ color: rgb(249 250 251 / var(--tw-text-opacity, 1));
+}
+.theme-mono-light .sidebar-nav-link.active {
+ --tw-text-opacity: 1;
+ color: rgb(55 65 81 / var(--tw-text-opacity, 1));
+}
+.theme-dp-dark .sidebar-nav-link.active {
+ --tw-text-opacity: 1;
+ color: rgb(235 78 104 / var(--tw-text-opacity, 1));
+}
+.theme-dp-light .sidebar-nav-link.active {
+ --tw-text-opacity: 1;
+ color: rgb(107 28 35 / var(--tw-text-opacity, 1));
+}
+.theme-tl-dark .sidebar-nav-link.active {
+ --tw-border-opacity: 1;
+ border-color: rgb(164 206 39 / var(--tw-border-opacity, 1));
+}
+.theme-tl-light .sidebar-nav-link.active {
+ --tw-border-opacity: 1;
+ border-color: rgb(100 144 68 / var(--tw-border-opacity, 1));
+}
+.theme-tb-dark .sidebar-nav-link.active {
+ --tw-border-opacity: 1;
+ border-color: rgb(229 217 147 / var(--tw-border-opacity, 1));
+}
+.theme-tb-light .sidebar-nav-link.active {
+ --tw-border-opacity: 1;
+ border-color: rgb(99 66 40 / var(--tw-border-opacity, 1));
+}
+.theme-sl-dark .sidebar-nav-link.active {
+ --tw-border-opacity: 1;
+ border-color: rgb(19 213 145 / var(--tw-border-opacity, 1));
+}
+.theme-sl-light .sidebar-nav-link.active {
+ --tw-border-opacity: 1;
+ border-color: rgb(0 128 118 / var(--tw-border-opacity, 1));
+}
+.theme-tr-dark .sidebar-nav-link.active {
+ --tw-border-opacity: 1;
+ border-color: rgb(220 139 54 / var(--tw-border-opacity, 1));
+}
+.theme-tr-light .sidebar-nav-link.active {
+ --tw-border-opacity: 1;
+ border-color: rgb(180 74 30 / var(--tw-border-opacity, 1));
+}
+.theme-re-dark .sidebar-nav-link.active {
+ --tw-border-opacity: 1;
+ border-color: rgb(32 195 254 / var(--tw-border-opacity, 1));
+}
+.theme-re-light .sidebar-nav-link.active {
+ --tw-border-opacity: 1;
+ border-color: rgb(3 79 146 / var(--tw-border-opacity, 1));
+}
+.theme-mono-dark .sidebar-nav-link.active {
+ --tw-border-opacity: 1;
+ border-color: rgb(249 250 251 / var(--tw-border-opacity, 1));
+}
+.theme-mono-light .sidebar-nav-link.active {
+ --tw-border-opacity: 1;
+ border-color: rgb(55 65 81 / var(--tw-border-opacity, 1));
+}
+.theme-dp-dark .sidebar-nav-link.active {
+ --tw-border-opacity: 1;
+ border-color: rgb(235 78 104 / var(--tw-border-opacity, 1));
+}
+.theme-dp-light .sidebar-nav-link.active {
+ --tw-border-opacity: 1;
+ border-color: rgb(107 28 35 / var(--tw-border-opacity, 1));
+}
+.sidebar-nav-link.active {
+ border-right-width: 2px;
+}
+.sidebar-nav-link-icon {
+ flex-shrink: 0;
+ font-size: 1.25rem;
+ line-height: 1.75rem;
+}
+.sidebar-nav-link-label {
+ margin-left: 0.75rem;
+ overflow: hidden;
+ white-space: nowrap;
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+ font-size: 0.875rem;
+ line-height: 1.25rem;
+ text-transform: uppercase;
+}
+.sidebar-nav-divider {
+ --tw-bg-opacity: 1;
+ background-color: rgb(209 213 219 / var(--tw-bg-opacity, 1));
+}
+.sidebar-nav-divider:is(.dark *) {
+ --tw-bg-opacity: 1;
+ background-color: rgb(113 113 122 / var(--tw-bg-opacity, 1));
+}
+.sidebar-nav-divider {
+ margin-left: 1rem;
+ margin-right: 1rem;
+ margin-top: 0.5rem;
+ margin-bottom: 0.5rem;
+ height: 1px;
+}
+.sidebar-nav-toggle {
+ position: absolute;
+ right: -0.75rem;
+ top: 50%;
+ height: 1.5rem;
+ width: 1.5rem;
+ --tw-translate-y: -50%;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+ border-radius: 9999px;
+ --tw-bg-opacity: 1;
+ background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
+}
+.sidebar-nav-toggle:is(.dark *) {
+ --tw-bg-opacity: 1;
+ background-color: rgb(63 63 70 / var(--tw-bg-opacity, 1));
+}
+.sidebar-nav-toggle {
+ --tw-border-opacity: 1;
+ border-color: rgb(209 213 219 / var(--tw-border-opacity, 1));
+}
+.sidebar-nav-toggle:is(.dark *) {
+ --tw-border-opacity: 1;
+ border-color: rgb(113 113 122 / var(--tw-border-opacity, 1));
+}
+.sidebar-nav-toggle {
+ border-width: 1px;
+ display: flex;
+ cursor: pointer;
+ align-items: center;
+ justify-content: center;
+ transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 150ms;
+}
+.sidebar-nav-toggle:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgb(229 231 235 / var(--tw-bg-opacity, 1));
+}
+.sidebar-nav-toggle:hover:is(.dark *) {
+ --tw-bg-opacity: 1;
+ background-color: rgb(70 70 78 / var(--tw-bg-opacity, 1));
+}
+.sidebar-nav-toggle {
+ --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
+ --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
+}
+/* Mobile drawer styles */
+.sidebar-drawer-backdrop {
+ position: fixed;
+ inset: 0px;
+ z-index: 30;
+ background-color: rgb(0 0 0 / 0.5);
+ transition-property: opacity;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 300ms;
+}
+.sidebar-drawer-backdrop-hidden {
+ pointer-events: none;
+ opacity: 0;
+}
+.sidebar-drawer-backdrop-visible {
+ opacity: 1;
+}
+.sidebar-drawer {
+ position: fixed;
+ left: 0px;
+ top: 0px;
+ z-index: 40;
+ height: 100%;
+ width: 16rem;
+ --tw-bg-opacity: 1;
+ background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
+}
+.sidebar-drawer:is(.dark *) {
+ --tw-bg-opacity: 1;
+ background-color: rgb(63 63 70 / var(--tw-bg-opacity, 1));
+}
+.sidebar-drawer {
+ --tw-border-opacity: 1;
+ border-color: rgb(209 213 219 / var(--tw-border-opacity, 1));
+}
+.sidebar-drawer:is(.dark *) {
+ --tw-border-opacity: 1;
+ border-color: rgb(113 113 122 / var(--tw-border-opacity, 1));
+}
+.sidebar-drawer {
+ border-right-width: 1px;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+ transition-property: transform;
+ transition-duration: 300ms;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ display: flex;
+ flex-direction: column;
+}
+.sidebar-drawer-closed {
+ --tw-translate-x: -100%;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+.sidebar-drawer-open {
+ --tw-translate-x: 0px;
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
+}
+/* Mobile header bar */
+.mobile-header {
+ position: fixed;
+ top: 0px;
+ left: 0px;
+ right: 0px;
+ z-index: 10;
+}
+@media (min-width: 768px) {.mobile-header {
+ display: none;
+ }
+}
+.mobile-header {
+ --tw-bg-opacity: 1;
+ background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
+}
+.mobile-header:is(.dark *) {
+ --tw-bg-opacity: 1;
+ background-color: rgb(63 63 70 / var(--tw-bg-opacity, 1));
+}
+.mobile-header {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ padding: 0.75rem;
+ --tw-border-opacity: 1;
+ border-color: rgb(209 213 219 / var(--tw-border-opacity, 1));
+}
+.mobile-header:is(.dark *) {
+ --tw-border-opacity: 1;
+ border-color: rgb(113 113 122 / var(--tw-border-opacity, 1));
+}
+.mobile-header {
+ border-bottom-width: 1px;
+}
+.mobile-header-menu-btn:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgb(229 231 235 / var(--tw-bg-opacity, 1));
+}
+.mobile-header-menu-btn:hover:is(.dark *) {
+ --tw-bg-opacity: 1;
+ background-color: rgb(39 39 42 / var(--tw-bg-opacity, 1));
+}
+.mobile-header-menu-btn {
+ cursor: pointer;
+ border-radius: 0.25rem;
+ padding: 0.5rem;
+}
+/* Content offset for fixed sidebar */
+.main-content-with-sidebar {
+ transition-property: all;
+ transition-duration: 300ms;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+}
+@media (min-width: 1024px) {.main-content-sidebar-expanded {
+ margin-left: 16rem;
+ }.main-content-sidebar-collapsed {
+ margin-left: 4rem;
+ }
+}
+.main-content-mobile-header {
+ padding-top: 3.5rem;
+}
+@media (min-width: 1024px) {.main-content-mobile-header {
+ padding-top: 0px;
+ }
+}
.\!visible {
visibility: visible !important;
}
@@ -2387,6 +2840,9 @@ select[multiple]:focus option:checked {
.h-5 {
height: 1.25rem;
}
+.h-6 {
+ height: 1.5rem;
+}
.h-8 {
height: 2rem;
}
@@ -2459,6 +2915,9 @@ select[multiple]:focus option:checked {
.w-5 {
width: 1.25rem;
}
+.w-6 {
+ width: 1.5rem;
+}
.w-60 {
width: 15rem;
}
diff --git a/os-league-tools-master/src/styles/index.css b/os-league-tools-master/src/styles/index.css
index fec9d6bd..c6e79325 100644
--- a/os-league-tools-master/src/styles/index.css
+++ b/os-league-tools-master/src/styles/index.css
@@ -360,6 +360,111 @@
box-shadow: inset 0px -7px 5px -5px var(--tw-shadow-color), 3px -3px 3px -3px var(--tw-shadow-color),
-3px -3px 3px -3px var(--tw-shadow-color);
}
+ /* SIDEBAR NAVIGATION */
+ .sidebar-nav {
+ @apply fixed left-0 top-0 h-full z-20;
+ @apply bg-primary;
+ @apply flex flex-col;
+ @apply transition-all duration-300 ease-in-out;
+ @apply border-r border-subdued;
+ }
+ .sidebar-nav-expanded {
+ @apply w-64;
+ }
+ .sidebar-nav-collapsed {
+ @apply w-16;
+ }
+ .sidebar-nav-brand {
+ @apply flex items-center p-4 border-b border-subdued h-16;
+ }
+ .sidebar-nav-brand-logo {
+ @apply h-8 w-8 flex-shrink-0;
+ }
+ .sidebar-nav-brand-text {
+ @apply ml-3 text-lg font-semibold uppercase text-primary;
+ @apply whitespace-nowrap overflow-hidden;
+ }
+ .sidebar-nav-content {
+ @apply flex-1 overflow-y-auto py-2;
+ }
+ .sidebar-nav-section {
+ @apply py-1;
+ }
+ .sidebar-nav-section-header {
+ @apply px-4 py-2 text-xs uppercase tracking-wider text-secondary-alt;
+ @apply whitespace-nowrap overflow-hidden;
+ }
+ .sidebar-nav-link {
+ @apply flex items-center px-4 py-3 text-primary;
+ @apply hover:bg-hover transition-colors cursor-pointer;
+ }
+ .sidebar-nav-link.active {
+ @apply text-accent border-r-2 border-accent bg-primary-alt;
+ }
+ .sidebar-nav-link-icon {
+ @apply text-xl flex-shrink-0;
+ }
+ .sidebar-nav-link-label {
+ @apply ml-3 font-mono text-sm uppercase whitespace-nowrap overflow-hidden;
+ }
+ .sidebar-nav-divider {
+ @apply h-px mx-4 my-2 bg-subdued;
+ }
+ .sidebar-nav-toggle {
+ @apply absolute -right-3 top-1/2 -translate-y-1/2 w-6 h-6 rounded-full;
+ @apply bg-primary border border-subdued;
+ @apply flex items-center justify-center cursor-pointer;
+ @apply hover:bg-primary-alt transition-colors;
+ @apply shadow-sm;
+ }
+ .sidebar-nav-footer {
+ @apply border-t border-subdued p-2;
+ }
+ /* Mobile drawer styles */
+ .sidebar-drawer-backdrop {
+ @apply fixed inset-0 bg-black/50 z-30;
+ @apply transition-opacity duration-300;
+ }
+ .sidebar-drawer-backdrop-hidden {
+ @apply opacity-0 pointer-events-none;
+ }
+ .sidebar-drawer-backdrop-visible {
+ @apply opacity-100;
+ }
+ .sidebar-drawer {
+ @apply fixed left-0 top-0 h-full w-64 z-40;
+ @apply bg-primary border-r border-subdued;
+ @apply transform transition-transform duration-300 ease-in-out;
+ @apply flex flex-col;
+ }
+ .sidebar-drawer-closed {
+ @apply -translate-x-full;
+ }
+ .sidebar-drawer-open {
+ @apply translate-x-0;
+ }
+ /* Mobile header bar */
+ .mobile-header {
+ @apply md:hidden fixed top-0 left-0 right-0 z-10;
+ @apply bg-primary p-3 flex items-center gap-3;
+ @apply border-b border-subdued;
+ }
+ .mobile-header-menu-btn {
+ @apply p-2 bg-hover rounded cursor-pointer;
+ }
+ /* Content offset for fixed sidebar */
+ .main-content-with-sidebar {
+ @apply transition-all duration-300 ease-in-out;
+ }
+ .main-content-sidebar-expanded {
+ @apply lg:ml-64;
+ }
+ .main-content-sidebar-collapsed {
+ @apply lg:ml-16;
+ }
+ .main-content-mobile-header {
+ @apply pt-14 lg:pt-0;
+ }
}
@layer utilities {