UNPKG

8.36 kBJavaScriptView Raw
1'use client';
2
3import * as React from 'react';
4import PropTypes from 'prop-types';
5import clsx from 'clsx';
6import { alpha } from '@mui/system/colorManipulator';
7import elementTypeAcceptingRef from '@mui/utils/elementTypeAcceptingRef';
8import composeClasses from '@mui/utils/composeClasses';
9import isFocusVisible from '@mui/utils/isFocusVisible';
10import capitalize from "../utils/capitalize.js";
11import { styled, useTheme } from "../zero-styled/index.js";
12import memoTheme from "../utils/memoTheme.js";
13import createSimplePaletteValueFilter from "../utils/createSimplePaletteValueFilter.js";
14import { useDefaultProps } from "../DefaultPropsProvider/index.js";
15import Typography from "../Typography/index.js";
16import linkClasses, { getLinkUtilityClass } from "./linkClasses.js";
17import getTextDecoration from "./getTextDecoration.js";
18import { jsx as _jsx } from "react/jsx-runtime";
19const v6Colors = {
20 primary: true,
21 secondary: true,
22 error: true,
23 info: true,
24 success: true,
25 warning: true,
26 textPrimary: true,
27 textSecondary: true,
28 textDisabled: true
29};
30const useUtilityClasses = ownerState => {
31 const {
32 classes,
33 component,
34 focusVisible,
35 underline
36 } = ownerState;
37 const slots = {
38 root: ['root', `underline${capitalize(underline)}`, component === 'button' && 'button', focusVisible && 'focusVisible']
39 };
40 return composeClasses(slots, getLinkUtilityClass, classes);
41};
42const LinkRoot = styled(Typography, {
43 name: 'MuiLink',
44 slot: 'Root',
45 overridesResolver: (props, styles) => {
46 const {
47 ownerState
48 } = props;
49 return [styles.root, styles[`underline${capitalize(ownerState.underline)}`], ownerState.component === 'button' && styles.button];
50 }
51})(memoTheme(({
52 theme
53}) => {
54 return {
55 variants: [{
56 props: {
57 underline: 'none'
58 },
59 style: {
60 textDecoration: 'none'
61 }
62 }, {
63 props: {
64 underline: 'hover'
65 },
66 style: {
67 textDecoration: 'none',
68 '&:hover': {
69 textDecoration: 'underline'
70 }
71 }
72 }, {
73 props: {
74 underline: 'always'
75 },
76 style: {
77 textDecoration: 'underline',
78 '&:hover': {
79 textDecorationColor: 'inherit'
80 }
81 }
82 }, {
83 props: ({
84 underline,
85 ownerState
86 }) => underline === 'always' && ownerState.color !== 'inherit',
87 style: {
88 textDecorationColor: 'var(--Link-underlineColor)'
89 }
90 }, ...Object.entries(theme.palette).filter(createSimplePaletteValueFilter()).map(([color]) => ({
91 props: {
92 underline: 'always',
93 color
94 },
95 style: {
96 '--Link-underlineColor': theme.vars ? `rgba(${theme.vars.palette[color].mainChannel} / 0.4)` : alpha(theme.palette[color].main, 0.4)
97 }
98 })), {
99 props: {
100 underline: 'always',
101 color: 'textPrimary'
102 },
103 style: {
104 '--Link-underlineColor': theme.vars ? `rgba(${theme.vars.palette.text.primaryChannel} / 0.4)` : alpha(theme.palette.text.primary, 0.4)
105 }
106 }, {
107 props: {
108 underline: 'always',
109 color: 'textSecondary'
110 },
111 style: {
112 '--Link-underlineColor': theme.vars ? `rgba(${theme.vars.palette.text.secondaryChannel} / 0.4)` : alpha(theme.palette.text.secondary, 0.4)
113 }
114 }, {
115 props: {
116 underline: 'always',
117 color: 'textDisabled'
118 },
119 style: {
120 '--Link-underlineColor': (theme.vars || theme).palette.text.disabled
121 }
122 }, {
123 props: {
124 component: 'button'
125 },
126 style: {
127 position: 'relative',
128 WebkitTapHighlightColor: 'transparent',
129 backgroundColor: 'transparent',
130 // Reset default value
131 // We disable the focus ring for mouse, touch and keyboard users.
132 outline: 0,
133 border: 0,
134 margin: 0,
135 // Remove the margin in Safari
136 borderRadius: 0,
137 padding: 0,
138 // Remove the padding in Firefox
139 cursor: 'pointer',
140 userSelect: 'none',
141 verticalAlign: 'middle',
142 MozAppearance: 'none',
143 // Reset
144 WebkitAppearance: 'none',
145 // Reset
146 '&::-moz-focus-inner': {
147 borderStyle: 'none' // Remove Firefox dotted outline.
148 },
149 [`&.${linkClasses.focusVisible}`]: {
150 outline: 'auto'
151 }
152 }
153 }]
154 };
155}));
156const Link = /*#__PURE__*/React.forwardRef(function Link(inProps, ref) {
157 const props = useDefaultProps({
158 props: inProps,
159 name: 'MuiLink'
160 });
161 const theme = useTheme();
162 const {
163 className,
164 color = 'primary',
165 component = 'a',
166 onBlur,
167 onFocus,
168 TypographyClasses,
169 underline = 'always',
170 variant = 'inherit',
171 sx,
172 ...other
173 } = props;
174 const [focusVisible, setFocusVisible] = React.useState(false);
175 const handleBlur = event => {
176 if (!isFocusVisible(event.target)) {
177 setFocusVisible(false);
178 }
179 if (onBlur) {
180 onBlur(event);
181 }
182 };
183 const handleFocus = event => {
184 if (isFocusVisible(event.target)) {
185 setFocusVisible(true);
186 }
187 if (onFocus) {
188 onFocus(event);
189 }
190 };
191 const ownerState = {
192 ...props,
193 color,
194 component,
195 focusVisible,
196 underline,
197 variant
198 };
199 const classes = useUtilityClasses(ownerState);
200 return /*#__PURE__*/_jsx(LinkRoot, {
201 color: color,
202 className: clsx(classes.root, className),
203 classes: TypographyClasses,
204 component: component,
205 onBlur: handleBlur,
206 onFocus: handleFocus,
207 ref: ref,
208 ownerState: ownerState,
209 variant: variant,
210 ...other,
211 sx: [...(v6Colors[color] === undefined ? [{
212 color
213 }] : []), ...(Array.isArray(sx) ? sx : [sx])],
214 style: {
215 ...other.style,
216 ...(underline === 'always' && color !== 'inherit' && !v6Colors[color] && {
217 '--Link-underlineColor': getTextDecoration({
218 theme,
219 ownerState
220 })
221 })
222 }
223 });
224});
225process.env.NODE_ENV !== "production" ? Link.propTypes /* remove-proptypes */ = {
226 // ┌────────────────────────────── Warning ──────────────────────────────┐
227 // │ These PropTypes are generated from the TypeScript type definitions. │
228 // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
229 // └─────────────────────────────────────────────────────────────────────┘
230 /**
231 * The content of the component.
232 */
233 children: PropTypes.node,
234 /**
235 * Override or extend the styles applied to the component.
236 */
237 classes: PropTypes.object,
238 /**
239 * @ignore
240 */
241 className: PropTypes.string,
242 /**
243 * The color of the link.
244 * @default 'primary'
245 */
246 color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['primary', 'secondary', 'success', 'error', 'info', 'warning', 'textPrimary', 'textSecondary', 'textDisabled']), PropTypes.string]),
247 /**
248 * The component used for the root node.
249 * Either a string to use a HTML element or a component.
250 */
251 component: elementTypeAcceptingRef,
252 /**
253 * @ignore
254 */
255 onBlur: PropTypes.func,
256 /**
257 * @ignore
258 */
259 onFocus: PropTypes.func,
260 /**
261 * @ignore
262 */
263 style: PropTypes.object,
264 /**
265 * The system prop that allows defining system overrides as well as additional CSS styles.
266 */
267 sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
268 /**
269 * `classes` prop applied to the [`Typography`](https://mui.com/material-ui/api/typography/) element.
270 */
271 TypographyClasses: PropTypes.object,
272 /**
273 * Controls when the link should have an underline.
274 * @default 'always'
275 */
276 underline: PropTypes.oneOf(['always', 'hover', 'none']),
277 /**
278 * Applies the theme typography styles.
279 * @default 'inherit'
280 */
281 variant: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['body1', 'body2', 'button', 'caption', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'inherit', 'overline', 'subtitle1', 'subtitle2']), PropTypes.string])
282} : void 0;
283export default Link;
\No newline at end of file