UNPKG

16.1 kBJavaScriptView Raw
1'use client';
2
3import * as React from 'react';
4import PropTypes from 'prop-types';
5import clsx from 'clsx';
6import composeClasses from '@mui/utils/composeClasses';
7import { alpha } from '@mui/system/colorManipulator';
8import { useRtl } from '@mui/system/RtlProvider';
9import paginationItemClasses, { getPaginationItemUtilityClass } from "./paginationItemClasses.js";
10import ButtonBase from "../ButtonBase/index.js";
11import capitalize from "../utils/capitalize.js";
12import createSimplePaletteValueFilter from "../utils/createSimplePaletteValueFilter.js";
13import FirstPageIcon from "../internal/svg-icons/FirstPage.js";
14import LastPageIcon from "../internal/svg-icons/LastPage.js";
15import NavigateBeforeIcon from "../internal/svg-icons/NavigateBefore.js";
16import NavigateNextIcon from "../internal/svg-icons/NavigateNext.js";
17import useSlot from "../utils/useSlot.js";
18import { styled } from "../zero-styled/index.js";
19import memoTheme from "../utils/memoTheme.js";
20import { useDefaultProps } from "../DefaultPropsProvider/index.js";
21import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
22const overridesResolver = (props, styles) => {
23 const {
24 ownerState
25 } = props;
26 return [styles.root, styles[ownerState.variant], styles[`size${capitalize(ownerState.size)}`], ownerState.variant === 'text' && styles[`text${capitalize(ownerState.color)}`], ownerState.variant === 'outlined' && styles[`outlined${capitalize(ownerState.color)}`], ownerState.shape === 'rounded' && styles.rounded, ownerState.type === 'page' && styles.page, (ownerState.type === 'start-ellipsis' || ownerState.type === 'end-ellipsis') && styles.ellipsis, (ownerState.type === 'previous' || ownerState.type === 'next') && styles.previousNext, (ownerState.type === 'first' || ownerState.type === 'last') && styles.firstLast];
27};
28const useUtilityClasses = ownerState => {
29 const {
30 classes,
31 color,
32 disabled,
33 selected,
34 size,
35 shape,
36 type,
37 variant
38 } = ownerState;
39 const slots = {
40 root: ['root', `size${capitalize(size)}`, variant, shape, color !== 'standard' && `color${capitalize(color)}`, color !== 'standard' && `${variant}${capitalize(color)}`, disabled && 'disabled', selected && 'selected', {
41 page: 'page',
42 first: 'firstLast',
43 last: 'firstLast',
44 'start-ellipsis': 'ellipsis',
45 'end-ellipsis': 'ellipsis',
46 previous: 'previousNext',
47 next: 'previousNext'
48 }[type]],
49 icon: ['icon']
50 };
51 return composeClasses(slots, getPaginationItemUtilityClass, classes);
52};
53const PaginationItemEllipsis = styled('div', {
54 name: 'MuiPaginationItem',
55 slot: 'Root',
56 overridesResolver
57})(memoTheme(({
58 theme
59}) => ({
60 ...theme.typography.body2,
61 borderRadius: 32 / 2,
62 textAlign: 'center',
63 boxSizing: 'border-box',
64 minWidth: 32,
65 padding: '0 6px',
66 margin: '0 3px',
67 color: (theme.vars || theme).palette.text.primary,
68 height: 'auto',
69 [`&.${paginationItemClasses.disabled}`]: {
70 opacity: (theme.vars || theme).palette.action.disabledOpacity
71 },
72 variants: [{
73 props: {
74 size: 'small'
75 },
76 style: {
77 minWidth: 26,
78 borderRadius: 26 / 2,
79 margin: '0 1px',
80 padding: '0 4px'
81 }
82 }, {
83 props: {
84 size: 'large'
85 },
86 style: {
87 minWidth: 40,
88 borderRadius: 40 / 2,
89 padding: '0 10px',
90 fontSize: theme.typography.pxToRem(15)
91 }
92 }]
93})));
94const PaginationItemPage = styled(ButtonBase, {
95 name: 'MuiPaginationItem',
96 slot: 'Root',
97 overridesResolver
98})(memoTheme(({
99 theme
100}) => ({
101 ...theme.typography.body2,
102 borderRadius: 32 / 2,
103 textAlign: 'center',
104 boxSizing: 'border-box',
105 minWidth: 32,
106 height: 32,
107 padding: '0 6px',
108 margin: '0 3px',
109 color: (theme.vars || theme).palette.text.primary,
110 [`&.${paginationItemClasses.focusVisible}`]: {
111 backgroundColor: (theme.vars || theme).palette.action.focus
112 },
113 [`&.${paginationItemClasses.disabled}`]: {
114 opacity: (theme.vars || theme).palette.action.disabledOpacity
115 },
116 transition: theme.transitions.create(['color', 'background-color'], {
117 duration: theme.transitions.duration.short
118 }),
119 '&:hover': {
120 backgroundColor: (theme.vars || theme).palette.action.hover,
121 // Reset on touch devices, it doesn't add specificity
122 '@media (hover: none)': {
123 backgroundColor: 'transparent'
124 }
125 },
126 [`&.${paginationItemClasses.selected}`]: {
127 backgroundColor: (theme.vars || theme).palette.action.selected,
128 '&:hover': {
129 backgroundColor: theme.vars ? `rgba(${theme.vars.palette.action.selectedChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` : alpha(theme.palette.action.selected, theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity),
130 // Reset on touch devices, it doesn't add specificity
131 '@media (hover: none)': {
132 backgroundColor: (theme.vars || theme).palette.action.selected
133 }
134 },
135 [`&.${paginationItemClasses.focusVisible}`]: {
136 backgroundColor: theme.vars ? `rgba(${theme.vars.palette.action.selectedChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.focusOpacity}))` : alpha(theme.palette.action.selected, theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity)
137 },
138 [`&.${paginationItemClasses.disabled}`]: {
139 opacity: 1,
140 color: (theme.vars || theme).palette.action.disabled,
141 backgroundColor: (theme.vars || theme).palette.action.selected
142 }
143 },
144 variants: [{
145 props: {
146 size: 'small'
147 },
148 style: {
149 minWidth: 26,
150 height: 26,
151 borderRadius: 26 / 2,
152 margin: '0 1px',
153 padding: '0 4px'
154 }
155 }, {
156 props: {
157 size: 'large'
158 },
159 style: {
160 minWidth: 40,
161 height: 40,
162 borderRadius: 40 / 2,
163 padding: '0 10px',
164 fontSize: theme.typography.pxToRem(15)
165 }
166 }, {
167 props: {
168 shape: 'rounded'
169 },
170 style: {
171 borderRadius: (theme.vars || theme).shape.borderRadius
172 }
173 }, {
174 props: {
175 variant: 'outlined'
176 },
177 style: {
178 border: theme.vars ? `1px solid rgba(${theme.vars.palette.common.onBackgroundChannel} / 0.23)` : `1px solid ${theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)'}`,
179 [`&.${paginationItemClasses.selected}`]: {
180 [`&.${paginationItemClasses.disabled}`]: {
181 borderColor: (theme.vars || theme).palette.action.disabledBackground,
182 color: (theme.vars || theme).palette.action.disabled
183 }
184 }
185 }
186 }, {
187 props: {
188 variant: 'text'
189 },
190 style: {
191 [`&.${paginationItemClasses.selected}`]: {
192 [`&.${paginationItemClasses.disabled}`]: {
193 color: (theme.vars || theme).palette.action.disabled
194 }
195 }
196 }
197 }, ...Object.entries(theme.palette).filter(createSimplePaletteValueFilter(['dark', 'contrastText'])).map(([color]) => ({
198 props: {
199 variant: 'text',
200 color
201 },
202 style: {
203 [`&.${paginationItemClasses.selected}`]: {
204 color: (theme.vars || theme).palette[color].contrastText,
205 backgroundColor: (theme.vars || theme).palette[color].main,
206 '&:hover': {
207 backgroundColor: (theme.vars || theme).palette[color].dark,
208 // Reset on touch devices, it doesn't add specificity
209 '@media (hover: none)': {
210 backgroundColor: (theme.vars || theme).palette[color].main
211 }
212 },
213 [`&.${paginationItemClasses.focusVisible}`]: {
214 backgroundColor: (theme.vars || theme).palette[color].dark
215 },
216 [`&.${paginationItemClasses.disabled}`]: {
217 color: (theme.vars || theme).palette.action.disabled
218 }
219 }
220 }
221 })), ...Object.entries(theme.palette).filter(createSimplePaletteValueFilter(['light'])).map(([color]) => ({
222 props: {
223 variant: 'outlined',
224 color
225 },
226 style: {
227 [`&.${paginationItemClasses.selected}`]: {
228 color: (theme.vars || theme).palette[color].main,
229 border: `1px solid ${theme.vars ? `rgba(${theme.vars.palette[color].mainChannel} / 0.5)` : alpha(theme.palette[color].main, 0.5)}`,
230 backgroundColor: theme.vars ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.activatedOpacity})` : alpha(theme.palette[color].main, theme.palette.action.activatedOpacity),
231 '&:hover': {
232 backgroundColor: theme.vars ? `rgba(${theme.vars.palette[color].mainChannel} / calc(${theme.vars.palette.action.activatedOpacity} + ${theme.vars.palette.action.focusOpacity}))` : alpha(theme.palette[color].main, theme.palette.action.activatedOpacity + theme.palette.action.focusOpacity),
233 // Reset on touch devices, it doesn't add specificity
234 '@media (hover: none)': {
235 backgroundColor: 'transparent'
236 }
237 },
238 [`&.${paginationItemClasses.focusVisible}`]: {
239 backgroundColor: theme.vars ? `rgba(${theme.vars.palette[color].mainChannel} / calc(${theme.vars.palette.action.activatedOpacity} + ${theme.vars.palette.action.focusOpacity}))` : alpha(theme.palette[color].main, theme.palette.action.activatedOpacity + theme.palette.action.focusOpacity)
240 }
241 }
242 }
243 }))]
244})));
245const PaginationItemPageIcon = styled('div', {
246 name: 'MuiPaginationItem',
247 slot: 'Icon',
248 overridesResolver: (props, styles) => styles.icon
249})(memoTheme(({
250 theme
251}) => ({
252 fontSize: theme.typography.pxToRem(20),
253 margin: '0 -8px',
254 variants: [{
255 props: {
256 size: 'small'
257 },
258 style: {
259 fontSize: theme.typography.pxToRem(18)
260 }
261 }, {
262 props: {
263 size: 'large'
264 },
265 style: {
266 fontSize: theme.typography.pxToRem(22)
267 }
268 }]
269})));
270const PaginationItem = /*#__PURE__*/React.forwardRef(function PaginationItem(inProps, ref) {
271 const props = useDefaultProps({
272 props: inProps,
273 name: 'MuiPaginationItem'
274 });
275 const {
276 className,
277 color = 'standard',
278 component,
279 components = {},
280 disabled = false,
281 page,
282 selected = false,
283 shape = 'circular',
284 size = 'medium',
285 slots = {},
286 slotProps = {},
287 type = 'page',
288 variant = 'text',
289 ...other
290 } = props;
291 const ownerState = {
292 ...props,
293 color,
294 disabled,
295 selected,
296 shape,
297 size,
298 type,
299 variant
300 };
301 const isRtl = useRtl();
302 const classes = useUtilityClasses(ownerState);
303 const externalForwardedProps = {
304 slots: {
305 previous: slots.previous ?? components.previous,
306 next: slots.next ?? components.next,
307 first: slots.first ?? components.first,
308 last: slots.last ?? components.last
309 },
310 slotProps
311 };
312 const [PreviousSlot, previousSlotProps] = useSlot('previous', {
313 elementType: NavigateBeforeIcon,
314 externalForwardedProps,
315 ownerState
316 });
317 const [NextSlot, nextSlotProps] = useSlot('next', {
318 elementType: NavigateNextIcon,
319 externalForwardedProps,
320 ownerState
321 });
322 const [FirstSlot, firstSlotProps] = useSlot('first', {
323 elementType: FirstPageIcon,
324 externalForwardedProps,
325 ownerState
326 });
327 const [LastSlot, lastSlotProps] = useSlot('last', {
328 elementType: LastPageIcon,
329 externalForwardedProps,
330 ownerState
331 });
332 const rtlAwareType = isRtl ? {
333 previous: 'next',
334 next: 'previous',
335 first: 'last',
336 last: 'first'
337 }[type] : type;
338 const IconSlot = {
339 previous: PreviousSlot,
340 next: NextSlot,
341 first: FirstSlot,
342 last: LastSlot
343 }[rtlAwareType];
344 const iconSlotProps = {
345 previous: previousSlotProps,
346 next: nextSlotProps,
347 first: firstSlotProps,
348 last: lastSlotProps
349 }[rtlAwareType];
350 return type === 'start-ellipsis' || type === 'end-ellipsis' ? /*#__PURE__*/_jsx(PaginationItemEllipsis, {
351 ref: ref,
352 ownerState: ownerState,
353 className: clsx(classes.root, className),
354 children: "\u2026"
355 }) : /*#__PURE__*/_jsxs(PaginationItemPage, {
356 ref: ref,
357 ownerState: ownerState,
358 component: component,
359 disabled: disabled,
360 className: clsx(classes.root, className),
361 ...other,
362 children: [type === 'page' && page, IconSlot ? /*#__PURE__*/_jsx(PaginationItemPageIcon, {
363 ...iconSlotProps,
364 className: classes.icon,
365 as: IconSlot
366 }) : null]
367 });
368});
369process.env.NODE_ENV !== "production" ? PaginationItem.propTypes /* remove-proptypes */ = {
370 // ┌────────────────────────────── Warning ──────────────────────────────┐
371 // │ These PropTypes are generated from the TypeScript type definitions. │
372 // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
373 // └─────────────────────────────────────────────────────────────────────┘
374 /**
375 * @ignore
376 */
377 children: PropTypes.node,
378 /**
379 * Override or extend the styles applied to the component.
380 */
381 classes: PropTypes.object,
382 /**
383 * @ignore
384 */
385 className: PropTypes.string,
386 /**
387 * The active color.
388 * It supports both default and custom theme colors, which can be added as shown in the
389 * [palette customization guide](https://mui.com/material-ui/customization/palette/#custom-colors).
390 * @default 'standard'
391 */
392 color: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['primary', 'secondary', 'standard']), PropTypes.string]),
393 /**
394 * The component used for the root node.
395 * Either a string to use a HTML element or a component.
396 */
397 component: PropTypes.elementType,
398 /**
399 * The components used for each slot inside.
400 *
401 * This prop is an alias for the `slots` prop.
402 * It's recommended to use the `slots` prop instead.
403 *
404 * @default {}
405 * @deprecated use the `slots` prop instead. This prop will be removed in v7. See [Migrating from deprecated APIs](https://mui.com/material-ui/migration/migrating-from-deprecated-apis/) for more details.
406 */
407 components: PropTypes.shape({
408 first: PropTypes.elementType,
409 last: PropTypes.elementType,
410 next: PropTypes.elementType,
411 previous: PropTypes.elementType
412 }),
413 /**
414 * If `true`, the component is disabled.
415 * @default false
416 */
417 disabled: PropTypes.bool,
418 /**
419 * The current page number.
420 */
421 page: PropTypes.node,
422 /**
423 * If `true` the pagination item is selected.
424 * @default false
425 */
426 selected: PropTypes.bool,
427 /**
428 * The shape of the pagination item.
429 * @default 'circular'
430 */
431 shape: PropTypes.oneOf(['circular', 'rounded']),
432 /**
433 * The size of the component.
434 * @default 'medium'
435 */
436 size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['small', 'medium', 'large']), PropTypes.string]),
437 /**
438 * The props used for each slot inside.
439 * @default {}
440 */
441 slotProps: PropTypes.shape({
442 first: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
443 last: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
444 next: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
445 previous: PropTypes.oneOfType([PropTypes.func, PropTypes.object])
446 }),
447 /**
448 * The components used for each slot inside.
449 * @default {}
450 */
451 slots: PropTypes.shape({
452 first: PropTypes.elementType,
453 last: PropTypes.elementType,
454 next: PropTypes.elementType,
455 previous: PropTypes.elementType
456 }),
457 /**
458 * The system prop that allows defining system overrides as well as additional CSS styles.
459 */
460 sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
461 /**
462 * The type of pagination item.
463 * @default 'page'
464 */
465 type: PropTypes.oneOf(['end-ellipsis', 'first', 'last', 'next', 'page', 'previous', 'start-ellipsis']),
466 /**
467 * The variant to use.
468 * @default 'text'
469 */
470 variant: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([PropTypes.oneOf(['outlined', 'text']), PropTypes.string])
471} : void 0;
472export default PaginationItem;
\No newline at end of file