/
ListItemLink.tsx
132 lines (126 loc) · 3.8 KB
/
ListItemLink.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
131
132
import type { AnchorHTMLAttributes, ElementType } from "react";
import { forwardRef } from "react";
import cn from "classnames";
import type { InteractionStatesOptions } from "@react-md/states";
import { useInteractionStates } from "@react-md/states";
import type { SimpleListItemProps } from "./getListItemHeight";
import { getListItemHeight } from "./getListItemHeight";
import type { ListItemChildrenProps } from "./ListItemChildren";
import { ListItemChildren } from "./ListItemChildren";
export interface ListItemLinkProps
extends AnchorHTMLAttributes<HTMLAnchorElement>,
ListItemChildrenProps,
Pick<SimpleListItemProps, "threeLines" | "height">,
InteractionStatesOptions<HTMLAnchorElement> {
/**
* An optional component to render as. This should really only be used if you
* are using a router library like
* {@link https://github.com/ReactTraining/react-router|react-router} or
* {@link https://github.com/reach/router|@reach/router}. This will call
* `createElement` with this value and provide all props and class name.
*/
component?: ElementType;
}
export interface ListItemLinkWithComponentProps extends ListItemLinkProps {
component: ElementType;
/**
* I'm not really sure of a good way to implement this, but when the
* `component` prop is provided, all valid props from that component should
* also be allowed.
*/
[key: string]: unknown;
}
/**
* This component is a really bad attempt at creating a `Link` within a `List`
* that has the main `ListItem` styles. It will probably be better to just use
* the `ListItemChildren` within your `Link` component instead.
*/
export const ListItemLink = forwardRef<
HTMLAnchorElement | ElementType,
ListItemLinkProps | ListItemLinkWithComponentProps
>(function ListItemLink(
{
className: propClassName,
textClassName,
secondaryTextClassName,
textChildren,
primaryText,
secondaryText,
children,
leftAddon,
leftAddonType = "icon",
leftAddonPosition = "middle",
rightAddon,
rightAddonType = "icon",
rightAddonPosition = "middle",
forceAddonWrap,
height: propHeight = "auto",
threeLines = false,
component: Component = "a",
disableSpacebarClick,
disableRipple,
disableProgrammaticRipple,
disablePressedFallback,
rippleTimeout,
rippleClassNames,
rippleClassName,
rippleContainerClassName,
...props
},
ref
) {
const height = getListItemHeight({
height: propHeight,
leftAddon,
leftAddonType,
rightAddon,
rightAddonType,
secondaryText,
});
const { ripples, className, handlers } = useInteractionStates({
className: propClassName,
handlers: props,
disableRipple,
disableProgrammaticRipple,
rippleTimeout,
rippleClassNames,
rippleClassName,
rippleContainerClassName,
disableSpacebarClick,
disablePressedFallback,
});
return (
<Component
{...props}
{...handlers}
ref={ref}
className={cn(
"rmd-list-item rmd-list-item--clickable rmd-list-item--link",
{
[`rmd-list-item--${height}`]:
height !== "auto" && height !== "normal",
"rmd-list-item--three-lines": !!secondaryText && threeLines,
},
className
)}
>
<ListItemChildren
textClassName={textClassName}
secondaryTextClassName={secondaryTextClassName}
textChildren={textChildren}
primaryText={primaryText}
secondaryText={secondaryText}
leftAddon={leftAddon}
leftAddonType={leftAddonType}
leftAddonPosition={leftAddonPosition}
rightAddon={rightAddon}
rightAddonType={rightAddonType}
rightAddonPosition={rightAddonPosition}
forceAddonWrap={forceAddonWrap}
>
{children}
</ListItemChildren>
{ripples}
</Component>
);
});