1 | import { css } from '@emotion/css';
|
2 | import { useFocusRing } from '@spark-web/a11y';
|
3 | import { Box } from '@spark-web/box';
|
4 | import { useLinkComponent } from '@spark-web/link';
|
5 | import { Text } from '@spark-web/text';
|
6 | import { useTheme } from '@spark-web/theme';
|
7 | import { forwardRef, Children, isValidElement, cloneElement } from 'react';
|
8 | import { jsx } from 'react/jsx-runtime';
|
9 |
|
10 | var NavLink = forwardRef(function (_ref, forwardedRef) {
|
11 | var _ref$borderRadius = _ref.borderRadius,
|
12 | borderRadius = _ref$borderRadius === void 0 ? 'small' : _ref$borderRadius,
|
13 | children = _ref.children,
|
14 | data = _ref.data,
|
15 | href = _ref.href,
|
16 | _ref$inline = _ref.inline,
|
17 | inline = _ref$inline === void 0 ? false : _ref$inline,
|
18 | _ref$isSelected = _ref.isSelected,
|
19 | isSelected = _ref$isSelected === void 0 ? false : _ref$isSelected,
|
20 | _ref$size = _ref.size,
|
21 | size = _ref$size === void 0 ? 'medium' : _ref$size;
|
22 | var linkComponent = useLinkComponent(forwardedRef);
|
23 | var styles = useNavLinkStyles(isSelected);
|
24 | return jsx(Box, {
|
25 | as: linkComponent,
|
26 | asElement: "a",
|
27 | href: href,
|
28 | "aria-current": isSelected ? 'page' : undefined,
|
29 | data: data
|
30 |
|
31 | ,
|
32 | background: isSelected ? 'primaryMuted' : undefined,
|
33 | display: inline ? 'inline-flex' : 'flex',
|
34 | alignItems: "center",
|
35 | gap: "small",
|
36 | paddingY: "small",
|
37 | paddingX: "medium",
|
38 | borderRadius: {
|
39 | tablet: borderRadius
|
40 | },
|
41 | className: css(styles),
|
42 | children: resolveNavLinkChildren({
|
43 | children: children,
|
44 | isSelected: isSelected,
|
45 | size: size
|
46 | })
|
47 | });
|
48 | });
|
49 | NavLink.displayName = 'NavLink';
|
50 | function useNavLinkStyles(isSelected) {
|
51 | var theme = useTheme();
|
52 | var focusRingStyles = useFocusRing();
|
53 | return {
|
54 | ':focus': focusRingStyles,
|
55 | ':hover': {
|
56 | backgroundColor: isSelected ? theme.backgroundInteractions.primaryLowHover : theme.color.background.surfaceMuted,
|
57 | '> *': {
|
58 | color: isSelected ? theme.color.foreground.primaryHover : undefined,
|
59 | stroke: isSelected ? theme.color.foreground.primaryHover : undefined
|
60 | }
|
61 | },
|
62 | ':active': {
|
63 | backgroundColor: isSelected ? theme.backgroundInteractions.positiveLowActive : theme.color.background.surfacePressed,
|
64 | '> *': {
|
65 | color: isSelected ? theme.color.foreground.primaryActive : undefined,
|
66 | stroke: isSelected ? theme.color.foreground.primaryActive : undefined
|
67 | }
|
68 | }
|
69 | };
|
70 | }
|
71 | function resolveNavLinkChildren(_ref2) {
|
72 | var children = _ref2.children,
|
73 | isSelected = _ref2.isSelected,
|
74 | size = _ref2.size;
|
75 | return Children.map(children, function (child) {
|
76 | if (typeof child === 'string') {
|
77 | return jsx(Text, {
|
78 | as: "span",
|
79 | baseline: false,
|
80 | overflowStrategy: "nowrap",
|
81 | weight: "semibold",
|
82 | size: mapTextSize[size],
|
83 | tone: isSelected ? 'primaryActive' : 'muted',
|
84 | children: child
|
85 | });
|
86 | }
|
87 | if ( isValidElement(child)) {
|
88 | return cloneElement(child, {
|
89 | size: 'xxsmall',
|
90 | tone: isSelected ? 'primaryActive' : 'muted'
|
91 | });
|
92 | }
|
93 | return null;
|
94 | });
|
95 | }
|
96 | var mapTextSize = {
|
97 | medium: 'small',
|
98 | large: 'standard'
|
99 | };
|
100 |
|
101 | export { NavLink };
|