fix sidebar
This commit is contained in:
parent
70d99473e1
commit
9bd798188d
@ -839,3 +839,9 @@ function UsersTable({ data, columns }) {
|
||||
```
|
||||
|
||||
`Sidebar.Exit` از `logoutKeycloak` داخلی UI Kit استفاده میکند و callback خروج از سامانه مقصد نیاز ندارد.
|
||||
|
||||
### Sidebar active route notes
|
||||
|
||||
`Sidebar` compares `currentPath` with each item's `path` and `aliases`, ignoring query strings, hashes, and trailing slashes. Use the actual application route as `path`; use `aliases` only for alternate routes that should keep the same item active.
|
||||
|
||||
Active sidebar items are rendered as non-links to avoid redundant same-route navigations. This is especially useful on pages that synchronize URL query params.
|
||||
|
||||
358
dist/layout.js
vendored
358
dist/layout.js
vendored
File diff suppressed because one or more lines are too long
@ -25,9 +25,19 @@ import { IoExit } from "react-icons/io5/index.js";
|
||||
import { logoutKeycloak } from "../core/keycloak.jsx";
|
||||
import { usePermission } from "../core/permission.jsx";
|
||||
|
||||
const normalizeSidebarPath = (value = "") => {
|
||||
const path = String(value).split(/[?#]/)[0] || "";
|
||||
|
||||
if (!path || path === "/") return path || "/";
|
||||
|
||||
return path.replace(/\/+$/, "");
|
||||
};
|
||||
|
||||
export const isSidebarPathActive = (currentPath, item) => {
|
||||
const normalizedPath = currentPath?.split("?")[0] || "";
|
||||
const candidatePaths = [item?.path, ...(item?.aliases || [])].filter(Boolean);
|
||||
const normalizedPath = normalizeSidebarPath(currentPath);
|
||||
const candidatePaths = [item?.path, ...(item?.aliases || [])]
|
||||
.filter(Boolean)
|
||||
.map(normalizeSidebarPath);
|
||||
|
||||
return candidatePaths.some(
|
||||
(path) => normalizedPath === path || normalizedPath.startsWith(`${path}/`),
|
||||
@ -58,19 +68,39 @@ const DesktopNavItem = ({
|
||||
linkComponent,
|
||||
onNavigate,
|
||||
}) => {
|
||||
const content = (
|
||||
<IconButton
|
||||
variant="ghost"
|
||||
icon={<Icon as={item.icon} />}
|
||||
fontSize="xl"
|
||||
size={{ base: "sm", lg: "lg" }}
|
||||
isDisabled={isDisabled}
|
||||
isActive={isActive}
|
||||
aria-label={item.title}
|
||||
aria-current={isActive ? "page" : undefined}
|
||||
onClick={isDisabled ? undefined : onNavigate}
|
||||
/>
|
||||
);
|
||||
const commonProps = {
|
||||
variant: isActive ? "solid" : "ghost",
|
||||
colorScheme: isActive ? "blue" : undefined,
|
||||
icon: <Icon as={item.icon} />,
|
||||
fontSize: "xl",
|
||||
size: { base: "sm", lg: "lg" },
|
||||
"aria-label": item.title,
|
||||
"aria-current": isActive ? "page" : undefined,
|
||||
};
|
||||
|
||||
let content;
|
||||
|
||||
if (isDisabled || isActive) {
|
||||
content = (
|
||||
<IconButton
|
||||
{...commonProps}
|
||||
isDisabled={isDisabled}
|
||||
cursor={isActive && !isDisabled ? "default" : undefined}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
const linkProps = linkComponent
|
||||
? { as: linkComponent, href: item.path }
|
||||
: { as: "a", href: item.path };
|
||||
|
||||
content = (
|
||||
<IconButton
|
||||
{...commonProps}
|
||||
{...linkProps}
|
||||
onClick={onNavigate}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
@ -83,17 +113,7 @@ const DesktopNavItem = ({
|
||||
fontWeight="bold"
|
||||
closeDelay={150}
|
||||
>
|
||||
{isDisabled ? (
|
||||
<Box as="span">{content}</Box>
|
||||
) : (
|
||||
<SidebarLink
|
||||
linkComponent={linkComponent}
|
||||
href={item.path}
|
||||
_hover={{ textDecoration: "none" }}
|
||||
>
|
||||
{content}
|
||||
</SidebarLink>
|
||||
)}
|
||||
<Box as="span">{content}</Box>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
@ -134,14 +154,15 @@ const MobileNavigationButton = ({
|
||||
</VStack>
|
||||
);
|
||||
|
||||
if (isDisabled) {
|
||||
if (isDisabled || isActive) {
|
||||
return (
|
||||
<Box
|
||||
flex="1"
|
||||
minW={0}
|
||||
display="flex"
|
||||
alignItems="center"
|
||||
aria-disabled="true"
|
||||
aria-disabled={isDisabled ? "true" : undefined}
|
||||
aria-current={isActive ? "page" : undefined}
|
||||
>
|
||||
{content}
|
||||
</Box>
|
||||
@ -398,8 +419,16 @@ const SidebarRoot = ({
|
||||
</VStack>
|
||||
);
|
||||
|
||||
if (isDisabled) {
|
||||
return <Box key={item.path}>{content}</Box>;
|
||||
if (isDisabled || isActive) {
|
||||
return (
|
||||
<Box
|
||||
key={item.path}
|
||||
aria-disabled={isDisabled ? "true" : undefined}
|
||||
aria-current={isActive ? "page" : undefined}
|
||||
>
|
||||
{content}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user