-
-
Notifications
You must be signed in to change notification settings - Fork 66
/
Copy pathNavLink.tsx
130 lines (119 loc) · 4.19 KB
/
NavLink.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import {
MantineColor,
NavLink as MantineNavLink,
MantineSize,
} from "@mantine/core";
import { BoxProps } from "props/box";
import { DashBaseProps, PersistenceProps } from "props/dash";
import { StylesApiProps } from "props/styles";
import React, { MouseEvent, useState, useEffect } from "react";
import { TargetProps, onClick } from "../../utils/anchor";
import { History } from '@plotly/dash-component-plugins';
import { setPersistence, getLoadingState } from "../../utils/dash3";
interface Props
extends BoxProps,
StylesApiProps,
DashBaseProps,
PersistenceProps {
/** Main link label */
label?: React.ReactNode;
/** Link description, displayed below the label */
description?: React.ReactNode;
/** Section displayed on the left side of the label */
leftSection?: React.ReactNode;
/** Section displayed on the right side of the label */
rightSection?: React.ReactNode;
/**
* Controls whether the link is styled as active (default: `false`).
* - `exact`: Active if `pathname` matches `href` exactly.
* - `partial`: Active if `pathname` starts with `href` (for subpages).
*/
active?: boolean | 'exact' | 'partial';
/** Key of `theme.colors` of any valid CSS color to control active styles, `theme.primaryColor` by default */
color?: MantineColor;
/** href */
href?: string;
/** Target */
target?: TargetProps;
/** If set, label and description will not wrap to the next line, `false` by default */
noWrap?: boolean;
/** Child `NavLink` components */
children?: React.ReactNode;
/** Controlled nested items collapse state */
opened?: boolean;
/** If set, right section will not be rotated when collapse is opened, `false` by default */
disableRightSectionRotation?: boolean;
/** Key of `theme.spacing` or any valid CSS value to set collapsed links `padding-left`, `'lg'` by default */
childrenOffset?: MantineSize | (string & {}) | number;
/** If set, disabled styles will be added to the root element, `false` by default */
disabled?: boolean;
/** Determines whether button text color with filled variant should depend on `background-color`. If luminosity of the `color` prop is less than `theme.luminosityThreshold`, then `theme.white` will be used for text color, otherwise `theme.black`. Overrides `theme.autoContrast`. */
autoContrast?: boolean;
/** An integer that represents the number of times that this element has been clicked on */
n_clicks?: number;
/** Whether to refresh the page */
refresh?: boolean;
}
/** NavLink */
const NavLink = ({
disabled,
href,
target,
refresh,
n_clicks = 0,
children,
persistence,
persisted_props,
persistence_type,
setProps,
loading_state,
active = false,
...others
}: Props) => {
const [linkActive, setLinkActive] = useState(false);
const pathnameToActive = pathname => {
setLinkActive(
active === true ||
(active === 'exact' && pathname === href) ||
(active === 'partial' && (pathname.startsWith(href + '/') || pathname === href))
);
};
useEffect(() => {
pathnameToActive(window.location.pathname);
if (typeof active === 'string') {
History.onChange(() => {
pathnameToActive(window.location.pathname);
});
}
}, [active]);
const onChange = (state: boolean) => {
setProps({ opened: state });
};
const increment = () => {
if (!disabled) {
setProps({
n_clicks: n_clicks + 1,
});
}
};
return (
<MantineNavLink
data-dash-is-loading={getLoadingState(loading_state) || undefined}
component="a"
onClick={(ev: MouseEvent<HTMLAnchorElement>) => {
increment();
onClick(ev, href, target, refresh);
}}
href={href}
target={target}
onChange={onChange}
disabled={disabled}
active={linkActive}
{...others}
>
{children}
</MantineNavLink>
);
};
setPersistence(NavLink, ["opened"])
export default NavLink;