1 | 'use client';
|
2 |
|
3 | import * as React from 'react';
|
4 | import PropTypes from 'prop-types';
|
5 | import clsx from 'clsx';
|
6 | import usePreviousProps from '@mui/utils/usePreviousProps';
|
7 | import composeClasses from '@mui/utils/composeClasses';
|
8 | import useSlotProps from '@mui/utils/useSlotProps';
|
9 | import useBadge from "./useBadge.js";
|
10 | import { styled } from "../zero-styled/index.js";
|
11 | import memoTheme from "../utils/memoTheme.js";
|
12 | import createSimplePaletteValueFilter from "../utils/createSimplePaletteValueFilter.js";
|
13 | import { useDefaultProps } from "../DefaultPropsProvider/index.js";
|
14 | import capitalize from "../utils/capitalize.js";
|
15 | import badgeClasses, { getBadgeUtilityClass } from "./badgeClasses.js";
|
16 | import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
17 | const RADIUS_STANDARD = 10;
|
18 | const RADIUS_DOT = 4;
|
19 | const useUtilityClasses = ownerState => {
|
20 | const {
|
21 | color,
|
22 | anchorOrigin,
|
23 | invisible,
|
24 | overlap,
|
25 | variant,
|
26 | classes = {}
|
27 | } = ownerState;
|
28 | const slots = {
|
29 | root: ['root'],
|
30 | badge: ['badge', variant, invisible && 'invisible', `anchorOrigin${capitalize(anchorOrigin.vertical)}${capitalize(anchorOrigin.horizontal)}`, `anchorOrigin${capitalize(anchorOrigin.vertical)}${capitalize(anchorOrigin.horizontal)}${capitalize(overlap)}`, `overlap${capitalize(overlap)}`, color !== 'default' && `color${capitalize(color)}`]
|
31 | };
|
32 | return composeClasses(slots, getBadgeUtilityClass, classes);
|
33 | };
|
34 | const BadgeRoot = styled('span', {
|
35 | name: 'MuiBadge',
|
36 | slot: 'Root',
|
37 | overridesResolver: (props, styles) => styles.root
|
38 | })({
|
39 | position: 'relative',
|
40 | display: 'inline-flex',
|
41 |
|
42 | verticalAlign: 'middle',
|
43 | flexShrink: 0
|
44 | });
|
45 | const BadgeBadge = styled('span', {
|
46 | name: 'MuiBadge',
|
47 | slot: 'Badge',
|
48 | overridesResolver: (props, styles) => {
|
49 | const {
|
50 | ownerState
|
51 | } = props;
|
52 | return [styles.badge, styles[ownerState.variant], styles[`anchorOrigin${capitalize(ownerState.anchorOrigin.vertical)}${capitalize(ownerState.anchorOrigin.horizontal)}${capitalize(ownerState.overlap)}`], ownerState.color !== 'default' && styles[`color${capitalize(ownerState.color)}`], ownerState.invisible && styles.invisible];
|
53 | }
|
54 | })(memoTheme(({
|
55 | theme
|
56 | }) => ({
|
57 | display: 'flex',
|
58 | flexDirection: 'row',
|
59 | flexWrap: 'wrap',
|
60 | justifyContent: 'center',
|
61 | alignContent: 'center',
|
62 | alignItems: 'center',
|
63 | position: 'absolute',
|
64 | boxSizing: 'border-box',
|
65 | fontFamily: theme.typography.fontFamily,
|
66 | fontWeight: theme.typography.fontWeightMedium,
|
67 | fontSize: theme.typography.pxToRem(12),
|
68 | minWidth: RADIUS_STANDARD * 2,
|
69 | lineHeight: 1,
|
70 | padding: '0 6px',
|
71 | height: RADIUS_STANDARD * 2,
|
72 | borderRadius: RADIUS_STANDARD,
|
73 | zIndex: 1,
|
74 |
|
75 | transition: theme.transitions.create('transform', {
|
76 | easing: theme.transitions.easing.easeInOut,
|
77 | duration: theme.transitions.duration.enteringScreen
|
78 | }),
|
79 | variants: [...Object.entries(theme.palette).filter(createSimplePaletteValueFilter(['contrastText'])).map(([color]) => ({
|
80 | props: {
|
81 | color
|
82 | },
|
83 | style: {
|
84 | backgroundColor: (theme.vars || theme).palette[color].main,
|
85 | color: (theme.vars || theme).palette[color].contrastText
|
86 | }
|
87 | })), {
|
88 | props: {
|
89 | variant: 'dot'
|
90 | },
|
91 | style: {
|
92 | borderRadius: RADIUS_DOT,
|
93 | height: RADIUS_DOT * 2,
|
94 | minWidth: RADIUS_DOT * 2,
|
95 | padding: 0
|
96 | }
|
97 | }, {
|
98 | props: ({
|
99 | ownerState
|
100 | }) => ownerState.anchorOrigin.vertical === 'top' && ownerState.anchorOrigin.horizontal === 'right' && ownerState.overlap === 'rectangular',
|
101 | style: {
|
102 | top: 0,
|
103 | right: 0,
|
104 | transform: 'scale(1) translate(50%, -50%)',
|
105 | transformOrigin: '100% 0%',
|
106 | [`&.${badgeClasses.invisible}`]: {
|
107 | transform: 'scale(0) translate(50%, -50%)'
|
108 | }
|
109 | }
|
110 | }, {
|
111 | props: ({
|
112 | ownerState
|
113 | }) => ownerState.anchorOrigin.vertical === 'bottom' && ownerState.anchorOrigin.horizontal === 'right' && ownerState.overlap === 'rectangular',
|
114 | style: {
|
115 | bottom: 0,
|
116 | right: 0,
|
117 | transform: 'scale(1) translate(50%, 50%)',
|
118 | transformOrigin: '100% 100%',
|
119 | [`&.${badgeClasses.invisible}`]: {
|
120 | transform: 'scale(0) translate(50%, 50%)'
|
121 | }
|
122 | }
|
123 | }, {
|
124 | props: ({
|
125 | ownerState
|
126 | }) => ownerState.anchorOrigin.vertical === 'top' && ownerState.anchorOrigin.horizontal === 'left' && ownerState.overlap === 'rectangular',
|
127 | style: {
|
128 | top: 0,
|
129 | left: 0,
|
130 | transform: 'scale(1) translate(-50%, -50%)',
|
131 | transformOrigin: '0% 0%',
|
132 | [`&.${badgeClasses.invisible}`]: {
|
133 | transform: 'scale(0) translate(-50%, -50%)'
|
134 | }
|
135 | }
|
136 | }, {
|
137 | props: ({
|
138 | ownerState
|
139 | }) => ownerState.anchorOrigin.vertical === 'bottom' && ownerState.anchorOrigin.horizontal === 'left' && ownerState.overlap === 'rectangular',
|
140 | style: {
|
141 | bottom: 0,
|
142 | left: 0,
|
143 | transform: 'scale(1) translate(-50%, 50%)',
|
144 | transformOrigin: '0% 100%',
|
145 | [`&.${badgeClasses.invisible}`]: {
|
146 | transform: 'scale(0) translate(-50%, 50%)'
|
147 | }
|
148 | }
|
149 | }, {
|
150 | props: ({
|
151 | ownerState
|
152 | }) => ownerState.anchorOrigin.vertical === 'top' && ownerState.anchorOrigin.horizontal === 'right' && ownerState.overlap === 'circular',
|
153 | style: {
|
154 | top: '14%',
|
155 | right: '14%',
|
156 | transform: 'scale(1) translate(50%, -50%)',
|
157 | transformOrigin: '100% 0%',
|
158 | [`&.${badgeClasses.invisible}`]: {
|
159 | transform: 'scale(0) translate(50%, -50%)'
|
160 | }
|
161 | }
|
162 | }, {
|
163 | props: ({
|
164 | ownerState
|
165 | }) => ownerState.anchorOrigin.vertical === 'bottom' && ownerState.anchorOrigin.horizontal === 'right' && ownerState.overlap === 'circular',
|
166 | style: {
|
167 | bottom: '14%',
|
168 | right: '14%',
|
169 | transform: 'scale(1) translate(50%, 50%)',
|
170 | transformOrigin: '100% 100%',
|
171 | [`&.${badgeClasses.invisible}`]: {
|
172 | transform: 'scale(0) translate(50%, 50%)'
|
173 | }
|
174 | }
|
175 | }, {
|
176 | props: ({
|
177 | ownerState
|
178 | }) => ownerState.anchorOrigin.vertical === 'top' && ownerState.anchorOrigin.horizontal === 'left' && ownerState.overlap === 'circular',
|
179 | style: {
|
180 | top: '14%',
|
181 | left: '14%',
|
182 | transform: 'scale(1) translate(-50%, -50%)',
|
183 | transformOrigin: '0% 0%',
|
184 | [`&.${badgeClasses.invisible}`]: {
|
185 | transform: 'scale(0) translate(-50%, -50%)'
|
186 | }
|
187 | }
|
188 | }, {
|
189 | props: ({
|
190 | ownerState
|
191 | }) => ownerState.anchorOrigin.vertical === 'bottom' && ownerState.anchorOrigin.horizontal === 'left' && ownerState.overlap === 'circular',
|
192 | style: {
|
193 | bottom: '14%',
|
194 | left: '14%',
|
195 | transform: 'scale(1) translate(-50%, 50%)',
|
196 | transformOrigin: '0% 100%',
|
197 | [`&.${badgeClasses.invisible}`]: {
|
198 | transform: 'scale(0) translate(-50%, 50%)'
|
199 | }
|
200 | }
|
201 | }, {
|
202 | props: {
|
203 | invisible: true
|
204 | },
|
205 | style: {
|
206 | transition: theme.transitions.create('transform', {
|
207 | easing: theme.transitions.easing.easeInOut,
|
208 | duration: theme.transitions.duration.leavingScreen
|
209 | })
|
210 | }
|
211 | }]
|
212 | })));
|
213 | function getAnchorOrigin(anchorOrigin) {
|
214 | return {
|
215 | vertical: anchorOrigin?.vertical ?? 'top',
|
216 | horizontal: anchorOrigin?.horizontal ?? 'right'
|
217 | };
|
218 | }
|
219 | const Badge = React.forwardRef(function Badge(inProps, ref) {
|
220 | const props = useDefaultProps({
|
221 | props: inProps,
|
222 | name: 'MuiBadge'
|
223 | });
|
224 | const {
|
225 | anchorOrigin: anchorOriginProp,
|
226 | className,
|
227 | classes: classesProp,
|
228 | component,
|
229 | components = {},
|
230 | componentsProps = {},
|
231 | children,
|
232 | overlap: overlapProp = 'rectangular',
|
233 | color: colorProp = 'default',
|
234 | invisible: invisibleProp = false,
|
235 | max: maxProp = 99,
|
236 | badgeContent: badgeContentProp,
|
237 | slots,
|
238 | slotProps,
|
239 | showZero = false,
|
240 | variant: variantProp = 'standard',
|
241 | ...other
|
242 | } = props;
|
243 | const {
|
244 | badgeContent,
|
245 | invisible: invisibleFromHook,
|
246 | max,
|
247 | displayValue: displayValueFromHook
|
248 | } = useBadge({
|
249 | max: maxProp,
|
250 | invisible: invisibleProp,
|
251 | badgeContent: badgeContentProp,
|
252 | showZero
|
253 | });
|
254 | const prevProps = usePreviousProps({
|
255 | anchorOrigin: getAnchorOrigin(anchorOriginProp),
|
256 | color: colorProp,
|
257 | overlap: overlapProp,
|
258 | variant: variantProp,
|
259 | badgeContent: badgeContentProp
|
260 | });
|
261 | const invisible = invisibleFromHook || badgeContent == null && variantProp !== 'dot';
|
262 | const {
|
263 | color = colorProp,
|
264 | overlap = overlapProp,
|
265 | anchorOrigin: anchorOriginPropProp,
|
266 | variant = variantProp
|
267 | } = invisible ? prevProps : props;
|
268 | const anchorOrigin = getAnchorOrigin(anchorOriginPropProp);
|
269 | const displayValue = variant !== 'dot' ? displayValueFromHook : undefined;
|
270 | const ownerState = {
|
271 | ...props,
|
272 | badgeContent,
|
273 | invisible,
|
274 | max,
|
275 | displayValue,
|
276 | showZero,
|
277 | anchorOrigin,
|
278 | color,
|
279 | overlap,
|
280 | variant
|
281 | };
|
282 | const classes = useUtilityClasses(ownerState);
|
283 |
|
284 |
|
285 | const RootSlot = slots?.root ?? components.Root ?? BadgeRoot;
|
286 | const BadgeSlot = slots?.badge ?? components.Badge ?? BadgeBadge;
|
287 | const rootSlotProps = slotProps?.root ?? componentsProps.root;
|
288 | const badgeSlotProps = slotProps?.badge ?? componentsProps.badge;
|
289 | const rootProps = useSlotProps({
|
290 | elementType: RootSlot,
|
291 | externalSlotProps: rootSlotProps,
|
292 | externalForwardedProps: other,
|
293 | additionalProps: {
|
294 | ref,
|
295 | as: component
|
296 | },
|
297 | ownerState,
|
298 | className: clsx(rootSlotProps?.className, classes.root, className)
|
299 | });
|
300 | const badgeProps = useSlotProps({
|
301 | elementType: BadgeSlot,
|
302 | externalSlotProps: badgeSlotProps,
|
303 | ownerState,
|
304 | className: clsx(classes.badge, badgeSlotProps?.className)
|
305 | });
|
306 | return _jsxs(RootSlot, {
|
307 | ...rootProps,
|
308 | children: [children, _jsx(BadgeSlot, {
|
309 | ...badgeProps,
|
310 | children: displayValue
|
311 | })]
|
312 | });
|
313 | });
|
314 | process.env.NODE_ENV !== "production" ? Badge.propTypes = {
|
315 |
|
316 |
|
317 |
|
318 |
|
319 | |
320 |
|
321 |
|
322 |
|
323 |
|
324 |
|
325 |
|
326 | anchorOrigin: PropTypes.shape({
|
327 | horizontal: PropTypes.oneOf(['left', 'right']),
|
328 | vertical: PropTypes.oneOf(['bottom', 'top'])
|
329 | }),
|
330 | |
331 |
|
332 |
|
333 | badgeContent: PropTypes.node,
|
334 | |
335 |
|
336 |
|
337 | children: PropTypes.node,
|
338 | |
339 |
|
340 |
|
341 | classes: PropTypes.object,
|
342 | |
343 |
|
344 |
|
345 | className: PropTypes.string,
|
346 | |
347 |
|
348 |
|
349 |
|
350 |
|
351 |
|
352 | color: PropTypes .oneOfType([PropTypes.oneOf(['default', 'primary', 'secondary', 'error', 'info', 'success', 'warning']), PropTypes.string]),
|
353 | |
354 |
|
355 |
|
356 |
|
357 | component: PropTypes.elementType,
|
358 | |
359 |
|
360 |
|
361 |
|
362 |
|
363 |
|
364 |
|
365 | components: PropTypes.shape({
|
366 | Badge: PropTypes.elementType,
|
367 | Root: PropTypes.elementType
|
368 | }),
|
369 | |
370 |
|
371 |
|
372 |
|
373 |
|
374 |
|
375 |
|
376 |
|
377 | componentsProps: PropTypes.shape({
|
378 | badge: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
379 | root: PropTypes.oneOfType([PropTypes.func, PropTypes.object])
|
380 | }),
|
381 | |
382 |
|
383 |
|
384 |
|
385 | invisible: PropTypes.bool,
|
386 | |
387 |
|
388 |
|
389 |
|
390 | max: PropTypes.number,
|
391 | |
392 |
|
393 |
|
394 |
|
395 | overlap: PropTypes.oneOf(['circular', 'rectangular']),
|
396 | |
397 |
|
398 |
|
399 |
|
400 | showZero: PropTypes.bool,
|
401 | |
402 |
|
403 |
|
404 |
|
405 | slotProps: PropTypes.shape({
|
406 | badge: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
407 | root: PropTypes.oneOfType([PropTypes.func, PropTypes.object])
|
408 | }),
|
409 | |
410 |
|
411 |
|
412 |
|
413 |
|
414 | slots: PropTypes.shape({
|
415 | badge: PropTypes.elementType,
|
416 | root: PropTypes.elementType
|
417 | }),
|
418 | |
419 |
|
420 |
|
421 | sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
|
422 | |
423 |
|
424 |
|
425 |
|
426 | variant: PropTypes .oneOfType([PropTypes.oneOf(['dot', 'standard']), PropTypes.string])
|
427 | } : void 0;
|
428 | export default Badge; |
\ | No newline at end of file |